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.
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:
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
Nine fields and one document. This is the whole of it:principal and no collected_tcs to send. The declaration is recorded by the act of filing a complete set rather than sent as a field. All three are 400s if you send them.Values
Field values are strings.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:
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.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.The response
Three keys, whatever you sent: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.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.
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:
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: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:
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. {"remitter_pan": "ABCPK1234F", "buyer_city": "Bengaluru"}. Values are strings, numbers or booleans. Dates are YYYY-MM-DD; amounts (principal, collected_tcs) are decimal strings in rupees. 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.
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.
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"