Skip to content

Developer Guide

Receiving (USD Line of Credit)

Receiving Payments with USD Line of Credit

Section titled “Receiving Payments with USD Line of Credit”

This guide explains how to receive Bitcoin (BTC) payments into a USD-denominated wallet using the Voltage Payments API. With a USD wallet (backed by a line of credit), incoming BTC is automatically converted to USD. You present Lightning invoices or on-chain addresses for payment in BTC, while your wallet balance is credited in USD.

  • A Voltage account with an active USD wallet (credit-backed wallet with an associated USD line of credit)
  • An Environment API key with access to the wallet’s environment
  • Line of credit enabled with access to the Quotes API
  • The UUIDs for your organization, environment, wallet, and line_of_credit_id

Receiving funds into a USD wallet is a multi-step process:

  1. Get a quote – Use POST /quotes to lock in the BTC→USD conversion rate for the amount you expect to receive
  2. Create a receive payment request – Use POST /payments to generate a Lightning invoice, on-chain address, or BIP21 URI, including the quote_id
  3. Retrieve payment details – Fetch the payment to get the actual invoice/address to present to the payer
  4. Monitor status – Wait for the payment to be received and credited
{
"amount": 1000,
"currency": "usd",
"unit": "cents"
}
  • USD: smallest unit is cents (1000 cents = $10.00)
  • BTC: smallest unit is millisatoshis (150000 msats = 1500 sats)
  • generating – Invoice/address is being created
  • receiving – Invoice/address generated and waiting for payment
  • completed – Fully received and credited
  • expired – Invoice expired before being paid
  • failed – Could not be generated or completed

Step 1: Get a Quote for BTC→USD Conversion

Section titled “Step 1: Get a Quote for BTC→USD Conversion”

Before creating the receive payment, obtain a quote to lock in the conversion rate.

POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/quotes
x-api-key: your-api-key
Content-Type: application/json
Terminal window
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": 100000,
"currency": "btc",
"unit": "msats"
},
"to": "usd"
}'
  • id – A client-generated UUID for the quote
  • line_of_credit_id – Your USD line of credit ID
  • network – The Bitcoin network
  • amount – The BTC amount you expect to receive (in msats)
  • to – Target currency for conversion (“usd”)

Save the quote_id from the response for Step 2.

With a quote ready, create the receive payment request.

POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments
x-api-key: your-api-key
Content-Type: application/json

Create a Lightning invoice that, when paid in BTC, credits your USD wallet.

Terminal window
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": "11ca843c-bdaa-44b6-965a-39ac550fcef7",
"wallet_id": "{usd_wallet_id}",
"currency": "usd",
"payment_kind": "bolt11",
"quote_id": "87654321-4321-8765-cba9-fed987654321",
"amount": {
"amount": 1000,
"currency": "usd",
"unit": "cents"
},
"description": "Receive BTC, convert to $10.00",
"expiration": 3600
}'
  • id – A client-generated UUID for the payment
  • wallet_id – Your USD wallet ID
  • currency – “usd” (must match the wallet’s currency)
  • payment_kind – “bolt11” to create a Lightning invoice
  • quote_id – The quote ID from Step 1 (required for USD wallets)
  • amount – The USD amount you wish to receive (e.g., 1000 cents = $10.00)
  • description – Optional memo to attach to the invoice (appears as memo in the response)
  • expiration – Optional expiration in seconds (default: 3600, max: 86400)

The API will calculate the corresponding BTC amount using the quote’s rate and generate a Lightning invoice for that BTC amount.

Generate a Bitcoin address tied to your USD wallet.

Terminal window
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": "11ca843c-bdaa-44b6-965a-39ac550fcef8",
"wallet_id": "{usd_wallet_id}",
"payment_kind": "onchain",
"quote_id": "87654321-4321-8765-cba9-fed987654321",
"amount": {
"amount": 1000,
"currency": "usd",
"unit": "cents"
},
"currency": "usd",
"description": "Receive BTC on-chain, convert to $10.00"
}'
  • payment_kind – “onchain” to generate an on-chain BTC address
  • quote_id – The quote ID (required for USD wallets)
  • amount – The USD amount you aim to receive
  • currency – “usd”
  • description – Optional description for your records

The response will include:

  • A Bitcoin address in data.address
  • data.receipts entries as the transaction confirms

Create a BIP21 URI that includes both a Lightning invoice and an on-chain address, giving the payer flexibility.

