Cancel an order
Orders that haven't reached completed status can be canceled at any point in the lifecycle—whether the customer changed their mind before paying, an item went out of stock, or a suspected fraudulent transaction needs to be voided immediately. This guide shows you when cancellation is appropriate, how to trigger it, and what to expect from the order and payment objects afterward.
Prerequisites
- A Commerce API key configured in your environment
- An order ID (
or_…) that you want to cancel - Familiarity with the order lifecycle
When to cancel
Cancellation is the right action when the order should never complete. Common cases:
- Customer request before payment — The customer abandoned the checkout or called in to withdraw. The order is in
requires_paymentand no money has moved yet. - Out-of-stock after order creation — You accepted the order but can't fulfill it. Cancel immediately to avoid the customer waiting on a payment that will never ship.
- Duplicate or fraudulent order — Your fraud detection flagged the transaction before it completed. Cancel with reason
"fraud"for your audit trail. - Timeout or expiry — You want to programmatically clean up stale orders that sat in
requires_paymentpast your SLA.
What cancellation does not cover: If the order has already reached completed status, you need a refund flow, not a cancellation. Cancellation is pre-completion only.
Cancel an order without refund
When the order has no captured payment—typically orders still in requires_payment before the customer confirms the OTP, or orders in preparing that were never paid—cancel without triggering a refund. Set execute_refund to false or omit it entirely.
Cancel order
curl https://api.zebo.dev/orders/cancel \
-H "Authorization: Bearer $SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"order_id": "or_kAVwBsk6EhQVv2YBUhYAqMf0lktEoQ0S7ZR8y2xi",
"reason": "customer_request"
}'
After a successful cancellation the order's status field becomes "canceled" and the payment (if one exists) transitions to "canceled" as well. The canceled_at timestamp is set on the payment object for your audit trail.
Cancel an order and refund the customer
If the customer's mobile money or card was already charged before you cancel, pass execute_refund: true. Commerce voids or reverses the payment in the same call—you don't need a separate refund API call.
Cancel with refund
curl https://api.zebo.dev/orders/cancel \
-H "Authorization: Bearer $SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"order_id": "or_kAVwBsk6EhQVv2YBUhYAqMf0lktEoQ0S7ZR8y2xi",
"reason": "inventory_unavailable",
"execute_refund": true
}'
Refund timing depends on the payment method. Mobile money reversals typically settle within minutes. Bank card reversals can take 5–10 business days depending on the issuing bank.
What happens after cancellation
Once canceled, an order cannot be reopened or modified. The cancellation is permanent. If the customer still wants to buy, create a new order.
The canceled order remains accessible via Lookup an order and Page through orders. It appears in your order history with status: "canceled" indefinitely—useful for customer service, auditing, and financial reconciliation.
Your balance is not affected by a cancellation unless a payment was already captured and you set execute_refund: true. In that case, a negative balance transaction is created for the refund amount, reducing your available balance by the refunded sum.
Related resources
- Cancel an order — API reference with all parameters
- The order lifecycle — Understand which statuses allow cancellation
- Lookup an order — Verify the order status after cancellation