Solidgate Payment Gateway for WooCommerce

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

  1. Upload the solidgate-payment-gateway-for-woocommerce folder to /wp-content/plugins/, or install via Plugins > Add New in WordPress admin.
  2. Activate the plugin through the Plugins screen.
  3. Go to WooCommerce > Settings > Payments and click Set up next to “Solidgate Payment Gateway for WooCommerce”.
  4. Enter your credentials from the Solidgate merchant dashboard:
    • Public Key
    • Private Key
    • Webhook Public Key
    • Webhook Private Key
  5. Choose your integration type: Integrated form or Payment page.
  6. 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.

Contributors

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 in class-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-woocommerce to match. Existing merchant settings (stored under the solid gateway 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.status to “refunded” — it stays at the order’s last payment status (e.g. “approved”) — and only add a type: "refund" entry to the transactions array. 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 from transaction.amount/transaction.id, fields that only exist in card_gate payloads. APM refund webhooks have no singular transaction object, so the refund amount resolved to nothing. Now falls back to the matching transactions[] 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 on gate.solidgate.com, not pay.solidgate.com — so refunding an APM order returned a “Blocked by WAF” error. The payment method is now parsed from the webhook (order.payment_method for card, order.method for APMs) and stored on the order, so process_refund() routes the request to the correct host: pay.solidgate.com for card/Apple Pay/Google Pay, gate.solidgate.com for everything else.
  • Fixed: The webhook’s transaction ID capture read transaction.id directly, which doesn’t exist in APM (alt_gate) webhook payloads — only a transactions array does. This meant set_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 never order.payment_method (the card field name).

2.6.5

  • Fixed: solid_order_success_callback() (the browser redirect to success_url) always re-verified payment with a live status() 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-up status() 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 live status() 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 raw status() 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_items sent to Solidgate were built with esc_html() (HTML-entity encoding, the wrong tool for a plain-text API field) and a Name ( qty ); format, producing values like Test 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 plain Name xQty format.

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 the SOLIDGATE-EVENT-TYPE header). 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.updated suffix 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 uses wp_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-woocommerce to match. Existing merchant settings (stored under the solid gateway ID) are unaffected.
  • Fixed: Removed a dead webhook route (?wc-api=solid_refund) that was wired to a solid_wh_refund_callback() method that did not exist anywhere in the plugin; refunds are already handled correctly via the main solid_hook webhook route.
  • Fixed: process_refund() used intval( $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-woocommerce for 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 uses wp_unslash() before sanitization.
  • Fixed: $_GET['order_id'] validated with isset() before use in callbacks.
  • Fixed: print_r() replaced with wp_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: License and License URI headers.
  • Added: readme.txt and composer.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/init for 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.