Mobile: RANGED_VALUE_RECHARGE
Recharge a receiver's account within a range of values.
| Product Type | Service (ID) | Subservice (ID) |
|---|---|---|
| RANGED_VALUE_RECHARGE | Mobile (1) | Airtime (11) |
Disclaimer
Example field values in response JSON files are significant for format and type only. Do not interpret them as actual data; prices, for example, are invented and non-binding.
Example Product Retrieval
For full endpoint descriptions, see:
GET /products/11874{
"accepted_calculation_modes": [
"SOURCE_AMOUNT",
"DESTINATION_AMOUNT"
],
"availability_zones": [
"INTERNATIONAL"
],
"benefits": [
{
"additional_information": null,
"amount": {
"base": {
"max": 1000,
"min": 0.5
},
"promotion_bonus": {
"max": 0,
"min": 0
},
"total_excluding_tax": {
"max": 1000,
"min": 0.5
},
"total_including_tax": {
"max": 1000,
"min": 0.5
}
},
"type": "CREDITS",
"unit": "GHS",
"unit_type": "CURRENCY"
}
],
"description": "",
"destination": {
"amount": {
"increment": 0.01,
"max": 1000,
"min": 0.5
},
"unit": "GHS",
"unit_type": "CURRENCY"
},
"id": 11874,
"name": "Open_Range",
"operator": {
"country": {
"iso_code": "GHA",
"name": "Ghana",
"regions": null
},
"id": 1613,
"name": "Vodafone Ghana",
"regions": null
},
"prices": {
"retail": null,
"wholesale": {
"amount": {
"max": 65.1759317171309,
"min": 0.0325879658585655
},
"fee": 0,
"unit": "USD",
"unit_type": "CURRENCY"
}
},
"promotions": null,
"rates": {
"base": 15.036225400709,
"retail": null,
"wholesale": 15.3430871435806
},
"regions": null,
"required_additional_identifier_fields": null,
"required_beneficiary_fields": null,
"required_credit_party_identifier_fields": [
[
"mobile_number"
]
],
"required_debit_party_identifier_fields": null,
"required_sender_fields": null,
"required_statement_identifier_fields": null,
"service": {
"id": 1,
"name": "Mobile",
"subservice": {
"id": 11,
"name": "Airtime"
}
},
"source": {
"amount": {
"max": 66.5060527725826,
"min": 0.0332530263862913
},
"unit": "USD",
"unit_type": "CURRENCY"
},
"tags": [
"AIRTIME"
],
"type": "RANGED_VALUE_RECHARGE",
"validity": null
}Prices and Amounts for Ranged Value Products
For Ranged Value products, here's what you need to know about the amounts:
-
Source Amount (
source.amount): The amount in the customer's wallet currency (face value). -
Destination Amount (
destination.amount): The amount in the recipient's currency (face value). -
Retail Price (
prices.retail): The suggested selling price. Customers can choose to charge this or something else. -
Wholesale Price (
prices.wholesale.amount): The amount deducted from the customer's wallet when buying this product.
Customers must use the Wholesale Price (prices.wholesale.amount) for ranged products and can add a margin. If they don't want to calculate this, they can set a Retail Price (prices.retail) in the DT Shop Portal and use that price from the API response.
So, regardless of the Source Amount (source.amount) or Destination Amount (destination.amount), we recommend using the Retail Price (prices.retail) or the Wholesale Price (prices.wholesale.amount) plus a margin.
For Ranged products, we recommend setting auto_confirm to false. This way, customers can see the Retail Price (prices.retail) before confirming the transaction.
Required Fields - Pay Close Attention
The "required_*" fields indicate the additional data elements beyond the standard minimum payload that you must include in POST transaction requests for each corresponding party or identifier. These fields specify the necessary information for a particular product. If a field is listed as required, your transaction request will likely be unsuccessful if it is not included.
WarningThe example shown is for a particular product type delivered by a specific operator. Always, always check the
"required_*"configuration for the exact product and operator you are integrating with. When the value of a"required_*"field isnull, it means that no additional fields are necessary for that specific section beyond the base requirements for this product. Don't assume based on this one provided example that the field or fields listed are the only possibilities!
"required_additional_identifier_fields": null,
"required_beneficiary_fields": null,
"required_credit_party_identifier_fields": [
[
"mobile_number"
]
],
"required_debit_party_identifier_fields": null,
"required_sender_fields": null,
"required_statement_identifier_fields": null,
{
// ... other necessary fields from the minimum payload ...
"credit_party_identifier": {
"mobile_number": "+639173143100"
},
// ... other fields ...
}
Example Benefits: Airtime
The following code details the benefits associated with airtime top-ups. Specifically, users will find credit rewards applicable to these transactions. The total_excluding_tax field indicates the local currency amount received.
The discovery endpoints from which you can find the transactions showing the benefits are:
.
"benefits": [
{
"additional_information": "",
"amount": {
"base": {
"max": 1000,
"min": 0.5
},
"promotion_bonus": {
"max": 0,
"min": 0
},
"total_excluding_tax": {
"max": 1000,
"min": 0.5
},
"total_including_tax": {
"max": 1000,
"min": 0.5
}
},
"type": "CREDITS",
"unit": "GHS",
"unit_type": "CURRENCY"
}
]
Disclaimer
Example field values in response JSON files are significant for format and type only. Do not interpret them as actual data; prices, for example, are invented and non-binding.
To post a transaction, you use the POST: Create a transaction asynchronously endpoint.
Implementation Techniques
Technique 1: One-Step Transaction
Create and confirm the transaction in one step.
{
"external_id": "TEST-001",
"product_id": 11874,
"credit_party_identifier": {
"mobile_number": "+639173143100"
},
"calculation_mode":"DESTINATION_AMOUNT",
"destination": {
"unit_type":"CURRENCY",
"unit":"GHS",
"amount":3
},
"auto_confirm": true
}Explanation: By setting auto_confirm to true, the transaction is created and confirmed immediately.
Technique 2: Two-Step Transaction
Create the transaction, then confirm it separately. When auto_confirm is set to false (or not specified):
- A separate POST request to Confirm a transaction asynchronously is required.
- This allows for a delay between transaction creation and submission to DT One, useful for:
- Collecting payment.
- Verifying RANGED product type prices.
Important:
- The maximum time allowed between the CREATED (1) and CONFIRMED (2) statuses is 60 minutes.
- Transactions not confirmed within 60 minutes will be automatically canceled.
{
"external_id": "TEST-001",
"product_id": 11874,
"credit_party_identifier": {
"mobile_number": "+233173143100"
},
"calculation_mode":"DESTINATION_AMOUNT",
"destination": {
"unit_type":"CURRENCY",
"unit":"GHS",
"amount":3
},
"auto_confirm": false
}Statuses for Transactions
For even more detailed information, see Handling Transactions.
---
config:
theme: neutral
fontSize: 16
look: neo
layout: fixed
---
flowchart LR
B@{ label: "<b>CREATED</b><br><span style=\"font-size: 2em;\">1</span>" } -- "<span style=color:>POST<br>/transactions<br>/[id]<br>/confirm</span>" --> C@{ label: "<b>CONFIRMED</b><br><span style=\"font-size: 2em;\">2</span>" }
C -- "<span style=color:>Sent to<br>receiving<br>partner</span>" --> D@{ label: "<b>SUBMITTED</b><br><span style=\"font-size: 2em;\">5</span>" }
D --> E@{ label: "<b>COMPLETED</b><br><span style=\"font-size: 2em;\">7</span>" }
E -- "<span style=color:>Callback</span>" --> F@{ label: "<b>REVERSED</b><br><span style=\"font-size: 2em;\">8</span>" }
B -- "<span style=color:>Callback</span>" --> G@{ label: "<b>REJECTED</b><br><span style=\"font-size: 2em;\">3</span>" }
B -- "<span style=color:>Callback<br>POST<br>/transactions<br>/[id]<br>/cancel</span>" --> H@{ label: "<b>CANCELLED</b><br><span style=\"font-size: 2em;\">4</span>" }
D -- "<span style=color:>Callback</span>" --> I@{ label: "<b>DECLINED</b><br><span style=\"font-size: 2em;\">9</span>" }
B@{ shape: rounded}
C@{ shape: rounded}
D@{ shape: rounded}
E@{ shape: rounded}
F@{ shape: rounded}
G@{ shape: rounded}
H@{ shape: rounded}
I@{ shape: rounded}
style B fill:#FFFFFF,stroke:#1D8DF0,stroke-width:3px
style C fill:#FFFFFF,stroke:#1D8DF0,stroke-width:3px
style D fill:#FFFFFF,stroke:#1D8DF0,stroke-width:3px
style E fill:#FFFFFF,color:#000,stroke:#90ee90,stroke-width:3px
style F fill:#FFFFFF,stroke:black,stroke-width:3px
style G fill:#FFFFFF,stroke:#f08080,stroke-width:3px
style H fill:#FFFFFF,stroke:#f08080,stroke-width:3px
style I fill:#FFFFFF,stroke:#f08080,stroke-width:3px
A final status is a status after which there are no further statuses.
Only COMPLETED 7, REJECTED 3, CANCELLED 4, and DECLINED 9 are final statuses. SUBMITTED 5 and CONFIRMED 2 are NOT final statuses.
- Transaction reachesSUBMITTED 5 status.
- An immediate hold is placed on the initiator’s wallet for the wholesale price of the product.
- If Status changes toCOMPLETED 7
- The wholesale price is deducted from the wallet.
- If Status remainsSUBMITTED 5
- The balance remains on hold.
- If Status changes toREVERSED 8, REJECTED 3, or DECLINED 9
- The hold is released, and the wallet balance is adjusted accordingly.
Minimum Payload Request
{
"external_id": "TEST-0001",
"product_id": 11874,
"credit_party_identifier": {
"mobile_number": "+233173143100"
},
"auto_confirm": true,
"calculation_mode":"DESTINATION_AMOUNT",
"destination": {
"unit_type":"CURRENCY",
"unit":"GHS",
"amount":3
},
"callback_url": "https://testcallbackurl.com/"
}Field Descriptions:
| Field Path | Description | Example |
|---|---|---|
external_id | Unique ID per request generated from customer side. | “TEST-001" |
product_id | ID of the product to be purchased | 1732 |
credit_party_identifier[]. mobile_number | Mobile number to be recharged. | "+639173143100" |
auto_confirm | Specify if the transaction will be generated in one or two steps using the confirmation check. | true |
calculation_mode | Define if the amount sent by the customer will be based on Source_Amount (customer wallet currency) or Destination_Amount (destination corridor currency) | "DESTINATION_AMOUNT" |
destination[].unit_type | This will the the unit type, for example CURRENCY | “CURRENCY“ |
destination[].unit | Define the unit from the unit type, if currency, define the product currency | "GHS" |
destination[].amount | Amount to be recharge, chosen by the end user | “3” |
callback_url | Callback URL or Webhook provided by the customer, we will send status updates to this url. | "https://testcallbackurl.com/" |
Response for POST: Create a Transaction Asynchronously
{
"adjusted_values": {
"destination": {
"amount": 3,
"unit": "GHS",
"unit_type": "CURRENCY"
},
"source": {
"amount": 0.222565015403669,
"unit": "USD",
"unit_type": "CURRENCY"
}
},
"benefits": [
{
"additional_information": null,
"amount": {
"base": {
"max": 1000,
"min": 0.5
},
"promotion_bonus": {
"max": 0,
"min": 0
},
"total_excluding_tax": {
"max": 1000,
"min": 0.5
},
"total_including_tax": {
"max": 1000,
"min": 0.5
}
},
"type": "CREDITS",
"unit": "GHS",
"unit_type": "CURRENCY"
}
],
"callback_url": "https://testcallbackurl.com/",
"confirmation_date": "2025-04-03T22:40:39.363175000Z",
"confirmation_expiration_date": "2025-04-03T23:40:39.340710000Z",
"creation_date": "2025-04-03T22:40:39.340710000Z",
"credit_party_identifier": {
"mobile_number": "+233506343100"
},
"external_id": "TEST-000002",
"id": 2239242607,
"prices": {
"retail": null,
"wholesale": {
"amount": 0.209211114479448,
"fee": 0,
"unit": "USD",
"unit_type": "CURRENCY"
}
},
"product": {
"description": "",
"id": 11874,
"name": "Open_Range",
"operator": {
"country": {
"iso_code": "GHA",
"name": "Ghana",
"regions": [
{
"code": "GHA",
"name": "Ghana"
}
]
},
"id": 1613,
"name": "Vodafone Ghana",
"regions": null
},
"regions": null,
"service": {
"id": 1,
"name": "Mobile",
"subservice": {
"id": 11,
"name": "Airtime"
}
},
"tags": [
"AIRTIME"
],
"type": "RANGED_VALUE_RECHARGE"
},
"promotions": null,
"rates": {
"base": 13.479207388272,
"retail": null,
"wholesale": 14.3395823279489
},
"requested_values": {
"destination": {
"amount": 3,
"unit": "GHS",
"unit_type": "CURRENCY"
}
},
"status": {
"class": {
"id": 2,
"message": "CONFIRMED"
},
"id": 20000,
"message": "CONFIRMED"
}
}Descriptions of Important Fields:
| Field Path | Description | Example |
|---|---|---|
callback_url | Callback URL or Webhook provided by the customer, we will send status updates to this url. | "https://testcallbackurl.com/" |
confirmation_date | Date when the confirmation was sent. | "2025-03-31T17:34:01.570116000Z" |
confirmation_expiration_date | Date and time when the confirmation window expires (transaction is auto-canceled if not confirmed by then). | "2025-03-31T18:34:01.511496000Z" |
creation_date | Date and time when the transaction was created. | "2025-03-31T17:34:01.511496000Z" |
external_id | Unique ID per request generated from customer side. | "TEST-00001" |
id | Unique ID per request generated from DTone side. | 2239238836 |
status[].class[].id | Class Id for the current transaction | 2 |
status[].class[].message | Class description for the current transaction | CONFIRMED |
status[].id | Status Id for the current transaction | 20000 |
status[].message | Status Description for the current transaction | CONFIRMED |
Disclaimer
Example field values in response JSON files are significant for format and type only. Do not interpret them as actual data; prices, for example, are invented and non-binding.
Example Status Retrieval
Technique 1: Callback
Provide the callback_url (described in Step 2. Post Transactions) in the transaction request to receive asynchronous status updates.
Technique 2: Query the transaction using an ID
Use one of the following endpoints:
-
GET: Query a list of transactions
Can be used to look up the transaction using the External ID generated by the customer side (as well as to query a list).
-
GET: Query a transaction by ID
Look up the transaction using the Transaction ID that DT One generated.
Requests and Responses for "Get Final Status"
GET /transactions?external_id=TEST-00002GET /transactions/2239242607{
"adjusted_values": {
"destination": {
"amount": 3,
"unit": "GHS",
"unit_type": "CURRENCY"
},
"source": {
"amount": 0.222565015403669,
"unit": "USD",
"unit_type": "CURRENCY"
}
},
"benefits": [
{
"additional_information": null,
"amount": {
"base": {
"max": 1000,
"min": 0.5
},
"promotion_bonus": {
"max": 0,
"min": 0
},
"total_excluding_tax": {
"max": 1000,
"min": 0.5
},
"total_including_tax": {
"max": 1000,
"min": 0.5
}
},
"type": "CREDITS",
"unit": "GHS",
"unit_type": "CURRENCY"
}
],
"callback_url": "https://testcallbackurl.com/",
"confirmation_date": "2025-04-03T22:40:39.363175000Z",
"confirmation_expiration_date": "2025-04-03T23:40:39.340710000Z",
"creation_date": "2025-04-03T22:40:39.340710000Z",
"credit_party_identifier": {
"mobile_number": "+233506343100"
},
"external_id": "TEST-000002",
"id": 2239242607,
"operator_reference": "TX_2239242607",
"prices": {
"retail": null,
"wholesale": {
"amount": 0.209211114479448,
"fee": 0,
"unit": "USD",
"unit_type": "CURRENCY"
}
},
"product": {
"description": "",
"id": 11874,
"name": "Open_Range",
"operator": {
"country": {
"iso_code": "GHA",
"name": "Ghana",
"regions": [
{
"code": "GHA",
"name": "Ghana"
}
]
},
"id": 1613,
"name": "Vodafone Ghana",
"regions": null
},
"regions": null,
"service": {
"id": 1,
"name": "Mobile",
"subservice": {
"id": 11,
"name": "Airtime"
}
},
"tags": [
"AIRTIME"
],
"type": "RANGED_VALUE_RECHARGE"
},
"promotions": null,
"rates": {
"base": 13.479207388272,
"retail": null,
"wholesale": 14.339582327949
},
"requested_values": {
"destination": {
"amount": 3,
"unit": "GHS",
"unit_type": "CURRENCY"
}
},
"status": {
"class": {
"id": 7,
"message": "COMPLETED"
},
"id": 70000,
"message": "COMPLETED"
}
}Updated 26 days ago