Skip to main content
The Qint Payments plugin adds a Pay with crypto method to WooCommerce checkout. Customers are redirected to Qint’s hosted checkout; orders update automatically via signed webhooks, with a polling fallback in case a webhook is missed.

Download qint-payments.zip

Current version 1.0.5 — a standard WordPress plugin package, installed through WP Admin.
Requirements
1

Install the plugin

Download qint-payments.zip, then in WP Admin go to Plugins → Add New → Upload Plugin, choose the zip, and Activate. WooCommerce must already be active.
2

Create an API key

In the Qint dashboard: Developers → API keys → Create key. Label it (e.g. woocommerce) and select both Read and Write scopes — Write creates payment intents; Read powers status polling and the settings-page connection test.
Copy the qk_live_… key now — it is shown only once.
3

Configure the gateway

  1. WP Admin → WooCommerce → Settings → Payments → Qint — Pay with crypto → Manage.
  2. Tick Enable Qint crypto payments.
  3. Optionally adjust the Title (default: “Pay with crypto”) and Description.
  4. Paste the API key and save.
The plugin immediately tests the key against the Qint API:
The payment method only appears at checkout when the store currency (WooCommerce → Settings → General → Currency) is enabled on Qint. Qint supports CHF, EUR, USD and GBP and can switch a currency off temporarily; the plugin reads the current list from the public list currencies endpoint (refreshed every 10 minutes and whenever you save the settings), shows it at the top of the gateway settings page (“Currencies enabled on Qint: …”), and warns there when your store currency is disabled or unsupported.
4

Create the webhook endpoint

Copy the Webhook URL for this store from the top of the gateway settings page. The plugin computes it for your site — don’t type it by hand. Its form depends on Settings → Permalinks in WordPress:
“Plain” permalinks: https://YOURSITE/wp-json/qint/v1/webhook does not work. On Plain permalinks that path serves your homepage with HTTP 200, so the Qint dashboard shows every delivery as delivered while your orders never update. Use the ?rest_route= URL shown on the settings page (since 1.0.4 the page also shows a warning on Plain permalinks), or switch to any other permalink structure and then update the endpoint URL in the Qint dashboard.
  1. Qint dashboard → Developers → Webhooks → Add endpoint → paste that URL.
  2. Copy the signing secret (whsec_…) shown on creation — shown only once.
  3. Paste it into the gateway’s Webhook signing secret field and save.
  4. Press Send test event in the dashboard. The delivery should show as delivered (HTTP 200), and WooCommerce → Status → Logs → qint-payments shows “Webhook test event (ping) received and verified”. A 401 means the secret in WooCommerce doesn’t match.
For webhooks to work:
  • The site must be reachable over HTTPS from the public internet.
  • The endpoint URL in the dashboard must be exactly the URL from the settings page (see the permalink table above).
  • Security plugins/WAFs must allow unauthenticated POSTs to that URL — the request is authenticated by its HMAC signature, not by cookies.

How orders are updated

Webhooks are the primary mechanism: every payment.status event is verified against the signing secret, deduplicated on X-Qint-Event-Id, then applied to the order. Because deliveries are not ordered, the plugin ignores a live status that arrives after a terminal one and any event whose occurredAt is older than the last one it applied. As a fallback, when the customer lands on the order-received (thank-you) page, on the order-pay page, or comes back from the hosted checkout with ?qint_intent=… in the URL, and the order is still pending/on-hold, the plugin polls GET /api/v1/intents/{id} once (throttled to one call per 30 s) and applies the same mapping. The “payment settled” note also lists the settlement figures the API reports. Applied from an API read (the polling fallback, or a reused intent at checkout) it reads, for example, Qint settlement: fee 1.00 EUR, net 99.00 EUR, credited 92.95 CHF. — from the intent’s feeAmount and netAmount (in the order currency) and creditAmount / creditCurrency (what the payment added to your Qint balance, in your Account Currency). The payment.status webhook carries the credit but not the fee and net, so a note written from a webhook reads Qint settlement: credited 92.95 CHF.; the full figures are always in the Qint dashboard. The admin order screen shows a Qint payment box with the intent id, cached status, underpaid/reversed flags and a dashboard link; the cache self-refreshes when older than 2 minutes while payment is pending.
An “on hold” order means either the customer underpaid — decide in the Qint dashboard’s review queue whether to accept the lesser amount or decline, see underpayments — or, if the note says REVERSED, that a settled payment was reversed by the payment partner: do not fulfil, and contact the buyer.

Currency availability

Since 1.0.3 the plugin follows Qint’s currency switches:
  • Hidden while off. The plugin caches the result of GET /api/v1/public/currencies for 10 minutes and hides the payment method at checkout while the store currency is switched off on Qint (or is not a Qint currency at all). Saving the gateway settings refreshes the list.
  • Settings page. The gateway settings page lists the currencies currently enabled on Qint and shows a warning when the store currency is disabled (”… is currently disabled on Qint, so the Qint payment method is hidden at checkout”) or unsupported.
  • API unreachable. If the list cannot be fetched, the plugin assumes CHF, EUR, USD and GBP are enabled and retries after one minute. Qint still refuses a disabled currency when the intent is created, which is handled as below.
  • Race at checkout. If a currency is switched off between the cached check and the order, the customer sees “Crypto payments are not available for orders in GBP at the moment. Please choose another payment method.” instead of the raw API error, and the plugin refreshes its cached list.

