Product Guide 06
Fintech AI

Cross-Border Payments: How to Build It

A step-by-step guide to building cross-border payments from India. Eight stages, the options at each one, exactly how each step connects to the next, real costs, and what breaks. Written for someone who has not built this before.

Verified September 2026Free · No signupOfficial sources only
BeginnerStart here. No prior knowledge assumed.

How to use this page

This page walks you through building one capability: moving money across India's border, legally, for goods or services. Receiving from overseas customers, paying overseas suppliers, or both.

It is the capability behind every Indian SaaS company, exporter, freelancer platform and marketplace that touches a foreign currency.

Watch out

The framework changed completely and the old one is still widely described as current. The OPGSP regime — imports capped at $2,000, exports at $10,000 per transaction, and services excluded entirely — was withdrawn by the RBI circular of 31 October 2023. It was replaced by PA-CB, then consolidated into the Master Direction on Regulation of Payment Aggregators of 15 September 2025. Anything describing OPGSP limits as live is describing a regime that no longer exists.

What cross-border payments actually are

Cross-border payments in India sit on three legal layers at once, and you cannot ignore any of them:

LayerWhat it governs
FEMA, 1999Whether the money may cross the border at all, and for what purpose.
RBI payment regulationWho is allowed to move it — AD banks, and now authorised PA-CBs.
PMLA / FIU-INDReporting obligations. A Delhi High Court ruling in July 2023 confirmed these operators are reporting entities.

The three PA-CB categories, by direction of flow:

CategoryDirectionWho needs it
ExportMoney coming in from overseas buyersSaaS, IT services, freelancers, exporters.
ImportMoney going out to overseas sellersBusinesses buying foreign goods, software or services.
BothTwo-wayMarketplaces, and anyone who both earns and spends abroad.
Note

Match the category to your flow before you sign anything. A provider authorised for export-only cannot process your outbound supplier payments, and you will find that out at the moment you need to pay someone. If you do both, you need a provider covering both — or two providers.

What it is not:

  • Not a wire transfer with an API. The documentation obligations are the product.
  • Not unlimited. See step 5.
  • Not something you can route around. Using unauthorised channels is a FEMA violation, with penalties running to criminal prosecution for wilful breaches.

The whole journey, in one table

#StepIn plain words
1Which direction?In, out, or both. It decides everything after.
2Pick your routeAD bank, a PA-CB provider, or become one.
3Verify the authorisationFinal, not in-principle. And the right category.
4Onboard the merchantKYC, plus the FEMA purpose of the money.
5Move it — inside the cap₹25 lakh per unit, and the word “unit” is doing work.
6Document itPurpose code, FIRA, EDPMS or IDPMS. This is what makes it legal, not just successful.
7The FXWhere the real cost lives, and where it is hidden.
8Reconcile and reportIncluding the FIU-IND obligation that surprises people.
Note

Step 6 is the one that separates a working integration from a compliant one. A payment can settle perfectly and still leave you with an open entry in a monitoring system that someone has to close, months later, without the paperwork.

IntermediateBuild it. Pipelines, tools and working code.

Steps 1 to 3 — direction, route and authorisation

Steps 1 and 2 — Direction, then route

RouteWhat it meansWhen it fits
AD Category-I bank directlyYour bank handles the remittance and the documentation.Low volume, large tickets, or anything above the PA-CB cap.
An authorised PA-CBA provider handles collection, conversion and paperwork.Most businesses. Better rates, better developer experience, and the documentation largely handled.
Become a PA-CB₹15 crore net worth at application, rising to ₹25 crore, plus authorisation, FIU-IND registration and FEMA obligations.Cross-border payments are your product.

Step 3 — Verify the authorisation

Watch out

The procurement trap: “in-principle approval” is not authorisation. Several well-known names have held in-principle PA-CB approval for extended periods while their final authorisation remained pending. In-principle means the RBI is minded to approve, subject to conditions. It does not mean the entity may yet process your cross-border payments. Ask two questions and get written answers: is the authorisation final, and which category does it cover? “We are RBI regulated” answers neither.

The same check applies to the accounts underneath. A PA-CB maintains separate collection accounts with an AD Category-I bank — one for imports, one for exports — and they must not be commingled, with each other or with the provider's own money. That separation is what keeps your export documentation intact, so your purpose codes and reconciliation continue to work. It is worth asking a provider to describe their account structure; a vague answer is informative.

Steps 4 to 6 — onboarding, the cap and the paperwork

Step 4 — Onboard the merchant

