Skip to main content

Sending payments

Overview

The Strike API can be used to send payments over the Bitcoin and Lightning Networks from a Strike user’s cash balance or bitcoin balance (currently available for select business accounts). This walkthrough shows you how to integrate the Strike API into your payment process for sending payments. Please contact business@strike.me for more information.

How sending a payment works

Sending a payment via the Strike API begins with obtaining a Lightning invoice or an on-chain Bitcoin address. A Lightning invoice is an alphanumeric code that acts as a request for payment, which may include an amount to be paid in bitcoin and the payment destination. An on-chain Bitcoin address is an alphanumeric code that acts as a destination for a Bitcoin payment.

Once a Lightning invoice or an on-chain address has been received, a quote must be generated. The quote specifies the cost of making the payment and can be set to either cash or bitcoin as the source currency. For paying with cash, the quote offers a temporary conversion rate between dollars and bitcoin, whereas for paying with bitcoin, the quote simply acts as a necessary step leading to payment execution. Additionally, for on-chain transactions the quote serves to specify the on-chain fee amount to be paid, which determines how quickly the transaction is confirmed on the blockchain. It’s important to note that Lightning invoices and quotes have expiration times.

To initiate a payment, simply execute the quote. When executed, the quote’s specified source currency will be debited from the sender’s account and the payment will be sent to the recipient via the specified sending method, either through the Lightning Network or broadcasted as an on-chain transaction. Please note that Lightning transactions are faster and cheaper than on-chain transactions, and are often considered preferable for many bitcoin payment solutions.

Sending flow

Integration walkthrough

1. Check supported currencies

Sending payments via the Strike API can be sourced from any of your account’s available currencies. To check which currencies are available, use the fetch public account profile info by handle endpoint, which will return the available currencies for sending payments, as well as the account’s default currency.

Below is an example request to fetch public account profile info:

Example request:
curl -X 'GET' \
'https://<ENVIRONMENT>/v1/accounts/handle/<HANDLE>/profile' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <API_KEY>'

To use this example yourself, simply replace the placeholder values with your own values. The <ENVIRONMENT> should be replaced with api.strike.me, the <API_KEY> should be replaced with your own API key bearer token, and the <HANDLE> should be replaced with your Strike handle.

Below is the response to the fetch public account profile info request:

Example response:
{
"handle": "astrid_waters64",
"canReceive": true,
"currencies": [
{
"currency": "BTC",
"isDefaultCurrency": false,
"isAvailable": true,
"isInvoiceable": false
},
{
"currency": "USD",
"isDefaultCurrency": true,
"isAvailable": true,
"isInvoiceable": true
}
]
}

The above response shows that this account is able to send payments from both their BTC and USD balances, and that USD is the account’s default currency. In the following step for generating a payment quote, if no sourceCurrency is specified for the quote, it will automatically be set to your account’s default currency.

2. Generate a payment quote

The payment process begins by obtaining either a Lightning invoice (lnInvoice) or on-chain Bitcoin address (btcAddress). Lightning invoices are encoded with the payment destination and the amount to be paid in bitcoin, while on-chain addresses simply act as a payment destination. Once a Lightning invoice or on-chain address has been received, a quote must be generated as a necessary step to make the payment.

Lightning payment quotes

For Lightning payments, use the create Lightning payment quote endpoint to generate a quote. For this endpoint, you’ll need to specify the Lightning invoice in the standard BOLT11 format, as well as the source currency for the payment. For Lightning invoices that don’t contain an amount to be paid, sometimes referred to as zero-amount or amountless invoices, the amount object must be included, detailing the desired payment amount, currency and feePolicy.

Payments can also be sent to a Lightning address or LNURL, using the create LNURL/LN address payment quote endpoint to generate the quote.

Below is an example request to generate a quote for a Lightning invoice:

Example request:
curl -X 'POST' \
'https://<ENVIRONMENT>/v1/payment-quotes/lightning' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <API_KEY> \
-H 'Content-Type: application/json' \
-d '{
"lnInvoice": "LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6",
"sourceCurrency": "USD"
}'

The above request did not include the amount object, since it’s for paying a BOLT11 invoice that already has a payment amount encoded within it. Including the amount object when the Lightning invoice contains a payment amount will result in a 422 error being returned as the quote generation response. Similarly, omitting the amount object when generating a quote for an amountless invoice will also result in a 422 error being returned.

Below is the response to the Lightning payment quote generation request:

Example response:
{
"paymentQuoteId": "99bb499a-aa28-4bf6-b976-4b74b2bee31f",
"description": "Invoice description",
"validUntil": "2023-02-03T03:27:34+00:00",
"conversionRate": {
"amount": "0.00004120",
"sourceCurrency": "USD",
"targetCurrency": "BTC"
},
"amount": {
"currency": "USD",
"amount": "167.00"
},
"lighningNetworkFee": {
"currency": "USD",
"amount": "0.54"
},
"totalAmount": {
"currency": "USD",
"amount": "167.54"
}
}

