<!-- ZenPays documentation · https://docs.zenpayz.com/docs/rest-api/endpoints/payments/confirm-payment -->

# Confirm Payment

Confirm a payment intent with customer and payment method details. This initiates the actual payment processing.

<EndpointHeader verb="POST" path="/api/v1/payment-intents/{intentId}/confirm" />

## Request

### Path Parameters

<ParamTable
  rows={[
    { name: "intentId", type: "string", required: true, desc: "Payment intent ID (e.g., `pi_xxxxx`)" },
  ]}
/>

### Headers

<ParamTable
  label="Header"
  rows={[
    { name: "Content-Type", required: true, desc: "`application/json`" },
    { name: "X-Request-Id", desc: "Unique request identifier (auto-generated if not provided)" },
  ]}
/>

:::note
This endpoint is **public** — no API key or signature required. It is called from the checkout page on behalf of the customer.
:::

### Body

<Tabs groupId="payment-type">
  <TabItem value="upi" label="UPI" default>

```json
{
  "customerDetails": {
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+911234567890",
    "address": {
      "country": "IN"
    }
  },
  "paymentMethodDetails": {
    "paymentMethod": "FIAT",
    "paymentType": "UPI",
    "upiId": "john@upi"
  },
  "deviceInfo": {
    "userAgent": "Mozilla/5.0 ...",
    "browserInfo": "Mozilla/5.0 ...",
    "screenWidth": 1512,
    "screenHeight": 982,
    "deviceFingerprint": "a1b2c3d4e5f6",
    "metadata": {
      "selectedPaymentMethod": "fiat",
      "selectedMethod": "upi",
      "specificPaymentMethod": "UPI",
      "customerCurrency": "INR"
    }
  }
}
```

  </TabItem>
  <TabItem value="card" label="Card">

:::tip
Card details (`cardNumber`, `expiryMonth`, `expiryYear`, `cvv`, `cardHolderName`) are optional. When omitted, the customer will be redirected to the TSP's hosted payment page to enter card details securely.
:::

```json
{
  "customerDetails": {
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+911234567890",
    "address": {
      "country": "IN"
    }
  },
  "paymentMethodDetails": {
    "paymentMethod": "FIAT",
    "paymentType": "CARD",
    "cardNumber": "4242424242424242",
    "expiryMonth": "12",
    "expiryYear": "2028",
    "cvv": "123",
    "cardHolderName": "John Doe"
  },
  "deviceInfo": {
    "userAgent": "Mozilla/5.0 ...",
    "browserInfo": "Mozilla/5.0 ...",
    "screenWidth": 1512,
    "screenHeight": 982,
    "deviceFingerprint": "a1b2c3d4e5f6",
    "metadata": {
      "selectedPaymentMethod": "fiat",
      "selectedMethod": "card",
      "specificPaymentMethod": "CARD",
      "customerCurrency": "INR"
    }
  }
}
```

  </TabItem>
  <TabItem value="bank_transfer" label="Bank Transfer">

```json
{
  "customerDetails": {
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+250793045233",
    "address": {
      "country": "RW"
    }
  },
  "paymentMethodDetails": {
    "paymentMethod": "FIAT",
    "paymentType": "BANK_TRANSFER"
  },
  "deviceInfo": {
    "userAgent": "Mozilla/5.0 ...",
    "browserInfo": "Mozilla/5.0 ...",
    "screenWidth": 1512,
    "screenHeight": 982,
    "deviceFingerprint": "a1b2c3d4e5f6",
    "metadata": {
      "selectedPaymentMethod": "fiat",
      "selectedMethod": "card",
      "specificPaymentMethod": "BANK_TRANSFER",
      "customerCurrency": "USD"
    }
  }
}
```

  </TabItem>
</Tabs>

### Field Reference

#### `customerDetails` (required)

