Charges
A charge starts the collection of a payment. Creating one persists an order, opens a payment attempt on the chosen channel, and returns a payer instruction telling you how the customer should pay.
The charge result
POST /api/v1/charges returns three objects plus an idempotency flag.
order
- Name
id- Type
- string
- Description
The fluxa order id, prefixed
ord_.
- Name
merchant_order_id- Type
- string
- Description
Your idempotency key for this order.
- Name
channel_code- Type
- string
- Description
The channel the charge was created on.
- Name
channel_name- Type
- string
- Description
Human-readable display name of that channel, resolved by the platform. Render this to people; keep
channel_codefor logic.
- Name
settlement_mode- Type
- string
- Description
Funds-flow mode stamped at creation:
direct(non-custodial direct settlement) orcustodial. External merchants always getdirect— the net settles on-chain straight to your own wallet;custodialis operator-internal. Immutable. See Settlement modes.
- Name
amount- Type
- string
- Description
The order amount, as a decimal string.
- Name
refunded_amount- Type
- string
- Description
Cumulative amount refunded so far.
0until a refund occurs.
- Name
currency- Type
- string
- Description
ISO currency / asset code, e.g.
USDorUSDT.
- Name
status- Type
- string
- Description
One of
created,pending,paid,expired,canceled,failed,refunded,partially_refunded.
- Name
is_test- Type
- boolean
- Description
truefor orders created with a test-mode key (never settles).
- Name
subject- Type
- string
- Description
Short description shown to the payer.
- Name
description- Type
- string
- Description
Longer free-text description.
- Name
metadata- Type
- object
- Description
The key/value object you attached at creation.
- Name
expires_at- Type
- timestamp
- Description
When an unpaid order expires, or
null.
- Name
paid_at- Type
- timestamp
- Description
When the order was paid, or
null.
- Name
created_at- Type
- timestamp
- Description
When the order was created.
instruction
The instruction tells the payer how to proceed. Its type selects which fields are populated.
- Name
type- Type
- string
- Description
redirect(send the payer toredirect_url),crypto_address(pay todeposit_address),client_secret(confirm client-side), ornone.
- Name
redirect_url- Type
- string
- Description
Hosted-checkout URL, for
redirectinstructions.
- Name
client_secret- Type
- string
- Description
Provider client secret, for
client_secretinstructions.
- Name
deposit_address- Type
- string
- Description
On-chain address to pay, for
crypto_addressinstructions.
- Name
chain- Type
- string
- Description
Chain code of the deposit address (e.g.
usdt_erc20).
- Name
asset- Type
- string
- Description
Asset to pay in (e.g.
USDT).
- Name
amount_due- Type
- string
- Description
Amount the payer must send.
- Name
required_confirmations- Type
- integer
- Description
On-chain confirmations required before the order is marked paid.
- Name
expires_at- Type
- timestamp
- Description
When the instruction expires, when applicable.
The result also includes a payment object (the attempt, with id, status, and crypto fields where relevant) and idempotent: true when an existing order was returned for a reused merchant_order_id.
Create a charge
Signed locally — your secret stays in this browser and is never sent or stored.
No keys yet? Create an API key pair in the merchant portal — the secret is shown only once. Open the merchant portal →
Create a charge on a channel. Idempotent on merchant_order_id: reusing a
value returns the existing order with idempotent: true instead of creating
a duplicate.
Required attributes
- Name
amount- Type
- string
- Description
The amount to collect, as a decimal string, e.g.
"49.90".
- Name
currency- Type
- string
- Description
The pricing currency / asset, e.g.
"USD"or"USDT".
Channel selection
Pass one of channel (explicit) or network (routed). With neither,
the request fails with channel_or_network_required.
- Name
channel- Type
- string
- Description
The channel
codeto charge on. List enabled channels via Channels. When set,networkis ignored.
- Name
network- Type
- string
- Description
Lowercase blockchain network label (
"tron","base","bsc","polygon","ethereum","arbitrum", …). fluxa routes (network,currency) to a channel. For external merchants this resolves to a self-hosted direct-settlement channel — the net settles on-chain to your own wallet. (A hosted custodial crypto gateway can sit behind the same routing as a fallback, but that path is operator-internal.) If no enabled channel collects the pair, the request fails withno_route.
Optional attributes
- Name
merchant_order_id- Type
- string
- Description
Your idempotency key. Strongly recommended so retries don't double-charge.
- Name
subject- Type
- string
- Description
Short description shown to the payer.
- Name
description- Type
- string
- Description
Longer free-text description.
- Name
metadata- Type
- object
- Description
Arbitrary key/value pairs stored with the order and echoed back.
- Name
return_url- Type
- string
- Description
Where to send the payer after a successful hosted checkout.
- Name
cancel_url- Type
- string
- Description
Where to send the payer if they cancel a hosted checkout.
- Name
expires_in_seconds- Type
- integer
- Description
Seconds until an unpaid order expires.
Request
// No channel: fluxa routes (network, currency) to an
// on-chain direct-settlement channel — the net settles
// straight to your own wallet.
const res = await pgFetch('POST', '/api/v1/charges', {
merchant_order_id: 'order-1002',
amount: '100',
currency: 'USDT',
network: 'tron',
})
const { order, instruction } = await res.json()
// instruction.type === 'crypto_address'
Response
{
"order": {
"id": "ord_2Zx9Qw8sUaM2",
"merchant_order_id": "order-1001",
"channel_code": "usdc_base",
"settlement_mode": "direct",
"amount": "100",
"refunded_amount": "0",
"currency": "USDC",
"status": "created",
"is_test": false,
"subject": "Pro plan",
"metadata": { "user_id": "u_42" },
"expires_at": null,
"paid_at": null,
"created_at": "2026-06-11T08:25:00Z"
},
"payment": {
"id": "pay_7K2mQ",
"order_id": "ord_2Zx9Qw8sUaM2",
"status": "initiated",
"amount": "100",
"currency": "USDC"
},
"instruction": {
"type": "crypto_address",
"deposit_address": "0x7a3b...c91e",
"amount_due": "100",
"chain": "usdc_base",
"asset": "USDC",
"required_confirmations": 12
},
"idempotent": false
}
For a live on-chain charge you must have a settlement address configured — the net amount
settles directly to your own address. Without one, fluxa refuses to create the charge. On-chain
orders also cannot be refunded through the platform or paid out (the funds never touch a
platform-held balance). See Settlement modes for the full funds-flow model
and the routing-specific error codes (no_route, channel_or_network_required,
payment_mode_disabled).