> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Pay Links

> Shareable payment links that deliver stablecoins via Lightning.

Pay Links are durable URLs that deliver a stablecoin payment via Lightning. Pick the denomination at link creation:

* `amountOut` pins the receiver's amount. The sender pays it plus fees on top. Cash App displays the sats required to cover output and fees. Stablecoin `amountOut` values must be whole-cent values.
* `amountFiatUsd` pins the sender's USD amount. Cash App displays exactly that figure, the receiver gets the net after fees, and the BTC/USD spot is locked at click time.

Each click generates a fresh Lightning invoice and redirects to a Lightning-compatible payment app. The link itself never expires.

```text theme={null}
https://orchestration.flashnet.xyz/pay/DNHKySOZ
```

<Info>
  Pay Links share the pipeline with the [fiat onramp](/products/orchestration/onramp). Onramp orders are created per request; Pay Links pre-encode destination, recipient, and denomination once and create an order on every click.
</Info>

<Warning>
  Pay Links are not available to residents of New York City.
</Warning>

## Which mode should I use?

|                  | `amountOut`                                 | `amountFiatUsd`                                                           |
| ---------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| Pin point        | Receiver's stablecoin amount                | Sender's USD amount                                                       |
| Cash App display | Sats equivalent to output + fees            | Exact USD figure on the link                                              |
| Fee position     | Added on top of sender's payment            | Deducted from receiver's output                                           |
| Spot drift       | Reprices each click                         | Reprices each click                                                       |
| Best for         | Invoices, donations of a fixed token amount | "Send me \$X" flows where the displayed dollar amount must match the link |

`amountFiatUsd` is the right pick when the user expects Cash App to show the exact figure on the link. `amountOut` is the right pick when the receiver must end up with an exact stablecoin amount regardless of fees. For 6-decimal stablecoins, use multiples of `10000`, for example `"50000000"` for \$50.00.

## How it works

1. Partner calls `POST /v1/pay-links` with a destination chain, asset, recipient address, and exactly one of `amountOut` or `amountFiatUsd`.
2. Orchestra returns a `shortId` and `shortUrl`.
3. Each click creates a fresh order. For `amountOut`, Orchestra reverse-prices the BTC input to deliver the requested output. For `amountFiatUsd`, Orchestra fetches BTC/USD spot, converts the USD figure to sats, and runs in `exact_in` mode.
4. After payment, Orchestra swaps BTC to the destination asset and delivers it.

If the link is shared in a group chat and three people click it, three independent orders are created. Spot is fetched per click, so each order reflects the rate at the moment of payment.

## What can I build with pay links?

* **Payment requests**: "Pay me \$50 USDC" as a link. Share via text, email, QR code, or embed in a website.
* **Invoicing**: Generate a link per invoice line item. The recipient pays the exact amount without manual entry.
* **Donations and tips**: A fixed-amount link on a profile or stream overlay.
* **Recurring collection**: Reuse the same link for repeated payments to the same address.

## Which destinations are supported?

Pay Links support any stablecoin destination that Orchestra supports from a Lightning BTC source:

| Chain    | Assets        |
| -------- | ------------- |
| Spark    | USDB          |
| Solana   | USDC          |
| Base     | USDC, USDT    |
| Ethereum | USDC, USDT    |
| Arbitrum | USDC, USDT    |
| Optimism | USDC, USDT    |
| Polygon  | USDC          |
| Tempo    | USDC, PathUSD |
| Tron     | USDT          |
| Plasma   | USDT          |
| Monad    | USDC          |

## Integration

