Перейти к содержимому
CoinsSendРазработчикам
Документация Payments

API Quickstart: invoice → webhook

Открыть MarkdownПодключить агента

Это содержимое пока не доступно на вашем языке.

This quickstart walks through a minimal, end-to-end integration path:

  1. Prepare signature-based API key authentication
  2. Create an invoice
  3. Redirect buyer to the payment page
  4. Verify invoice webhooks

  • Base URL: https://api.coinssend.com
  • A merchant ID from your CoinsSend dashboard
  • A merchant API key for signature auth (Merchant + Sign headers; withdrawals also require Timestamp)

References:

Want a coding assistant to build this flow? Use the full checkout prompt in AI Integration Prompts after reviewing these steps.


Step 1) Prepare API key signature auth for merchant endpoints

Section titled “Step 1) Prepare API key signature auth for merchant endpoints”

Get your merchant ID and API key from the CoinsSend dashboard before making public API requests.

For signed endpoints (for example POST /v1/invoices), generate:

canonical_body = json_encode(json_decode(request_body)) using PHP defaults
Sign = md5(base64(canonical_body) + API_KEY)

Withdrawal requests use a stricter timestamped signature instead:

Timestamp = current Unix timestamp in seconds
Sign = hmac_sha256(base64(canonical_body) + "." + Timestamp, API_KEY)

Send canonical_body as the request body. PHP’s default JSON encoding escapes slashes and non-ASCII characters, so plain JSON.stringify() output is not always equivalent.

Example in Node.js:

import { createHash } from 'node:crypto';
function canonicalJson(value) {
return JSON.stringify(value)
.replace(/\//g, '\\/')
.replace(/[\u0080-\uFFFF]/g, (character) =>
`\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`
);
}
const body = canonicalJson({
order_id: 'order_10001',
amount: '100.50',
is_customer_fee: true,
allow_card_payments: true,
success_url: 'https://merchant.example/pay/success',
cancel_url: 'https://merchant.example/pay/cancel'
});
const sign = createHash('md5')
.update(Buffer.from(body).toString('base64') + process.env.COINSSEND_API_KEY)
.digest('hex');

Required headers for signed merchant API calls:

  • Merchant: <MERCHANT_ID>
  • Sign: <computed_md5_signature>
  • Content-Type: application/json

For POST /v1/withdrawals, send Timestamp: <unix_timestamp_seconds> and set Sign to the HMAC-SHA256 value.


Terminal window
BODY='{"order_id":"order_10001","amount":"100.50","is_customer_fee":true,"allow_card_payments":true,"success_url":"https:\/\/merchant.example\/pay\/success","cancel_url":"https:\/\/merchant.example\/pay\/cancel"}'
# BODY is canonical PHP-compatible JSON. Compute SIGN from these exact bytes.
SIGN='<computed_md5_signature>'
curl -X POST "https://api.coinssend.com/v1/invoices" \
-H "Content-Type: application/json" \
-H "Merchant: $MERCHANT_ID" \
-H "Sign: $SIGN" \
-d "$BODY"

Example response:

{
"status": "success",
"data": {
"id": "4e7d786f-a4a6-4a42-b0e5-6f2bb8a5f0f2",
"order_id": "order_10001",
"url": "https://pay.coinssend.com/invoice_code",
"code": "invoice_code",
"amount": "100.50",
"payer_amount": "100.50",
"expired_at": "2026-04-03T12:00:00+00:00",
"created_at": "2026-04-02T12:00:00+00:00"
}
}

Use data.url from invoice creation response as the checkout URL.

  • Typical shape: https://pay.coinssend.com/{invoice_code}
  • data.code can also be used with public invoice lookup: GET /v1/invoices/{invoiceCode}
  • Direct crypto payment is always available. Card checkout is shown only when allow_card_payments is true and the invoice amount or remaining amount is at least $15.00 / 1500 cents.
  • allow_card_payments and provider_card can appear in invoice lookup and payment-page invoice payloads, but they are not part of the POST /v1/invoices create response.
  • Redirects from success or cancel URLs, provider redirects, provider webhooks, and provider status polling are only UX signals or provider hints. Confirm payment from invoice status changes after chain confirmation, usually through signed webhooks.

When invoice/payment state changes, CoinsSend sends signed webhook callbacks to your webhook URL.

Common events for this flow:

  • invoice.paid
  • invoice.expired
  • aml.rejected.invoice (when AML blocks invoice deposit)

Verify X-Signature using your API key and the raw request body bytes:

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $apiKey);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('invalid signature');
}
  • Expand invoice validation and error handling: Invoices
  • Add duplicate-safe processing in your webhook consumer: Webhooks
  • Do not blindly retry invoice creation: the endpoint has no idempotency-key contract. Reconcile by order_id before deciding whether to create again.
  • Review request signing details: Authentication