Skip to content

Deposits and invoices

Use an invoice for one order with a fixed price. Use a deposit for a customer balance that can be topped up repeatedly.

Terminal window
curl -X POST 'https://platform.invoise.me/api/v1/shops/{shop_id}/invoices' \
-H 'Authorization: Bearer ivk_...' \
-H 'Idempotency-Key: <saved-unique-key>' \
-H 'Content-Type: application/json' \
-d "{\"chain_id\":${CHAIN_ID:?},\"token\":\"${TOKEN_ADDRESS:?}\",\"amount\":\"${AMOUNT:?}\",\"external_id\":\"order-123\"}"

Replace {shop_id} with your shop ID. Set CHAIN_ID and TOKEN_ADDRESS from the API response and AMOUNT in the selected token’s smallest units. external_id links the invoice to an order in your system; it does not replace the idempotency key.

The response is 202 Accepted. Save its id and poll the issuance endpoint until address is available. Then give the payer the returned payment_url.

Partial payments add up. Once enough confirmed money arrives, Invoise schedules the payout and closes the invoice. The recipient gets the invoice amount minus the service fee. Any overpayment goes to Invoise, not to the recipient.

Invoices are one-time payments; they do not renew automatically.

An invoice stays open for 30 days by default. To choose another lifetime, add expires_in to the request body, for example "expires_in":"7d". Allowed values are 1d, 7d, 30d, 180d and 365d.

Invoice responses, including the public checkout, carry expires_at. When that time passes, an unpaid invoice closes: cancelled_at is set and the invoice.cancelled webhook is sent with data.reason set to expired. A payment that arrives later is still recorded and can still settle, as with a cancelled invoice.

Deposits do not expire. Sending expires_in when creating a deposit returns 400 invalid_expires_in.

Use the same request headers with this endpoint and body:

Terminal window
curl -X POST 'https://platform.invoise.me/api/v1/shops/{shop_id}/deposits' \
-H 'Authorization: Bearer ivk_...' \
-H 'Idempotency-Key: <saved-unique-key>' \
-H 'Content-Type: application/json' \
-d "{\"chain_id\":${CHAIN_ID:?},\"token\":\"${TOKEN_ADDRESS:?}\",\"external_id\":\"customer-123\"}"

Do not set a fixed amount. Wait for the address in the same way as an invoice. The address can receive repeated top-ups in the chosen token and network.

Small deposits accumulate until they reach the shop’s payout threshold. Read it from GET /api/v1/shops/{shop_id}/terms.

Send assets instead of chain_id and token to let the payer choose how to pay. It works for invoices and deposits:

Terminal window
curl -X POST 'https://platform.invoise.me/api/v1/shops/{shop_id}/invoices' \
-H 'Authorization: Bearer ivk_...' \
-H 'Idempotency-Key: <saved-unique-key>' \
-H 'Content-Type: application/json' \
-d '{"assets":[{"chain_id":<chain-id>,"token":"<token-address>"},{"chain_id":<other-chain-id>,"token":"<other-token-address>"}],"amount":"10.5","external_id":"order-124"}'

With assets, the invoice amount is a decimal token amount, such as "10.5", not base units: the tokens can have different decimals. Each option must reach its network’s minimum_payment.

The response is a group. Each option is a separate invoice or deposit address with its own address, amount in base units and status:

{
"id": "<group-id>",
"group": true,
"shop_id": "<shop-id>",
"public_id": "<public-id>",
"status": "registering",
"payment_url": "https://pay.invoise.me/<public-id>",
"options": [
{
"id": "<option-id>",
"public_id": "<option-public-id>",
"chain_id": 12345,
"token": "<token-address>",
"token_decimals": 6,
"family": "evm",
"amount": "10500000",
"address": null,
"status": "registering"
}
],
"expires_at": "2026-10-19T09:00:00Z"
}

Save the group id. GET /api/v1/shops/{shop_id}/issuances/{id} returns the group with every option; poll it until the options have addresses, then give the payer the group’s payment_url, where they pick an option.

An invoice group is paid once. Its status follows the option that was paid, and paid_issuance_id names it. Webhook events are sent per option and carry group_id and group_public_id. duplicate: true means the group was already paid through another option: do not credit the order twice. A deposit group keeps one reusable address per option.

Cancel an invoice group or pause a deposit group by the group id; every option changes together. An option’s own id returns 400 issuance_in_group.

If one option cannot be created, nothing is created and error.details names the option as {chain_id, token}. An empty or repeated pair, or assets sent together with chain_id or token, returns 400 invalid_assets.

One invoice can be at most 1,000,000 tokens. A merchant can have up to 2,000 active invoices and a limited number of active deposit addresses per network family. Cancel invoices or disable deposits you no longer need to free a place. See Limits for the exact values and error codes.

Action Request
Pause a deposit’s checkout PATCH /api/v1/shops/{shop_id}/deposits/{id} with {"enabled":false}. Use true to enable it again.
Cancel an invoice’s checkout POST /api/v1/shops/{shop_id}/invoices/{id}/cancel.

Send authentication and a saved Idempotency-Key for either operation.

These actions close the payment page. They do not refund money or stop monitoring the address. Funds sent to a cancelled invoice can still settle; its events carry invoice_cancelled: true.

Funds sent after an invoice has already settled are recorded as late transfers. They are not automatically paid out. Recovery, including wrong-token recovery, requires a separate manual operation.

See the API reference for full request and response fields.