Minimum order amount

Every Qint payment must be between CHF 10 and CHF 100’000 (or the equivalent in EUR, USD or GBP); the API refuses other amounts with 400 amount_out_of_range. Since 1.0.4 the plugin doesn’t offer a method that cannot work:
  • Hidden below the minimum. When the cart total is below the minimum, the Qint payment method is not shown. On the classic checkout and the order-pay page the customer sees Qint’s limits message instead: “Pay with crypto is not available for this order. Payments must be between CHF 10 and CHF 100’000 (or the equivalent). This amount is CHF 5.00.” The block checkout hides the method live as the cart total changes.
  • CHF stores are judged exactly against CHF 10.
  • EUR, USD and GBP stores need Qint’s exchange rate, which is not public. The plugin learns it the first time Qint refuses an amount (the refusal reports the CHF equivalent) and keeps it for an hour; from then on small carts hide the method.
  • Unknown minimum = visible. Whenever the minimum cannot be determined, the method stays visible and checkout keeps working; if Qint then refuses the amount, the customer sees Qint’s own limits message rather than a generic error.

What the plugin sends and stores

  • Intents are created with POST /api/v1/intents using amount (order total, 2 decimals), currency, a title of the form Order #1001 — Your Shop and an order-derived idempotencyKey (woo-{site}-{order id}), so a double-click or a retried checkout never creates two intents. The order-received page is passed as returnUrl when the site runs on HTTPS.
  • The intent id (pi_…), checkout URL and last known status are stored as order meta; the intent id is also set as the order’s transaction id on settlement.
  • Nothing is loaded from third-party domains in the storefront or admin, and no tracking is added.

Troubleshooting

Check, in this order: the gateway is enabled; an API key is saved; the store currency is CHF, EUR, USD or GBP and currently enabled on Qint (the gateway settings page lists the enabled currencies and warns if yours is off); the cart total is at least CHF 10 or the equivalent (see Minimum order amount). On the block checkout, hard-refresh the page after enabling the gateway.
The intent creation failed. Open WooCommerce → Status → Logs → qint-payments: a 401 means the key is invalid or the merchant is not approved; a 403 means the key lacks the Write scope; a 429 means the API rate limit was hit — it clears by itself.
Webhooks are not reaching the plugin. First compare the endpoint URL in the dashboard with the Webhook URL for this store on the gateway settings page: if your permalinks are “Plain” and the endpoint points at /wp-json/qint/v1/webhook, deliveries show as delivered (HTTP 200) because WordPress answers with your homepage — replace the URL with the index.php?rest_route= form from the settings page. Otherwise check the last error in Developers → Webhooks: a 401 means the signing secret in WooCommerce doesn’t match the endpoint’s; a 404 or 403 usually means a security plugin or WAF blocks the URL; a connection error means the site isn’t publicly reachable over HTTPS. Meanwhile, opening the order-received page (or the admin order screen) polls the API and reconciles the order.
Either the buyer underpaid (see underpayments) or a settled payment was reversed — the order note says which. Decide in the Qint dashboard; the plugin never completes a reversed payment.
WooCommerce → Status → Logs, source qint-payments. Every rejected webhook, failed API call and test ping is recorded there.

Uninstall

Deleting the plugin from the Plugins screen removes its settings and transients. Order meta (intent ids, statuses) is preserved as part of your order history.

Changelog

1.0.5 — Follows the Qint API change of 20 October 2026 (your balance is held in fiat, in your Account Currency): the “payment settled” order note shows the amount credited to your Qint balance in that currency (credited 92.95 CHF) instead of the stablecoin credited, which the API no longer reports. The webhook path shows the credit as well. No settings change. 1.0.4 — The gateway settings page shows the exact webhook URL for your store, ready to copy, and warns when permalinks are “Plain” (where /wp-json/qint/v1/webhook serves the homepage, so deliveries looked successful while orders never updated). The payment method is hidden when the cart is below Qint’s minimum (CHF 10 or the equivalent) and the checkout shows Qint’s limits message; if the minimum can’t be determined the method stays visible. Fixes the payment method not appearing on the block checkout on current WooCommerce versions. Tested up to WordPress 7.1 and WooCommerce 11.2. 1.0.3 — Respects Qint’s currency switches: reads the enabled currencies from GET /api/v1/public/currencies (cached 10 minutes, 1 minute after a failed fetch, falling back to CHF/EUR/USD/GBP) and hides the payment method while the store currency is off; the settings page lists the enabled currencies and warns when the store currency is disabled or unsupported; a checkout that races a switch-off shows a clear message instead of the raw API error; the “payment settled” order note adds Qint’s fee, the net amount and the settlement asset credited (USDT/USDC) when the API reports them. 1.0.2 — Adds GBP as a supported store currency. 1.0.1 — Handles payments reversed after settlement (order on hold, never completed); polling no longer clears the underpaid flag; stale/out-of-order webhook deliveries are ignored; intents are reused only while amount and currency still match the order; reconciles on return from the hosted checkout; test pings are logged. 1.0.0 — Initial release: hosted-checkout redirect gateway, signed webhook receiver, order-received polling fallback, admin order box, block checkout support.