CLINK
Accept Bitcoin Lightning payments via CLINK
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 Copy to clipboardClinkPaymentProviderService Core payment provider with CLINK SDK integration Copy to clipboardCurrencyService Fiat-to-sats conversion (CoinGecko, Kraken, Fixed, Manual) Copy to clipboardSubscriptionService 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
1npm install medusa-plugin-bitcoin-lightning-via-clink
2. Configure
Add to your Copy to clipboard-config.ts:
1234567891011121314151617181920import { 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 stringcurrencySource: "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
1234567891011121314151617181920ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 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) β
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 Copy to clipboardnoffer string Yes - Your CLINK offer string Copy to clipboardcurrencySource string No Copy to clipboardcoingecko Exchange rate source Copy to clipboardfixedBtcRate number No - Fixed BTC rate (if using Copy to clipboardfixed source) Copy to clipboardinvoiceTimeout number No Copy to clipboard600 Invoice expiry in seconds Copy to clipboardpollInterval number No Copy to clipboard5000 Polling interval in ms Copy to clipboardenableSubscriptions boolean No Copy to clipboardfalse Enable nDebit subscriptions Copy to clipboardmerchantPubkey string Only for subscriptions - Merchant Nostr pubkey (64-hex); required when Copy to clipboardenableSubscriptions Copy to clipboardwebhookSecret string No - HMAC secret to verify webhook payloads (see Security below) Copy to clipboardrefundContactEmail string No - Merchant email for refunds Copy to clipboardrefundContactNostr string No - Merchant Nostr for refunds Copy to clipboarddebug boolean No Copy to clipboardfalse 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 Copy to clipboard
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 (Copy to clipboard
wss://only) and IP addresses are checked for safety. Localhost, Copy to clipboard.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 Copy to clipboard
k1correlation key ties each debit request to the originating subscription. - Payment hash correlation - The webhook verifies the payment's Copy to clipboard
payment_hashmatches the expected session before confirming the order.
Webhook secret
Two ways to set it (env var takes precedence):
12# Option 1: environment variableCLINK_WEBHOOK_SECRET=your-secret npm start
1234// Option 2: plugin optionoptions: {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 Copy to clipboardnOffer):
- ShockWallet - Menu > Static Offer
- Lightning.Pub - Dashboard > Offers
- ZEUS - Settings > CLINK
For Customers (to pay):
Development
1234567891011# Install dependenciesnpm install# Run testsnpm test# Buildnpm run build# Watch modenpm 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

