# Receiving (USD Line of Credit)

# 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.

:::note
For Development testing, choose **Mutinynet USD**. Payments arrive over Bitcoin or Lightning while the wallet and line of credit are denominated in USD. **Mutinynet Bitcoin** and **Voltage Cash** are not the correct wallets for this workflow.
:::

## Prerequisites

- 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`

## Workflow Overview

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

:::note
USD wallets do not support "any-amount" invoices because a specific quote (fixed amount) is required.
:::

## Key Data Shapes

### Amount Object

```json
{
  "amount": 1000,
  "currency": "usd",
  "unit": "cents"
}
```

- **USD**: smallest unit is cents (1000 cents = $10.00)
- **BTC**: smallest unit is millisatoshis (150000 msats = 1500 sats)

### Receive Statuses

- `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

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

### Endpoint

```text
POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/quotes
```

### Headers

```text
x-api-key: your-api-key
Content-Type: application/json
```

### Example Request

```bash
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"
  }'
```

### Request Fields

- `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.

:::caution
Quotes are short-lived (typically 2 minutes) to account for BTC price volatility. Use a fresh quote when creating the payment.
:::

## Step 2: Create a Receive Payment

With a quote ready, create the receive payment request.

### Endpoint

```text
POST https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments
```

### Headers

```text
x-api-key: your-api-key
Content-Type: application/json
```

### 2.1 Receive a Lightning (Bolt11) Payment

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

```bash
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
  }'
```

### Request Fields

- `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.

### 2.2 Receive an On-Chain Bitcoin Payment

Generate a Bitcoin address tied to your USD wallet.

```bash
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"
  }'
```

### Request Fields

- `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

:::note
Generate a new receive payment (with a new quote) for each separate on-chain payment you expect. The quote locks the rate for that specific amount and timeframe.
:::

:::caution
If an on-chain payment arrives after the quote expires, the payment may fail or be rejected. Always ensure the payer sends funds promptly within the quote validity window (typically 2 minutes).
:::

### 2.3 Receive a Unified BIP21 Payment

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

```bash
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
  }'
```

### Request Fields

- `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.

## Step 3: Retrieve Payment Details

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

### Endpoint

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

### Example

```bash
curl 'https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}' \
  --header 'x-api-key: your-api-key'
```

### Example Response

```json
{
  "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": []
}
```

### Key Response Fields

- `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

## Listing Incoming Payments

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

### Endpoint

```text
GET https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments
```

### Query Parameters

- `direction=receive` – Only incoming payments
- `wallet_id={wallet_id}` – Specific wallet
- `statuses[]=receiving&statuses[]=completed` – Filter by status
- `offset`, `limit` – Pagination

### Example

```bash
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'
```

## Viewing Payment History

See the lifecycle of a receive payment:

```text
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.

## Monitoring Receive Status

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)

## Webhooks for Receive Events

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

### Create a Webhook

```text
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.:

```json
[
  { "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](/webhooks) for the complete payload and identifier map.

### Test a Webhook

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

### Webhook Payload

Receive webhook payloads include:

- `type` – "receive"
- `detail.data` – Full Payment object
- `detail.event` – Event type (`generated`, `refreshed`, `expired`, `succeeded`, `completed`, `failed`)

## Error Handling

### HTTP Status Codes

- **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

### Receive Errors

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.
