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

# UPI Intent

> PayCollect UPI Intent flow — minimal and enriched requests, initiation response (redirectUrl), post-success statusData, headers, and merchant callback.

## When to Use

Use **UPI Intent** when your merchant uses hosted PayCollect for **INR UPI** and wants PayGlocal to collect the approval flow on its hosted checkout. Your backend calls **[GPI (Checkout Flow)](/api-reference/payments-v2/paycollect/gpi)** (`POST /gl/v1/payments/initiate/paycollect`); the JSON body is the **payment intent**. PayGlocal returns a **hosted `redirectUrl`** so the shopper completes **UPI\_INTENT** via QR or in-flow approval.

<Note>
  This page documents **two response shapes** you will see in practice: (1) right after **initiation** — nested envelope with `redirectUrl` / `statusUrl` (session created, customer not finished); (2) after **successful authorization** on a status or payflow payload — `data.statusData` with `paymentMethod: "UPI_INTENT"` and UI-oriented blocks.
</Note>

## UPI (India)

Hosted PayCollect is the standard entry point for **UPI** in India: your server calls this endpoint with amount and callback URL, then sends the customer to `redirectUrl`. For the customer journey and funds flow see [UPI](/api-reference/payment/upi). This page covers UPI Intent request/response details, including optional `billingData` / `riskData` and the post-success `statusData` payload.

***

## Merchant Endpoint

| Environment | Base URL                       | Initiate (PayCollect)                      |
| ----------- | ------------------------------ | ------------------------------------------ |
| Sandbox     | `https://api.uat.payglocal.in` | `POST /gl/v1/payments/initiate/paycollect` |
| Production  | `https://api.payglocal.in`     | `POST /gl/v1/payments/initiate/paycollect` |

<Note>
  Traffic captured from **`gcc.uat.payglocal.in`** (merchant console “Test transaction”) may use a different path and **browser cookies**. For production integrations, call only **`api.uat.payglocal.in`** or **`api.payglocal.in`** with [RSA-signed JWS](/key-management/overview) in `x-gl-token-external`.
</Note>

***

## Request Body

The JSON is the **plaintext your client signs** (or wraps per your encryption settings). You can send a **minimal** body for UPI or add **`paymentData.billingData`** and **`riskData`** for richer risk scoring and display.

### Minimal (UPI-ready)

```json theme={null}
{
  "merchantTxnId": "23AEE8CB6B62EE2AF07",
  "paymentData": {
    "totalAmount": "10",
    "txnCurrency": "INR"
  },
  "merchantCallbackURL": "https://www.example.com/payglocal/callback"
}
```

### With optional billing and risk data

The example below matches a **fuller integration**: billing contact lines, customer history, line-item `orderData`, and `shippingData` (required patterns for some alternate payment methods may still apply globally—validate with your integration spec for UPI-only traffic).

```json theme={null}
{
  "merchantTxnId": "23AEE8CB6B62EE2AF07",
  "paymentData": {
    "totalAmount": "1044",
    "txnCurrency": "INR",
    "billingData": {
      "firstName": "TestName",
      "addressStreet1": "HelloAddress1",
      "addressStreet2": "Address2",
      "emailId": "test@payglocal.in",
      "callingCode": "+91",
      "phoneNumber": "9999999999"
    }
  },
  "riskData": {
    "customerData": {
      "merchantAssignedCustomerId": "11230092",
      "customerAccountType": "1",
      "customerSuccessOrderCount": "32",
      "customerAccountCreationDate": "20180412"
    },
    "orderData": [
      {
        "productDescription": "AppleAirPodsPro",
        "productSKU": "MNO00390",
        "productType": "Electronics",
        "itemUnitPrice": "12000.00",
        "itemQuantity": "1"
      },
      {
        "productDescription": "BeatsHeadphones",
        "productSKU": "MNO004929",
        "productType": "Electronics",
        "itemUnitPrice": "14000.00",
        "itemQuantity": "2"
      }
    ],
    "shippingData": {
      "firstName": "John",
      "lastName": "Doe",
      "addressStreet1": "福建省,福州市-鼓楼区,杨桥中路231号星城国际大厦824室",
      "addressStreet2": "Punctualitylane",
      "addressCity": "Bangalore",
      "addressState": "Karnataka",
      "addressPostalCode": "560094",
      "addressCountry": "IT",
      "emailId": "test@payglocal.in",
      "callingCode": "+91",
      "phoneNumber": "9999999999"
    }
  },
  "merchantCallbackURL": "https://www.example.com/payglocal/callback"
}
```