Standard KYC under the Master Direction, plus one thing domestic onboarding does not have: the FEMA purpose. You are not just establishing who they are, you are establishing what the money is for, because that determines whether it may cross the border at all.

Ongoing due diligence applies, and enhanced due diligence kicks in above ₹2.5 lakh per unit. That is low enough that for most B2B exporters it is the normal case rather than the exception — build it into the flow rather than treating it as an escalation.

Step 5 — Move it, inside the cap

Python — step 5, the cap, and the word doing all the work
from decimal import Decimal

# Per-unit cap on goods and services processed through a PA-CB.
PER_UNIT_CAP = Decimal("2500000")      # Rs 25 lakh
EDD_THRESHOLD = Decimal("250000")      # Rs 2.5 lakh -> enhanced due diligence

# NOTE THE WORD. The OPGSP limit it replaced was PER TRANSACTION. This one is
# PER UNIT of goods or services, and how a "unit" is measured is genuinely
# ambiguous -- the RBI has not defined it precisely and practitioners have been
# asking since the 2023 circular.
#
# Practical consequence: a Rs 35 lakh consulting engagement is NOT solved by
# splitting it into two payments. If it is one unit of service, it is one unit.
# Structuring invoices to duck the cap is the thing that looks like structuring.

def check_transaction(txn) -> dict:
    flags = []
    if txn["value_inr"] > PER_UNIT_CAP:
        flags.append({
            "block": True, "why": "exceeds_per_unit_cap",
            "action": "route via an AD bank directly, not by splitting the invoice",
        })
    if txn["value_inr"] > EDD_THRESHOLD:
        flags.append({"block": False, "why": "enhanced_due_diligence_required",
                      "action": "EDD on the counterparty before processing"})
    if not txn.get("purpose_code"):
        flags.append({"block": True, "why": "no_purpose_code",
                      "action": "a payment without a FEMA purpose is not a payment you can make"})
    if txn["direction"] not in txn["provider_categories"]:
        flags.append({"block": True, "why": "provider_not_authorised_for_direction",
                      "action": "export-only cannot process imports"})
    return {"allow": not any(f["block"] for f in flags), "flags": flags}

# WHAT TO CHECK
# [ ] above the cap, the answer is a DIFFERENT ROUTE, not a smaller invoice.
#     An AD bank can handle what a PA-CB cannot. Splitting to fit is the
#     pattern every AML system is built to notice
# [ ] "unit" is ambiguous. Write down YOUR interpretation, get it agreed with
#     your provider and your bank IN WRITING, and apply it consistently. An
#     inconsistent interpretation is worse than a conservative one
# [ ] EDD above Rs 2.5 lakh is on the COUNTERPARTY, and it takes time. Build it
#     into the flow, not as a blocking surprise at payment
# [ ] the purpose code is chosen from the RBI list at the point of the payment,
#     not guessed later by finance from the narration
# [ ] provider category is checked in code against the direction. It is a
#     one-line check and it prevents a whole class of failed payment

The gotcha nobody documents: the cap is per unit, not per transaction — a deliberate change from the OPGSP regime it replaced, and the RBI has not defined precisely what a “unit” is. For a physical good it is intuitive. For a ₹35 lakh consulting engagement it is not, and splitting the invoice is exactly the behaviour an AML system is designed to flag. The correct answer above the cap is a different route — an AD bank — not a smaller invoice. Write down your interpretation of “unit”, agree it with your provider and your bank in writing, and apply it the same way every time.

Step 6 — Document it

Python — step 6, the documentation that makes it legal
# A payment that settles is not the same as a payment that is compliant. The
# money arriving is the easy part; closing the regulatory entry is the work.

PURPOSE_CODES = {          # illustrative -- use the current RBI list
    "P0802": "software consultancy / implementation",
    "P0807": "business and management consultancy",
    "P1006": "advertising and market research",
    "P0103": "export of goods",
}

def remittance_record(txn, merchant):
    rec = {
        "direction": txn["direction"],               # INWARD | OUTWARD
        "purpose_code": txn["purpose_code"],          # chosen at payment time
        "amount_fcy": txn["amount_fcy"],
        "currency": txn["currency"],
        "amount_inr": txn["amount_inr"],
        "fx_rate_applied": txn["fx_rate"],
        "value_date": txn["value_date"],
        "counterparty": txn["counterparty"],
        "invoice_ref": txn["invoice_ref"],
        "contract_ref": txn.get("contract_ref"),
    }
    if txn["direction"] == "INWARD":
        # Export of services or goods. The AD bank reports into EDPMS, and the
        # entry stays OPEN until it is matched and closed. An unclosed entry is
        # a compliance item with your name on it, months later.
        rec["fira_required"] = True                  # Foreign Inward Remittance Advice
        rec["edpms_entry"] = "expected"
        rec["close_by"] = txn["value_date"] + realisation_window(merchant)
    else:
        # Import. Reported into IDPMS, and the entry closes against evidence
        # that you actually received what you paid for.
        rec["idpms_entry"] = "expected"
        rec["evidence_required"] = ["bill_of_entry" if txn["is_goods"]
                                    else "service_completion_evidence"]
    return rec

