Changelog

Watenga API version history — what changed, what's new, and breaking changes.

2026-10-29

Latest29 October 2026

One casing and one list shape; versioned API apps

Breaking changes

  • Every API app is on 2026-10-29: new apps are created on it and every existing app was moved to it on 30 October 2026 (an app without a pinned version is answered in it too; dashboard sign-in and the hosted pages keep the original shape). Every response key is snake_case (merchantTransactionId → merchant_transaction_id, displayId → display_id). Your metadata keys are returned as you set them.
  • Only for 2026-10-29: every list answers { object: "list", data, has_more, next_cursor } (with total_count where the list counts). Pass next_cursor back as cursor. Transactions, refunds, payment links, invoices, quotations, subscriptions, plans, customers, saved cards, events and request logs.
  • Only for 2026-10-29: POST /v1/transactions/{id}/refund and GET /v1/refunds/{id} answer the refund itself (not { refund: … }); POST /v1/subscriptions, GET /v1/subscriptions/{id} and GET /v1/merchant/customers/{id} answer the subscription or customer, with its other parts beside it.
  • Only for 2026-10-29: validation errors name fields in snake_case (error.param, error.details.issues[].path).
  • A publishable key pays only a checkout session (its client_secret, created by your server with POST /v1/checkout/sessions), a payment link or an invoice; otherwise 403 CLIENT_SECRET_REQUIRED, whatever the API version.
  • Webhook events carry the resource only as data.object, whatever the API version.

Added

  • Watenga-Version request header: answer one request in another version; an unknown version is refused with 400 INVALID_API_VERSION. Every response names its version in the Watenga-Version header.
  • API apps are pinned to a version: new apps to the latest; change it in the developer console (dashboard sign-in, audited).
  • Request bodies take snake_case names everywhere (merchant_transaction_id, return_url, customer_email …); camelCase is still accepted.
  • Every error carries request_id (also the X-Request-ID header), doc_url (its entry in the error-code reference) and, for validation errors, param.
  • The error-code reference lists every code the API answers, generated from the API.
  • POST /v1/checkout/sessions/{id}/expire ends an open checkout session (409 while a payment for it is under way).
  • Canonical paths: /v1/payment-methods (saved cards) and /v1/subscriptions/{id}/pause | resume | change | items | phases | payment-method | upcoming-invoice | events.
  • The OpenAPI documents are generated from the API’s own routes and request schemas: every public route is documented with its auth type (API key or dashboard sign-in only) and restricted-key scope; admin routes are not published. The Postman collection carries request bodies.
  • Idempotency-Key is accepted on every authenticated write, with one rule: same key and body replays the first response for 24 hours; same key, different body: 422 IDEMPOTENCY_KEY_REUSED.
  • Webhook endpoints: several per API app (/v1/developer/apps/{id}/webhook-endpoints, /v1/developer/webhook-endpoints/{id}), each with its own URL, events and signing secret. The app’s webhook URL is its default endpoint.
  • Signing-secret rotation with an overlap (rotate-secret, or the app’s webhook-secret/regenerate with overlap_hours, default 24): during the overlap Watenga-Signature carries a v1 signature for each secret, so a receiver holding either verifies.
  • Failed deliveries are retried for about three days (1 min, 5 min, 30 min, 2 h, 5 h, 10 h, 10 h, 20 h, 24 h). An endpoint failing repeatedly is reported in the dashboard; one failing for three days is switched off. POST …/webhook-endpoints/{id}/replay sends its failed events again.
  • watenga listen and watenga trigger (test mode): POST /v1/developer/listen-sessions, GET …/listen-sessions/{id}/events, POST /v1/developer/webhooks/trigger.
  • Restricted keys have one scope per resource: payments, payment links, invoices (with quotations), subscriptions (with billing), customers, shop, donations, bookings, Elements sessions, webhooks, account, refunds. Existing keys keep the access they had.
  • Customers through the API: list, retrieve, create and update with a secret key or a restricted key with the customers scope.
  • Secret-key rotation with an overlap: POST /v1/developer/apps/{id}/regenerate-secret takes overlap_hours (0 by default: the old key stops at once; at most 168). During the overlap the old key keeps working; POST /v1/developer/apps/{id}/previous-secret/expire ends it early. Dashboard sign-in and two-step verification only.
  • Restricted keys can expire (expires_at, set when the key is created in the developer console); an expired key is refused.
  • expand (2026-10-29, secret and restricted keys): inline related objects next to their id on a resource read, e.g. GET /v1/subscriptions/{id}?expand=plan,customer or GET /v1/subscriptions?expand=data.plan. Each is read with your key; one your scopes do not allow stays an id and is listed in expand_errors.
  • Lists of saved cards take the list’s next_cursor as cursor (like every other list).

