Accept Bitcoin Lightning payments on your BTCPay Server via the CLINK protocol (clinkme.dev). Customers pay with ShockWallet, BXRD.app, ZEUS, Amethyst, Electrum or any CLINK-compatible Lightning wallet. Enable Lightning Auto-Renew Subscription payments. All communication flows over Nostr relays — no Node.js required, no web server for your Lightning node.
- Merchant generates a CLINK Offer string (
nOffer1...) from their CLINK-compatible Lightning node - Customer checks out and selects "Lightning (CLINK)" as payment method
- The plugin uses the
nOfferto request a BOLT11 Lightning invoice from the merchant's node over Nostr (pure C# Nostr protocol — NIP-44 encrypted kind 21001 events) - Customer scans the QR code and pays with any Lightning wallet
- Payment is confirmed via CLINK protocol receipt
No Node.js, no native binaries, no external runtime dependencies. All Nostr communication is handled natively in C# via ClientWebSocket, ChaCha20Poly1305, and pure C# secp256k1 arithmetic. 92 unit tests.
- CLINK Offer (nOffer) based Lightning payments via Nostr
- Pure C# Nostr protocol — no Node.js, no JavaScript bridge
- NIP-44 v2 encrypted communication (ChaCha20Poly1305 + HKDF + secp256k1 ECDH)
- Subscription auto-renewals via nDebit protocol
- Admin configuration page for store-level settings
- QR code display for easy mobile payment
- Payment polling and automatic status updates
- Configurable invoice timeout and poll interval
- Support for additional Nostr relays
- Lightning setup accordion integration in store settings
- Store-isolated state via
IStoreRepository(no file-based persistence)
- BTCPay Server v2.4.0+
- .NET SDK 10.0+
- A CLINK-compatible Lightning wallet/node (ShockWallet, BXRD.app, Lightning.Pub, ZEUS, Amethyst)
- Download the latest release
.btcpayplugin package from the releases page - Go to Server Settings > Plugins in your BTCPay Server
- Upload and install the plugin
- Go to your store settings and click CLINK Lightning in the integrations nav
- Configure your CLINK offer string
# Clone with submodules
git clone --recurse-submodules https://github.com/WoompaLoompa/btcpay-clink.git
cd btcpayserver-clink
# Or if already cloned without submodules
git submodule update --init --recursive
# Build the plugin
dotnet build
# Register for local debugging
./plugin-register.shNo JavaScript build step required. The plugin has zero runtime dependencies beyond .NET and BTCPay Server.
Navigate to your store settings and click CLINK Lightning in the integrations sidebar.
| Setting | Description |
|---|---|
| Enable/Disable | Turn CLINK payments on/off for this store |
| CLINK Offer String | Your nOffer1... string from ShockWallet / BXRD.app / Lightning.Pub |
| Title | Payment method title shown at checkout |
| Description | Payment method description shown at checkout |
| Invoice Timeout | Seconds before the Lightning invoice expires (default: 600) |
| Poll Interval | Milliseconds between payment status checks (default: 5000) |
| Additional Relays | Optional Nostr relays for redundancy (one per line) |
- Open ShockWallet
- Go to Menu > Linked Apps > nOffer
- Copy the
noffer1...string - Paste into the plugin settings
- Open BXRD.app in your browser
- Go to your nOffer settings
- Copy the
noffer1...string - Paste into the plugin settings
- Log into your Lightning.Pub dashboard
- Navigate to Offers
- Copy the generated
noffer1...string
- Open ZEUS wallet
- Go to ZEUS Pay > Manage Offer
- Copy the offer string
btcpayserver-clink/
├── src/BTCPayServer.Plugins.Clink/
│ ├── Plugin.cs # Plugin entry point
│ ├── Controllers/
│ │ └── ClinkController.cs # Admin + payment API endpoints
│ ├── Services/
│ │ ├── ClinkService.cs # Settings management + BTC conversion
│ │ ├── ClinkNostrBridge.cs # C# Nostr protocol orchestrator
│ │ ├── ClinkLightningClient.cs # ILightningClient implementation
│ │ ├── ClinkConnectionStringHandler.cs # Connection string parser
│ │ ├── NostrEventStore.cs # Store-scoped Nostr event state
│ │ ├── NdebitRegistry.cs # Store-scoped nDebit registry
│ │ └── EmailNdebitStore.cs # Email → nDebit mapping
│ ├── Nostr/
│ │ ├── Secp256k1Point.cs # Pure C# secp256k1 (lift_x, ECDH, Schnorr)
│ │ ├── Nip44.cs # NIP-44 v2 encrypt/decrypt
│ │ ├── NostrRelayClient.cs # WebSocket Nostr relay client
│ │ ├── Bech32Decoder.cs # Bech32 decode + CLINK TLV parser
│ │ └── ClinkProtocol.cs # CLINK protocol (request/check/pay)
│ ├── Models/
│ │ ├── ClinkSettings.cs # Store configuration model
│ │ ├── ClinkPaymentData.cs # Payment tracking model
│ │ └── PaymentNotification.cs # Payment notification payload
│ ├── Views/
│ │ ├── Clink/
│ │ │ ├── Configure.cshtml # Admin configuration page
│ │ │ ├── ClinkStoreNav.cshtml # Store nav extension
│ │ │ ├── LightningSetupCustom.cshtml # Lightning setup accordion
│ │ │ ├── ClinkCheckoutPayment.cshtml # Checkout integration
│ │ │ └── NdebitSetup.cshtml # Auto-pay setup page
│ │ ├── _ViewImports.cshtml
│ │ └── _ViewStart.cshtml
│ ├── Resources/
│ │ ├── js/
│ │ │ └── clink-payment.js # Client-side checkout script
│ │ └── css/
│ │ └── clink-payment.css # Checkout styles
│ └── Data/
│ └── ClinkDbContext.cs # Database context
├── src/BTCPayServer.Plugins.Clink.Tests/
│ ├── RelayUrlValidatorTests.cs # Relay URL validation (12 tests)
│ ├── ClinkInputValidationTests.cs # Input validation pipeline tests
│ ├── TlvSecurityTests.cs # Injection-safe TLV decoding tests
│ ├── PaymentDataExpiryTests.cs # Payment data expiry enforcement tests
│ ├── NdebitIntegrationTests.cs # TLV parsing, payload format, preimage SHA256
│ ├── Bech32DecoderTests.cs # Bech32/CLINK format tests
│ ├── Nip44Tests.cs # NIP-44 crypto tests
│ └── StoreIsolationTests.cs # Store isolation regression tests
├── plugin-env.sh # Dev environment setup
├── plugin-register.sh # Debug registration script
└── README.md
GPL-3.0