Download qint-payments.zip
Current version 1.0.5 — a standard WordPress plugin package, installed through WP Admin.
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.3
Configure the gateway
- WP Admin → WooCommerce → Settings → Payments → Qint — Pay with crypto → Manage.
- Tick Enable Qint crypto payments.
- Optionally adjust the Title (default: “Pay with crypto”) and Description.
- Paste the API key and save.
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:
- Qint dashboard → Developers → Webhooks → Add endpoint → paste that URL.
- Copy the signing secret (
whsec_…) shown on creation — shown only once. - Paste it into the gateway’s Webhook signing secret field and save.
- Press Send test event in the dashboard. The delivery should show
as delivered (HTTP 200), and WooCommerce → Status → Logs →
qint-paymentsshows “Webhook test event (ping) received and verified”. A 401 means the secret in WooCommerce doesn’t match.
- 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.
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/currenciesfor 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 with400 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/intentsusingamount(order total, 2 decimals),currency, atitleof the formOrder #1001 — Your Shopand an order-derivedidempotencyKey(woo-{site}-{order id}), so a double-click or a retried checkout never creates two intents. The order-received page is passed asreturnUrlwhen 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
The payment method doesn't show at checkout
The payment method doesn't show at checkout
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.
Customers see “We could not start the crypto payment”
Customers see “We could not start the crypto payment”
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.Orders stay “Pending payment” after the customer paid
Orders stay “Pending payment” after the customer paid
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.The order is “On hold”
The order is “On hold”
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.
Where are the logs?
Where are the logs?
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.