> 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/submit-payment.md).

# Submit Payment

This page explains how to execute a previously prepared payment.

***

### Submit a Payment

The `POST /payments/submit` endpoint executes a previously prepared payment.

Submitting a payment is the step where funds are actually moved. This endpoint takes a prepared `paymentId` and submits it for execution on the underlying networks.

You **must prepare a payment first** using the Prepare Payment endpoint before submitting it.

***

### Endpoint

```shellscript
POST /payments/submit
```

***

### Headers

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

***

### Request Body

```json
{
  "paymentId": "pay_456",
  "idempotencyKey": "order_12345",
  "signedPayload": "0xabcdef..."
}
```

#### Required Fields

* `paymentId` — The identifier returned from the prepare step
* `idempotencyKey` — Used to prevent duplicate execution
* `signedPayload` — Authorisation or signature required to execute the payment

***

### Signing and Authorisation

Submitting a payment typically requires a **signature or signed payload** from the payer.

The exact signing mechanism depends on:

* the payer’s wallet
* the underlying blockchain(s)
* the execution strategy

Pingpay does not generate signatures on behalf of the payer. Your application is responsible for obtaining and providing the required payment authorisation.

***

### Idempotency

The `idempotencyKey` ensures that retrying a submit request does **not result in duplicate execution**.

* Use the same idempotency key that was used during preparation
* Repeating the request with the same key will return the existing execution result
* This allows safe retries if network errors occur

Idempotency is **required** for this endpoint.

***

### Response

A successful request returns the updated payment object.

```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"
    },
    "updatedAt": "2025-01-01T00:01:00.000Z"
  }
}
```

***

### Payment Status

After submission, the payment status reflects execution progress.

The payment status will be one of:

* `PENDING` — Execution has been initiated
* `SUCCESS` — Payment completed successfully
* `FAILED` — Payment failed during execution

Final status should be confirmed by retrieving the payment.

***

#### Notes

* Submitting a payment **initiates execution**
* This operation should be treated as **non-reversible**
* Always use idempotency keys when retrying
* Do not submit the same payment with different idempotency keys

***

### Error Response Example

```json
{
  "code": "INVALID_PAYMENT_STATE",
  "message": "Payment cannot be submitted in its current state."
}
```
