Products · Gateway

Acceptance Gateway

Waafi · CAC · SabaPay · D-Money · East Africa Bank — every Djiboutian payment rail through a single PaymentIntents API, one webhook signature, one dashboard.

5 live railspi_

Supported providers

Provider valueRailCountryFlow
waafiWaafipay mobile walletDjiboutiOTP push
cacCAC International Bank account debitDjiboutiRedirect
sabapaySaba African Bank PayMe + FundTransferDjiboutiUSSD push
dmoneyDjibouti Telecom D-Money USSD walletDjiboutiOTP push
eabEast Africa Bank account debitDjiboutiRedirect
mockDeterministic sandbox stubsSandboxAll flows

How it works

  1. 1

    Create a PaymentIntent

    POST to /v1/payment_intents with provider, amount (integer minor units), currency, and the customer contact — customer_msisdn for mobile-money rails or customer_account for bank rails. Include an Idempotency-Key equal to your order ID.
  2. 2

    Handle next_action

    Inspect next_action.type in the response. Collect an OTP from the customer (Waafi, D-Money), redirect to the bank portal URL (CAC, EAB), or surface the USSD code string (SabaPay). See provider-specific shapes below.
  3. 3

    Confirm with OTP or wait for redirect callback

    For OTP rails, POST the code to /v1/payment_intents/{id}/confirm. For redirect-based rails, MerasPay receives the bank callback and transitions the intent — no confirm call needed.
  4. 4

    Receive the webhook

    Listen for payment_intent.succeeded on your registered webhook endpoint. This is the authoritative signal to fulfil the order — the synchronous response may still show processing while the rail settles.
  5. 5

    Refund if needed

    POST to /v1/refunds with payment_intent_id and an optional partial amount. Refunds are settled back to the originating rail.

Endpoints

POST/v1/payment_intents

Create a PaymentIntent on any domestic rail.

POST/v1/payment_intents/{id}/confirm

Submit OTP or acknowledge redirect return.

POST/v1/refunds

Initiate a full or partial refund.

Full parameter reference → Payment Intents API

Provider-specific next_action shapes

waafi · dmoney

{
  "type": "collect_otp",
  "otp_length": 6
}

Prompt the customer to enter the OTP sent to their mobile number, then call confirm.

cac · eab

{
  "type": "redirect",
  "redirect_url": "https://..."
}

Redirect the customer to the bank portal. MerasPay receives the callback and updates the intent automatically.

sabapay

{
  "type": "ussd_push",
  "ussd_code": "*801*..."
}

Display the USSD string to the customer. They dial it on their handset to approve the debit.

Example — Waafi payment

1. Create intentbash
curl -X POST https://api.merashub.com/v1/payment_intents \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: order_1042" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "DJF",
    "provider": "waafi",
    "customer_msisdn": "+25377xxxxxxx",
    "description": "Order #1042"
  }'
Response — requires_actionjson
{
  "id": "pi_01J2KM9FXVZB3RN4TQ8E7PW6AC",
  "status": "requires_action",
  "next_action": {
    "type": "collect_otp",
    "otp_length": 6
  },
  "amount_minor": 15000,
  "currency": "DJF",
  "provider": "waafi",
  "created_at": "2026-05-25T09:00:00Z"
}
2. Confirm with OTPbash
curl -X POST https://api.merashub.com/v1/payment_intents/pi_01J2KM9FXVZB3RN4TQ8E7PW6AC/confirm \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{ "otp": "847231" }'
Response — succeededjson
{
  "id": "pi_01J2KM9FXVZB3RN4TQ8E7PW6AC",
  "status": "succeeded",
  "amount_minor": 15000,
  "currency": "DJF",
  "provider": "waafi",
  "succeeded_at": "2026-05-25T09:00:14Z"
}

Automatic provider routing

Provider routing is automatic when you pass provider. Use POST /v1/routing/rules to configure fallback chains — for example, fall back from Waafi to D-Money if the Waafi rail is degraded.

Go-live checklist

  • KYC approved and merchant account in live environment.
  • Live API keys issued from the dashboard (Settings → API Keys).
  • Webhook endpoint registered and HMAC signature verified end-to-end.
  • Idempotency-Key on every create call — use your order or transaction ID.
  • Sandbox tests passing for every provider you plan to use in production.