Test mode

A simulated chain, including the three failures nobody can otherwise rehearse.

A sk_test_ key puts every call against a simulated chain. Same endpoints, same response shapes, same events — the only difference is that nothing costs anything and the chain does what you tell it.

Why it is a key prefix and not a separate host

Because the code that goes to production is then the code you tested. A separate sandbox host means a base URL somebody has to remember to change, and the class of bug where they did not.

Test data and live data are separate; a test key cannot see live objects, and a live key cannot see test ones.

Pay without any USDT

curl -X POST $PAYGATE/v1/test/payments/{id}/pay \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" -d '{}'

Pay a partial amount to reach underpaid:

curl -X POST $PAYGATE/v1/test/payments/{id}/pay \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"amount_decimal":"10.00"}'

Move the chain

Confirmations arrive when blocks do. Advance them:

curl -X POST $PAYGATE/v1/test/advance \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"blocks":12}'

The three that matter

Reorg. Undo a confirmed payment. paid becomes reversed, and payment.reversed is emitted:

curl -X POST $PAYGATE/v1/test/payments/{id}/reorg \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" -d '{}'

Late payment. Let a payment expire, then pay it. It completes rather than being lost, and raises payment.late_payment.

Underpayment. Above. Then top it up with a second partial payment and watch it complete.

If your integration has never seen these three, it has not been tested — it has been demonstrated.

Mandates in test mode

Recurring payments need a customer's on-chain authorisation, which in test mode is a call rather than a wallet signature:

# fund the simulated customer
curl -X POST $PAYGATE/v1/test/mandates/{id}/fund \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"amount_decimal":"500.00"}'

# and sign
curl -X POST $PAYGATE/v1/test/mandates/{id}/authorize \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" -d '{}'

A simulated authorisation raises mandate.authorized exactly as a real one does — otherwise test mode would authorise the mandate and tell nobody, and that event is the only report you have that your customer signed.

What test mode is not

It is not a second gateway. /v1/test/* answers 501 on a deployment built without the simulated chain — which is honest, where a 404 would suggest the endpoint was never real.