<Steps>
  <Step title="Create a pay link">
    Receiver-pinned (`amountOut`):

    ```ts theme={null}
    const BASE_URL = 'https://orchestration.flashnet.xyz';

    const response = await fetch(`${BASE_URL}/v1/pay-links`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.FLASHNET_API_KEY}`,
        'X-Idempotency-Key': `paylink:${Date.now()}`,
      },
      body: JSON.stringify({
        destinationChain: 'solana',
        destinationAsset: 'USDC',
        recipientAddress: 'So1YourSolanaAddress...',
        amountOut: '50000000', // $50 USDC (6 decimals)
        label: 'Invoice #1234',
      }),
    }).then((r) => r.json());
    ```

    Sender-pinned (`amountFiatUsd`):

    ```ts theme={null}
    const response = await fetch(`${BASE_URL}/v1/pay-links`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.FLASHNET_API_KEY}`,
        'X-Idempotency-Key': `paylink:${Date.now()}`,
      },
      body: JSON.stringify({
        destinationChain: 'solana',
        destinationAsset: 'USDC',
        recipientAddress: 'So1YourSolanaAddress...',
        amountFiatUsd: '50.00', // sender pays exactly $50 in Cash App
        label: 'Tip jar',
      }),
    }).then((r) => r.json());
    ```

    Response:

    ```json theme={null}
    {
      "payLink": {
        "id": "pl_abc123",
        "shortId": "DNHKySOZ",
        "destinationChain": "solana",
        "destinationAsset": "USDC",
        "recipientAddress": "So1YourSolanaAddress...",
        "amountOut": null,
        "amountFiatUsd": "50.00",
        "amountFiatCurrency": "USD",
        "affiliateId": null,
        "label": "Tip jar",
        "enabled": true,
        "createdAt": "2026-01-15T12:00:00.000Z",
        "updatedAt": "2026-01-15T12:00:00.000Z",
        "shortUrl": "https://orchestration.flashnet.xyz/pay/DNHKySOZ"
      }
    }
    ```

    For receiver-pinned links, `amountOut` carries the value and the fiat fields are `null`. Exactly one of `amountOut` or `amountFiatUsd` is set on every link.
  </Step>

  <Step title="Share the link">
    Share the `shortUrl` anywhere. On click:

    * Orchestra creates an exact-out Lightning quote (BTC sats calculated from the desired stablecoin output at current rates).
    * A fresh BOLT11 invoice is generated.
    * The browser redirects to `https://cash.app/launch/lightning/{invoice}`.
    * The user's Lightning-compatible app opens with the payment ready.

    ```
    https://orchestration.flashnet.xyz/pay/DNHKySOZ
    ```

    The default link serves a landing page with OpenGraph metadata (title, image) for rich previews in iMessage, WhatsApp, Twitter, etc., then redirects the user to pay the Lightning invoice.

    If you want to handle your own messaging previews or embed the link in a custom UI, use the `/go` variant to skip the landing page and go straight to quote creation and payment redirect:

    ```
    https://orchestration.flashnet.xyz/pay/DNHKySOZ/go
    ```
  </Step>

  <Step title="Track orders from a pay link">
    Each click creates a standard Orchestra order. Track them the same way as any other order: via webhooks or polling.

    Outbound `order.*` webhooks include `payLinkId` (and `payLinkLabel` when the link was created with a `label`) for orders originated from a pay-link, so you can reconcile events without keeping a separate mapping.

    List all orders created from a specific pay link:

    ```ts theme={null}
    const orders = await fetch(
      `${BASE_URL}/v1/orchestration/history?payLinkId=pl_abc123`,
      { headers: { Authorization: `Bearer ${API_KEY}` } }
    ).then((r) => r.json());
    ```
  </Step>

  <Step title="Disable a pay link">
    Disabled links return a 404 page. Existing orders created before disabling continue to process.

    ```ts theme={null}
    await fetch(`${BASE_URL}/v1/pay-links/pl_abc123`, {
      method: 'DELETE',
      headers: {
        Authorization: `Bearer ${process.env.FLASHNET_API_KEY}`,
        'X-Idempotency-Key': `disable:${Date.now()}`,
      },
    });
    ```
  </Step>
</Steps>

## Frontend integration

