> ## Documentation Index
> Fetch the complete documentation index at: https://docs.splashpay.co.tz/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic TANQR

> Generate Bank of Tanzania compliant Dynamic TANQR codes for accepting instant payments.

# 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.

<Card title="Dynamic QR Payments" icon="qr-code">
  Generate a unique QR code for every payment and receive real-time payment notifications through webhooks.
</Card>

***

## Endpoint

```http theme={null}
POST /payments/dynamic-qr
```

***

## Base URL

<Tabs>
  <Tab title="Sandbox">
    ```bash theme={null}
    https://sandbox-api.splashpay.co.tz/api/v1
    ```

    Use this environment for development and testing.
  </Tab>

  <Tab title="Production">
    ```bash theme={null}
    https://api.splashpay.co.tz/api/v1
    ```

    Use this environment for live transactions.
  </Tab>
</Tabs>

***

# Request Body

| Field              | Type   | Required | Description               |
| ------------------ | ------ | :------: | ------------------------- |
| reference          | string |    Yes   | Unique merchant reference |
| buyer\_name        | string |    Yes   | Customer full name        |
| buyer\_email       | string |    Yes   | Customer email address    |
| buyer\_phone       | string |    Yes   | Customer phone number     |
| amount             | number |    Yes   | Payment amount            |
| currency           | string |    Yes   | Currency (`TZS`)          |
| billing\_firstname | string |    Yes   | Billing first name        |
| billing\_lastname  | string |    Yes   | Billing last name         |
| billing\_address   | string |    Yes   | Billing address           |
| billing\_city      | string |    Yes   | Billing city              |
| billing\_state     | string |    Yes   | Billing state             |
| billing\_postcode  | string |    Yes   | Billing postcode          |
| billing\_country   | string |    Yes   | ISO Country Code          |
| billing\_phone     | string |    Yes   | Billing phone number      |

***

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  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"
  }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.splashpay.co.tz/api/v1/payments/dynamic-qr',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-KEY': process.env.SPLASHPAY_KEY,
        'X-API-SECRET': process.env.SPLASHPAY_SECRET,
        'Idempotency-Key': crypto.randomUUID(),
      },
      body: JSON.stringify({
        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'
      }),
    }
  );

  const payment = await response.json();
  ```

  ```python Python theme={null}
  import uuid
  import requests

  response = requests.post(
      "https://api.splashpay.co.tz/api/v1/payments/dynamic-qr",
      headers={
          "Content-Type": "application/json",
          "X-API-KEY": "YOUR_API_KEY",
          "X-API-SECRET": "YOUR_API_SECRET",
          "Idempotency-Key": str(uuid.uuid4())
      },
      json={
          "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"
      }
  )

  print(response.json())
  ```
</CodeGroup>

***

# Successful Response

```json theme={null}
{
  "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:

```text theme={null}
data:image/png;base64,
```

Example

```html theme={null}
<img src="data:image/png;base64,{qr}" alt="SplashPay TANQR" />
```

# Payment Status

| Status     | Description                          |
| ---------- | ------------------------------------ |
| pending    | Waiting for customer to scan and pay |
| processing | Payment is being processed           |
| success    | Payment completed successfully       |
| failed     | Payment failed                       |
| cancelled  | Payment cancelled                    |
| expired    | QR code expired before payment       |

***

# Webhook Payload

```json theme={null}
{
  "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

```json theme={null}
{
  "status": "error",
  "code": "INVALID_REQUEST",
  "message": "The request payload is invalid."
}
```

## Authentication Failed

```json theme={null}
{
  "status": "error",
  "code": "UNAUTHORIZED",
  "message": "Invalid API credentials."
}
```

## Duplicate Request

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

***

# Best Practices

<Steps>
  <Step title="Generate a unique reference">
    Every QR payment should use a unique merchant reference.
  </Step>

  <Step title="Display the QR immediately">
    Render the Base64 image returned in the `qr` field to allow the customer to scan and pay.
  </Step>

  <Step title="Use Webhooks">
    Update transaction status using webhook notifications instead of polling.
  </Step>

  <Step title="Verify Payment Status">
    If a webhook is delayed, retrieve the latest transaction status using the Payment Status endpoint.
  </Step>

  <Step title="Use Idempotency Keys">
    Always include a unique `Idempotency-Key` when generating a Dynamic TANQR.
  </Step>
</Steps>

***

# Next Steps

<CardGroup cols={2}>
  <Card title="Payment Status" href="/collections/status" icon="circle-check">
    Retrieve the latest status of a QR payment.
  </Card>

  <Card title="Webhooks" href="/collections/webhooks" icon="webhook">
    Receive real-time payment notifications.
  </Card>
</CardGroup>
