---
updatedAt: 2026-02-28T11:24:59.000Z
agentTools:
  projectIndex: https://neutronpay.readme.io/llms.txt
---

# Receive Bitcoin On-Chain

Receive Bitcoin via an on-chain transaction into your Neutron wallet. You can either use your **static deposit address** or create a **transaction-specific address** for tracking individual payments.

## Overview

```
Sender's Wallet  ──BTC on-chain──►  Neutron  ──►  Your Neutron Wallet
```

**Use case:** Accepting Bitcoin payments from external wallets, exchanges, or any source that doesn't support Lightning.

> 📘 **Prefer Lightning?** On-chain transactions require blockchain confirmations (10-60 min). For instant settlement, use [Lightning receive](/reference/receive-bitcoin-with-lightning-invoice) instead.

## Option 1: Static Deposit Address

Every Neutron account has a **static Bitcoin address** — a permanent, reusable address that deposits directly into your wallet. No transaction creation needed.

### Get Your Address

```bash
curl -X GET https://api.neutron.me/api/v2/account/onchain-address \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

### Response

```json
{
  "staticOnchainAddress": "3M5A4DZX8zcybTrH3ebR9ys2jYJZ8BzBBz"
}
```

Share this address with anyone who wants to send you Bitcoin. Funds are automatically credited to your wallet after blockchain confirmations.

> 📘 This address is **permanent and reusable**. You don't need to generate a new one for each payment.

**Best for:** Simple deposits, wallet-to-wallet transfers, receiving from exchanges.

## Option 2: Transaction-Specific Address

For tracking individual payments (e.g., e-commerce orders), create a transaction that generates a unique address tied to a specific amount.

### Step 1: Create Transaction

```bash
curl -X POST https://api.neutron.me/api/v2/transaction \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "sourceReq": {
      "ccy": "BTC",
      "method": "on-chain",
      "reqDetails": {}
    },
    "destReq": {
      "ccy": "BTC",
      "method": "neutronpay",
      "amtRequested": 0.001,
      "reqDetails": {}
    },
    "extRefId": "order-1234"
  }'
```

#### Request Fields

| Field                  | Type   | Required | Description                                                   |
| ---------------------- | ------ | -------- | ------------------------------------------------------------- |
| `sourceReq.ccy`        | string | ✅        | `"BTC"`                                                       |
| `sourceReq.method`     | string | ✅        | `"on-chain"`                                                  |
| `sourceReq.reqDetails` | object | ✅        | Empty object `{}`                                             |
| `destReq.ccy`          | string | ✅        | `"BTC"`                                                       |
| `destReq.method`       | string | ✅        | `"neutronpay"` (into your wallet)                             |
| `destReq.amtRequested` | number | ✅        | Amount in **BTC** (e.g., `0.001` = 100,000 sats)              |
| `destReq.reqDetails`   | object | ✅        | Empty object `{}`                                             |
| `extRefId`             | string | ❌        | Your reference ID (e.g., order number) — returned in webhooks |

> ⚠️ **Amounts are in BTC**, not satoshis. `0.00000100` = 100 sats.

> ⚠️ Set the amount on **one side only** (source OR dest), not both.

#### Response

```json
{
  "txnId": "7c5d9b60-e47f-41ef-859b-d77b2aa43f74",
  "accountId": "ne01-abc123def456",
  "txnState": "quoted",
  "sourceReq": {
    "ccy": "BTC",
    "method": "on-chain",
    "amtRequested": 0.001,
    "reqStatus": "0",
    "reqDetails": {
      "address": null,
      "invoicePageUrl": null
    }
  },
  "destReq": {
    "ccy": "BTC",
    "method": "neutronpay",
    "amtRequested": 0.001,
    "reqStatus": "0"
  },
  "fxRate": 1,
  "createdAt": 1770342000000
}
```

> 📘 The Bitcoin address is **not generated yet** at this stage — `address` is `null`. You must confirm the transaction first.

### Step 2: Confirm Transaction

Confirm to generate the payment address:

```bash
curl -X PUT https://api.neutron.me/api/v2/transaction/7c5d9b60-e47f-41ef-859b-d77b2aa43f74/confirm \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

> ⚠️ The `Content-Type: application/json` header is **required** on PUT requests, even with no request body.

#### Response

```json
{
  "txnId": "7c5d9b60-e47f-41ef-859b-d77b2aa43f74",
  "accountId": "ne01-abc123def456",
  "txnState": "srcintent",
  "sourceReq": {
    "ccy": "BTC",
    "method": "on-chain",
    "amtRequested": 0.001,
    "reqStatus": "0",
    "reqDetails": {
      "address": "3LPV8RBJT7NcSgb4y38ofzPHKQ68WGKbPM",
      "amount": 0.001,
      "invoice": "bitcoin:3LPV8RBJT7NcSgb4y38ofzPHKQ68WGKbPM?amount=0.00100000&message=",
      "invoicePageUrl": "https://endash.npay.live/payment-invoice/7c5d9b60-...?token=...",
      "expiredAt": "2026-02-12T06:54:45.931Z"
    }
  },
  "destReq": {
    "ccy": "BTC",
    "method": "neutronpay",
    "amtRequested": 0.001,
    "reqStatus": "0"
  },
  "fxRate": 1,
  "createdAt": 1770342000000
}
```

