Appearance
Customers
Every order is delivered to a customer who has at least one address. Customers are scoped to your merchant account — phone numbers and emails are de-duplicated within your account only.
Create a customer
POST /integration/merchant/customer
Request body:
json
{
"name": "Sara Ahmad",
"phoneNumber": "+96550001234",
"email": "[email protected]",
"addresses": [
{
"label": "Home",
"addressType": "home",
"governorateId": "<governorate-id>",
"neighborhoodId": "<neighborhood-id>",
"blockId": "4",
"streetId": "12",
"houseNumber": "8",
"buildingName": "Al-Salam Tower",
"floorNumber": "3",
"apartmentNumber": "11"
}
]
}| Field | Required | Notes |
|---|---|---|
name | Yes | Customer full name. |
phoneNumber | Yes | Validated and normalized. Must be unique within your merchant account. |
email | No | Validated if provided. Unique within your merchant account. |
addresses | No | Up to 5. The first address becomes the default. label is the only schema-required address field; governorateId and neighborhoodId are required for pricing. |
Response: 201 Created
json
{
"success": true,
"data": {
"customer": {
"_id": "665f...",
"name": "Sara Ahmad",
"phoneNumber": "96550001234",
"addresses": [ { "_id": "665f...", "label": "Home", "isDefault": true, /* ... */ } ]
}
}
}Store customer._id and the relevant addresses[]._id — you need both to create an order.
Find or create a customer
POST /integration/merchant/customer/upsert
The most convenient endpoint for e-commerce flows: pass a phone number and get back the existing customer, or create a new one — all in a single call.
Request body:
json
{ "phoneNumber": "+96550001234", "name": "Sara Ahmad" }| Field | Required | Notes |
|---|---|---|
phoneNumber | Yes | Searched within your merchant account. |
name | If creating | Required when no match is found and a new customer must be created. |
email | No | Stored on creation only if the customer doesn't exist yet. |
Response:
json
{
"success": true,
"data": {
"customer": { "_id": "665f...", "name": "Sara Ahmad", /* ... */ },
"created": false
}
}created: true means a new customer was created; created: false means an existing one was returned. The customer shape is identical in both cases.
Address fields
| Field | Required | Description |
|---|---|---|
label | Schema required | A name for the address, e.g. "Home", "Office". |
governorateId | Required for pricing | From the area tree. Orders cannot be priced without it. |
neighborhoodId | Required for pricing | From the area tree. Orders cannot be priced without it. |
addressType | Optional | home (default) | apartment | office. |
blockId | Optional — strongly preferred | Improves pricing accuracy and routing. |
streetId | Optional | Street within the block. |
parcelId | Optional | Parcel identifier. |
houseNumber | Optional | House or villa number. |
buildingName | Optional | Name of the building or tower. |
floorNumber | Optional | Floor within a building. |
apartmentNumber | Optional | Apartment unit number. |
officeNumber | Optional | Office unit number. |
paciNumber | Optional | Kuwait Civil ID (PACI) parcel number. |
line1 | Optional | Free-text fallback address line. |
coordinates | Optional | { "lat": <number>, "lng": <number> }. |
Required for pricing
At minimum, each address needs governorateId and neighborhoodId — the delivery fee is resolved from them. Provide blockId as well whenever you can. If a customer gives you their Kuwait Civil ID (PACI number), resolve the full hierarchy in one call via GET /governorate-area/civil-id.
List customers
GET /integration/merchant/customer
Returns your merchant's customers with pagination. Supports ?page, ?limit, and ?search query parameters. The list is always returned under data.list with data.pagination.
Get a customer
GET /integration/merchant/customer/:customerId
Returns a single customer (must belong to your merchant), including all addresses.
Update a customer
PUT /integration/merchant/customer/:customerId
Updates the customer's name, phoneNumber, or email. Only send the fields you want to change.
Request body:
json
{ "name": "Sara A. Al-Rashidi", "email": "[email protected]" }Response: 200 OK — updated customer object.
Add an address
POST /integration/merchant/customer/:customerId/address
Adds an address to an existing customer (max 5 total). The first address added to a customer with no addresses becomes the default.
Request body:
json
{
"label": "Office",
"governorateId": "<governorate-id>",
"neighborhoodId": "<neighborhood-id>",
"blockId": "7",
"streetId": "3",
"buildingName": "Trade Center",
"officeNumber": "402"
}label, governorateId, and neighborhoodId are required; the rest are optional (see Address fields).
Response: 201 Created
json
{
"success": true,
"data": {
"address": { "_id": "665f...", "label": "Office", "isDefault": false /* ... */ },
"addresses": [ /* all of the customer's addresses */ ]
}
}Update an address
PUT /integration/merchant/customer/:customerId/address/:addressId
Updates fields on an existing address. Send the same fields accepted at creation. Wasal verifies the customer belongs to your merchant before applying the change.
Set the default address
PUT /integration/merchant/customer/:customerId/address/:addressId/default
Marks the given address as the customer's default. When an order omits customerAddressId, the default address is used.
Delete an address
DELETE /integration/merchant/customer/:customerId/address/:addressId
Removes an address from the customer. The customer must have at least one remaining address before you can create new orders for them.
Delete a customer
DELETE /integration/merchant/customer/:customerId
Removes the customer from your merchant account. The customer record is soft-deleted and no longer accessible through your merchant key.
Customers with existing orders cannot be deleted. If the customer has one or more orders under your merchant account, the request returns
409 CUSTOMER_HAS_ORDERS. Cancel or resolve the outstanding orders before deleting the customer.
Response: 200 OK
json
{ "success": true, "message": "Customer removed from merchant successfully" }Errors
| HTTP | code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | One or more fields invalid — see errors. |
| 400 | MAX_ADDRESSES_EXCEEDED | Customer already has 5 addresses. |
| 404 | CUSTOMER_NOT_FOUND | Customer does not exist or is not linked to your merchant. |
| 409 | CUSTOMER_PHONE_DUPLICATE | A customer with this phone already exists for your merchant. |
| 409 | CUSTOMER_EMAIL_DUPLICATE | A customer with this email already exists for your merchant. |
| 409 | CUSTOMER_HAS_ORDERS | Customer has existing orders and cannot be deleted. |
See the full Error Reference.
