How to create a Limited Fiat Invoice via API

General API integration rules

Before starting an integration please check our Get started with API page for more info.

Limited Fiat Invoice API Integration

To accept a single payment for a product with a fixed price when initial price specified in fiat currency you can use Single Fiat invoice type. Single Fiat Invoice is an instrument that allows you to receive a fixed amount of funds for your product.

The invoice is paid in cryptocurrency but the pay amount is being recalculated every 15 minutes according to fiat amount value that you used during invoice creation.

You can find more information about other features of Public API integration in our documentation.

Creating Single Fiat Invoice

To create a new Invoice use the following endpoint: New Single Fiat Invoice (POST <<baseUrl2>>/api/v1/invoice/single-fiat/create)

You can find the detailed description of all the parameters in the documentation: New Single Fiat Invoice

Here we consider the most important ones.

  • amount - the amount of money merchant want to receive for a product/service in crypto. Recalculates every 15 minutes from fiatAmount value.
  • currency (required) - the crypto currency of payment.
  • fiatAmount (required) - the fiat amount of the invoice. The crypto amount is being calculated according to this value.
  • fiatCurrency (required) - the fiat currency of the invoice.
  • description (required) - the description of product/service.
  • idempotencyKey - a specific UUID for the payment link which guarantees uniqueness of the request. It’s possible to check the status of the invoice by this parameter after creation.

So to create an invoice without additional options you just have to send request:

curl --location --request POST '<<baseUrl2>>/api/v1/invoice/single-fiat/create' \
--header 'Key: <your_api_key>' \
--header 'Sign: <your_sign>' \
--header 'Content-Type: application/json' \
--data-raw '
{
  "timestamp": 13292792792,
  "account": "0xc195df92dd9db2a8f28e597981f113d6e7582f8b",
  "payload": {
        "currency": "USDC",
        "description": "invoice for client 1",
        "idempotencyKey": "1be6a518-6dcd-477d-96af-dd914b1300ce",
        "fiatAmount": 1000,
        "fiatCurrency": "EUR"
    }
}'

Some additional options:

  • You can set a specific custom ID to your Invoice by transmitting externalId field in request body. It’s possible to check the status of the invoice by this parameter after creation. Here, for example, you can pass a unique client ID and then use this method Get Invoices by External ID get them all. As well, externalId is returned in all types of events in webhooks, if it is set.
  • By default the invoice is available 90 days. You can set custom expiration time of an invoice by transmitting expiration field in request body but the expiration date may only be less than 90 days from the current moment. After this time the invoice will be unavailable for payment.
  • You can customise interface of your invoice by transmitting return_url, support_url and logo_url fields.

If the creation was successful you receive the response:

  • Response example
    {
        "id": 1373,
        "invoiceAddress": "0xc23670524181205cdddef7a7e471674779b20797",
        "type": "SINGLE_FIAT",
        "totalDebitAmount": 0,
        "amount": 980,
        "currency": "USDC",
        "state": "PENDING_PAYMENT",
        "description": "invoice for client 1",
        "createdDate": "2022-09-05T06:54:41.421731",
        "idempotencyKey": "d7067648-cf1f-4d95-afd1-3f7228992671",
        "expiration": "2022-10-05T06:54:41.421458",
        "fiatAmount": 1000,
        "fiatCurrency": "EUR",
        "isInterventionResolved": true,
        "subscriptionEnabled": false
    }
    

To complete the payment the client must pay the amount of money from amount field to the address specified in invoiceAddress field.

Now after you’ve successfully created an Invoice you can send link for payment to your client. Link format: <<widgetUrl>>/invoice/{idempotencyKey}

Invoice Payment link view

The invoice amount for payment will recalculate every time you open the Payment Link according to fiatAmount that you set earlier.

Or you can build your own invoice interface using data from the response.

For example, you can use the following HTML template:

  <div class="invoice">
    <h4 class="fullCurrency">Tether USD (TRC-20)</h4>
    <h4 class="rate"><span class="amount">1800</span> <span class="currency">USDT</span> = <span class="fiatAmount">1801.1</span> <span class="fiatCurrency">USD</span></h4>
    <p class="amount"><span id="amount">1800</span> <span class="currency">USDT</span></p>
    <button onclick="copyText('amount')">Copy Amount</button>
    <p class="wallet-address" id="wallet-address">TEoZ53apYcxrJspfCCb7PGh5CJKMiRrAMX</p>
    <button onclick="copyText('wallet-address')">Copy Address</button>
    <br>
    <hr>
    <p>or scan QR code</p>
    <img class="qr-code" src="https://api.qrserver.com/v1/create-qr-code/?data=TEoZ53apYcxrJspfCCb7PGh5CJKMiRrAMX&size=150x150"
      alt="QR Code">
  </div>
  <script>
    function copyText(elementId) {
      var copyText = document.getElementById(elementId);
      var textArea = document.createElement("textarea");
      textArea.value = copyText.innerText;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      textArea.remove();
    }
  </script>