After confirmation, the response includes:

| Field                       | Description                                                              |
| --------------------------- | ------------------------------------------------------------------------ |
| `reqDetails.address`        | Bitcoin address for the sender to pay                                    |
| `reqDetails.amount`         | Expected amount in BTC                                                   |
| `reqDetails.invoice`        | BIP21 URI — opens the sender's wallet with address and amount pre-filled |
| `reqDetails.invoicePageUrl` | Hosted payment page with QR code                                         |
| `reqDetails.expiredAt`      | Expiration time — the sender must pay before this                        |

### Step 3: Share with Sender

Share one of these with the sender:

* **Bitcoin address** — sender enters the address and amount manually
* **BIP21 URI** (`bitcoin:3LPV...?amount=0.001`) — opens their wallet app with details pre-filled
* **Invoice page URL** — a hosted page with a QR code for easy scanning

## Integration Example

```
Customer selects "Pay with Bitcoin"
        │
        ▼
Your server: POST /api/v2/transaction  (create)
        │
        ▼
Your server: PUT /api/v2/transaction/{txnId}/confirm
        │
        ▼
Display BIP21 QR code or link to invoicePageUrl
        │
        ▼
Customer sends BTC from their wallet
        │
        ▼
Neutron detects on-chain payment + confirmations
        │
        ▼
Webhook → Your server marks order as paid
```

### Polling vs Webhooks

| Method                                        | Best for                                          |
| --------------------------------------------- | ------------------------------------------------- |
| **Webhooks** (recommended)                    | Production apps — notified when payment confirms  |
| **Polling** `GET /api/v2/transaction/{txnId}` | Prototypes — check periodically until `completed` |

See [Webhook Guide](/reference/purpose) for setup instructions.

## SDK Examples

### TypeScript (neutron-sdk)

```typescript
import { Neutron } from "neutron-sdk";

const neutron = new Neutron({
  apiKey: process.env.NEUTRON_API_KEY,
  apiSecret: process.env.NEUTRON_API_SECRET,
});

// Get your static deposit address
const { address } = await neutron.account.btcAddress();
console.log("Deposit to:", address);

// Or create a transaction-specific address
const txn = await neutron.transactions.create({
  sourceReq: { ccy: "BTC", method: "on-chain", reqDetails: {} },
  destReq: { ccy: "BTC", method: "neutronpay", amtRequested: 0.001, reqDetails: {} },
  extRefId: "order-1234",
});
const confirmed = await neutron.transactions.confirm(txn.txnId);
console.log("Pay to:", confirmed.sourceReq.reqDetails.address);
```

### Python (neutron-python)

```python
from neutron import Neutron

client = Neutron(api_key="...", api_secret="...")

# Get your static deposit address
addr = client.account.btc_address()
print("Deposit to:", addr["address"])

# Or create a transaction-specific address
txn = client.transactions.create({
    "sourceReq": {"ccy": "BTC", "method": "on-chain", "reqDetails": {}},
    "destReq": {"ccy": "BTC", "method": "neutronpay", "amtRequested": 0.001, "reqDetails": {}},
    "extRefId": "order-1234",
})
confirmed = client.transactions.confirm(txn["txnId"])
print("Pay to:", confirmed["sourceReq"]["reqDetails"]["address"])
```

## Transaction States

| State        | Meaning                                                      |
| ------------ | ------------------------------------------------------------ |
| `quoted`     | Transaction created — address not yet generated              |
| `srcintent`  | Confirmed — Bitcoin address generated, waiting for payment ⏳ |
| `srccreated` | On-chain payment detected (awaiting confirmations)           |
| `completed`  | Payment confirmed on-chain — funds in your wallet ✅          |
| `expired`    | Address expired before payment                               |
| `failed`     | Transaction failed                                           |

On-chain transactions typically require 1-6 blockchain confirmations (10-60 minutes).

See [Transaction Status Types](/reference/transaction-status-types) for the complete state reference.

## Fees

Receiving on-chain Bitcoin has minimal or zero fees:

| Fee             | Description                           |
| --------------- | ------------------------------------- |
| **Neutron fee** | Service fee (often zero for receives) |
| **Network fee** | None — the sender pays the mining fee |

## Notes

* **No KYC required** for Bitcoin on-chain transactions. KYC is only needed for [fiat payouts](/reference/fiat-out).
* The transaction-specific address has an **expiration time** — share it with the sender promptly.
* The static address has **no expiration** — it's always valid.
* Use `extRefId` to attach your own order/reference ID for easy matching in webhooks.
* Amounts are always in **BTC**, not satoshis (100 sats = `0.00000100`).

## Related

* [Send Bitcoin On-Chain](/reference/neutronpay-to-btc) — Send BTC from your wallet
* [Transaction Status Types](/reference/transaction-status-types) — Complete state reference
* [Webhook Guide](/reference/purpose) — Real-time payment notifications