BTCPay Lightning Part 2: The Inbound Channel Journey

BTCPay Lightning Part 2: The Inbound Channel Journey

This is the second part of the guide on how to configure the Lightning Node in a BTCPay Server to be able to receive payments which are made by Shopify consumers to a Lightning Node address that is presented to them during the Shopify Shopping Cart payment process. This continues from Part 1 where we successfully configured and opened our first Lightning channel.

Where we are: Just with Outbound Liquidity

In the prior post, we configured the BTCPay Server's Lightning Node with a funded Satoshi balance and opened our first Lightning channel. We initially opened a channel to the ACINQ peer node, but encountered routing challenges that led us to explore other well-connected peers. We ultimately established two 100,000 sat channels with blocktank and gameb_1 - both nodes that showed as "Reachable" in Lightning Terminal and were open to accepting connections.

When we opened these channels, all the transfer capacity was on the Store's side. This is called "outbound liquidity" - we can send payments, but we can't receive them.

As a merchant, this is the opposite of what we need. We need a way for bitcoin money to flow from the consumer's wallet through Shopify to our Lightning Node invoice to the Lightning Node network to our Lightning Node, eventually "looping out" to our BTCPay Server's BTC Wallet. Where, as Bitcoin Maximalists, we HODL it, of course.

Describing Liquidity Direction:

  • Outbound liquidity: You have sats on the Store side of the channel, so you can send payments
  • Inbound liquidity: You have available capacity at the Store side, so you can receive payments

For merchants: You need inbound in order to receive customer payments.

We now have a Lightning Node with two open channels (blocktank and gameb_1) with 100,000 sats each of outbound capacity and 0 sats of inbound. The next step is to create inbound liquidity so we can receive customer payments.

Creating Inbound Liquidity: Two Approaches

There are fundamentally two ways to create inbound capacity:

  1. Spend sats from your channels: When you send a Lightning payment, you decrease your local balance and increase your remote balance - this creates inbound capacity organically.
  2. Submarine swap (Loop Out): You send Lightning sats out over the Lightning Network, receive regular Bitcoin back on-chain, and this creates inbound capacity on your channel.

We'll explore both methods, but first let's set up the tools.

Lightning Terminal and Loop

Loop is a submarine swap service created by Lightning Labs. A submarine swap is an atomic swap between on-chain Bitcoin and Lightning Network Bitcoin - it lets you move funds between the two layers without trust.

Loop is included with Lightning Terminal (LiT), a web-based interface that bundles several Lightning management tools. Installing it on BTCPay Server is trivially easy.

A submarine swap is an atomic swap between on-chain Bitcoin and Lightning Network Bitcoin. It lets you move funds between the two layers without trust — for example, to send an on-chain payment yet receive Lightning sats in return, or the reverse.

Simply:
It uses the same HTLC (hash time-locked contract) mechanism that Lightning itself uses. One party creates a secret (a preimage) and its hash. The on-chain transaction is locked to that hash, and the Lightning payment is also locked to the same hash.

When the Lightning payment is claimed the preimage is revealed to the claimant and that preimage is then used to claim the on-chain funds too. Because both sides of the swap use the same secret, neither party can cheat - either both legs complete or neither does.

Why is it called "submarine":
Because the transaction "dives below the surface" - it goes from the visible on-chain BTC layer (the "surface") down into the Lightning Network (which operates "underwater," off-chain); for the reverse swap, it surfaces back up from Lightning to on-chain BTC.

Coined by Alex Bosworth, an early implementor of the technology, the metaphor is about moving between what's publicly visible on the blockchain and what's happening in the off-chain layer beneath it.

Adding Lightning Terminal to BTCPay

BTCPay Server uses Docker Compose with optional "fragments" - pre-built configurations you can add. Lightning Terminal is one of these fragments.

  • first, ssh into your BTCPay Server and su to root.
cd ~/btcpayserver-docker
export LIT_PASSWD="YourSecurePasswordHere"
  • store this Lightning Terminal password with your other passwords for this BTCPay Server.

You need it when launching the "terminal" from the BTCPay Server's Lightning page.

  • next, add the BTCPay Fragment for the Lightning Terminal and re-run the BTCPay Server setup

export BTCPAYGEN_ADDITIONAL_FRAGMENTS="$BTCPAYGEN_ADDITIONAL_FRAGMENTS;opt-add-lightning-terminal" . ./btcpay-setup.sh -i

Well-crafted BTCPay Server scripts:

