Including the Card Verification Number (CVN) is crucial for successful card transactions. While often optional, providing the CVN significantly improves approval rates, especially for European cards which commonly decline without it. To facilitate secure, one-click payments, you can enable end-users to reuse their stored card details while still requiring CVN and authentication for every transaction.
One-click payment flow
Once a card is stored, you can use the payment_token_id for future payments. For added security, your customers may be required to re-enter their CVN during one-click payments, ensuring compliance and reducing fraud risk.
How to Implement
Create a payment session
Initiate a payment session by sending a POST request to the
/sessions
endpoint. This request should include thecard_payment_token_id
of the stored card.
Request - POST /sessions
| Response - POST /sessions
|
---|
Collect the CVN
Implement card_session.js in the head element of your payment page
<head>
<script type="text/javascript" src="https://js.xendit.co/cards-session.min.js">
</head>
Then, collect the CVN information
<head>
<script type="text/javascript" src="https://js.xendit.co/cards-session.min.js">
</head>
<body>
<div class="credit-card-form">
<form id="credit-card-form">
<div class="form-group">
<label for="cvn">CVN</label>
<input type="text" id="cvn" name="cvn" placeholder="123" />
</div>
</form>
</div>
<script type="text/javascript">
</script>
</body>
Request - to card_session_js
| Response - from card_session_js
|
---|
Important: Store the payment_request_id
as it is crucial for tracking the transaction status and will be included in the payment webhook.
3. Redirect to the authentication page
Redirect your customer to the authentication page provided by the action_url
from the response object. This is where the cardholder completes the 3D Secure authentication.
4. Customer completes authentication
After successfully authenticating, your customer will be redirected to your success_return_url
. If authentication fails, they will be redirected to your cancel_return_url
.
5. Receive the webhook
Xendit will send a payment webhook to your configured webhook endpoint, indicating the final status of the transaction. You can match this webhook with the payment_request_id
you stored earlier.
Example payment.capture
webhook
{
"created": "2024-12-18T05:46:35.109Z",
"business_id": "62440e322008e87fb29c1fd0",
"event": "payment.capture",
"data": {
"type": "PAY",
"status": "SUCCEEDED",
"country": "ID",
"created": "2024-12-18T05:46:08.192Z",
"updated": "2024-12-18T05:46:30.627Z",
"captures": [
{
"capture_id": "cptr-08f17fa3-e80c-4d8e-8c34-17aa3400bc1c",
"capture_amount": 10000,
"capture_timestamp": "2024-12-18T05:46:34.234Z"
}
],
"currency": "IDR",
"payment_id": "py-3f57d678-2448-4c9f-a433-8468d366fb5c",
"business_id": "62440e322008e87fb29c1fd0",
"customer_id": "cust-7de9a9b4-37e8-40ad-b665-d97f42e538c5",
"channel_code": "CARDS",
"reference_id": "97ba0a32-b996-4abf-8a7b-6184a6644676_b8d18f2f-3",
"capture_method": "AUTOMATIC",
"request_amount": 10000,
"payment_details": {
"authorization_data": {
"reconciliation_id": "7345007929096981703954",
"authorization_code": "831000",
"acquirer_merchant_id": "xendit_ctv_agg",
"network_response_code": "00",
"network_transaction_id": "016153570198200",
"cvn_verification_result": "M",
"retrieval_reference_number": "435205253972",
"address_verification_result": "M",
"network_response_code_descriptor": "Approved and completed sucessfully"
},
"authentication_data": {
"flow": "CHALLENGE",
"a_res": {
"eci": "05",
"message_version": "2.1.0",
"authentication_value": "AAIBBYNoEwAAACcKhAJkdQAAAAA=","directory_server_trans_id": "e537f539-d59f-4ebe-8d56-7fdc31a8e9b4"
}
}
},
"payment_request_id": "pr-5593127f-8c7b-4d2f-b487-c785ffc21e2f"
},
"api_version": "v3"
}
It's recommended to save the payment_id
and payment_details
from the webhook, correlated with the payment_request_id
, as proof of payment.
Example implementation
For a practical demonstration of collecting CVN using card_session.js
on your frontend, refer to our example page: