Sending payments

Once the SDK is initialized, you can directly begin sending payments. The send process takes two steps:

  1. Preparing the Payment
  2. Sending the Payment

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 destination, and also returns the relative fees related to the payment so they can be confirmed.

The destination field of the payment request supports Liquid BIP21, Liquid addresses and Lightning invoices

Lightning

When sending via Lightning, the bolt11 invoice amount must be set. If the optional prepare request amount is also set, the SDK will make sure the two values match, else an error will be thrown.

The SDK will also validate that the amount is within the send lightning limits of the swap service.

Rust
// Set the bolt11 invoice you wish to pay
let prepare_response = sdk
    .prepare_send_payment(&PrepareSendRequest {
        destination: "<bolt11 invoice>".to_string(),
        amount_sat: None,
    })
    .await?;

// If the fees are acceptable, continue to create the Send Payment
let send_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", send_fees_sat);
Swift
// Set the bolt11 invoice you wish to pay
let prepareResponse = try? sdk
    .prepareSendPayment(req: PrepareSendRequest (
        destination: "<bolt11 invoice>"
    ))

// If the fees are acceptable, continue to create the Send Payment
let sendFeesSat = prepareResponse!.feesSat
print("Fees: {} sats", sendFeesSat);
Kotlin
// Set the bolt11 you wish to pay
val destination = "<bolt11 invoice>"
try {
    val prepareResponse = sdk.prepareSendPayment(PrepareSendRequest(destination))

    // If the fees are acceptable, continue to create the Send Payment
    val sendFeesSat = prepareResponse.feesSat;
    // Log.v("Breez", "Fees: ${sendFeesSat} sats")
} catch (e: Exception) {
    // handle error
}
React Native
// Set the bolt11 invoice you wish to pay
const prepareResponse = await prepareSendPayment({
  destination: '<bolt11 invoice>'
})

// If the fees are acceptable, continue to create the Send Payment
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
Dart
// Set the bolt11 invoice you wish to pay
PrepareSendResponse prepareSendResponse = await breezSDKLiquid.instance!.prepareSendPayment(
  req: PrepareSendRequest(destination: "<bolt11 invoice>"),
);

// If the fees are acceptable, continue to create the Send Payment
BigInt sendFeesSat = prepareSendResponse.feesSat;
print("Fees: $sendFeesSat sats");
Python
# Set the bolt11 invoice you wish to pay
destination = "<bolt11 invoice>"
try:
    prepare_response = sdk.prepare_send_payment(PrepareSendRequest(destination))

    # If the fees are acceptable, continue to create the Send Payment
    send_fees_sat = prepare_response.fees_sat
    logging.debug("Fees: ", send_fees_sat, " sats")
    return prepare_response
except Exception as error:
    logging.error(error)
    raise
Go
// Set the bolt11 invoice you wish to pay
destination := "<bolt11 invoice>"
prepareRequest := breez_sdk_liquid.PrepareSendRequest{
    Destination: destination,
}
prepareResponse, err := sdk.PrepareSendPayment(prepareRequest)
if err != nil {
    log.Printf("Error: %#v", err)
    return
}

sendFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", sendFeesSat)
C#
// Set the bolt11 invoice you wish to pay
var destination = "<bolt11 invoice>";
try
{
    var prepareResponse = sdk.PrepareSendPayment(new PrepareSendRequest(destination));

    // If the fees are acceptable, continue to create the Send Payment
    var sendFeesSat = prepareResponse.feesSat;
    Console.WriteLine($"Fees: {sendFeesSat} sats");
}
catch (Exception)
{
    // Handle error
}

Developer note

When paying an invoice generated by another Liquid SDK instance, or any other application which uses the Boltz swapper internally, the payment will fall back to a direct onchain payment. The advantage of this is the payer will spend less on fees, as they are no longer relying on external services to execute the payment. Note that this also means a Breez API key will be required in order for the payment to be executed. To learn more about this process and how it works in detail, see the Boltz documentation for Magic Routing Hints (MRH).

Bitcoin

For onchain (Bitcoin) payments, see Sending an on-chain transaction.

Liquid

When sending via Liquid, a BIP21 URI or Liquid address can be used as the destination.

If a Liquid address is used, the optional prepare request amount must be set.

If a BIP21 URI is used, either the BIP21 URI amount or optional prepare request amount must be set. When both amounts are set, the SDK will prioritize the request amount over the BIP21 amount.

Note: If a valid Breez API key is not provided, the method will throw an error requiring you to specify one.

Rust
// Set the Liquid BIP21 or Liquid address you wish to pay
let optional_amount_sat = Some(5_000);
let prepare_response = sdk
    .prepare_send_payment(&PrepareSendRequest {
        destination: "<Liquid BIP21 or address>".to_string(),
        amount_sat: optional_amount_sat,
    })
    .await?;