The above response shows the generated quote, identifiable by its unique paymentQuoteId. The quote contains a conversion rate between the sourceCurrency and bitcoin, the totalAmount needed to make the payment, a validUntil timestamp showing the expiration time, and the lightningNetworkFee. Lightning Network fees are paid to node operators within the Network when payments are routed to their intended destination.

The totalAmount combines both the invoiced amount and the lightningNetworkFee, and therefore represents the actual amount that will be paid by executing the quote. Please note that when sending a payment to a Strike user in the same currency, the conversionRate is not returned in the quote generation response.

If the Lightning invoice came from a Strike user and doesn't involve a cross-region or cross-currency conversion, then the payment quote will automatically default to a direct payment (Strike account to Strike account), therefore no Lightning-specific data will be returned in the response.

When paying an amountless invoice, the quote creation process follows the same procedure, except that an amount object must be included, specifying the amount to be paid and the currency for the amount. Additionally, the optional feePolicy can be included as part of the amount object and can be set to either INCLUSIVE or EXCLUSIVE. If set to INCLUSIVE, the on-chain fees will be included in the sending amount, effectively reducing your send amount to accommodate the fees. If set to EXCLUSIVE, the on-chain fees will be added on top of your specified sending amount. The feePolicy is an optional parameter, which defaults to EXCLUSIVE.

On-chain payment quotes

For on-chain payments, before generating a quote you must first determine your desired on-chain fee tier, which determines how quickly the payment is delivered by being confirmed on the blockchain. The three available tiers are tier_fast (higher fees, ~10-30 minute delivery), tier_standard (mid-range fees, ~1 hour delivery), and tier_free (no fees, ~12 hour delivery). To retrieve the tier details, use the get on-chain tiers endpoint and specify the btcAddress, amount, and currency denomination you wish to send.

Below is an example request to get on-chain tiers:

Example request:
curl -L -X POST 'https://api.strike.me/v1/payment-quotes/onchain/tiers' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-raw '{
"btcAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": {
"amount": "10.99",
"currency": "USD"
}
}'

Below is the response for the on-chain tiers request:

Example response:
[
{
"id": "tier_fast",
"estimatedDeliveryDurationInMin": 10,
"estimatedFee": {
"amount": "0.00002862",
"currency": "BTC"
}
},
{
"id": "tier_standard",
"estimatedDeliveryDurationInMin": 60,
"estimatedFee": {
"amount": "0.00000363",
"currency": "BTC"
}
},
{
"id": "tier_free",
"estimatedDeliveryDurationInMin": 720,
"estimatedFee": {
"amount": "0",
"currency": "BTC"
}
}
]

Once you have decided your preferred on-chain fee tier, use the create on-chain payment quote endpoint to generate a quote. For this endpoint, you’ll need to specify the on-chain Bitcoin address, the source currency for the payment, the amount and currency denomination you wish to send, and your desired on-chain fee tier.

Additionally, you can specify the optional fee policy in your quote generation request. The fee policy can be set to either INCLUSIVE or EXCLUSIVE. If set to INCLUSIVE, the on-chain fees will be included in the sending amount, effectively reducing your send amount to accommodate the fees. If set to EXCLUSIVE, the on-chain fees will be added on top of your specified sending amount. The feePolicy is an optional parameter, which defaults to EXCLUSIVE.

Below is an example request to generate a quote for an on-chain payment:

Example request:
curl -L -X POST 'https://api.strike.me/v1/payment-quotes/onchain' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-raw '{
"btcAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"sourceCurrency": "USD",
"description": "Payment for order #2383.",
"amount": {
"amount": "10.99",
"currency": "USD",
"feePolicy": "INCLUSIVE"
},
"onchainTierId": "tier_fast"
}'

Below is the response to the on-chain payment quote generation request:

Example response:
{
"paymentQuoteId": "c155cbd8-0dd2-451e-bfc2-100b3378879d",
"description": "Payment for order #2383.",
"validUntil": "2023-07-10T11:57:02.251+00:00",
"conversionRate": {
"amount": "0.00003281",
"sourceCurrency": "USD",
"targetCurrency": "BTC"
},
"amount": {
"amount": "10.39",
"currency": "USD"
},
"totalFee": {
"amount": "0.60",
"currency": "USD"
},
"totalAmount": {
"amount": "10.99",
"currency": "USD"
},
"estimatedDeliveryDurationInMin": 10
}

The above response shows the generated quote, identifiable by its unique paymentQuoteId. Similar to generating a quote for a Lightning payment, this on-chain quote contains a conversion rate between the sourceCurrency and bitcoin, the totalAmount needed to make the payment, a validUntil timestamp showing the expiration time, and the totalFee.

