Skip to content

Quickstart

You will mint a session token from your merchant backend, then use it to start a payment. By the end you will have a transaction_id and a pending status from the sandbox gateway.

This page is the same flow in three stacks. Pick the tab that matches yours.

Your merchant backend does this. The session token is bound to the amount, currency, and customer_reference you pass.

Terminal window
curl https://app.api.gtwy.pdirect.com/api/v1/internal/sessions/create \
-X POST \
-H "Authorization: Bearer mch_3f9a2e1b:sk_test_x8a3pqr2zv9b1n4wmd6t7k0c8jh5y2u" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7c2e9a1d-4b6f-4c8e-9a5f-1d3e2c7b9a4d" \
-d '{
"amount": "12.50",
"currency": "usd",
"customer_reference": "cust_abc123",
"ttl_seconds": 1800
}'

You get back, exactly once:

{
"session_id": "607f1f77bcf86cd799439011",
"session_token": "sess_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789",
"issued_at": "2026-05-05T10:15:00Z",
"expires_at": "2026-05-05T10:45:00Z"
}

Hand the session_token to your client. Do not log it.

Terminal window
curl https://app.api.gtwy.pdirect.com/api/v1/payments/collect \
-X POST \
-H "Authorization: Bearer sess_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8d3f0e2b-5c7d-4e9f-aab2-2e4f3d8c0b6e" \
-d '{
"payment_method": "wallet",
"user_info": "full",
"payment_method_info": "full",
"fee_covered_by": "buyer",
"delivery_behaviour": "direct_delivery",
"notify_url": "https://merchant.example.com/pdirect/webhook",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_number": "+243998857000",
"wallet_number": "3005710720108954",
"wallet_pin": "048698"
}'

amount, currency, and customer_reference are bound to the session — omit them from this body. (They’re still accepted for backwards compat; drift from the session binding is a 400.)

The gateway responds with a transaction ID and a pending status:

{
"success": true,
"transaction_id": "txn_8f3a4c2e9b1d7a6f5c0e8d",
"status": "pending",
"message": "Payment request received",
"amount": "12.50",
"currency": "usd",
"fee_amount": "0.50",
"total_amount": "13.00",
"created_at": "2026-05-05T10:15:00Z"
}

Sandbox wallet payments using +243998857000 and the test PIN above will move to approved within a few seconds.

  1. Your backend authenticated to the gateway with Authorization: Bearer <key_id>:<merchant_secret> and declared (amount, currency, customer_reference) for this checkout.
  2. The gateway minted a session_token bound to those values, with a 30-minute TTL.
  3. Your client presented the session_token and submitted a matching payment body. The gateway accepted because the bound values matched.
  4. The gateway forwarded to the underlying processor and returned a transaction_id you can poll with GET /payments/status/{transaction_id} or wait for a webhook on your notify_url.
  • Receive the result. Set up a webhook endpoint to receive asynchronous status updates. See Webhooks.
  • Handle errors. Read the Errors page to recognise the four-digit code system.
  • Go beyond wallet. Card payments, mobile money, and B2C payouts follow the same mint session → submit body → poll or webhook pattern.
  • Read the SDK reference. Flutter / Angular.