<ParamTable
  rows={[
    { name: "name", type: "string", required: true, desc: "Customer full name (max 100 chars)" },
    { name: "email", type: "string", required: true, desc: "Customer email" },
    { name: "phone", type: "string", desc: "Customer phone (max 15 chars)" },
    { name: "address.country", type: "string", desc: "ISO 3166-1 alpha-2 country code" },
  ]}
/>

#### `paymentMethodDetails` (optional)

<ParamTable
  rows={[
    { name: "paymentMethod", type: "string", required: true, desc: "`FIAT` or `CRYPTO`" },
    { name: "paymentType", type: "string", required: true, desc: "Payment type within the method (see below)" },
  ]}
/>

**Fiat payment types** (`paymentMethod: "FIAT"`):

| `paymentType` | Additional Fields | Description |
|----------------|-------------------|-------------|
| `UPI` | `upiId` (string) — UPI VPA e.g. `user@upi` | UPI payment |
| `CARD` | `cardNumber`, `expiryMonth`, `expiryYear`, `cvv`, `cardHolderName` | Card payment |
| `NETBANKING` | `bankCode` (string) — bank code | Net banking |
| `BANK_TRANSFER` | — | Bank transfer |
| `PIX` | — | PIX (Brazil) |
| `WALLET` | — | Wallet payment |

**Crypto payment types** (`paymentMethod: "CRYPTO"`):

| `paymentType` | Additional Fields | Description |
|----------------|-------------------|-------------|
| `DIRECT_CRYPTO` | `chain` (string) — blockchain e.g. `ethereum`, `tron` | Direct crypto payment |
| `BUY_WITH_WALLET` | `chain` (string) — blockchain | Crypto purchase via wallet |

#### `deviceInfo` (optional)

<ParamTable
  rows={[
    { name: "userAgent", type: "string", desc: "Browser user agent" },
    { name: "browserInfo", type: "string", desc: "Browser info string" },
    { name: "screenWidth", type: "number", desc: "Screen width in pixels" },
    { name: "screenHeight", type: "number", desc: "Screen height in pixels" },
    { name: "deviceFingerprint", type: "string", desc: "Device fingerprint hash" },
    { name: "metadata", type: "object", desc: "Additional context (selected method, customer currency, etc.)" },
  ]}
/>

## Response

### Success (200 OK)

```json
{
  "success": true,
  "data": {
    "intentId": "pi_1771910100598_prckpcg01",
    "status": "processing",
    "redirectUrl": "https://checkout.zenpayz.io/pay/xxxxx",
    "externalTransactionId": "txn_abc123"
  },
  "message": "Payment confirmed successfully",
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-02-24T05:15:00.599Z",
    "processing_time_ms": 1250,
    "api_version": "v1",
    "endpoint": "POST /payment-intent/:intentId/confirm"
  }
}
```

### Error Responses

<ErrorTable
  rows={[
    { code: "INVALID_REQUEST", status: "400", message: "Missing required fields" },
    { code: "UNAUTHORIZED", status: "401", message: "Invalid API key" },
    { code: "PAYMENT_INTENT_NOT_FOUND", status: "404", message: "Intent doesn't exist" },
    { code: "STATE_CONFLICT", status: "409", message: "Intent not in valid state" },
    { code: "PAYMENT_FAILED", status: "422", message: "Payment processing failed" },
    { code: "CHANNEL_LIMIT_MIN_EXCEEDED", status: "422", message: "Amount below minimum for payment method" },
    { code: "CHANNEL_LIMIT_MAX_EXCEEDED", status: "422", message: "Amount exceeds maximum for payment method" },
  ]}
/>

<CodeRail>

## Examples

<Tabs groupId="language">
  <TabItem value="curl" label="cURL" default>

