---
name: natural-create-payment
description: Create a payment from a customer's wallet to a recipient on the Natural platform. Use when you have a customerPartyId and need to create a payment. Use natural-list-customers to discover customers and natural-check-balance for pre-flight balance checks.
metadata:
  author: Natural
  version: "1.0"
---

# Create Payment

Create a payment from a customer's wallet to a recipient (email, phone, or party ID) on the Natural platform.

This skill handles only payment creation. For related operations, see:

- **[List Customers](https://natural.co/skills/list-customers.md)** — discover customers with delegated payment authority
- **[Check Balance](https://natural.co/skills/check-balance.md)** — pre-flight balance check
- **[Get Transaction](https://natural.co/skills/get-transaction.md)** — verify payment status after creation

## Prerequisites

- A valid API key (`sk_*`) is configured
- You have a `customerPartyId` (`pty_xxx`) with delegated payment authority
- You know your `agentId` (`agt_xxx`) and have a session `instanceId`

## Parameters

Required:

| Parameter         | Format                     | Description                      |
| ----------------- | -------------------------- | -------------------------------- |
| `customerPartyId` | `pty_xxx`                  | The customer's party ID          |
| `recipient`       | email, phone, or `pty_xxx` | Who receives the payment         |
| `amount`          | integer (minor units)      | Amount in cents. $50.00 = `5000` |
| `memo`            | string (max 500)           | Description of the payment       |
| `idempotencyKey`  | string (max 256)           | Unique key for this request      |

Agent attribution (strongly recommended):

| Parameter    | Format           | Description                                                                                               |
| ------------ | ---------------- | --------------------------------------------------------------------------------------------------------- |
| `agentId`    | `agt_xxx`        | Your agent ID                                                                                             |
| `instanceId` | free-form string | Session or conversation ID (e.g., a UUID or your own identifier). **Required** when `agentId` is provided |

Optional:

| Parameter  | Default | Description   |
| ---------- | ------- | ------------- |
| `currency` | `USD`   | Currency code |

## Workflow

### 1. Validate inputs

- **Amounts are always in minor units (cents).** Convert dollar amounts before sending: `$50.00` becomes `5000`, `$1.50` becomes `150`.
- **Recipient format:** email must contain `@`, phone must start with `+` or be 10+ digits, party ID must start with `pty_`.
- **Idempotency:** Generate a unique `idempotencyKey` per payment intent. If you need to retry a failed request, reuse the same key to prevent duplicate payments. Generate a new key for each distinct payment.

### 2. Send the payment

Execute the payment creation using the CLI or MCP adapter below.

### 3. Confirm submission

The response includes a `transactionId` (`txn_xxx`) and initial `status`. Use [Get Transaction](https://natural.co/skills/get-transaction.md) to check the final status if needed.

## Error handling

When a payment fails, categorize by cause:

- **Insufficient funds:** Inform the user of the shortfall — use [Check Balance](https://natural.co/skills/check-balance.md) to show the current balance
- **Invalid recipient:** Verify the recipient format
- **Auth error:** API key is missing, invalid, or lacks permission for this customer
- **Rate limit / server error:** Wait and retry with the same `idempotencyKey`

## Agent attribution

Always provide `agentId` and `instanceId` when available. This enables:

- Audit trails linking payments to the agent and session that initiated them
- Scoped transaction listing (filter by agent)
- Observability across the full request chain (CLI/MCP -> SDK -> server)

When `agentId` is provided, `instanceId` is **required** by both CLI and MCP. Omitting it will result in a validation error.

---

## CLI Adapter

Execute the create-payment workflow using the `natural` CLI. All commands should use `--format json` for structured output that agents can parse.

### Command

```bash
natural payments create \
  --customer-party-id pty_xxx \
  --counterparty bob@example.com \
  --amount 5000 \
  --description "Invoice #789" \
  --x-agent-id agt_xxx \
  --x-instance-id conv-abc-123 \
  --format json
```

The `--idempotency-key` flag is optional — the CLI auto-generates a UUID if omitted. Pass it explicitly when retrying a failed request.

Response shape:

```json
{
  "transactionId": "txn_xxx",
  "status": "PROCESSING",
  "amount": 5000,
  "currency": "USD",
  "memo": "Invoice #789",
  "senderName": "John Doe",
  "recipientName": "bob@example.com",
  "direction": "OUTBOUND",
  "isDelegated": true,
  "createdAt": "2026-04-03T12:00:00Z",
  "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"
}
```

### Exit codes

| Code | Meaning                                              | Action                           |
| ---- | ---------------------------------------------------- | -------------------------------- |
| 0    | Success                                              | Parse JSON response              |
| 1    | Business error (insufficient funds, invalid request) | Read error message, do not retry |
| 2    | Usage error (missing flags, bad arguments)           | Fix the command                  |
| 3    | Auth error (missing or invalid API key)              | Check credentials                |
| 4    | Network/server error (timeout, rate limit)           | Retry with same idempotency key  |

### Notes

- Always pass `--format json` — human-formatted output is not designed for agent parsing
- Amounts are always minor units (cents) in both input and output
- Pass the format flag explicitly for clarity, even when stdout is piped

---

## MCP Adapter

Execute the create-payment workflow using Natural MCP server tools. The MCP server authenticates via Bearer token in the session.

### Tool

Tool: `create_payment`

```json
{
  "amount": 5000,
  "customerPartyId": "pty_xxx",
  "recipient": "bob@example.com",
  "memo": "Invoice #789",
  "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
  "agentId": "agt_xxx",
  "instanceId": "conv-abc-123"
}
```

Unlike the CLI, the MCP tool requires `idempotencyKey` explicitly — it does not auto-generate one.

The response includes all transaction fields, including `claimLink` when the payment status is `PENDING_CLAIM`.

### Error handling

MCP tool errors are returned as tool call failures with an error message. Categorize by the message content:

- Authentication errors: API key issues
- Validation errors: missing or invalid parameters (e.g., `instanceId is required when agentId is provided`)
- Business errors: insufficient funds, invalid recipient
- Server errors: retry with the same `idempotencyKey`

### Notes

- `idempotencyKey` is required — always generate and provide one
- `instanceId` is required when `agentId` is provided, enforced at both MCP and SDK layers
