Skip to main content

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​

TypeWhen to useCreation method
SINGLEOne payment with a fixed crypto amount.[POST] invoice/single/create
SINGLE_FIATOne payment where invoice amount is set in fiat and paid in crypto.[POST] invoice/single-fiat/create
UNLIMITEDReusable invoice address that can receive multiple payments in any amount.[POST] invoice/unlimited/create

Integration flow​

Common setup​

  1. Choose the invoice type that matches your payment scenario.
  2. Create the invoice by using the corresponding Invoice API creation method.
  3. Save the returned id, idempotencyKey, invoiceAddress, type, and state.
  4. 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.

  1. Optional: Calypso may send INVOICE_MEM_POOL_FOUND when the customer transaction is detected in the blockchain mempool. This webhook is not guaranteed: on fast blockchains, the mempool status may be skipped.
  2. 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.
  3. If Calypso sends INVOICE_PAID, mark the customer-facing payment as successful.
  4. INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED is 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.

  1. INVOICE_EXPIRED is 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.
  2. INVOICE_FAILED is 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.

  1. Optional: INVOICE_PENDING_COMPLIANCE is 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.
  2. 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.

  1. After INVOICE_FUNDS_RECEIVED_FOR_INVOICE, Calypso may send INVOICE_PENDING_INTERVENTION.
  2. Check the invoice details by using [POST] invoice and review state, interventionType, amount, totalDebitAmount, and isInterventionResolved.
  3. 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.

Invoice creation sequence

Checkout form options​

After an invoice is created, you can show the checkout experience to the customer in one of three ways.

OptionDescription
Calypso payment linkRedirect the customer to https://pay.calypso.money/invoice/{idempotencyKey}.
iframe checkout formEmbed the Calypso checkout page into the merchant website with an iframe.
Custom checkout formBuild 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.

FieldTypeRequiredDescription
accountstringYesMerchant account ID. The request will be sent for this account.
timestampnumberYesCurrent 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.
payloadobjectYesObject with invoice creation data.

Invoice creation methods​

Create SINGLE invoice - [POST] invoice/single/create​

Payload fieldTypeRequiredDescription
amountnumberYesInvoice amount in crypto currency.
currencystringYesCrypto currency of the invoice.
descriptionstringYesShort invoice description.
fiatAvailablebooleanYesShows whether the merchant can process payments in fiat currency.
expirationstringNoInvoice expiration date and time. Default value is 1 day.
idempotencyKeystringNoExternal ID in UUID format. Can be used to prevent duplicate creation and build a payment link.
returnUrlstringNoURL where the customer can return from the payment page.
logoUrlstringNoMerchant logo URL shown on the payment page. PNG format is recommended.
supportUrlstringNoMerchant support URL shown on the payment page.
externalIdstringNoMerchant-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 fieldTypeRequiredDescription
fiatAmountnumberYesInvoice amount in fiat currency.
fiatCurrencystringYesFiat currency of the invoice amount.
currencystringYesCrypto currency used for payment.
descriptionstringYesShort invoice description.
fiatAvailablebooleanYesShows whether the merchant can process payments in fiat currency.
expirationstringNoInvoice expiration date and time. Default value is 1 day.
idempotencyKeystringNoExternal ID in UUID format.
returnUrlstringNoURL where the customer can return from the payment page.
logoUrlstringNoMerchant logo URL shown on the payment page.
supportUrlstringNoMerchant support URL shown on the payment page.
externalIdstringNoMerchant-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 fieldTypeRequiredDescription
currencystringYesCrypto currency of the invoice.
descriptionstringYesShort invoice description.
fiatAvailablebooleanYesShows whether the merchant can process payments in fiat currency.
idempotencyKeystringNoExternal ID in UUID format.
returnUrlstringNoURL where the customer can return from the payment page.
logoUrlstringNoMerchant logo URL shown on the payment page.
supportUrlstringNoMerchant support URL shown on the payment page.
externalIdstringNoMerchant-side invoice ID.

Response fields​

All invoice creation methods return invoice data.

FieldTypeDescription
idstringCalypso invoice ID.
invoiceAddressstringCrypto address where the customer sends funds.
typestringInvoice type: SINGLE, SINGLE_FIAT, or UNLIMITED.
amountnumberInvoice amount. For SINGLE_FIAT, this is the calculated crypto amount.
feenumberService fee for the invoice.
totalDebitAmountnumberTotal amount received on the invoice address.
currencystringInvoice crypto currency.
statestringCurrent invoice status.
lastDepositHashstringLast deposit transaction hash, if available.
descriptionstringInvoice description.
createdDatestringInvoice creation date and time.
idempotencyKeystringExternal ID in UUID format used during invoice creation.
expirationstringInvoice expiration date and time, if set.
fiatAmountnumberFiat amount for SINGLE_FIAT invoice.
fiatCurrencystringFiat currency for SINGLE_FIAT invoice.
lastFiatUpdatedstringTime when the exchange rate was last updated for SINGLE_FIAT invoice.
interventionTypestringIntervention case: OVERPAY or UNDERPAY.
isInterventionResolvedbooleanShows whether intervention was resolved.
subscriptionEnabledbooleanShows whether customer email notifications are enabled.
returnUrlstringMerchant return URL.
logoUrlstringMerchant logo URL.
supportUrlstringMerchant support URL.
externalIdstringMerchant-side invoice ID.
autoconversionobjectInvoice autoconversion configuration, if enabled.
fiatAvailablebooleanShows whether fiat payments are available.
creationSourcestringInvoice creation source.

Invoice statuses​

StatusDescription
PENDING_PAYMENTInvoice is created and waiting for payment.
MEM_POOL_FOUNDIncoming transaction was detected in the blockchain mempool.
PENDING_COMPLIANCE_CHECKIncoming transaction is under compliance review. This intermediate state is optional and may be skipped when compliance is passed automatically.
DECLINEDTransaction was rejected by compliance. INVOICE_COMPLIANCE_DECLINED is sent for a negative compliance result.
PAIDInvoice was paid. Required funds were received on the invoice address.
PENDING_INTERVENTIONMerchant intervention is required because the received amount does not match the expected amount or another payment issue occurred.
COMPLETEDFunds were credited to the merchant account.
ARCHIVEDInvoice was archived and is not available for payment.
CANCELInvoice was canceled.
REVERSEDInvoice 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 valueMeaningRecommended merchant page
SUCCESSInvoice payment reached a successful final status.Success page or order confirmation.
FAILEDInvoice payment was declined, archived, or failed.Failed or expired payment page.
absentNo 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 amountPaid amountRatioResult
10.234 USDT10.23 USDT0.9996Success
10.234 USDT10.00 USDT0.977Intervention 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.

DocumentLink
Embed invoice data to your payment pageHow to embed invoice data to your payment page
Invoice webhooksInvoice webhooks
Manage interventionsHow to manage interventions via API
Invoice API referenceInvoice API