Introduction

Badala provides your e-commerce store with REST API endpoints to complete checkout transactions.

For testing, you can use your Badala API test details provided on your business account dashboard.

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Base URL
https://Badala.africa/api

Not a developer?

Use our alternative plugins to get started with Badala.

Make a payment

Enable your customers to checkout with Badala by sending a JSON object and handle the response objects.


JSON OBJECT

Sends a request to initiate the payment transaction. Below are the parameters required to return a successful response


  • id string required

    A unique id referencing the transaction object. For example, the invoice or reference value. This value will be important for the return callback.

  • api_key string required

    Your api key which will be used to identify your store. Follow steps 1 - 18 to setup your api_key.

  • type string required

    The transaction method taking place.

  • currency string required

    At the moment, only South African Rands are supported.

  • total_amount float required

    Total amount used to checkout. This amount should be inclusive of any additional costs, such as shipping or discounts, etc.

  • items string required

    A short string of items bought by the online customer. **Used as reference.

  • return_method string required

    HTTP method that should be used to send PAYMENT RESPONSE back to the return_url. Choose between GET or POST.

  • return_url string required

    Callback url used to handle the response with the results from the transaction. The HTTP method provided in return_method will be used to send the PAYMENT RESPONSEto the return_url.

JSON OBJECT RESPONSE

Returns the result object from the initiating request, including the transaction id.


If "success": False, the message key will state the reason why the initiating request failed and the complete_payment_url key will have a blank string value.


If "success": True, use the complete_payment_url value as suggested below for the customer to complete the transaction.


  • complete_payment_url string

    On success and once you've handled the response, use this url to redirect users to complete the transaction on Badala. For example, window.location.href = complete_payment_url


PAYMENT RESPONSE

Returns the result object from the payment transaction, including the transaction id. This object will be sent to the return_url using the return_method provided.


If "success": False, the message key will state the reason why the payment transaction failed. A new initiating request would have to be created.


If "success": True, the payment would complete.

ENDPOINT URL
1
 POST /payment/ 
        
JSON OBJECT
{
    "id": "#1878567",
    "api_key": "Srtygo#4789gdfg398+dg",
    "type": "payment",
    "currency": "R",
    "total_amount": 290.50,
    "items": "Bucket hat, Sleeve less Tee",
    "return_method": "GET",
    "return_url": "https://your-domain.com/handle/response/"
}
JSON OBJECT RESPONSE
{
    "id": "#1878567",
    "success": True,
    "message": "Initiating payment request successful",
    "datetime": "2020-10-22T20:13:08.958619Z",
    "complete_payment_url": "https://airbuy.africa/api/payment/T29vaE0Nso/",
    "status_code": 200
}
PAYMENT RESPONSE
{
    "id": "#1878567",
    "success": True,
    "message": "Payment successful",
    "datetime": "2020-10-22T20:18:08.105378Z",
    "status_code": 200
}

Refunds

Retrieves a PaymentMethod object.

Parameters
  • id string required

    The unique id that was used to initiate the transaction.

  • api_key string required

    Your api key which will be used to identify your store. Follow steps 1 - 18 to setup your api_key.

  • type string required

    The transaction method taking place.

  • currency string required

    At the moment, only South African Rands are supported.

  • total_amount float required

    Total amount refundable inclusive of any additional costs.

  • reason string required

    A short reason for returning the goods.

Returns

Returns an object with the refund results.

ENDPOINT URL
1
 POST /refund/ 
        
JSON OBJECT
{
    "id": "#1878567",
    "api_key": "Srtygo#4789gdfg398+dg",
    "type": "refund",
    "currency": "R",
    "total_amount": 290.50,
    "reason": "Clothes didn't fit"
}
Response
{
    "id": "#1878567",
    "success": True,
    "message": "Refund successful",
    "datetime": "2020-10-26T10:56:14.3710522Z",
    "status_code": 200
}

Escrow API Overview

The Badala Escrow API enables secure payment processing between buyers and sellers. Funds are held safely in escrow until the transaction is completed, protecting both parties.

