Guest checkout, also known as a one-off payment, is the simplest way for customers to complete a transaction without needing to create an account. During this process, customers enter their card details, authenticate themselves, and finalize their purchase.
Guest checkout flow
1. Create a payment session
Request - POST /sessions
| Response - POST /sessions
|
---|
2. Collect card information
Implement card_session.js on your page. Collect the card information using Xendit.payment.collectCardData(reqData, xenditResponseHandler)
. This will collect the card information and send it to Xendit using card_session.js.
Request - to card_session_js
| Response - from card_session_js
|
---|
Important: Store the payment_request_id
. You'll need it to retrieve the transaction's status and it will be included in the payment webhook for status updates.
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 failure_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.
Guest checkout without authentication (one-off payment)
We highly recommend performing authentication when processing card transactions. Authentication does not only provide a liability shift (protecting you from certain fraud disputes), it additionally ensures users are who they say they are.
However, upon request and after a risk-based assessment, Xendit can activate guest checkout without mandating authentication. We’ll perform a risk-based assessment, before allowing you to accept transactions without authentication.
Guest checkout flow without authentication
How to implement
1. Create a payment session
Request - POST /sessions
| Response - POST /sessions
|
---|
2. Gather the card information
Similar to the authenticated flow, Initiate card_session.js on your page and use Xendit.payment.collectCardData(reqData, xenditResponseHandler)
to collect the card details. This will collect the card information and send it to Xendit using card_session.js.
Request - to card_session_js
| Response - from card_session_js
|
---|
Important: Make sure to store the payment_request_id
as you’ll need it to retrieve the state of the transaction at a later stage.
3. Receive the webhook
Xendit will immediately send a payment webhook to your webhook endpoint with the final transaction status. You can match the payment webhook with the payment_request_id.
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"
}
As with the authenticated flow, you can save the payment_id
and payment_details
correlated with the payment_request_id
as proof of payment.
4. Get the status of the transaction
If you prefer to poll for the transaction status rather than relying solely on webhooks, you can use the GET Payment Request endpoint with your payment_request_id
.
Request: GET https://api.xendit.co/v3/payment_requests/YOUR_PAYMENT_REQUEST_ID
This will return the status of the transaction.
Response - from payment_requests
|
---|