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

# Callbacks

> Receive payment collection notifications from Bpay on your server.

When a subscriber initiates a payment, Bpay POSTs transaction details to your configured callback URL. Your server must respond with **HTTP 200 OK** and a JSON acknowledgement.

See [Receive payment collection callback](/api-reference/payments-collection/receive-payment-collection-callback) for the interactive API reference, or use the [Bpay collection simulator](/api-reference/payments-collection/simulator) to test your endpoint.

***

## Callback flow

```text theme={null}
Subscriber pays via mobile money
        │
        ▼
Bpay receives payment
        │
        │ HTTP POST (JSON)
        ▼
Your callback URL
        │
        ▼
Your server returns accept/reject response
```

***

## Callback parameters

| Parameter           | Type   | Description                                                  |
| ------------------- | ------ | ------------------------------------------------------------ |
| `transaction_id`    | String | Unique transaction ID generated by Beem                      |
| `amount_collected`  | Number | Amount of money collected                                    |
| `source_currency`   | String | ISO currency code for sending (default: `TZS`)               |
| `target_currency`   | String | ISO currency code for receiving (default: `TZS`)             |
| `subscriber_msisdn` | String | Subscriber mobile number in international format without `+` |
| `reference_number`  | String | Reference number entered by the subscriber                   |
| `paybill_number`    | String | Merchant or paybill number the payment was received into     |
| `timestamp`         | String | Timestamp for the transaction                                |
| `mcc_network`       | Number | Mobile country code identifying the network                  |
| `mnc_network`       | Number | Mobile network code identifying the network                  |
| `network_name`      | String | Name of the carrier (e.g. `vodacom`)                         |

***

## Sample callback payload

```json theme={null}
{
  "transaction_id": "121w",
  "amount_collected": "4000",
  "source_currency": "TZS",
  "target_currency": "TZS",
  "subscriber_msisdn": "2557777777",
  "reference_number": "6cc545R",
  "paybill_number": "2233",
  "timestamp": "2",
  "mcc_network": "255",
  "mnc_network": "787",
  "network_name": "vodacom"
}
```

***

## Expected response

Respond with **HTTP 200 OK**:

```json theme={null}
{
  "transaction_id": "121@12",
  "successful": "true"
}
```

| Field            | Description                                              |
| ---------------- | -------------------------------------------------------- |
| `transaction_id` | Same transaction ID from the callback request            |
| `successful`     | `"true"` to accept the transaction; `"false"` to decline |

<Warning>
  If you return `successful: false`, the transaction is declined with the mobile network and funds are refunded to the subscriber.
</Warning>

***

## Sample implementations

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const express = require("express");
    const app = express();

    app.use(express.urlencoded({ extended: false }));
    app.use(express.json());

    app.post("/", (req, res) => {
      const {
        transaction_id,
        amount_collected,
        source_currency,
        target_currency,
        subscriber_msisdn,
        reference_number,
        paybill_number,
        timestamp,
        mcc_network,
        mnc_network,
        network_name,
      } = req.body;

      // Process the payment here

      res.json({
        transaction_id,
        successful: "true",
      });
    });

    app.listen(7000, () => console.log("app running on port 7000"));
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    <?php
    $data = file_get_contents('php://input');
    $data = json_decode($data, true);

    $transaction_id = $data['transaction_id'];
    $amount_collected = $data['amount_collected'];
    $subscriber_msisdn = $data['subscriber_msisdn'];
    $reference_number = $data['reference_number'];

    // Process the payment here

    $res = ['transaction_id' => $transaction_id, 'successful' => 'TRUE'];
    echo json_encode($res);
    ?>
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from flask import Flask, request, jsonify

    app = Flask(__name__)

    @app.route('/submit', methods=['POST'])
    def payment_callback():
        data = request.get_json()
        transaction_id = data['transaction_id']
        amount_collected = data['amount_collected']
        subscriber_msisdn = data['subscriber_msisdn']
        reference_number = data['reference_number']

        # Process the payment here

        return jsonify({
            'transaction_id': transaction_id,
            'successful': 'true',
        })

    if __name__ == '__main__':
        app.run(debug=True)
    ```
  </Tab>

  <Tab title="GitHub">
    [beem-pay-collect-api-sample — callback](https://github.com/beemafrica/beem-pay-collect-api-sample/tree/master/callback)
  </Tab>
</Tabs>
