SDK — crypto orders
The client.cryptoOrders resource wraps every
customer-facing endpoint on the surface with full type
safety. Admin endpoints are not exposed; integrators that need
them call the REST surface directly.
Quote
Preview a tier's fiat-cents price (and the crypto pay range, once NowPayments is wired up) without minting an order:
const quote = await client.cryptoOrders.quote({ product: 'solo_manual' });
console.log(quote.price_cents, quote.price_currency); Mint a checkout
Always pair the call with an idempotencyKey so
accidental double-submits don't mint duplicate orders:
const key = crypto.randomUUID();
const order = await client.cryptoOrders.createCheckout(
{ product: 'team_manual', price_cents: 4900, price_currency: 'USD' },
{ idempotencyKey: key },
);
console.log(order.order_id, order.payment_address);
On a duplicate key within the 24h window, the SDK returns the
original order — same order_id, same
created_at. See
/docs/idempotency-keys.
List + drill down
const { orders } = await client.cryptoOrders.list();
for (const o of orders) {
console.log(o.order_id, o.status, o.expires_at);
}
// V-666.BR — narrow to a single status server-side.
const { orders: paid } = await client.cryptoOrders.list({
status: 'paid',
limit: 25,
});
const single = await client.cryptoOrders.get('ord_abc123def456');
console.log(single.events); // V-666.AU timeline status accepts pending,
confirming, paid, failed,
partial, or cancelled. Unknown values
return a 400 from the server. limit is clamped to
1..=100; the default is 50.
Pagination
// V-666.BU — explicit cursor paging.
let cursor: string | undefined;
while (true) {
const page = await client.cryptoOrders.list({ status: 'paid', cursor });
for (const o of page.orders) console.log(o.order_id);
if (!page.next_cursor) break;
cursor = page.next_cursor;
}
// Or use the async iterator helper:
for await (const o of client.cryptoOrders.listAll({ status: 'paid' })) {
console.log(o.order_id);
} Update the customer note
await client.cryptoOrders.updateNote('ord_abc', {
customer_note: 'PO-9921',
}); Cancel a pending order
try {
await client.cryptoOrders.cancel('ord_abc');
} catch (err) {
// 409: order has moved past pending; cancellation is no longer self-service.
// 404: order doesn't exist or belongs to another account.
} Crypto payments are non-refundable. Cancelling a pending order halts its pay window; cancelling a paid order is not supported — past billing periods stay billed. See /legal/refunds.
Fetch the receipt
The JSON receipt is the canonical machine-readable artefact. For PDF / text variants, hit the corresponding REST endpoint directly:
const receipt = await client.cryptoOrders.receipt('ord_abc');
console.log(receipt.paid_at, receipt.price_cents); Listening for settlement
crypto.order.paid / crypto.order.failed
events are emitted server-side and are now subscribable — see
/docs/webhooks-crypto-events
for the payload contract. For integrations without an inbound
HTTPS endpoint, poll
client.cryptoOrders.get(order_id) until
status transitions to paid or
failed. The SDK ships
verifyWebhookSignature for every live event type,
including the now-live crypto.order.* events alongside the
session + quota + api-key + egress-capability event domains.
End-to-end example
A runnable end-to-end walkthrough — quote, idempotent checkout,
update note, fetch receipt, cursor-iterate paid orders — ships
with the SDK as packages/sdk-typescript/examples/crypto-checkout.ts.
Run with DRIFTSTACK_API_KEY=... npx tsx examples/crypto-checkout.ts.