Reverse AFT Pull Transaction
Reverse a previously successful AFT pull transaction.
Requirements:
- Must be submitted within 24 hours of original transaction
- Only for Visa Direct AFT transactions
- Provide original RRN (Retrieval Reference Number)
Authorization
BasicAuth Partner credentials (username/password) provisioned during onboarding
In: header
Request Body
application/json
The externalTransactionId of the original AFT pull transaction being reversed
RRN (Retrieval Reference Number) from the original pull transaction response
Payer card PAN from the original pull transaction
^\d{13,19}$Reason code for the reversal. Common values:
DUPLICATE_TRANSACTION— Transaction was processed more than onceCUSTOMER_REQUEST— Customer requested reversalFRAUD— Suspected fraudulent transaction
Unique external ID for this reversal transaction (must be different from original)
Partner entity identifier
Must be VISA — AFT reversals are Visa Direct only
"VISA"Must be AFT_PULL_REVERSAL for AFT pull reversals
Channel/origin of the reversal request
"API" | "WEB" | "MOBILE" | "POS"Product identifier (should match original transaction)
MCC from the original transaction (defaults to 6540 if not provided)
"6540"Response Body
application/json
application/json
application/json
curl -X POST "https://secure.yappay.in/Yappay/direct/pull/reversal" \ -H "Content-Type: application/json" \ -d '{ "originalTransactionId": "EXT-M2P-250", "originalRetrievalReferenceNumber": "601018633791", "reason": "DUPLICATE_TRANSACTION", "business": "M2P", "networkType": "VISA", "transactionType": "AFT_PULL_REVERSAL", "externalTransactionId": "EXT-M2P-253", "transactionOrigin": "API", "senderPrimaryAccountNumber": "4012001037141112", "productId": "GENERAL" }'{
"result": {
"actionCode": "00",
"responseCode": "string",
"retrievalReferenceNumber": "string",
"errorMessage": "string"
},
"error": {
"errorCode": "string",
"shortMessage": "string",
"detailMessage": "string",
"fieldErrors": [
"string"
],
"networkHttpStatusCode": 0
}
}{
"result": null,
"error": {
"errorCode": "VALIDATION_ERROR",
"shortMessage": "Invalid request",
"detailMessage": "recipientPan is required",
"fieldErrors": [
"recipientPan: must not be blank"
]
}
}{
"result": null,
"error": {
"errorCode": "INTERNAL_ERROR",
"shortMessage": "Internal server error",
"detailMessage": "An unexpected error occurred. Please contact support."
}
}Pull Funds from Card (AFT) POST
Debit funds from a customer's card (Account Funding Transaction). **Visa Direct only.** > **⚠️ Important**: The response from this API indicates only whether the request was > accepted or a 3DS challenge is required. **Do not rely on this response to determine > final transaction status.** Always call > `GET /Yappay/txn-manager/v2/fetch/{externalTransactionId}` to confirm the final > `txnStatus` (e.g., `PAYMENT_SUCCESS`, `PAYMENT_FAILURE`) after the 3DS flow completes. ## 3DS Authentication Modes This endpoint supports two 3DS flows depending on who performs authentication: ### Mode 1 — Platform-Managed 3DS (`method: THREE_DS`) Submit the request with `authentication.method: "THREE_DS"` and **omit** `cavv`/`eci`. The platform initiates the 3DS challenge and returns an `htmlContent` field containing an HTML form that must be rendered in the customer's browser to complete authentication. Once the customer completes the challenge, resubmit the transaction with the CAVV/ECI received. ### Mode 2 — Partner-Provided CAVV/ECI Complete 3DS externally (via your own 3DS provider) and submit the resulting `cavv` and `eci` in the `authentication` block. Omit `method` or leave it empty. ## Token Types (`tokenType`) - `"01"` — M2P-generated card token (PCI DSS tokenized by M2P) - `"02"` — Network-generated card token (e.g., MDES/VTS network token) - `"03"` — Clear card number (partner is PCI DSS compliant) ## Use Cases - PPI/wallet loading - Prepaid card top-up - Account funding
Create Card Token (Frontend Only) POST
Tokenize a customer's card by submitting AES-encrypted card data directly from the **customer's browser or mobile app**. Returns an `altId` (M2P card token) that can be used in AFT pull and OCT push calls with `tokenType: "01"`. > ⚠️ **This call MUST originate from the customer's frontend (browser/app), NOT > from your backend server.** If your backend relays this call, card data enters > PCI scope on your systems, violating the non-PCI compliance boundary. **Use the `url` returned by `POST /bitUrl/v2/generateSharedSecret`** as the full endpoint for this request (it contains a signed session `key` query parameter). ### Encryption Flow (JavaScript example) ```js const { CryptoJS } = window; // load from cdnjs // Keys derived from the generateSharedSecret response const cvvAESKey = CryptoJS.SHA256(serverPublicKey); const payloadKey = CryptoJS.SHA256(sharedSecret); const iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000"); // 1. Encrypt CVV using serverPublicKey-derived key const encryptedCvv = CryptoJS.AES.encrypt( cvv, cvvAESKey, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ).toString(); // 2. Build payload and encrypt the whole thing using sharedSecret-derived key const payload = { cardNumber: "4012001037141112", cardExpiry: "2027-12", cvv: encryptedCvv, // CVV is double-encrypted networkType: "VISA", business: "YOUR_BUSINESS_CODE", entityId: "1234567890" }; const encryptedReq = CryptoJS.AES.encrypt( JSON.stringify(payload), payloadKey, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ).toString(); ``` The `encryptedReq` string above is the value to submit in the request body. ### Token Lifecycle - Token state: `ACTIVE` → `CONSUMED` (after one successful transaction) or `EXPIRED` (after ~15 min TTL) - Tokens are **single-use** — each AFT/OCT transaction consumes the token
