> ## Documentation Index
> Fetch the complete documentation index at: https://developer.tazapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# upi_inr_native_vpa_flow

> Accept UPI payments via collect request using the customer's VPA (Virtual Payment Address).

## Overview

The customer enters their UPI VPA (e.g., `test@bank`) at checkout. A collect request is sent to their UPI-linked bank app. The customer approves and authenticates with their UPI PIN — funds settle instantly.

***

## Step 1: Create a Payin

Create a payin with `invoice_currency: INR`. The payin is created with status `requires_payment_method`.

```bash theme={null}
curl --request POST \
     --url https://service-sandbox.tazapay.com/v3/payin \
     --header 'accept: application/json' \
     --header 'authorization: Basic xxxxxxxXXXXxxxxxxxxxxxxxxxxx' \
     --header 'content-type: application/json' \
     --data '{
  "invoice_currency": "INR",
  "amount": 10000,
  "transaction_description": "Test"
}'
```

***

## Step 2: Confirm the Payin

Confirm the payin to send a collect request to the customer's UPI app. Status moves to `requires_action`.

Pass the following in `payment_method_details`:

| Field            | Subfield      | Type   | Required | Description                                                                                               |
| ---------------- | ------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------- |
| `type`           |               | enum   | Yes      | Must be `upi_inr_native`                                                                                  |
| `upi_inr_native` |               | object | Yes      | UPI payment details                                                                                       |
|                  | `payer_vpa`   | string | Yes      | Customer's VPA (e.g., `test@bank`). Alphanumeric with `.` and `@` only — no spaces or special characters. |
| `items`          |               | array  | Yes      | List of items                                                                                             |
|                  | `name`        | string | Yes      | Item name                                                                                                 |
|                  | `description` | string | No       | Item description                                                                                          |
|                  | `amount`      | int64  | Yes      | Unit price                                                                                                |
|                  | `quantity`    | int64  | Yes      | Quantity                                                                                                  |

```bash theme={null}
curl --request POST \
     --url https://service-sandbox.tazapay.com/v3/payin/pay_cttprok2ukmk385sbfm0/confirm \
     --header 'accept: application/json' \
     --header 'authorization: Basic xxxxxxxXXXXxxxxxxxxxxxxxxxxx' \
     --header 'content-type: application/json' \
     --data '{
  "customer_details": {
    "name": "Andrea Lark",
    "email": "andrea@example.com",
    "country": "IN"
  },
  "items": [
    {
      "name": "Software Service for Antivirus",
      "description": "Firewall Antivirus",
      "amount": 10000,
      "quantity": 1
    }
  ],
  "payment_method_details": {
    "type": "upi_inr_native",
    "upi_inr_native": {
      "payer_vpa": "test@bank"
    }
  }
}'
```

<Accordion title="Combine Steps 1 & 2 into a single API call">
  Pass all parameters to the Create Payin endpoint along with `"confirm": true`.

  | Field     | Type    | Required | Description                    |
  | --------- | ------- | -------- | ------------------------------ |
  | `confirm` | boolean | Yes      | Confirms the payin on creation |

  ```bash theme={null}
  curl --request POST \
       --url https://service-sandbox.tazapay.com/v3/payin \
       --header 'accept: application/json' \
       --header 'authorization: Basic xxxxxxxXXXXxxxxxxxxxxxxxxxxx' \
       --header 'content-type: application/json' \
       --data '{
    "customer_details": {
      "name": "Andrea Lark",
      "email": "andrea@example.com",
      "country": "IN"
    },
    "items": [
      {
        "name": "Software Service for Antivirus",
        "description": "Firewall Antivirus",
        "amount": 10000,
        "quantity": 1
      }
    ],
    "confirm": true,
    "invoice_currency": "INR",
    "amount": 10000,
    "transaction_description": "test",
    "payment_method_details": {
      "type": "upi_inr_native",
      "upi_inr_native": {
        "payer_vpa": "test@bank"
      }
    }
  }'
  ```
</Accordion>

<Note>
  The collect request expires after **5 minutes**. If the customer does not approve within this window, re-confirm the payin (Step 2) to send a new request.
</Note>

***

## Step 3: Handle Post-Payment Events

Tazapay sends webhooks to your configured endpoint.

| Event                    | Description                     | Next Steps                                         |
| ------------------------ | ------------------------------- | -------------------------------------------------- |
| `payin.succeeded`        | Customer approved before expiry | Fulfill the order                                  |
| `payment_attempt.failed` | Request expired unapproved      | Re-confirm the payin to send a new collect request |

***

## Testing

| Scenario         | Action                                                                               |
| ---------------- | ------------------------------------------------------------------------------------ |
| Simulate success | Click **Simulate Success** on the `redirect_url` → receives `payin.succeeded`        |
| Simulate failure | Click **Simulate Failure** on the `redirect_url` → receives `payment_attempt.failed` |

***

## Refunds

`upi_inr_native` supports **partial refunds**.

<Tabs>
  <Tab title="Via Dashboard">
    Refer to the [refund guide](https://support.tazapay.com/how-do-i-request-a-refund-from-my-dashboard).
  </Tab>

  <Tab title="Via API">
    ```bash theme={null}
    curl --request POST \
         --url https://service-sandbox.tazapay.com/v3/refund \
         --header 'accept: application/json' \
         --header 'authorization: Basic xxxxxxxXXXXxxxxxxxxxxxxxxxxx' \
         --header 'content-type: application/json' \
         --data '{
      "payin": "pay_cmiiaamaq0pbt3fkadm0",
      "amount": 10000,
      "currency": "INR",
      "reason": "Customer Return"
    }'
    ```

    <Note>
      `amount` and `currency` are not required for a full refund.
    </Note>
  </Tab>
</Tabs>