Changed

  • GET /v1/billing/entitlements/check reads the live rule: a feature is held while a subscription is active or trialing, or past due inside its grace period; access ends the moment the subscription or its grace period ends, even before the lifecycle job runs; a plan feature set to false grants nothing.
  • Charging a saved card (POST /v1/payment-methods/{id}/charge) is a money-moving write: an Idempotency-Key is held fail-closed.
  • The business profile, statement descriptor, beneficial owners and KYC documents (/v1/onboarding writes) are dashboard-only: API keys are refused with 403 JWT_REQUIRED.
  • The delivery retry (POST /v1/developer/apps/{id}/webhooks/deliveries/{id}/retry) sends the original event again (it sent a placeholder).
  • A subscription created with a test key is test mode: every charge for it runs on the sandbox driver and its pay link is paid in test mode only.
  • The payouts scope and the app’s Payouts switch are gone: payouts are dashboard-only with two-step verification and no key reaches them.

Removed

  • Removed before any integration went live (30 October 2026): POST /v1/public/trustpay/session/start and /session/verify (TrustPay buyer sign-in by phone code; the TrustPay buyer area signs in with Watenga Pass, and a buyer opens their order with the link from the checkout).
  • Removed before any integration went live: the /v1/payment_methods alias (use /v1/payment-methods) and the /v1/billing/subscriptions/{id}/pause, resume, change, items, phases, payment-method, upcoming-invoice and events aliases (use /v1/subscriptions/{id}/…).
  • Removed before any integration went live: publishable-key payments without a checkout session and the resource fields directly under webhook data for apps on 2026-01-01.

v1.0.0

1 June 2026

Initial public release (API version 2026-01-01)

Added

  • Payment sessions for card, mobile money, and Zimswitch via POST /v1/checkout/create
  • Checkout status polling via GET /v1/checkout/:id/status
  • Transaction listing, retrieval, and refunds
  • Payment links CRUD endpoints
  • Payout requests and listing
  • Account balance and merchant profile endpoints
  • Multi-app API key system with sandbox and live environments
  • Restricted keys with granular permission scopes
  • Outbound webhooks with HMAC-SHA256 signature verification
  • Idempotency-Key header support on all state-changing endpoints
  • Watenga.js embedded checkout widget (SAQ A scope)
  • EcoCash direct API integration for mobile money
  • WooCommerce and WHMCS payment plugins

v0.9.0

15 May 2026

Release candidate

Added

  • Developer portal with API reference and interactive sandbox console
  • Webhook event logs and API call logs in the developer portal
  • Developer team invites with role-based permissions

Changed

  • Statement descriptor format standardized to WATENGA*<suffix> (22 char max)
  • Success result code regex expanded for frictionless 3DS flows

v0.8.0

20 April 2026

Beta

Breaking changes

  • POST /v1/checkout/create now requires merchantTransactionId (was optional in alpha)

Added

  • Subscription billing endpoints (create, cancel, list)
  • Invoice generation and PDF delivery

v0.7.0

10 March 2026

Alpha

Added

  • EFT PAY / COPY&PAY card processing adapter
  • Zimswitch local card routing
  • PayFac sub-merchant ledger with rolling reserve (5%, 90 days)
  • KYC document upload and admin review workflow