Skip to content

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.co

Use 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 typeNumberResult
Visa4242 4242 4242 4242Charge succeeds.
Visa (debit)4000 0566 5566 5556Charge succeeds.
Mastercard5555 5555 5555 4444Charge succeeds.
American Express3782 822463 10005Charge succeeds.

Declines

Card typeNumberResult
Visa4000 0000 0000 0002Generic decline.
Visa4000 0000 0000 9995Insufficient funds.
Visa4000 0000 0000 9987Lost card.
Visa4000 0000 0000 9979Stolen card.
Visa4000 0000 0000 0069Expired card.
Visa4000 0000 0000 0127Incorrect CVC.
Visa4000 0000 0000 0119Processing 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 typeNumberBehaviour
Visa4000 0027 6000 3184Requires 3DS authentication; succeeds when the shopper confirms.
Visa4000 0082 6000 3178Requires 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.

  1. Subscribe your sandbox endpoint (portal, or the subscription API) and store the signing secret it returns.
  2. Send a webhook.test event from the portal — it bypasses your event-type filter, so it always lands. Confirm your signature verification passes and you respond 2xx.
  3. 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:

  1. Happy path — create a checkout, complete it with 4242 4242 4242 4242, confirm your checkout.authorized handler fires, captures, and the checkout reaches captured. (Legacy flow: confirm your success page captures after landing on return_url.)
  2. 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.
  3. Duplicate delivery — replay the same event (same envelope id) at your handler. Confirm you don't fulfil twice.
  4. Decline — pay with 4000 0000 0000 0002. Confirm your code reacts to the failed status and doesn't fulfil the order.
  5. Abandonment — start a checkout, close the Maytes window. Confirm the shopper lands on your cancel_url and your order stays in the right state.
  6. Cancel — for a checkout that authorized but you don't want to capture, call /cancel. Confirm the status reaches voided and you receive checkout.voided with reason: "merchant_cancel".
  7. Amount mismatch — send a total_amount that doesn't reconcile with your line items. Confirm you handle 422 invalid_amount_arithmetic.
  8. Order-already-authorized — retry your create call for the same merchant_order_id. Confirm you handle 409 order_already_authorized by reusing the existing checkout_uuid instead 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.