Start

Getting started

Create a payment session, embed checkout, and receive webhooks.

Prerequisites

  • Portal access with KYB approved, business status ACTIVE, and a receive payment ID configured.
  • Production checkout domains registered under Integrations → Allowed browser origins.
  • An HTTPS endpoint that can accept Zippy webhook POSTs.
  • Backend ability to store secrets securely (API key + webhook signing secret).
  • A page or route on a registered origin where you can embed @zippypay/checkout.

Configure Zippy Pay

  1. Complete KYB and confirm business is active in the portal. Payment session creation requires KYB approval, status = ACTIVE, and a configured receive payment ID.
  2. Register allowed browser origins under Integrations → Allowed browser origins for every domain where checkout runs (HTTPS in production; localhost for local dev only).
  3. Create an API key under Developer → API Keys. Plaintext is shown once as zp_live_....
  4. Register an HTTPS webhook endpoint under Developer → Webhooks. Store the one-time whsec_... signing secret.

Create a payment session

From your trusted backend, call POST /api/v1/payment-sessions with your business API key. Send Idempotency-Key and X-Correlation-Id on every create request.

POST/api/v1/payment-sessions
curl -X POST "https://api.zippypay.io/api/v1/payment-sessions" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: zp_live_REDACTED" \
  -H "Idempotency-Key: 83596f5e-2134-4e66-8304-20d61f290cf0" \
  -H "X-Correlation-Id: merchant-request-123" \
  -d '{
    "amount": "25.00",
    "currency": "USD",
    "merchantReference": "order-12345",
    "successUrl": "https://yourstore.com/checkout/success",
    "failureUrl": "https://yourstore.com/checkout/failure",
    "metadata": {
      "orderId": "12345"
    }
  }'

Response excerpt

json
{
  "sessionId": "550e8400-e29b-41d4-a716-446655440000",
  "clientToken": "zps_REDACTED",
  "expiresAt": "2026-08-31T12:30:00.000Z"
}

Store sessionId with your order or cart. Pass sessionId and clientToken to the Checkout SDK — never expose your zp_live_ API key in the browser.

Embed checkout

Install and initialize @zippypay/checkout with the values returned from session creation:

Checkout SDK quick embed

javascript
import { ZippyPay } from "@zippypay/checkout";

const checkout = ZippyPay.create({
  sessionId: "550e8400-e29b-41d4-a716-446655440000",
  clientToken: "zps_REDACTED",
  container: "#zippy-checkout",
  onComplete: (result) => {
    console.log("Payment complete", result);
  },
  onError: (error) => {
    console.error("Checkout error", error);
  },
});

The customer completes payment in the embedded checkout UI. Your backend does not accept card or wallet details directly — the SDK and Zippy mobile app handle payer authentication.

Receive events

Prefer webhooks for fulfillment. When a payment succeeds, Zippy sends payment_session.completed with the session status, amount, and transaction details:

payment_session.completed

json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "type": "payment_session.completed",
  "createdAt": "2026-08-31T12:00:00.000Z",
  "data": {
    "paymentSessionId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "COMPLETED",
    "merchantReference": "order-12345",
    "amount": "25.00",
    "currency": "USD",
    "transactionId": "880e8400-e29b-41d4-a716-446655440003",
    "transactionStatus": "COMPLETED",
    "payer": {
      "paymentId": "john.doe12",
      "displayName": "John S."
    }
  }
}

As a fallback, poll merchant GET endpoints from your backend by sessionId or merchantReference until status is terminal. See Get a payment session and Get by merchantReference.

Verify every delivery with your whsec_... secret before updating order state. Read Webhooks overview and signature verification for the full receiver checklist.

Common failures

  • Sending the API key under a header other than X-Api-Key.
  • Embedding checkout before prerequisites are met (KYB, active business, payment ID, or registered origin) → session create or checkout init fails.
  • Checkout hosted on an unregistered domain → payment-session.origin-not-allowed.
  • Passing the API key to the browser instead of the zps_ client token.
  • Webhook URL not HTTPS, or verifying a re-serialized JSON body instead of the exact raw bytes.
  • Fulfilling on redirect alone without verifying payment_session.completed.