July 4, 2022

Crypto Pay API

Crypto Pay is a payment system based on Crypto Bot that allows you to accept payments in crypto and transfer coins to users using our API.

Subscribe to our News Channel to be the first to know about the latest updates and join the discussion in our chat.

Recent changes

Crypto Pay API 1.1.3 (October 3, 2022)

  • New parameter fee in Invoice object shows the amount of charged service fees. Returned only if the invoice has paid status.
  • New parameter usd_rate in Invoice object shows the price of the asset in USD. Returned only if the invoice has paid status.

Crypto Pay API 1.1.2 (September 5, 2022)

  • Method transfer is disabled by default for new apps.
  • Set an allowlist of IP addresses in the “Security” section of your app.

Crypto Pay API 1.1.1 (July 26, 2022)

  • Added support for ETH to the mainnet.

Crypto Pay API 1.1 (February 2, 2022)

  • Apps can now send coins to users using the new method transfer.
  • Added support for hidden message in invoices.
  • New parameter expires_in to set a payment time limit for new invoices.
  • Added new expiration_date field in Invoice object.

Note: In order to use the new method transfer, you need to create a new app.

Authorizing your app

First, you need to create a new app and get API token. Open @CryptoBot (@CryptoTestnetBot for testnet), go to Crypto Pay and tap Create App to get API Token.

All queries to Crypto Pay API must be served over HTTPS. Use either URL query string or application/json or application/x-www-form-urlencoded or multipart/form-data for passing parameters. API Token must be passed in the header parameter Crypto-Pay-API-Token. URL must be presented in this form: https://pay.crypt.bot/api/%method%. Example request:

GET /api/getMe HTTP/1.1
Host: pay.crypt.bot
Crypto-Pay-API-Token: 123456789:AAzQcZWQqQAbsfgPnOLr4FHC8Doa4L7KryC

Testnet:

Bot: @CryptoTestnetBot

URL: https://testnet-pay.crypt.bot/

Mainnet:

Bot: @CryptoBot

URL: https://pay.crypt.bot/

Getting updates

There are two ways of receiving updates for your app — you can use getInvoices method to get a list of created invoices or Webhooks to receive updates in realtime.

Methods

Types

Available methods

We support GET and POST HTTP methods. Response contains a JSON-object which always has the Boolean field ok. If ok equals true, the request was successful, and the result of the query can be found in result field. In case of an unsuccessful request, ok equals false, and the error is explained in error field (e.g. PARAM_SHORT_NAME_REQUIRED). All queries must be made using UTF-8.

Tip: Use Big.js or another lib to work with big numbers.

getMe

Use this method to test your app's authentication token. Requires no parameters. On success, returns basic information about an app.

createInvoice

Use this method to create a new invoice. On success, returns an object of the created invoice.

  • asset (String)
    Currency code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “BNB”, “BUSD” and “USDC”.
  • amount (String)
    Amount of the invoice in float. For example: 125.50
  • description (String)
    Optional. Description for the invoice. User will see this description when they pay the invoice. Up to 1024 characters.
  • hidden_message (String)
    Optional. Text of the message that will be shown to a user after the invoice is paid. Up to 2o48 characters.
  • paid_btn_name (String)
    Optional. Name of the button that will be shown to a user after the invoice is paid.
    Supported names:
    viewItem – “View Item”
    openChannel – “View Channel”
    openBot – “Open Bot”
    callback – “Return”
  • paid_btn_url (String)
    Optional. Required if paid_btn_name is used. URL to be opened when the button is pressed. You can set any success link (for example, a link to your bot). Starts with https or http.
  • payload (String)
    Optional. Any data you want to attach to the invoice (for example, user ID, payment ID, ect). Up to 4kb.
  • allow_comments (Boolean)
    Optional. Allow a user to add a comment to the payment. Default is true.
  • allow_anonymous (Boolean)
    Optional. Allow a user to pay the invoice anonymously. Default is true.
  • expires_in (Number)
    Optional. You can set a payment time limit for the invoice in seconds. Values between 1-2678400 are accepted.

transfer

Use this method to send coins from your app's balance to a user. On success, returns object of completed transfer. This method must first be enabled in the security settings of your app. Open @CryptoBot (@CryptoTestnetBot for testnet), go to Crypto Pay → My Apps, choose an app, then go to Security -> Transfers... and tap Enable.

  • user_id (Number)
    Telegram user ID. User must have previously used @CryptoBot (@CryptoTestnetBot for testnet).
  • asset (String)
    Currency code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “BNB”, “BUSD” and “USDC”.
  • amount (String)
    Amount of the transfer in float. The minimum and maximum amounts for each of the supported assets roughly correspond to the limit of 1-25000 USD. Use getExchangeRates to convert amounts. For example: 125.50
  • spend_id (String)
    UUID or any random UTF-8 string generated for each transfer to make your request idempotent in cases when it should be retried (for example, request timeout, connection reset, 500 HTTP status, etc). Only one transfer with the same spend_id can be accepted from your app. Up to 64 symbols.
  • comment (String)
    Optional. Comment for the transfer. Users will see this comment when they get notified about the transfer. Up to 1024 symbols.
  • disable_send_notification (Boolean)
    Optional. Pass true if the user should not receive a notification about the completed transfer. Default is false.

