Get API Keys

The Crypto Payment API You Can Read in Ten Minutes

Two calls to take money, one webhook to trust it. This is how the API works; the full reference comes with your keys.

Authentication

Every request from your server uses HTTP Basic auth: your project ID as the user name and your project secret as the password. Keep the secret on your server; it also signs your webhooks.

The API address and the full reference come with your project keys.

HTTP
Authorization: Basic base64(PROJECT_ID:PROJECT_SECRET)

Create an Invoice

Use an invoice when the customer pays for one order. Pass your own 24-character order ID as payload, the price in USD, how far an amount may fall short (0 to 5%), the expiry time and the URL that receives this invoice's webhooks.

payloadYour order ID, 24 hexadecimal characters
meta.pricePrice in USD
meta.tolerancePercentAllowed shortfall, 0 to 5
meta.expiresAtExpiry, ISO 8601, in the future
meta.webhookUrlWhere this invoice's events are sent
Request
{
  "payload": "65f2c1a9e4b0d3f7a2c91e04",
  "meta": {
    "price": "120",
    "tolerancePercent": "1",
    "expiresAt": "2026-12-01T12:00:00Z",
    "webhookUrl": "https://shop.example/webhooks/rubysend"
  }
}

The response carries an addresses object keyed by network. Show your customer the networks you want to offer.

200 OK
{
  "id": "0b6f3c1e-8a52-4d7e-9c41-2f6a8d0e5b17",
  "payload": "65f2c1a9e4b0d3f7a2c91e04",
  "meta": {
    "type": "invoice",
    "status": "pending",
    "price": "120",
    "paid": "0",
    "expiresAt": "2026-12-01T12:00:00.000Z"
  },
  "addresses": {
    "tron": "T…",
    "ethereum": "0x…",
    "bsc": "0x…",
    "bitcoin": "bc1q…"
  }
}

Permanent Deposit Addresses

Use permanent addresses for top-ups: wallets, games, exchanges, subscriptions. Pass your customer's 24-character ID as payload and get the same addresses every time.

{ "payload": "66a0b7d2c5e8f1a3b6d904c7" }

Invoice Statuses

pendingWaiting for payment
paidThe full price arrived
underpaidLess than the price arrived
overpaidMore than 1% above the price arrived
expiredNo payment before the expiry time

Webhooks

Each event is a POST with a JSON body and an X-Webhook-Signature header: the HMAC-SHA256 of the raw body, keyed with your project secret decoded from hex, written as hex. Answer with any 2xx status. Anything else is retried: invoice events every 15 seconds until delivered, payment events every 10 minutes, up to 150 times.

Events

invoice:<status>An invoice changed status
pending-paymentA payment was seen and is waiting for confirmations
confirmed-paymentA payment was confirmed and credited
failed-paymentA payment could not be processed
Webhook
POST /webhooks/rubysend
Content-Type: application/json
X-Webhook-Signature: 9c1fd2…e07a

{
  "id": "4e1a…c93f",
  "message": {
    "event": "invoice:paid",
    "data": { "id": "0b6f3c1e-…", "payload": "65f2c1a9e4b0d3f7a2c91e04" }
  },
  "attempt": 0,
  "timestamp": 1764590400
}

Verify the Signature

import crypto from 'node:crypto';
import express from 'express';

const secret = Buffer.from(process.env.RUBYSEND_SECRET, 'hex');

// keep the raw body: the signature covers its exact bytes
app.post('/webhooks/rubysend', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto.createHmac('sha256', secret).update(req.body).digest('hex');
  const given = req.get('X-Webhook-Signature') ?? '';
  if (given.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  const { message } = JSON.parse(req.body);
  if (message.event === 'invoice:paid') markOrderPaid(message.data.payload);
  res.sendStatus(200);
});

Confirmations by Network

NetworkCoinsConfirmationsTime to Credit
TRONTRXUSDT1about 3 s
EthereumETHUSDTUSDCDAI5about 1 min
BNB Smart ChainBNBUSDTUSDCDAI10about 8 s
PolygonPOLUSDTUSDCDAI20about 40 s
BaseETHUSDTUSDC10about 20 s
BitcoinBTC1about 10 min
XRP LedgerXRP1about 4 s
DogecoinDOGE3about 3 min

Limits Worth Knowing

  • Payments of $1 or less are ignored as dust
  • Invoice shortfall tolerance: up to 5%
  • An invoice is overpaid when more than 1% above its price arrives
  • A project's secret can be rotated once every 5 minutes

Ready for Your Keys?

We create your project and send you its ID and secret.

Get API Keys