WooCommerce plugin

Install and configure the bundled WooCommerce plugin, understand how it reconciles orders without webhooks, and know the three settings on its screen that do nothing.

5 min readUpdated 3 August 2026woocommerce, wordpress, plugins, integration

The gateway ships one integration plugin: Bicrypto Payment Gateway for WooCommerce, version 2.0.0. A merchant downloads it from Gateway → Developers → Integrations and installs it like any WordPress plugin. It is the fastest path from "merchant account approved" to "taking orders", and it is a reasonable reference implementation for anyone writing their own.

Requirements

  • WordPress 5.8+, WooCommerce 7.0+, PHP 7.4+
  • HTTPS on the shop
  • An approved merchant account and at least one key pair

The plugin supports WooCommerce Blocks checkout and HPOS (High-Performance Order Storage).

Install and configure

  1. Download the zip. /gateway/integrationWooCommerce → Download. The backend builds the archive on the fly from its own source tree.

  2. Upload and activate in WordPress under Plugins → Add New → Upload. Activation schedules an hourly reconciliation job — see below.

  3. Open WooCommerce → Settings → Payments → Bicrypto.

  4. Set the API URL to your platform origin, with no trailing path: https://exchange.example.com.

  5. Paste the keys. Test public and secret in one pair of fields, live public and secret in the other. Only the secret key is ever sent; the public key fields are there for completeness.

  6. Leave Test mode on and place a real order end to end.

  7. Turn Test mode off and place one small live order.

What the plugin does per order

When a buyer chooses Pay with Bicrypto:

  1. WooCommerce sets the order to the custom status Awaiting Bicrypto Payment.
  2. The plugin calls POST /api/gateway/v1/payment/create with the order total, the shop currency, the order id as merchantOrderId, billing name and email, and a lineItems array built from the cart — including separate lines for shipping, each fee and tax when tax is not included in prices.
  3. metadata carries the WordPress order id, order key, site URL and plugin version, which is what makes an order traceable from your admin payment screen.
  4. The buyer is redirected to checkoutUrl and pays on your platform.
  5. They come back to ?wc-api=bicrypto_return&order_id=…&status=success|cancel.

On return with status=success the plugin does not trust the redirect: it reads GET /api/gateway/v1/payment/{id} and only completes the order if the status is COMPLETED. On FAILED or EXPIRED it fails the order and sends the buyer back to checkout. On status=cancel it restores the cart, cancels the order and returns the buyer to checkout with a notice.

Refunds work from the WooCommerce order screen. The plugin posts to /api/gateway/v1/refund, so partial refunds are supported and the money returns to the buyer's original wallets.

How orders actually reconcile

Its create-payment request does not include a webhookUrl field. Since the gateway only sends events to the URL supplied on the payment, the plugin's webhook endpoint is never called — no matter what you paste into its Webhook Secret box or copy out of its Callback URLs panel.

This is not fatal. Reconciliation is done by the return handler plus an hourly WordPress cron sweep. But it does mean an order is confirmed on the buyer's return or up to an hour later, never within seconds of payment.

The sweep (bicrypto_check_pending_payments) runs hourly, takes up to 50 orders that are still Awaiting Bicrypto Payment or Pending and older than an hour, reads each payment's status from the API, and completes, fails or cancels the order accordingly. WordPress cron is traffic-driven — a shop with no visitors does not run it. On a low-traffic shop, wire wp-cron.php to a real system cron.

If you do wire up the plugin's webhook endpoint by hand, be aware its handler disagrees with what the gateway sends in three places: it reads X-Webhook-Signature where the gateway sends X-Gateway-Signature; it computes the HMAC over the body alone, without the timestamp. prefix and without the sha256= prefix; and it looks for the event name in a top-level event key where the gateway sends type. Verification and dispatch both fail. Rely on the polling path, or write your own handler using the signature recipe.

Settings that do nothing

Three fields on the plugin's screen have no effect against this gateway:

  • Webhook Secret — the handler that would use it is never reached.
  • The Callback URLs panel — it tells the merchant to "copy these URLs to your Bicrypto Merchant Dashboard". There is no field to paste them into; the gateway takes redirect and webhook URLs per payment, and the plugin already sets its own return and cancel URLs on every request.
  • Live/Test Public Key — stored, displayed, never transmitted.

Everything else — API URL, test mode, the two secret keys, debug logging — is live.

Troubleshooting

The archive is zipped out of backend/src/api/(ext)/gateway/integration/plugins at request time. A deployment that ships only compiled JavaScript leaves that folder behind, and the download returns a 500 whose message names the missing directory. Re-deploy the backend including non-TypeScript assets under backend/src.

Either the buyer never completed the payment, or WordPress cron is not running and the buyer did not come back through the return URL. Check the payment in your admin payment list: if it is COMPLETED there and pending in WooCommerce, it is a cron problem on the shop, not a gateway problem. Turn on Debug Log in the plugin and use the Sync action on the order screen to force a status read.

The plugin uses the test secret when Test mode is on and the live secret when it is off. Filling only one pair and toggling the mode produces this error.

The shop currency has to exist in two places on the platform: the merchant's allowedCurrencies and the platform's enabled wallet-type map. A shop selling in GBP against a merchant configured for USD fails on the first request. See Install.

The buyer is either not signed in to your platform, or holds no balance in any enabled currency. The checkout can only spend wallets that exist on your platform — see the warning on the overview.

Next: Admin — merchants.