Glossary

BOLT-12 Refund

A BOLT-12 message type that allows a payer to request a return payment from the original recipient, enabling structured refund flows on the Lightning Network.

Key Takeaways

  • A BOLT-12 refund uses the reverse invoice_request flow defined in the BOLT specification: the merchant publishes an invoice_request for the amount owed, and the original payer responds with an invoice that the merchant then pays.
  • The invreq_payer_id (payer key) from the original BOLT-12 offer payment serves as a cryptographic proof of purchase, allowing the merchant to verify refund eligibility without relying on external records.
  • Unlike BOLT-11, which has no native refund mechanism and requires manual coordination of a separate payment, BOLT-12 defines a structured protocol-level flow for returning funds to the original sender.

What Is a BOLT-12 Refund?

A BOLT-12 refund is a structured payment flow within the BOLT-12 offers specification that enables a merchant or recipient to return funds to the original payer. The BOLT-12 spec describes this as the "merchant-pays-user" flow, applicable to scenarios like ATM withdrawals and refunds. Rather than introducing a dedicated refund message, BOLT-12 reuses the existing invoice_request mechanism in reverse: instead of the payer requesting an invoice from the merchant, the merchant creates an invoice_request specifying the refund amount, and the payer responds with an invoice to be paid.

This reverse flow solves a long-standing gap in Lightning payments. BOLT-11 invoices are one-directional: they describe a payment from sender to receiver with no protocol-level way to initiate a return. If a merchant needed to refund a customer, both parties had to coordinate out-of-band. The customer would generate a new invoice, share it via email or chat, and the merchant would pay it manually. BOLT-12 formalizes this into a cryptographically verifiable, in-protocol workflow.

How It Works

The BOLT-12 refund flow leverages the same onion message infrastructure used for standard offer payments, but with reversed roles. The party initiating the refund (typically the merchant) acts as the payer, and the original customer acts as the invoice issuer.

The Refund Flow Step by Step

  1. The customer originally pays the merchant via a standard BOLT-12 offer flow, which records an invreq_payer_id (payer key) as a cryptographic identifier for the buyer
  2. When a refund is needed, the merchant creates a standalone invoice_request containing the refund amount (invreq_amount), a description (offer_description), and their own invreq_payer_id
  3. The merchant delivers this invoice_request to the customer, either via onion message using stored invreq_paths (blinded reply paths) from the original payment, or out-of-band as an encoded string
  4. The customer's wallet validates the invoice_request, generates a fresh invoice with a unique payment hash, and sends it back to the merchant via onion message
  5. The merchant verifies the invoice, confirms the invoice_node_id matches the expected recipient, and pays the invoice through standard Lightning HTLC routing

The critical element is the payer key (invreq_payer_id) from the original transaction. This key cryptographically links the refund to the original purchase, allowing the merchant to verify that the refund request comes from the actual buyer rather than an impersonator.

Invoice Request Without an Offer

For refunds, the invoice_request does not reference an existing offer. According to the BOLT-12 specification, a standalone invoice_request (one without offer_issuer_id or offer_paths) must include several required fields:

# Standalone invoice_request for a refund (encoded with lnr prefix)
# Required fields:
#   invreq_payer_id   - merchant's key for this refund
#   invreq_metadata   - opaque data for verification
#   invreq_amount     - refund amount in millisatoshis
#   offer_description - human-readable reason for the refund
#
# Optional fields:
#   invreq_payer_note - free-text note (e.g., "Refund for order #1042")
#   invreq_paths      - blinded paths for receiving the reply invoice
#   invreq_chain      - required if the chain is not solely Bitcoin

# Fields that MUST NOT be present in a standalone request:
#   offer_metadata, offer_chains, offer_amount,
#   offer_currency, offer_features, offer_quantity_max,
#   offer_paths, offer_issuer_id, signature

When the customer's wallet receives this standalone invoice_request, it validates that the required fields are present and that invreq_amount is set. The wallet then generates an invoice where invoice_amount equals invreq_amount. If invreq_paths was included, the invoice must be delivered via one of those blinded paths; otherwise, it is sent directly to the invreq_payer_id.

Payer Key as Proof of Purchase

Each BOLT-12 payment includes an invreq_payer_id: a point key chosen by the sender that acts as a pseudonymous identifier. This key is committed to the invoice and serves multiple purposes:

  • The merchant can store the payer key alongside order records, creating a link between the Lightning payment and the business transaction
  • When processing a refund, the merchant can verify the requester controls the private key corresponding to the original invreq_payer_id, proving they are the actual buyer
  • The payer key is unlinkable across different payments: a customer uses a different key for each purchase, preserving privacy while still enabling per-transaction refund eligibility

This is a significant improvement over BOLT-11, which has no standard mechanism for payer identification and requires merchants to rely on external identifiers (email, account ID) to match refund requests to original payments.

Comparison to BOLT-11 Refund Workarounds

Before BOLT-12, Lightning refunds required entirely manual coordination. The limitations of the BOLT-11 approach highlight why a protocol-level solution matters:

AspectBOLT-11 WorkaroundBOLT-12 Refund Flow
InitiationCustomer generates new invoice, shares out-of-bandMerchant creates invoice_request in-protocol
Identity verificationNo cryptographic link to original paymentPayer key proves original purchase
PrivacyRoute hints may expose customer nodeBlinded paths hide both parties
AutomationFully manual, requires human coordinationCan be automated by wallet software
Partial refundsCustomer must create invoice for exact partial amountMerchant specifies amount in invoice_request
Expiry riskBOLT-11 invoice may expire before merchant paysInvoice generated on demand from live request