## What the fields mean (plain language)

* `merchantTxnId`: Your unique order reference. It appears in the hosted checkout, the `redirectUrl` session, and the callback so you can match UI screenshots and server logs to an order.
* `paymentData.totalAmount` / `paymentData.txnCurrency`: The amount and currency for this session (e.g. `1044` / `INR`).
* `paymentData.billingData`: Optional shopper contact and address lines used for receipts and richer display on the hosted page, and for fraud scoring when allowed.
* `riskData.customerData`: Merchant-provided signals about the shopper (merchant-assigned id, account age, successful-order count) used to improve risk decisions.
* `riskData.orderData`: Line items and unit prices to help reconciliation and give context to fraud engines.
* `riskData.shippingData`: Shipping/delivery address info; required for some alternate payment methods and uses ISO-style country codes for `addressCountry`.
* `merchantCallbackURL`: HTTPS endpoint PayGlocal POSTs to after checkout completes; verify the `x-gl-token` in the callback before trusting the payload (see [Payment Initiation Flow](/integration/payment-flow)).

***

## Response A — After initiation (session / QR phase)

Immediately after a successful **PayCollect** API call, the envelope may nest twice inside `data`. Use the **innermost** object for the hosted session links.

```json theme={null}
{
  "gid": "gl_9f9ff90dfc95c19a",
  "status": "SUCCESS",
  "message": "Got the response from txn server",
  "timestamp": "11/05/2026 14:26:52",
  "reasonCode": "GL-201-001",
  "data": {
    "gid": "gl_o-9f9ff90e82cfafb07515k0ZX2",
    "status": "INPROGRESS",
    "message": "Transaction Created Successfully",
    "timestamp": "11/05/2026 14:26:52",
    "reasonCode": "200",
    "data": {
      "redirectUrl": "https://api.uat.payglocal.in/gl/payflow-ui/?x-gl-token=eyJ...truncated",
      "statusUrl": "https://api.uat.payglocal.in/gl/v1/payments/gl_o-9f9ff90e82cfafb07515k0ZX2/status?x-gl-token=eyJ...truncated",
      "merchantTxnId": "23AEE8CB6B62EE2AF07"
    },
    "errors": null
  },
  "errors": null
}
```

* Outer `gid` / `status` / `reasonCode`: Outcome of the **initiate** HTTP call.
* `data.gid`: PayGlocal order / payflow id (`gl_o-...`) for the hosted session.
* `data.data.redirectUrl`: HTTP GET target for the browser; customer completes UPI here.
* `data.data.statusUrl`: Optional browser or integration URL carrying a status token; prefer server **Get Status** and validated callbacks for truth.
* `data.data.merchantTxnId`: Echo of your transaction id.

***

## Response B — After successful payment (status / payflow UI payload)

After the customer completes UPI and the transaction moves to a captured (or sent-for-capture) state, some responses return **`data.statusData`** — a **UI-oriented** block for confirmation screens and deep links. `paymentMethod` is set to **`UPI_INTENT`** for this rail.

