Credit Forex Card
Loads forex currency onto a cardholder's forex card wallet. This is used for initial loading and reloading of forex cards.
Integration Sequence (follow in order)
- Fetch conversion rate —
POST /v1/forex/conversion-rate— returns per-walletconversionRate,baseConversionRate,netAmount,baseConvertedAmount,discountRate,discountAmount,conversionGst,valueOfSupply. - Fetch fee summary —
POST /v1/forex/summary/fee— returnssummary.feeDetails,summary.tcs,summary.gst,summary.total,summary.lrs. Pass the sameproduct.promocodeIdandsummary.feeWaiverflag you intend to use. - Submit this request — populate
walletAmountfrom step 1 andsummaryfrom step 2. Do not independently compute any fee, tax, or rate field.
summary Object — What to Pass
| Field | Source | Notes |
|---|---|---|
feeDetails | Fee summary API | Preferred. Each key creates a separate ledger entry |
tcs | Fee summary API | Pass here and in walletAmount[0].tcs |
conversionGst | Conversion rate API | Triggers a separate branch debit for GST |
valueOfSupply | Conversion rate API | Required when conversionGst > 0 |
total | Fee summary API | Grand total the customer pays |
gst | Fee summary API | GST on product fees (not conversion) |
feeWaiver | Operator decision | Set before calling fee summary API |
fees | Deprecated | Use feeDetails map instead |
walletAmount Array — What to Pass
One entry per currency wallet being loaded. Populate from the conversion rate API response.
tcsinwalletAmount[0]must equalsummary.tcs(duplication required for ledger routing)fees,gstat wallet level echo from conversion/fee API — do not compute independentlydiscountRate,discountAmountecho from conversion rate API — do not alter
Fee Waiver
Set summary.feeWaiver = ALLOWED when the customer qualifies for a fee waiver.
You must upload the waiver approval document and pass its reference in summary.feeWaiverApproval.
Re-call the fee summary API with feeWaiver: ALLOWED to get the zero-fee breakdown before submitting.
TCS and conversionGst are never waived — they are regulatory charges.
Promo Codes
If a promo code is active for this product, pass product.promocodeId (the internal promo code ID
provided by M2P, not a customer-facing promo string). Pass the same promocodeId when calling
the fee summary API to receive the promotional fee schedule. The promo code affects product-level fees
(registration, load fee) only — TCS and conversionGst are unaffected.
Do not pass promocodeId in reload requests — the platform reads it automatically from the
card's original issuance record.
Compliance Documents
- Passport: Mandatory for all forex loads
- Visa: Required for travel-related loads
- Air Ticket: Required for travel loads
- Purpose Proof: Required for educational/medical purpose
- A2 Form: RBI declaration form
- Fee Waiver Approval: Required if
feeWaiver = ALLOWED
Key Fields
kitNo: Card kit numberwallet.accountId: Target currency wallet account IDamount: Load amount in the foreign currency (e.g., 500 for $500 USD)hierarchyId: Branch/corporate hierarchy ID processing the loadtransactionType: AlwaysCREDITfor this endpoint
Authorization
bearerAuth tenantId JWT Bearer token from the Authentication API
In: header
Your unique tenant identifier assigned during onboarding
In: header
Header Parameters
Your unique tenant identifier
Request Body
application/json
Required. Branch/corporate hierarchy ID
1 <= lengthRequired. Card kit number associated with the particular card/product
1 <= lengthUnique entity identifier for the transaction associated with the customer
Customer's mobile number
Full name of the customer
Encrypted Card Number of the customer
Unique customer identifier
Type of card issued; Single for single-user, Bulk for bulk issuance
"Single" | "Bulk"Transaction amount in the wallet currency
0 <= valueDescription or remarks for the transaction
Required. CREDIT for loading, DEBIT for withdrawal
"CREDIT" | "DEBIT"Indicates partial or full debit transaction
"PARTIAL_DEBIT" | "FULL_DEBIT" | "FULL_DEBIT_WITH_CLOSURE"Product details associated with the transaction
Wallet details used for the transaction
Trip details (required for CREDIT operations)
Funding source details
List of wallet amounts and conversion details (for multi-wallet operations)
Summary of transaction including fees, GST, TCS, etc.
Reason for fee waiver approval, if any
Declarations such as FATCA, ITR, T&C, LRS
Branch code or hierarchy ID where the transaction occurred
Teller ID who processed the transaction
Retrieval Reference Number for the transaction
Indicates which channel this transaction is initiated from
Indicates if transaction is initiated from a branch
Indicates if maker-checker workflow is enabled for this transaction
Loan details if applicable; mandatory if purpose of travel is EDUCATIONAL_LOAN_LETTER
Custom attributes for additional data
Required when feeWaiver = ALLOWED. Upload the approval document using the
file upload API and pass the returned fileName and filePath here.
The platform validates the document exists before processing the transaction.
Ignored when feeWaiver = NOTALLOWED.
"SUCCESS" | "FAILED" | "CREATED""SUCCESS" | "FAILURE"Response Body
application/json
application/json
application/json
curl -X POST "https://sandbox-api.m2pprepaid.com/prepaid/customer/v1/forex/card-holder-loads/credit" \ -H "X-TENANT-ID: ACME_CORP" \ -H "Content-Type: application/json" \ -d '{ "hierarchyId": "90009", "kitNo": "320000541", "entityId": "476843769320000541160925", "mobile": { "value": "9876543210", "countryCode": 91 }, "amount": 500, "transactionType": "CREDIT", "product": { "productId": "FRX001", "productType": "FOREX" }, "wallet": { "accountId": "c515d3a6-6c51-4f64-bd7b-d9cbd9c5b22f" }, "trip": { "country": { "name": "United States", "threeDigitCountryCode": "USA" }, "startDate": "2025-05-01", "endDate": "2025-05-15", "purposeOfTravel": { "code": "PERSONAL_VISIT", "purpose": "Personal Visit" }, "type": "NEW" }, "funding": { "fundingMode": "SAVINGS_ACCOUNT", "sourceOfFund": "SELF", "accountNo": "1234567890", "ifsc": "SBIN0001234" }, "summary": { "fees": 250, "gst": 45, "tcs": 500, "total": 42545 }, "declarations": { "fatca": true, "lrs": true, "tc": true } }'{
"result": {
"id": "FRX20250415001",
"currentStatus": "CREATED",
"status": "SUCCESS",
"kitNo": "320000541",
"amount": 500,
"transactionType": "CREDIT"
},
"pagination": null
}{
"type": "https://www.m2pfintech.com/problem/problem-with-message",
"title": "Bad Request",
"status": 400,
"detail": "Unable to convert http message",
"message": "error.http.400"
}{
"type": "https://www.m2pfintech.com/problem/problem-with-message",
"title": "The given load amount of $10 is less than the required minimum of $20. Please enter valid amount.",
"status": 409,
"detail": "The given load amount of $10 is less than the required minimum of $20. Please enter valid amount.",
"message": "error.business",
"businessCode": "PP_CORP_157"
}Credit or Debit Wallet POST
Performs a direct credit or debit on a cardholder's wallet. This is the fundamental money-movement API used for programmatic fund transfers. ### Use Cases - **CREDIT**: Load funds, cashback, refund, promotional credit - **DEBIT**: Fee deduction, penalty charge, adjustment ### Idempotency The `txnRef` field serves as an idempotency key. Sending the same `txnRef` twice will result in a **duplicate transaction error** (409), preventing accidental double-processing. ### Response Returns pre-balance, post-balance, and the transaction status. Use the `externalTransactionId` from the response for subsequent lookups. ### Important Notes - `amount` is always a positive number — the `transactionType` determines credit vs debit - `txnRef` must be unique per transaction (alphanumeric, hyphens allowed) - `entityId` identifies the specific cardholder account - For load transactions, set `txnOrigin` to `LOAD`
Debit Forex Card (Partial Withdrawal) POST
Debits (withdraws) a specific amount from a forex card wallet. The withdrawn amount is credited back to the customer's bank account. ### When to Use - Customer wants to withdraw unused forex after a trip - Partial encashment of forex card balance - Fund reallocation between wallets (debit one, credit another) ### Key Difference from Debit-Closure This is a **partial debit** — the card and wallet remain active after the transaction. For full withdrawal with card closure, use the Debit with Closure endpoint.
