Zahlo Checkout gateway: the plugin discovers the merchant’s current card and wallet capabilities and creates a hosted card session.
Requirements
- WordPress 6.0+
- WooCommerce 8.0+ (9.5 tested)
- PHP 8.0+
- A Zahlo merchant account that is ready for hosted payment methods
- A public HTTPS store origin for return and signed callback delivery
Install and configure
- Install and activate the
zahlo-payplugin. - Open WooCommerce → Settings → Payments → Zahlo Checkout.
- Enter the server-side Merchant API Key and Merchant API Origin. Saving verifies the key with
GET /api/v1/payment-methods. - Enter the browser public_api_url. Use the HTTPS tunnel origin for a local store; an HTTPS store cannot load the SDK from HTTP.
- Enter the public store_public_url used for hosted return and callback URLs. Do not use
localhostfor a remote sandbox or production store. - Enable card in the Zahlo merchant account and clear WooCommerce transients after capability changes.
Environment selection
Use the Demo environment while integrating and testing. Set the plugin’s Merchant API Origin tohttps://merchant-demo.zahlo.eu, use a Demo API key, and keep return and callback URLs on an HTTPS Demo store origin. Before going live, switch all three values together to https://merchant.zahlo.eu, a production API key, and the production store origin. Never mix a Demo key with the production origin or a production key with Demo.
Supported methods and checkout modes
The plugin requestsGET /api/v1/payment-methods with the API key. If the response is unavailable, malformed, or reports no supported method, Zahlo Checkout is hidden. The hosted session then uses POST /api/v1/checkout-sessions with mode: "hosted" and method: "card".
Both Classic checkout and WooCommerce Checkout Blocks use the same gateway ID, order correlation, hosted redirect, and callback path. Wallet visibility also depends on the shopper’s device/browser and the configured hosted domain.
The plugin does not collect raw card data or add OAuth; it delegates payment interaction to the hosted checkout.
Order and callback lifecycle
- WooCommerce creates one hosted session with the order amount in integer minor units, EUR currency, return URLs, callback URL, and an order-scoped idempotency key.
- The order stores
_zahlo_session_idand_zahlo_client_token, moves toon-hold, and the cart is emptied. - The thank-you page loads the Zahlo SDK from
public_api_url. The client token is sent as a form/body or bearer credential; it is never put in a URL. - A browser success return is reconciled with the authoritative session. It is not by itself proof of payment.
- Zahlo sends a signed
POST /?wc-api=zahlo_webhook. The plugin verifies the raw-body HMAC, correlates session/reference, gateway method, amount, and currency, and applies the order transition once. - Duplicate confirmations are acknowledged without a second transition. Failed and cancelled events leave the order unpaid; pending or expired sessions show retry guidance without a redirect loop.
Security
- Keep the Merchant API Key in server-side WordPress settings or protected configuration. It is also the HMAC callback secret and is never placed in browser scripts.
- Use HTTPS for the merchant origin, browser origin, public store origin, and callback delivery in production.
- Fulfill only from the confirmed order status / signed callback path. Do not fulfill from a thank-you URL alone.
- Keep the plugin’s server API origin and browser API origin distinct when a local server is exposed through an HTTPS tunnel.
Upgrade, uninstall, and troubleshooting
Upgrading preserves orders, gateway settings, and hosted session metadata. After changing an origin, clear WooCommerce transients and flush rewrite rules, then run one Classic and one Blocks test order. Deactivation does not delete orders or options; remove old options only as an operator-controlled cleanup after confirming no pending orders depend on them.- Gateway missing: verify the API key and check the card/wallet capability response; the plugin fails closed when capability discovery fails.
- SDK or redirect fails: check
public_api_urlis HTTPS andstore_public_urlis publicly reachable. - Order remains on hold: inspect
_zahlo_session_idand callback delivery; do not mark the order paid manually from the browser return. - Invalid signature: confirm the matching merchant API key and verify that the callback URL is the generated
/?wc-api=zahlo_webhookendpoint.