// If the fees are acceptable, continue to create the Send Payment
let send_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", send_fees_sat);
Swift
// Set the Liquid BIP21 or Liquid address you wish to pay
let optionalAmountSat: UInt64? = Optional.some(5000)
let prepareResponse = try? sdk
    .prepareSendPayment(req: PrepareSendRequest (
        destination: "<Liquid BIP21 or address>",
        amountSat: optionalAmountSat
    ))

// If the fees are acceptable, continue to create the Send Payment
let sendFeesSat = prepareResponse!.feesSat
print("Fees: {} sats", sendFeesSat);
Kotlin
// Set the Liquid BIP21 or Liquid address you wish to pay
val destination = "<Liquid BIP21 or address>"
try {
    val optionalAmountSat = 5_000.toULong();
    val prepareResponse = sdk.prepareSendPayment(PrepareSendRequest(destination, optionalAmountSat))

    // If the fees are acceptable, continue to create the Send Payment
    val sendFeesSat = prepareResponse.feesSat;
    // Log.v("Breez", "Fees: ${sendFeesSat} sats")
} catch (e: Exception) {
    // handle error
}
React Native
// Set the Liquid BIP21 or Liquid address you wish to pay
const optionalAmountSat = 5_000
const prepareResponse = await prepareSendPayment({
  destination: '<Liquid BIP21 or address>',
  amountSat: optionalAmountSat
})

// If the fees are acceptable, continue to create the Send Payment
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
Dart
// Set the Liquid BIP21 or Liquid address you wish to pay
BigInt optionalAmountSat = BigInt.from(5000);

PrepareSendResponse prepareSendResponse = await breezSDKLiquid.instance!.prepareSendPayment(
  req: PrepareSendRequest(destination: "<Liquid BIP21 or address>", amountSat: optionalAmountSat),
);

// If the fees are acceptable, continue to create the Send Payment
BigInt sendFeesSat = prepareSendResponse.feesSat;
print("Fees: $sendFeesSat sats");
Python
# Set the Liquid BIP21 or Liquid address you wish to pay
destination = "<Liquid BIP21 or address>"
try:
    optional_amount_sat = 5_000
    prepare_response = sdk.prepare_send_payment(PrepareSendRequest(destination, optional_amount_sat))

    # If the fees are acceptable, continue to create the Send Payment
    send_fees_sat = prepare_response.fees_sat
    logging.debug("Fees: ", send_fees_sat, " sats")
    return prepare_response
except Exception as error:
    logging.error(error)
    raise
Go
// Set the Liquid BIP21 or Liquid address you wish to pay
destination := "<Liquid BIP21 or address>"
optionalAmountSat := uint64(5_000)
prepareRequest := breez_sdk_liquid.PrepareSendRequest{
    Destination: destination,
    AmountSat:   &optionalAmountSat,
}
prepareResponse, err := sdk.PrepareSendPayment(prepareRequest)
if err != nil {
    log.Printf("Error: %#v", err)
    return
}

sendFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", sendFeesSat)
C#
// Set the Liquid BIP21 or address you wish to pay
var destination = "<Liquid BIP21 or address>";
try
{
    ulong optionalAmountSat = 5000;
    var prepareResponse = sdk.PrepareSendPayment(new PrepareSendRequest(destination, optionalAmountSat));

    // If the fees are acceptable, continue to create the Send Payment
    var sendFeesSat = prepareResponse.feesSat;
    Console.WriteLine($"Fees: {sendFeesSat} sats");
}
catch (Exception)
{
    // Handle error
}

Sending Payments

Once the payment has been prepared, all you have to do is pass the prepare response as an argument to the send method.

Rust
let send_response = sdk
    .send_payment(&SendPaymentRequest { prepare_response })
    .await?;
let payment = send_response.payment;
Swift
let sendResponse = try? sdk.sendPayment(req: SendPaymentRequest (
    prepareResponse: prepareResponse
))
let payment = sendResponse!.payment
Kotlin
try {
    val sendResponse = sdk.sendPayment(SendPaymentRequest(prepareResponse))
    val payment = sendResponse.payment
} catch (e: Exception) {
    // handle error
}
React Native
const sendResponse = await sendPayment({
  prepareResponse
})
const payment = sendResponse.payment
Dart
SendPaymentResponse sendPaymentResponse = await breezSDKLiquid.instance!.sendPayment(
  req: SendPaymentRequest(prepareResponse: prepareResponse),
);
Payment payment = sendPaymentResponse.payment;
Python
try:
    send_response = sdk.send_payment(SendPaymentRequest(prepare_response))
    payment = send_response.payment
except Exception as error:
    logging.error(error)
    raise
Go
req := breez_sdk_liquid.SendPaymentRequest{
    PrepareResponse: prepareResponse,
}
if response, err := sdk.SendPayment(req); err == nil {
    payment := response.Payment
    log.Printf("Payment: %#v", payment)
}
C#
try
{
    var sendResponse = sdk.SendPayment(new SendPaymentRequest(prepareResponse));
    var payment = sendResponse.payment;
}
catch (Exception)
{
    // Handle error
}