# WHAT TO CHECK
# [ ] FIRA is requested and STORED per inward remittance. It is the evidence
#     the money is export proceeds and not something else, and clients,
#     auditors and the tax authority all ask for it eventually
# [ ] EDPMS / IDPMS entries are TRACKED TO CLOSURE, not assumed closed. An open
#     entry is the single most common cross-border compliance debt, and it
#     surfaces as a bank refusing your next transaction
# [ ] the purpose code is picked at payment time from the current RBI list.
#     Reverse-engineering it from a bank narration months later is guesswork
# [ ] store the FX RATE APPLIED, not just the INR amount. Without it you cannot
#     audit the spread in step 7
# [ ] invoice and contract references are captured with the payment, because
#     closing an EDPMS entry needs the documents, not the payment record
# [ ] outward payments need evidence you received the thing. A bill of entry
#     for goods; something defensible for services

The gotcha nobody documents: EDPMS and IDPMS entries stay open until somebody closes them. The payment succeeds, the money is in the account, everyone moves on — and an entry sits in a monitoring system waiting for documentation. It surfaces months later as a bank declining your next transaction until the backlog is cleared. Track entries to closure as a first-class part of the product, not as something finance will sort out at year end, because by then the invoices are hard to find and the people who raised them have moved on.

Steps 7 and 8 — FX, reconciliation and reporting

Step 7 — The FX

This is where the money goes, and it is almost never on the pricing page.

A provider quoting “1% fee” may be applying an exchange rate two or three percent away from the interbank rate. The fee is visible and the spread is not, and the spread is usually the larger number. Build Sheet 05 records that all-in cross-border costs are frequently reported in the 5–7% range against a 3% headline, and the difference is almost entirely FX.

Ask thisWhy
“What is your markup over the interbank mid-rate?”The only question that gets a comparable number. “Competitive rates” is not an answer.
“Show me the rate you applied on my last ten transactions, against the mid at that timestamp.”Turns a claim into arithmetic. Store the applied rate per transaction and you can compute this yourself.
“Who else takes a cut before it lands?”Correspondent bank charges, beneficiary bank charges, and lifting fees are real and often undisclosed.
Watch out

Store the FX rate applied, per transaction, from day one. Without it you cannot audit your provider, cannot compare two providers honestly, and cannot answer a merchant asking why they received less than they expected. It is one column, and adding it later means the historical comparison you actually want is impossible.

Step 8 — Reconcile and report

Three obligations that arrive together and are usually owned by nobody:

  • Reconciliation. Foreign currency in, INR out, at a rate, on a date, with fees deducted somewhere. See Build Sheet 05 — the control-total discipline applies identically, with an FX leg added.
  • EDPMS / IDPMS closure, tracked as a queue with an owner and an age.
  • FIU-IND. Cross-border payment operators are reporting entities under the PMLA. Registration and reporting obligations follow, and Build Sheet 04 covers the mechanics.

What it costs

Cross-border payments — what it costs

Verified September 2026
Headline provider feedirect
Commonly quoted around 1–3%. This is the visible part and usually the smaller one.
FX spreaddirect
Where the money actually goes. Markup over the interbank mid-rate, rarely disclosed as a number. All-in cross-border cost is frequently reported at 5–7% against a 3% headline.
Correspondent and beneficiary bank chargesdirect
Deducted in transit by banks you never chose. Ask who takes a cut before the money lands — the answer is often more than one party.
Becoming a PA-CBdirect
₹15 crore net worth at application, rising to ₹25 crore. Plus authorisation, FIU-IND registration, separate import and export collection accounts with an AD Category-I bank, and FEMA reporting. A licensed business, not a feature.
Enhanced due diligencedirect
Required above ₹2.5 lakh per unit — low enough that for most B2B exporters it is the normal case. Analyst time, not licence cost.
EDPMS / IDPMS closuredirect
The cost nobody budgets. Someone must chase documents and close entries. Left alone it accumulates until a bank stops processing your transactions, and then it is urgent.
Where to buy these: Payments Reconciliation Build Sheet names every tool with its unit cost. Getting Access covers which ones you can sign up for today, which need a sales call, and which are licensed.
Note