Terminal window
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": "11ca843c-bdaa-44b6-965a-39ac550fcef9",
"wallet_id": "{usd_wallet_id}",
"payment_kind": "bip21",
"quote_id": "87654321-4321-8765-cba9-fed987654321",
"amount": {
"amount": 1000,
"currency": "usd",
"unit": "cents"
},
"currency": "usd",
"description": "Receive BTC via BIP21, convert to $10.00",
"expiration": 3600
}'
  • payment_kind – “bip21” for a unified payment request
  • quote_id – The quote ID (required)
  • amount – USD amount to receive
  • expiration – Optional expiration for the Lightning invoice portion (the on-chain address doesn’t expire, but the quote’s rate may not hold if significantly delayed)
  • description – Optional note

The generated data.address will be a BIP21 URI the payer can scan. Whether they pay via Lightning or on-chain, your wallet will be credited in USD at the locked rate.

After creating a receive payment, fetch it to get the actual invoice or address.

GET https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}
Terminal window
curl 'https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}' \
--header 'x-api-key: your-api-key'
{
"direction": "receive",
"id": "11ca843c-bdaa-44b6-965a-39ac550fcef7",
"wallet_id": "{wallet_id}",
"organization_id": "{organization_id}",
"environment_id": "{environment_id}",
"created_at": "2025-02-12T20:16:14.095785Z",
"updated_at": "2025-02-12T20:16:14.807961Z",
"currency": "usd",
"type": "bolt11",
"data": {
"payment_request": "lntbs1500n1pn66qv...",
"amount": {
"amount": 1000,
"currency": "usd",
"unit": "cents"
},
"memo": "Receive BTC, convert to $10.00",
"expiration": 3600,
"market_quote": {
"from": "btc",
"to": "usd",
"rate": "25000.00",
"quoted_at": "2025-02-12T20:16:14Z"
}
},
"requested_amount": {
"amount": 1000,
"currency": "usd",
"unit": "cents"
},
"status": "receiving",
"error": null,
"frozen": [],
"exchanges": []
}
  • direction – “receive” for incoming payments
  • type – bolt11 | onchain | bip21
  • data.payment_request – The Lightning invoice string (for bolt11/bip21)
  • data.address – The Bitcoin address (for onchain/bip21)
  • data.market_quote – The exchange rate used for conversion
  • requested_amount – The USD amount you originally requested
  • status – Current receive state
  • error – Structured error info if something failed
  • frozen – Parts of the payment frozen for compliance
  • exchanges – Currency exchange details

List and filter payments, including only receive-direction ones.

GET https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments
  • direction=receive – Only incoming payments
  • wallet_id={wallet_id} – Specific wallet
  • statuses[]=receiving&statuses[]=completed – Filter by status
  • offset, limit – Pagination
Terminal window
curl 'https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments?direction=receive&wallet_id={wallet_id}&limit=50' \
--header 'x-api-key: your-api-key'

See the lifecycle of a receive payment:

GET https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}/history

The response contains ordered events with timestamps and errors (if any), useful for debugging and audits.

Typical state transitions:

  1. generating → Payment being set up
  2. receiving → Invoice/address generated, waiting for funds
  3. completed → Funds received and credited
  4. expired → Invoice expired before payment
  5. failed → An error occurred

You can monitor by:

  • Polling GET /payments/{payment_id} until status is terminal (completed, expired, or failed)
  • Webhooks (recommended)

Create a webhook to get real-time notifications when receive payments are generated, completed, expired, etc.

POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/webhooks

Include in the request:

  • id – A client-generated UUID for the webhook registration; the create response returns this same value
  • url – Your HTTPS endpoint
  • name – Webhook name
  • events – Array of event types, e.g.:
[
{ "receive": "generated" },
{ "receive": "completed" },
{ "receive": "expired" },
{ "receive": "failed" }
]

The create response also returns a one-time shared_secret. Store it for signature verification; it is not included in callbacks. In a receive callback, detail.data.id is the payment ID supplied when the payment was created, not the webhook ID or organization ID. See Webhooks for the complete payload and identifier map.

POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/webhooks/{webhook_id}/test

Receive webhook payloads include:

  • type – “receive”
  • detail.data – Full Payment object
  • detail.event – Event type (generated, refreshed, expired, succeeded, completed, failed)
  • 202 – Receive payment creation accepted
  • 200 – Successful retrieval/list/history
  • 400 – Invalid request (bad IDs, missing fields, invalid quote, etc.)
  • 403 – Authentication/authorization error
  • 404 – Payment not found
  • 500 – Server error

Within the payment object, the error field may contain:

  • receive_failed
  • expired
  • rejected

For USD conversions, data.market_quote and exchanges help you understand which rate was used.