---
title: Create & complete a payment | API Docs
description: Create a payment for a connected customer, wait until it's ready, and hand the card to your agent.
---

Once a customer’s handle is [connected](/guides/agentcard/connect-a-customer/index.md), your agent can pay a merchant on their behalf with a card from their Agentcard Wallet. A payment moves through a short lifecycle; you create it, wait for `ready`, then retrieve the card handoff.

Base URL: `https://api.linqapp.com/api/partner/v3`.

## 1. Create the payment

Terminal window

```
curl -X POST https://api.linqapp.com/api/partner/v3/payments \
  -H "Authorization: Bearer $LINQ_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "handle": "+14155550123",
    "amount_cents": 2500,
    "currency": "usd",
    "description": "Burger order",
    "merchant": { "name": "DoorDash", "url": "doordash.com" }
  }'
```

| Field                            | Required | Notes                                           |
| -------------------------------- | -------- | ----------------------------------------------- |
| `handle`                         | yes      | Connected customer — phone (E.164) or email.    |
| `amount_cents`                   | yes      | Integer, **minor units** (`2500` = $25.00 USD). |
| `currency`                       | yes      | ISO currency code, lowercase (`usd`).           |
| `description`                    | no       | Shown to the customer.                          |
| `merchant.name` / `merchant.url` | no       | Where the agent will spend.                     |
| `metadata`                       | no       | Your own key/value pairs.                       |

Always send an `Idempotency-Key`; retrying the same key returns the original payment instead of creating a second one.

```
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "needs_connection",
  "handle": "+14155550123",
  "amount_cents": 2500,
  "currency": "usd",
  "description": "Burger order",
  "attach_url": "https://zero.linqapp.com/...",
  "approval_url": "https://zero.linqapp.com/..."
}
```

If the handle isn’t connected yet, `status` is `needs_connection` — send the customer to `attach_url` to add a card, or `approval_url` to approve with a passkey, to finish connecting.

## 2. Wait until the payment is `ready`

Don’t poll in a tight loop — react to [webhooks](/guides/agentcard/webhooks/index.md), then re-fetch for authoritative status:

Terminal window

```
curl https://api.linqapp.com/api/partner/v3/payments/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer $LINQ_API_KEY"
```

Payment statuses:

| Status                 | Meaning                                                       |
| ---------------------- | ------------------------------------------------------------- |
| `needs_connection`     | The handle isn’t connected — send them through connect first. |
| `connecting`           | Connection in progress.                                       |
| `awaiting_user_action` | Waiting on the customer (e.g. approval).                      |
| `ready`                | The card is available — retrieve the handoff.                 |
| `authorized`           | The merchant placed a hold on the card.                       |
| `succeeded`            | The charge settled.                                           |
| `declined`             | The charge was declined.                                      |
| `canceled`             | You canceled the payment.                                     |
| `expired`              | The payment lapsed before completing.                         |

## 3. Retrieve the card and let the agent pay

When `status` is `ready`, fetch the handoff and let your agent redeem it at Agentcard. Details never pass through Linq — see [Cards & credentials](/guides/agentcard/cards-and-credentials/index.md).

Terminal window

```
curl https://api.linqapp.com/api/partner/v3/payments/550e8400-e29b-41d4-a716-446655440000/credentials \
  -H "Authorization: Bearer $LINQ_API_KEY"
```

## 4. Confirm the outcome

You’ll get `payment.authorized` when the merchant holds the card, then the payment settles to `succeeded` — poll `GET /payments/{id}` to confirm, as there is no `succeeded` webhook. If the charge fails you’ll get `payment.declined`.

## Cancel a payment

Cancel one that hasn’t completed:

Terminal window

```
curl -X POST https://api.linqapp.com/api/partner/v3/payments/550e8400-e29b-41d4-a716-446655440000/cancel \
  -H "Authorization: Bearer $LINQ_API_KEY"
```

## Notes

- Re-fetch the payment on any webhook rather than trusting the event body.
- `declined`, `canceled`, and `expired` are terminal — create a new payment to retry.

## Next

- [Cards & credentials](/guides/agentcard/cards-and-credentials/index.md)
- [Errors, statuses & go-live](/guides/agentcard/errors-and-go-live/index.md)
