How to create an invoice via API
Overview
Invoice API allows merchants to create crypto invoices, show payment details to customers, and track payment processing until funds are credited to the merchant account.
Use this guide to create any supported invoice type: SINGLE, SINGLE_FIAT, or UNLIMITED.
Invoice types
| Type | When to use | Creation method |
|---|---|---|
| SINGLE | One payment with a fixed crypto amount. | [POST] invoice/single/create |
| SINGLE_FIAT | One payment where invoice amount is set in fiat and paid in crypto. | [POST] invoice/single-fiat/create |
| UNLIMITED | Reusable invoice address that can receive multiple payments in any amount. | [POST] invoice/unlimited/create |
Integration flow
Common setup
- Choose the invoice type that matches your payment scenario.
- Create the invoice by using the corresponding Invoice API creation method.
-
Save the returned
id,idempotencyKey,invoiceAddress,type, andstate. - Show payment details to the customer through a Calypso payment link, an iframe checkout form, or your own checkout page.
Successful payment flow
Use this flow when the customer pays the invoice and Calypso can complete the payment without manual intervention.
-
Optional: Calypso may send
INVOICE_MEM_POOL_FOUNDwhen the customer transaction is detected in the blockchain mempool. This webhook is not guaranteed: on fast blockchains, the mempool status may be skipped. -
When Calypso sends
INVOICE_FUNDS_RECEIVED_FOR_INVOICE, record that funds were received on the invoice address. This webhook confirms the deposit, but it is not always the final payment result. -
If Calypso sends
INVOICE_PAID, mark the customer-facing payment as successful. -
INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETEDis sent when funds are credited to the merchant account balance. Use it for reconciliation, not as the customer-facing payment confirmation.
If needed, verify the current invoice status by using [POST] invoice.
No payment or failed processing flow
Use this flow when the customer does not complete the payment in time or invoice processing cannot be completed.
-
INVOICE_EXPIREDis sent if the invoice expiration time passes before a successful payment is completed. Stop accepting payment for this invoice and create a new invoice if the customer still needs to pay. -
INVOICE_FAILEDis sent if invoice processing fails because Calypso cannot complete the payment flow for this invoice. Stop the current payment flow and verify the invoice state through [POST] invoice.
Compliance corner case
Use this flow only when the transaction is routed to compliance review.
-
Optional:
INVOICE_PENDING_COMPLIANCEis sent only if the transaction is routed to compliance review under the relevant compliance conditions. If the transaction automatically passes compliance, this webhook is not sent; continue waiting for the next invoice status webhook. -
If Calypso sends
INVOICE_COMPLIANCE_DECLINED, treat it as a terminal negative compliance result and do not mark the invoice as paid.
Intervention corner case
Use this flow when funds were received, but the payment requires merchant action, for example because of underpay or overpay.
-
After
INVOICE_FUNDS_RECEIVED_FOR_INVOICE, Calypso may sendINVOICE_PENDING_INTERVENTION. -
Check the invoice details by using [POST] invoice and review
state,interventionType,amount,totalDebitAmount, andisInterventionResolved. -
Do not mark the invoice as paid until the intervention is resolved and the invoice reaches
PAID.
Sequence
Names of requests on the scheme indicate the successful Invoice API flow and invoice webhook events.
Checkout form options
After an invoice is created, you can show the checkout experience to the customer in one of three ways.
| Option | Description |
|---|---|
| Calypso payment link | Redirect the customer to https://pay.calypso.money/invoice/{idempotencyKey}. |
| iframe checkout form | Embed the Calypso checkout page into the merchant website with an iframe. |
| Custom checkout form | Build your own payment page using invoiceAddress, amount, currency, fiatAmount, fiatCurrency, and QR code data from the invoice response. |
iframe checkout form
Use iframe when you want the customer to stay on the merchant website while the Calypso checkout form handles payment details.
<iframe
src="https://pay.calypso.money/invoice/{idempotencyKey}"
title="Calypso invoice checkout"
width="100%"
height="720"
style="border: 0;"
allow="clipboard-write"
></iframe>
Replace {idempotencyKey} with the invoice idempotencyKey returned in the invoice creation response.
Common request fields
All invoice creation methods use the same request wrapper.
| Field | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Merchant account ID. The request will be sent for this account. |
| timestamp | number | Yes | Current Unix UTC timestamp in milliseconds. The value must not be less than 3 minutes in the past or greater than 3 minutes in the future. |
| payload | object | Yes | Object with invoice creation data. |
Invoice creation methods
Create SINGLE invoice - [POST] invoice/single/create
| Payload field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Invoice amount in crypto currency. |
| currency | string | Yes | Crypto currency of the invoice. |
| description | string | Yes | Short invoice description. |
| fiatAvailable | boolean | Yes | Shows whether the merchant can process payments in fiat currency. |
| expiration | string | No | Invoice expiration date and time. Default value is 1 day. |
| idempotencyKey | string | No | External ID in UUID format. Can be used to prevent duplicate creation and build a payment link. |
| returnUrl | string | No | URL where the customer can return from the payment page. |
| logoUrl | string | No | Merchant logo URL shown on the payment page. PNG format is recommended. |
| supportUrl | string | No | Merchant support URL shown on the payment page. |
| externalId | string | No | Merchant-side invoice ID. |
Request example
{
"account": "0x0000000000000000000000000000000000000000",
"timestamp": 1761650432438,
"payload": {
"amount": 100,
"currency": "USDT_TRX",
"description": "Order #1001",
"fiatAvailable": false,
"idempotencyKey": "123e4567-e89b-12d3-a456-426614174000",
"returnUrl": "https://merchant.com/checkout",
"externalId": "order-1001"
}
}
Create SINGLE_FIAT invoice - [POST] invoice/single-fiat/create
| Payload field | Type | Required | Description |
|---|---|---|---|
| fiatAmount | number | Yes | Invoice amount in fiat currency. |
| fiatCurrency | string | Yes | Fiat currency of the invoice amount. |
| currency | string | Yes | Crypto currency used for payment. |
| description | string | Yes | Short invoice description. |
| fiatAvailable | boolean | Yes | Shows whether the merchant can process payments in fiat currency. |
| expiration | string | No | Invoice expiration date and time. Default value is 1 day. |
| idempotencyKey | string | No | External ID in UUID format. |
| returnUrl | string | No | URL where the customer can return from the payment page. |
| logoUrl | string | No | Merchant logo URL shown on the payment page. |
| supportUrl | string | No | Merchant support URL shown on the payment page. |
| externalId | string | No | Merchant-side invoice ID. |
Request example
{
"account": "0x0000000000000000000000000000000000000000",
"timestamp": 1761650432438,
"payload": {
"fiatAmount": 100,
"fiatCurrency": "USD",
"currency": "USDT_TRX",
"description": "Order #1002",
"fiatAvailable": true,
"idempotencyKey": "123e4567-e89b-12d3-a456-426614174001",
"returnUrl": "https://merchant.com/checkout",
"externalId": "order-1002"
}
}
Create UNLIMITED invoice - [POST] invoice/unlimited/create
| Payload field | Type | Required | Description |
|---|---|---|---|
| currency | string | Yes | Crypto currency of the invoice. |
| description | string | Yes | Short invoice description. |
| fiatAvailable | boolean | Yes | Shows whether the merchant can process payments in fiat currency. |
| idempotencyKey | string | No | External ID in UUID format. |
| returnUrl | string | No | URL where the customer can return from the payment page. |
| logoUrl | string | No | Merchant logo URL shown on the payment page. |
| supportUrl | string | No | Merchant support URL shown on the payment page. |
| externalId | string | No | Merchant-side invoice ID. |
Response fields
All invoice creation methods return invoice data.
| Field | Type | Description |
|---|---|---|
| id | string | Calypso invoice ID. |
| invoiceAddress | string | Crypto address where the customer sends funds. |
| type | string | Invoice type: SINGLE, SINGLE_FIAT, or UNLIMITED. |
| amount | number | Invoice amount. For SINGLE_FIAT, this is the calculated crypto amount. |
| fee | number | Service fee for the invoice. |
| totalDebitAmount | number | Total amount received on the invoice address. |
| currency | string | Invoice crypto currency. |
| state | string | Current invoice status. |
| lastDepositHash | string | Last deposit transaction hash, if available. |
| description | string | Invoice description. |
| createdDate | string | Invoice creation date and time. |
| idempotencyKey | string | External ID in UUID format used during invoice creation. |
| expiration | string | Invoice expiration date and time, if set. |
| fiatAmount | number | Fiat amount for SINGLE_FIAT invoice. |
| fiatCurrency | string | Fiat currency for SINGLE_FIAT invoice. |
| lastFiatUpdated | string | Time when the exchange rate was last updated for SINGLE_FIAT invoice. |
| interventionType | string | Intervention case: OVERPAY or UNDERPAY. |
| isInterventionResolved | boolean | Shows whether intervention was resolved. |
| subscriptionEnabled | boolean | Shows whether customer email notifications are enabled. |
| returnUrl | string | Merchant return URL. |
| logoUrl | string | Merchant logo URL. |
| supportUrl | string | Merchant support URL. |
| externalId | string | Merchant-side invoice ID. |
| autoconversion | object | Invoice autoconversion configuration, if enabled. |
| fiatAvailable | boolean | Shows whether fiat payments are available. |
| creationSource | string | Invoice creation source. |
Invoice statuses
| Status | Description |
|---|---|
| PENDING_PAYMENT | Invoice is created and waiting for payment. |
| MEM_POOL_FOUND | Incoming transaction was detected in the blockchain mempool. |
| PENDING_COMPLIANCE_CHECK | Incoming transaction is under compliance review. This intermediate state is optional and may be skipped when compliance is passed automatically. |
| DECLINED | Transaction was rejected by compliance. INVOICE_COMPLIANCE_DECLINED is sent for a negative compliance result. |
| PAID | Invoice was paid. Required funds were received on the invoice address. |
| PENDING_INTERVENTION | Merchant intervention is required because the received amount does not match the expected amount or another payment issue occurred. |
| COMPLETED | Funds were credited to the merchant account. |
| ARCHIVED | Invoice was archived and is not available for payment. |
| CANCEL | Invoice was canceled. |
| REVERSED | Invoice payment was reversed. |
Webhook event types use the INVOICE_ prefix, for example INVOICE_PAID. Invoice statuses returned in state do not use this prefix.
returnUrl payment status
When Calypso redirects the customer to returnUrl, it can append the paymentStatus query parameter.
paymentStatus value | Meaning | Recommended merchant page |
|---|---|---|
| SUCCESS | Invoice payment reached a successful final status. | Success page or order confirmation. |
| FAILED | Invoice payment was declined, archived, or failed. | Failed or expired payment page. |
| absent | No status-specific redirect was applied. | Standard return page. |
paymentStatus is a redirect parameter, not the invoice state. Always use webhooks or [POST] invoice as the source of truth for backend order processing.
Underpay handling
Calypso applies an internal underpay threshold of 0.995, or 99.5%, for invoices.
| Invoice amount | Paid amount | Ratio | Result |
|---|---|---|---|
| 10.234 USDT | 10.23 USDT | 0.9996 | Success |
| 10.234 USDT | 10.00 USDT | 0.977 | Intervention flow |
This threshold is fixed and cannot be changed by the merchant. It is especially important when displayed payment amounts are rounded or when network fees affect the transferred amount.
Related docs
| Document | Link |
|---|---|
| Embed invoice data to your payment page | How to embed invoice data to your payment page |
| Invoice webhooks | Invoice webhooks |
| Manage interventions | How to manage interventions via API |
| Invoice API reference | Invoice API |