Skip to content

API Endpoints ​

All requests require authentication headers. See Authentication for details.

Base URL: https://papi.cryptumpay.com

Response Format ​

All responses use the same envelope structure:

typescript
// Success
{ "data": T, "errorObject": null }

// Error
{ "data": null, "errorObject": { "httpCode": number, "appCode": number, "message"?: string } }

POST /v1/orders ​

Creates a new merchant order. Depending on your integration approach, the returned order ID can be:

  • Passed to the widget so the customer completes payment inline on your site
  • Used to form a payment gateway link — https://pay.cryptumpay.com/m/{orderId} — and sent to the customer via email, messenger, SMS, or any other channel (see Without Widget)
  • Used entirely without the widget, from your own app's UI — see White-label / Native App

Request Body ​

FieldTypeRequiredDescription
titlestringYesOrder title shown to the customer
descriptionstringYesOrder description shown to the customer
fiatAmountstringOne of two price basesPayment amount as a decimal string, e.g. "9.99". Mutually exclusive with cryptoAmount — see below
fiatCurrencystringWith fiatAmountFiat currency code, e.g. "usd" or "eur"
cryptoCurrencystringOne of two price basesCryptocurrency ticker, e.g. "usdt". Use together with cryptoBlockchain and cryptoAmount instead of fiatAmount/fiatCurrency
cryptoBlockchainstringWith cryptoCurrencyBlockchain name, e.g. "tron", "bsc" (same values as in POST /v1/withdraw)
cryptoAmountstringWith cryptoCurrencyOrder price denominated in crypto, as a decimal string. The equivalent fiatAmount is calculated for you from the current rate. When this basis is used, the request also creates and attaches the customer order (deposit address, exact amount) in the same call — see Price basis below
clientEmailstringNoYour end customer's email, attached to the resulting deposit/customer order (distinct from projectDataUserEmail, which is just metadata on the merchant order)
urlstringNoReturn URL for the payment gate (overrides project-level successPath/failPath)
projectDataUserIdstringNoYour internal user ID to attach to the order
projectDataUserEmailstringNoCustomer email to attach to the order (metadata only)
projectDataOrderIdstringNoYour internal order ID to attach to the order
projectDataMetastringNoArbitrary metadata string (e.g. JSON) to attach to the order

Price basis ​

You can price an order in fiat or in crypto — pick exactly one:

  • fiatAmount + fiatCurrency — the classic flow. Creates only the merchant order; the customer (via widget or your own app, calling the endpoints below) still has to pick a network to pay with.
  • cryptoCurrency + cryptoBlockchain + cryptoAmount — for apps with their own network picker (use GET /v1/currencies to build it). Creates the merchant order and the customer order (deposit address) in one call, since the network is already known. fiatCurrency is optional here — it defaults to your project's preferred fiat currency, and is used only for bookkeeping/reporting, not for pricing.

Who pays the fees

If your project is configured so the merchant absorbs a given fee (service fee and/or network transfer fee), the customer pays exactly cryptoAmount for that fee. If the customer absorbs it, it's added on top automatically. GET /v1/currencies already returns a cryptoMinAmount that accounts for this, so you don't need to do this math yourself — just stay above it.

Response ​

json
{
  "data": {
    "id": "1c555afe-77bc-ab57-ffa0-27cdacc94000",
    "project": {
      "id": "string",
      "feePercent": 1.5,
      "logoUrl": "https://...",
      "title": "My Store",
      "url": "https://mystore.com"
    },
    "expiresAt": 1745975440234,
    "customerOrderRequest": {
      "fiatTicker": "usd",
      "fiatAmount": "9.99",
      "title": "Order #1",
      "description": "My product",
      "url": null,
      "projectData": {}
    }
  },
  "errorObject": null
}

When you create an order using the cryptoAmount price basis, the response has the same shape (id is always the merchant order ID), plus a customerOrder field with the deposit details — identical to what GET /v1/orders/:orderId returns right after creation:

json
{
  "data": {
    "id": "1c555afe-77bc-ab57-ffa0-27cdacc94000",
    "project": { ... },
    "expiresAt": 1745975440234,
    "customerOrderRequest": { ... },
    "customerOrderId": "4fc1ae7b-c7f9-4dc7-2222-8d37f993e28f",
    "customerOrder": {
      "status": "created",
      "cryptoTicker": "trx",
      "cryptoBlockchainId": 12,
      "cryptoAmount": "150.5",
      "depositAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
      "expiresAt": 1745977240234,
      "depositsList": [],
      "summary": { ... }
    }
  },
  "errorObject": null
}

id is always the merchant order ID

Regardless of which price basis you use, id in the response is always the merchant order ID — the same ID you'd use for GET /v1/orders/:orderId or the pay.cryptumpay.com/m/{orderId} link. The deposit-specific details (address, exact crypto amount, status) live under customerOrder, present only once a customer order exists.

Errors ​

appCodeDescription
6000Order creation failed (service unavailable or invalid parameters)

Node.js SDK ​

typescript
const response = await client.createOrder({
  title: 'Order #12345',
  description: 'Shopping cart checkout',
  fiatAmount: '49.99',
  fiatCurrency: 'usd',
  projectDataUserId: 'user_42',
  projectDataOrderId: 'internal-order-123',
});

if (response.errorObject) {
  console.error('Failed to create order:', response.errorObject);
} else {
  const orderId = response.data.id;
  // Pass orderId to the widget via onCreateOrder callback
}

GET /v1/currencies ​

Returns the cryptocurrencies and networks currently available for payment, with the limits and fees relevant to your project. Use this to build your own currency/network picker for the cryptoAmount price basis of POST /v1/orders (see White-label / Native App) — no rate lookups or fee math required on your side.

This endpoint only covers the crypto side. It does not return fiat rates or fiat-denominated limits — if you need to quote a price in fiat, convert it yourself; the orders themselves are always priced in either fiat or crypto, your choice, independently of this endpoint.

Response ​

