Skip to main content

Dynamic TANQR

The Dynamic TANQR API enables merchants to generate a unique QR code for every payment transaction. Customers can scan the QR code using any participating banking or mobile banking application that supports the Tanzania National QR (TANQR) standard. Unlike Static QR codes, Dynamic QR codes are generated per transaction and include the payment amount and transaction reference.

Dynamic QR Payments

Generate a unique QR code for every payment and receive real-time payment notifications through webhooks.

Endpoint

POST /payments/dynamic-qr

Base URL

https://sandbox-api.splashpay.co.tz/api/v1
Use this environment for development and testing.

Request Body

FieldTypeRequiredDescription
referencestringYesUnique merchant reference
buyer_namestringYesCustomer full name
buyer_emailstringYesCustomer email address
buyer_phonestringYesCustomer phone number
amountnumberYesPayment amount
currencystringYesCurrency (TZS)
billing_firstnamestringYesBilling first name
billing_lastnamestringYesBilling last name
billing_addressstringYesBilling address
billing_citystringYesBilling city
billing_statestringYesBilling state
billing_postcodestringYesBilling postcode
billing_countrystringYesISO Country Code
billing_phonestringYesBilling phone number

Example Request

curl --request POST \
  --url https://api.splashpay.co.tz/api/v1/payments/dynamic-qr \
  --header "Content-Type: application/json" \
  --header "X-API-KEY: pk_live_xxxxxxxxxxxxx" \
  --header "X-API-SECRET: sk_live_xxxxxxxxxxxxx" \
  --header "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  --data '{
    "reference":"CIR-6723e8ss6",
    "buyer_email":"john.doe@example.com",
    "buyer_name":"John Doe",
    "buyer_phone":"255744123456",
    "amount":1000,
    "currency":"TZS",
    "billing_firstname":"John",
    "billing_lastname":"Doe",
    "billing_address":"Bwawani, Mkonze",
    "billing_city":"Dodoma",
    "billing_state":"Tanzania",
    "billing_postcode":"67116",
    "billing_country":"TZ",
    "billing_phone":"255744123456"
}'

Successful Response

{
  "status": "success",
  "code": "PAYMENT_INITIATED",
  "message": "Payment initiated",
  "data": {
    "merchant_id": 2,
    "customer_name": "John Doe",
    "customer_email": "john.doe@example.com",
    "customer_phone": "255744123456",
    "reference": "CIR-6723e8ss6",
    "amount": "1000.00",
    "fee": 10,
    "net_amount": 990,
    "currency": "TZS",
    "source": "api",
    "payment_method": "tanqr",
    "provider": "selcom",
    "provider_reference": null,
    "qr": "iVBORw0KGgoAAAANSUhEUgAA...",
    "status": "pending",
    "metadata": null,
    "created_at": "2026-07-03T12:02:23Z",
    "processing_at": "2026-07-03T15:02:23Z"
  },
  "meta": [],
  "request_id": "a92e05fe-2156-4891-b659-5a9fcee3ee87"
}

QR Code

The qr field contains the generated QR code as a Base64-encoded PNG image. To display the QR code in a web browser, prepend the following prefix:
data:image/png;base64,
Example
<img src="data:image/png;base64,{qr}" alt="SplashPay TANQR" />

Payment Status

StatusDescription
pendingWaiting for customer to scan and pay
processingPayment is being processed
successPayment completed successfully
failedPayment failed
cancelledPayment cancelled
expiredQR code expired before payment

Webhook Payload

{
  "event": "payment.success",
  "created_at": "2026-07-03T15:04:30Z",
  "data": {
    "reference": "CIR-6723e8ss6",
    "amount": "1000.00",
    "fee": "10.00",
    "net_amount": "990.00",
    "currency": "TZS",
    "status": "success",
    "customer_name": "John Doe",
    "customer_email": "john.doe@example.com",
    "customer_phone": "255744123456",
    "payment_method": "tanqr",
    "provider": "selcom",
    "provider_reference": "1769142083",
    "metadata": null
  }
}

Error Responses

Invalid Request

{
  "status": "error",
  "code": "INVALID_REQUEST",
  "message": "The request payload is invalid."
}

Authentication Failed

{
  "status": "error",
  "code": "UNAUTHORIZED",
  "message": "Invalid API credentials."
}

Duplicate Request

{
  "status": "error",
  "code": "DUPLICATE_REQUEST",
  "message": "A request with this Idempotency-Key has already been processed."
}

Best Practices

1

Generate a unique reference

Every QR payment should use a unique merchant reference.
2

Display the QR immediately

Render the Base64 image returned in the qr field to allow the customer to scan and pay.
3

Use Webhooks

Update transaction status using webhook notifications instead of polling.
4

Verify Payment Status

If a webhook is delayed, retrieve the latest transaction status using the Payment Status endpoint.
5

Use Idempotency Keys

Always include a unique Idempotency-Key when generating a Dynamic TANQR.

Next Steps

Payment Status

Retrieve the latest status of a QR payment.

Webhooks

Receive real-time payment notifications.