See in details: How to embed invoice data to your payment page

Tracking invoice state

After creating Single Fiat Invoice you can receive information about it from the system. There are two options to track changes in invoice state:

  1. Get invoice data via request by ID.
  2. Set webhooks for invoices

Get data about specific invoice

To receive information about earlier created Invoice you can use Get a Specific Invoice endpoint (POST <<baseUrl2>>/api/v1/invoice).

You can request invoice by id, externalId or idempotencyKey.

More info on Get a Specific Invoice endpoint: Get a specific Invoice

Example of the request by id:

curl --location --request POST '<<baseUrl2>>/api/v1/invoice' \
--header 'Key: <your_api_key>' \
--header 'Sign: <your_sign>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "timestamp": 13292792792,
  "account": "0xc195df92dd9db2a8f28e597981f113d6e7582f8b",
  "payload": {
    "id": 1373
  }
}'

In response you will receive invoice data:

  • Response example
    {
        "id": 1373,
        "invoiceAddress": "0xc23670524181205cdddef7a7e471674779b20797",
        "type": "SINGLE_FIAT",
        "totalDebitAmount": 0,
      	"amount": 980,
        "currency": "USDC",
        "state": "PENDING_PAYMENT",
        "description": "invoice for client 1",
        "createdDate": "2022-09-05T06:54:41.421731",
        "idempotencyKey": "d7067648-cf1f-4d95-afd1-3f7228992671",
        "expiration": "2022-10-05T06:54:41.421458",
        "fiatAmount": 1000,
        "fiatCurrency": "EUR",
        "isInterventionResolved": true,
        "subscriptionEnabled": false
    }
    

The most important fields you need to pay attention to:

  • state - represents the status of the invoice. More info about possible states in documentation: Limited Invoice
  • totalDebitAmount - received amount of money to this invoice.

Receive information about your payments via Webhooks

To track the state of your created Invoice you can use Calypso Pay functionality which is called Webhooks.

Webhook is a way for an app to provide other applications with real-time information.
The Webhooks API allows you to subscribe to events happening with your created objects (Invoices or Payouts) in Calypso. Rather than making an API call to check status of invoice or payout during processing, Calypso can send an HTTP request to an endpoint you configure.

More detailed information about Calypso Webhooks functionality: Webhooks

  1. First of all, to receive information about Invoice state change you need to create a subscription for system events which you want to track.

There are several types of events which you need to track in order to understand what is happening to your Invoices.

The main events are:

Event typeDescription
INVOICE_FUNDS_RECEIVED_FOR_INVOICEThe event shows if funds have been received to invoice wallet
INVOICE_PAIDInvoice successfully paid. All required amount has been received to invoice wallet.
INVOICE_PENDING_INTERVENTIONInvoice has changed state to INVOICE_PENDING_INTERVENTION. Either more or less funds was received to the invoice wallet than required
INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETEDFunds have been received from invoice wallet to the merchant balance.

More info on Calypso Webhooks event types: Types of events

We’ll look at more scenarios of using Webhooks in Successful Single Fiat Invoice payment scenario and How to manage interventions via API? sections.

To create a subscription for those events you can use the Create Webhook Public API endpoint: POST <<baseUrl2>>/api/v1/subscription/webhook/create

curl --location --request POST '<<baseUrl2>>/api/v1/subscription/webhook/create' \
--header 'Key: <your_api_key>' \
--header 'Sign: <your_sign>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "timestamp": 13292792792,
  "account": "0xc195df92dd9db2a8f28e597981f113d6e7582f8b",
  "payload": {
    "notificationEventTypes": [
      "INVOICE_FUNDS_RECEIVED_FOR_INVOICE",
      "INVOICE_PAID",
      "INVOICE_PENDING_INTERVENTION",
      "INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED"
    ],
    "requestId": "bf9348b7-2c14-46d7-868c-b597852da319",
    "url": "Your App URL"
  }
}'

You can subscribe to all types of events if you specify value “INVOICE” in the notificationServiceTypes field instead of enumeration all types of events in notificationEventTypes.

In the response you will get:

{
    "requestId": "bf9348b7-2c14-46d7-868c-b597852da319",
    "notificationEventTypes": [
      "INVOICE_FUNDS_RECEIVED_FOR_INVOICE",
      "INVOICE_PAID",
      "INVOICE_PENDING_INTERVENTION",
      "INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED"
    ],
    "url": "Your App URL",
    "createdDate": "2022-08-22T08:24:00.307535"
}

