Crypto is currently the only payin rail. The integration itself is not crypto-specific — you
create a payment, redirect the customer, and act on a callback. If other rails are added, those
three steps do not change; only the fields describing the crypto leg stop being the only option.
Before you start
Four things must be set up on your account. Ask your account manager — none of them are self-service:
You will also need your API credentials from
Developer Tools — the same API Key, Encryption
Secret and HMAC Secret the payout API uses.
1. Set up the request helper
Payins use the identical transport as every other endpoint: an AES-256-GCM encrypted body, an HMAC-signed request, and your API key. If you already integrated payouts, reuse the helper you already have — there is nothing new to write. If you are starting fresh, copy thecall() helper from
Quickstart step 2. It is available in Node, Python, Go
and Java.
Payin endpoints take no JWT. Creating a payment link moves no money by itself, so it is
authenticated by your API key, request signature and IP allowlist. A payin-only integration never
calls
/api/v1/user/login.2. Create the payment
CallPOST /api/v1/gateway/payments/create with your own order
reference and the amount.
checkout_url and an expires_at.
merchant_reference is your idempotency key. Reusing it returns the existing payment instead
of creating a second one, so a retry after a network timeout is safe and hands you back the same
checkout_url. Use one reference per order.3. Redirect your customer
Send them tocheckout_url. That page is hosted by us and carries your branding.
On that page your customer picks a currency and network, sees a deposit address and a QR code, and
sends the funds from their own wallet. When they finish they are returned to your success_url;
if they cancel, to your fail_url.
4. Handle the callback
We POST a signed JSON body to your callback URL when the payment settles. This is the event you fulfil on — full details in Payin callbacks.- Verify the signature. Same headers and same scheme as payout callbacks, so your existing verification code works unchanged.
- Be idempotent. Unlike payouts, payin callbacks are retried — up to 8 attempts — so the same event can arrive more than once.
- Handle all three settled statuses separately.
paidandoverpaidmean the customer paid in full — fulfil.underpaidmeans they paid less, by any amount, and must never auto-fulfil.
5. Confirm with a status lookup (optional)
POST /api/v1/gateway/payments/status reads back a payment by
your own reference.
For reconciliation and support, not for driving fulfilment. Polling it in a loop will be rate
limited and will always be slower than the callback already on its way to you.
What your customer can pay with
The checkout offers the assets you are configured to accept, on the networks we support for each. It is a matrix, not a list — an asset is not available on every network:
Two things follow from accepting more than one:
- You end up holding whichever your customer chose. Accepting USDC means you will have a USDC balance, separate from your USDT balance. There is no automatic conversion between them.
- Your payout currencies must keep up. A balance in an asset you are not enabled to pay out from is money you can see and cannot move. Ask for both to be enabled together.
The three currencies on a payment
A single payin involves three currencies and they are frequently different. Confusing them is the most common integration mistake here, so every response names each one explicitly:
On the status endpoint the same value is called
deposit_asset — it is the asset the customer
deposited, which is by definition the one you were credited in.
Amounts and fees
requested_amount— what you asked formerchant_fee_amount— the total we charge you, as a single figurecredited_amount— what reached your balance, after our fee
"100.00", not 100.00. Parsing them into a
floating-point type will eventually cost you precision on a real payment.
Order amounts accept at most 2 decimal places. A finer amount is rejected at create time rather
than rounded, so your customer is never charged a different figure than your order says.
Payment statuses
Expiry is not final
A checkout link has a deadline — 30 minutes by default, set per payment withexpires_in_seconds (minimum 5 minutes, maximum 24 hours). When it passes, the payment stops being
one we expect to settle.
30 minutes is short on purpose: it is roughly how long a customer stays in a checkout, and the
window is also how long we hold a deposit address open. If your customers pay from an exchange
withdrawal rather than a self-custody wallet, raise it — those can take far longer to clear.
paid, and you still get the callback. Expiry stops us waiting; it does not close the
door. Do not treat expired as a terminal refusal in your own system.
Reconciliation
Payins appear in your monthly statement in their own Payments Received section, separate from payouts, with totals per credited currency. A month in which you only took payments and sent none still produces a statement. They also appear in your transactions list asgateway_deposit rows, each showing the currency it was credited in.
Testing in sandbox
Change the base URL tohttps://sandbox.pontisglobe.com and everything else stays the same. Nothing
is stored, no deposit address is reserved, and no money can move.
The outcome is driven by the last two digits of your merchant_reference, so you can reproduce a
paid, underpaid or overpaid payment on demand. Full walkthrough and the trigger table:
Sandbox — payins.
Going live
Everything in Going live applies. Additionally, for payins:- Redirect hosts registered for production — your live
success_url/fail_urlhosts are allow-listed separately from any test ones - Callback handler idempotent and signature-verified — payin callbacks retry, so a handler that double-fulfils will double-fulfil in production
- All three settled statuses handled, and
underpaidhandled separately — confirm a partial payment does not reach your fulfilment path - Payout currencies cover the assets you accept — otherwise a real customer payment lands in a balance you cannot move
- One small live payment end to end — confirm the callback arrives, the balance moves, and the transaction appears before you send customers to it