Developer Guide
Sending (USD Line of Credit)
24 min
sending payments with usd line of credit this guide explains how to send lightning network and on chain bitcoin payments from a usd denominated wallet using the voltage payments api usd wallets leverage a line of credit to convert usd to btc at the time of payment prerequisites a voltage account with an active usd wallet (credit backed wallet with an associated usd line of credit) an api key with access to the environment (from the "api keys" page in your dashboard) the quotes api enabled, and a valid line of credit id for your usd wallet's line of credit the target lightning invoice or bitcoin address you intend to pay workflow overview sending from a usd wallet involves three steps determine the btc amount – if paying a lightning invoice, decode it to extract the payment amount in millisatoshis for on chain payments where you already know the amount, skip to step 2 obtain a conversion quote – use the post /quotes endpoint to get a quote for converting usd to btc this locks in an exchange rate and returns a quote id create the payment – call the post /payments endpoint with your usd wallet, including the quote id and payment details step 1 determine the btc amount from a lightning invoice to create a quote, you need the btc amount in millisatoshis (msats) when paying a lightning invoice, the amount is encoded in the invoice string itself and must be extracted before you can request a quote the voltage api does not currently provide an invoice decoding endpoint you will need to decode the invoice client side using a bolt 11 decoding library javascript / typescript using light bolt11 decoder https //www npmjs com/package/light bolt11 decoder npm install light bolt11 decoder import { decode } from 'light bolt11 decoder'; const invoice = 'lnbc1500n1p '; const decoded = decode(invoice); const amountsection = decoded sections find(s => s name === 'amount'); const amountmsats = amountsection ? number(amountsection value) null; if (!amountmsats) { throw new error('invoice does not contain an amount'); } console log(`amount ${amountmsats} msats`); // use amountmsats as the "amount" in your quote request (step 2) python using bolt11 https //pypi org/project/bolt11/ pip install bolt11 import bolt11 invoice = "lnbc1500n1p " decoded = bolt11 decode(invoice) amount msats = decoded amount msat if not amount msats raise valueerror("invoice does not contain an amount") print(f"amount {amount msats} msats") \# use amount msats as the "amount" in your quote request (step 2) for on chain or bip21 payments where you already know the amount you want to send, you can skip this step and go directly to step 2 step 2 get a quote for usd→btc conversion before creating a payment from a usd wallet, you must get a quote to convert the payment amount into btc use the amount you decoded in step 1 (or the amount you already know for on chain payments) endpoint post https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/quotes headers x api key your api key content type application/json example request curl 'https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/quotes' \\ \ request post \\ \ header 'x api key your api key' \\ \ header 'content type application/json' \\ \ data '{ "id" "87654321 4321 8765 cba9 fed987654321", "line of credit id" "{line of credit id}", "network" "mainnet", "amount" { "amount" 150000, "currency" "btc", "unit" "msats" }, "to" "usd" }' request fields id – a client generated uuid for the quote (for idempotency) line of credit id – your usd line of credit id network – the bitcoin network ("mainnet", "testnet", "signet", or "mutinynet") amount – the btc amount you need to send (in msats) when paying a lightning invoice, this is the amount decoded in step 1 to – target currency for conversion ("usd") the api will respond with a quote object containing an exchange rate and a quote id use that quote id in step 3 quotes are time limited use the quote promptly before it expires step 3 create a payment from the usd wallet with a valid quote in hand, create the payment using the post /payments endpoint endpoint post https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments headers x api key your api key content type application/json 3 1 send a lightning (bolt11) payment to pay a lightning invoice from a usd wallet, provide the invoice in the payment request field curl 'https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments' \\ \ request post \\ \ header 'x api key your api key' \\ \ header 'content type application/json' \\ \ data '{ "id" "68d00852 8dd8 4c71 94d2 91c84695da78", "wallet id" "{usd wallet id}", "currency" "usd", "quote id" "12345678 1234 5678 9abc def012345678", "type" "bolt11", "data" { "payment request" "lnbc1500n1p ", "amount" { "currency" "btc", "amount" 150000, "unit" "msats" }, "max fee" { "currency" "btc", "amount" 1000, "unit" "msats" } } }' request fields id – a client generated uuid for the payment (for idempotency) wallet id – the uuid of your usd wallet currency – "usd" (the wallet's currency) quote id – the uuid of the quote obtained in step 2 ( required for usd wallets ) type – "bolt11" for a lightning payment data payment request – the bolt 11 lightning invoice string (cannot be empty) data amount – optional btc amount object required if the invoice has no amount encoded; must match if the invoice has a fixed amount data max fee – optional maximum routing fee in btc (defaults to 1% of payment or 1,000 msats, whichever is greater) 3 2 send an on chain bitcoin payment to send btc on chain from a usd wallet, provide the bitcoin address and amount curl 'https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments' \\ \ request post \\ \ header 'x api key your api key' \\ \ header 'content type application/json' \\ \ data '{ "id" "2ec1e783 19b4 4c10 8181 66336a6232bd", "wallet id" "{usd wallet id}", "currency" "usd", "quote id" "12345678 1234 5678 9abc def012345678", "type" "onchain", "data" { "address" "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "amount" { "currency" "btc", "amount" 15000000, "unit" "msats" }, "max fee" { "currency" "btc", "amount" 1000000, "unit" "msats" }, "description" "payment for services" } }' request fields type – "onchain" for an on chain btc payment data address – the recipient's bitcoin address data amount – the amount to send in btc (msats) example 15,000,000 msats = 15,000 sats data max fee – optional maximum miner fee in msats data description – optional memo for your records 3 3 send a unified bip21 payment a bip21 uri can include both an on chain address and an embedded lightning invoice the api will parse the uri and execute the payment via lightning or on chain as appropriate curl 'https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments' \\ \ request post \\ \ header 'x api key your api key' \\ \ header 'content type application/json' \\ \ data '{ "id" "3e84b6c5 5bbe 4e0f 9fb3 f1198330f6fa", "wallet id" "{usd wallet id}", "currency" "usd", "quote id" "12345678 1234 5678 9abc def012345678", "type" "bip21", "data" { "address" "bitcoin\ bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh?label=example%20store\&message=payment%20for%20services\&lightning=lnbc1500 qpz", "payment request" "lnbc1500n1p ", "amount" { "currency" "btc", "amount" 150000, "unit" "msats" }, "max fee" { "currency" "btc", "amount" 1000, "unit" "msats" }, "description" "payment for services" } }' request fields type – "bip21" for a unified bitcoin payment data address – the bip21 uri string (required) data payment request – optional lightning invoice if you have it separately data amount – optional btc amount object (can be omitted if uri contains amount) data max fee – optional max lightning fee in msats data description – optional memo (independent of any invoice memo) monitoring payment status after initiating a payment, monitor its status using get https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments/{payment id} example curl 'https //voltageapi com/v1/organizations/{organization id}/environments/{environment id}/payments/{payment id}' \\ \ header 'x api key your api key' payment states sending – payment is in progress completed – payment was successful and funds have been delivered failed – payment failed (check the error field for details) response fields for usd payments for completed usd payments, the response includes data market quote – the exchange rate used for usd/btc conversion data amount – the amount in usd that was debited from your wallet error handling http status codes 200 – success 400 – invalid request (missing fields, expired/invalid quote, etc ) 403 – authentication or permissions error 404 – resource not found 500 – server error common errors missing quote id – usd wallet payments require a valid quote id expired quote – quotes are time limited; obtain a new one invalid invoice – the lightning invoice is malformed or expired insufficient balance – your usd wallet doesn't have enough funds when a payment fails, the status will be "failed" and the error object will contain details about the failure reason