Description
Solidgate Payment Gateway for WooCommerce integrates the Solidgate payment platform into your WooCommerce store. Customers can pay by credit or debit card directly on your checkout page using an embedded payment form, or be redirected to a Solidgate-hosted payment page.
The plugin supports both the classic WooCommerce checkout and the modern Gutenberg block-based checkout out of the box.
Key features
- Embedded payment form — card fields and APM buttons appear directly inside the checkout payment section as soon as the customer selects this gateway, no redirect required.
- Hosted payment page — redirect customers to a Solidgate-hosted page to complete payment.
- Classic and block checkout — fully compatible with both the legacy WooCommerce checkout and the WooCommerce Blocks (Gutenberg) checkout.
- BLIK — automatically rendered for PLN orders with a Poland billing address.
- MB Way — automatically rendered for EUR orders with a Portugal billing address.
- Bizum — automatically rendered for EUR orders with a Spain billing address.
- Webhook-based order updates — order status (authorized, settled, declined, refunded) is updated in real time via Solidgate webhooks.
- Refunds from WooCommerce admin — issue full or partial refunds directly from the order screen.
- HPOS compatible — fully supports WooCommerce High-Performance Order Storage (custom order tables).
- Logging — optional debug logging to the WooCommerce log for troubleshooting.
How APMs work
BLIK, MB Way, and Bizum buttons are rendered automatically by the Solidgate SDK when the order currency and the customer’s billing country match the APM requirements. No extra configuration is needed — the SDK silently ignores button containers when conditions are not met, so enabling all three APMs has no visual impact on customers who are not eligible for them.
Third-Party Service
This plugin connects to the Solidgate payment platform (https://solidgate.com) to process payments. Solidgate is a third-party service — by using this plugin you are subject to their terms and privacy policy.
What data is sent to Solidgate:
- Order details: amount, currency, order ID
- Customer billing country and email address (used for payment form pre-fill and APM eligibility)
- Payment method data entered by the customer inside the Solidgate-hosted iframe (card numbers are never processed by your server)
- Webhook signatures sent from Solidgate to your site to confirm payment status
When data is sent: Data is transmitted at checkout when the customer initiates payment, and via webhooks when Solidgate sends order status updates (authorised, settled, declined, refunded).
- Solidgate Terms of Service: https://solidgate.com/terms/
- Solidgate Privacy Policy: https://solidgate.com/privacy-policy/
Requirements
- WordPress 5.6 or later
- WooCommerce 6.0 or later
- PHP 7.4 or later
- A Solidgate merchant account — sign up at solidgate.com
Installation
- Upload the
solidgate-payment-gateway-for-woocommercefolder to/wp-content/plugins/, or install via Plugins > Add New in WordPress admin. - Activate the plugin through the Plugins screen.
- Go to WooCommerce > Settings > Payments and click Set up next to “Solidgate Payment Gateway for WooCommerce”.
- Enter your credentials from the Solidgate merchant dashboard:
- Public Key
- Private Key
- Webhook Public Key
- Webhook Private Key
- Choose your integration type: Integrated form or Payment page.
- In the Solidgate dashboard, set your webhook URL to:
https://yoursite.com/?wc-api=solid_hook
FAQ
-
Where do I get my API keys?
-
Log in to your Solidgate merchant dashboard and navigate to Settings > API Keys.
-
What is the difference between “Integrated form” and “Payment page”?
-
With Integrated form, the Solidgate card form appears directly inside the checkout payment section as soon as the customer selects this gateway — no redirect, no modal. Customers fill their card details inline and click Pay to authorize the payment, then WooCommerce finalizes the order. With Payment page, customers are redirected to a Solidgate-hosted page to complete payment and then returned to your store.
-
How do I set up the webhook?
-
In your Solidgate merchant dashboard, add a webhook endpoint pointing to
https://yoursite.com/?wc-api=solid_hook. Solidgate will send order status events (authorize, settle, decline, refund) to this URL, and the plugin will update the corresponding WooCommerce order automatically. -
Does the plugin support refunds?
-
Yes. You can issue full or partial refunds directly from the WooCommerce order screen (WooCommerce > Orders > [order] > Refund). The plugin calls the Solidgate refund API automatically.
-
Which countries and currencies are supported for APMs?
-
- BLIK — PLN (Polish Zloty), billing country: Poland
- MB Way — EUR, billing country: Portugal
- Bizum — EUR, billing country: Spain
APM buttons appear automatically when the order matches the required currency and country. No extra configuration is needed.
-
Is the plugin compatible with WooCommerce HPOS?
-
Yes. The plugin declares compatibility with WooCommerce High-Performance Order Storage (custom order tables) and uses
wc_get_orders()for all order lookups. -
Does the plugin work with the block-based checkout?
-
Yes. The plugin registers a WooCommerce Blocks payment method integration via
AbstractPaymentMethodType. In Integrated form mode the card form renders inline in the payment method area. After the customer authorizes their card, WooCommerce’s Place Order button finalizes the order. -
Is PCI compliance maintained?
-
Yes. Card data is entered directly inside a Solidgate-hosted iframe served from
cdn.solidgate.com. Your server never handles raw card numbers.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Solidgate Payment Gateway for WooCommerce” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Solidgate Payment Gateway for WooCommerce” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.8.4
- Fixed: customer_first_name and customer_last_name are now omitted from the Solidgate API request when empty, preventing error 2.01 “cannot be blank” for guest checkouts where billing name fields are not filled.
2.8.3
- Security: payment init endpoint (/wp-json/solid/v1/init) now always reads amount and currency from the server-side WC cart — client-provided values are ignored. Previously a visitor with a valid WP REST nonce could send {“amount”:1} to obtain a $0.01 Solidgate payment form for any cart total.
- Security: payment init token is now bound to the WC session customer ID via a hash stored in the transient. A token created in one browser session cannot be consumed by a different session.
- Security: auth_ok webhook handler now skips orders already in processing/completed/refunded state, preventing redundant processing on duplicate webhook deliveries.
2.8.2
- Fixed: Added a missing/misplaced
translators:comment for two translatable strings with placeholders inclass-wc-solid-gateway.php(refund pending-confirmation notice and refund-failure order note), per WordPress.org Plugin Check. - Fixed: Shortened the 2.8.0 and 2.6.0 Upgrade Notice entries to comply with WordPress.org’s 300-character limit.
2.8.1
- Changed: In Integrated form mode, the native WooCommerce “Place order” button is now hidden on the classic checkout while Solidgate is the selected payment method. The SDK’s own PAY button already authorizes the card and auto-submits the checkout on success, so the native button never did anything useful — it either blocked with an error before the card form was completed, or was redundant after. Hidden/shown dynamically as the customer switches payment methods or WC re-renders the payment box.
2.8.0
- Changed: Plugin renamed from “Solidgate Payment Form for WooCommerce” back to “Solidgate Payment Gateway for WooCommerce”. Slug, main plugin file, and text domain updated to
solidgate-payment-gateway-for-woocommerceto match. Existing merchant settings (stored under thesolidgateway ID) are unaffected.
2.7.4
- Fixed: A refund submission that came back “pending” (see 2.7.3) left no trace on the order and nothing stopped a second click on Refund from submitting a duplicate request to Solidgate.
process_refund()now writes an order note for every outcome (submitted/pending, confirmed, declined, or request error), and blocks a new refund attempt while an earlier one is still awaiting confirmation, with a clear note explaining not to retry. The webhook handler clears that pending marker once it confirms the refund’s final status, so a genuinely new refund attempt afterward isn’t blocked.
2.7.3
- Fixed: Admin-initiated refunds (WooCommerce > Orders > Refund) were confirmed as soon as Solidgate’s refund API responded with any order object, without checking whether the refund transaction itself had actually cleared. For APM methods (iDEAL, confirmed in testing) the API response is frequently still “processing” at that point, so WooCommerce recorded the refund as successful before Solidgate had confirmed it.
process_refund()now only reports success once the refund transaction’s status is “success”; a “processing” result is reported back to WooCommerce as a pending error (so WooCommerce does not record a premature refund) and the confirmed refund is created automatically by the webhook handler once Solidgate reports “success” (see 2.7.2). A “fail” status is reported to the admin immediately. - Note: because WooCommerce’s refund screen is synchronous, a “pending” result surfaces as a WooCommerce error notice rather than a success message, even though the refund was actually submitted and accepted by Solidgate — the order will show as refunded automatically once the webhook confirms it, with no action needed.
2.7.2
- Fixed:
process_webhook_charge_refunded()created the WooCommerce refund as soon as a refund webhook arrived, even though the refund transaction itself could still be “processing” (or later fail) — e.g. an iDEAL refund isn’t final the moment it’s initiated. Now waits for the refund transaction’s own status to reach “success” before creating the WC refund; a “fail” status is logged as an explicit order note instead of being silently ignored, and pending statuses are logged and left for a follow-up webhook. - Added: idempotency guard against duplicate refund webhooks (Solidgate’s own webhook docs note duplicates can occur) — each processed refund transaction ID is recorded on the order so a repeated “success” webhook for the same refund can’t create a second WooCommerce refund on a partially-refunded order.
2.7.1
- Fixed: APM (BLIK, iDEAL, etc.) refunds initiated from the Solidgate Hub never appeared in WooCommerce. Unlike card refunds, alt_gate refund webhooks never change
order.statusto “refunded” — it stays at the order’s last payment status (e.g. “approved”) — and only add atype: "refund"entry to thetransactionsarray. The dispatcher now checks for that entry before treating an “approved”/”settle_ok” webhook as a new charge, and routes it to the refund handler instead. - Fixed:
process_webhook_charge_refunded()read the refund amount and transaction ID fromtransaction.amount/transaction.id, fields that only exist in card_gate payloads. APM refund webhooks have no singulartransactionobject, so the refund amount resolved to nothing. Now falls back to the matchingtransactions[]entry when the singular field isn’t present.
2.7.0
- Fixed: Refunds initiated from the WooCommerce admin (Orders > Refund) always called Solidgate’s card API (
pay.solidgate.com), regardless of how the order was actually paid. Solidgate’s v1 API uses domain-specific hosts — APM orders (BLIK, iDEAL, MB Way, Bizum, etc.) live ongate.solidgate.com, notpay.solidgate.com— so refunding an APM order returned a “Blocked by WAF” error. The payment method is now parsed from the webhook (order.payment_methodfor card,order.methodfor APMs) and stored on the order, soprocess_refund()routes the request to the correct host:pay.solidgate.comfor card/Apple Pay/Google Pay,gate.solidgate.comfor everything else. - Fixed: The webhook’s transaction ID capture read
transaction.iddirectly, which doesn’t exist in APM (alt_gate) webhook payloads — only atransactionsarray does. This meantset_transaction_id()/payment_complete()received an empty transaction ID for every APM order. Now resolves the ID from either shape. - Fixed: The “Solid charge complete” order note always logged “Method: default” for card orders, because it only checked
order.method(the APM field name) and neverorder.payment_method(the card field name).
2.6.5
- Fixed:
solid_order_success_callback()(the browser redirect tosuccess_url) always re-verified payment with a livestatus()API call, even when the webhook had already confirmed and completed the order moments earlier. This caused false “Payment could not be verified” rejections on successful APM (iDEAL, tested) payments where the follow-upstatus()call didn’t return the same result as the webhook. Now checks whether the order is already processing/completed/refunded (webhook-confirmed) first, and only falls back to the livestatus()call when no completing webhook has landed yet — same server-side verification guarantee, no redirect is trusted blindly.
2.6.4
- Debug:
solid_order_success_callback()now logs the rawstatus()API response. Seen in the field: for an APM order (iDEAL, alt_gate), the webhook confirms status “approved” but the browser-redirect status check comes back with an empty status, incorrectly rejecting a successful payment. Root cause not yet confirmed — this logs the actual response shape so the fix can target the real cause instead of guessing.
2.6.3
- Fixed:
order_description/order_itemssent to Solidgate were built withesc_html()(HTML-entity encoding, the wrong tool for a plain-text API field) and aName ( qty );format, producing values likeTest product ( 1 );— special symbols like parentheses and semicolons are not safe in these fields. Both the Hosted Payment Page and Integrated form flows now sanitize product names and descriptions to letters, numbers, spaces, and basic safe punctuation only, and use a plainName xQtyformat.
2.6.2
- Fixed: Webhook handler read the Solidgate event type from
$_GET['type'], a query parameter Solidgate never sends (the type is sent as theSOLIDGATE-EVENT-TYPEheader). This made every incoming webhook resolve to an empty event type, so no webhook was ever processed and paid orders stayed stuck on “on-hold” indefinitely despite the webhook request itself succeeding (200 OK). Now reads the type from the header. - Fixed: The webhook dispatcher only matched the literal event types
order.updated/alt_order.updated, but Solidgate’s actual webhook payloads are gate-prefixed (e.g.card_gate.order.updated). Now matches any*.order.updatedsuffix as well as the older bare values.
2.6.1
- Fixed: Hosted Payment Page flow generated its Solidgate order ID as
{order_id}_{time()}— second-resolution only, so a quick retry (failed payment, reloaded tab) within the same second could produce a duplicate ID that webhooks use as their order lookup key. Now useswp_generate_uuid4(), matching the Integrated form flow’s uniqueness guarantee. - Fixed:
solid_order_failture_callback()(the browser redirect Solidgate sends the customer to on decline) unconditionally set the order to “failed” with no check of current status. Because the webhook and this browser redirect are independent, unordered channels, a webhook that already completed the order before the browser finished redirecting could get overwritten back to “failed”. The callback now skips orders already in processing/completed/refunded, mirroring the guard added to the webhook handler in 2.6.0.
2.6.0
- Changed: Plugin renamed from “Solidgate Payment Gateway for WooCommerce” to “Solidgate Payment Form for WooCommerce”. Slug, main plugin file, and text domain updated to
solidgate-payment-form-for-woocommerceto match. Existing merchant settings (stored under thesolidgateway ID) are unaffected. - Fixed: Removed a dead webhook route (
?wc-api=solid_refund) that was wired to asolid_wh_refund_callback()method that did not exist anywhere in the plugin; refunds are already handled correctly via the mainsolid_hookwebhook route. - Fixed:
process_refund()usedintval( $amount * 100 )to convert to minor units, which truncates instead of rounding and can silently refund the wrong amount on certain floating-point totals (e.g. 19.999999999998); now uses(int) round( $amount * 100 ), consistent with the rest of the codebase. - Fixed: A late or duplicate “declined” webhook arriving after an order was already marked processing/completed/refunded by an earlier webhook could incorrectly cancel that already-paid order.
process_webhook_charge_declined()now skips orders in those statuses. - Fixed: Blocks checkout and classic checkout used a stale “Visa/Mastercard” fallback title that no longer matched the gateway’s actual default title (“Card payments & Other”); both now use the same default.
2.5.0
- Changed: Integrated form mode now renders the card form inline in the payment section immediately when the gateway is selected, instead of opening a modal after clicking Place Order (Stripe/Braintree-style UX).
- Changed: Classic checkout no longer depends on jQuery Modal — removed that dependency.
- Changed: Both classic and block checkout share the same token-based flow through process_payment().
- Changed: /solid/v1/init REST endpoint now reads cart totals from the WC session when called without body parameters (classic checkout), so no extra AJAX is needed for amount/currency.
- Added: Loading shimmer animation while the payment form initializes.
- Added: Auto re-initialization when cart totals change (coupon or shipping update).
2.4.0
- Fixed: Plugin slug renamed to
solidgate-for-woocommercefor WP.org compliance. - Fixed: Plugin name updated to “Solidgate Payment Gateway for WooCommerce”.
- Fixed: Text domain updated throughout to match plugin slug.
- Fixed: jQuery Modal bundled locally — removed CDN dependency.
- Fixed:
$_POST['solid_token']now useswp_unslash()before sanitization. - Fixed:
$_GET['order_id']validated withisset()before use in callbacks. - Fixed:
print_r()replaced withwp_json_encode()in all log calls. - Fixed: Missing translators comments added to all sprintf/__() calls.
- Fixed: Removed
load_plugin_textdomain()(auto-loaded since WP 4.6). - Fixed: Webhook nonce check suppressed with explanation (server-to-server, no WP nonce).
- Fixed: Slow DB query phpcs notices suppressed with explanation.
- Added:
LicenseandLicense URIheaders. - Added:
readme.txtandcomposer.json.
2.3.0
- Added: BLIK, MB Way, and Bizum APM support for classic and block checkout.
- Added:
geo_country(ISO 3166-1 alpha-3) in order body for APM auto-rendering. - Added:
future_usage: { payment_type: one-time }globally (required by MB Way and Bizum). - Fixed: APM container divs now output inline in
payment_fields()for classic checkout.
2.2.0
- Added: WooCommerce Block checkout support via
AbstractPaymentMethodType. - Added: REST endpoint
/wp-json/solid/v1/initfor pre-order payment initialization. - Added: React portal overlay for block checkout (bypasses WC processing-state opacity).
- Added: Billing email and country pre-filled in Solidgate form from WC store data.
2.1.0
- Initial public release.