Skip to content

About

A WooCommerce payment gateway that bridges your store to Grin (GRIN, MimbleWimble) through the Such-Software BTCPay Grin plugin.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Grin (BTCPay) Bridge for WooCommerce

A WooCommerce payment gateway that bridges your store to Grin (GRIN, MimbleWimble) through the Such-Software BTCPay Grin plugin.

Works with the classic and block (Cart/Checkout block) checkout, and is HPOS-compatible.


Before you begin — what you need

This plugin is only the WooCommerce half. It does not run a Grin wallet or node itself; it talks to a BTCPay Server that does. You need all of the following already working:

  1. A BTCPay Server you control (a base URL like https://btcpay.example.com).
  2. The Such-Software BTCPay Grin plugin installed on that BTCPay Server, with:
    • a store that has Grin enabled, and
    • a synced grin-wallet + grin node behind it (so invoices can be issued and watched).
  3. A WooCommerce site (WooCommerce 6.0+, PHP 7.4+) where you can install this plugin.
  4. The ability to reach your WooCommerce webhook endpoint from BTCPay — if a bot wall or page cache sits in front of WordPress, the path /wp-json/grin-btcpay/v1/webhook must be exempted (see Configuration).

If you don't have the BTCPay Grin plugin and a synced wallet/node yet, set that up first — this gateway has nothing to talk to without it.


Why a custom gateway?

The BTCPay Grin plugin is not a native BTCPay payment method (it has no IPaymentMethodHandler), so Grin never appears on a standard BTCPay invoice. It is a self-contained flow with its own REST API, slatepack checkout page, and HMAC-signed webhooks (originally built for headless Medusa storefronts). The official BTCPay for WooCommerce plugin therefore can't surface Grin. This plugin bridges WooCommerce to that REST API.

How it works

WooCommerce checkout  ─ customer picks "Grin (GRIN)"
   │
   ▼ process_payment()
   POST {BTCPay}/stores/{storeId}/plugins/grin/invoices
        { amount, currency, orderId, redirectUrl }
        ◄── { invoiceId, checkoutUrl, amount(GRIN) }
   │  order → on-hold (awaiting payment), redirect customer
   ▼
Grin slatepack checkout (on BTCPay)  ─ pay via slatepack ─► on broadcast, browser returns
   │
   ▼ HMAC-signed webhook → POST /wp-json/grin-btcpay/v1/webhook
   order advances (see status mapping)

The fiat→GRIN conversion happens inside BTCPay (Gate.io rate); the GRIN amount is fixed by the issued invoice, so the customer can only pay the exact requested amount.

Order status mapping

BTCPay event WooCommerce result
invoice created on-hold — awaiting payment (reserves stock)
InvoiceProcessing stays on-hold — payment broadcast, awaiting confirmations
InvoicePaymentSettled payment_complete() → processing (or completed for virtual)
InvoiceInvalid failed — reorg / double-spend after confirmation
InvoiceExpired cancelled — window elapsed unpaid

This matches BTCPay's recommended convention (settle → "defaults", letting WooCommerce choose processing vs. completed by product type). Orders start on-hold (not pending) so WooCommerce's default unpaid-order auto-cancel doesn't kill slow crypto payments before the window is up.

Webhook payload note: the Grin plugin sends two payload shapes — the checkout (broadcast) path uses metadata.order_id; the monitor path (settled/invalid/expired) uses metadata.medusa_cart_id and omits the top-level invoiceId. This plugin reads both, which is required for confirmations and expiry to register.

Expiry

Primary: the BTCPay InvoiceExpired webhook → order cancelled. Fallback: a WooCommerce scheduled check (Payment window (minutes), default 1440 / 24h to match BTCPay's invoice expiry) cancels the order if it's still unpaid and the webhook was missed.

Requirements

  • WooCommerce 6.0+ (tested on 10.8.1, block checkout + HPOS).
  • PHP 7.4+.
  • A BTCPay Server running the Such-Software Grin plugin, with a store, Grin enabled, and a synced grin-wallet + node.

Installation

  1. Copy this folder to wp-content/plugins/grin-btcpay-woocommerce/.
  2. Activate Grin (BTCPay) for WooCommerce.
  3. Configure (below).

Configuration

WooCommerce → Settings → Payments → Grin (GRIN):

Field Value
Enable on
Title e.g. Grin (GRIN)
BTCPay URL e.g. https://btcpay.example.com
BTCPay Store ID the store with the Grin plugin enabled
Webhook Secret a shared secret (see below)
Payment window minutes before an unpaid order is cancelled (default 1440)

BTCPay → your store → Grin settings:

  • Webhook URL: https://YOURSITE/wp-json/grin-btcpay/v1/webhook
  • Webhook Secret: the same value as above.

If your site sits behind a bot wall (e.g. Anubis) or page cache, exempt the exact path /wp-json/grin-btcpay/v1/webhook so the signed POST reaches WordPress directly (it is HMAC-authenticated).

Security model

  • Webhooks authenticated by HMAC-SHA256 over the raw body, constant-time compared (hash_equals) against btcpay-sig: sha256=<hex>. Missing/invalid signature → 401; no secret configured → endpoint refuses (500).
  • Invoice binding: each webhook's invoice id is checked (constant-time) against the invoice id stored on the order, so a valid signature for one order can't be replayed against another.
  • Idempotent: payment_complete() only runs when the order isn't already paid.
  • Amount integrity is enforced upstream — the GRIN amount is locked into the issued invoice.
  • The webhook route is intentionally permission_callback => __return_true (the HMAC signature is the auth, not a WP nonce — the caller is BTCPay, not a browser). The secret is never logged.

BTCPay-side hardening (outside this plugin): the …/plugins/grin/invoices create endpoint is unauthenticated by design. If invoice spam is a concern, restrict that path at your reverse proxy to your store server. Keep the checkout/status GETs public.

Troubleshooting

Enable Debug logging in the gateway settings, then watch WooCommerce → Status → Logs (source grin_btcpay). It logs invoice-create requests and incoming webhooks (never secrets).

License

GPL-2.0-or-later.

About

A WooCommerce payment gateway that bridges your store to Grin (GRIN, MimbleWimble) through the Such-Software BTCPay Grin plugin.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages