# Receiving

# Receiving Payments

This guide explains how to receive **Lightning**, **on-chain Bitcoin**,
and **BIP21 unified** payments using the Voltage Payments API.

## Related Guides

For detailed guides specific to your wallet type:

- [Receiving (USD Line of Credit)](/receiving-usd-line-of-credit) – For USD wallets (requires quotes)
- [Receiving (BTC Line of Credit)](/receiving-btc-line-of-credit) – For BTC wallets (no quotes needed)

## Dashboard cross-check

For the BTC workflow on this page, choose **Mutinynet Bitcoin**. If you are testing the USD line-of-credit workflow, use **Mutinynet USD** and follow [Receiving (USD Line of Credit)](/receiving-usd-line-of-credit). **Voltage Cash** is the experimental stablecoin test wallet and is not used for either BTC or USD line-of-credit testing.

In the selected Development wallet, select **Receive**, enter a test amount and optional memo, and select **Create Payment Request**. Use the generated request only in an appropriate test workflow.

A generated or pending request is not proof of payment. Confirm the incoming terminal state in **All Payments**, then reconcile that state through the Payments API or webhooks for automated workflows.

![Receive form filled with a test amount and memo](/images/13-receive-form-filled.png)

*Create a payment request only within an appropriate test workflow.*

![Incoming test payment in the receiving wallet history](/images/34-receiving-wallet-payment-history.png)

*Confirm the incoming terminal state in the receiving wallet and through the API or webhooks.*

## Prerequisites

- A Voltage account with at least one **wallet** in the target environment
- An **environment API key** (x-api-key) from your dashboard
- For **USD wallets** (receiving BTC → USD), a **Line of Credit** and
  access to the **Quotes** API

## High‑Level Flow

Receiving a payment is still 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

All of this happens via the **Payments** endpoints:

- POST
  `/organizations/{organization_id}/environments/{environment_id}/payments`
  – create send *or* receive payments
- GET
  `/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}`
  – get a single payment
- GET
  `/organizations/{organization_id}/environments/{environment_id}/payments`
  – list payments (filter for direction=receive)
- GET
  `/organizations/{organization_id}/environments/{environment_id}/payments/{payment_id}/history`
  – timeline of status changes

## Key Data Shapes

### Amount

Supported patterns:

- **BTC**: smallest unit is millisatoshis
- **USD**: smallest unit is cents
- **Assets**: smallest unit is base units

*Legacy fields amount\_msats and amount\_sats are still accepted*
*but **deprecated**. Prefer the amount object.*

### Payment kinds (receive)

When creating a **receive** payment, you set:

- `bolt11` – Lightning invoice
- `onchain` – On-chain Bitcoin address
- `bip21` – Unified BIP21 URI (on-chain + optional LN)
- `taprootasset` – Taproot Asset invoice

### Receive statuses

For incoming payments, the status field uses:

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

## Step 1 – Create a Receive Payment

### Endpoint

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

The same endpoint creates send and receive payments. A successful request returns `202 Accepted` with an empty body; poll the payment by the `id` you submitted.

### Headers

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

### 1.1 Receive a fixed‑amount Lightning (BOLT11) payment – BTC wallet

Use the **“Receive Payment with Specific Amount”** shape:

```json
{
  "id": "9c3f1a80-4d7e-4a52-9f21-8a6b0c5d3e14",
  "wallet_id": "7a68a525-9d11-4c1e-a3dd-1c2bf1378ba2",
  "payment_kind": "bolt11",
  "amount": {
    "currency": "btc",
    "amount": 150000,
    "unit": "msats"
  },
  "description": "Order 123",
  "expiration": 3600
}
```

For USD wallets, also include a `quote_id`.

### Required Fields

*Note: The* `description` *field in your request appears as* `memo` *in the response.*

**Required fields (fixed‑amount receive):**

