Selecting sandbox
Send a request with aypk_test_... key. There is no separate URL — the same
https://api.yuvexpay.com base URL serves both environments.
Payment behavior matrix
The terminal status is not reached at creation.POST /v1/payments always
returns the non-terminal status — NEW, or PENDING_METHOD_SELECTION for a
hosted checkout. A status check runs about 5 seconds later and writes the
outcome; in the hosted flow, 5 seconds after the payer selects a method.
The outcome is picked from the decimal cents of the requested amount:
So
R$ 49.02 simulates an unpaid PIX, R$ 99.04 simulates an expired PIX, and
any value ending in .01 (R$ 1.01, R$ 49.01, R$ 1000.01) simulates a
successful payment.
These recipes drive PIX only. Sandbox CARD and BOLETO charges are created
at the card and boleto acquirer rather than at the PIX simulator, so their cents
are ignored — drive those with
POST /v1/payments/{paymentId}/simulate.
Forcing a terminal status
POST /v1/payments/{paymentId}/simulate moves a sandbox payment to a terminal
status immediately, whatever its amount and payment method. Use it instead of
waiting for the check, and to reach outcomes the cents table cannot produce.
It requires the payments:write scope and a ypk_test_ key. A production key is
rejected with 403 and error code FORBIDDEN. A production payment id is not
visible to a sandbox key at all, so it returns 404.
Any other value is rejected with
400. The response is the updated payment, in
the same shape as GET /v1/payments/{paymentId}.
X-Idempotency-Key is optional here — honoured when you send it, not required.
Withdrawal behavior matrix
Sandbox withdrawals follow the same convention. The status is reached synchronously, so aGET /v1/withdrawals/{withdrawalId} right after creation already shows it:
Refund behavior matrix
The decimal portion is read from the payment amount being refunded, not the
refund request itself.
Webhooks in sandbox
A webhook endpoint belongs to the account, not to an environment: there is no separate sandbox endpoint and no separate sandbox secret. So a sandbox charge that reachesPAID produces no PAYMENT_PAID delivery, and waiting for one
will not succeed.
Read the resource instead. Poll GET /v1/payments/{paymentId} or
GET /v1/withdrawals/{withdrawalId} and read status. A withdrawal is already
terminal on the first read; a payment reaches its terminal status about 5
seconds after creation, or immediately if you call
/simulate, which is the fastest way to put a
charge into the state your handler is waiting for.
To exercise your verifier — signature, timestamp skew, header parsing — use
the Send test button on the endpoint in the dashboard. It delivers a real,
correctly signed TEST event to your endpoint with X-Webhook-Event: TEST and
a body of {"event":"webhook.test","createdAt":"…","data":{"message":"…","livemode":false}}.
That is the one delivery a sandbox-only account receives.
See the Webhooks guide for the verification algorithm.
Sandbox idempotency keys
Idempotency keys are scoped per environment. The same key value can be reused in sandbox and production without colliding — they’re separate keyspaces. Within sandbox, the same rules apply as in production: a 24-hour TTL and a payload match on retries.Limits and isolation
- Sandbox payments and withdrawals never affect your production balance or reports.
- Receipts are generated for sandbox payments and withdrawals, and the
lookup is scoped to the key’s environment: a
ypk_test_key resolves only sandbox ids and aypk_live_key only production ids. The other environment returns404even for an id on your own account. - Statements are built from the real-money ledger, which sandbox
transactions never touch.
GET /v1/documents/statementswith a sandbox key therefore returns an empty statement with zero balances, not your production ledger. - Splits stay inside one environment. A sandbox payment can only split to a
company that is in sandbox mode, and a production payment only to a production
company; the other direction is always rejected, never silently ignored, with
400 SPLIT_RELATIONSHIP_PENDINGwhen the recipient has not accepted in this environment and400 SPLIT_ENVIRONMENT_MISMATCHwhen it had. Consent is per environment, so a recipient that accepted in production still has to accept in sandbox. A sandbox split never touches a production balance, statement or report. - Webhooks are not delivered — see Webhooks in sandbox.
- Sandbox keys cannot access production data, and vice versa.
Going live
When your integration is stable:- Create a
ypk_live_key in the dashboard (requires completed KYB). - Configure your webhook endpoint and store its secret. This is the point at which webhooks start being delivered at all — verify the endpoint with the dashboard’s Send test button before opening real traffic.
- Swap the API key in your environment variables.
- Run a small live transaction end-to-end before opening real traffic.

