Send Payment

How do I send a Bitcoin Lightning Network payment?

Availability

👍

To enable in the production environment, please contact the partner success team.

Overview

The Cybrid Platform supports sending payment in either USD or BTC.

In order to support customers sending payments on the Lightning Network, a special type of account called an "invoice operations" pre-fund account must be created. Invoice operations accounts can be created in USDor BTC, dependiong on the currency you want to support your customers using to pay Lightning Network invoices. The balance of your invoice operations account is held with Cybrid's third party Lightning Network provider to allow for instant payment of Lightning invoices. Invoice operations accounts can be created to hold balances in USD or BTC.

Customer payments are made from your invoice operations pre-fund account to instantly settle the payment of the invoice. When a Lightning Network payment is made, the payment amount will also be book-transferred from the customer's fiat account, for USD payments, or the customer's trading account, for BTC payments, to the bank's fiat USD account or trading BTC account (see figure below). Both the invoice operations pre-fund account and the customer's fiat account must have sufficient balance to fund the customer's payment amount including network fees.

In order to fund (and top-up as required, step #2 in the diagram above) the invoice operations pre-fund account, a special type of transfer called an "inter-account" transfer must be used to transfer from the bank's fiat or trading account to the invoice operations pre-fund account. These inter-account transfers use wire transfers, in the case of USD accounts, and on-chain transfers, in the case of BTC accounts between the Cybrid Platform and the Lightning Network provider. Wire fees and on-chain network fees apply, as appropriate. These inter-account transfer fees will be included in the partner's Cybrid Platform monthly invoicing.

To allow a customer to send a Bitcoin Lightning Network payment follow these steps on the Cybrid Platform:

  1. Create a bank-level fiat account for USD payments and/ or a trading account for BTC payments;
  2. Create and fund a customer-level fiat account or trading account;
  3. Create an invoice operations pre-fund account in either USD or BTC;
  4. Fund the invoice operations pre-fund account with an inter-account transfer;
  5. Create a Lightning Network payment transfer; and,
  6. Top-up the invoice operations pre-fund account, as required.

For this guide, we'll use the following terminology:

  • The Cybrid partner's customer will be referred to as the "payer".
  • The payer's end-merchant will be referred to as the "payee".

1. Creating bank-level accounts

If you haven't already, create a bank-level fiat account for USD payments or a bank-level trading account for BTC payments. This is a one-time operation.

See the guide for creating accounts at the bank-level here.

2. Create and fund the customer-level account

If you haven't already, create a customer-level fiat account or trading account. This is a one-time operation.

Once the customer-level account has been created, the account must be funded. This is an ongoing operation.

See the guides for creating and funding accounts at the customer-level here and here.

3. Create an invoice operations pre-fund account

The invoice operations pre-fund account is created at the bank-level. This is a one-time operation.

You may create a USD or a BTC invoice operations pre-fund account at the bank-level via the POST /api/accounts endpoint.

An example POST /api/accounts request body is below:

{
  "type": "invoice_operations",
  "asset": "USD",
  "name": "<insert account descriptive name>"
}

When executed, the following response body will be returned:

{
  "created_at": "<created_at timestamp>",
  "updated_at": "<updated_at timestamp>",
  "type": "invoice_operations",
  "guid": "<created account GUID>",
  "asset": "USD",
  "name": "<inserted account descriptive name>",
  "bank_guid": "762a77263ea05ee526a330a98b2b610c",
  "platform_balance": 0,
  "platform_available": 0,
  "state": "storing",
  "labels": null
}

The account will begin in "state":"storing", and automatically progress to "state":"created" which is the terminal state for accounts.

4. Fund the invoice operations pre-fund account with an inter-account transfer

The invoice operations pre-fund account must funded in order for a customer to send a payment via the Lightning Network. This is an ongoing operation.

👍

Note: When funding the invoice operations pre-fund account, be sure to also account for potential network fees.

You may create a quote to fund the invoice operations pre-fund account via the POST /api/quotes endpoint.

An example POST /api/quotes request body is below:

{
  "product_type": "inter_account",
  "asset": "USD",
  "deliver_amount": <insert deliver_amount>
}

When executed, the following response body will be returned:

{
  "created_at": "<created_at timestamp>",
  "updated_at": "<updated_at timestamp>",
  "guid": "<created quote_guid>",
  "product_type": "inter_account",
  "bank_guid": "<associated bank_guid>",
  "asset": "USD",
  "side": "deposit",
  "receive_amount": <calculated receive_amount>,
  "deliver_amount": <inserted deliver_amount>,
  "fee": 0,
  "issued_at": "<issued_at timestamp>",
  "expires_at": "<expires_at timestamp>"
}

Use the the above quote GUID in the POST /api/transfers request.

An example POST /api/transfers request body is below:

{
  "transfer_type": "inter_account",
  "quote_guid": "<insert quote_guid>",
  "source_account_guid": "<insert bank-level fiat or trading account_guid>",
  "destination_account_guid": "<insert invoice operations account_guid>"
}

When executed, the following response body will be returned:

{
  "created_at": "<created_at timestamp>",
  "updated_at": "<updated_at timestamp>",
  "guid": "<created transfer_guid>",
  "transfer_type": "inter_account",
  "bank_guid": "<associated bank_guid>",
  "quote_guid": "<inserted quote_guid>",
  "external_bank_account_guid": null,
  "asset": "USD",
  "side": "deposit",
  "state": "storing",
  "failure_code": null,
  "amount": <inserted deliver_amount>,
  "estimated_amount": <inserted deliver_amount>,
  "fee": 0,
  "source_account": {
    "type": "fiat",
    "guid": "<inserted bank-level fiat account_guid>",
    "bank_guid": "<associated bank_guid>"
  },
  "source_participants": null,
  "destination_account": {
    "type": "invoice_operations",
    "guid": "<insert invoice operations account_guid>",
    "bank_guid": "<associated bank_guid>"
  },
  "destination_participants": null,
  "labels": null
}

Use the GET /api/transfers/{transfer_guid} endpoint to verify the "state" of the transfer.

Once the transfer has progressed to "state":"completed", use the GET /api/accounts/{account_guid} endpoint to verify that the "platform_available" balance of the invoice operations account has been credited to the reflect the transfer amount.

5. Create a Lightning Network payment transfer

Once the invoice operations pre-fund account has been funded, customers may now send a payment in order to pay a Lightning Network invoice (see the Receive Payment guide for steps to create a Lightning Network invoice).

For a customer (i.e., the payor) that is "state":"verified", and has a fiat or trading account, you may send payment to a Lightning Network invoice via the POST /api/transfers endpoint.

You may create a "lightning_transfer" quote using the POST /api/quotes endpoint.

An example POST /api/quotes request body is below:

{
  "product_type": "lightning_transfer",
  "customer_guid": "<insert customer_guid>",
  "network_address": "<insert network_address>",
  "asset": "USD"
}

👍

Note: When creating quotes in sandbox banks, the "receive_amount" will be a randomly generated amount.

👍

Note: Since Lightning Network channels are not created in sandbox banks (i.e. "network_address" will always be "sandbox_network_address"), when creating quotes for payment instructions that were generated in sandbox banks the "network_address" can be any string value.

When executed, the following response body will be returned:

{
  "created_at": "<created_at timestamp>",
  "updated_at": "<updated_at timestamp>",
  "guid": "<created quote_guid>",
  "product_type": "lightning_transfer",
  "customer_guid": "<inserted customer_guid>",
  "asset": "USD",
  "side": "withdrawal",
  "receive_amount": <calculated receive_amount>,
  "deliver_amount": <calculated deliver_amount>,
  "fee": 0,
  "issued_at": "<issued_at timestamp>",
  "expires_at": "<expires_at timestamp>"
  "network_fee_asset": "USD",
  "network_address": "<inserted network_address>"
}

You may create a "lightning" transfer using the "quote_guid" from above and the POST /api/transfer endpoint.

👍

Note: When creating the "lightning" transfer, you may specify if the partner or the customer is paying the network fees by inserting either the bank-level fiat or trading account_guid or the customer-level fiat or trading account_guid in the "network_fee_account_guid".

An example POST /api/transfers request body is below:

{
  "transfer_type": "lightning",
  "customer_guid": "<inserted customer_guid>",
  "quote_guid": "<inserted quote_guid>",
  "network_fee_account_guid": "<inserted network_fee_account_guid>"
}

When executed, the following response body will be returned:

{
  "created_at": "<created_at timestamp>",
  "updated_at": "<updated_at timestamp>",
  "guid": "<created transfer_guid>",
  "transfer_type": "lightning",
  "customer_guid": "<inserted customer_guid>",
  "quote_guid": "<inserted quote_guid>",
  "external_bank_account_guid": null,
  "asset": "USD",
  "side": "withdrawal",
  "state": "storing",
  "failure_code": null,
  "amount": <calculated amount>,
  "estimated_amount": <calculated estimated_amount>,
  "fee": 0,
  "source_account": {
    "type": "fiat",
    "guid": "<inserted account_guid>",
    "customer_guid": "<inserted customer_guid>"
  },
  "source_participants": null,
  "destination_account": null,
  "destination_participants": null,
  "labels": null
}

Use the GET /api/transfers/{transfer_guid} endpoint to verify the "state" of the transfer.

Once the transfer has progressed to "state":"completed":

  • Use the GET /api/accounts/{account_guid} endpoint to verify that the "platform_available" balance of the invoice operations pre-fund account has been debited by the transfer and network fee amounts.
    • The invoice operations pre-fund account initially covers the payment amount including network fees.
  • Use the GET /api/accounts/{account_guid} endpoint to verify that the "platform_available" balance of the customer fiat account has also been debited to the reflect the transfer amount.
    • The payment amount including network fees will be book transferred from the network fees if the customer's account was chosen to cover the network fees.
  • Use the GET /api/accounts/{account_guid} endpoint to verify that the "platform_available" balance of the bank-level fiat account has been credited to the reflect the transfer amount.

6. Top-up the invoice operations pre-fund account as required

In order to top-up the invoice operations pre-fund, repeat step 3: Fund the invoice operations pre-fund account.