Payments

A payment represents a single customer checkout. You create a payment server-side, redirect the customer to checkout_url, and NahuPay handles the method selection, USSD push, or bank redirect.

The payment object

{
  "id":           "pay_01hx9m2k4bw3zfjq",
  "object":       "payment",
  "amount":       50000,
  "currency":     "ETB",
  "status":       "completed",
  "method":       "telebirr",
  "checkout_url": "https://checkout.nahupay.com/pay/ch_abc123",
  "success_url":  "https://yourstore.com/success",
  "cancel_url":   "https://yourstore.com/cart",
  "metadata": {
    "order_id": "ORD-1234"
  },
  "created_at":   "2026-07-10T08:15:00Z",
  "expires_at":   "2026-07-10T08:45:00Z",
  "completed_at": "2026-07-10T08:17:32Z"
}

Fields

FieldTypeDescription
idstringUnique payment identifier. Prefix: pay_
objectstringAlways "payment"
amountintegerAmount in ETB cents. 50000 = 500.00 ETB
currencystringAlways "ETB" in current API version
statusstringpending | processing | completed | failed | expired | refunded
methodstring | nullPayment method used. null until the customer selects one
checkout_urlstringRedirect the customer here. Expires after 30 min
success_urlstringWhere NahuPay redirects after success
cancel_urlstringWhere NahuPay redirects if the customer cancels
metadataobjectUp to 20 key/value pairs you can attach for your own use
created_atISO 8601When the payment was created
expires_atISO 8601When the checkout URL expires
completed_atISO 8601 | nullWhen payment was confirmed

Create a payment

POST/v1/payments
curl https://api.nahupay.com/v1/payments \
  -H "Authorization: Bearer test_sk_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "amount":      50000,
    "currency":    "ETB",
    "methods":     ["telebirr", "bank_transfer"],
    "success_url": "https://yourstore.com/success",
    "cancel_url":  "https://yourstore.com/cart",
    "metadata":    { "order_id": "ORD-1234" }
  }'

Request parameters

ParameterRequiredTypeDescription
amountintegerPayment amount in ETB cents. Min: 100 (1 ETB).
currencystringMust be "ETB".
methodsarrayPayment methods to offer. At least one required.
success_urlstringHTTPS URL to redirect to after successful payment.
cancel_urlstringHTTPS URL to redirect to if the customer cancels.
metadataobjectUp to 20 key/value pairs. Values must be strings.
idempotency_keystringPass a unique string to safely retry failed requests.
expires_inintegerSeconds until the checkout expires. Default: 1800.

Retrieve a payment

GET/v1/payments/:id
curl https://api.nahupay.com/v1/payments/pay_01hx9m2k4bw3zfjq \
  -H "Authorization: Bearer test_sk_abc123"

Returns the full payment object. Use this to poll status before going live — in production, rely on webhooks instead.

List payments

GET/v1/payments
curl "https://api.nahupay.com/v1/payments?limit=20&status=completed" \
  -H "Authorization: Bearer test_sk_abc123"

Query parameters

ParameterDefaultDescription
limit10Number of results (1–100).
afterCursor from previous page's next_cursor.
statusFilter by status: pending | completed | failed | etc.
methodFilter by method: telebirr | mpesa | bank_transfer | etc.
created_gteISO 8601 timestamp — only payments created after this.
created_lteISO 8601 timestamp — only payments created before this.

Test scenarios

In sandbox mode, use these test phone numbers to trigger specific outcomes on TeleBirr USSD push:

Phone numberOutcome
0911 000 001Payment completes immediately
0911 000 002Payment fails — insufficient balance
0911 000 003Payment times out after 30 seconds
0911 000 004User cancels on USSD menu