Process Topup Order
Process a top-up order for a specific eSIM with automatic profit calculation.
Endpoint
POST /api/v1/business/topup/order
Authentication
This endpoint requires HMAC authentication. See Authentication for details.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| RT-AccessCode | String | Yes | Your API access code |
| RT-RequestID | String | Yes | Unique request ID (UUID v4) |
| RT-Timestamp | String | Yes | Request timestamp in milliseconds |
| RT-Signature | String | Yes | HMAC-SHA256 signature |
| Content-Type | String | Yes | application/json |
Request Body
Simply provide the ICCID and package code - everything else is handled automatically.
| Field | Type | Required | Description |
|---|---|---|---|
| iccid | String | Yes | eSIM ICCID to top up |
| packageCode | String | Yes | Package code from topup packages endpoint |
| quantity | Integer | No | Number of packages (default: 1) |
The API automatically handles:
- ✅ Package name lookup
- ✅ Price calculation with your custom markup
- ✅ Topup compatibility validation
Example Requests
Single Topup:
{
"iccid": "8943108170002570328",
"packageCode": "turkey-7days-1gb-topup"
}
Multiple Topups:
{
"iccid": "8943108170002570328",
"packageCode": "TOPUP_PLGJ7UB3C",
"quantity": 2
}
Response
Success Response (200 OK)
USD User Example:
{
"success": true,
"message": "eSIM top-up processed successfully",
"orderReference": "topup_1755559183090_vyf9w",
"iccid": "8943108170002570328",
"packageName": "Turkey 1GB 7Days",
"newBalance": 550.68,
"currency": "USD",
"status": "completed",
"amount": 2.45,
"profit": 0.23,
"processing_time_ms": 3724,
"esimData": {
"newTotalVolumeGB": 8.0,
"newRemainingVolumeGB": 8.0,
"expiredTime": "February 13, 2026 at 11:27 PM"
}
}
IQD User Example:
{
"success": true,
"message": "eSIM top-up processed successfully",
"orderReference": "topup_1755559183090_vyf9w",
"iccid": "8943108170002570328",
"packageName": "Iraq 1GB 7Days",
"newBalance": 726895,
"currency": "IQD",
"status": "completed",
"amount": 4856,
"profit": 456,
"processing_time_ms": 3724,
"esimData": {
"newTotalVolumeGB": 8.0,
"newRemainingVolumeGB": 8.0,
"expiredTime": "February 13, 2026 at 11:27 PM"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | Boolean | Operation success status |
| message | String | Success message |
| orderReference | String | Unique order reference for tracking |
| iccid | String | eSIM ICCID that was topped up |
| packageName | String | Name of the topup package applied |
| newBalance | Number | Your updated account balance in preferred currency |
| currency | String | Currency code (USD or IQD based on user preference) |
| status | String | Order status (always "completed" for successful orders) |
| amount | Number | Total amount charged in user's preferred currency |
| profit | Number | Your profit from this transaction in user's preferred currency |
| processing_time_ms | Integer | Processing time in milliseconds |
| esimData | Object | Updated eSIM information |
eSIM Data Object
| Field | Type | Description |
|---|---|---|
| newTotalVolumeGB | Number | New total data capacity in GB after topup |
| newRemainingVolumeGB | Number | New remaining data in GB (total - used) |
| expiredTime | String | Human-readable expiry date and time |
Error Responses
400 Bad Request
Missing required fields:
{
"success": false,
"message": "Missing required fields: iccid, packageCode",
"code": "MISSING_FIELDS"
}
eSIM not found:
{
"success": false,
"error": "eSIM not found or access denied",
"code": "ESIM_NOT_FOUND"
}
eSIM cannot be topped up:
{
"success": false,
"error": "eSIM cannot be topped up. Current status: EXPIRED",
"message": "Only ACTIVE, DEPLETED, or USED_EXPIRED eSIMs can be topped up",
"code": "ESIM_NOT_TOPPABLE"
}
Insufficient balance:
{
"success": false,
"error": "Insufficient balance",
"message": "Your current balance is $2.50. Required: $3.68",
"code": "INSUFFICIENT_BALANCE"
}
Invalid topup package:
{
"success": false,
"message": "Invalid top-up package code. Package not found.",
"code": "INVALID_TOPUP_PACKAGE"
}
Topup not supported:
{
"success": false,
"error": "Top-ups not available for this eSIM",
"code": "TOPUP_NOT_SUPPORTED"
}
401 Unauthorized
See Authentication documentation for authentication errors.
500 Internal Server Error
{
"success": false,
"error": "Failed to process topup order"
}
Examples
Basic Topup Order
// Simple - just iccid and packageCode
const orderData = {
iccid: '8943108170002570328',
packageCode: 'TOPUP_PLGJ7UB3C'
};
const response = await fetch(
'https://esimfly.net/api/v1/business/topup/order',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
...generateHMACHeaders() // Your HMAC function
},
body: JSON.stringify(orderData)
}
);
const result = await response.json();
if (result.success) {
console.log(`Topup successful! Order: ${result.orderReference}`);
console.log(`New balance: $${result.newBalance}`);
console.log(`Profit earned: $${result.profit}`);
console.log(`eSIM now has ${result.esimData.newTotalVolumeGB}GB total`);
}
Error Handling
try {
const response = await fetch(/* ... */);
const result = await response.json();
if (!result.success) {
switch (result.code) {
case 'INSUFFICIENT_BALANCE':
console.log('Need to add funds to account');
break;
case 'ESIM_NOT_TOPPABLE':
console.log('eSIM cannot be topped up in current state');
break;
case 'INVALID_TOPUP_PACKAGE':
console.log('Package not valid for this eSIM');
break;
default:
console.log('Topup failed:', result.error);
}
}
} catch (error) {
console.error('Request failed:', error);
}
Important Notes
Automatic Processing
- Balance deduction happens automatically upon successful topup
- Profit calculation is handled server-side using your account settings
- eSIM data is updated in real-time
Provider Compatibility
- Cross-provider topups are supported (e.g., topping up any eSIM with any compatible package)
- Provider detection is automatic based on package code format
- All provider-specific logic is handled transparently
Security & Validation
- Package prices are validated server-side to prevent manipulation
- Only eSIMs you own can be topped up
- Balance checks are performed before processing
- All transactions are logged and auditable
Best Practices
- Get packages first: Always call Get Topup Packages to get available options
- Use exact codes: Use the exact
package_codereturned from the packages endpoint - Handle errors gracefully: Always check for insufficient balance and eSIM status errors
- Store order reference: Keep
orderReferencefor customer support and tracking - Monitor profit: Track your earnings using the
profitfield in responses
Relationship to Other Endpoints
- Prerequisites: Get eSIMs to get ICCID, then Get Topup Packages
- Follow-up: Use Get Orders to track order history
- Account: Check Get Balance for current balance after topup
Legacy Integration Note
If you have an existing integration that sends additional fields like packageName or price, it will continue to work without any changes. The API is fully backward compatible.
For new integrations, we recommend using only iccid and packageCode (and optionally quantity) as shown in the examples above for simpler implementation.