Do not worry about losing your BTCPay Server's blockchain sync or channel
data when reconfiguring. The configuration scripts gracefully stops containers, regenerates the configuration, and starts everything back up.

Your fully-synced Bitcoin node stays synced, the channel remains intact, and
everything was back online in about 5 minutes.

BTCPay Server's blockchain data lives in persistent Docker volumes that don't get altered during reconfigurations. (Be careful if you run Docker commands yourself, there are a few that will delete vital state data and files.)

After the restart, the Lightning Terminal launcher appears in your BTCPay Server under the Lightning page along with the RTL launcher.

Accessing Lightning Terminal

Clicking on Lightning Terminal widget opened a new tab asking for the Lightning Terminal password. This is the same LIT_PASSWD chosen during installation.

The first time you log in, it also generates a "Connect Passphrase" - a unique authentication token for this session. This is separate from your password and used for securing the connection between the web interface and your Lightning node.

Security Note: The Connect Passphrase is generated automatically and you don't need to remember it. It's stored in your browser session. Your LIT_PASSWD is what you store in your password vault and use each time you log in.

Understanding the Lightning Terminal Interface

Lightning Terminal has an attractive interface compared to RTL. The Explore tab shows recommended peers based on network analysis - this is where we discovered blocktank and gameb_1 as "Reachable" connection options after our initial ACINQ channel experiments.

On the Loop tab, you'll see the peers and channels you've opened. Our two 100k sat channels with blocktank and gameb_1 appear here.

The interface for Loop Out uses a slider-based design. It takes some time to figure out what the slider for the channel is actually tuning. It adjusts the PPM for the Loop Out transaction.

What is PPM?

PPM stands for "Parts Per Million" - it's the routing fee rate you're willing to pay for the Lightning payment to reach the Loop server.

Here's how it works:

  • Higher PPM (right side of slider): You're willing to pay more in fees, which gives the network more flexibility to find a route
  • Lower PPM (left side of slider): You pay minimal fees, but the route might fail if it requires expensive hops

For a 100,000 sat Loop Out:

  • At 500 PPM: Maximum ~50 sats in routing fees (~$0.05)
  • At 100 PPM: Maximum ~10 sats in routing fees (~$0.01)
  • At 1 PPM: Essentially free routing

Note that this PPM-tuned fee is separate from the Loop service fee (~0.5-1%) and the Bitcoin mining fee for the on-chain transaction.

Using the Slider

To perform a Loop, you slide the bar to the left, meaning you decrease your Lightning balance and receive on-chain funds in return, performing a Loop Out. You can also perform a Loop In, which refills your Lightning channels using your on-chain balance.

Use the slider to choose how many satoshis you want to swap. A warning will appear if you do not meet the minimum swap size for the nodes participating in the swap.

The Diagnosis: New Channel Propagation

Before attempting Loop Out or testing payments, we learned an important lesson about channel maturity.

Lightning Network Gossip Takes Time

When you open a Lightning channel, here's what happens:

  • Immediate (0-10 minutes): On-chain transaction confirms, channel opens, shows as "Active" in your node
  • First hour: You and your peer know about the channel, but the rest of the network doesn't
  • 6-24 hours: Channel announcement propagates through the Lightning Network via gossip protocol
  • 24+ hours: Most routing nodes know about your channel and can include it in their pathfinding

After opening our blocktank and gameb_1 channels, we needed to wait several days for full network propagation before routing would work reliably. Attempting to use very young channels resulted in routing failures - not because anything was wrong, but simply because the network hadn't learned about them yet.

Critical Lesson: There's a difference between a channel being "active" (both peers online, channel state valid) and a channel being "useful for routing" (other nodes know it exists and can route through it). Patience is required.

Testing Inbound: The Simpler Approach

After waiting for channel propagation, we decided to create inbound capacity the organic way first - by spending sats to purchase something useful.

When you spend Lightning sats, you:

  • Decrease your local balance (outbound capacity)
  • Increase your remote balance (inbound capacity)
  • Get something you actually want

We considered using The Bitcoin Company to purchase a gift card, spending approximately 50,000 sats from one of our channels. This would have immediately created 50,000 sats of inbound capacity - accomplishing the mission with a purchase and getting a useful gift card in the process. This wasn't necessary. However, we will try that soon to assure that it, too, works.

Testing Receipt of Payments

With inbound capacity established, it was time to test whether our node could actually receive payments from external wallets.

Creating a Lightning Invoice