```json theme={null}
{
  "gid": "gl_9fa080c916c547d2f37l2k0uQX2",
  "status": "200 OK",
  "message": "Transaction is sent_for_capture",
  "timestamp": "11/05/2026 15:59:45",
  "reasonCode": "GL-201-001",
  "data": {
    "statusData": {
      "headerInfo": {
        "mid": "nagsmiduat",
        "merchantTxnId": "23AEE8CB6B62EE2AF07",
        "merchantShortName": "PayGlocal",
        "merchantLogo": "null",
        "productDescription": null,
        "productData": null
      },
      "amountInfo": {
        "currency": "INR",
        "amount": "1044",
        "currencySymbol": "₹"
      },
      "themeInfo": null,
      "merchantCustomizedFlow": null,
      "dccInfo": null,
      "paymentMethod": "UPI_INTENT",
      "messageBlock": {
        "displayMessage": "Your transaction of SYMBOL AMOUNT CURRENCY was successful!",
        "reasonCode": "GL-201-001",
        "status": "SENT_FOR_CAPTURE",
        "message": null
      },
      "plData": null,
      "merchantCallback": "https://api.uat.payglocal.in/gl/v1/payments/merchantCallback?x-gl-token=eyJ...truncated",
      "isEmbedFlow": null,
      "forms": {}
    }
  },
  "errors": null
}
```

### How to read `statusData`

* `headerInfo`: Display metadata such as `mid`, `merchantTxnId`, and `merchantShortName` (optional logo/product fields appear when present).
* `amountInfo`: `amount`, `currency`, and `currencySymbol` for the success UI (e.g. ₹ + **1044** + INR).
* `paymentMethod`: `UPI_INTENT` identifies the rail used for this session.
* `messageBlock.displayMessage`: Template string for the success line; replace SYMBOL/AMOUNT/CURRENCY with `amountInfo` when rendering.
* `messageBlock.status`: Lifecycle state returned to the UI (e.g. `SENT_FOR_CAPTURE`).
* `messageBlock.reasonCode`: PayGlocal reason code aligned with the message (e.g. `GL-201-001`).
* `merchantCallback`: Full callback URL (including `x-gl-token`) for redirect-style handoff to your domain — treat the token as a secret and always validate server-side.
* `forms`: Reserved/extended fields; often an empty `{}` for standard UPI Intent.

<Warning>
  Never log or persist full **`x-gl-token`** values from `redirectUrl`, `statusUrl`, or `merchantCallback`. Truncate in logs and rotate sessions if a token leaks.
</Warning>

***

## HTTP Headers (server-to-server)

| Header                                               | Required? | Notes                                                                                                                |
| ---------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------- |
| `Content-Type`                                       | Yes       | `application/json` for JSON bodies (unless your client sends encrypted content per JWE setup).                       |
| `x-gl-token-external`                                | Yes       | RSA-signed **JWS** for the Payment API per [Key Management](/key-management/overview).                               |
| `x-gl-merchantid`, `x-gl-kid`                        | Often     | Added by official sample clients alongside signing.                                                                  |
| `:authority`, `:method`, `:path`, `:scheme`          | No        | HTTP/2 pseudo-headers set by the client stack.                                                                       |
| `cookie`, `origin`, `referer`, `sec-*`, `user-agent` | No        | Typical **browser-only** noise when copying DevTools from the GCC console—not part of your merchant server contract. |

***

## After `redirectUrl`

1. **HTTP GET** redirect the shopper to `redirectUrl` from Response A ([Payment Initiation Flow](/integration/payment-flow)).
2. Customer completes **UPI** on the hosted page.
3. PayGlocal **POSTs** to your `merchantCallbackURL` with **`x-gl-token`**; validate and show your confirmation page.
4. Use **[Get Transaction Status](/api-reference/payments-v2/common/get-transaction-status)** with the payflow / order `gid` whenever you need authoritative state.

***

## Error Scenarios

