Reference

Changelog

Versioned entries for this API reference.

  • 2026-05-12
    Official PHP SDK shipped — key2pay/key2pay-php
    Hand-polished (not just auto-generated) — includes transparent Bearer auto-refresh, idempotency-key generation, retry-with-backoff honouring Retry-After, typed exceptions per error class, and a webhook signature verifier with built-in 24h grace window support for rotate-secret migrations. PHP 8.1+, MIT, source in sdks/php/. Node.js and Python on the roadmap — meanwhile generate from /api/openapi.json with oazapfts / openapi-python-client / oapi-codegen.
  • 2026-05-12
    OpenAPI 3.1 spec published at /api/openapi.json + Scalar viewer at /docs/openapi
    Full public API surface is now machine-readable. Point your generator at https://api.key2pays.com/api/openapi.json (or any subdomain — same spec everywhere, CORS-wildcard) to scaffold a typed client in any language. Embedded Scalar viewer renders the spec interactively at /docs/openapi with try-it-now per endpoint. Hand-written (not zod-generated) so descriptions and examples stay integrator-friendly.
  • 2026-05-12
    P1 + P2 docs sweep: lifecycle, payment-data shapes, multi-tenant, tiers, settlement, Sandbox-Simulate header, refund shape clarified
    Six new doc pages (payment-lifecycle, payment-data-shapes, multi-tenant, account-tiers, settlement-flow, sandbox-simulate) + quickstart rewritten as an 8-step walkthrough + refund response sample corrected to match the actual API (camelCase, ISO-8601, local-currency major units — the old docs sample with snake_case + cents was fiction). New Sandbox-Simulate header lets CI drive deterministic outcomes (`paid`, `failed`, `expired`, `chargeback`, `slow_payment`) without needing the playground UI.
  • 2026-05-12
    Webhook CRUD completed: GET/PATCH/DELETE/rotate/replay endpoints + delivery log
    Six new endpoints under /api/v1/webhooks/* make webhook management fully programmatic: GET /webhooks (list), GET /webhooks/{id}, PATCH /webhooks/{id} (update url/events without losing secret), DELETE /webhooks/{id}, POST /webhooks/{id}/rotate-secret (24h grace window with dual signing), GET /webhooks/{id}/deliveries (paginated log), POST /webhooks/{id}/deliveries/{deliveryId}/replay (force retry). The dispatcher now sends two signatures during rotation: `X-Key2Pay-Signature: t=…,v1=<new>,v0=<old>` while the previous secret is in its 24h grace window.
  • 2026-05-12
    Pagination: docs unified on offset-based, GET /webhooks now paginates
    The /docs/pagination page used to describe a cursor-based model that didn't match the actual implementation. Resolved: all paginated list endpoints (/api/v1/payments, /api/v1/webhooks) use the SAME offset-based envelope — `?limit=&offset=` query params, response `{ data, pagination: { total, limit, offset, pages } }`. GET /api/v1/webhooks now returns the pagination block too (previously omitted). /api/v1/payment-methods is documented as a non-paginated catalog endpoint and keeps its config-style response shape. Cursor-based pagination is on the roadmap as a future opt-in for high-volume scans.
  • 2026-05-12
    Dedicated POST /api/v1/checkout/sessions for the hosted-checkout flow
    There are now TWO endpoints to create a payment, one per flow: `POST /api/v1/payments` returns the upstream provider's `paymentFormUrl` (direct charge — you redirect or embed it yourself); `POST /api/v1/checkout/sessions` returns OUR own `checkoutUrl` (hosted — we handle the per-method UI for you and the integrator never sees the upstream URL). Pick the one that matches your integration model. The legacy `hostedCheckout: true` flag on /payments still works for back-compat.
  • 2026-05-12
    Country ISO-2 ↔ ISO-3 normalization at the entry point
    POST /api/v1/payments now normalizes `country` to ISO-3 internally — sending `"MX"` and `"MEX"` produces identical results. Earlier, ISO-2 + paymentMethodId could surface a misleading `cascade_exhausted — No provider is currently routable for method=spei region=MX` even when the processor was healthy. The routability check on GET /api/v1/payment-methods also now mirrors the cascade's externalId scoping, so `routable: true` no longer overpromises.
  • 2026-05-12
    Unified field name: paymentMethodId everywhere
    The 4-digit unique id of each payment method is now called `paymentMethodId` on every surface — GET /api/v1/payment-methods returns it on each method entry, POST /api/v1/payments accepts it as the body field, GET /api/v1/payments echoes it on every transaction row, and you can filter listings by ?paymentMethodId=…. Same name, same value, full round-trip. The earlier `code` field is gone.
  • 2026-05-12
    Per-method 4-digit ids + interactive sandbox console
    GET /api/v1/payment-methods returns one row per retailer/bank/native rail (Walmart, BBVA, SPEI, OXXO…), each with a stable 4-digit id. POST /api/v1/payments accepts that id and the cascade routes by that exact upstream. The sandbox playground at /sandbox/login lets you drive every status transition with one click and watch webhook deliveries land live.
  • 2026-05-12
    Webhook event names: payment.completed canonical
    `payment.completed` is now the canonical name for capture success — `payment.captured` is kept as a back-compat alias and fires alongside. `payment.refunded` replaces `refund.succeeded`. The full event catalog is in the Webhooks page.
  • 2026-05-01
    Initial public reference
    Hosted checkout, direct payments, refunds, listing, balance, webhooks, ping, me.