How Escrow Works:

  1. Create: Merchant creates an escrow account for an order
  2. Fund: Customer funds the escrow (via Paystack, Ozow, or wallet)
  3. Activate: Escrow becomes active once funded
  4. Release: Funds are released to merchant after order fulfillment

Authentication: All Escrow API requests require a valid JWT Bearer token in the Authorization header.

Escrow Base URL
https://api.airbuy.africa/escrow/api

Authorization Header
Authorization: Bearer <your-jwt-token>

Escrow Account Statuses

CREATED    - Escrow created, awaiting funding
FUNDED     - Funds received and held
ACTIVE     - Ready for operations
RELEASED   - Funds released to merchant
DISPUTED   - Under dispute, funds frozen
CANCELLED  - Cancelled, funds refunded
EXPIRED    - Expired without completion
        

Create Escrow Account

Create a new escrow account for a transaction between a buyer (payer) and seller (payee).


REQUEST BODY

All amounts should be sent as strings with two decimal places (e.g., "150.00").


  • payer_id string (UUID) required

    The unique identifier (UUID) of the buyer/consumer.

  • payee_id string (UUID) required

    The unique identifier (UUID) of the seller/merchant.

  • amount string required

    The escrow amount as a decimal string (e.g., "150.00").

  • currency string

    Currency code: ZAR, AIRBUCKS, or USD. Default: AIRBUCKS

  • external_transaction_id string

    Your unique transaction/order reference ID for tracking.

  • merchant_order_id string

    Optional merchant order reference.

  • expires_at string (ISO 8601)

    Escrow expiration datetime. Default: 7 days from creation.

  • terms string

    Optional terms and conditions for this escrow.

  • auto_release_enabled boolean

    Enable automatic release after delay. Default: true

  • auto_release_delay_hours integer

    Hours before auto-release (if enabled). Default: 24

Returns

Returns the created escrow account object with a unique account_number (e.g., ESC12345678) used for all subsequent operations.

ENDPOINT
 POST /accounts/ 
Request Body
{
  "payer_id": "550e8400-e29b-41d4-a716-446655440000",
  "payee_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "amount": "250.00",
  "currency": "ZAR",
  "external_transaction_id": "ORDER-2024-001234",
  "terms": "Release upon delivery confirmation"
}
Response (201 Created)
{
  "account_number": "ESC87654321",
  "status": "created",
  "amount": "250.00",
  "currency": "ZAR",
  "payer_id": "550e8400-e29b-41d4-a716-446655440000",
  "payee_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "external_transaction_id": "ORDER-2024-001234",
  "expires_at": "2024-01-22T10:30:00Z",
  "created_at": "2024-01-15T10:30:00Z"
}

Fund Escrow Account

Initiate payment to fund an escrow account. Supports Paystack, Ozow, or wallet payments.


REQUEST BODY

  • provider_code string

    Payment provider: PAYSTACK or OZOW. Default: PAYSTACK

  • email string required for Paystack

    Payer's email address (required for Paystack).

  • metadata object

    Optional metadata to include with the payment.

Returns

Returns a payment URL to redirect the customer to complete payment.

ENDPOINT
 POST /accounts/{account_number}/initiate_deposit/ 
Request Body
{
  "provider_code": "PAYSTACK",
  "email": "customer@example.com"
}
Response (200 OK)
{
  "authorization_url": "https://checkout.paystack.com/abc123",
  "reference": "PAY_REF_ABC123",
  "amount": "250.00",
  "currency": "ZAR"
}

Release Escrow Funds

Release funds from escrow to the merchant/payee. This action is typically triggered after order fulfillment.


NOTES
  • Escrow must be in ACTIVE or FUNDED status
  • Funds are transferred to merchant's wallet
  • Email notifications are sent to both parties
  • Status changes to RELEASED

Returns

Returns the updated escrow account with status: "released".

ENDPOINT
 POST /accounts/{account_number}/release/ 
Response (200 OK)
{
  "account_number": "ESC87654321",
  "status": "released",
  "amount": "250.00",
  "net_amount": "243.75",
  "released_at": "2024-01-16T14:22:00Z",
  "message": "Funds successfully released to merchant"
}