Pay Links share the browser-side deep link patterns with Onramp. For the Cash App navigation trick, the SSE order-tracking hook, the API-key proxy pattern, and the pipeline-progress UI, see [Deep link best practices](/products/orchestration/deeplink-best-practices).

## API reference

### POST /v1/pay-links

Create a new pay link. Requires authentication and idempotency.

**Request body:**

| Field              | Required | Type   | Notes                                                                                                                                                           |
| ------------------ | -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `destinationChain` | Yes      | string | Target chain (e.g., `solana`, `base`, `tron`)                                                                                                                   |
| `destinationAsset` | Yes      | string | Target asset (`USDB`, `USDC`, `USDT`, or `PathUSD`, depending on chain)                                                                                         |
| `recipientAddress` | Yes      | string | Destination address on the target chain                                                                                                                         |
| `amountOut`        | One of   | string | Desired output in smallest units (e.g., `"50000000"` = \$50 USDC). Must be a whole-cent stablecoin value. Receiver gets exactly this; sender pays it plus fees. |
| `amountFiatUsd`    | One of   | string | Sender's USD amount as a decimal string (e.g., `"50.00"`). Range $1.00 to $50,000.00. Receiver gets the net after fees; Cash App displays this exact figure.    |
| `affiliateId`      | No       | string | Registered affiliate ID for fee collection                                                                                                                      |
| `label`            | No       | string | Partner-facing label (max 255 chars)                                                                                                                            |

Exactly one of `amountOut` or `amountFiatUsd` must be set. The two are mutually exclusive.

### GET /v1/pay-links

List pay links for the authenticated partner. Supports `limit`, `offset`, and `includeDisabled` query parameters.

### GET /v1/pay-links/:id

Get a single pay link by ID.

### DELETE /v1/pay-links/:id

Disable a pay link (soft delete). The link returns 404 after disabling. Requires idempotency.

## What are the fees?

Platform fees use custom pricing based on route and volume. Affiliate fees are variable, configured per affiliate. Where fees land depends on which mode the link uses:

* `amountOut` mode: fees are added on top of the sender's Lightning invoice. The receiver gets exactly `amountOut`.
* `amountFiatUsd` mode: fees are deducted from the receiver's output. The sender pays exactly `amountFiatUsd` in BTC at click-time spot.

When execution produces stablecoin surplus above a receiver-pinned amount, Orchestra retains the surplus as `roundingFeeAmount`. This does not change the receiver's `amountOut`.

### Affiliate fees

Pay links support affiliate fees through the `affiliateId` field. Register an affiliate via `PUT /v1/affiliates/:affiliateId` first, then reference it when creating the link. Fees follow the same position as the platform fee: on top in `amountOut` mode, deducted from output in `amountFiatUsd` mode.

```json theme={null}
{
  "destinationChain": "solana",
  "destinationAsset": "USDC",
  "recipientAddress": "So1...",
  "amountOut": "50000000",
  "affiliateId": "my-partner"
}
```

## Pricing

Each click computes a fresh quote. The amount the sender pays reflects:

1. The pinned amount: receiver-side (`amountOut`) or sender-side (`amountFiatUsd`).
2. Platform fee (route-dependent).
3. Affiliate fees (if configured).
4. BTC/USDB swap rate at the moment of the click. For `amountFiatUsd`, the BTC/USD spot snapshot is also recorded on the order webhook as `spotUsdPerBtc`.

For `amountFiatUsd` orders, the order webhook payload mirrors `amountFiatUsd`, `amountFiatCurrency`, and `spotUsdPerBtc` at the top level so partners can reconcile the displayed Cash App figure with the delivered output without parsing `paymentIntent`.

## Next steps

* [Fiat Onramp](/products/orchestration/onramp) for the input-denominated variant
* [Order Lifecycle](/products/orchestration/order-lifecycle) for status tracking
* [Webhooks](/products/orchestration/webhooks) for real-time order updates
