curl --request POST \
--url https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/ \
--header 'Content-Type: application/json' \
--header 'X-API-Version: <api-key>' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--header 'X-Merchant-ID: <api-key>' \
--data '
{
"fields": {
"buyer_name": "Northwind Technologies Pvt Ltd",
"buyer_address_line_1": "7th Floor, Prestige Tower, Residency Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560025",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"invoice_amount": "125000.00",
"declaration": true
},
"documents": [
{
"code": "invoice",
"ref": "8207383264"
}
],
"finalize": true
}
'import requests
url = "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
payload = {
"fields": {
"buyer_name": "Northwind Technologies Pvt Ltd",
"buyer_address_line_1": "7th Floor, Prestige Tower, Residency Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560025",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"invoice_amount": "125000.00",
"declaration": True
},
"documents": [
{
"code": "invoice",
"ref": "8207383264"
}
],
"finalize": True
}
headers = {
"X-Client-ID": "<api-key>",
"X-Client-Secret": "<api-key>",
"X-Merchant-ID": "<api-key>",
"X-API-Version": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-ID': '<api-key>',
'X-Client-Secret': '<api-key>',
'X-Merchant-ID': '<api-key>',
'X-API-Version': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: {
buyer_name: 'Northwind Technologies Pvt Ltd',
buyer_address_line_1: '7th Floor, Prestige Tower, Residency Road',
buyer_city: 'Bengaluru',
buyer_state: 'Karnataka',
buyer_postal_code: '560025',
buyer_email: '[email protected]',
buyer_phone: '+919876543210',
invoice_number: 'INV-2026-0041',
invoice_date: '2026-08-01',
invoice_amount: '125000.00',
declaration: true
},
documents: [{code: 'invoice', ref: '8207383264'}],
finalize: true
})
};
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 => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fields' => [
'buyer_name' => 'Northwind Technologies Pvt Ltd',
'buyer_address_line_1' => '7th Floor, Prestige Tower, Residency Road',
'buyer_city' => 'Bengaluru',
'buyer_state' => 'Karnataka',
'buyer_postal_code' => '560025',
'buyer_email' => '[email protected]',
'buyer_phone' => '+919876543210',
'invoice_number' => 'INV-2026-0041',
'invoice_date' => '2026-08-01',
'invoice_amount' => '125000.00',
'declaration' => true
],
'documents' => [
[
'code' => 'invoice',
'ref' => '8207383264'
]
],
'finalize' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
payload := strings.NewReader("{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
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>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("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>")
.header("Content-Type", "application/json")
.body("{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}")
.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::Post.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>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "incomplete",
"outstanding": [
"invoice_number",
"invoice_date",
"invoice"
]
}
}Submit LRS Verification Details
What an LRS payment is asked for, and how to send it — the remitter’s identity, the declarations, and the documents its purpose code requires.
curl --request POST \
--url https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/ \
--header 'Content-Type: application/json' \
--header 'X-API-Version: <api-key>' \
--header 'X-Client-ID: <api-key>' \
--header 'X-Client-Secret: <api-key>' \
--header 'X-Merchant-ID: <api-key>' \
--data '
{
"fields": {
"buyer_name": "Northwind Technologies Pvt Ltd",
"buyer_address_line_1": "7th Floor, Prestige Tower, Residency Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560025",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"invoice_amount": "125000.00",
"declaration": true
},
"documents": [
{
"code": "invoice",
"ref": "8207383264"
}
],
"finalize": true
}
'import requests
url = "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
payload = {
"fields": {
"buyer_name": "Northwind Technologies Pvt Ltd",
"buyer_address_line_1": "7th Floor, Prestige Tower, Residency Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560025",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"invoice_amount": "125000.00",
"declaration": True
},
"documents": [
{
"code": "invoice",
"ref": "8207383264"
}
],
"finalize": True
}
headers = {
"X-Client-ID": "<api-key>",
"X-Client-Secret": "<api-key>",
"X-Merchant-ID": "<api-key>",
"X-API-Version": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-ID': '<api-key>',
'X-Client-Secret': '<api-key>',
'X-Merchant-ID': '<api-key>',
'X-API-Version': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: {
buyer_name: 'Northwind Technologies Pvt Ltd',
buyer_address_line_1: '7th Floor, Prestige Tower, Residency Road',
buyer_city: 'Bengaluru',
buyer_state: 'Karnataka',
buyer_postal_code: '560025',
buyer_email: '[email protected]',
buyer_phone: '+919876543210',
invoice_number: 'INV-2026-0041',
invoice_date: '2026-08-01',
invoice_amount: '125000.00',
declaration: true
},
documents: [{code: 'invoice', ref: '8207383264'}],
finalize: true
})
};
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 => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fields' => [
'buyer_name' => 'Northwind Technologies Pvt Ltd',
'buyer_address_line_1' => '7th Floor, Prestige Tower, Residency Road',
'buyer_city' => 'Bengaluru',
'buyer_state' => 'Karnataka',
'buyer_postal_code' => '560025',
'buyer_email' => '[email protected]',
'buyer_phone' => '+919876543210',
'invoice_number' => 'INV-2026-0041',
'invoice_date' => '2026-08-01',
'invoice_amount' => '125000.00',
'declaration' => true
],
'documents' => [
[
'code' => 'invoice',
'ref' => '8207383264'
]
],
'finalize' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-pacb-uat.eximpe.com/pg/payments/{payment_id}/verification/"
payload := strings.NewReader("{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
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>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("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>")
.header("Content-Type", "application/json")
.body("{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}")
.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::Post.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>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fields\": {\n \"buyer_name\": \"Northwind Technologies Pvt Ltd\",\n \"buyer_address_line_1\": \"7th Floor, Prestige Tower, Residency Road\",\n \"buyer_city\": \"Bengaluru\",\n \"buyer_state\": \"Karnataka\",\n \"buyer_postal_code\": \"560025\",\n \"buyer_email\": \"[email protected]\",\n \"buyer_phone\": \"+919876543210\",\n \"invoice_number\": \"INV-2026-0041\",\n \"invoice_date\": \"2026-08-01\",\n \"invoice_amount\": \"125000.00\",\n \"declaration\": true\n },\n \"documents\": [\n {\n \"code\": \"invoice\",\n \"ref\": \"8207383264\"\n }\n ],\n \"finalize\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "incomplete",
"outstanding": [
"invoice_number",
"invoice_date",
"invoice"
]
}
}Overview
An LRS payment answers a longer list than an ordinary one: the remitter’s verified identity, the LRS declarations, the TCS collected, and a set of documents that depends on the purpose code. This page is that list, and what happens once it is complete.fields, documents, partial sends and the response shape all work identically. Only what a payment is asked for differs, and that is what this page covers. If you do not handle LRS payments, the other page is all you need.LRS_VERIFICATION_NEEDED webhook use.
There is nothing to map between them — every one of those places names an item under code:
| Where you read it | What you do with it |
|---|---|
the GET’s fields[].code | the key you put in fields |
the GET’s documents[].code | the code you put in documents |
the webhook’s action_required_fields[].code | the key you put in fields |
the webhook’s action_required_documents[].code | the code you put in documents |
fields is an object; documents is a list of {code, ref} naming files uploaded earlier through Upload Document. Files are never posted to this endpoint.The loop
An event arrives
LRS_VERIFICATION_NEEDED lists what the payment owes — each entry a code and a sentence.You upload any files
ref per file. Upload each as it arrives; nothing has to be held back.You send what you have
{code, ref}. Partial is fine — later sends merge over earlier ones.You read where the payment stands
status, and outstanding — the codes still owed after this write.The body depends on the checklist
There is one endpoint and one envelope —fields, documents, finalize — but what belongs inside them is decided by the payment’s checklist, not by you. That checklist comes from the order’s business model and purpose code together. Sending a key it does not ask for is a 400.
You never have to work out which set applies: GET the same path and it tells you, or read the codes off the event.
business_model and purpose_code together in fields — see Submit Payment Verification Details for the rules that govern the pair — and if the code is one of the five below, the payment switches to LRS_VERIFICATION_NEEDED and starts being asked for everything on this page.Until the pair is set no checklist claims the payment, so nothing else can be validated. The pair may ride in the same call as the rest.{
"fields": {
"buyer_name": "Ravi Kumar",
"buyer_address_line_1": "12 Brigade Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560001",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"remitter_pan": "ABCPK1234F",
"remitter_dob": "1985-04-12",
"remitter_relation": "PARENT",
"buyer_declaration": true,
"amount_to_be_settled": "150000.00",
"student_name": "Ananya Kumar",
"student_dob": "2005-09-30",
"student_passport_number": "Z1234567"
},
"documents": [
{ "code": "offer_letter", "ref": "<ref from Upload Document>" },
{ "code": "passport", "ref": "<ref from Upload Document>" },
{ "code": "student_id_or_visa", "ref": "<ref from Upload Document>" },
{ "code": "relationship_declaration", "ref": "<ref from Upload Document>" }
],
"finalize": true
}
{
"fields": {
"buyer_name": "Ravi Kumar",
"buyer_address_line_1": "12 Brigade Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560001",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"remitter_pan": "ABCPK1234F",
"remitter_dob": "1985-04-12",
"remitter_relation": "PARENT",
"buyer_declaration": true,
"amount_to_be_settled": "150000.00",
"student_name": "Ananya Kumar",
"student_dob": "2005-09-30"
},
"documents": [
{ "code": "offer_letter", "ref": "<ref from Upload Document>" },
{ "code": "student_id", "ref": "<ref from Upload Document>" },
{ "code": "relationship_declaration", "ref": "<ref from Upload Document>" }
],
"finalize": true
}
{
"fields": {
"buyer_name": "Ravi Kumar",
"buyer_address_line_1": "12 Brigade Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560001",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"remitter_pan": "ABCPK1234F",
"remitter_dob": "1985-04-12",
"remitter_relation": "SELF",
"buyer_declaration": true,
"amount_to_be_settled": "150000.00"
},
"documents": [
{ "code": "passenger_list", "ref": "<ref from Upload Document>" },
{ "code": "traveller_passports", "ref": "<ref from Upload Document>" },
{ "code": "traveller_visas", "waiver_reason": "Destination is visa-free for this passport" },
{ "code": "ticket", "ref": "<ref from Upload Document>" },
{ "code": "invoice", "ref": "<ref from Upload Document>" }
],
"finalize": true
}
remitter_relation as PARENT, which is what makes relationship_declaration and the student_* fields owed. Declare SELF and they all drop out — as they have in the travel example, where the same conditional fields are called primary_person_*.The remitter’s name and the TCS are not fields here. The name is whatever Verify PAN recorded against the PAN you declare, and the TCS is the figure we quote — sending either back would only give us a second number to disagree with.What differs, and what does not
S0305 | S1107 | S0303 · S0304 · S0306 | |
|---|---|---|---|
| Buyer and invoice fields | same | same | same |
Remitter identity, declaration, amount_to_be_settled | same | same | same |
Who the money is for, when the relation is not SELF | student_name, student_dob, student_passport_number | student_name, student_dob | primary_person_name, primary_person_dob, primary_person_passport_number |
| Required documents | offer_letter, passport, student_id_or_visa | offer_letter, student_id | passenger_list, traveller_passports, traveller_visas, ticket, invoice |
| Optional documents | fee_invoice | fee_invoice | — |
Values
Field values are strings, numbers or booleans.| Kind | Send |
|---|---|
Dates (invoice_date, remitter_dob, student_dob, primary_person_dob) | YYYY-MM-DD |
Amounts (amount_to_be_settled) | A decimal string in rupees, e.g. "150000.00" |
remitter_relation | SELF · PARENT · GUARDIAN · SPOUSE · SIBLING · OTHER |
buyer_declaration | true, once the payer has affirmed the wording in the item’s message |
business_model | B2B or B2C. Case-insensitive. |
purpose_code | A FEMA/FETERS code the account this payment settles to is allow-listed for, e.g. S0305. Case-insensitive. For a PSP that is the sub-merchant on the order, not the calling credential. |
400, not a silent drop. A misspelled remitter_pan that we quietly ignored would leave the payment waiting forever for a field you believe you sent. Every key is checked before any is written, so one typo cannot half-apply a call.null or an empty string — a blank value is itself a 400, with the same reasoning. A boolean requirement is only satisfied by true; false reads as not yet answered.
Documents
Each entry names one code and exactly one ofref or waiver_reason. Sending both, or neither, is a 400.
| Key | |
|---|---|
code | The checklist code this file answers — offer_letter, passport, student_id_or_visa, … |
ref | A ref returned by Upload Document. |
waiver_reason | Why the document is not being supplied. Only accepted on items whose waivable is true. |
400. Sending it again in a later call is fine — the newer ref or waiver replaces the earlier row.
Linking a top-up
When a credit is a further payment against an earlier one — the buyer was short, or paid the TCS separately — say so on the call that files:{
"fields": { "…": "…" },
"linked_payment_id": "PR6938527534",
"reason": "REMAINING_AMOUNT"
}
| Key | |
|---|---|
linked_payment_id | The earlier payment this one tops up. Resolved against your own payments; a link we cannot resolve is refused. |
reason | REMAINING_AMOUNT — covering a shortfall on the amount to be settled. TCS_PAYMENT — paying the TCS separately. An audit label on the link. |
reason without a linked_payment_id is a 400. The reverse is fine: a link with no reason is just an unlabelled link.Like finalize, these describe the send, not the payment. They are read by the call that actually files, and a call that only stages carries them nowhere — so send them with the call that completes the set.Partial sends are merged
Send three fields today and two tomorrow and you have sent five. Nothing you sent earlier is wiped by a later call, and a field’s newest value wins. This is deliberate: nobody collects a passport scan, a visa and a letter of admission in the same instant.finalize defaults to true. It applies only to a complete set and never forces an incomplete one through, so a partial send is accepted either way — you do not have to set it. Pass finalize: false when you have sent everything but do not want the payment’s verification completed yet, and the details are recorded without going to the verification gateway.settlement_status is UNDER_REVIEW, VERIFIED, READY_FOR_SETTLEMENT or SETTLED refuses further sends — the staged rows are the record of what went to the gateway, and a later edit would leave them disagreeing with what was actually filed. GET the same path to read settlement_status before you send.The response
Three keys, whatever you sent — and a fourth,refusal, on the one response that has something more to say: a complete set the gateway refused.
{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "incomplete",
"outstanding": ["remitter_pan", "remitter_dob", "offer_letter"]
}
}
{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "in_review",
"outstanding": []
}
}
{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "action_required",
"outstanding": [],
"refusal": {
"reason": null,
"missing": ["outstanding"],
"outstanding_cents": 73750
}
}
}
| Value | What it means | What to do |
|---|---|---|
incomplete | Something is still owed. outstanding names it. | Send the rest. |
complete | Nothing is outstanding, and nothing was filed — you passed finalize: false, or this payment’s checklist is not an LRS one and needs no gateway handoff. | Nothing, unless you held it back. |
in_review | The set was complete, the verification gateway took it, and it passed. The payment is with us. | Nothing. |
action_required | The set was complete and filed, and the gateway did not pass the payment. | Read the event, fix what it names, re-send only that. |
GET on satisfied: false. Empty when nothing is.This is the list, not a pointer to one. You do not need a second call to learn what is left.status: action_required — absent from every other response, so read it as a key that may not be there rather than one that is sometimes null.Where outstanding says what the checklist still wants, this says what the gateway did. They answer different questions, and the handoff only runs once the checklist is satisfied — so a refusal always arrives with outstanding empty.| Key | |
|---|---|
reason | The headline verdict, upper-case — or null when there is no verdict beyond the items in missing. |
missing | What the gateway still wants, in its own vocabulary. These are not checklist codes. |
outstanding_cents | The shortfall still owed — principal plus MDR, GST and TCS, less what was received — in paise. 0 when the refusal is not about money. |
reason is one of:| Value | What it means |
|---|---|
PURPOSE_CODE_NOT_ALLOWED | The purpose code is not one the account this payment settles to is allow-listed for. For a PSP that is the sub-merchant on the order, not the calling credential. |
PURPOSE_CODE_NOT_IN_REGISTRY | The code is not an LRS purpose code at all. |
PAN_NOT_VERIFIED | The remitter’s PAN is unverified, and could not be verified now. |
PAN_NAME_MISMATCH | The buyer named on the order is not the PAN’s registered holder — the verification vendor’s verdict. |
SENDER_NAME_MISMATCH | The same two names, judged by our own fuzzy match rather than the vendor’s. |
null | No headline verdict — missing and outstanding_cents are the whole story. |
PAN_NAME_MISMATCH and SENDER_NAME_MISMATCH compare the same pair — the buyer name on the order against the name the PAN is registered to. Only the judge differs: the verification vendor reaches the first, our own fuzzy match the second, which is why a name can clear one and fail the other. Build one remediation, not two: correct whichever of the two names is wrong, and send again.missing names gateway tokens: purpose_code, remitter.pan, declarations, primary_person, tcs, outstanding (a shortfall), and documents.<type> for each document still wanted — documents.passport, documents.offer_letter, and so on.The purpose-code and PAN verdicts are reached before anything else is looked at, so each carries exactly one entry in missing and outstanding_cents: 0. Only SENDER_NAME_MISMATCH and a null reason can carry a shortfall, or more than one entry.refusal is a shortcut, not the record. The same verdict always arrives as LRS_VERIFICATION_NEEDED, translated into the checklist codes you send under. An integration driven by events needs nothing from here; this exists so a caller holding the response does not have to wait for the webhook to learn why.action_required never means your details were discarded. Everything that reached us is held against the payment, whether the call ended in a refusal, a vendor outage or a half-finished set. You re-send the one thing that failed, not the whole set.outstanding is empty and status is action_required
That pair is not a contradiction — it is the most important thing this response says. The checklist is satisfied; the gateway refused. Supplying a PAN is not the same as it verifying, and no requirement list has anything to say about that.
The verdict arrives as LRS_VERIFICATION_NEEDED, same event type and same shape as any other, with the conclusion folded into the relevant entry’s message — a shortfall’s rupee figure, a PAN that would not verify, a sender who is not the account holder.
This same response says it too, in refusal — the verdict, what the gateway still wants, and any shortfall in paise. Read that if you would rather not wait for the event.
Completion
finalize defaults to true and applies only to a complete set. It never forces an incomplete one through. Pass finalize: false to stage details without triggering verification — useful when you know more is coming, and the response then reads complete because the checklist is satisfied even though nothing was filed.
When a complete set is filed it runs through the verification gateway — PAN verification, the sender-to-account-holder match, the TCS recomputation and the exactly-once LRS counter posting. in_review means all of that passed.
in_review or action_required rather than complete. You only see complete here if you held the filing back with finalize: false.When the handoff itself does not happen
A complete set can fail to reach a verdict at all:| What happened | Answer | Event |
|---|---|---|
| A dependency was briefly unreachable. Your details are saved — staging commits before the handoff is attempted, so repeat the same request and re-send nothing. | an error, not 200 | none |
| Verification declined the payment — for example it is already past submit. | an error, not 200 | none |
| The gateway reached a verdict and refused. | 200, status: action_required | LRS_VERIFICATION_NEEDED |
200. A refusal the gateway actually reached is a successful call that reports action_required and always arrives as an event too; an error response means the handoff never got that far.Errors
Every refusal is answered in the standard error envelope. Every refusal is a400, whatever the reason — the code inside the envelope is what tells them apart, not the status.
error.code | When |
|---|---|
40359 | The send itself is wrong — see the codes below. Also: the payment has no checklist, and you did not send the classifying pair. |
40360 | No such payment for this merchant — the same answer whether it does not exist or belongs to someone else. Also: the verification has already been filed and details can no longer be changed. Read settlement_status from the GET first. |
400 on the send carries details keyed by the offending code, so one call reports every problem at once:
{
"success": false,
"error": {
"code": 40359,
"message": "Invalid LRS request.",
"details": {
"buyer_citty": "Not a requirement of this payment's checklist.",
"invoice": "This is a document code; send it under 'documents'.",
"ticket": "Sent more than once in this call."
}
}
}
| Message | Cause |
|---|---|
Not a requirement of this payment's checklist. | The code is not one this checklist asks for. |
This is a document code; send it under 'documents'. | A document code appeared as a key in fields. |
This is a field code; send it under 'fields'. | The reverse. |
Blank value; omit the key instead. | null, "", or whitespace. |
Sent more than once in this call. | The same document code twice in one documents array. |
This document cannot be waived. | A waiver_reason on an item whose waivable is not true. |
Unknown document ref. | The ref is not one of the uploads held for the settling merchant or its parent/children. |
Already set on the order; it cannot be changed here. | business_model or purpose_code after classification has landed. |
| Message | Cause |
|---|---|
Not a date; send YYYY-MM-DD. | A date field that will not parse. |
Not an amount; send a number like "500000.00". | An amount_to_be_settled that is not a decimal. |
Not a recognised relation. | remitter_relation outside the six accepted values. |
Where each value goes
Most fields flow into the verification and settlement record. Two are collected but held rather than forwarded, and it is worth knowing which:| Field | Where it goes |
|---|---|
buyer_name | Held. The credit’s own sender name on the order is authoritative — the LRS own-account check compares the verified PAN holder against that, so a submitted value must not overwrite it. |
purpose_code | Held. Read from the order, which is what the settlement file uses. |
Related
Submit Payment Verification Details
Get Verification Requirements
Upload Document
ref.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.
Body
Answers keyed by checklist code, e.g. {"buyer_city": "Bengaluru", "invoice_number": "INV-2026-0041"}. Values are strings, numbers or booleans. Dates are YYYY-MM-DD; invoice_amount is a decimal string in rupees and declaration is a boolean. An unknown key is a 400 rather than a silent drop — a typo you never hear about would leave the payment waiting forever for a field you believe you sent. Omit a key rather than sending null or an empty string; a blank value is also a 400.
{
"buyer_name": "Northwind Technologies Pvt Ltd",
"buyer_address_line_1": "7th Floor, Prestige Tower, Residency Road",
"buyer_city": "Bengaluru",
"buyer_state": "Karnataka",
"buyer_postal_code": "560025",
"buyer_email": "[email protected]",
"buyer_phone": "+919876543210",
"invoice_number": "INV-2026-0041",
"invoice_date": "2026-08-01",
"invoice_amount": "125000.00",
"declaration": true
}
Documents by reference, or waivers. Each entry names exactly one of ref and waiver_reason; sending both, neither, or the same code twice in one call is a 400.
Show child attributes
Show child attributes
Whether to run a complete set through the payment's verification gateway — the LRS gateway on an LRS payment, the B2B-services one on a services payment. Never forces an incomplete set through.
The earlier payment this one tops up — the buyer was short, or paid the TCS separately. Resolved against your own payments; a link that cannot be resolved is refused. Read by the call that files, so send it with the call that completes the set. LRS only: a B2B-services payment has no top-up concept and ignores this key rather than refusing it.
"PR6938527534"
Why the two payments are linked; an audit label on the link. REMAINING_AMOUNT — covering a principal shortfall. TCS_PAYMENT — paying the TCS separately. Only valid together with linked_payment_id. LRS only, like linked_payment_id: ignored on a B2B-services payment.
REMAINING_AMOUNT, TCS_PAYMENT "REMAINING_AMOUNT"