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

# Payments (Receive Money)

> Accept payments via Stripe, crypto, and agent payment protocols — one integration for every payment rail

Anyway lets you create products with payment links and accept payments through two providers: **Stripe** (fiat/card) and **Crypto** (USDC on Base). Each product is tied to one provider.

## Creating Products & Payment Links

Products are the foundation of payments. Creating a product automatically generates a payment link.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    # Crypto product (default provider)
    anyway products create --name "My Product" --price 29.99

    # Stripe product
    anyway products create --name "My Product" --price 29.99 --provider stripe

    # Stripe subscription
    anyway products create --name "Pro Plan" --price 9.99 --provider stripe --type recurring --interval month

    # Crypto with flexible amount (buyer decides)
    anyway products create --name "Donation" --provider crypto
    ```

    The payment link URL is returned in the output. Use `--format json` to capture it programmatically:

    ```bash theme={null}
    result=$(anyway products create --name "API Product" --price 49.99 --format json)
    payment_link=$(echo $result | jq -r '.paymentLink.paymentLinkUrl')
    ```
  </Tab>

  <Tab title="Webapp">
    1. Go to [Products](https://app.anyway.sh/products) and click **Create Product**
    2. Fill in the product name, description, and pricing
    3. Select the payment provider (Stripe or Crypto)
    4. For Stripe: choose one-time or recurring, set the price
    5. For Crypto: optionally set a fixed price, or leave blank for flexible amount
    6. A payment link is automatically created — copy it from the product detail page
  </Tab>
</Tabs>

### Managing Payment Links

<Tabs>
  <Tab title="Webapp">
    Go to [Products](https://app.anyway.sh/products), click a product to open its detail page. From there you can:

    * View all payment links and their status
    * Copy a payment link URL
    * Create additional payment links with different pricing or providers
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    # List payment links for a product
    anyway products payment-links <productId>

    # Create additional payment link for a product
    anyway products payment-links <productId> create --price 19.99 --provider crypto
    ```
  </Tab>
</Tabs>

## Stripe Payments

