UPI Intent
PayCollect UPI Intent flow — minimal and enriched requests, initiation response (redirectUrl), post-success statusData, headers, and merchant callback.
curl --request POST \
--url https://api.payglocal.in/gl/v1/payments/initiate/paycollect \
--header 'Content-Type: application/json' \
--header 'x-gl-token-external: <api-key>' \
--data '
{
"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"
}
'import requests
url = "https://api.payglocal.in/gl/v1/payments/initiate/paycollect"
payload = {
"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"
}
headers = {
"x-gl-token-external": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://api.payglocal.in/gl/v1/payments/initiate/paycollect")
.header("x-gl-token-external", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"merchantTxnId\": \"23AEE8CB6B62EE2AF07\",\n \"merchantUniqueId\": \"IFNN939494NJFJ\",\n \"captureTxn\": false,\n \"paymentData\": {\n \"totalAmount\": \"10.00\",\n \"txnCurrency\": \"INR\",\n \"billingData\": {\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"addressStreet1\": \"221B Baker Street\",\n \"addressCity\": \"Bengaluru\",\n \"addressCountry\": \"IND\",\n \"emailId\": \"john.doe@example.com\",\n \"callingCode\": \"+91\",\n \"phoneNumber\": \"9999999999\"\n }\n },\n \"merchantCallbackURL\": \"https://api.prod.payglocal.in/gl/v1/payments/merchantCallback\"\n}")
.asString();const url = 'https://api.payglocal.in/gl/v1/payments/initiate/paycollect';
const options = {
method: 'POST',
headers: {'x-gl-token-external': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
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'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));{
"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
}{
"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"
}
]
}{
"gid": "gl_9c2645ed09edb22e",
"timestamp": "10/01/2026 15:00:00",
"reasonCode": "UNAUTHORIZED",
"data": {},
"errors": null,
"errorDetails": [
{
"fieldName": "authorization",
"message": "Invalid x-gl-token-external"
}
]
}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) (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.
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.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 toredirectUrl. For the customer journey and funds flow see 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 |
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 in x-gl-token-external.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 addpaymentData.billingData and riskData for richer risk scoring and display.
Minimal (UPI-ready)
{
"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-itemorderData, and shippingData (required patterns for some alternate payment methods may still apply globally—validate with your integration spec for UPI-only traffic).
{
"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, theredirectUrlsession, 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 foraddressCountry.merchantCallbackURL: HTTPS endpoint PayGlocal POSTs to after checkout completes; verify thex-gl-tokenin the callback before trusting the payload (see Payment Initiation Flow).
Response A — After initiation (session / QR phase)
Immediately after a successful PayCollect API call, the envelope may nest twice insidedata. Use the innermost object for the hosted session links.
{
"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 returndata.statusData — a UI-oriented block for confirmation screens and deep links. paymentMethod is set to UPI_INTENT for this rail.
{
"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 asmid,merchantTxnId, andmerchantShortName(optional logo/product fields appear when present).amountInfo:amount,currency, andcurrencySymbolfor the success UI (e.g. ₹ + 1044 + INR).paymentMethod:UPI_INTENTidentifies the rail used for this session.messageBlock.displayMessage: Template string for the success line; replace SYMBOL/AMOUNT/CURRENCY withamountInfowhen 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 (includingx-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.
x-gl-token values from redirectUrl, statusUrl, or merchantCallback. Truncate in logs and rotate sessions if a token leaks.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. |
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
- HTTP GET redirect the shopper to
redirectUrlfrom Response A (Payment Initiation Flow). - Customer completes UPI on the hosted page.
- PayGlocal POSTs to your
merchantCallbackURLwithx-gl-token; validate and show your confirmation page. - Use Get Transaction Status with the payflow / order
gidwhenever 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. |
Authorizations
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.
Body
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.
Merchant's unique transaction identifier. Alphanumeric only.
4 - 50"23AEE8CB6B62EE2AF07"
Customers are redirected here post payment completion.
"https://api.prod.payglocal.in/gl/v1/payments/merchantCallback"
Hosted checkout payment details for PayCollect standing instruction registration.
Do not send cardData, tokenData, or authenticationData — the customer registers the mandate on redirectUrl.
Show child attributes
Show child attributes
Must be false for authorise-only.
false Optional stable merchant-side ID for idempotency and reconciliation. Alphanumeric only.
15 - 40"IFNN939494NJFJ"
Recommended for fraud checks and processor compliance.
Show child attributes
Show child attributes
Response
Returned immediately from initiate. Redirect the customer to data.redirectUrl, then poll data.statusUrl or Get Transaction Status. Expect AUTHORIZED until you capture. No mandateId in data.
Response envelope for PayCollect initiate (200).
PayGlocal transaction ID. Use for status, capture, and refund APIs.
"gl_9c2645ed09edb22e"
High-level status. Typically INPROGRESS immediately after initiate.
"INPROGRESS"
Human-readable status message.
"Transaction Created Successfully"
Response timestamp (DD/MM/YYYY HH:MM:SS).
"02/06/2026 21:47:33"
Success code on initiate (e.g. 200). See 4xx responses for error codes.
"200"
Show child attributes
Show child attributes
null on success.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.payglocal.in/gl/v1/payments/initiate/paycollect \
--header 'Content-Type: application/json' \
--header 'x-gl-token-external: <api-key>' \
--data '
{
"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"
}
'import requests
url = "https://api.payglocal.in/gl/v1/payments/initiate/paycollect"
payload = {
"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"
}
headers = {
"x-gl-token-external": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://api.payglocal.in/gl/v1/payments/initiate/paycollect")
.header("x-gl-token-external", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"merchantTxnId\": \"23AEE8CB6B62EE2AF07\",\n \"merchantUniqueId\": \"IFNN939494NJFJ\",\n \"captureTxn\": false,\n \"paymentData\": {\n \"totalAmount\": \"10.00\",\n \"txnCurrency\": \"INR\",\n \"billingData\": {\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"addressStreet1\": \"221B Baker Street\",\n \"addressCity\": \"Bengaluru\",\n \"addressCountry\": \"IND\",\n \"emailId\": \"john.doe@example.com\",\n \"callingCode\": \"+91\",\n \"phoneNumber\": \"9999999999\"\n }\n },\n \"merchantCallbackURL\": \"https://api.prod.payglocal.in/gl/v1/payments/merchantCallback\"\n}")
.asString();const url = 'https://api.payglocal.in/gl/v1/payments/initiate/paycollect';
const options = {
method: 'POST',
headers: {'x-gl-token-external': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
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'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));{
"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
}{
"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"
}
]
}{
"gid": "gl_9c2645ed09edb22e",
"timestamp": "10/01/2026 15:00:00",
"reasonCode": "UNAUTHORIZED",
"data": {},
"errors": null,
"errorDetails": [
{
"fieldName": "authorization",
"message": "Invalid x-gl-token-external"
}
]
}
