Upgrade Virtual Card to Physical
Upgrades an existing virtual card to a physical card. A physical card is embossed and dispatched against the supplied communication address, while the card account and balance are retained.
What this does
- Maps the existing virtual card account to a new physical kit (
kitNo). - Optionally applies a specific plastic design (
plasticCodeDto). - Optionally locks the card on upgrade until the customer activates it (
lockOnUpgrade). - Optionally seeds transaction preferences (domestic / international limits).
Notes
kitNois mandatory — it identifies the physical kit being assigned.- If
communicationAddress.usePrimaryAddressistrue, the customer's primary address on file is used and the other address fields may be omitted. - Address fields are encrypted/masked in transit per PCI/PII handling.
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
Physical card upgrade details
Required. Physical kit number being assigned to the card.
1 <= lengthCommunication / mailing address. Address lines are encrypted and masked in transit.
Plastic design / code applied to the physical card.
When true, the card is locked on upgrade until the customer activates it.
falseDomestic and international preference categories
Response Body
application/json
application/json
application/json
curl -X PUT "https://sandbox-api.m2pprepaid.com/prepaid/customer/v1/cards/upgrade/physical" \ -H "X-TENANT-ID: ACME_CORP" \ -H "Content-Type: application/json" \ -d '{ "kitNo": "20004574", "lockOnUpgrade": false, "communicationAddress": { "address1": "123 Main Street", "address2": "Apt 4B", "city": "Chennai", "state": "Tamil Nadu", "country": "India", "pin": "600001", "usePrimaryAddress": false }, "plasticCodeDto": { "code": "PLASTIC001", "description": "Standard card design" } }'{
"result": {
"message": "Card upgraded to physical successfully"
},
"pagination": null
}{
"type": "https://www.m2pfintech.com/problem/constraint-violation",
"title": "Method argument not valid",
"status": 400,
"message": "error.validation",
"fieldErrors": [
{
"field": "mobile",
"message": "Invalid contact",
"objectName": "changeCardPin"
}
]
}{
"type": "https://www.m2pfintech.com/problem/problem-with-message",
"title": "Invalid Kit",
"status": 409,
"detail": "Invalid Kit",
"message": "error.business",
"businessCode": "PPCUST_018"
}Update Card PIN (Change Existing PIN) POST
Changes the card PIN from an existing PIN to a new PIN. Requires the current PIN and OTP verification. ### Difference from Set PIN - **Set PIN (v2)**: For first-time PIN setup or reset. Uses RSA-encrypted PIN. - **Update PIN**: For changing an existing PIN. Uses plain-text PIN (4 digits). ### PIN Lock Protection After 3 consecutive failed OTP attempts, the PIN change operation is locked for **10 minutes**. This prevents brute-force attacks. ### Flow 1. Generate OTP → receive `traceNumber` 2. Call this API with `oldPin`, `newPin`, OTP, and `traceNumber`
Validate Card PIN POST
Verifies whether the provided PIN is correct for the given card. This is a read-only check — it does not modify the PIN. ### When to Use - Pre-validate PIN before a sensitive operation (e.g., viewing card details) - Implement "confirm PIN" flows in your mobile/web app - PIN-based authentication for in-app transactions ### Important Notes - Returns `{ valid: true/false }` — never reveals the actual PIN - Uses the same `ChangeCardPinDto` as Set/Update PIN but only reads `oldPin` - No OTP required for validation
