m2pfintech
API LibraryTransaction

Credit or Debit Wallet

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
POST
/v1/transactions/

Authorization

bearerAuth tenantId
AuthorizationBearer <token>

JWT Bearer token from the Authentication API

In: header

X-TENANT-ID<token>

Your unique tenant identifier assigned during onboarding

In: header

Header Parameters

X-TENANT-ID*string

Your unique tenant identifier

Request Body

application/json

mobile?
entityId*string

Required. Cardholder's entity identifier

Length1 <= length
amount*string

Required. Transaction amount (always positive). Example: 1000.00

Length1 <= length
txnRef*string

Required. Unique transaction reference (idempotency key). Pattern: alphanumeric with hyphens. Must be unique per transaction.

Match^[a-zA-Z0-9-]+$
Length1 <= length
transactionType*string

Required. Type of transaction

Value in"CREDIT" | "DEBIT" | "REFUND" | "REVERSAL" | "LOAD_NET" | "LOAD_DC" | "LOAD_CC" | "LOAD_UPI_COLL" | "LOAD_UPI_INTENT" | "LOAD_SWEEP" | "LOAD_FT" | "LOAD_IR" | "ACCOUNT_CLOSURE" | "CASHBACK"
txnOrigin*string

Required. Origin/channel of the transaction

Value in"ATM" | "POS" | "ECOM" | "WEB" | "LOAD"
description?string

Human-readable reason for the transaction

mcc?string

Merchant Category Code (for POS/ECOM transactions)

merchantId?string

Merchant identifier (for POS/ECOM transactions)

merchantName?string

Merchant name

merchantLocation?string

Merchant location

rrn?string

Retrieval Reference Number (for network-originated transactions)

acquirerId?string

Acquirer ID (for POS/ECOM transactions)

terminalId?string

Terminal ID (for POS/ATM transactions)

forwardingInstitutionCode?string
pgId?string
pymtInstrumentType?string

Response Body

application/json

application/json

application/json

curl -X POST "https://sandbox-api.m2pprepaid.com/prepaid/customer/v1/transactions/" \  -H "X-TENANT-ID: ACME_CORP" \  -H "Content-Type: application/json" \  -d '{    "mobile": {      "value": "9876543210",      "countryCode": 91    },    "entityId": "476843769320000001160925",    "amount": "1000",    "txnRef": "CB-20250415-001",    "transactionType": "CASHBACK",    "txnOrigin": "WEB",    "description": "Cashback for April promotion"  }'

{
  "result": {
    "transactionDto": {
      "amount": "1000.00",
      "preBalance": "8000.00",
      "postBalance": "9000.00",
      "transactionType": "CASHBACK",
      "txnOrigin": "WEB",
      "transactionStatus": "SUCCESS",
      "externalTransactionId": "CB-20250415-001",
      "time": "2025-04-15T10:30:00.000Z",
      "crDr": "C"
    }
  },
  "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": "Customer does not exist",
  "status": 409,
  "detail": "Customer does not exists for id :476843769320000001160925",
  "message": "error.business",
  "businessCode": "PPCUST_002"
}

Load Corporate Pool Wallet POST

Creates a new load transaction for crediting or debiting **corporate hierarchy pool wallets**. This is used to manage the master pool from which individual cardholder loads are funded. ### Corporate Pool vs Card Holder Load - **Corporate Pool Load**: Funds the corporate/branch wallet (the "pool") - **Card Holder Load**: Loads an individual cardholder's card from the pool ### Flow 1. Bank credits the corporate pool wallet (this API) 2. Corporate/branch loads individual cards from the pool (Card Holder Load API) ### Maker-Checker Pool loads typically require approval. The response `currentStatus` will be `CREATED` until approved by a checker.

Credit Forex Card POST

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) 1. **Fetch conversion rate** — `POST /v1/forex/conversion-rate` — returns per-wallet `conversionRate`, `baseConversionRate`, `netAmount`, `baseConvertedAmount`, `discountRate`, `discountAmount`, `conversionGst`, `valueOfSupply`. 2. **Fetch fee summary** — `POST /v1/forex/summary/fee` — returns `summary.feeDetails`, `summary.tcs`, `summary.gst`, `summary.total`, `summary.lrs`. Pass the same `product.promocodeId` and `summary.feeWaiver` flag you intend to use. 3. **Submit this request** — populate `walletAmount` from step 1 and `summary` from 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. - `tcs` in `walletAmount[0]` must equal `summary.tcs` (duplication required for ledger routing) - `fees`, `gst` at wallet level echo from conversion/fee API — do not compute independently - `discountRate`, `discountAmount` echo 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 number - `wallet.accountId`: Target currency wallet account ID - `amount`: Load amount in the foreign currency (e.g., 500 for $500 USD) - `hierarchyId`: Branch/corporate hierarchy ID processing the load - `transactionType`: Always `CREDIT` for this endpoint