Skip to main content
POST
Create a payin
Creates a payin and returns the hosted checkout URL. See Payins for how the flow fits together.
The fields above are what you encrypt, not what goes on the wire. The body is always { "data": "<aes-256-gcm ciphertext>" } — see Authentication.
No JWT. Unlike the payout endpoints, payin endpoints do not take an authorization header — creating a payment link moves no money on its own, so it is authenticated by your API key, request signature and IP allowlist alone. You can skip the login call entirely for a payin-only integration.
success_url and fail_url hosts must be registered on your merchant profile before they will be accepted — an unregistered host is rejected with redirect_domain_not_allowed before a payment is created. Ask your account manager to add them.

Idempotency

Reusing a merchant_reference returns the existing payment rather than creating a second one. A retry after a network timeout is safe and gives you back the original checkout_url. The status code is how you tell the two apart: 201 means you just created it, 200 means this merchant_reference was already used and you are getting the original payment — and its original checkout_url — back.
The checkout_url is a bearer credential. Anyone holding it can see the order amount and the deposit address. Send it to your customer directly — do not log it, email it to a shared inbox, or put it anywhere indexable.

Example request

All examples assume you’ve already encrypted the body and signed the request. The transport is identical to payouts, so the helper in Payouts quickstart is the same one both products use.

Errors

Quote request_id when you contact support — it identifies the exact request in our logs.
A 503 is about us, not your request: retry the same payload with backoff and it will succeed once the condition clears. A 4xx will not change on retry. See Errors for the envelope shape shared by every endpoint.

Authorizations

x-api-key
string
header
required

Identifies your account. Issued from Developer Tools in the dashboard.

Headers

x-timestamp
integer<int64>
required

Unix epoch in seconds — not milliseconds. Must be within ±5 minutes of our clock, which is what makes a captured request unusable later. Keep your client's clock NTP-synced.

Example:

1748023400

x-signature
string
required

HMAC-SHA256 over the signing string, hex encoded. The timestamp is part of what is signed, so a replayed body cannot be re-dated. See https://docs.pontisglobe.com/authentication for how it is built.

Example:

"2f8a9b4c1d7e0a3f6b8c2d5e9f1a4b7c0d3e6f9a2b5c8d1e4f7a0b3c6d9e2f5a"

Body

application/json
merchant_reference
string
required

Your own order id. Also the idempotency key.

Required string length: 1 - 128
Example:

"ORDER-1042"

amount
string
required

A positive decimal string, at most 2 decimal places. More than two is rejected rather than rounded — a sub-cent order would have the payer charged something the merchant's own order does not say.

Pattern: ^\d+(\.\d+)?$
Example:

"100.00"

success_url
string<uri>
required

https only, no embedded credentials, and the host must be on your account's allowed domains.

fail_url
string<uri>
required
currency
enum<string>
default:USDT
Available options:
USDT
expires_in_seconds
integer

5 minutes to 24 hours. Also how long a deposit address stays open.

Required range: 300 <= x <= 86400

Response

Idempotent replay — this merchant_reference already existed. The status code is the only difference from 201.

ok
enum<boolean>
Available options:
true
data
object