json
{
  "data": [
    {
      "cryptoCurrency": "trx",
      "cryptoBlockchain": "tron",
      "cryptoMinAmount": "7.5",
      "cryptoMaxAmount": "99998.9",
      "transferFee": "1.1"
    },
    {
      "cryptoCurrency": "usdt",
      "cryptoBlockchain": "bsc",
      "cryptoMinAmount": "5.000000",
      "cryptoMaxAmount": "49999.5"
    }
  ],
  "errorObject": null
}
  • cryptoMinAmount is already the safe minimum for cryptoAmount in POST /v1/orders — if your project absorbs a fee, this number already accounts for it, so any amount at or above it is guaranteed valid.
  • cryptoMaxAmount already leaves room for the network transfer fee.
  • transferFee (network fee) is present only if your customer pays it (your project's fee-side setting). If your project absorbs it, the field is omitted — it doesn't affect what you charge the customer.
  • serviceFeePercent (CryptumPay's service fee, as a percentage) is present only if your customer pays it. If your project absorbs it, the field is omitted.
  • Networks currently under maintenance or with deposits disabled are left out of the list entirely.

Node.js SDK ​

typescript
const response = await client.getCurrencies();

if (!response.errorObject) {
  for (const entry of response.data) {
    console.log(`${entry.cryptoCurrency} on ${entry.cryptoBlockchain}: min ${entry.cryptoMinAmount}`);
  }
}

GET /v1/orders/:orderId ​

Returns the current state of a merchant order, including whether a customer has started payment (customerOrderId).

Path Parameters ​

ParameterDescription
orderIdThe merchant order ID returned by POST /v1/orders

Response ​

json
{
  "data": {
    "id": "1c555afe-77bc-ab57-ffa0-27cdacc94000",
    "project": { ... },
    "expiresAt": 1745975440234,
    "customerOrderRequest": { ... },
    "customerOrderId": "4fc1ae7b-c7f9-4dc7-2222-8d37f993e28f",
    "customerOrder": {
      "status": "created",
      "cryptoTicker": "trx",
      "cryptoBlockchainId": 12,
      "cryptoAmount": "150.5",
      "depositAddress": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
      "expiresAt": 1745977240234,
      "depositsList": [],
      "summary": { ... }
    },
    "financeSummary": {
      "status": 3,
      "accrued": true,
      "income": {
        "amount": "49.10",
        "currency": "usd"
      }
    }
  },
  "errorObject": null
}

customerOrder is null until the customer has picked a network and the deposit address has been assigned — either via the widget, or via your own app calling POST /v1/orders with the cryptoAmount price basis. Use it to re-fetch the deposit address/amount at any point (e.g. after your app was closed and reopened), without needing a separate endpoint.

financeSummary is present only after the customer order reaches a final state. income reflects the amount actually credited after fees.

financeSummary Statuses ​

statusDescription
0In progress — customer order is being processed
1Under review — order is pending manual review
2Canceled — order was canceled
3Paid — payment received and funds credited
4Crediting — funds are being credited to your balance

The accrued field is true once funds have been credited to your project balance.

Confirming a successful payment

To confirm that funds were received, check that financeSummary.status is 3 or 4:

  • Status 3 (Paid) — funds have already been credited to your project balance.
  • Status 4 (Crediting) — crediting is still in progress, but the system has definitely received the payment and will complete the transfer shortly.

Do not fulfill orders based on status 0 (In progress) or 1 (Under review), as those states are not yet final.

Errors ​

appCodeDescription
6001Order not found or does not belong to your project

Node.js SDK ​

typescript
const response = await client.getOrder('1c555afe-77bc-ab57-ffa0-27cdacc94000');

if (response.errorObject) {
  console.error('Order not found:', response.errorObject);
} else {
  console.log('Customer order ID:', response.data.customerOrderId);
  console.log('Finance summary:', response.data.financeSummary);
}

POST /v1/withdraw ​

IP Whitelist Required

This endpoint checks the IP address of the request. You must configure an IP whitelist for your API key in the console. Requests from unlisted IPs will be rejected with error 8002. See Authentication → IP Whitelist.

Initiates a cryptocurrency withdrawal to an external address.

Request Body ​

FieldTypeRequiredDescription
currencystringYesCryptocurrency ticker, e.g. "usdt"
blockchainstringYesBlockchain identifier, e.g. "bsc", "tron"
addressstringYesDestination wallet address
amountstringYesAmount to withdraw as a decimal string, e.g. "100.00"
extrastring | nullNoMemo/tag for blockchains that require it (e.g. XRP, TON)

Response ​

json
{
  "data": {
    "id": "b44ac754-b67a-4d79-8c78-61e01b9c1196"
  },
  "errorObject": null
}

Errors ​

appCodeDescription
8000Withdrawal creation failed (insufficient balance, invalid address, or service unavailable)
8002IP whitelist not configured for this API key
7003Request IP is not in the whitelist

Node.js SDK ​

typescript
const response = await client.withdraw({
  currency: 'usdt',
  blockchain: 'bsc',
  address: '0xYOUR_WALLET_ADDRESS',
  amount: '100.00',
});

if (response.errorObject) {
  console.error('Withdrawal failed:', response.errorObject);
} else {
  console.log('Withdrawal ID:', response.data.id);
}

GET /v1/withdraw/:id ​

IP Whitelist Required

Same requirement as POST /v1/withdraw — IP whitelist must be configured. See Authentication → IP Whitelist.

Returns the current status of a withdrawal.

Path Parameters ​

ParameterDescription
idThe withdrawal ID returned by POST /v1/withdraw

Response ​

json
{
  "data": {
    "status": "finished",
    "hash": "0xabc123..."
  },
  "errorObject": null
}

hash is the on-chain transaction hash, available once the transaction is broadcast.

Withdrawal Statuses ​

StatusDescription
createdWithdrawal queued, not yet processed
pendingTransaction submitted to the blockchain
finishedTransaction confirmed on-chain
failedWithdrawal could not be completed

Errors ​

appCodeDescription
8001Withdrawal not found or does not belong to your project

See Also ​

Released under the MIT License.