- `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" | "onchain" | "bip21" | "taprootasset"
- `amount` – Amount object for the requested amount

Optional:

- `description` – memo / description
- `expiration` – invoice expiry in seconds (defaults to 3600; max 86400
  for LN / BIP21)

### 1.2 Receive a Lightning invoice with *any* amount (BTC wallet only)

For “pay any amount” invoices, use the **“Receive Payment with Any**
**Amount”** shape:

```json
{
  "id": "b7d2e4f1-3c8a-4b96-8e05-1f2a7c9d4b63",
  "wallet_id": "7a68a525-9d11-4c1e-a3dd-1c2bf1378ba2",
  "currency": "btc",
  "payment_kind": "bolt11",
  "description": "Pay what you want",
  "expiration": 3600
}
```

**Notes**

- currency must be "btc"
- payment\_kind can be "bolt11" or "bip21"
- No amount is included; the payer chooses the amount

### 1.3 Receive an on‑chain BTC payment

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

```json
{
  "id": "4e8c1d35-9a7b-42f0-b6d8-3c5e1a9f7204",
  "wallet_id": "7a68a525-9d11-4c1e-a3dd-1c2bf1378ba2",
  "payment_kind": "onchain",
  "amount": {
    "currency": "btc",
    "amount": 150000000,
    "unit": "msats"
  },
  "description": "Invoice 4821"
}
```

The response will include:

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

### 1.4 Receive a BIP21 unified payment (on‑chain + LN)

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

```json
{
  "id": "6a1b9c47-2e5d-4f83-9107-8b4c2d6e5a39",
  "wallet_id": "7a68a525-9d11-4c1e-a3dd-1c2bf1378ba2",
  "payment_kind": "bip21",
  "amount": {
    "currency": "btc",
    "amount": 150000000,
    "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 LN parts

## Step 2: Retrieve Payment Details

### Endpoint

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

### Headers

```text
x-api-key: your-api-key
```

### Example response – BTC Lightning receive

```json
{
  "bip21_uri": "lightning:lntbs1500n1pn5w25ypp59sfhx5llskdp6rmsmmq3zs86xey6l4y9wkzvkjl5v2cw0ex7xd4sdqqcqzzsxqyz5vqsp5u333jtc7lh0qvkusq5ntcpm3n2jjx6tw8jz7zvpqpnt3v8e572eq9qxpqysgq4hm7n79tnk76j4ll4f7ey9mmxdyj5pwzcmyqgxtgz40vjg9w58wq73040qvuurj83jakt2zws6y9qgzg2f6gtnj3ajf0mj4gw4mdt2cqhr2tpz",
  "created_at": "2025-02-12T21:21:21.744713Z",
  "currency": "btc",
  "data": {
    "amount": {
      "amount": 150000,
      "currency": "btc",
      "unit": "msats"
    },
    "amount_msats": 150000,
    "expiration": 3600,
    "market_quote": null,
    "memo": "Order 123",
    "payment_request": "lntbs1500n1pn5w25ypp59sfhx5llskdp6rmsmmq3zs86xey6l4y9wkzvkjl5v2cw0ex7xd4sdqqcqzzsxqyz5vqsp5u333jtc7lh0qvkusq5ntcpm3n2jjx6tw8jz7zvpqpnt3v8e572eq9qxpqysgq4hm7n79tnk76j4ll4f7ey9mmxdyj5pwzcmyqgxtgz40vjg9w58wq73040qvuurj83jakt2zws6y9qgzg2f6gtnj3ajf0mj4gw4mdt2cqhr2tpz",
    "receipts": [
      {
        "data": {
          "ledger_id": "03d87c6d-2cf8-414b-929a-eceeb4c896ed",
          "payment_hash": "2222222222222222222222222222222222222222222222222222222222222222",
          "preimage": "1111111111111111111111111111111111111111111111111111111111111111"
        },
        "type": "lightning"
      }
    ]
  },
  "direction": "receive",
  "environment_id": "123e4567-e89b-12d3-a456-426614174000",
  "error": null,
  "exchanges": [],
  "frozen": [],
  "id": "11ca843c-bdaa-44b6-965a-39ac550fcef7",
  "organization_id": "b0684ab8-1130-46af-8f70-71519442f108",
  "requested_amount": {
    "amount": 150000,
    "currency": "btc",
    "unit": "msats"
  },
  "status": "completed",
  "type": "bolt11",
  "updated_at": "2025-02-12T21:23:03.173159Z",
  "wallet_id": "7a68a525-9d11-4c1e-a3dd-1c2bf1378ba2"
}
```

Key fields for receives:

- `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 (generating, receiving, expired,
  failed, completed)
- `error` – structured error info if something failed
- `frozen` – parts of the payment frozen for compliance (e.g., OFAC)
- `exchanges` – currency exchange details when quotes/markets are involved

## Listing Incoming Payments

You can list and filter payments, including only receive‑direction ones.

### Endpoint

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

### Useful query params

- `direction=receive` – only incoming payments
- `wallet_id={wallet_id}` – specific wallet
- `statuses[]=receiving&statuses[]=completed` – filter by status
- Pagination: `offset`, `limit`

### Example

```bash
curl 'https://voltageapi.com/v1/organizations/{organization_id}/environments/{environment_id}/payments?direction=receive&limit=25' \
  --header 'x-api-key: your-api-key'
```

## Viewing Payment History

To see the lifecycle of a receive payment:

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

Example response contains ordered events with timestamps and errors (if
any), which is helpful for debugging or audits.

## Monitoring Receive Status

Typical state transitions for incoming payments:

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`)
- And/or by using **webhooks** (recommended)

## Webhooks for Receive Events (Recommended)

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

`NewWebhookRequest` includes:

- `id` – a client-generated UUID for the webhook registration; the create response returns this same value
- `url` – your HTTPS endpoint
- `name` – webhook name
- `events` – an array of event type objects; each object contains exactly one event:

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

**You can test webhooks with:**

```text
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` – receive event type (`generated`, `refreshed`,
  `expired`, `succeeded`, `completed`, `failed`)

## Processing Fees

Your organization can charge an optional percentage **processing fee** on payments. Processing fees are off by default and are configured per wallet. See [Processing Fees](/processing-fees) for how to view and set your rates.

On a receive, the processing fee is **included in the payer-facing amount** on the generated invoice, address, or BIP21 URI. The payer funds it, and it sits **outside** the amount credited to your wallet.

When a rate is configured, receive payment responses include a `processing_fee` object and a `payment_breakdown`:

```json
{
  "processing_fee": {
    "basis_points": 250,
    "amount": { "currency": "btc", "amount": 3750, "unit": "msats" }
  },
  "payment_breakdown": {
    "principal":      { "currency": "btc", "amount": 150000, "unit": "msats" },
    "network_fee":    { "currency": "btc", "amount": 0,      "unit": "msats" },
    "processing_fee": { "currency": "btc", "amount": 3750,   "unit": "msats" }
  }
}
```

- `processing_fee.basis_points` – the configured rate applied to this payment. `100` is 1%, `250` is 2.5%.
- `processing_fee.amount` – the fee calculated for this payment, in the principal's assessment currency. It is available before settlement and stays stable across partial or excess payments.
- `data.fees` – the processing fee assessed for this receive, when configured.
- `payment_breakdown.processing_fee` – the authoritative settled fee. Use this for reconciliation.

Both fields are omitted when no processing fee applies, so this does not affect integrations that have no rate configured.

## Error Handling

Common HTTP responses from Payments endpoints:

- `202` – receive payment creation accepted (invoice/address generation
  started)
- `200` – successful retrieval / list / history
- `400` – invalid request (bad IDs, missing fields, invalid quote for USD,
  etc.)
- `403` – authentication/authorization error
- `404` – payment not found in this organization + environment
- `500` – server error

Within the payment object:

- **Receive errors** (in error) include:
  - `receive_failed`
  - `expired`
  - `rejected`
- For USD conversions, `data.market_quote` + `exchanges` help you
  understand which rate was used.