| Scenario                           | Typical signal               | Action                                                                         |
| ---------------------------------- | ---------------------------- | ------------------------------------------------------------------------------ |
| Initiate validation failure        | HTTP 4xx, `errors` populated | Fix body fields per OpenAPI / support feedback and retry.                      |
| Auth / signing failure             | HTTP 401                     | Check `x-gl-token-external`, key id, and clock skew.                           |
| Customer abandons hosted page      | No callback                  | Poll **Get Status** and expire your own checkout session.                      |
| Token validation fails on callback | Invalid `x-gl-token`         | Use **Get Status** with stored `gid` / `merchantTxnId` before showing success. |


## OpenAPI

````yaml POST /gl/v1/payments/initiate/paycollect
openapi: 3.0.3
info:
  title: PayCollect initiate — authorize (Payments V2)
  version: 1.0.0
  description: >-
    Payments V2 documentation slice. Production calls use `POST
    /gl/v1/payments/initiate/paycollect`.
servers:
  - url: https://api.payglocal.in
    description: Production
  - url: https://api.uat.payglocal.in
    description: Sandbox
security: []
paths:
  /gl/v1/payments/initiate/paycollect:
    post:
      tags:
        - Payment
      summary: PayCollect authorize payment — auth only (request body)
      description: >
        **Endpoint:** `POST /gl/v1/payments/initiate/paycollect` — same URL for
        GPI, on-demand SI, auto-debit, and authorize; only the request body
        differs.


        Hosted checkout — authorize without capture. Set `captureTxn: false`. No
        `cardData`, `tokenData`, or `standingInstruction`.

        **Cards and international Apple Pay only** — UPI and net banking are not
        supported for auth.
      operationId: paycollectInitiateAuth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionRequestPayCollectAuth'
            examples:
              auth_only:
                summary: Auth-only
                value:
                  merchantTxnId: 23AEE8CB6B62EE2AF07
                  merchantUniqueId: IFNN939494NJFJ
                  captureTxn: false
                  paymentData:
                    totalAmount: '10.00'
                    txnCurrency: INR
                    billingData:
                      firstName: John
                      lastName: Doe
                      addressStreet1: 221B Baker Street
                      addressCity: Bengaluru
                      addressCountry: IND
                      emailId: john.doe@example.com
                      callingCode: '+91'
                      phoneNumber: '9999999999'
                  merchantCallbackURL: >-
                    https://api.prod.payglocal.in/gl/v1/payments/merchantCallback
      responses:
        '200':
          description: >
            Returned immediately from initiate. Redirect the customer to
            `data.redirectUrl`, then poll `data.statusUrl` or [Get Transaction
            Status](/api-reference/payments-v2/common/get-transaction-status).
            Expect `AUTHORIZED` until you capture. **No `mandateId`** in `data`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponsePayCollectInitiate'
              example:
                gid: gl_o-a057c4d6b6c620741apzp0ZX2
                status: INPROGRESS
                message: Transaction Created Successfully
                timestamp: 02/06/2026 21:47:33
                reasonCode: '200'
                data:
                  redirectUrl: >-
                    https://api.uat.payglocal.in/gl/payflow-ui/?x-gl-token=example
                  statusUrl: >-
                    https://api.uat.payglocal.in/gl/v1/payments/gl_o-a057c4d6b6c620741apzp0ZX2/status?x-gl-token=example
                  merchantTxnId: 23AEE8CB6B62EE2AF07
                errors: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
        - JwsTokenAuth: []
