Submit Payment Verification Details
Send a payment’s verification details — buyer, invoice and goods fields — in a single JSON call.
Overview
When a payment needs verification details before it can settle, this is where you send them. One call carries every field the payment is waiting on, and you can send them as you collect them rather than all at once. Use it when you receive aVERIFICATION_NEEDED webhook with verification_status of ACTION_REQUIRED.
POST /pg/payments/{uid}/upload-verification-details/, which is deprecated. The old endpoint took one fixed set of fields, rewrote them all on every call, and worked on a single gateway. Move existing integrations across when convenient; build new ones here.When this applies
Credits that land in a Virtual Bank Account create a payment against an order. If that order is missing anything the payment needs before it can settle, the platform emitsVERIFICATION_NEEDED naming exactly which fields are absent. This endpoint is how you supply them programmatically, rather than editing the order in the dashboard.
Payment recorded
Missing fields reported
VERIFICATION_NEEDED fires with an action_required_fields array naming each one.Supply the details
POST them to this endpoint, under the same codes the event used.Read what is left
outstanding — the codes still owed after that call.A worked example
Your answers go infields, keyed by code; files you have already uploaded go in documents as { "code": …, "ref": … }.
POST /pg/payments/{payment_id}/documents/, which returns a ref, then name that ref under its code in documents.Which codes to send
The codes come from the payment, not from a fixed list. Read them offaction_required_fields on the webhook, or call GET /pg/payments/{payment_id}/verification/ at any time for the full set with a satisfied flag on each item. What a payment is asked for depends on what it is, and it changes as the underlying regulatory requirements do — read the codes rather than hardcoding them, and a revision reaches you without a release on your side.
These are the ones an import payment is most often asked for:
invoice.
type_of_goods is not sent here. It is part of the order’s product details, declared when you create the order, and it is never listed as outstanding.Send as much or as little as you have
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. Nobody collects an invoice, an address and an IEC 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 it.The response
in_review and action_required. They do not arise on this flow.Errors
A refused send answers in the standard error envelope, withdetails keyed by the offending code — so one call reports every problem at once:
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 LRS set through the verification gateway. Never forces an incomplete one 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.
"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.
REMAINING_AMOUNT, TCS_PAYMENT "REMAINING_AMOUNT"