More info on Webhooks management in Calypso Pay system: Webhook API

  1. After successful creation of subscription for Payment events and providing your client with Payment Link you can wait for your client to make payment.

Successful Single Fiat Invoice payment scenario

When money are received to invoice address you will receive webhook with type INVOICE_FUNDS_RECEIVED_FOR_INVOICE. It means that money delivered to invoice but it doesn't inform whether the right amount was received. You can compare amount from the webhook payload on your side or wait for the next webhook.

  • The example of webhook payload:
{
  "requestId": "535b0c92-32b8-4679-9d9e-56ebda031ff7",
  "id": 16579,
  "createdDate": "2022-08-25T12:54:48.645795",
  "level": "SUCCESS",
  "service": "INVOICE",
  "eventType": "INVOICE_FUNDS_RECEIVED_FOR_INVOICE",
  "data": {
    "type": "INVOICE_FUNDS_RECEIVED_FOR_INVOICE",
    "amount": 0.001043,
    "transactionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "message": "invoice for client 1",
    "currency": "ETH",
    "externalId": null,
    "fiatAmount": {},
    "createdDate": "2022-08-25T12:47:28.200475",
    "description": "invoice for client 1",
    "paymentDate": "2022-08-25T12:54:48.605098",
    "senderAddress": "0xf127e5b7666f51aa346f374213113298014f5969",
    "idempotencyKey": "1be6a518-6dcd-477d-96af-dd914b1300ce",
    "transactionHash": "0xa76b638428b0702b6d6721f89f4806b9853fae65315dd1f6f34ce71deae0380b",
    "parentExternalId": 1346
  }
}

If client successfully paid the invoice (he sent the right amount of money) you will receive webhook with type INVOICE_PAID. Receiving this type of webhook guarantees that the invoice was fully paid.

  • The example of webhook payload:
{
  "id":9677,
  "viewed":false,
  "createdDate":"2023-03-13T11:16:53.274743",
  "level":"INFO","service":"INVOICE",
  "data":{
    "type":"INVOICE_PAID",
    "amount":0.001043,
    "currency":"ETH",
    "realAmount":0.001043,
    "description":"test",
    "idempotencyKey":"1be6a518-6dcd-477d-96af-dd914b1300ce",
    "parentExternalId":1346
  }
}

To avoid errors related to receiving webhooks, it is necessary to request information about the invoice in Calypso Pay after receiving the webhook. To get detailed information about invoice you can use Get a Specific Invoice endpoint (POST <<baseUrl2>>/api/v1/invoice using idempotencyKey, externalId or parentExternalId (id in request).

You will see changes in the fields:

  • The value of state is PAID.
  • The value of totalDebitAmount is changed to received payment amount.
  • The value of fee shows the amount of service fee charged from the deposit amount of the invoice.

That means that the money were sent by client and they were received to invoice wallet address (invoiceAddress field).

After receiving the correct amount of money to the invoice address in Calypso system the money will be automatically credited to the merchant balance.

When money successfully credited to the balance you will receive webhook with type INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED.

The example of webhook payload:

{
  "requestId": "e505bbf7-0dcd-4097-b0c7-70372a5c68d3",
  "id": 9974,
  "createdDate": "2022-09-05T07:39:18.929518",
  "level": "SUCCESS",
  "service": "INVOICE",
  "eventType": "INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED",
  "data": {
    "type": "INVOICE_TRANSLATION_TO_ACCOUNT_COMPLETED",
    "amount": 0.01,
    "message": "unlimited invoice for client 2",
    "currency": "ETH",
    "externalId": "1234",
    "fiatAmount": {
      "EUR": 0.919371150133309,
      "USD": 1.0
    },
    "serviceFee": 0.0001,
    "createdDate": "2022-09-05T07:39:18.929518",
    "idempotencyKey": "9a995722-6dc1-4536-9d0a-8965914b45d3",
    "parentExternalId": 1375
  }
}

The most important fields in the event payload:

  • parentExternalId - system ID of invoice.
  • externalId - custom merchant ID, that could be set when the invoice was created.
  • amount - amount of money paid for this invoice.
  • serviceFee - service fee for the invoice deposit. This amount will be charged from the deposit amount.

In order to calculate exact amount of money credited to the merchant balance you should deduct serviceFee from amount.

You will see changes in the fields:

  • The value of state is COMPLETED.

Interventions

For advanced invoice usage scenarios and error handling please check our How to manage interventions via API? page.