<Note>
  Before creating Stripe products, connect your Stripe account via `anyway init wallets --type stripe` or the [Wallets page](https://app.anyway.sh/wallets).
</Note>

### How it works

1. Create a product with `--provider stripe`
2. Share the payment link URL with your customer
3. Customer completes payment via Stripe's hosted checkout (card, 3D Secure, etc.)
4. Order appears in your [Orders](https://app.anyway.sh/orders) page and `anyway orders list`

### Supported pricing models

| Model                | CLI flags                                        | Description       |
| -------------------- | ------------------------------------------------ | ----------------- |
| One-time             | `--price 29.99`                                  | Single charge     |
| Monthly subscription | `--price 9.99 --type recurring --interval month` | Recurring monthly |
| Yearly subscription  | `--price 99 --type recurring --interval year`    | Recurring yearly  |

### Payouts

View your Stripe balance and request payouts from the [Wallets page](https://app.anyway.sh/wallets) or [Finance page](https://app.anyway.sh/finance).

## Crypto Payments (USDC on Base)

Crypto payment links accept USDC on the Base network (Ethereum L2).

<Note>
  Before creating crypto products, activate your USDC wallet via `anyway init wallets --type crypto` or the [Wallets page](https://app.anyway.sh/wallets).
</Note>

### Pay by Human (Browser)

Share the payment link URL with your customer. The checkout page at `https://app.anyway.sh/pay/<PAYMENT_LINK_ID>` handles:

* Wallet connection
* Balance checks
* Transaction submission and confirmation

No code needed — the customer handles everything in the browser.

### Pay by Agent/Automation (Programmatic)

For programmatic payments (e.g., agent-to-agent), send USDC directly on-chain using `viem`.

**Prerequisites:**

* Node.js with `viem` installed: `npm install -g viem`
* Base wallet private key with USDC balance and small ETH for gas (\~0.0001 ETH)

#### Step 1 — Fetch payment instructions

```
GET https://app-prod.anyway.sh/v1/pay/agent/<PAYMENT_LINK_ID>
```

Response (key fields):

```json theme={null}
{
  "success": true,
  "data": {
    "linkId": "PL...",
    "status": "ACTIVE",
    "recipient": "0x...",
    "amount": null,
    "currency": "USDC",
    "chain": "base",
    "network": "Base (Ethereum L2)",
    "usdcContract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "confirmUrl": "/v1/pay/<LINK_ID>/confirm"
  }
}
```

* `amount: null` means flexible / any amount — the sender decides how much to pay.
* If `amount` is set, send exactly that amount.

#### Step 2 — Check balances

```javascript theme={null}
const { createPublicClient, http, formatEther, formatUnits } = require('viem');
const { privateKeyToAccount } = require('viem/accounts');
const { base } = require('viem/chains');

const USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const account = privateKeyToAccount(privateKey);
const client = createPublicClient({ chain: base, transport: http() });

const [ethBalance, usdcBalance] = await Promise.all([
  client.getBalance({ address: account.address }),
  client.readContract({
    address: USDC,
    abi: [{ name: 'balanceOf', type: 'function', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' }],
    functionName: 'balanceOf',
    args: [account.address]
  })
]);

console.log('ETH:', formatEther(ethBalance));
console.log('USDC:', formatUnits(usdcBalance, 6));
```

<Warning>
  If ETH balance is 0, you cannot send transactions. Top up ETH on Base network first.
</Warning>

#### Step 3 — Human-in-the-loop confirmation (REQUIRED)

Before sending, surface a summary and wait for **explicit human approval**:

```
Payment Link ID : <PAYMENT_LINK_ID>
Recipient       : <RECIPIENT_ADDRESS>
Amount          : <AMOUNT_USDC> USDC
Network         : Base (Ethereum L2)
Sender wallet   : <SENDER_ADDRESS>

⚠️ This transaction is IRREVERSIBLE. Once sent, USDC cannot be recalled.
```

<Warning>
  If an AI agent determined the payment amount, that same agent must NOT self-approve. Approval must come from an independent human or system. If the calling system does not support human-in-the-loop, programmatic payment must not be used.
</Warning>

#### Step 4 — Send USDC

Only after explicit human approval:

```javascript theme={null}
const { createWalletClient, http, publicActions, parseUnits } = require('viem');
const { privateKeyToAccount } = require('viem/accounts');
const { base } = require('viem/chains');

const USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const account = privateKeyToAccount(privateKey);
const client = createWalletClient({ account, chain: base, transport: http() }).extend(publicActions);

const txHash = await client.writeContract({
  address: USDC,
  abi: [{ name: 'transfer', type: 'function', inputs: [{ name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' }], outputs: [{ type: 'bool' }], stateMutability: 'nonpayable' }],
  functionName: 'transfer',
  args: [recipient, parseUnits(amountUsdc, 6)]
});

console.log('TX Hash:', txHash);
console.log('Track:', `https://basescan.org/tx/${txHash}`);
```

#### Step 5 — Confirm payment

**5a — Immediately after submitting** (before on-chain confirmation):

```
POST https://app-prod.anyway.sh/v1/pay/<LINK_ID>/confirm
Content-Type: application/json

{
  "txHash": "0x...",
  "email": "sender@example.com",
  "note": "Payment for <description>"
}
```

If response is `TX_PENDING`, the transaction hasn't mined yet — wait 5–15 seconds and retry.

**5b — After block confirmations:**

```
POST https://app-prod.anyway.sh/v1/pay/<LINK_ID>/confirm
Content-Type: application/json

{ "txHash": "0x..." }
```

Success response:

```json theme={null}
{
  "success": true,
  "message": "Payment confirmed",
  "data": { "status": "PAID", "orderId": "ORD..." }
}
```

### Troubleshooting

| Error                             | Cause                         | Fix                                        |
| --------------------------------- | ----------------------------- | ------------------------------------------ |
| `insufficient funds for transfer` | ETH balance = 0               | Top up ETH on Base network                 |
| `TX_PENDING`                      | Transaction not yet mined     | Wait 5–15s, retry confirm                  |
| `TX_NOT_FOUND`                    | Wrong txHash or wrong network | Verify on [BaseScan](https://basescan.org) |

### Reference

* USDC contract on Base: `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`
* Gas cost: ~~0.00000027 ETH per transfer (~~\$0.0007)
* Block explorer: `https://basescan.org/tx/<txHash>`

## Viewing Orders

All paid orders (Stripe and crypto) are unified in one view:

```bash theme={null}
anyway orders list                              # All orders
anyway orders list --status paid                # Paid only
anyway orders list --product <productId>        # By product
anyway orders list --from 2024-01-01 --to 2024-12-31  # By date range
anyway orders list --format csv > orders.csv    # Export
```

Or view at [Orders page](https://app.anyway.sh/orders).
