Skip to main content
This walks through the minimum a partner backend needs to do to create a payment intent and hand it off to the Zennopay SDK on mobile. There is one credential to manage — your HMAC signing secret — and no key pair to generate.
Sandbox HMAC keys are issued manually during onboarding for v1. Email partners@zennopay.com to receive a sandbox key ID and signing secret.
Environments. Point everything at the sandbox host (https://api.sandbox.zennopay.com) while integrating; swap to production (https://api.zennopay.com) at go-live. Sandbox HMAC keys are rejected by production and vice versa. See Environments.The older api.zennopay.in / api.sandbox.zennopay.in hosts are still served for existing integrations — zennopay.com is simply the canonical domain for new work.

1. Get your credentials

You will receive exactly two things:
  • A key ID (e.g. acme_sandbox_2026q2).
  • A 32-byte signing secret for HMAC-signed API calls.
That’s it — no RSA key pair, no iss/kid, no JWKS endpoint to publish. Zennopay mints the client session token for you. Store both values as environment variables on your backend:
See Authentication for the full key-management model.

2. Create a payment intent (and get a session token back)

Construct the canonical request string, HMAC-SHA256 it with your signing secret, and send it with the four required headers plus an Idempotency-Key. The body carries your opaque user ID, the authorized USD amount in cents, the corridor, and your per-payment KYC + sanctions attestations.
You should receive a 201 Created. The response carries the session_token (and its expiry) alongside the intent — there is no second call to mint one:
Return intent_id and session_token to your app. See Build your session endpoint for a complete Node.js route.

3. Present the PaymentSheet

Pass the intent_id and session_token to the Zennopay PaymentSheet on the user’s device. The SDK renders the whole pay experience natively, in-process — scan → amount + FX quote → slide-to-pay → result — and delivers one typed PaymentResult to your callback. No browser, no redirect, no URL scheme.
See the platform guides for the full lifecycle (camera permission, session refresh, theming, testing):

PaymentSheet overview

Session endpoint

iOS

Android

Flutter

React Native

Test your integration

4. Receive the webhook

After the payment settles (or fails), Zennopay POSTs a signed webhook to your configured endpoint. See Webhooks for the payload shape and signature verification steps.

Reference partner starter

The reference zennopay-partner-starter (v0.2.0+) ships this exact flow — a runnable Express backend that’s HMAC-only, with no key pair. It reads the same three environment variables:
Upgrading from a pre-0.2.0 starter? The HMAC-only flow removes the RSA session-signing key entirely. Delete session_signing_key.pem, drop the JWT_ISS / kid / JWKS wiring, and stop minting session JWTs — read session_token straight off the create response instead.

Common errors

All 401s use a generic message in the response body. Use the request_id field to correlate with internal logs when contacting support.