Billing
Billing API
The Billing API lets apps charge merchants for services. All payments flow through the SeloraX platform, which handles payment collection and applies a fixed 10% commission + ~2.5% gateway fee. The developer chooses who pays these fees (fee_payer setting in the Developer Portal).
Charge amount limits: Minimum 10.00 BDT, maximum 50,000.00 BDT.
Charges
One-time charges for fixed-price services or purchases.
Create a Charge
Create a one-time charge that the merchant must approve.
POST /api/apps/v1/billing/charges
Authentication
Required. Must include valid app credentials.
Scope
billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Short name for the charge (shown to merchant) |
description | string | No | Longer description of what the charge is for |
amount | number | Yes | Charge amount (min: 10.00, max: 50,000.00) |
currency | string | No | Currency code (default: "BDT") |
return_url | string | Yes | URL to redirect the merchant after approval/decline |
metadata | object | No | Arbitrary key-value metadata attached to the charge |
idempotency_key | string | No | Unique key to prevent duplicate charges |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/billing/charges" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Premium Theme",
"description": "One-time purchase of the Starter Pro theme",
"amount": 1500.00,
"currency": "BDT",
"return_url": "https://myapp.com/billing/callback",
"metadata": { "theme_id": "starter-pro" },
"idempotency_key": "charge-theme-starter-pro-store-22"
}'Response
{
"message": "Charge created successfully",
"data": {
"charge_id": 45,
"app_id": 2,
"store_id": 22,
"installation_id": 2,
"name": "Premium Theme",
"description": "One-time purchase of the Starter Pro theme",
"amount": 1500.00,
"base_amount": 1500.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 150.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 37.50,
"developer_amount": 1312.50,
"status": "pending",
"confirmation_url": "https://admin.selorax.io/22/settings/apps/billing/45",
"return_url": "https://myapp.com/billing/callback",
"metadata": { "theme_id": "starter-pro" },
"created_at": "2025-06-15T12:00:00.000Z"
},
"status": 200
}After creation, redirect the merchant to confirmation_url so they can approve or decline the charge. Once the merchant completes payment, they are redirected back to your return_url with ?payment=success&charge_id=45 (or payment=cancelled / payment=failed).
Error Responses
| Code | Status | Meaning |
|---|---|---|
invalid_amount | 400 | Amount is below 10.00 or above 50,000.00 |
invalid_installation | 400 | App installation is inactive |
invalid_token | 401 | Token is expired or invalid |
insufficient_scope | 403 | App does not have billing scope |
Get a Charge
Retrieve details for a specific charge.
GET /api/apps/v1/billing/charges/:id
Authentication
Required. Must include valid app credentials.
Scope
billing
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | integer | The charge ID |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/billing/charges/45" \
-H "Authorization: Bearer <token>"Response
{
"message": "Charge fetched successfully",
"data": {
"charge_id": 45,
"app_id": 2,
"store_id": 22,
"installation_id": 2,
"name": "Premium Theme",
"description": "One-time purchase of the Starter Pro theme",
"amount": 1500.00,
"base_amount": 1500.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 150.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 37.50,
"developer_amount": 1312.50,
"status": "active",
"confirmation_url": "https://admin.selorax.io/22/settings/apps/billing/45",
"return_url": "https://myapp.com/billing/callback",
"metadata": { "theme_id": "starter-pro" },
"activated_at": "2025-06-15T12:05:00.000Z",
"created_at": "2025-06-15T12:00:00.000Z"
},
"status": 200
}Charge Statuses
| Status | Description |
|---|---|
pending | Charge created, awaiting merchant approval |
active | Merchant approved and payment collected |
declined | Merchant declined the charge |
cancelled | Charge was cancelled by the app, merchant, or system |
expired | Charge expired (48 hours without merchant action) |
Error Responses
| Code | Status | Meaning |
|---|---|---|
charge_not_found | 404 | Charge does not exist or does not belong to your app |
invalid_token | 401 | Token is expired or invalid |
List Charges
Retrieve all charges created by your app for the current store.
GET /api/apps/v1/billing/charges
Authentication
Required. Must include valid app credentials.
Scope
billing
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Items per page |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/billing/charges?page=1&limit=10" \
-H "Authorization: Bearer <token>"Response
{
"message": "Charges fetched successfully",
"data": [
{
"charge_id": 45,
"name": "Premium Theme",
"amount": 1500.00,
"base_amount": 1500.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 150.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 37.50,
"developer_amount": 1312.50,
"status": "active",
"created_at": "2025-06-15T12:00:00.000Z"
},
{
"charge_id": 40,
"name": "Setup Fee",
"amount": 500.00,
"base_amount": 500.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 50.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 12.50,
"developer_amount": 437.50,
"status": "pending",
"created_at": "2025-06-10T08:00:00.000Z"
}
],
"status": 200
}Subscriptions
Recurring charges billed on a monthly or yearly interval.
Create a Subscription
Create a recurring subscription charge.
POST /api/apps/v1/billing/subscriptions
Authentication
Required. Must include valid app credentials.
Scope
billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Subscription plan name |
description | string | No | Description of the subscription |
amount | number | Yes | Recurring charge amount (min: 10.00, max: 50,000.00) |
currency | string | No | Currency code (default: "BDT") |
billing_interval | string | Yes | Billing frequency: "monthly" or "yearly" |
trial_days | integer | No | Number of free trial days before first charge (default: 0) |
return_url | string | Yes | URL to redirect after approval/decline |
metadata | object | No | Arbitrary key-value metadata |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/billing/subscriptions" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Plan",
"description": "Unlimited messaging with priority support",
"amount": 999.00,
"currency": "BDT",
"billing_interval": "monthly",
"trial_days": 14,
"return_url": "https://myapp.com/billing/callback"
}'Response
{
"message": "Subscription created successfully",
"data": {
"charge_id": 46,
"app_id": 2,
"store_id": 22,
"installation_id": 2,
"name": "Pro Plan",
"description": "Unlimited messaging with priority support",
"amount": 999.00,
"base_amount": 999.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 99.90,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 24.98,
"developer_amount": 874.12,
"billing_interval": "monthly",
"trial_days": 14,
"trial_ends_at": "2025-06-29T12:00:00.000Z",
"status": "pending",
"confirmation_url": "https://admin.selorax.io/22/settings/apps/billing/46",
"return_url": "https://myapp.com/billing/callback",
"created_at": "2025-06-15T12:00:00.000Z"
},
"status": 200
}Error Responses
| Code | Status | Meaning |
|---|---|---|
invalid_amount | 400 | Amount is below 10.00 or above 50,000.00 |
invalid_installation | 400 | App installation is inactive |
insufficient_scope | 403 | App does not have billing scope |
Cancel a Charge
Cancel a pending or active charge (including recurring subscriptions). This endpoint is used by merchants from the dashboard.
POST /api/apps/billing/charges/:id/cancel
Authentication
Requires [auth, admin, storeOwnership] middleware and the apps__install_apps permission.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | integer | The charge ID to cancel |
Example Request
curl -X POST "https://api.selorax.io/api/apps/billing/charges/46/cancel" \
-H "Authorization: Bearer <merchant_token>"Response
{
"message": "Charge cancelled.",
"data": {
"charge_id": 46,
"status": "cancelled"
},
"status": 200
}Error Responses
| Code | Status | Meaning |
|---|---|---|
charge_not_found | 404 | Charge does not exist |
Usage Charges
Variable charges based on consumption. Usage charges are tied to an active subscription.
Create a Usage Charge
Record a usage-based charge. The total amount is calculated as quantity * unit_price.
POST /api/apps/v1/billing/usage-charges
Authentication
Required. Must include valid app credentials.
Scope
billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
description | string | Yes | Description of the usage (e.g. "50 SMS messages sent") |
quantity | number | Yes | Number of units consumed |
unit_price | number | Yes | Price per unit |
metadata | object | No | Arbitrary key-value metadata |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/billing/usage-charges" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "50 SMS messages sent in June 2025",
"quantity": 50,
"unit_price": 2.50,
"metadata": { "period": "2025-06" }
}'Response
{
"message": "Usage charge created successfully",
"data": {
"usage_charge_id": 12,
"app_id": 2,
"store_id": 22,
"description": "50 SMS messages sent in June 2025",
"quantity": 50,
"unit_price": 2.50,
"amount": 125.00,
"currency": "BDT",
"platform_amount": 12.50,
"developer_amount": 112.50,
"metadata": { "period": "2025-06" },
"created_at": "2025-07-01T00:00:00.000Z"
},
"status": 200
}List Usage Charges
Retrieve all usage charges for the current store.
GET /api/apps/v1/billing/usage-charges
Authentication
Required. Must include valid app credentials.
Scope
billing
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Items per page |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/billing/usage-charges?page=1&limit=10" \
-H "Authorization: Bearer <token>"Response
{
"message": "Usage charges fetched successfully",
"data": [
{
"usage_charge_id": 12,
"description": "50 SMS messages sent in June 2025",
"quantity": 50,
"unit_price": 2.50,
"amount": 125.00,
"created_at": "2025-07-01T00:00:00.000Z"
}
],
"status": 200
}Wallet
Store wallet operations. Each store has a wallet with a BDT balance that apps can read and debit.
Get Wallet Balance
Retrieve the current wallet balance for the authenticated store.
GET /api/apps/v1/billing/wallet
Authentication
Required. Must include valid app credentials.
Scope
billing
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/billing/wallet" \
-H "Authorization: Bearer <token>"Response
{
"message": "Wallet fetched successfully",
"data": {
"wallet_id": 10,
"store_id": 22,
"balance": 4500.00,
"currency": "BDT",
"total_topup": 10000.00,
"total_spent": 5500.00
},
"status": 200
}Response Fields
| Field | Type | Description |
|---|---|---|
wallet_id | integer | Unique wallet identifier |
store_id | integer | Store the wallet belongs to |
balance | number | Current available balance |
currency | string | Wallet currency (always "BDT") |
total_topup | number | Lifetime total top-ups |
total_spent | number | Lifetime total debits |
Debit Wallet
Deduct an amount from the store's wallet balance.
POST /api/apps/v1/billing/wallet/debit
Authentication
Required. Must include valid app credentials.
Scope
billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount to debit (min: 10.00, max: 50,000.00) |
description | string | Yes | Reason for the debit |
metadata | object | No | Arbitrary key-value metadata |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/billing/wallet/debit" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"amount": 125.00,
"description": "SMS usage for June 2025",
"metadata": { "period": "2025-06", "sms_count": 50 }
}'Response
{
"message": "Wallet debited successfully",
"data": {
"wallet_id": 10,
"balance": 4375.00,
"deducted": 125.00
},
"status": 200
}Error Responses
| Code | Status | Meaning |
|---|---|---|
insufficient_balance | 400 | Wallet balance is too low for the requested amount |
invalid_amount | 400 | Amount is below 10.00 or above 50,000.00 |
insufficient_scope | 403 | App does not have billing scope |
List Wallet Transactions
Retrieve a paginated list of wallet transactions.
GET /api/apps/v1/billing/wallet/transactions
Authentication
Required. Must include valid app credentials.
Scope
billing
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Items per page |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/billing/wallet/transactions?page=1&limit=20" \
-H "Authorization: Bearer <token>"Response
{
"message": "Transactions fetched successfully",
"data": [
{
"transaction_id": 88,
"wallet_id": 10,
"type": "deduction",
"amount": 125.00,
"balance_after": 4375.00,
"description": "SMS usage for June 2025",
"created_at": "2025-07-01T00:05:00.000Z"
},
{
"transaction_id": 85,
"wallet_id": 10,
"type": "topup",
"amount": 5000.00,
"balance_after": 4500.00,
"description": "Wallet top-up via EPS",
"created_at": "2025-06-25T10:00:00.000Z"
},
{
"transaction_id": 80,
"wallet_id": 10,
"type": "refund",
"amount": 500.00,
"balance_after": -500.00,
"description": "Refund for cancelled charge #40",
"created_at": "2025-06-20T15:00:00.000Z"
}
],
"status": 200
}Transaction Types
| Type | Description |
|---|---|
topup | Funds added to wallet |
deduction | Funds debited from wallet |
refund | Funds returned to wallet |
Create Wallet Top-Up
Create a charge to add funds to the store's wallet. The merchant must approve the payment.
POST /api/apps/v1/billing/wallet-topup
Authentication
Required. Must include valid app credentials.
Scope
billing
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Top-up amount (min: 10.00, max: 50,000.00) |
return_url | string | Yes | URL to redirect after payment |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/billing/wallet-topup" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000.00,
"return_url": "https://myapp.com/billing/wallet-callback"
}'Response
{
"message": "Wallet top-up charge created successfully",
"data": {
"charge_id": 50,
"type": "wallet_topup",
"amount": 5000.00,
"base_amount": 5000.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 500.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 125.00,
"developer_amount": 4375.00,
"status": "pending",
"confirmation_url": "https://admin.selorax.io/22/settings/apps/billing/50",
"return_url": "https://myapp.com/billing/wallet-callback",
"created_at": "2025-07-01T12:00:00.000Z"
},
"status": 200
}Error Responses
| Code | Status | Meaning |
|---|---|---|
invalid_amount | 400 | Amount is below 10.00 or above 50,000.00 |
invalid_installation | 400 | App installation is inactive |
insufficient_scope | 403 | App does not have billing scope |