Check Escrow Status

Retrieve details and current status of an escrow account.

Returns

Returns the full escrow account object including balance information.

ENDPOINT
 GET /accounts/{account_number}/ 
Response (200 OK)
{
  "account_number": "ESC87654321",
  "status": "active",
  "amount": "250.00",
  "currency": "ZAR",
  "available_balance": "250.00",
  "held_balance": "0.00",
  "payer_id": "550e8400-e29b-41d4-a716-446655440000",
  "payee_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "external_transaction_id": "ORDER-2024-001234",
  "created_at": "2024-01-15T10:30:00Z",
  "funded_at": "2024-01-15T11:45:00Z",
  "expires_at": "2024-01-22T10:30:00Z"
}
Get Balance Only
 GET /accounts/{account_number}/balance/ 

Cancel Escrow & Refund

Cancel an escrow account and refund funds to the payer/buyer.


REQUEST BODY

  • reason string

    Optional reason for cancellation.


NOTES
  • Can only cancel escrows that haven't been released
  • Funds are refunded to payer's wallet
  • Status changes to CANCELLED

Returns

Returns the updated escrow account with status: "cancelled".

ENDPOINT
 POST /accounts/{account_number}/cancel/ 
Request Body
{
  "reason": "Order cancelled by customer"
}
Response (200 OK)
{
  "account_number": "ESC87654321",
  "status": "cancelled",
  "cancelled_at": "2024-01-15T16:00:00Z",
  "cancellation_reason": "Order cancelled by customer",
  "refund_status": "completed",
  "message": "Escrow cancelled and funds refunded"
}

Escrow Disputes

Create and manage disputes for escrow transactions. Disputes freeze the escrow funds until resolved.


CREATE DISPUTE - REQUEST BODY

  • reason string required

    Reason for the dispute.


DISPUTE TYPES
  • item_not_as_described - Product doesn't match listing
  • non_delivery - Order not delivered
  • quality_issue - Product quality complaint
  • other - Other dispute type

RESOLUTION OUTCOMES
  • refund_to_payer - Full refund to buyer
  • release_to_payee - Full release to seller
  • partial_refund - Split resolution
  • cancelled - Dispute cancelled

Returns

Returns the dispute object with status and resolution details.

ENDPOINTS
 POST /accounts/{account_number}/dispute/
 GET  /disputes/
 GET  /disputes/{id}/
Create Dispute Request
{
  "reason": "Item not received after 14 days"
}
Response (200 OK)
{
  "account_number": "ESC87654321",
  "status": "disputed",
  "dispute_reason": "Item not received after 14 days",
  "disputed_at": "2024-01-20T09:15:00Z",
  "message": "Dispute created. Funds are now frozen pending resolution."
}
List Disputes Response
{
  "count": 15,
  "next": "https://api.airbuy.africa/escrow/api/disputes/?page=2",
  "previous": null,
  "results": [
    {
      "id": "disp_abc123",
      "escrow_account": "ESC87654321",
      "status": "investigating",
      "dispute_type": "non_delivery",
      "disputed_amount": "250.00",
      "created_at": "2024-01-20T09:15:00Z"
    }
  ]
}

Request Status

Badala uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.). Codes in the 5xx range indicate an error with Badala's servers (these are rare).

HTTP status code summary
200 - OKEverything worked as expected.
400 - Bad RequestThe request was unacceptable, often due to missing a required parameter.
401 - UnauthorizedNo valid API key provided.
402 - Request FailedThe parameters were valid but the request failed.
403 - ForbiddenThe API key doesn't have permissions to perform the request.
404 - Not FoundThe requested resource doesn't exist.
409 - ConflictThe request conflicts with another request (perhaps due to using the same idempotent key).
429 - Too Many RequestsToo many requests hit the API too quickly. We recommend an exponential backoff of your requests.
500, 502, 503, 504 - Server ErrorsSomething went wrong on Badala's end. (These are rare.)