Receiving payments
With the Breez SDK you aren't required to open a channel and set up your inbound liquidity.
Once the SDK is initialized, you can directly begin receiving payments. The receive process takes two steps:
Developer note
Consider implementing the Notification Plugin when using the Breez SDK in a mobile application. By registering a webhook the application can receive notifications to process the payment in the background.Preparing Payments
During the prepare step, the SDK ensures that the inputs are valid with respect to the specified payment method, and also returns the relative fees related to the payment so they can be confirmed.
The SDK currently supports three methods of receiving: Lightning, Bitcoin and Liquid:
Lightning
When receiving via Lightning, we generate an invoice to be paid. Note that the payment may fallback to a direct Liquid payment (if the payer's client supports this).
Note: The amount field is currently mandatory when paying via Lightning.
// Fetch the Receive lightning limits
let current_limits = sdk.fetch_lightning_limits().await?;
info!("Minimum amount: {} sats", current_limits.receive.min_sat);
info!("Maximum amount: {} sats", current_limits.receive.max_sat);
// Set the invoice amount you wish the payer to send, which should be within the above limits
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
payment_method: PaymentMethod::Lightning,
payer_amount_sat: Some(5_000),
})
.await?;
// If the fees are acceptable, continue to create the Receive Payment
let receive_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", receive_fees_sat);
// Fetch the Receive lightning limits
let currentLimits = try? sdk.fetchLightningLimits()
print("Minimum amount: {} sats", currentLimits?.receive.minSat ?? 0);
print("Maximum amount: {} sats", currentLimits?.receive.maxSat ?? 0);
// Set the invoice amount you wish the payer to send, which should be within the above limits
let prepareResponse = try? sdk
.prepareReceivePayment(req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.lightning,
payerAmountSat: 5_000
));
// If the fees are acceptable, continue to create the Receive Payment
let receiveFeesSat = prepareResponse!.feesSat;
print("Fees: {} sats", receiveFeesSat);
try {
// Fetch the lightning Receive limits
val currentLimits = sdk.fetchLightningLimits()
// Log.v("Breez", "Minimum amount allowed to deposit in sats: ${currentLimits.receive.minSat}")
// Log.v("Breez", "Maximum amount allowed to deposit in sats: ${currentLimits.receive.maxSat}")
// Set the invoice amount you wish the payer to send, which should be within the above limits
val prepareRequest = PrepareReceiveRequest(PaymentMethod.LIGHTNING, 5_000.toULong())
val prepareResponse = sdk.prepareReceivePayment(prepareRequest)
// If the fees are acceptable, continue to create the Receive Payment
val receiveFeesSat = prepareResponse.feesSat;
// Log.v("Breez", "Fees: ${receiveFeesSat} sats")
} catch (e: Exception) {
// handle error
}
// Fetch the Receive lightning limits
const currentLimits = await fetchLightningLimits()
console.log(`Minimum amount, in sats: ${currentLimits.receive.minSat}`)
console.log(`Maximum amount, in sats: ${currentLimits.receive.maxSat}`)
// Set the amount you wish the payer to send via lightning, which should be within the above limits
const prepareResponse = await prepareReceivePayment({
paymentMethod: PaymentMethod.LIGHTNING,
payerAmountSat: 5_000
})
// If the fees are acceptable, continue to create the Receive Payment
const receiveFeesSat = prepareResponse.feesSat
console.log(`Fees: ${receiveFeesSat} sats`)
// Fetch the Receive lightning limits
LightningPaymentLimitsResponse currentLightningLimits =
await breezSDKLiquid.instance!.fetchLightningLimits();
print("Minimum amount: ${currentLightningLimits.receive.minSat} sats");
print("Maximum amount: ${currentLightningLimits.receive.maxSat} sats");
// Create an invoice and set the amount you wish the payer to send
PrepareReceiveResponse prepareResponse =
await breezSDKLiquid.instance!.prepareReceivePayment(
req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.lightning,
payerAmountSat: 5000 as BigInt,
),
);
// If the fees are acceptable, continue to create the Receive Payment
BigInt receiveFeesSat = prepareResponse.feesSat;
print("Fees: $receiveFeesSat sats");
try:
# Fetch the lightning Receive limits
current_limits = sdk.fetch_lightning_limits()
logging.debug("Minimum amount allowed to deposit in sats ", current_limits.receive.min_sat)
logging.debug("Maximum amount allowed to deposit in sats ", current_limits.receive.max_sat)
# Set the invoice amount you wish the payer to send, which should be within the above limits
prepare_request = PrepareReceiveRequest(PaymentMethod.LIGHTNING, 5_000)
prepare_response = sdk.prepare_receive_payment(prepare_request)
# If the fees are acceptable, continue to create the Receive Payment
receive_fees_sat = prepare_response.fees_sat
logging.debug("Fees: ", receive_fees_sat, " sats")
return prepare_response
except Exception as error:
logging.error(error)
raise
// Fetch the lightning Receive limits
if currentLimits, err := sdk.FetchLightningLimits(); err == nil {
log.Printf("Minimum amount, in sats: %v", currentLimits.Receive.MinSat)
log.Printf("Maximum amount, in sats: %v", currentLimits.Receive.MaxSat)
}
// Set the invoice amount you wish the payer to send, which should be within the above limits
optionalPayerAmountSat := uint64(5_000)
prepareRequest := breez_sdk_liquid.PrepareReceiveRequest{
PaymentMethod: breez_sdk_liquid.PaymentMethodLightning,
PayerAmountSat: &optionalPayerAmountSat,
}
if prepareResponse, err := sdk.PrepareReceivePayment(prepareRequest); err == nil {
// If the fees are acceptable, continue to create the Receive Payment
receiveFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", receiveFeesSat)
}
try
{
// Fetch the lightning Receive limits
var currentLimits = sdk.FetchLightningLimits();
Console.WriteLine($"Minimum amount allowed to deposit in sats: {currentLimits.receive.minSat}");
Console.WriteLine($"Maximum amount allowed to deposit in sats: {currentLimits.receive.maxSat}");
// Set the invoice amount you wish the payer to send, which should be within the above limits
var prepareRequest = new PrepareReceiveRequest(PaymentMethod.Lightning, 5000);
var prepareResponse = sdk.PrepareReceivePayment(prepareRequest);
// If the fees are acceptable, continue to create the Receive Payment
var receiveFeesSat = prepareResponse.feesSat;
Console.WriteLine($"Fees: {receiveFeesSat} sats");
}
catch (Exception)
{
// Handle error
}
Bitcoin
When receiving via Bitcoin, we generate a Bitcoin BIP21 URI to be paid.
Note: The amount field is currently mandatory when paying via Bitcoin.
// Fetch the Receive onchain limits
let current_limits = sdk.fetch_onchain_limits().await?;
info!("Minimum amount: {} sats", current_limits.receive.min_sat);
info!("Maximum amount: {} sats", current_limits.receive.max_sat);
// Set the onchain amount you wish the payer to send, which should be within the above limits
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
payment_method: PaymentMethod::BitcoinAddress,
payer_amount_sat: Some(5_000),
})
.await?;
// If the fees are acceptable, continue to create the Receive Payment
let receive_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", receive_fees_sat);
// Fetch the Receive onchain limits
let currentLimits = try? sdk.fetchOnchainLimits()
print("Minimum amount: {} sats", currentLimits?.receive.minSat ?? 0);
print("Maximum amount: {} sats", currentLimits?.receive.maxSat ?? 0);
// Set the onchain amount you wish the payer to send, which should be within the above limits
let prepareResponse = try? sdk
.prepareReceivePayment(req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.bitcoinAddress,
payerAmountSat: 5_000
));
// If the fees are acceptable, continue to create the Receive Payment
let receiveFeesSat = prepareResponse!.feesSat;
print("Fees: {} sats", receiveFeesSat);
try {
// Fetch the onchain Receive limits
val currentLimits = sdk.fetchOnchainLimits()
// Log.v("Breez", "Minimum amount allowed to deposit in sats: ${currentLimits.receive.minSat}")
// Log.v("Breez", "Maximum amount allowed to deposit in sats: ${currentLimits.receive.maxSat}")
// Set the onchain amount you wish the payer to send, which should be within the above limits
val prepareRequest = PrepareReceiveRequest(PaymentMethod.BITCOIN_ADDRESS, 5_000.toULong())
val prepareResponse = sdk.prepareReceivePayment(prepareRequest)
// If the fees are acceptable, continue to create the Receive Payment
val receiveFeesSat = prepareResponse.feesSat;
// Log.v("Breez", "Fees: ${receiveFeesSat} sats")
} catch (e: Exception) {
// handle error
}
// Fetch the Onchain lightning limits
const currentLimits = await fetchOnchainLimits()
console.log(`Minimum amount, in sats: ${currentLimits.receive.minSat}`)
console.log(`Maximum amount, in sats: ${currentLimits.receive.maxSat}`)
// Set the onchain amount you wish the payer to send, which should be within the above limits
const prepareResponse = await prepareReceivePayment({
paymentMethod: PaymentMethod.BITCOIN_ADDRESS,
payerAmountSat: 5_000
})
// If the fees are acceptable, continue to create the Receive Payment
const receiveFeesSat = prepareResponse.feesSat
console.log(`Fees: ${receiveFeesSat} sats`)
// Fetch the Receive onchain limits
OnchainPaymentLimitsResponse currentOnchainLimits =
await breezSDKLiquid.instance!.fetchOnchainLimits();
print("Minimum amount: ${currentOnchainLimits.receive.minSat} sats");
print("Maximum amount: ${currentOnchainLimits.receive.maxSat} sats");
// Or create a cross-chain transfer (Liquid to Bitcoin) via chain swap
PrepareReceiveResponse prepareResponse =
await breezSDKLiquid.instance!.prepareReceivePayment(
req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.bitcoinAddress,
payerAmountSat: 5000 as BigInt,
),
);
// If the fees are acceptable, continue to create the Receive Payment
BigInt receiveFeesSat = prepareResponse.feesSat;
print("Fees: $receiveFeesSat sats");
try:
# Fetch the onchain Receive limits
current_limits = sdk.fetch_onchain_limits()
logging.debug("Minimum amount allowed to deposit in sats ", current_limits.receive.min_sat)
logging.debug("Maximum amount allowed to deposit in sats ", current_limits.receive.max_sat)
# Set the onchain amount you wish the payer to send, which should be within the above limits
prepare_request = PrepareReceiveRequest(PaymentMethod.BITCOIN_ADDRESS, 5_000)
prepare_response = sdk.prepare_receive_payment(prepare_request)
# If the fees are acceptable, continue to create the Receive Payment
receive_fees_sat = prepare_response.fees_sat
logging.debug("Fees: ", receive_fees_sat, " sats")
return prepare_response
except Exception as error:
logging.error(error)
raise
// Fetch the onchain Receive limits
if currentLimits, err := sdk.FetchOnchainLimits(); err == nil {
log.Printf("Minimum amount, in sats: %v", currentLimits.Receive.MinSat)
log.Printf("Maximum amount, in sats: %v", currentLimits.Receive.MaxSat)
}
// Set the onchain amount you wish the payer to send, which should be within the above limits
optionalPayerAmountSat := uint64(5_000)
prepareRequest := breez_sdk_liquid.PrepareReceiveRequest{
PaymentMethod: breez_sdk_liquid.PaymentMethodBitcoinAddress,
PayerAmountSat: &optionalPayerAmountSat,
}
if prepareResponse, err := sdk.PrepareReceivePayment(prepareRequest); err == nil {
// If the fees are acceptable, continue to create the Receive Payment
receiveFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", receiveFeesSat)
}
try
{
// Fetch the onchain Receive limits
var currentLimits = sdk.FetchOnchainLimits();
Console.WriteLine($"Minimum amount allowed to deposit in sats: {currentLimits.receive.minSat}");
Console.WriteLine($"Maximum amount allowed to deposit in sats: {currentLimits.receive.maxSat}");
// Set the onchain amount you wish the payer to send, which should be within the above limits
var prepareRequest = new PrepareReceiveRequest(PaymentMethod.BitcoinAddress, 5000);
var prepareResponse = sdk.PrepareReceivePayment(prepareRequest);
// If the fees are acceptable, continue to create the Receive Payment
var receiveFeesSat = prepareResponse.feesSat;
Console.WriteLine($"Fees: {receiveFeesSat} sats");
}
catch (Exception)
{
// Handle error
}
Developer note
The above checks include validating against maximum and minimum limits. Your application's users must be informed of these limits because if the amount transferred to the swap address falls outside this valid range, the funds will not be successfully received via the normal swap flow. In such cases, a manual refund will be necessary. For further instructions on how to execute a manual refund, see the section on refunding payments.
Liquid
When receiving via Liquid, we can either generate an address to receive to, or a BIP21 URI with information regarding the payment (currently only the amount and message).
To generate a BIP21 address, all you have to do is specify a payer amount.
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
payment_method: PaymentMethod::LiquidAddress,
payer_amount_sat: Some(5_000), // Not specifying the amount will create a plain Liquid address instead
})
.await?;
// If the fees are acceptable, continue to create the Receive Payment
let receive_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", receive_fees_sat);
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
let prepareResponse = try? sdk
.prepareReceivePayment(req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.liquidAddress,
payerAmountSat: 5_000 // Not specifying the amount will create a plain Liquid address instead
))
// If the fees are acceptable, continue to create the Receive Payment
let receiveFeesSat = prepareResponse!.feesSat;
print("Fees: {} sats", receiveFeesSat);
try {
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
// Note: Not setting the amount will generate a plain Liquid address
val prepareRequest = PrepareReceiveRequest(PaymentMethod.LIQUID_ADDRESS, 5_000.toULong())
val prepareResponse = sdk.prepareReceivePayment(prepareRequest)
// If the fees are acceptable, continue to create the Receive Payment
val receiveFeesSat = prepareResponse.feesSat;
// Log.v("Breez", "Fees: ${receiveFeesSat} sats")
} catch (e: Exception) {
// handle error
}
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
const prepareResponse = await prepareReceivePayment({
paymentMethod: PaymentMethod.LIQUID_ADDRESS,
payerAmountSat: 5_000 // Not specifying the amount will create a plain Liquid address instead
})
// If the fees are acceptable, continue to create the Receive Payment
const receiveFeesSat = prepareResponse.feesSat
console.log(`Fees: ${receiveFeesSat} sats`)
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
PrepareReceiveResponse prepareResponse =
await breezSDKLiquid.instance!.prepareReceivePayment(
req: PrepareReceiveRequest(
paymentMethod: PaymentMethod.liquidAddress,
payerAmountSat: 5000
as BigInt, // Not specifying the amount will create a plain Liquid address instead
),
);
// If the fees are acceptable, continue to create the Receive Payment
BigInt receiveFeesSat = prepareResponse.feesSat;
print("Fees: $receiveFeesSat sats");
try:
# Create a Liquid BIP21 URI/address to receive a payment to.
# There are no limits, but the payer amount should be greater than broadcast fees when specified
# Note: Not setting the amount will generate a plain Liquid address
prepare_request = PrepareReceiveRequest(PaymentMethod.LIQUID_ADDRESS, 5_000)
prepare_response = sdk.prepare_receive_payment(prepare_request)
# If the fees are acceptable, continue to create the Receive Payment
receive_fees_sat = prepare_response.fees_sat
logging.debug("Fees: ", receive_fees_sat, " sats")
return prepare_response
except Exception as error:
logging.error(error)
raise
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
// Note: Not setting the amount will generate a plain Liquid address
optionalPayerAmountSat := uint64(5_000)
prepareRequest := breez_sdk_liquid.PrepareReceiveRequest{
PaymentMethod: breez_sdk_liquid.PaymentMethodLiquidAddress,
PayerAmountSat: &optionalPayerAmountSat,
}
if prepareResponse, err := sdk.PrepareReceivePayment(prepareRequest); err == nil {
// If the fees are acceptable, continue to create the Receive Payment
receiveFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", receiveFeesSat)
}
try
{
// Create a Liquid BIP21 URI/address to receive a payment to.
// There are no limits, but the payer amount should be greater than broadcast fees when specified
// Note: Not setting the amount will generate a plain Liquid address
var prepareRequest = new PrepareReceiveRequest(PaymentMethod.LiquidAddress, 5000);
var prepareResponse = sdk.PrepareReceivePayment(prepareRequest);
// If the fees are acceptable, continue to create the Receive Payment
var receiveFeesSat = prepareResponse.feesSat;
Console.WriteLine($"Fees: {receiveFeesSat} sats");
}
catch (Exception)
{
// Handle error
}
Receiving Payments
Once the payment has been prepared, all you have to do is pass the prepare response as an argument to the receive method, optionally specifying a description.
Note: The description field will be used differently, depending on the payment method:
- For Lightning payments, it will be encoded in the invoice
- For Bitcoin/Liquid BIP21 payments, it will be encoded in the URI as the
message
field. - For plain Liquid payments, the description has no effect.
let optional_description = Some("<description>".to_string());
let res = sdk
.receive_payment(&ReceivePaymentRequest {
prepare_response,
description: optional_description,
use_description_hash: None,
})
.await?;
let destination = res.destination;
let optionalDescription = "<description>"
let res = try? sdk.receivePayment(req: ReceivePaymentRequest(
prepareResponse: prepareResponse,
description: optionalDescription
))
let destination: String = res!.destination;
print("Destination: {}", destination);
try {
val optionalDescription = "<description>";
val req = ReceivePaymentRequest(prepareResponse, optionalDescription)
val res = sdk.receivePayment(req)
val destination = res.destination;
} catch (e: Exception) {
// handle error
}
const optionalDescription = '<description>'
const res = await receivePayment({
prepareResponse,
description: optionalDescription
})
const destination = res.destination
String optionalDescription = "<description>";
ReceivePaymentResponse res = await breezSDKLiquid.instance!.receivePayment(
req: ReceivePaymentRequest(
description: optionalDescription,
prepareResponse: prepareResponse,
),
);
String destination = res.destination;
try:
optional_description = "<description>"
req = ReceivePaymentRequest(prepare_response, optional_description)
res = sdk.receive_payment(req)
destination = res.destination
except Exception as error:
logging.error(error)
raise
optionalDescription := "<description>"
req := breez_sdk_liquid.ReceivePaymentRequest{
PrepareResponse: prepareResponse,
Description: &optionalDescription,
}
if res, err := sdk.ReceivePayment(req); err == nil {
// If the fees are acceptable, continue to create the Receive Payment
destination := res.Destination
log.Printf("Destination: %v", destination)
}
try
{
var optionalDescription = "<description>";
var req = new ReceivePaymentRequest(prepareResponse, optionalDescription);
var res = sdk.ReceivePayment(req);
var destination = res.destination;
}
catch (Exception)
{
// Handle error
}