# Receiving (BTC Line of Credit)

# Receiving Payments with Bitcoin Line of Credit

This guide explains how to receive Lightning, on-chain Bitcoin, and BIP21 unified payments into a BTC-denominated wallet using the Voltage Payments API.

:::note
For Development testing, choose **Mutinynet Bitcoin**. This is the correct wallet for a Bitcoin line of credit as well as Node-backed Bitcoin testing. **Mutinynet USD** and **Voltage Cash** are not the correct wallets for this workflow.
:::

## Prerequisites

- A Voltage account with an active **BTC wallet** (wallet associated with a Bitcoin line of credit)
- An **Environment API key** (x-api-key) from your dashboard

:::note
**No quotes needed!** Unlike USD wallets, BTC wallets receive payments directly in BTC without currency conversion. You do not need to use the Quotes API.
:::

## Workflow Overview

Receiving a payment is a two-step process:

1. **Create** a receive payment request (invoice/address/URI)
2. **Retrieve** the payment to get the invoice details and monitor status

## Key Data Shapes

### Amount Object

```json
{
  "amount": 150000,
  "currency": "btc",
  "unit": "msats"
}
```

BTC amounts use millisatoshis (msats) as the smallest unit.

*Legacy fields* `amount_msats` *and* `amount_sats` *are still accepted but deprecated. Prefer the amount object.*

### Payment Kinds (receive)

- `bolt11` – Lightning invoice
- `onchain` – On-chain Bitcoin address
- `bip21` – Unified BIP21 URI (on-chain + optional Lightning)
- `taprootasset` – Taproot Asset invoice (not covered in this guide)

### Receive Statuses

- `generating` – Invoice/address is being created
- `receiving` – Invoice/address created and waiting for payment
- `completed` – Fully received and credited
- `expired` – Invoice expired before being paid
- `failed` – Could not be generated or completed

## Creating Receive Payments

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

### Receive a Fixed-Amount Lightning (BOLT11) Payment

```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": "{wallet_id}",
    "currency": "btc",
    "payment_kind": "bolt11",
    "amount": {
      "amount": 150000,
      "currency": "btc",
      "unit": "msats"
    },
    "description": "test payment",
    "expiration": 3600
  }'
```

### Required Fields

- `id` – Your unique idempotent ID (UUID recommended)
- `wallet_id` – Wallet that will receive funds
- `currency` – "btc" (must match the wallet's currency)
- `payment_kind` – "bolt11"
- `amount` – Amount object for the requested amount

### Optional Fields

- `description` – Memo/description (appears as `memo` in the response)
- `expiration` – Invoice expiry in seconds (default: 3600, max: 86400 for Lightning)

### Receive a Lightning Invoice with Any Amount

BTC wallets support "pay any amount" invoices. Simply omit the `amount` field:

```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": "b3e12e2f-5e80-4fb6-9c37-0a2d9af6c1f0",
    "wallet_id": "{wallet_id}",
    "currency": "btc",
    "payment_kind": "bolt11",
    "description": "donation (any amount)",
    "expiration": 3600
  }'
```

:::note
Any-amount invoices are only supported for BTC wallets, not USD wallets (which require a fixed quote).
:::

### Receive an On-Chain BTC Payment

Creates a new on-chain address and tracks the payment:

```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": "{wallet_id}",
    "currency": "btc",
    "payment_kind": "onchain",
    "amount": {
      "amount": 150000000,
      "currency": "btc",
      "unit": "msats"
    },
    "description": "on-chain deposit"
  }'
```

The response will include:

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

:::caution
For accounting simplicity, please **separate** Lightning and on-chain usage between different wallets if you are on a node-backed setup.
:::

### Receive a BIP21 Unified Payment (On-Chain + Lightning)

Creates a BIP21 URI that can embed both an on-chain address and a Lightning invoice:

```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": "{wallet_id}",
    "currency": "btc",
    "payment_kind": "bip21",
    "amount": {
      "amount": 150000,
      "currency": "btc",
      "unit": "msats"
    },
    "description": "Payment for services",
    "expiration": 3600
  }'
```

The resulting data will include:

- `payment_request` (optional BOLT11)
- `address` (BTC address)
- `receipts` for completed on-chain or Lightning parts

## Retrieve Payment Details

### 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": "btc",
  "type": "bolt11",
  "data": {
    "payment_request": "lntbs1500n1pn66qv...",
    "amount": {
      "amount": 150000,
      "currency": "btc",
      "unit": "msats"
    },
    "amount_msats": 150000,
    "memo": "test payment",
    "expiration": 3600,
    "market_quote": null
  },
  "requested_amount": {
    "amount": 150000,
    "currency": "btc",
    "unit": "msats"
  },
  "status": "receiving",
  "error": null,
  "frozen": [],
  "exchanges": []
}
```

### Key Response Fields

- `direction` – Always "receive" for incoming payments
- `type` – bolt11 | onchain | bip21 | taprootasset
- `data.payment_request` / `data.address` / `data.receipts` depending on type
- `requested_amount` – What you originally requested
- `status` – Current receive state
- `error` – Structured error info if something failed
- `frozen` – Parts of the payment frozen for compliance (e.g., OFAC)

## Listing Incoming Payments

### 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), helpful for debugging or audits.

## Monitoring Receive Status

Typical state transitions:

1. `generating` → Payment being set up (invoice/address generation)
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 (see `error` field for details)

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:

- `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](#) 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

- `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 (invoice/address generation started)
- **200** – Successful retrieval/list/history
- **400** – Invalid request (bad IDs, missing fields, etc.)
- **403** – Authentication/authorization error
- **404** – Payment not found in this organization + environment
- **500** – Server error

### Receive Errors

Within the payment object, the `error` field may contain:

- `receive_failed`
- `expired`
- `rejected`
