

Understanding Lightning Invoices
To send and receive Lightning payments, you can generate and pay Lightning invoices. A Lightning invoice (also called a payment request) is a specially formatted string that contains all the information needed to make a Lightning Network payment:- Amount: How many satoshis to send (can be omitted for zero-amount invoices)
- Destination: The recipient’s node public key
- Payment Hash: A unique identifier for the payment
- Description: Optional memo describing the payment
- Expiry: How long the invoice is valid for (use the returned
invoice.expiresAt)
lnbc1...
Lightning Deposit Flow
The complete process for receiving Lightning payments into your Spark wallet:1
Create Invoice
Generate a Lightning invoice with the desired amount and description.
2
Share Invoice
Provide the invoice to the sender (via QR code, link, or text).
3
Monitor Payment
Track the payment status until completion.
Create Lightning Invoice
Generate Lightning invoices to receive Bitcoin payments that will be deposited into your Spark wallet. Creates a Lightning invoice for receiving Bitcoin payments.Spark Payment Integration
Spark provides two ways to enable Spark-based payments alongside Lightning invoices:Option 1: Spark Invoice in Routing Hints
By settingincludeSparkInvoice: true, a Spark invoice is embedded in the routing hints section of the BOLT11 invoice. This allows Spark-compatible wallets to automatically detect and pay over Spark instead of Lightning, providing a seamless user experience:
- Spark-compatible wallets can pay directly over Spark (faster, potentially lower fees)
- Non-Spark wallets will pay via Lightning as normal
- The payment is correlated to the original invoice
Option 2: Spark Address in Fallback Field
By passing intrue for includeSparkAddress, a 36-byte string consisting of a recognizable header and a receiver’s compressed identity public key SPK:identitypubkey will get embedded in the fallback address (f) field of a BOLT11 invoice:
Fallback Address Format
The embedded Spark address in the fallback field will look something like this:includeSparkAddress and includeSparkInvoice in the same invoice.
Creating Invoices for Other Spark Users
To generate an invoice for another Spark user, pass in the 33-byte compressed identity pubkey as a string toreceiverIdentityPubkey:
If a wallet is generating an invoice for itself and wants to embed its own Spark identity in the invoice, it will not need to pass in a
receiverIdentityPubkey to embed a Spark address. That will get taken care of on the backend. Passing it in shouldn’t change anything though.SPARK_LIGHTNING_RECEIVE_FINISHED webhook for an invoice it creates on behalf of someone else. Register the webhook on that wallet; do not assume the receiver alone will receive the notification. The receive-request lookup is restricted to the requester or receiver. Preserve the requesting wallet’s identity across process restarts, or query as the receiver.
In the SDK, invoice creation uses SparkWallet, which also runs background claims and maintenance. See wallet lifecycle.
Zero-Amount Invoices
Spark supports creating zero-amount Lightning invoices. Zero-amount invoices don’t have a fixed amount and allow the sender to specify the amount when making the payment.Creating Zero-Amount Invoices
To create a zero-amount invoice, pass0 for the amountSats parameter:
Monitor Lightning Payments
Track incoming Lightning payments and their status using receive request monitoring. Gets the status of a Lightning receive request by ID.Match the invoice, request, and transfer
Save the receive request’sid and invoice.paymentHash when creating the invoice. The BOLT11 payment hash identifies the Lightning payment; the Spark transfer ID identifies the movement of funds on Spark. They are different identifiers.
Once the receive request has a transfer, request.transfer.sparkId links it to operator transfer history:
Transfer does not carry the Lightning payment hash. If you start with a Spark transfer ID, use getTransferFromSsp() to retrieve its associated payment request. A plain Lightning receive can have no sparkInvoice; that optional field is not the correlation key, and includeSparkAddress: false does not populate it.
Only the requester or receiver can look up the receive request. An unrelated wallet gets null, which does not establish that the invoice does not exist. A viewer grant for Bitcoin history does not grant access to Lightning receive requests.
Amounts and units
For example, a 1,000-sat invoice has
originalValue: 1000000 with originalUnit: "MILLISATOSHI". Do not compare bare amount values across these surfaces. The request has no amountReceived field.
Completion and event order
A Lightning receive request status such asPAYMENT_PREIMAGE_RECOVERED or TRANSFER_COMPLETED, an operator transfer status, and the wallet’s transfer:claimed event describe different steps. A completed Lightning receive request does not establish that the receiver has claimed the funds. See received versus spendable.
The incoming Spark transfer can appear before the receive request is finalized and its webhook is delivered. These describe successive parts of the receive flow. Your application may observe events and lookup responses at different times, so do not require a particular notification arrival order. Persist the identifiers, handle repeated notifications, and re-query the request if its transfer is not yet available. Stream heartbeats are connection activity, not payments; do not depend on a fixed heartbeat interval.
For server notifications, see Webhooks, including the difference between webhook IDs and SDK request IDs.