Crypto top-up API lifecycle
The cryptocurrency payments guide walks the dashboard flow. This page is the same lifecycle driven from an integration: you create the top-up, open the hosted invoice URL for the payer, poll the intent until it settles, and optionally cancel it while the invoice is still unfunded. Every sample below is copy-pasteable. The three endpoints require an API key carrying thebilling:write scope (or an owner, admin, or billing dashboard
session) and are rate-limited as money-moving operations.
1. Create a top-up intent
POST /api/v1/billing/balance/top-up-crypto mints a NOWPayments hosted
invoice and returns its URL. Idempotency-Key is required: re-submitting
the same key returns the original invoice instead of minting a new one, and
re-using the key with a different (amount, currency) returns
409 IDEMPOTENCY_KEY_REUSED.
200
amountis in minor units (cents): minimum100(10,000).currencyaccepts onlyusdtoday — the wallet ledger is USD-denominated.successUrlandcancelUrlmust be on a trusted origin (orbit.devotel.io).feePaidByUserreflects the network-fee policy: for top-ups of 50 the fee is added on top ofamountat the hosted invoice (feePaidByUser: true,feeCents: 0).- If crypto top-up is not yet enabled for your account, the endpoint returns
503 SERVICE_UNAVAILABLE— use Stripe Checkout in the meantime.
checkoutUrl in a browser for the payer. The coin and the exact
crypto amount are chosen on the hosted page; the intent settles once the
network confirms the transfer.
2. Poll the status
GET /api/v1/billing/crypto-topup/{intentId}/status returns the current
state of the intent. Poll it with a few seconds’ spacing while the payment
settles; the endpoint self-heals a dropped provider callback, so the poll
always reflects the latest known state. Read scope (billing:read) is
sufficient for this call.
200
metadata carries them:
order_id, plus on-chain fields such as pay_address, pay_amount, and
expires_at, as the provider surfaces them — not every coin reports
every field. A 404 means the intent does not exist or belongs to a
different organization.
Stop polling when paymentStatus reaches a terminal state:
- Success terminal:
finished— the wallet is credited;refunded. - Retry terminal:
failed,expired,cancelled— create a new intent to try again. See the state table linked below before retrying.
3. Cancel a pending top-up
POST /api/v1/billing/crypto-topup/{intentId}/cancel cancels an intent
while it is still unfunded. Cancellation succeeds only in waiting or
confirming; once the payment is confirmed, sending, finished,
refunded, failed, or already expired, the cancel is rejected and the
response carries the live status.
200
409
details.current_status always shows the live state (finished,
confirmed, sending, refunded, failed, expired, or cancelled),
so re-poll the status endpoint after a 409. Cancellation is Orbit-side
only — the provider has no invoice-cancel API, so the receiving address
stays open — and a cancel never loses money: if funds arrive after you
cancel, the settlement callback overrides cancelled and credits your
wallet exactly once.
4. Status taxonomy
The full state machine — every status, its meaning, and which states allow a cancel — is maintained on the guide: Status meanings. The common path iswaiting → confirming → confirmed → sending → finished.
5. Webhook events on settlement
When the top-up reachesfinished and the wallet is credited, Orbit
delivers balance.topped_up to your webhook endpoints, tagged
payment_method: "crypto_nowpayments" with amount_cents and currency
in the payload. The same event fires for Stripe (card) top-ups, so one
handler covers both funding sources. Subscribe to it under Dashboard →
Developers → Webhooks; the full billing event list is in the
webhook event catalog.
Use the webhook instead of long-running polling: create the intent, show
the invoice, and treat balance.topped_up as the definitive receipt that
the wallet moved. Poll the status endpoint as a fallback when the event
has not arrived yet.
6. Sandbox behavior
Sandbox mode short-circuits messaging and voice sends before they touch a carrier; money endpoints behave differently. Crypto top-ups run against the real NOWPayments service — Orbit’s staging integration points at the NOWPayments sandbox environment (api-sandbox.nowpayments.io), where
invoices behave like the real thing without moving real funds.
In practice:
- There are no magic numbers for crypto top-ups — the magic-number convention applies to message, voice, and number-purchase simulation, not to billing.
- On developer staging: exercise both lifecycle paths for free (create → poll, and create → cancel) against the NOWPayments sandbox environment.
- On production: cancel an unfunded intent (step 3) to test your lifecycle handling without spending funds. Never send test transfers on a live account — settled crypto is non-refundable without operator action.
Related pages
- Cryptocurrency payments — dashboard flow, status meanings, refunds, fee policy.
- Crypto refunds — operator-driven refund flow.
- Webhook events — the full billing event catalog.
- Authentication — API key scopes and headers.