Accept payment with Zebo Checkout
Create an order and redirect your customer to the invoice URL. Commerce handles the payment flow, OTP verification, and receipt generation.
Recommended approach. See Zebo Checkout for why this works better than custom checkout.
Step 1: Create an order
Call /orders/new with customer details and line items. Commerce generates invoice URLs automatically—one for web payment, one for PDF download. Store the order ID for status tracking.
Create order
curl https://api.zebo.dev/orders/new \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "order_inv_001",
"customer_data": {
"name": "Gloria Kesewaa",
"email_address": "gloria@example.com",
"phone_number": "+233544998605"
},
"line_items": [
{
"type": "product",
"product": {
"type": "physical",
"name": "Utility Sneakers",
"quantity": 1,
"price": { "currency": "ghs", "value": 20000 }
}
}
]
}'
Response
Partial response. See complete Order object.
{
"order": {
"id": "or_XyZ9kL2mQrTfVqYz1wNb",
"number": "INV-2025-001",
"status": "requires_payment",
"invoice": {
"id": "inv_AbC123XyZ",
"format": {
"web": {
"url": "https://checkout.zebo.dev/or_XyZ9kL2mQrTfVqYz1wNb"
},
"pdf": {
"url": "https://checkout.zebo.dev/or_XyZ9kL2mQrTfVqYz1wNb/pdf"
}
}
}
}
}
Step 2: Direct customer to payment
Choose how to get the customer to the payment page:
Extract invoice.format.web.url from the response and return it to your client. The client redirects immediately—customer lands on the payment page while they're still engaged. This works for in-app checkouts where the customer initiated the purchase.
// Server: Return URL to client
return {
invoiceURL: order.invoice.format.web.url,
}
// Client: Redirect to invoice
const response = await fetch('/api/create-order', { ... })
const { invoiceURL } = await response.json()
window.location.href = invoiceURL
Step 3: Track payment status
Use /orders/lookup to check payment status. Poll periodically or check when the customer returns to your app. When status becomes "paid", funds are in your Commerce balance.
Check status
curl https://api.zebo.dev/orders/lookup \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"order_id": "or_XyZ9kL2mQrTfVqYz1wNb"}'
Customization
Configure redirect and cancel URLs
{
"checkout_settings": {
"redirect_url": "https://yoursite.com/order/complete",
"cancel_url": "https://yoursite.com/order/cancelled"
}
}
Strongly recommended for a delightful customer experience. When payment completes, customers land on your redirect_url where you can show order confirmation and next steps. When customers abandon checkout without paying, they land on your cancel_url where you can show incomplete order details or offer alternative payment methods.
Set due date
{
"due_date": "2025-05-15T23:59:59Z"
}
Shows prominently on invoice. Order becomes "overdue" after this date but payment still works.
Add line item details
{
"product": {
"name": "Utility Sneakers",
"about": "Size: 42 | Color: Black"
}
}
Appears below product name on invoice.
Update branding
Change logo, business name, and colors in the Commerce dashboard under Settings → Branding. Applies to all new invoices instantly.
See Checkout customization for more options.
Common patterns
Subscriptions: Create new order each cycle, send new invoice URL.
Deposits: Create separate orders for deposit and balance. Link via reference field.
Multi-currency: Create one order per currency.
See Common patterns for implementation details.
Next steps
- Zebo Checkout — Why Zebo Checkout works better than custom checkout
- Orders — Complete order API reference
- Accept a payment — Build custom checkout (advanced)