Order
Handling Order Webhook Events
Overview
When a update for an order is received, our system triggers a webhook event. This event is sent as an HTTP POST request to the endpoint you have specified in the admin dashboard.
Setting Up the Webhook Endpoint
- Endpoint Configuration: Define the endpoint in the admin dashboard where webhook events will be sent.
- Security Measures: Ensure your endpoint is secure and can validate the authenticity of the webhook events received. Each request carries your secret token in the
Authorizationheader — validate it on every request and reject mismatches with401. The token is sent verbatim (noBearerprefix) and the body is not signed. See Authorization for the full details, including token rotation.
When you receive it
The ORDER webhook is sent every time an order changes — it is created, paid, delivered, cancelled, refunded, or its items change. Each call carries the full current state of the order, not just the change. The two moments that matter for the Integration flow:
| Moment | status | paymentStatus | Extra fields | What to do |
|---|---|---|---|---|
| Buyer paid | AWAITING_SHIPMENT | PAID | paidAt | Release / ship the goods. The money is held by Sevi; your wallet is not credited yet. |
| Delivery confirmed | DELIVERED | PAID | deliveredAt, deliveryConfirmedBy | Order complete. Your wallet is credited (you also get a TRANSACTION webhook). |
deliveryConfirmedBy tells you who confirmed the delivery:
| Value | Meaning |
|---|---|
SELLER | You, via orderDeliver or the seller dashboard |
BUYER | The buyer confirmed receipt in the Sevi app |
SEVI | Sevi staff confirmed it (e.g. after a support call) |
SYSTEM | Confirmed automatically, without a person involved |
A DELIVERED webhook for an order you have not called orderDeliver on is normal — the buyer confirmed first. You do not need to call orderDeliver afterwards (doing so is a harmless no-op).
paymentStatus: PAID means the buyer paid. You, the seller, are credited when the order is DELIVERED.
Order of delivery
Webhooks are sent asynchronously and retried on failure, so they can arrive out of order or more than once. Always use the status / paymentStatus in the payload as the current truth, ignore a payload that is "older" than what you already processed (e.g. AWAITING_SHIPMENT after DELIVERED), and use paidAt / deliveredAt for timestamps rather than the time you received the call.
Best Practices
- Logging: Keep logs of the webhook events for troubleshooting and auditing purposes.
- Idempotency: Ensure your webhook handling logic is idempotent to avoid duplicate processing in case of multiple event deliveries.
- Timely Processing: Process webhook events promptly to maintain up-to-date order status in your system.
- Return a 200/201 status: The webhook will retry up to 3 times with exponential backoff if a non-200/201 response is returned.
Payload Reference
The webhook sends a JSON body with two top-level keys: order and customer.
{
"order": { ... },
"customer": { ... }
}
order
Always present. Contains the order details and related information.
| Field | Type | Description |
|---|---|---|
id | string | Order ID |
referenceNumber | string | null | Unique order reference (e.g. ORD-123456) |
platformReference | string | null | External platform reference |
platformId | string | null | External platform ID |
vendorId | string | null | Vendor wallet account |
customerId | string | null | Customer wallet account |
status | string | null | PENDING, AWAITING_SHIPMENT, DELIVERED, ARCHIVED, CANCELLED, REFUNDED, RETURNED |
paymentStatus | string | PENDING, PARTIALLY_PAID, CREDIT_PROPOSAL_INITIATED, PAID, PARTIALLY_REFUNDED, REFUNDED |
paidAt | datetime | null | When the buyer's payment was completed (order became PAID) |
deliveredAt | datetime | null | When the order was marked DELIVERED. null unless status is DELIVERED |
deliveryConfirmedBy | string | null | Who confirmed the delivery: SELLER, BUYER, SEVI, SYSTEM. null unless status is DELIVERED |
paymentMethod | string | null | SEVI_PAY, SEVI_WALLET, etc. |
amount | number | Order amount |
originalAmount | number | Original amount before discount |
discount | number | Discount applied |
fixedVat | number | Fixed VAT amount |
percentageVat | number | Percentage VAT |
rewardAmount | number | Reward amount |
currency | string | null | KES, UGX, USD |
name | string | null | Order name / description |
phoneNumber | string | null | Customer phone number on the order |
notes | string | null | Order notes |
items | json | null | Order line items (shape varies by platform) |
ecommercePlatform | string | null | SEVI, WOOCOMMERCE, etc. |
creditConfigurationId | string | null | Credit configuration used |
paymentReferenceNumber | string | null | Payment workflow reference |
returnURL | string | null | Return URL after payment |
deliverDirect | boolean | null | Whether order is delivered directly |
createdByCustomer | boolean | null | Whether order was created by the customer |
createdAt | datetime | Creation timestamp |
approvedByVendor | datetime | null | When approved by vendor |
order.shipping
Shipping / delivery address. null if not provided.
| Field | Type | Description |
|---|---|---|
id | string | Shipping address ID |
firstName | string | null | First name |
lastName | string | null | Last name |
company | string | null | Company name |
address1 | string | null | Address line 1 |
address2 | string | null | Address line 2 |
landmark | string | null | Landmark |
city | string | null | City |
state | string | null | State / province |
postcode | string | null | Postal code |
country | string | null | Country code |
email | string | null | |
phoneNumber | string | null | Phone number |
longitude | string | null | GPS longitude |
latitude | string | null | GPS latitude |
shippingType | string | null | Shipping type |
shippingFee | number | null | Shipping fee |
isDefault | boolean | null | Whether this is the default address |
createdAt | datetime | null | Creation timestamp |
order.billing
Billing address. null if not provided.
| Field | Type | Description |
|---|---|---|
id | string | Billing address ID |
firstName | string | null | First name |
lastName | string | null | Last name |
company | string | null | Company name |
address1 | string | null | Address line 1 |
address2 | string | null | Address line 2 |
city | string | null | City |
state | string | null | State / province |
postcode | string | null | Postal code |
country | string | null | Country code |
email | string | null | |
phoneNumber | string | null | Phone number |
customer
Customer details as known by the vendor. null if the customer/vendor relationship is not found.
| Field | Type | Description |
|---|---|---|
name | string | null | Customer name |
email | string | null | Customer email |
reference | string | null | Customer reference in the vendor's system |
phoneNumbers | string[] | Customer phone numbers |
Full Example
{
"order": {
"id": "01234567-abcd-...",
"referenceNumber": "ORD-123456",
"platformReference": null,
"platformId": null,
"vendorId": "WAL-vendor-...",
"customerId": "WAL-buyer-...",
"status": "DELIVERED",
"paymentStatus": "PAID",
"paymentMethod": "SEVI_PAY",
"amount": 5000.00,
"originalAmount": 5000.00,
"discount": 0.00,
"fixedVat": 0.00,
"percentageVat": 0.00,
"rewardAmount": 0.00,
"currency": "KES",
"name": "Order for Widget",
"phoneNumber": "+254712345678",
"notes": null,
"items": [
{
"id": "...",
"name": "Widget",
"price": 5000,
"quantity": 1
}
],
"ecommercePlatform": "SEVI",
"creditConfigurationId": "01234567-...",
"paymentReferenceNumber": "wf-...",
"returnURL": null,
"deliverDirect": false,
"createdByCustomer": false,
"createdAt": "2025-01-15T09:00:00.000Z",
"approvedByVendor": "2025-01-15T09:05:00.000Z",
"paidAt": "2025-01-15T09:12:41.000Z",
"deliveredAt": "2025-01-16T14:03:10.000Z",
"deliveryConfirmedBy": "BUYER",
"shipping": {
"id": "01234567-abcd-...",
"firstName": "John",
"lastName": "Doe",
"company": null,
"address1": "123 Main St",
"address2": null,
"landmark": "Near the market",
"city": "Nairobi",
"state": "Nairobi",
"postcode": "00100",
"country": "KE",
"email": "john@example.com",
"phoneNumber": "+254712345678",
"longitude": "36.8219",
"latitude": "-1.2921",
"shippingType": null,
"shippingFee": null,
"isDefault": true,
"createdAt": "2024-08-01T00:00:00.000Z"
},
"billing": {
"id": "01234567-abcd-...",
"firstName": "John",
"lastName": "Doe",
"company": null,
"address1": "123 Main St",
"address2": null,
"city": "Nairobi",
"state": "Nairobi",
"postcode": "00100",
"country": "KE",
"email": "john@example.com",
"phoneNumber": "+254712345678"
}
},
"customer": {
"name": "John Doe",
"email": "john@example.com",
"reference": "CUS018082",
"phoneNumbers": ["+254712345678"]
}
}