components:
  schemas:
    TransactionRequestPayCollectAuth:
      allOf:
        - $ref: '#/components/schemas/PayCollectInitiateFieldsSI'
        - type: object
          description: >
            PayCollect auth-only initiate (`captureTxn` must be `false`).

            Do **not** send `cardData`, `tokenData`, or `standingInstruction` in
            the request body.

            Hosted checkout for auth supports **cards** and **international
            Apple Pay** only — **not** UPI or net banking.
          required:
            - merchantTxnId
            - paymentData
            - merchantCallbackURL
            - captureTxn
          properties:
            paymentData:
              $ref: '#/components/schemas/PaymentPayCollectInitiateHostedSI'
            captureTxn:
              type: boolean
              description: Must be `false` for authorise-only.
              enum:
                - false
    ApiResponsePayCollectInitiate:
      type: object
      description: Response envelope for PayCollect initiate (`200`).
      properties:
        gid:
          type: string
          description: PayGlocal transaction ID. Use for status, capture, and refund APIs.
          example: gl_9c2645ed09edb22e
        status:
          type: string
          description: >-
            High-level status. Typically `INPROGRESS` immediately after
            initiate.
          example: INPROGRESS
        message:
          type: string
          description: Human-readable status message.
          example: Transaction Created Successfully
        timestamp:
          type: string
          description: Response timestamp (`DD/MM/YYYY HH:MM:SS`).
          example: 02/06/2026 21:47:33
        reasonCode:
          type: string
          description: >-
            Success code on initiate (e.g. `200`). See `4xx` responses for error
            codes.
          example: '200'
        data:
          $ref: '#/components/schemas/InitiateResponseDataPayCollect'
        errors:
          type: object
          nullable: true
          description: '`null` on success.'
          additionalProperties:
            type: string
    PayCollectInitiateFieldsSI:
      type: object
      properties:
        merchantTxnId:
          type: string
          description: Merchant's unique transaction identifier. Alphanumeric only.
          minLength: 4
          maxLength: 50
          example: 23AEE8CB6B62EE2AF07
        merchantUniqueId:
          type: string
          description: >-
            Optional stable merchant-side ID for idempotency and reconciliation.
            Alphanumeric only.
          minLength: 15
          maxLength: 40
          example: IFNN939494NJFJ
        riskData:
          allOf:
            - $ref: '#/components/schemas/Risk'
          description: Recommended for fraud checks and processor compliance.
        merchantCallbackURL:
          type: string
          format: uri
          description: Customers are redirected here post payment completion.
          example: https://api.prod.payglocal.in/gl/v1/payments/merchantCallback
    PaymentPayCollectInitiateHostedSI:
      type: object
      description: >
        Hosted checkout payment details for PayCollect standing instruction
        registration.

        Do **not** send `cardData`, `tokenData`, or `authenticationData` — the
        customer registers the mandate on `redirectUrl`.
      required:
        - totalAmount
        - txnCurrency
      properties:
        totalAmount:
          type: string
          description: >-
            Transaction amount as a decimal string. Supports up to 4 decimal
            places.
          example: '10.00'
        txnCurrency:
          type: string
          description: >-
            ISO 4217 currency code. Must be uppercase (e.g. `INR`, `USD`,
            `EUR`).
          example: INR
        billingData:
          allOf:
            - $ref: '#/components/schemas/Billing'
          description: >
            Cardholder billing address. Required for digital product / service
            transactions

            and flight bookings. Preferred for all other transaction types.
    InitiateResponseDataPayCollect:
      type: object
      properties:
        redirectUrl:
          type: string
          format: uri
          description: >-
            Hosted checkout URL — redirect the customer's browser here via
            **HTTP GET** to complete payment.
          example: https://api.uat.payglocal.in/gl/payflow-ui/?x-gl-token=example
        statusUrl:
          type: string
          format: uri
          description: >-
            Pre-authenticated URL to poll status after the customer completes
            payment.
          example: >-
            https://api.uat.payglocal.in/gl/v1/payments/gl_9c2645ed09edb22e/status?x-gl-token=example
        merchantTxnId:
          type: string
          description: Echo of `merchantTxnId` from the initiate request body.
          example: order_1712345678
    CommonErrorResponse:
      type: object
      properties:
        gid:
          type: string
          example: gl_9c2645ed09edb22e
        timestamp:
          type: string
          example: 10/01/2026 15:00:00
        reasonCode:
          type: string
          example: VALIDATION_ERROR
        data:
          type: object
        errors:
          type: object
        errorDetails:
          type: array
          items:
            $ref: '#/components/schemas/ErrorDetail'
    Risk:
      type: object
      description: Risk & analytics payload forwarded to fraud engines.
      properties:
        customerData:
          $ref: '#/components/schemas/Customer'
        shippingData:
          $ref: '#/components/schemas/Shipping'
        orderData:
          type: array
          items:
            $ref: '#/components/schemas/RiskItem'
    Billing:
      type: object
      description: Billing address + contact details of the payer.
      properties:
        firstName:
          type: string
          example: John
        lastName:
          type: string
          example: Doe
        emailId:
          type: string
          format: email
          example: john.doe@example.com
        callingCode:
          type: string
          example: '+91'
        phoneNumber:
          type: string
          example: '9999999999'
        addressStreet1:
          type: string
          example: 221B Baker Street
        addressStreet2:
          type: string
        addressCity:
          type: string
          example: Bengaluru
        addressState:
          type: string
          example: Karnataka
        addressStateCode:
          type: string
          example: KA
        addressPostalCode:
          type: string
          example: '560001'
        addressCountry:
          type: string
          description: ISO 3166-1 alpha-3 country code.
          example: IND
    ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: Name of the field that failed validation.
          example: panNumber
        message:
          type: string
          description: Human-readable error message.
          example: Required field is missing
    Customer:
      type: object
      description: Payer identity for risk evaluation.
      properties:
        merchantAssignedCustomerId:
          type: string
          example: cust_12345
        firstName:
          type: string
        lastName:
          type: string
        emailId:
          type: string
          format: email
        callingCode:
          type: string
        mobileNumber:
          type: string
    Shipping:
      type: object
      description: Shipping address for physical-goods orders.
      properties:
        firstName:
          type: string
        lastName:
          type: string
        emailId:
          type: string
          format: email
        addressStreet1:
          type: string
        addressStreet2:
          type: string
        addressCity:
          type: string
        addressState:
          type: string
        addressPostalCode:
          type: string
        addressCountry:
          type: string
          example: IND
    RiskItem:
      type: object
      description: Single line-item in the cart for risk analytics.
      properties:
        itemId:
          type: string
        itemName:
          type: string
        itemQuantity:
          type: integer
        itemPrice:
          type: string
        itemCategory:
          type: string
  responses:
    BadRequest:
      description: Validation error — missing or invalid fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CommonErrorResponse'
          examples:
            validationError:
              summary: Validation error example
              value:
                gid: gl_9c2645ed09edb22e
                timestamp: 10/01/2026 15:00:00
                reasonCode: VALIDATION_ERROR
                data: {}
                errors: null
                errorDetails:
                  - fieldName: paymentData.totalAmount
                    message: This field is required
    Unauthorized:
      description: Authentication failed — invalid API key or digest.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CommonErrorResponse'
          examples:
            unauthorizedError:
              summary: Unauthorized error example
              value:
                gid: gl_9c2645ed09edb22e
                timestamp: 10/01/2026 15:00:00
                reasonCode: UNAUTHORIZED
                data: {}
                errors: null
                errorDetails:
                  - fieldName: authorization
                    message: Invalid x-gl-token-external
  securitySchemes:
    JwsTokenAuth:
      type: apiKey
      in: header
      name: x-gl-token-external
      description: >
        RSA-signed JWS (JSON Web Signature) token carrying the request payload.

        - Header: `{ "alg": "RS256", "kid": "<merchant-key-id>", "iss":
        "<merchant-id>", "x-gl-enc": "false", "is-digested": "true" }`

        - Payload: the exact JSON body sent in the request (or its SHA-256
        digest when `is-digested=true`).

        - Signed with the merchant's RSA private key; PayGlocal verifies with
        the matching public key.

        Used by all `/gl/v1/payments/*` endpoints.

````