When using Reloadly’s AirTime API there are two ways of making a top-up:
The difference between a synchronous and an asynchronous operation lies in the fact that, when making a syncrhonous call the client won’t get a response until de server has finished processing the request, whereas in the asynchronous one the response is immediate, though the operation might not have even started yet.
In the case of an asynchronous operation, the moment to spawn the actions that must take place after the top-up has taken effect is not easy to determine.
The Reloadly API offers two ways for you to know when the time has come.
Via long-poll
One way to go about it is to have a process regularly asking Reloadly for the status of the operation.
To do this you’ll rely on this endpoint (https://docs.reloadly.com/airtime/top-ups/top-up-status).
Here’s how it’d go:
- Get the access token
- Make the request for an async top-up
- Make a request to get the status of the request. If the result obtained is:
PROCESSING
wait a little while and try againSUCCESSFUL
orREFUNDED
execute appropriate followup actions
This how you could do this through the CLI, assuming you’ve already got your access token:
curl --location --request POST https://topups.reloadly.com/topups-async --header 'Authorization: Bearer YOUR_TOKEN' --header 'Accept: application/com.reloadly.topups-v1+json' --header 'Content-Type: application/json' --data-raw '{ "operatorId":"YOUR_OPERATOR_ID", "amount":"10", "recipientPhone": { "countryCode": "YOUR_ISO_COUNTRY_CODE", "number": "YOUR_LOCAL_PHONE_NUMBER" } }
This request would result in something like:
{ "transactionId": 28805 }
Once you have the transactionId
you can followup to get a status update like this:
curl --location --request GET https://topups.reloadly.com/topups/28805/status --header 'Accept: application/com.reloadly.topups-v1+json' --header 'Authorization: Bearer YOUR_TOKEN'
Which will return something like:
{ "code": null, "message": null, "status": "SUCCESSFUL", "transaction": { "transactionId": 28805, "status": "SUCCESSFUL", "operatorTransactionId": null, "customIdentifier": null, "recipientPhone": "YOUR_LOCAL_PHONE_NUMBER", "recipientEmail": null, "senderPhone": null, "countryCode": "YOUR_COUNTRY_ISO_CODE", "operatorId": YOUR_OPERATOR_ID, "operatorName": "YOUR_OPERATOR_NAME", "discount": 0, "discountCurrencyCode": "EUR", "requestedAmount": 10, "requestedAmountCurrencyCode": "EUR", "deliveredAmount": 10, "deliveredAmountCurrencyCode": "EUR", "transactionDate": "2022-03-18 09:11:24", "pinDetail": null, "balanceInfo": { "oldBalance": 741.01448, "newBalance": 731.01448, "cost": 10, "currencyCode": "EUR", "currencyName": "Euro", "updatedAt": "2022-03-18 13:11:24" } } }
Via a webhook
Another, much better, approach is to let Reloadly make a callback upon operation end.
In this case you’ll have to:
- Create a public endpoint on your side, which can handle
POST
requests from Reloadly - Register your endpoint in your Reloadly Dashboard
- Make the originating request
This way, you’ll save a lot of resources since you won’t need to have a constantly running process issuing trivial requests to Reloadly’s servers.
Instead, your application will be the one receiving one request for every relevant event.
In a way, using this scheme you get the best of both worlds, sync and async.
Once you have your endpoint created, registering it in Reloadly is easy. Just follow this instructions.
The third point, making the originating request, is exactly the same as in the previous section, so let’s have a closer look at the endpoint itself.
How to create the public endpoint
This part can be as easy or complex as you want it to though a few basic items must be in place:
- A webserver to host your recipient application
- Public access to such server
- A URL within the webserver to be used as webhook target
Here’s a PHP example of what it might look like:
<?php http_response_code(400); logMessage("Got a callback from Reloadly".PHP_EOL); if ('POST' !== strtoupper($_SERVER['REQUEST_METHOD'])) { die('Only POST requests are acceptable'); } $postBody = file_get_contents('php://input'); logMessage("Post body = '$postBody'".PHP_EOL); try { $event = json_decode($postBody, true, 512, JSON_THROW_ON_ERROR); $eventType = $event['type']; logMessage("Event type = '$eventType'".PHP_EOL); switch ($eventType) { case 'airtime_transaction.status': http_response_code(200); $status = $event['data']['transaction']['status']; logMessage("Status = '$status'".PHP_EOL); doImportantStuff(); break; default: logMessage('Unsupported eventType '.$eventType); } echo json_encode(['received' => true]); } catch (\Exception $exception) { logMessage('POST body wasn\'t json'); } function logMessage(string $message): void { error_log(date('[Y-m-d H:i:s] - '.$message)); } function doImportantStuff() { // Fill in the blanks }
At the point of this writing the only available event you can expect from Reloadly is airtime_transaction.status
but that will most certainly change soon so keep this resource on your radar and, if you want to have a broader look at Reloadly’s webhooks here is where you should go next.
A couple of things to keep in mind when building your endpoint:
- The requests you’ll be receiving will be
POST
- The details of the event will be sent as json through the post body
- The structure of the post body is similar to:
{ "id": 1, "type": "airtime_transaction.status", "liveMode": false, "date": "2022-02-28 08:07:00", "data": { "code": null, "message": null, "status": "SUCCESSFUL", "transaction": { "transactionId": 1, "status": "SUCCESSFUL", "operatorTransactionId": null, "customIdentifier": null, "recipientPhone": "50936377111", "recipientEmail": null, "senderPhone": "13056154908", "countryCode": "HT", "operatorId": 173, "operatorName": "Digicel Haiti", "discount": 1.2, "discountCurrencyCode": "USD", "requestedAmount": 10, "requestedAmountCurrencyCode": "USD", "deliveredAmount": 1030.07, "deliveredAmountCurrencyCode": "HTG", "transactionDate": "2022-02-28 03:06:58", "pinDetail": null, "balanceInfo": { "oldBalance": 1000.00000, "newBalance": 991.20000, "currencyCode": "USD", "currencyName": "US Dollar", "updatedAt": "2022-02-28 08:06:58" } } } }
For more details read this article.