Get authentication
EndPoint
POST /credit-card/enrollment/validate/:authenticationId
Header Params
| Param | Required | Type | Description | Note | 
|---|---|---|---|---|
| X-APPOTAPAY-AUTH | required | String | How to generate JWT_TOKEN | |
| Content-Type | required | String | Value: application/json | |
| X-Request-ID | optional | String | UUIDv4 format. Request ID to check when a problem occurs | max:42 | 
| Language | optional | String | The value viorencorresponding to the payment link will be Vietnamese or English, (default: vi) | in:vi,en | 
| X-Account-Ref-ID | optional | String | Iidentifier of the sub account provided by AppotaPay. Mandatory be passed over when processing payment for transactions of owner-type sub account | 
{
    "X-APPOTAPAY-AUTH": "JWT_TOKEN",
    "Content-Type": "application/json",
    "X-Request-ID": "Your_Unique_id",
    "Language": "vi",
    "X-Account-Ref-ID": "9723f73b-9295-4acb-884b-ab6310c2e653"
}
Request Params
| Parameters | Requirement | Data type | Description | Note | 
|---|---|---|---|---|
| authenticationId | required | String | authenticationIdis from the URL query when redirecting user to merchant's page | 
Response Params
{
    "authenticationId": "01HQHR9W32E2RDSF6KM51PSJ92",
    "merchantRefId": "HJ1OsUcDI",
    "status": "PENDING",
    "amount": 1000000,
    "currency": "VND",
    "tokenId": "01hqhr8vgdw64qhqgvm2tsbpew",
    "deviceDataCollectionUrl": "https://acpg.dev.appotapay.com/credit-card/authenticate?id=01HQHR9W32E2RDSF6KM51PSJ92&signature=cf6e30824b5e66e0c401701f3416e72c5b069a01c3a80a316cf9e54f9b855675",
    "card": {
        "number": "400000XXXXXX0010",
        "expirationMonth": "12",
        "expirationYear": "29",
        "cardBrand": "MASTERCARD",
        "cardType": "CREDIT",
        "country": "VN"
    }
}
Success
Http Status Code
200-OK
| Parameters | Data type | Description | Note | 
|---|---|---|---|
| authenticationId | String | Unique authentication ID returned by AppotaPay to identify the 3DS transaction. | |
| merchantRefId | String | Your reference ID for identifying the transaction | Min:1 Max:40 | 
| card | String | Data of the card being charged | |
| card.number | String | Card number | 16 numbers | 
| card.expirationMonth | String | Card expiration month, including leading 0 (E.g.: 03 for March) | Format: MM | 
| card.expirationYear | String | Card expiration year (E.g.: 27) | Format: YY | 
| card.type | String | Card type: CREDIT / DEBIT / PREPAID / UNKNOWN | |
| card.brand | String | Card brand: VISA / MASTERCARD / JCB / AMEX | |
| card.country | String | Country of the card issuing bank in ISO 3166-1 alpha-2 format (E.g.: VN, US) | |
| amount | Float | Amount of the payment processed on the card, being submitted for authentication (E.g.: 1000) | Support VND | 
| status | String | Authentication status classified as: CARD_ENROLLEDCard is 3DS enrolled and pending verification by userENROLLMENT_CHECK_FAILEDFailed to check enrollment status. Likely due to an issue with the issuer or card network.CARD_NOT_ENROLLEDCard is not 3DS enrolledVERIFIED3DS verification succeededFAILED3DS verification failedPENDINGEMV 3DS and MIGS only. Redirect the user to the 3DS page to continue the process. | |
| deviceDataCollectionUrl | String | If the status is CARD_ENROLLEDorPENDING, cardholder needs to be redirected to this URL to proceed with 3DS verification | |
| eci | String | ECI status code for card's enrollment. 05or02- Successful authentication. Proceed with authorization.06or01- Card not enrolled or authentication skipped due to frictionless flow. Proceed with authorization.07or00- Failed authentication. | |
| threeDsVersion | String | 3DS version of the current authentication request Examples: - 2.1.0- 3DS 2.0 / EMV 3DS:- 1.0.2- 3DS 1.0 | 
Error
HTTP Status Code !=
200
Authentication Callback
After we receive the 3DS verification result, we will send a callback to the merchant’s callback URL (that the merchant sent us before integration) through a POST request.
Event Schema
| Parameters | Data type | Description | 
|---|---|---|
| event | String | Type of event. For authentication events it will be: credit_card.authentication | 
| responseTime | String | Response time of the event according to RFC-3339 standard, time zone UTC+7 | 
| data | String | Data of the event. See Event Object structure For readable data, you should use: - Base64 Decode data string - Then, JSON Decode data string from string was Base64 Decoded Example decode data: - dataJson = JSON_Decode(Base64_Decode(data)) | 
| signature | String | Signature to verify data signature = HMACSHA256(data, secret_key) - data: param data from request body - secret_key: from your application is registered to AppotaPay | 
Event Object structure
| authenticationId | String | Unique authentication ID returned by AppotaPay to identify the 3DS transaction. | |
| merchantRefId | String | Your reference ID for identifying the transaction | Min:1 Max:40 | 
| card | String | Data of the card being charged | |
| card.number | String | Card number | 16 numbers | 
| card.expirationMonth | String | Card expiration month, including leading 0 (E.g.: 03 for March) | Format: MM | 
| card.expirationYear | String | Card expiration year (E.g.: 27) | Format: YY | 
| card.type | String | Card type: CREDIT / DEBIT / PREPAID / UNKNOWN | |
| card.brand | String | Card brand: VISA / MASTERCARD / JCB / AMEX | |
| card.country | String | Country of the card issuing bank in ISO 3166-1 alpha-2 format (E.g.: VN, US) | |
| amount | Float | Amount of the payment processed on the card, being submitted for authentication (E.g.: 1000) | Support VND | 
| status | String | Authentication status classified as: CARD_ENROLLEDCard is 3DS enrolled and pending verification by userENROLLMENT_CHECK_FAILEDFailed to check enrollment status. Likely due to an issue with the issuer or card network.CARD_NOT_ENROLLEDCard is not 3DS enrolledVERIFIED3DS verification succeededFAILED3DS verification failedPENDINGEMV 3DS and MIGS only. Redirect the user to the 3DS page to continue the process. | |
| eci | String | ECI status code for card's enrollment. 05or02- Successful authentication. Proceed with authorization.06or01- Card not enrolled or authentication skipped due to frictionless flow. Proceed with authorization.07or00- Failed authentication. | |
| threeDsVersion | String | 3DS version of the current authentication request Examples: - 2.1.0- 3DS 2.0 / EMV 3DS:- 1.0.2- 3DS 1.0 | 
Example event callback data
{
  "event": "credit_card.authentication",
  "responseTime": "2023-12-12T11:54:23+07:00",
  "data": "eyJhdXRoZW50aWNhdGlvbklkIjoiMDFISEU2MDJYMzVNV1ZHWUtBREo5UVdNNEciLCJtZXJjaGFudFJlZklkIjoiYXV2ekVla1FRIiwic3RhdHVzIjoiVkVSSUZJRUQiLCJhbW91bnQiOjEwMDAwLCJjdXJyZW5jeSI6IlZORCIsImNhcmQiOnsibnVtYmVyIjoiNTIwMDAwWFhYWFhYMjE1MSIsImV4cGlyYXRpb25Nb250aCI6IjAxIiwiZXhwaXJhdGlvblllYXIiOiIyNCIsImNhcmRCcmFuZCI6Ik1BU1RFUkNBUkQiLCJjYXJkVHlwZSI6IkNSRURJVCIsImNvdW50cnkiOiJNWSJ9LCJlY2kiOiIwMiIsInRocmVlRHNWZXJzaW9uIjoiMi4yLjAifQ",
  "signature": "3d82e6b73cc8ebaa433137d74700422163fc1851d260b879aa7b6041f5bcefbf"
}
When you decode data, you can view callback event data detail:
{
  "event": "credit_card.authentication",
  "responseTime": "2023-12-12T11:54:23+07:00",
  "data": {
    "authenticationId": "01HHE602X35MWVGYKADJ9QWM4G",
    "merchantRefId": "auvzEekQQ",
    "status": "VERIFIED",
    "amount": 10000,
    "currency": "VND",
    "card": {
      "number": "520000XXXXXX2151",
      "expirationMonth": "01",
      "expirationYear": "24",
      "cardBrand": "MASTERCARD",
      "cardType": "CREDIT",
      "country": "MY"
    },
    "eci": "02",
    "threeDsVersion": "2.2.0"
  },
  "signature": "3d82e6b73cc8ebaa433137d74700422163fc1851d260b879aa7b6041f5bcefbf"
}
To verify data by signature, you can use secret_key from JWT (your application was registered)
data = "eyJhdXRoZW50aWNhdGlvbklkIjoiMDFISEU2MDJYMzVNV1ZHWUtBREo5UVdNNEciLCJtZXJjaGFudFJlZklkIjoiYXV2ekVla1FRIiwic3RhdHVzIjoiVkVSSUZJRUQiLCJhbW91bnQiOjEwMDAwLCJjdXJyZW5jeSI6IlZORCIsImNhcmQiOnsibnVtYmVyIjoiNTIwMDAwWFhYWFhYMjE1MSIsImV4cGlyYXRpb25Nb250aCI6IjAxIiwiZXhwaXJhdGlvblllYXIiOiIyNCIsImNhcmRCcmFuZCI6Ik1BU1RFUkNBUkQiLCJjYXJkVHlwZSI6IkNSRURJVCIsImNvdW50cnkiOiJNWSJ9LCJlY2kiOiIwMiIsInRocmVlRHNWZXJzaW9uIjoiMi4yLjAifQ";
secret_key = "Your_secret_key_was_resigtered"
signature = HMACSHA256(data, secret_key)
The reference link to generate the signature: Free online Hash Hmac tool using algorithm SHA1, SHA256, SHA512 and more - Devtool