Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/wcpos/mollie-terminal-for-woocommerce/releases/download/v0.5.10/mollie-terminal-for-woocommerce.zipMollie Terminal support for WooCommerce and WooCommerce POS.
This plugin starts Mollie pointofsale payments for in-person checkout and treats Mollie as the source of truth for payment and refund state. Local WooCommerce order meta is only a cache.
Safety model
- Per-order locks prevent duplicate payment/refund mutations.
- Every webhook, poll, cancel, retry, and refund path fetches authoritative Mollie state before changing an order.
- Webhooks only trust the payment ID from Mollie, then fetch the payment.
- Payment attempts are append-only history.
- Refund retries reconcile by Mollie refund IDs and metadata before creating another refund.
- POS payments are limited to EUR until broader Mollie Terminal currency support is confirmed.
Setup
- Install and activate WooCommerce.
- Activate this plugin.
- Go to WooCommerce → Settings → Payments → Mollie Terminal.
- Choose an API key source: enter the Mollie API key matching the selected mode here, or reuse the key already configured in the official Mollie Payments for WooCommerce plugin (matched to the selected mode). See the note below about test mode.
- If you accept terminal payments, pick a default terminal from the dropdown. The list is fetched live from your Mollie account (inactive terminals are hidden — Mollie cannot reactivate them), so you no longer paste a terminal ID by hand. QR-only setups can leave it empty.
- Optionally restrict Enabled terminals to the devices actually in use — only those can be chosen at checkout (empty = all active terminals; the default terminal is always available).
- Optionally enable Lock terminal selection so cashiers cannot change the terminal at checkout; the default terminal is then always used (enforced server-side as well).
- The Checkout debug logs setting (off by default) shows the on-panel log tools; leave it off unless gathering logs for support — activity is always recorded in WooCommerce → Status → Logs.
- Save. The webhook URL is set automatically on every payment — no Mollie dashboard configuration is required.
You do not need to enter a Mollie Profile ID: it is not required for
pointofsale payments, and terminals are listed across the whole account.
Checkout flow
At checkout the cashier optionally picks a terminal from the dropdown (defaults to the configured one) and clicks Start Terminal Payment. The plugin then:
- shows
Sending to terminal…→Waiting for terminal…, - polls Mollie automatically (every 2s by default; filter
mtfwc_poll_interval_ms/mtfwc_poll_timeout_msto tune), - and, when the terminal confirms, redirects straight to the thank-you page (the POS-aware order-received URL, the same one the Stripe/SumUp terminal gateways use).
The panel uses a single button that toggles between Start Terminal Payment and Cancel Terminal Payment while a payment is in flight. If the checkout is reloaded mid-payment, the panel resumes polling the open payment automatically. If the customer changes their mind and another payment method is selected, the terminal payment is stopped and canceled.
QR code payments
Merchants in the Netherlands and Belgium can also let customers pay by scanning an on-screen iDEAL or Bancontact QR code with their banking app. Enable the methods you accept under WooCommerce → Settings → Payments → Mollie Terminal → QR code payments. The cashier can then switch the checkout panel from Terminal to QR code, choose a method when both are enabled, and click Show QR code.
The plugin tracks QR payments through the same automatic Mollie polling and webhook flow as terminal payments. After paying on their phone, the customer lands on the WooCommerce order-received page. iDEAL QR can be tried with a Mollie test API key; Bancontact QR requires live mode. Bancontact caps QR payments at €1,500.00 per transaction (a scheme limit, not a plugin one); for larger totals use the terminal.
Stale payment cleanup
A Mollie pointofsale payment can stay "open" on the Mollie side if the flow
is abandoned. The plugin actively cancels open payments when:
- the auto-poll times out (5 minutes by default) — the cancel command is sent automatically instead of leaving the payment behind,
- the order is completed with a different payment method (customer changed their mind and paid cash) or the order is cancelled in WooCommerce — a server-side hook cancels the open Mollie payment and leaves an order note,
- the checkout page is closed mid-payment — a best-effort cancel beacon fires,
- as a server-side backstop, a WP-Cron sweep (every 10 minutes) cancels
payments left open past a threshold on still-unpaid orders, covering the cases
where the browser is closed or the network drops before the above can fire
(threshold filterable via
mtfwc_stale_payment_seconds).
If Mollie will not cancel an open payment — usually an unresponsive or powered-off terminal — the attempt is abandoned locally: the panel returns to idle so the cashier can start a fresh payment or pick another method without creating a new order, and the lingering Mollie payment is reconciled by the webhook or canceled by the sweep. If the payment already reached the terminal, the customer cancels on the device itself; these cleanups are safe no-ops in that case.
Test mode limitation
Mollie terminals only exist on live accounts. The Mollie test API key cannot drive a physical (or iOS/Android) terminal, so terminal payments cannot be exercised end-to-end in the test environment. This is a Mollie platform limitation, not a plugin restriction. Use Live mode with your live API key to take terminal payments. The settings screen shows a warning when test mode is selected. iDEAL QR payments do work in test mode.
Development
composer run lint
composer run test
References
- Mollie Create Payment API: https://docs.mollie.com/reference/create-payment
- Mollie Terminal setup: https://docs.mollie.com/docs/setting-up-terminal
Releases
18 releases. Each count is every asset in that release; expand a row for the breakdown.
Active-site estimate ≈10 comes from the v0.5.9 cohort. Method.