In BTCPay Server, we created a small test invoice for 76 sats - just enough to verify the payment flow worked.

The invoice displays:

  • A QR code
  • A payment request string starting with lnbc
  • Payment hash and other technical details

Important: Make sure you're creating a Lightning invoice, not a regular Bitcoin on-chain address. Lightning invoices start with "lnbc" and have QR codes. On-chain addresses start with "bc1" (or other formats). They are very different payment types.

First Attempt: Coinbase Wallet

We first tried using a Coinbase account in the Coinbase mobile app. Despite Coinbase having Lightning support, the payment failed to honor the invoice.

This aligns with reports that Coinbase's Lightning implementation is limited and doesn't work well with all Lightning nodes. (See https://help.coinbase.com/en/coinbase/trading-and-funding/sending-or-receiving-cryptocurrency/lightning)

Success: Wallet of Satoshi

Wallet of Satoshi is a dedicated Lightning wallet with excellent routing capabilities. We opened the app, scanned our BTCPay invoice QR code, and clicked Send.

Result: Success! ✅

The 76 sat payment arrived instantly at our Lightning node. Our BTCPay Server showed the invoice as "Paid," and we could see the channel balance shift:

  • Local balance increased by 76 sats
  • Remote balance decreased by 76 sats

Our merchant Lightning node was now fully operational and ready to receive customer payments!

What This Proves

Successfully receiving a payment from Wallet of Satoshi demonstrated:

  • ✅ Our Lightning channels are properly propagated through the network
  • ✅ External wallets can find routes to our node
  • ✅ BTCPay Server's Lightning integration works end-to-end
  • ✅ We can receive payments from customers worldwide
  • ✅ The entire setup is ready for Shopify integration

Key Takeaways

What we Learned:

On Peer Selection:

  • Not all Lightning peers are equally well-connected
  • Lightning Terminal's "Explore" feature helps find reachable peers
  • Having multiple channels provides redundancy and better routing
  • Peer connectivity matters for successful payments

On Inbound Liquidity:

  • Opening a channel creates OUTBOUND liquidity (you can send)
  • Merchants need INBOUND liquidity (to receive payments)
  • Spending sats is the simplest way to create inbound capacity
  • Loop Out is available as an alternative when needed

On Lightning Terminal:

  • Adding fragments to BTCPay is straightforward with Docker
  • Reconfigurations don't lose blockchain sync or channel data
  • LIT_PASSWD set during install is used for web login
  • The Explore feature helps identify good peer candidates

On Network Propagation:

  • New channels take 24+ hours to propagate through the network
  • "Active" in RTL doesn't mean "known to the network"
  • Routing failures in the first days are normal, not errors
  • Patience is essential - wait several days before expecting reliable routing

On Testing:

  • Coinbase Lightning support is limited - not recommended for testing
  • Wallet of Satoshi works reliably for testing merchant receives
  • Small test invoices (76-1000 sats) are perfect for validation
  • Successful test payment proves the entire stack works

For Other Merchants Following This Path

If you're setting up Lightning for your own store, here's what I'd recommend based on this experience:

  1. Choose well-connected peers using Lightning Terminal's Explore feature
  2. Open 2-3 smaller channels rather than one large channel for redundancy
  3. Wait 48-72 hours after opening before testing payments
  4. Create inbound by spending on gift cards or useful items first
  5. Test with Wallet of Satoshi before enabling in production
  6. Start with small invoices (100-1000 sats) to validate the flow

The total timeline from starting your BTCPay Server to accepting customer Lightning payments is about 3-5 days if you account for blockchain sync, channel opening confirmations, and network propagation. But most of that is passive waiting time, not active work.

The actual hands-on configuration time is maybe 2-3 hours total across both parts of this setup.

Cost Summary

Here's what was spent on this Lightning setup:

  • Bitcoin for channels: $200 worth in two 100k sat channels (this is CAPITAL, not spent - still yours in the channels)
  • On-chain fees to open channels: ~$10-15 total
  • Server costs: AWS EC2 instance (~$40-60/month for full node)

Ready for Production

With successful inbound liquidity and a confirmed test payment, the Lightning node is now ready for Shopify integration. The next step is enabling Lightning as a payment option in the store and processing real customer payments.

The journey from zero Lightning knowledge to operational merchant node took patience and troubleshooting, but the result is a self-custodial payment system that can accept instant, low-fee Bitcoin payments from anywhere in the world.

Return to Collection