# Charge a customer

To take a payment from a customer, create a charge. Say how much and in which coin, add whatever you already know, and send them to the checkout page that comes back. You do not need a payment link for this.

## Four steps

**1. See which coins you can offer.** GET /v1/assets lists the coins on offer, whether your account takes each, and the lowest price each can be charged at. Show them on your own page, or ask the customer.

```bash
curl "https://api.velirapay.com/v1/assets?currency=USD" \
  -H "Authorization: Bearer vp_live_…"
```

**2. Create the charge.** Only amount, currency and asset are required. Everything else is optional, and spares the customer from giving it again.

```bash
curl -X POST https://api.velirapay.com/v1/charges \
  -H "Authorization: Bearer vp_live_…" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "150.00",
    "currency": "USD",
    "asset": "BTC",
    "description": "Order #1042",
    "customer": {
      "email": "ada@example.com",
      "name": "Ada Lovelace",
      "reference": "cus_1042"
    },
    "metadata": {"order_id": "1042"},
    "success_url": "https://example.com/orders/1042"
  }'
```

**3. Send the customer to the checkout_url.** It shows the exact amount, the address, a QR code and a 30-minute countdown, and updates itself. Redirect them there, put it in a message, or pass send_email to have it emailed.

**4. Wait for charge.paid.** Your webhook endpoint is told when the payment confirms, with your metadata in the payload, so you can fulfil the order. The money is forwarded to your wallet on its own.

[Set up a webhook endpoint →](https://velirapay.com/docs/webhooks)

## Prefill what you already know

All of this is optional, and goes straight on the charge when you create it.

| Field | Type | Description |
| --- | --- | --- |
| `customer.email, customer.name` | string | Who pays. The email gets the receipt, and the payment page if you ask for it to be sent. |
| `customer.reference, phone, country, ip_address, user_agent, metadata` | mixed | Anything else you know about them, to help you spot fraud before you ship. |
| `description` | string | What the payment is for, shown at checkout, in the email and on the receipt. |
| `metadata` | object | Your own references, such as an order number. They come back on the charge and in every webhook about it. |
| `custom_fields` | array | Up to five labelled details shown with the charge in the dashboard, such as the answers to a payment link's questions. |
| `coupon` | string | One of your coupons, taken off the amount. |
| `success_url, cancel_url` | string | https:// addresses on your own site: a button back once they have paid, and a link back if they leave without paying. |
| `success_message` | string | What the customer is told once they have paid, on the page and in the receipt. |
| `send_email` | boolean | Email the customer the payment page as soon as the charge exists. |

[See the charge object and every field →](https://velirapay.com/docs/charges)

## Which one to use

| When | Use | Endpoint | Why |
| --- | --- | --- | --- |
| You are asking one customer for one payment | A charge | `POST /v1/charges` | The default. It has one checkout page for that one payment, with the rate locked for 30 minutes. |
| The customer should choose the coin, or pays later | An invoice | `POST /v1/invoices` | It needs their name and email, has no timer, can be itemised and reminded, and lets them pick the coin on its page. |
| Many customers pay through the same public page | A payment link, created once | `POST /v1/payment-links` | A product sold again and again, a tip jar, a link on your site. Each customer picks their own coin. |

Do not create a new payment link for each customer or each order. A link is a page meant to be opened by many people: it stays in your list, keeps taking payments until you close it, and its price is not tied to any one order. A charge is made for exactly this, and needs nothing cleaned up afterwards, because it expires by itself.

## When you do not know the coin

A charge has its coin from the start, because its exchange rate, amount and deposit address depend on it. So ask, on your own page or in the conversation, and offer the coins from GET /v1/assets. If the customer should choose on our page instead and you have their name and email, create an invoice.

## Try it without real money

Use a vp_test_ key, and pay the charge with POST /v1/charges/{id}/simulate: it becomes paid, and the webhooks and emails go out as for a real payment.

```bash
curl -X POST https://api.velirapay.com/v1/charges/2t4bcuqkpkoy/simulate \
  -H "Authorization: Bearer vp_test_…"
```

## For AI assistants

On the MCP server, the tool to charge a customer is create_charge, which takes the same details. [See the MCP server →](https://velirapay.com/docs/mcp)

Every page of this documentation is also available as Markdown, by adding .md to its address, and all of it in one file at https://velirapay.com/llms-full.txt.
