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_code for logic.

  • Name
    settlement_mode
    Type
    string
    Description

    Funds-flow mode stamped at creation: direct (non-custodial direct settlement) or custodial. External merchants always get direct — the net settles on-chain straight to your own wallet; custodial is 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. 0 until a refund occurs.

  • Name
    currency
    Type
    string
    Description

    ISO currency / asset code, e.g. USD or USDT.

  • Name
    status
    Type
    string
    Description

    One of created, pending, paid, expired, canceled, failed, refunded, partially_refunded.

  • Name
    is_test
    Type
    boolean
    Description

    true for 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 to redirect_url), crypto_address (pay to deposit_address), client_secret (confirm client-side), or none.

  • Name
    redirect_url
    Type
    string
    Description

    Hosted-checkout URL, for redirect instructions.

  • Name
    client_secret
    Type
    string
    Description

    Provider client secret, for client_secret instructions.

  • Name
    deposit_address
    Type
    string
    Description

    On-chain address to pay, for crypto_address instructions.

  • 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.


POST/api/v1/charges

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 code to charge on. List enabled channels via Channels. When set, network is 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 with no_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

POST
/api/v1/charges
// 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
}