getInvoices

Use this method to get invoices of your app. On success, returns array of invoices.

  • asset (String)
    Optional. Currency codes separated by comma. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “BNB”, “BUSD” and “USDC”. Defaults to all assets.
  • invoice_ids (String)
    Optional. Invoice IDs separated by comma.
  • status (String)
    Optional. Status of invoices to be returned. Available statuses: “active” and “paid”. Defaults to all statuses.
  • offset (Number)
    Optional. Offset needed to return a specific subset of invoices. Default is 0.
  • count (Number)
    Optional. Number of invoices to be returned. Values between 1-1000 are accepted. Default is 100.

getBalance

Use this method to get balances of your app. Requires no parameters. Returns array of assets.

getExchangeRates

Use this method to get exchange rates of supported currencies. Requires no parameters. Returns array of currencies.

getCurrencies

Use this method to get a list of supported currencies. Requires no parameters. Returns array of currencies.

Available types

Invoice

  • invoice_id (Number)
    Unique ID for this invoice.
  • status (String)
    Status of the invoice, can be either “active”, “paid” or “expired”.
  • hash (String)
    Hash of the invoice.
  • asset (String)
    Currency code. Currently, can be “USDT”, “TON”, “BTC”, “ETH”, “BNB”, “BUSD” or “USDC”.
  • amount (String)
    Amount of the invoice.
  • fee (String)
    Optional. Amount of charged service fees. Returned only if the invoice has paid status.
  • pay_url (String)
    URL should be presented to the user to pay the invoice.
  • description (String)
    Optional. Description for this invoice.
  • created_at (String)
    Date the invoice was created in ISO 8601 format.
  • usd_rate (String)
    Optional. Price of the asset in USD. Returned only if the invoice has paid status.
  • allow_comments (Boolean)
    True, if the user can add comment to the payment.
  • allow_anonymous (Boolean)
    True, if the user can pay the invoice anonymously.
  • expiration_date (String)
    Optional. Date the invoice expires in Unix time.
  • paid_at (String)
    Optional. Date the invoice was paid in Unix time.
  • paid_anonymously (Boolean)
    True, if the invoice was paid anonymously.
  • comment (String)
    Optional. Comment to the payment from the user.
  • hidden_message (String)
    Optional. Text of the hidden message for this invoice.
  • payload (String)
    Optional. Previously provided data for this invoice.
  • paid_btn_name (String)
    Optional. Name of the button, can be “viewItem”, “openChannel”, “openChannel” or “callback”.
  • paid_btn_url (String)
    Optional. URL of the button.

Transfer

  • transfer_id (Number)
    Unique ID for this transfer.
  • user_id (String)
    Telegram user ID the transfer was sent to.
  • asset (String)
    Currency code. Currently, can be “USDT”, “TON”, “BTC”, “ETH”, “BNB”, “BUSD” or “USDC”.
  • amount (String)
    Amount of the transfer.
  • status (String)
    Status of the transfer, can be “completed”.
  • completed_at (String)
    Date the transfer was completed in ISO 8601 format.
  • comment (String)
    Optional. Comment for this transfer.

Webhooks

Use Webhooks to get updates for your app, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts.

Webhook request may be sent at least one time.

To make sure that the Webhook request was sent by Crypto Pay API, use a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your app's token, you can be pretty sure it’s us.

How to enable Webhooks?

Open @CryptoBot (@CryptoTestnetBot for testnet), go to Crypto Pay → My Apps, choose an app, then choose Webhooks... and tap 🌕 Enable Webhooks. Then enter HTTPS url which should be used by Crypto Pay API to post to.

Webhook updates

All requests sent by Crypto Pay API has this JSON object:

  • update_id (Number)
    Non-unique update ID.
  • update_type (String)
    Webhook update type. Supported update types:
    invoice_paid – the update sent when the invoice is paid.
  • request_date (String)
    Date the request was sent in ISO 8601 format.
  • payload (Object)
    Payload contains Invoice object.

Verifying webhook updates

You can verify the received update and the integrity of the received data by comparing the header parameter crypto-pay-api-signature and the hexadecimal representation of HMAC-SHA-256 signature used to sign the entire request body (unparsed JSON string) with a secret key that is SHA256 hash of your app's token.

The full check might look like this:

const { createHash, createHmac } = require('crypto')

const checkSignature = (token, { body, headers }) => {
  const secret = createHash('sha256').update(token).digest()
  const checkString = JSON.stringify(body)
  const hmac = createHmac('sha256', secret).update(checkString).digest('hex')
  return hmac === signature['crypto-pay-api-signature']
}

console.log(checkSignature('XXX:XXXXX', { body: req.body, headers: req.headers }))

To prevent outdated data from being used, you can additionally check the request_date field which contains the date the request was sent in ISO 8601 format.

Libraries

Node.js

.NET

PHP

Python

Go