Skip to main content

Botswana

The 54Pay Collections API enables merchants to accept payments through prepaid voucher systems in Botswana. This payment method digitizes cash for online transactions, functioning similarly to airtime vouchers but working like bank cards.

Key Characteristics

Unlike mobile money implementations in other markets, Botswana's voucher system operates through a validate-and-redeem workflow that processes prepaid voucher PINs instead of initiating real-time mobile money transfers.

Authentication

All API requests require the following HTTP headers:

HeaderTypeDescription
X-modulestringBase64(amount+transactionReference+customerNumber)
X-businessstringBase64-encoded Merchant Public Key: {Base64(Merchant Public Key)}
Content-TypestringMust be application/json
x-appstringMust be api

Integration Methods

The API supports two distinct integration methods determined by the requestType passed in the request header. You must choose the method that best aligns with your business logic:

  • Integration Method A ("requestType": "A") — Strict Validation: The voucher amount is strictly validated against the transactionAmount passed in your API request. If the requested transactionAmount does not exactly match the actual value of the prepaid voucher, the transaction will be rejected.
  • Integration Method B ("requestType": "B") — Flexible Processing: The voucher will be processed and redeemed for its actual underlying value, regardless of the transactionAmount passed in your API request.
Critical for Method B

Because the redeemed amount may differ from the requested amount, you must use the amount_received field in the asynchronous webhook payload to determine the actual value to credit the customer. Failing to do so may result in giving the customer more value than the voucher is worth.

Initiate Collection

Processes a payment transaction using a prepaid voucher PIN.

Endpoint: POST https://subsidiary.dev.mypaygate.co/collection/v1/payin

Sample Request

curl --location 'https://subsidiary.dev.mypaygate.co/collection/v1/payin' --header 'X-module: MTBUWE40MjkwNTU3ODIyMDc3MDAwMDA=' --header 'X-business: {Base64(Merchant Public Key)}' --header 'Content-Type: application/json' --header 'X-app: api' --data-raw '{
"requestHeader": {
"clientId": "",
"requestType": "A"
},
"customerName": "Ayo Akin",
"customerEmail": "user@gmail.com",
"customerNumber": "26772345684",
"voucherPin": "1234567890123456",
"transactionReference": "TXN50518093",
"transactionDescription": "Test",
"transactionAmount": 100,
"transactionCurrency": "BWP",
"transactionCountry": "BW",
"successUrl": "",
"errorUrl": "",
"cancelUrl": "",
"operatorCode": "BWVCH",
"webhookUrl": ""
}'

note

Set "requestType": "A" or "requestType": "B" depending on your preferred integration method.

Success Response Example

{
"responseDetails": {
"responseCode": "00",
"responseMessage": "COMPLETED"
},
"transactionReference": "TXN50518093",
"otpIsRequired": false,
"lengthOfOtp": 0,
"paymentCompletionRequired": false
}

Error Response Examples

Invalid Voucher:
{
"responseDetails": {
"responseCode": "06",
"responseMessage": "FAILED",
"failedReason": "Invalid Voucher",
"voucherPurchaseWebsite": "https://www.paybills.co.bw/#/OTT"
},
"transactionReference": "TXN_20241215_001"
}


Amount Mismatch (only when using requestType: A):
{
"responseDetails": {
"responseCode": "06",
"responseMessage": "FAILED",
"failedReason": "Voucher value does not match transaction amount",
"voucherPurchaseWebsite": "https://www.paybills.co.bw/#/OTT"
},
"transactionReference": "TXN_20241215_001"
}

Expired Voucher:
{
"responseDetails": {
"responseCode": "06",
"responseMessage": "FAILED",
"failedReason": "VOUCHER EXPIRED",
"voucherPurchaseWebsite": "https://ottbotswana.com/vouchers"
},
"transactionReference": "TXN_20241215_001"
}

Test Voucher PINs

Voucher PINAmount (BWP)Expected Behavior
1234567890123456100Returns successful response
1111111111111111100Always returns "Invalid Voucher" error
botswana - voucher

Webhooks

Important: Value Crediting and amount_received

The amount_received field in the webhook payload represents the actual, real-world value of the remitted voucher — not the transactionAmount sent in your original API request.

If you are using Integration Method B (requestType: B): It is absolutely critical that you always use the amount_received field from the webhook payload to validate and credit the customer's account. Using the original request amount can result in crediting the customer with more value than the physical voucher was worth.

Payment Status Webhook

Implement webhook handlers to receive asynchronous transaction status updates.

Sample Webhooks - Success


{
"transaction_reference": "PG-C-176590537521970",
"transaction_status": "Funds Received",
"transaction_fee": 5,
"amount_received": 100,
"initiated_date": "2025-12-16 18:16:15",
"current_status_date": "2025-12-16 18:16:15",
"received_from": {},
"merchant_reference": "TXN50518093",
"status": "COMPLETED",
"currency_code": "BWP"
}

Sample Webhooks - Failed


{
"transaction_reference": "PG-C-176587434198385",
"transaction_status": "Transaction Failed",
"transaction_fee": 0,
"amount_received": 100,
"initiated_date": "2025-12-16 09:39:01",
"current_status_date": "2025-12-16 09:39:02",
"received_from": {},
"merchant_reference": "TXN15414935",
"status": "FAILED",
"currency_code": "BWP",
"failure_reason": "Invalid Voucher"
}

Webhook Status Values

StatusDescription
COMPLETEDPayment successfully received and voucher redeemed.
FAILEDPayment failed, voucher invalid, or voucher expired.

Webhook Implementation

Your webhook endpoint must:

  1. Accept POST requests: Listen for incoming webhook notifications.
  2. Validate payload: Verify merchant_reference matches your internal records.
  3. Return 200 OK: Respond within 5 seconds to acknowledge receipt.
  4. Process asynchronously: Handle your business logic (like crediting the user based on amount_received) after responding with a 200 OK.
  5. Handle duplicates: Implement idempotency checks using transaction_reference.

Webhook Security

To ensure webhook authenticity:

  • Verify requests originate strictly from 54Pay IP addresses.
  • Validate that the merchant_reference exists and is pending in your system.
  • Store webhook payloads for a historical audit trail.