Docs

Developer documentation

Create payment links from your backend, receive secure callbacks, and deliver WhatsApp confirmations through 1Confirmed.

Quick start

  1. Create a merchant in the console and configure Payzone with your paywall URL, merchant account and secret keys.
  2. Generate an API key (prefix pg_live_). The plaintext value is shown once.
  3. Call the REST API to create a payment link.
  4. Forward the returned payment_url to your customer (WhatsApp, email, SMS…).
  5. Receive a server-to-server webhook on terminal status.

Authentication

Every REST request must include a bearer API key. Treat keys as secrets and rotate them via the console.

Authorization: Bearer pg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Gateway callbacks (Payzone)

Configure your Payzone account callback URL to https://pg.1confirmed.com/api/public/callback/{merchantCode}. PG verifies the X-Callback-Signature HMAC-SHA256 header against the merchant secret before updating the payment status — invalid signatures return 401.

Stripe setup

Stripe uses hosted Checkout. Each merchant connects with their own keys; credentials are encrypted at rest (AES-256-GCM) and only ever leave the database to sign API calls.

  1. In the Stripe Dashboard, copy your Secret key (sk_test_… while testing, sk_live_… in production). The publishable key is optional.
  2. In the PG console, open Gateways → Stripe → Configure, paste the secret key, and pick a webhook setup mode.
  3. Auto-provision (recommended): we call Stripe on your behalf to create a webhook endpoint scoped to your merchant and store the signing secret. Nothing else for you to do.
  4. Manual: copy the endpoint URL we show you (https://pg.1confirmed.com/api/public/stripe-webhook/{merchantCode}), add it in Stripe Dashboard → Developers → Webhooks, subscribe to the events listed below, then paste the whsec_… signing secret back into the dialog.

Events handled in V1:

  • checkout.session.completedpayment.succeeded
  • checkout.session.async_payment_succeededpayment.succeeded
  • checkout.session.async_payment_failedpayment.failed
  • payment_intent.payment_failedpayment.failed
  • checkout.session.expiredpayment.cancelled

When creating a payment link via the REST API, set "gateway": "stripe". Refunds, disputes, subscriptions, and Stripe Connect onboarding are not in V1.

Outbound webhooks

Register one or more endpoints from the console. Every delivery is signed:

POST https://your-app.example.com/hooks/pg
x-pg-event: payment.succeeded
x-pg-signature: hex(hmac_sha256(endpoint_secret, body))

{
  "event": "payment.succeeded",
  "created_at": "2026-06-23T13:45:01.000Z",
  "data": {
    "payment_request_id": "8b9b…",
    "reference": "INV-A-1042",
    "gateway": "payzone",
    "gateway_transaction_id": "PZN-9817263",
    "status": "succeeded"
  }
}

Verify the signature with a constant-time comparison. Failed deliveries are retried automatically with an exponential schedule (5m, 15m, 1h, 4h, 12h) before being marked exhausted.

Event types

  • payment.processing — gateway acknowledged but not finalized.
  • payment.succeeded — funds captured.
  • payment.failed — gateway returned a terminal failure.
  • payment.cancelled — customer cancelled before completion.

WhatsApp delivery (1Confirmed)

When a payment reaches a terminal state and a customer_phone was provided, PG dispatches a WhatsApp confirmation through the 1Confirmed messaging API. This requires the ONECONFIRMED_API_KEY backend secret. When the secret is absent the rest of the flow continues unchanged.

Errors

The API uses standard HTTP status codes and returns a JSON body:

{ "error": "Invalid signature" }
  • 400 — validation error (check error field).
  • 401 — missing/invalid API key or callback signature.
  • 403 — API key does not belong to the requested merchant.
  • 404 — unknown merchant or payment reference.
  • 503 — gateway not configured for this merchant.