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.
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
-
Download the zip.
/gateway/integration→ WooCommerce → Download. The backend builds the archive on the fly from its own source tree. -
Upload and activate in WordPress under Plugins → Add New → Upload. Activation schedules an hourly reconciliation job — see below.
-
Open WooCommerce → Settings → Payments → Bicrypto.
-
Set the API URL to your platform origin, with no trailing path:
https://exchange.example.com. -
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.
-
Leave Test mode on and place a real order end to end.
-
Turn Test mode off and place one small live order.
What the plugin does per order
When a buyer chooses Pay with Bicrypto:
- WooCommerce sets the order to the custom status Awaiting Bicrypto Payment.
- The plugin calls
POST /api/gateway/v1/payment/createwith the order total, the shop currency, the order id asmerchantOrderId, billing name and email, and alineItemsarray built from the cart — including separate lines for shipping, each fee and tax when tax is not included in prices. metadatacarries the WordPress order id, order key, site URL and plugin version, which is what makes an order traceable from your admin payment screen.- The buyer is redirected to
checkoutUrland pays on your platform. - 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.