medusa-plugin-bitcoin-lightning-via-clink

August 1, 2026 ยท View on GitHub

icon

medusa-plugin-bitcoin-lightning-via-clink

Bitcoin Lightning payment module for MedusaJS eCommerce via the CLINK protocol.

npm version License: GPL v3 Medusa v2 CLINK

Features

  • โšก Lightning Payments - Accept Bitcoin Lightning payments via CLINK protocol
  • ๐Ÿ”’ Self-Custodial - Your node, your funds, no third-party
  • ๐ŸŒ Nostr-Native - All communication via Nostr relays, no web server needed
  • ๐Ÿ’ฑ Auto Conversion - CoinGecko, Kraken, Fixed rate, or Manual
  • ๐Ÿ”„ Subscriptions - Auto-renewal via CLINK Debits (nDebit)
  • ๐Ÿ“ฑ QR + Copy - Beautiful QR codes with one-click copy for invoices
  • ๐Ÿ” Privacy - Ephemeral Nostr keys for payment requests
  • ๐Ÿ›ก๏ธ Dual Confirmation - Webhook (primary) + Polling (backup)
  • ๐Ÿ“Š Admin Dashboard - Configure everything from the Medusa admin panel

What's in the Box

ComponentDescription
ClinkPaymentProviderServiceCore payment provider with CLINK SDK integration
CurrencyServiceFiat-to-sats conversion (CoinGecko, Kraken, Fixed, Manual)
SubscriptionServiceRecurring payments via nDebit protocol
Admin Settings WidgetConfigure noffer, currency source, subscriptions, refunds
Storefront ComponentQR code + copy + countdown timer + payment status polling
Webhook EndpointReal-time payment confirmations from CLINK relay
Status EndpointBackup polling for payment verification

Quick Start

1. Install

npm install medusa-plugin-bitcoin-lightning-via-clink

2. Configure

Add to your -config.ts:

import { Modules } from "@medusajs/framework/utils"

module.exports = defineConfig({
  modules: [
    {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            resolve: "medusa-plugin-bitcoin-lightning-via-clink",
            id: "clink",
            options: {
              noffer: "noffer1...", // Your CLINK offer string
              currencySource: "coingecko",
              invoiceTimeout: 600,
              debug: false
            }
          }
        ]
      }
    }
  ]
})

3. Enable in Admin

  1. Go to Settings > Regions
  2. Edit your region
  3. Enable Lightning (CLINK) as a payment provider

4. Accept Payments!

Customers can now pay with Lightning at checkout.

Documentation

Full documentation lives on the GitHub Wiki:

How It Works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        CHECKOUT FLOW                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                  โ”‚
โ”‚  Customer selects "Pay with Lightning"                           โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  Medusa requests invoice                                         โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  CLINK SDK decodes nOffer โ†’ requests BOLT11 from your node       โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  QR code + invoice displayed to customer                         โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  Customer scans QR with Lightning wallet                         โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  Payment confirmed via Webhook (primary) OR Polling (backup)     โ”‚
โ”‚       โ”‚                                                          โ”‚
โ”‚       โ–ผ                                                          โ”‚
โ”‚  Order confirmed! โšก                                             โ”‚
โ”‚                                                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

No web server needed for your Lightning node. All communication flows over Nostr. See the Wiki architecture page for the full data flow.

Requirements

Configuration Options

OptionTypeRequiredDefaultDescription
nofferstringYes-Your CLINK offer string
currencySourcestringNocoingeckoExchange rate source
fixedBtcRatenumberNo-Fixed BTC rate (if using fixed source)
invoiceTimeoutnumberNo600Invoice expiry in seconds
pollIntervalnumberNo5000Polling interval in ms
enableSubscriptionsbooleanNofalseEnable nDebit subscriptions
merchantPubkeystringOnly for subscriptions-Merchant Nostr pubkey (64-hex); required when enableSubscriptions
webhookSecretstringNo-HMAC secret to verify webhook payloads (see Security below)
refundContactEmailstringNo-Merchant email for refunds
refundContactNostrstringNo-Merchant Nostr for refunds
debugbooleanNofalseEnable debug logging

Security

v1.0.2 hardened the plugin against common payment and network attacks:

  • BOLT11 validation - Invoices returned by your node are validated before being shown to customers: mainnet bc prefix, amount matches the requested total, and a reasonable expiry. Invalid invoices are rejected and the payment session is failed.
  • SSRF protection - Relay URLs are validated (wss:// only) and IP addresses are checked for safety. Localhost, .local domains, private/loopback/CGNAT/link-local IPs, and unsafe IPv6 ranges (ULA, link-local, multicast, IPv4-mapped) are rejected.
  • Webhook signature verification - Confirmations sent to the webhook endpoint are verified with an HMAC-SHA256 signature before the order is confirmed. Set a shared secret and the plugin will reject unsigned or tampered webhooks.
  • nDebit validation - Subscription debit pointers are decoded and validated (pubkey, relay) before use. A k1 correlation key ties each debit request to the originating subscription.
  • Payment hash correlation - The webhook verifies the payment's payment_hash matches the expected session before confirming the order.

Webhook secret

Two ways to set it (env var takes precedence):

# Option 1: environment variable
CLINK_WEBHOOK_SECRET=your-secret npm start
// Option 2: plugin option
options: {
  webhookSecret: "your-secret"
}

If no secret is configured, webhook signatures are not checked (single-tenant setups behind a firewall). Configure one in production. See the Configuration Wiki page for details.

See the Configuration Wiki page for details on each option.

Supported Wallets

For Merchants (to get your nOffer):

For Customers (to pay):

Development

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

# Watch mode
npm run dev

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

License

GPL-3.0 - See LICENSE for details.

Support

Other Conversations