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 B2B Services Verification Details
What a B2B services payment is asked for, and how to send it — the buyer, the invoice fields, and the commercial invoice. No identity, no amount, no tax.
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
A B2B services payment answers a short list: who the buyer is, which invoice this is, and the invoice itself. No identity document, no amount to declare, no tax. 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.VERIFICATION_NEEDED webhook use. There is nothing to map between them — the GET names an item under code, the event names the same string in action_required_fields, and this endpoint takes it back under that key.
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
VERIFICATION_NEEDED lists what the payment owes, as a flat array of codes in action_required_fields. While the payment is still unclassified that list is a legacy order-field check and can name product_description and hs_code, which this flow never asks for — classify the payment, then read the real set from Get Verification Requirements.You classify it, if nothing has
business_model and purpose_code before anything else can be checked.You upload the invoice
ref.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.Classify it first
A payment with nobusiness_model and purpose_code on its order has no requirement set, so nothing else about it can be validated. Both travel together:
curl -X POST 'https://api-pacb-uat.eximpe.com/pg/payments/PR6938527534/verification/' \
-H 'X-Client-ID: <client_id>' -H 'X-Client-Secret: <client_secret>' \
-H 'X-API-Version: 3.0.0' \
-H 'Content-Type: application/json' \
-d '{ "fields": { "business_model": "B2B", "purpose_code": "S0802" }, "finalize": false }'
business_model and purpose_code must travel together, and only once. Send one without the other and the call is refused naming the one you left out. Once set, sending either again is a 400 — Already set on the order; it cannot be changed here.S0802, S0803, S1005, S1009, S1010, S1013, S1015, S1016, S1017, S1105, S1106 — all against business_model: "B2B". They share one requirement set. The code must also be one your settling entity is enabled for; a valid code you are not enabled for is rejected just like one that does not exist.The complete body
Eleven fields and one document. This is the whole of it:{
"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
}
buyer_postal_code is stored on the order as an Indian PIN code, so send the remitter’s Indian address rather than your own overseas one.invoice_amount is a checklist field, in rupees, cross-checked against the credit — more than a paisa apart and the finalizing call is refused naming it. declaration is a boolean and has to be true. What settles is still the credit itself, and no tax is collected on top, so amount_to_be_settled stays a 400.Values
Field values are strings.| Kind | Send |
|---|---|
invoice_date | YYYY-MM-DD |
buyer_postal_code | A six-digit Indian PIN code |
business_model | B2B. Case-insensitive. |
purpose_code | One of the eleven services codes your merchant account is allow-listed for. Case-insensitive. |
400, not a silent drop. A misspelled invoice_number 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.
Documents
One entry, naming the invoice’s checklist code and theref you got from Upload Document:
| Key | |
|---|---|
code | invoice — the only document this set asks for. |
ref | A ref returned by Upload Document for this payment. A ref from one of your other payments reads as unknown. |
400. Sending it again in a later call is fine — the newer ref replaces the earlier row.
code, and this flow has exactly one document type per code, so all the payment’s invoices are filed when the set completes — not just the one whose ref you sent. Upload a second invoice and it goes with them; you do not cite it, and you cannot leave it out.invoice item reads as satisfied because an accepted invoice exists on the payment, not because you named a ref. So citing a ref again after Ops rejected that invoice leaves the item outstanding: upload a replacement, then cite the new ref. Check Get Verification Requirements rather than assuming a repeat citation cleared it.waiver_reason is not accepted on this flow. No B2B services item is waivable, so there is nothing to discharge with a reason instead of a file. Sending one is a 400 reading This document cannot be waived., keyed by the document’s code.linked_payment_id and reason are ignored here. The shared request body accepts them, but they mark a payment as a top-up of an earlier one — an LRS concept. B2B services has none, so both are read and discarded rather than refused. Do not send them expecting a link.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.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 verification filed yet.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:{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "incomplete",
"outstanding": ["buyer_city", "invoice"]
}
}
{
"success": true,
"message": "Verification details received",
"data": {
"payment_id": "PR6938527534",
"status": "in_review",
"outstanding": []
}
}
status | Meaning |
|---|---|
incomplete | Something is still owed — outstanding lists the codes. |
complete | Everything was sent, but the set was staged rather than filed (finalize: false). |
in_review | The complete set was filed. The payment is with EximPe Ops for review. |
in_review — or is refused with a 400 naming what to fix. There is no action_required here; do not write a branch for a value you will never receive.400 on the finalizing call costs you a re-send of the one thing that failed, not the whole set.Completion
A complete B2B services set hands off to its own verification gateway, andin_review is what says it got there. That handoff is also what writes the staged values onto the order — which is why a second group of refusals only appears on the finalizing call.
Errors
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 messages below. Also: the payment has no requirement set, 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. |
ERR_IMPORT_VERIFICATION_001 | The invoice_number is already used by another of your payments. Raised only by the call that files — see below. |
ERR_B2B_SERVICES_004 | The verification has left your hands — under review, approved or rejected — and can no longer be edited. |
ERR_B2B_SERVICES_006 | A document being filed does not belong to this payment. |
code, not on message. 40359 is shared with the other verification flows; message names which one refused you, so a classified B2B services payment always reads Invalid B2B services request. The code is the stable part.Before the payment is classified there is no flow to name, and the wording is Invalid verification request. instead — the one case on this flow where the message is not the services one.Not every refusal is 40359. A few carry a code of their own, listed above — they are the specific ones, and they say more than the shared code does. Treat any code you do not recognise as a 400 you should not retry unchanged.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 B2B services request.",
"details": {
"buyer_citty": "Not a requirement of this payment's checklist.",
"invoice": "This is a document code; send it under 'documents'."
}
}
}
| Message | Cause |
|---|---|
Not a requirement of this payment's checklist. | The code is not one this set asks for — hs_code, iec, amount_to_be_settled and remitter_pan all land here. |
This is a document code; send it under 'documents'. | invoice 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. |
Unknown document ref. | The ref is not one of this payment’s active documents. A ref uploaded against another payment, or superseded by a later upload of the same type, reads as unknown. |
This document cannot be waived. | A waiver_reason on an item whose waivable is not true. No B2B services item is waivable, so every waiver_reason on this flow lands here. |
Already set on the order; it cannot be changed here. | business_model or purpose_code after classification has landed. |
Raised only by the call that files
A second group appears only when a complete set is filed, as the staged values are read for the gateway and written onto the order:| Message | Cause |
|---|---|
Not a date; send YYYY-MM-DD. | invoice_date will not parse. |
Enter a valid Indian PIN code. | buyer_postal_code is not a PIN code in the India Post directory. A foreign postal code lands here — the buyer is the Indian remitter, not your customer abroad. |
invoice_number is unique per merchant, so a collision surfaces here too. Unlike the refusals above it does not answer under 40359 — it carries its own code:
{
"success": false,
"error": {
"code": "ERR_IMPORT_VERIFICATION_001",
"message": "Invoice number already exists.",
"details": "Invoice number already exists."
}
}
invoice_number is unique per merchant across filed verifications. Re-using one from an earlier payment is refused here, not at the call that staged it — raise a new number and send that field again.These all arrive on the finalizing call rather than the call that staged the value, because nothing reads a date as a date — or writes anything to the order — until the set is complete. Your details are still saved; fix the named code and re-send only that.Related
Get Verification Requirements
Upload Document
ref.B2B Services Verification
List Settlement Documents
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"