curl --request GET \
--url https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/ \
--header 'X-API-Version: <api-key>' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--header 'X-Merchant-ID: <api-key>'import requests
url = "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
headers = {
"X-Client-ID": "<api-key>",
"X-Client-Secret": "<api-key>",
"X-Merchant-ID": "<api-key>",
"X-API-Version": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-Client-ID': '<api-key>',
'X-Client-Secret': '<api-key>',
'X-Merchant-ID': '<api-key>',
'X-API-Version': '<api-key>'
}
};
fetch('https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Version: <api-key>",
"X-Client-ID: <api-key>",
"X-Client-Secret: <api-key>",
"X-Merchant-ID: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Client-ID", "<api-key>")
req.Header.Add("X-Client-Secret", "<api-key>")
req.Header.Add("X-Merchant-ID", "<api-key>")
req.Header.Add("X-API-Version", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/")
.header("X-Client-ID", "<api-key>")
.header("X-Client-Secret", "<api-key>")
.header("X-Merchant-ID", "<api-key>")
.header("X-API-Version", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Client-ID"] = '<api-key>'
request["X-Client-Secret"] = '<api-key>'
request["X-Merchant-ID"] = '<api-key>'
request["X-API-Version"] = '<api-key>'
response = http.request(request)
puts response.read_bodyGet Verification Requirements
Everything a payment’s checklist calls for — every field and document, which are satisfied, and what state the payment itself is in.
curl --request GET \
--url https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/ \
--header 'X-API-Version: <api-key>' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--header 'X-Merchant-ID: <api-key>'import requests
url = "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
headers = {
"X-Client-ID": "<api-key>",
"X-Client-Secret": "<api-key>",
"X-Merchant-ID": "<api-key>",
"X-API-Version": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'X-Client-ID': '<api-key>',
'X-Client-Secret': '<api-key>',
'X-Merchant-ID': '<api-key>',
'X-API-Version': '<api-key>'
}
};
fetch('https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Version: <api-key>",
"X-Client-ID: <api-key>",
"X-Client-Secret: <api-key>",
"X-Merchant-ID: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-Client-ID", "<api-key>")
req.Header.Add("X-Client-Secret", "<api-key>")
req.Header.Add("X-Merchant-ID", "<api-key>")
req.Header.Add("X-API-Version", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/")
.header("X-Client-ID", "<api-key>")
.header("X-Client-Secret", "<api-key>")
.header("X-Merchant-ID", "<api-key>")
.header("X-API-Version", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-Client-ID"] = '<api-key>'
request["X-Client-Secret"] = '<api-key>'
request["X-Merchant-ID"] = '<api-key>'
request["X-API-Version"] = '<api-key>'
response = http.request(request)
puts response.read_bodyOverview
Returns the verification requirements for one payment: every field and document its checklist calls for, which are already satisfied, and which are still outstanding. The checklist is chosen by two facts on the order — its business model and its purpose code. Until both are declared no checklist claims the payment, and this endpoint asks for them instead. TheLRS_VERIFICATION_NEEDED webhook lists what a payment is missing. This returns the whole set. Both describe the same items in the same shape, from the same read — an entry here is an entry there plus satisfied and provided.
When to use it
You missed an event
settlement_status, which tells you whether sending anything is still possible.You need the whole set
You are resuming
You are building the form
fields and documents describe the whole set, satisfied or not, with a message per item safe to show a payer. Filter on satisfied for what is still owed.Response
Complete, unedited responses: an education payment (S0305) with nothing supplied yet, a payment nothing has classified, and a travel payment whose documents include waivable ones.
{
"success": true,
"message": "Verification requirements",
"data": {
"payment_id": "PR6938527534",
"order_id": "OD3376378679",
"settlement_status": "ACTION_REQUIRED",
"business_model": "B2C",
"purpose_code": "S0305",
"fields": [
{
"code": "buyer_name",
"message": "Buyer / remitter name",
"satisfied": false,
"provided": false
},
{
"code": "buyer_address_line_1",
"message": "Buyer address line 1",
"satisfied": false,
"provided": false
},
{
"code": "buyer_city",
"message": "Buyer city",
"satisfied": false,
"provided": false
},
{
"code": "buyer_state",
"message": "Buyer state",
"satisfied": false,
"provided": false
},
{
"code": "buyer_postal_code",
"message": "Buyer PIN code",
"satisfied": false,
"provided": false
},
{
"code": "buyer_email",
"message": "Buyer email",
"satisfied": false,
"provided": false
},
{
"code": "buyer_phone",
"message": "Buyer phone",
"satisfied": false,
"provided": false
},
{
"code": "invoice_number",
"message": "Invoice number",
"satisfied": false,
"provided": false
},
{
"code": "invoice_date",
"message": "Invoice date",
"satisfied": false,
"provided": false
},
{
"code": "remitter_pan",
"message": "Remitter PAN",
"satisfied": false,
"provided": false
},
{
"code": "remitter_dob",
"message": "Remitter date of birth (as per PAN)",
"satisfied": false,
"provided": false
},
{
"code": "remitter_relation",
"message": "Remitter's relation to the person the remittance is for",
"satisfied": false,
"provided": false
},
{
"code": "buyer_declaration",
"message": "The LRS declaration the payer affirms: resident in India, within the LRS limit, permitted purpose",
"satisfied": false,
"provided": false
},
{
"code": "amount_to_be_settled",
"message": "Amount to be settled for this payment, in INR",
"satisfied": false,
"provided": false
},
{
"code": "student_name",
"message": "Name of the student the remittance is for",
"satisfied": true,
"provided": false,
"condition": "PAYING_FOR_SOMEONE_ELSE"
},
{
"code": "student_dob",
"message": "Date of birth of the student the remittance is for",
"satisfied": true,
"provided": false,
"condition": "PAYING_FOR_SOMEONE_ELSE"
},
{
"code": "student_passport_number",
"message": "Passport number of the student the remittance is for",
"satisfied": true,
"provided": false,
"condition": "PAYING_FOR_SOMEONE_ELSE"
}
],
"documents": [
{
"code": "relationship_declaration",
"message": "Self-declaration of the remitter's relationship to the person the remittance is for",
"satisfied": true,
"provided": false,
"condition": "PAYING_FOR_SOMEONE_ELSE"
},
{
"code": "offer_letter",
"message": "Letter of admission from the institution",
"satisfied": false,
"provided": false
},
{
"code": "passport",
"message": "Student's passport",
"satisfied": false,
"provided": false
},
{
"code": "student_id_or_visa",
"message": "Student visa or university ID card (either)",
"satisfied": false,
"provided": false
},
{
"code": "fee_invoice",
"message": "Fee invoice",
"satisfied": true,
"provided": false,
"optional": true
}
]
}
}
{
"success": true,
"message": "Verification requirements",
"data": {
"payment_id": "PR4471903288",
"order_id": "OD9925177340",
"settlement_status": "ACTION_REQUIRED",
"business_model": null,
"purpose_code": null,
"fields": [
{
"code": "business_model",
"message": "Business model (B2B or B2C)",
"satisfied": false,
"provided": false
},
{
"code": "purpose_code",
"message": "FEMA/FETERS purpose code for this order",
"satisfied": false,
"provided": false
}
],
"documents": []
}
}
{
"success": true,
"message": "Verification requirements",
"data": {
"payment_id": "PR7042318866",
"order_id": "OD8451220934",
"settlement_status": "ACTION_REQUIRED",
"business_model": "B2C",
"purpose_code": "S0306",
"fields": ["… the same buyer, invoice, remitter and amount fields as S0305, minus the student ones …"],
"documents": [
{
"code": "relationship_declaration",
"message": "Self-declaration of the remitter's relationship to the person the remittance is for",
"satisfied": true,
"provided": false,
"condition": "PAYING_FOR_SOMEONE_ELSE"
},
{
"code": "passenger_list",
"message": "Passenger list — name and passport number of every traveller",
"satisfied": false,
"provided": false
},
{
"code": "traveller_passports",
"message": "Passports of all travellers",
"satisfied": false,
"provided": false
},
{
"code": "traveller_visas",
"message": "Visas of all travellers",
"satisfied": false,
"provided": false,
"waivable": true
},
{
"code": "ticket",
"message": "Travel tickets",
"satisfied": false,
"provided": false,
"waivable": true
},
{
"code": "invoice",
"message": "Invoice for the trip",
"satisfied": false,
"provided": false
}
]
}
}
business_model and purpose_code come back null, and the two facts that would resolve them are listed as ordinary outstanding fields — same shape as any other entry. Send them back under those codes and the real checklist appears on the next call.Reading the response
The payment
payment_id in this endpoint’s own path.| Value | What it means for you |
|---|---|
ACTION_REQUIRED | The payment is waiting on you. Send what is outstanding. |
INFO_PENDING | The same, earlier in the flow — nothing has been filed yet. |
UNDER_REVIEW | Filed and with us. Sending is closed — see below. |
VERIFIED · READY_FOR_SETTLEMENT · SETTLED | Past verification. Sending is closed. |
EXPIRED · REJECTED · ON_HOLD | The payment did not proceed. Nothing you send reopens it. |
NOT_APPLICABLE, PAYMENT_PENDING, PAYMENT_FAILED or SETTLEMENT_ERROR — states in which no verification is being asked of you.Once the verification has been filed, staging closes: a POST to this path is refused rather than half-applied, because the staged rows are the record of what actually went to the gateway. UNDER_REVIEW, VERIFIED, READY_FOR_SETTLEMENT and SETTLED are the four states where that is true. Read this key before you send, and you will not collect a refusal you had no way to see coming.B2B or B2C, or null while nothing has declared it.null while none is declared.The items
There is one list per kind, holding the whole set. There is no separate “missing” array — what is still owed is a filter:const outstanding = data.fields.filter(f => !f.satisfied)
fields and documents carries code, message, satisfied and provided. The remaining keys appear only when they apply, so their absence is meaningful: no optional key means the item is required, no waivable key means it cannot be waived.
fields, or as a document’s code. See Submit Verification Details.buyer_declaration it is the wording the payer must be shown before affirming.The same key on a submit-failure event carries a sentence about what went wrong instead. One key, always the plainest thing there is to say about the item.false is what “missing” means.An optional item is satisfied from the very first response, and a conditional item whose condition does not hold is satisfied vacuously. Neither blocks completion.satisfied:satisfied | provided | Means |
|---|---|---|
false | false | Owed. Send it. |
true | true | Done. |
true | false | Nothing owed, nothing sent — an optional item, or a conditional one that does not apply to this payment. |
satisfied alone is not enough. To offer optionals to a payer as well as chase what is owed, widen the filter:const offerable = data.documents.filter(
d => !d.satisfied || (d.optional && !d.provided)
)
true, on items that never block completion. Absent on required items — there is no "optional": false.An optional item is listed until you supply it, because an optional document nobody is told about is one nobody sends.| Value | Owed when |
|---|---|
PAYING_FOR_SOMEONE_ELSE | remitter_relation is declared as anything other than SELF. |
PHYSICAL_GOODS_ONLY | The order ships physical goods. |
satisfied: true, provided: false. It is still listed, so you know it exists.true, on documents you may discharge with a waiver_reason instead of a file — a visa the destination does not require, a ticket not yet issued.A waivable document stays satisfied: false until you either upload it or record a waiver. The waiver is yours to declare, not ours to assume.student_id_or_visa). The key is part of the contract because a future revision may split such a pair, and an integration that reads it will absorb that without a release.What was sent under a document code
An entry indocuments carries three more keys once a row exists for that code. They are absent while the slot is untouched, so their presence is itself the signal that something is held. ref needs a file; doc_status does not — a slot discharged by a waiver is a stored row with no file, and reads PENDING with no ref:
{
"code": "offer_letter",
"message": "Letter of admission from the institution",
"satisfied": false,
"provided": true,
"ref": "6757940683",
"doc_status": "REJECTED",
"rejection_reason": "Letter is for the wrong intake term."
}
ref you submitted. Present only once a file has been sent under this code: a replacement upload supersedes the older row, so this always names the current file.PENDING (not reviewed individually), VERIFIED (accepted) or REJECTED (refused — replace it). Present once a row exists for the slot, including one discharged by a waiver — that row has no file, so it reads PENDING and carries no ref.It is not a synonym for satisfied. satisfied says whether the checklist item blocks completion; doc_status says what a reviewer made of the file.fields never carry them — a field has no file and no reviewer mark — and the B2B goods and B2B services responses are unchanged. The same three keys appear on document entries in LRS_VERIFICATION_NEEDED and VERIFICATION_STATUS, with the same meanings.No status, deliberately
Earlier versions returned a rolled-up status of complete / incomplete / not_applicable. It is gone, for two reasons:
- It answered the wrong question. “Every box is ticked” is not “the payment passed”. A payment can be complete on its checklist and still be refused at the gateway — a PAN that will not verify, a sender who is not the account holder, a credit that does not cover the amount.
- It collided. The
POSTon this same URL returns astatustoo, and there the word reports what the gateway did. One word, two meanings, same path.
const complete = [...data.fields, ...data.documents].every(i => i.satisfied)
settlement_status, the submit response, or LRS_VERIFICATION_NEEDED.
GET never verifies a PAN, posts to an LRS counter or moves a payment; it reports the requirement set and what has been collected against it.Errors
Every refusal is a400; the code inside the envelope is what tells them apart.
error.code | When |
|---|---|
40360 | No such payment for this merchant. The same answer whether it does not exist or belongs to someone else, so the endpoint never confirms another merchant’s payment id. |
40359 | The payment is classified, but no checklist covers that business model and purpose code — there is nothing to report. An unclassified payment is not this case: it answers 200, asking for the two classifying facts. |
What each checklist asks for
The exact set is always what this endpoint returns — this is a summary, and a revision lands there before it lands in any table.Every checklist starts here
Buyer and invoice basics, read straight off the order:buyer_name · buyer_address_line_1 · buyer_city · buyer_state · buyer_postal_code · buyer_email · buyer_phone · invoice_number · invoice_date
The one exception is the light B2C set (S0101, S0802, S0301), which asks for buyer_name and an optional invoice, and nothing else.
LRS checklists
S0305, S1107, S0303, S0304 and S0306 add the remitter’s verified identity, the declaration and the amounts:
| Code | Asks for |
|---|---|
remitter_pan | Remitter PAN |
remitter_dob | Remitter date of birth, as per PAN |
remitter_relation | SELF · PARENT · GUARDIAN · SPOUSE · SIBLING · OTHER |
buyer_declaration | One affirmation covering all three LRS claims — send true once the payer has affirmed the wording in message |
amount_to_be_settled | The amount to settle for this payment, in INR |
| Who the money is for | Conditional: owed once remitter_relation is not SELF. Education codes ask for student_name · student_dob (· student_passport_number on S0305); travel codes ask for primary_person_name · primary_person_dob · primary_person_passport_number |
| Document code | S0305 | S1107 | S0303 · S0304 · S0306 |
|---|---|---|---|
offer_letter — letter of admission | required | required | — |
passport — student’s passport | required | — | — |
student_id_or_visa — student visa or university ID card | required | — | — |
student_id — university ID card | — | required | — |
fee_invoice | optional | optional | — |
passenger_list | — | — | required |
traveller_passports | — | — | required |
traveller_visas | — | — | required, waivable |
ticket | — | — | required, waivable |
invoice — invoice for the trip | — | — | required |
relationship_declaration | conditional | conditional | conditional |
student_id_or_visa is one code that accepts either document. Upload a visa or a university ID card under this single code — there is no separate student_visa or university_id_card to send, and no alternative group to reconcile. S1107 has no travel leg, so no visa exists and the university ID stands alone as student_id.B2B checklists
| Code | Extra fields | Documents |
|---|---|---|
S0101 — goods | product_description, iec, and hs_code (conditional: physical goods) | invoice |
S0802 · S0803 · S1005 · S1009 · S1010 · S1013 · S1015 · S1016 · S1017 · S1105 · S1106 — services | none | invoice |
The requirement set can grow
Answering one requirement can reveal another. Declaringremitter_relation as anything other than SELF flips the fields naming the person the money is for — student_* on the education codes, primary_person_* on the travel ones — and the relationship self-declaration to satisfied: false, because they are only owed in that case.
This is expected. Re-read fields and documents after every write rather than assuming the list you started with is final.
Related
Submit Verification Details
Upload Document
ref a document entry needs.LRS_VERIFICATION_NEEDED
Quote LRS Amount
Authorizations
Client Application ID - Your unique application identifier used to authenticate API requests. You can find your Client ID in the Developer Settings section of the merchant dashboard.
Client Secret Key - Your secret key used alongside the Client ID for secure authentication. Keep this confidential and never expose it in client-side code. Available in the Developer Settings section of the merchant dashboard.
Merchant Identifier - The unique ID for the merchant account. This is required for PSP (Payment Service Provider) merchants who manage multiple merchant accounts. You can find merchant IDs in the Merchant Management section of the dashboard.
API Version - Specifies which version of the API to use (e.g., '1.X.X', '2.X.X', or '3.X.X'). This header allows you to control which API version your integration uses. Default version information is available in the Developer Settings.
Path Parameters
UID of the payment the details are for.
Response
The payment's checklist and the current state of each item.
true
"Verification requirements"
What a payment needs and what it already has — the whole checklist, unlike the LRS_VERIFICATION_NEEDED webhook, which lists only what is outstanding. There is deliberately no rolled-up completion field: each item carries its own satisfied, and settlement_status reports where the payment itself stands.
Show child attributes
Show child attributes