Compute your effective all-in rate yourself, per transaction: (amount the counterparty sent − amount that reached the account) ÷ amount sent. Compare it to the interbank mid at that timestamp. That single number makes every provider comparable and it is the one nobody will quote you.

AdvancedShip it. Failure modes, thresholds and evidence.

Three versions you could build

The starting version

Build: one authorised PA-CB provider matching your direction → purpose code captured at payment time → FIRA requested and stored per inward remittance → FX rate stored per transaction → a spreadsheet tracking EDPMS entries to closure.

It breaks when: a transaction exceeds the per-unit cap, or you start paying outward and your provider is export-only.

The proper version

Build: everything above, plus — an AD bank relationship for above-cap transactions → provider category checked in code against direction → EDD built into the flow above ₹2.5 lakh → a written, agreed interpretation of “unit” → an EDPMS/IDPMS closure queue with an owner and an age report → effective all-in rate computed per transaction and reviewed monthly.

Trade: the documentation machinery is real work that produces nothing visible until the day it is needed, and then it is the only thing that matters.

Becoming the PA-CB

Build: authorisation, ₹25 crore net worth, separate collection accounts, FEMA and FIU-IND reporting, merchant due diligence at scale.

Use when: cross-border payments are the product. Not to save on FX.

Note

If you take one thing from this page: store the FX rate applied on every single transaction, starting with the first one. It is one column. Without it you cannot audit your provider, compare alternatives honestly, or explain a shortfall to a merchant — and it cannot be reconstructed later.

What goes wrong

What goes wrongWhyFix
Provider cannot process your paymentExport-only authorisation, outbound payment.Check category against direction, in code.
“RBI regulated” turns out to be in-principleNobody asked whether authorisation was final.Two written questions: final, and which category.
An invoice is split to fit the capIt seemed like the obvious workaround.Route above-cap transactions through an AD bank.
The bank stops processingA backlog of open EDPMS entries.Track closure as a queue from the first transaction.
The merchant received less than expectedSpread plus correspondent charges, neither visible.Store the applied rate; compute all-in cost per transaction.
Purpose code guessed at year endNot captured at payment time.Pick it from the current RBI list, at payment.
No FIRA when a client asksNever requested.Request and store per inward remittance.
EDD blocks a payment unexpectedlyTreated as an escalation, not a step.Above ₹2.5 lakh it is the normal path.

Where to go next

Watch out

This page is a guide, not a specification. Cross-border payments are governed by FEMA, and using an unauthorised channel is a statutory violation rather than a commercial mistake. Nothing here is legal advice. Have your route, your purpose-code mapping and your documentation process reviewed by qualified counsel and your AD bank before the first transaction.

Sources

Every figure, rule and date on this page, and where to check it. Entries are typed so you can see which are primary-sourced and which are industry reporting.

  1. officialRBI Master Direction on Regulation of Payment Aggregators (15 September 2025) — the consolidated framework including PA-CB: the three categories, net worth, the separate import and export collection accounts with AD Category-I banks, and the prohibition on commingling. www.rbi.org.in
  2. officialRBI circular on Regulation of PA-CBs (31 October 2023) — the creation of the PA-CB framework, the withdrawal of OPGSP, the ₹25 lakh per-unit cap and the ₹2.5 lakh enhanced due diligence threshold. www.rbi.org.in
  3. officialForeign Exchange Management Act, 1999 and RBI purpose codes — whether money may cross the border and under which purpose, plus the EDPMS and IDPMS monitoring systems. www.rbi.org.in
  4. officialFIU-IND — the reporting-entity obligation that attaches to cross-border payment operators under the PMLA. fiuindia.gov.in
  5. industryPA-CB practitioner commentary — the OPGSP limits it replaced ($2,000 imports, $10,000 exports, services excluded), the ambiguity in the word "unit", and the in-principle-versus-final authorisation distinction. Practitioner-sourced; verify current authorisation status directly with the provider.
  6. industryCross-border cost reporting — the 5–7% all-in figure against a ~3% headline, and the composition of correspondent and beneficiary charges. Compute your own effective rate rather than relying on any published range.

Checked September 2026. Authorisation status changes; verify with the provider before routing money.

Ask an AI about this page

Opens your assistant with this page as the source, and a question rather than a summary. It will ask what you are building before it answers.

Nothing is sent from here. The link carries only this page’s title and address.