Guide

Sandbox & test cards

Manza provides a sandbox environment so you can integrate, test edge cases, and verify webhook handling without moving real money or charging real cards.

Accessing the sandbox#

Use the Manza sandbox for your region. Sandbox and production data are isolated: API keys, customers, payments and webhook endpoints from one environment do not appear in the other. Use a key created in the same sandbox as your API base URL.

RegionSandbox dashboardSandbox API base
Moroccoma.manza.devhttps://ma.manza.dev/api
South Africaza.manza.devhttps://za.manza.dev/api

Open Settings → Developer → API Keys in that sandbox dashboard and create a dedicated key. Select entity:read for the first request below, plus the scopes needed by your integration. Copy the key when it is shown and store it securely; do not place it in browser code or source control.

Verify API access#

Set MANZA_API_KEY in your backend environment to your sandbox key. Set MANZA_BASE_URL to https://ma.manza.dev for Morocco or https://za.manza.dev for South Africa — the host without the /api suffix, which is what the official SDKs read (they append /api/... themselves). Then make this read-only request:

curl "$MANZA_BASE_URL/api/entity" \
  -H "Authorization: Bearer $MANZA_API_KEY"

A 200 response returns the workspace associated with your key. Confirm it is the workspace you intended before continuing. API access and workspace activation must be enabled in the sandbox; creating a key does not enable product access.

ResponseWhat to check
401Check the Bearer token and confirm the key was created in this sandbox, not production or the other region.
403 with error.type = insufficient_scopeCreate a key with the endpoint's required scope. Existing keys do not gain new scopes automatically.
403 with error.message = Feature not enabled or API access not enabledAsk support to enable the required access for your sandbox workspace. Share the workspace and sandbox URL, never the API key.
403 with error.type = entity_inactiveComplete workspace activation or ask support about activation of your sandbox workspace.

Product feature access and API-key scopes are checked separately. A successful entity request verifies authentication and basic API access; it does not prove every product endpoint is enabled. Follow the relevant API reference for its required scopes and approval flow.

Test cards#

Use these card numbers on any sandbox hosted payment page. Any future expiry date, any 3-digit CVC, and any postcode are accepted.

Card numberBrandResult
4242 4242 4242 4242VisaPayment succeeds
5555 5555 5555 4444MastercardPayment succeeds
4000 0000 0000 0002VisaCard declined
Real card numbers are never charged on the sandbox. Submitting one returns a generic decline.

Reconciling payment state#

Two ways to confirm whether a sandbox payment succeeded:

  • API — GET the checkout session or payment link and check the status field.
  • Webhooks — listen for checkout_session.completed or payment_link.paid. Sandbox webhooks fire identically to production, signed with the same scheme.
Webhooks are the source of truth for fulfillment. Use the API endpoints for reconciliation or recovery when a webhook is missed.

A confirmed payment first reads clearing (credited, provider settlement pending, settled_at null) — sandbox included. Fulfill on checkout_session.completed / payment_link.paid; if you also track settlement, listen for checkout_session.settled / payment_link.payment_settled, which fire once settled_at is set.

Going live#

When your sandbox integration is stable:

  1. Mint a fresh API key from the production dashboard (production keys can't be cloned from sandbox).
  2. Switch your application's base URL from the sandbox host to production.
  3. Replace test-card flows with real card collection (the hosted page handles PCI).
  4. Re-register your webhook endpoint against the production dashboard.