Card Activation
Flow Summary
The current activation flow is:
Step 1. Resend the activation OTPPOST /api/v1/cards/resend-activation-otp
Step 2. Verify the OTPPOST /api/v1/cards/verify-activation-otp
Step 3. Activate the cardPOST /api/v1/cards/activate
All routes below should be treated as protected routes and sent with:
Authorization: Bearer <access_token>
All three routes below also pass through DecryptField(), so they accept either plain JSON or the encrypted wrapper described in Overview.
1. Resend Card Activation OTP
POST /api/v1/cards/resend-activation-otp
Sends a fresh OTP for physical-card activation.
Important backend behavior
- Requires the latest physical card request still in processing
- Requires the current user to already have an email address
- The service stores the OTP in Redis for
5minutes - The response always includes
remaining_seconds: 60 - The handler message implies a 60-second resend cooldown, but the current service does not actually enforce that cooldown before issuing a new OTP
Success response shape
{
"status_code": 200,
"message": "Card activation OTP sent successfully",
"data": {
"success": true,
"remaining_seconds": 60
}
}
2. Verify Card Activation OTP
POST /api/v1/cards/verify-activation-otp
Verifies the OTP and returns the activation payload needed for the final activation call.
Request
{
"otp_code": "123456"
}
Important backend behavior
- The OTP is checked against Redis key
otp:card_activation:<mobileUserID> - The stored OTP is six digits
- On success, the service returns the latest processing physical card request's activation payload
Success response shape
{
"status_code": 200,
"message": "Success",
"data": {
"card_id": "5e5d4990-2241-46dc-9dbd-8abcf97e6061",
"activation_code": "12345678"
}
}
3. Activate Card
POST /api/v1/cards/activate
Completes physical-card activation with the upstream card UUID, activation code, and a new card PIN.
Request
{
"card_id": "5e5d4990-2241-46dc-9dbd-8abcf97e6061",
"activation_code": "12345678",
"pin": "123456",
"confirm_pin": "123456"
}
Request rules
card_idis requiredcard_idmust be a UUID stringactivation_codeis required and must be exactly 8 digitspinis required and must be exactly 6 digitsconfirm_pinis required and must exactly matchpin
Important backend behavior
- This route is synchronous, not queued
- It calls UQPay directly and returns the upstream activation result
- On upstream validation failure, the API returns a business error with the parsed upstream metadata in the payload