```bash
# No authentication required — this is a public endpoint
curl -X POST "https://api.zenpayz.com/api/v1/payment-intents/pi_1771910100598_prckpcg01/confirm" \
  -H "Content-Type: application/json" \
  -d '{
    "customerDetails": {
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "+911234567890",
      "address": { "country": "IN" }
    },
    "paymentMethodDetails": {
      "paymentMethod": "FIAT",
      "paymentType": "UPI",
      "upiId": "john@upi"
    },
    "deviceInfo": {
      "userAgent": "Mozilla/5.0...",
      "deviceFingerprint": "a1b2c3d4e5f6"
    }
  }'
```

  </TabItem>
  <TabItem value="javascript" label="JavaScript">

```javascript
const intentId = 'pi_1771910100598_prckpcg01';

const body = {
  customerDetails: {
    name: 'John Doe',
    email: 'john@example.com',
    phone: '+911234567890',
    address: { country: 'IN' },
  },
  paymentMethodDetails: {
    paymentMethod: 'FIAT',
    paymentType: 'UPI',
    upiId: 'john@upi',
  },
  deviceInfo: {
    userAgent: navigator.userAgent,
    screenWidth: window.screen.width,
    screenHeight: window.screen.height,
    deviceFingerprint: 'a1b2c3d4e5f6',
    metadata: {
      selectedPaymentMethod: 'fiat',
      selectedMethod: 'upi',
      specificPaymentMethod: 'UPI',
      customerCurrency: 'INR',
    },
  },
};

// No authentication needed — public endpoint
const response = await fetch(
  `https://api.zenpayz.com/api/v1/payment-intents/${intentId}/confirm`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }
);

const result = await response.json();

if (result.data.redirectUrl) {
  window.location.href = result.data.redirectUrl;
}
```

  </TabItem>
  <TabItem value="python" label="Python">

```python
import requests

intent_id = "pi_1771910100598_prckpcg01"

body = {
    "customerDetails": {
        "name": "John Doe",
        "email": "john@example.com",
        "phone": "+911234567890",
        "address": {"country": "IN"},
    },
    "paymentMethodDetails": {
        "paymentMethod": "FIAT",
        "paymentType": "UPI",
        "upiId": "john@upi",
    },
    "deviceInfo": {
        "userAgent": "Mozilla/5.0...",
        "deviceFingerprint": "a1b2c3d4e5f6",
    },
}

# No authentication needed — public endpoint
response = requests.post(
    f"https://api.zenpayz.com/api/v1/payment-intents/{intent_id}/confirm",
    headers={"Content-Type": "application/json"},
    json=body,
)

result = response.json()
if result["data"].get("redirectUrl"):
    print(f"Redirect to: {result['data']['redirectUrl']}")
```

  </TabItem>
  <TabItem value="sdk" label="SDK (Recommended)">

```javascript
// JavaScript SDK
const result = await zenpays.payments.confirmPayment('pi_1771910100598_prckpcg01', {
  customerDetails: {
    name: 'John Doe',
    email: 'john@example.com',
    phone: '+911234567890',
    address: { country: 'IN' },
  },
  paymentMethodDetails: {
    paymentMethod: 'FIAT',
    paymentType: 'UPI',
    upiId: 'john@upi',
  },
});

if (result.redirectUrl) {
  window.location.href = result.redirectUrl;
}
```

  </TabItem>
</Tabs>

</CodeRail>

## Handling Payment Actions

The response may require additional actions:

| Action Type | Description | Next Step |
|-------------|-------------|-----------|
| `redirect` | Redirect to payment page | Navigate to `redirectUrl` |
| `3ds_authentication` | 3D Secure required | Show 3DS popup/iframe |
| `otp_verification` | OTP required | Display OTP input |
| `none` | No action needed | Payment complete |

## Related Endpoints

- [Create Payment Intent](/docs/rest-api/endpoints/payments/create-payment-intent)
- [Get Payment Intent](/docs/rest-api/endpoints/payments/get-payment-intent)
- [Webhooks](/docs/guides/webhooks) - Handle async status updates