For a deeper look at how these flows compare, see the research article on Lightning invoices: BOLT-11, BOLT-12, and beyond.

Use Cases

E-Commerce Returns

Online merchants accepting Lightning payments can integrate BOLT-12 refunds into their return workflows. When a customer requests a return, the merchant's system creates an invoice_request for the refund amount and delivers it to the customer. The customer's wallet handles the rest automatically: validating the request, generating an invoice, and receiving the refund payment. No email thread or manual invoice sharing is required.

Partial Refunds and Adjustments

Because the merchant controls the invreq_amount field, partial refunds are straightforward. A restaurant that overcharged a customer can issue an invoice_request for just the overage amount. A subscription service can prorate a cancellation refund. The amount is explicit in the protocol message, reducing disputes about refund calculations.

Point-of-Sale Corrections

Physical retail scenarios benefit from BOLT-12 refunds when transactions need to be reversed at the counter. A merchant using a static BOLT-12 offer for accepting payments can initiate a refund by presenting the customer with an invoice_request encoded as a QR code. The customer scans it with their wallet, which generates and returns an invoice, and the merchant's node pays it immediately.

Cancellations and Disputes

Lightning payments are final by design: once an HTLC settles and the preimage is revealed, there is no protocol-level reversal. BOLT-12 refunds provide a structured alternative for merchants who want to offer customer-friendly cancellation policies without sacrificing the finality guarantees that make Lightning attractive. The refund is a new payment in the opposite direction, not a reversal of the original transaction.

Why It Matters

Refund capability is table stakes for commerce. Traditional payment rails like credit cards have built-in chargeback mechanisms, and customers expect some form of recourse when products are defective or services are not delivered. Lightning's lack of a native refund flow has been a barrier to merchant adoption: businesses accustomed to payment processor integrations that handle refunds programmatically cannot easily replicate that workflow on Lightning without BOLT-12.

By formalizing refunds at the protocol level, BOLT-12 makes Lightning more viable for mainstream commerce. Wallet developers can build refund UIs that work consistently across implementations, and merchants can integrate refund logic into their existing order management systems. For platforms like Spark, which aims to make Bitcoin payments accessible to everyday users, protocol-level refund support removes a significant friction point for both merchants and customers.

Implementation Status

BOLT-12 was formally merged into the Lightning specification in September 2024, but implementation maturity varies across node software. The refund flow, being a specific application of the invoice_request mechanism, depends on full BOLT-12 support:

  • Core Lightning (CLN): the most mature implementation, with full BOLT-12 support including offer creation, invoice requests, and the merchant-pays-user flow that enables refunds
  • LDK (Lightning Dev Kit): supports BOLT-12 offers and onion messages, enabling wallet developers building on LDK to implement refund flows
  • Eclair: supports BOLT-12 offers and onion messages natively, with ACINQ integrating the feature into the Phoenix mobile wallet
  • LND: BOLT-12 support remains experimental, available behind the --protocol.experimental-offers flag or through the LNDK sidecar. Native refund flow support is not yet production-ready

A community proposal on Delving Bitcoin suggests adding an optional refund_invoice_required field to offers, which would require payers to include a pre-built refund invoice in their invoice_request at payment time. This would enable automatic refunds without requiring a follow-up round trip. The proposal is under discussion and has not been adopted into the specification.

Risks and Considerations

No Protocol-Level Enforcement

BOLT-12 refunds are cooperative: the merchant must voluntarily initiate the refund flow. The protocol provides the mechanism but does not enforce refund policies. Unlike credit card chargebacks, where the card network can compel the merchant to return funds, a Lightning merchant can simply refuse to create the invoice_request. Buyers relying on refund guarantees still need trust in the merchant or a third-party dispute resolution layer.

Identity Confirmation Challenge

When processing a standalone invoice_request (one without an associated offer), the spec notes that the payer "MAY reject the invoice if it cannot confirm invoice_node_id out-of-band." This means the merchant receiving a refund invoice has no automatic way to verify the invoice was created by the intended recipient. In practice, merchants should verify the invoice_node_id against stored records from the original payment to prevent refund fraud.

Onion Message Reliability

The refund flow depends on onion messages for delivering invoice_requests and receiving invoices in return. Onion messages are best-effort: nodes can drop them without penalty, and there are no economic incentives for reliable forwarding. If the customer's node is temporarily unreachable, the invoice_request may fail silently. Merchants implementing refund systems need retry logic and fallback delivery mechanisms.

Adoption Fragmentation

Because LND (the most widely deployed Lightning implementation) lacks production-ready BOLT-12 support, refund flows cannot reliably reach all Lightning users. A merchant running CLN can initiate refunds, but customers running LND wallets may be unable to process the invoice_request. This fragmentation limits the practical utility of BOLT-12 refunds until cross-implementation support matures. For more context on the adoption landscape, see the research article on BOLT-12 adoption in 2026.

Privacy Considerations

While blinded paths protect node identity during the refund flow, the payer key (invreq_payer_id) creates a persistent link between the original payment and the refund. If a merchant's database is breached, an attacker could correlate refund records with payment records. Customers concerned about privacy should be aware that accepting a refund through this flow creates a linkable record between two transactions.

This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.