> For the complete documentation index, see [llms.txt](https://pingpay.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pingpay.gitbook.io/docs/pingpay-api/headless-payments/prepare-payment.md).

# Prepare Payment

This page explains how to define and validate a payment intent before execution

***

### **Prepare a Payment** <a href="#retrieve-checkout-session" id="retrieve-checkout-session"></a>

The `POST /payments/prepare` endpoint creates a **payment intent**.

Preparing a payment defines *what* will be paid, *by whom*, and *to whom*, but **does not execute the payment**. This step validates the request, calculates fees, and returns a `paymentId` that is later used to submit and track the payment.

This endpoint is the **first step** in all headless payment flows.

***

### Endpoint

```shellscript
POST /payments/prepare
```

***

### Headers

```http
x-publishable-key: pk_test_123456
Content-Type: application/json
```

***

### Request Body

```json
{
  "payer": {
    "address": "payer.near",
    "chainId": "near-mainnet"
  },
  "recipient": {
    "address": "example.near",
    "chainId": "near-mainnet"
  },
  "asset": {
    "assetId": "nep141:wrap.near",
    "amount": "1000000000000000000000000"
  },
  "idempotencyKey": "order_12345",
  "memo": "Invoice #12345"
}
```

#### **Required fields**

* `payer`
* `recipient`
* `asset`
* `idempotencyKey`

***

### Idempotency

The `idempotencyKey` ensures that repeated requests with the same key **do not create duplicate payment intents**.

* Use a unique, deterministic value per payment (e.g. order ID)
* Reusing the same key will return the original prepared payment
* This allows safe retries in the event of network failures

Idempotency is **required** for this endpoint.

***

### Response

A successful request returns the prepared payment intent.

```json
{
  "payment": {
    "paymentId": "pay_456",
    "status": "PENDING",
    "payer": {
      "address": "payer.near",
      "chainId": "near-mainnet"
    },
    "recipient": {
      "address": "example.near",
      "chainId": "near-mainnet"
    },
    "asset": {
      "assetId": "nep141:wrap.near",
      "amount": "1000000000000000000000000"
    },
    "feeQuote": {
      "totalFee": "1000000000000000000000"
    },
    "createdAt": "2025-01-01T00:00:00.000Z"
  }
}
```

#### **Key Fields**

* `paymentId` — Unique identifier for the prepared payment
* `status` — Initial value is `PENDING`
* `feeQuote.totalFee` — Estimated total fees for executing the payment

***

#### **Notes**

* Preparing a payment **does not move funds**
* No blockchain transaction is submitted at this stage
* The returned `paymentId` must be used when submitting the payment
* Fees may vary depending on execution conditions

***

### Error Response Example

```json
{
  "code": "INVALID_REQUEST",
  "message": "Invalid payment parameters."
}

```
