medusa-plugin-bitcoin-lightning-via-clink
August 1, 2026 ยท View on GitHub

medusa-plugin-bitcoin-lightning-via-clink
Bitcoin Lightning payment module for MedusaJS eCommerce via the CLINK protocol.
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
| Component | Description |
|---|---|
ClinkPaymentProviderService | Core payment provider with CLINK SDK integration |
CurrencyService | Fiat-to-sats conversion (CoinGecko, Kraken, Fixed, Manual) |
SubscriptionService | Recurring payments via nDebit protocol |
| Admin Settings Widget | Configure noffer, currency source, subscriptions, refunds |
| Storefront Component | QR code + copy + countdown timer + payment status polling |
| Webhook Endpoint | Real-time payment confirmations from CLINK relay |
| Status Endpoint | Backup 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
- Go to Settings > Regions
- Edit your region
- 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:
- Getting Started
- Configuration
- Guide for Merchants
- Guide for Customers
- Guide for Subscriptions
- Currency Sources
- Troubleshooting
- FAQ
- Changelog
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
- Medusa v2.x
- Node.js >= 18.0.0
- A CLINK-compatible Lightning wallet/node:
- ShockWallet (iOS/Android/Desktop)
- Lightning.Pub (self-hosted)
- ZEUS (iOS/Android)
- Amethyst (Android)
- Electrum with CLINK plugin (Desktop)
Configuration Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
noffer | string | Yes | - | Your CLINK offer string |
currencySource | string | No | coingecko | Exchange rate source |
fixedBtcRate | number | No | - | Fixed BTC rate (if using fixed source) |
invoiceTimeout | number | No | 600 | Invoice expiry in seconds |
pollInterval | number | No | 5000 | Polling interval in ms |
enableSubscriptions | boolean | No | false | Enable nDebit subscriptions |
merchantPubkey | string | Only for subscriptions | - | Merchant Nostr pubkey (64-hex); required when enableSubscriptions |
webhookSecret | string | No | - | HMAC secret to verify webhook payloads (see Security below) |
refundContactEmail | string | No | - | Merchant email for refunds |
refundContactNostr | string | No | - | Merchant Nostr for refunds |
debug | boolean | No | false | Enable 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
bcprefix, 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,.localdomains, 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
k1correlation key ties each debit request to the originating subscription. - Payment hash correlation - The webhook verifies the payment's
payment_hashmatches 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):
- ShockWallet - Menu > Static Offer
- Lightning.Pub - Dashboard > Offers
- ZEUS - Settings > CLINK
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
- In Medusa GH forum: https://github.com/medusajs/medusa/discussions/16162
- In Medusa Discord: https://discord.com/channels/876835651130097704/1529853260276437123