The totalAmount combines both the invoiced amount and the totalFee, and therefore represents the actual amount that will be paid by executing the quote. Please note that when sending a payment to a Strike user in the same currency, the conversionRate is not returned in the quote generation response.

If the Bitcoin address came from a Strike account and doesn't involve a cross-region or cross-currency conversion, then the payment quote will automatically default to a direct payment (Strike account to Strike account), therefore no on-chain-specific data will be returned in the response.

3. Execute the payment quote

To pay the quote’s totalAmount, you must execute the quote. To execute the quote, use the execute payment quote endpoint and specify the paymentQuoteId that was returned in the quote generation response in step 2.

Below is an example request to execute a Lightning payment quote:

Example request:
curl -X 'PATCH' \
'https://<ENVIRONMENT>/v1/payment-quotes/<PAYMENT_QUOTE_ID>/execute' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Length: 0'

When a payment quote is executed, the response will be returned as a newly created payment object.

Below is the response to the quote execution request:

Example response:
{
"paymentId": "11aa533f-232b-5bff-b967-abba2beef13",
"state": "COMPLETED",
"completed": "2023-02-03T03:28:34+00:00",
"conversionRate": {
"amount": "0.00004120",
"sourceCurrency": "USD",
"targetCurrency": "BTC"
},
"amount": {
"currency": "USD",
"amount": "167.00"
},
"lightningNetworkFee": {
"currency": "USD",
"amount": "0.54"
},
"totalAmount": {
"currency": "USD",
"amount": "167.54"
}
}

The above response shows the new payment object that was created as a result of executing the quote. The payment has its own unique paymentId, relevant conversionRate, and currency amounts for the payment. Please note that the paymentId is different from the paymentQuoteId that was executed at the beginning of step 3. This paymentID can be called upon to retrieve the current state of the payment in the following step.

Also note that both Lightning invoices and quotes have expiration times. If the Lightning invoice expires before being paid, then a new Lightning invoice must be obtained and a new quote must be generated to pay that new Lightning invoice. If only the quote expires before being executed, but the Lightning invoice remains unexpired, then you can simply generate a new payment quote to be executed. On-chain addresses do not expire.

4. Check payment status

Once the payment has been created as a result of executing the quote, the initial response will contain the state of the payment, indicating its current status. If the state is returned as COMPLETED, then the payment was successful and no further actions are needed.

For on-chain payments, the state will transition from PENDING to COMPLETED only after it has 1 confirmation on the Bitcoin blockchain, which may take minutes to hours depending on the on-chain fee tier you specified in step 2.

You can be notified of a payment’s state change by subscribing to the payment.updated webhook event. When one of your subscribed events occurs, a POST request will be automatically made to the webhook URI of the subscription. For details on how to subscribe to webhook events visit the webhooks section.

Below is an example webhook subscription response for the payment.updated webhook event:

Example response:
{
"id": "34f43981-fe06-4d05-9fc4-e858e8f9529b4",
"eventType": "payment.updated",
"webhookVersion": "v1",
"data": {
"entityId": "11aa533f-232b-5bff-b967-abba2beef13",
"changes": [
"state"
]
},
"created": "2023-02-03T03:34:34+00:00",
}

In this response, the id is the webhook event ID and the entityId is the paymentID of the payment object, indicating that the state of the payment has changed. Please note that the webhook subscription response doesn’t contain the new payment state, rather it describes that the state has changed.

To request the new state of the payment, use the get payment by ID endpoint, which will return the current state of the payment.

Below is an example request to get the payment by ID:

Example request:
curl -X GET \
'https://<ENVIRONMENT>/v1/payments/<PAYMENT_ID>' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <API_KEY>'

Below is the response to the get payment by ID request:

Example response:
{
"paymentId": "11aa533f-232b-5bff-b967-abba2beef13",
"state": "COMPLETED",
"completed": "2023-02-03T03:28:34+00:00",
"conversionRate": {
"amount": "0.00004120",
"sourceCurrency": "USD",
"targetCurrency": "BTC"
},
"amount": {
"currency": "USD",
"amount": "167.00"
},
"lightningNetworkFee": {
"currency": "USD",
"amount": "0.54"
},
"totalAmount": {
"currency": "USD",
"amount": "167.54"
}
}

In the above response, the state of the payment is COMPLETED, indicating that the payment was successfully sent.

Additionally, you can subscribe to the payment.created webhook event, which will notify you when a new payment object has been created.

Below is an example webhook subscription response for the payment.created webhook event:

Example response:
{
"id": "34f43981-fe06-4d05-9fc4-e858e8f9529b4",
"eventType": "payment.created",
"webhookVersion": "v1",
"data": {
"entityId": "11aa533f-232b-5bff-b967-abba2beef13"
},
"created": "2023-02-03T03:34:34+00:00",
}