Appearance
Sandbox environment
Maytes provides a fully isolated sandbox environment for building and validating your integration before going live. Sandbox traffic is separated from production: no real money moves, no real settlements happen, and accounts you create in the sandbox never appear in your live merchant portal.
Sandbox base URL
https://sandbox-api.maytes.coUse your sandbox client_id / client_secret (from the merchant portal) against this host. The API shape is identical to production — only the host and credentials change. See Environments for the full list.
Test cards
Payments in the Maytes window are processed through Stripe. In the sandbox, use these card numbers — any future expiry date, any 3-digit CVC, and any postal code are accepted.
Successful payments
| Card type | Number | Result |
|---|---|---|
| Visa | 4242 4242 4242 4242 | Charge succeeds. |
| Visa (debit) | 4000 0566 5566 5556 | Charge succeeds. |
| Mastercard | 5555 5555 5555 4444 | Charge succeeds. |
| American Express | 3782 822463 10005 | Charge succeeds. |
Declines
| Card type | Number | Result |
|---|---|---|
| Visa | 4000 0000 0000 0002 | Generic decline. |
| Visa | 4000 0000 0000 9995 | Insufficient funds. |
| Visa | 4000 0000 0000 9987 | Lost card. |
| Visa | 4000 0000 0000 9979 | Stolen card. |
| Visa | 4000 0000 0000 0069 | Expired card. |
| Visa | 4000 0000 0000 0127 | Incorrect CVC. |
| Visa | 4000 0000 0000 0119 | Processing error. |
Use these to exercise your error handling — a declined checkout transitions to failed, and your integration shouldn't fulfil the order.
3-D Secure authentication
| Card type | Number | Behaviour |
|---|---|---|
| Visa | 4000 0027 6000 3184 | Requires 3DS authentication; succeeds when the shopper confirms. |
| Visa | 4000 0082 6000 3178 | Requires 3DS authentication; fails when the shopper confirms. |
The shopper will see Stripe's 3DS challenge inside the Maytes window. Approve or decline it to test both paths.
The full Stripe test-card catalogue (international cards, fraud-blocked numbers, AVS variations, etc.) lives in Stripe's docs.
Testing webhooks
Webhook deliveries are HTTPS POSTs from the public internet, so your endpoint must be reachable — for local development put a tunnel (ngrok, cloudflared) in front of your dev server and subscribe the tunnel URL.
- Subscribe your sandbox endpoint (portal, or the subscription API) and store the signing secret it returns.
- Send a
webhook.testevent from the portal — it bypasses your event-type filter, so it always lands. Confirm your signature verification passes and you respond 2xx. - Check the delivery log (portal, or
GET /api/merchant/v1/webhooks/deliveries) — every attempt is recorded with the HTTP status your endpoint returned, which is usually all you need to debug a misbehaving handler.
What to test before going live
A reasonable smoke list for a new integration:
- Happy path — create a checkout, complete it with
4242 4242 4242 4242, confirm yourcheckout.authorizedhandler fires, captures, and the checkout reachescaptured. (Legacy flow: confirm your success page captures after landing onreturn_url.) - Signature rejection — send a request to your webhook endpoint with a bad signature. Confirm you reject it with a 4xx and don't process it.
- Duplicate delivery — replay the same event (same envelope
id) at your handler. Confirm you don't fulfil twice. - Decline — pay with
4000 0000 0000 0002. Confirm your code reacts to thefailedstatus and doesn't fulfil the order. - Abandonment — start a checkout, close the Maytes window. Confirm the shopper lands on your
cancel_urland your order stays in the right state. - Cancel — for a checkout that authorized but you don't want to capture, call
/cancel. Confirm the status reachesvoidedand you receivecheckout.voidedwithreason: "merchant_cancel". - Amount mismatch — send a
total_amountthat doesn't reconcile with your line items. Confirm you handle422 invalid_amount_arithmetic. - Order-already-authorized — retry your create call for the same
merchant_order_id. Confirm you handle409 order_already_authorizedby reusing the existingcheckout_uuidinstead of recreating.
Sandbox data is isolated
The sandbox is a separate world from production:
- No real money moves. Stripe in test mode never charges a real card; settlements never reach a bank account.
- Separate accounts. Customer accounts created in the sandbox only exist in the sandbox.
- Separate portal. Your sandbox merchant portal is separate from your live one.
When you're ready to go live, swap your sandbox credentials for the production pair (from the portal), point your calls at https://api.maytes.co, and create a production webhook subscription — it has its own signing secret. Everything else — request shape, status lifecycle, error codes — is identical.
Next
- Quickstart — the webhook flow end to end, against this environment.
- Webhooks — signature verification and delivery semantics.
- Authentication — how to mint a Bearer token from your credentials.
- API reference — the full schema against the sandbox.
