Safe Acceptance
This section shows you how to create a Charge using our Safe Acceptance API.
Using Tokens
If your payment flow and use cases make use of our Tokenization API, follow the steps below
- Send the card details from your frontend client to our Tokenization API via xendit.js or our SDKs.
- You can choose whether to initiate 3DS or not via the should_authenticate field in the Tokenization request.
- Xendit returns a token_id to you in the Tokenization (and Authentication, if you initiated 3DS) response.
- Use that token_id to create a Safe Acceptance request, including signature generation and validation. Note that if you have already initiated 3DS for this transaction at the Tokenization stage, you should not initiate 3DS again in the Safe Acceptance API request.
- You will receive the payment success or failure result via the Safe Acceptance webhook, at the return_url which you send to us in the Safe Acceptance request.
Using the full card number (PAN)
If you prefer to charge the card directly from your frontend client, follow the steps below
- Send the card details from your frontend client directly to Xendit in a Safe Acceptance API request, including signature generation and validation.
- In the request, you would include the card PAN in the card_number field (remember to include as much details about the card as you can). Make sure that the PAN is not being sent from your backend server as that breaches PCI-DSS compliance if you are not properly certified.
- If you wish to initiate 3DS authentication for this transaction, set should_authenticate as true in the Safe Acceptance API request.
- If 3DS is initiated, Xendit will return a response containing the URL necessary for generating the 3DS 2-Factor authentication page (e.g. Verified By Visa, MasterCard SecureCode). This must be handled on your frontend client and exposed to the cardholder for 3DS verification.
- When the 3DS process is completed, Xendit will proceed to process the card payment.
- You will receive the payment success or failure result via the Safe Acceptance webhook, at the return_url which you send to us in the Safe Acceptance request.
Signature generation
Why is a signature necessary when sending a request via the Xendit Safe Acceptance API?
Using this API, requests are initiated, and responses returned to, the client side instead of server-to-server. This exposes a possible security vulnerability if the requests/responses are intercepted during communication, and the interceptor interferes with the payload.
The API uses a signature as a validator for requests and corresponding responses. A signature is generated from the request and response body by hashing with a shared secret key that is only known by the merchant and Xendit.
If you verify the signature in Xendit’s response and it does not match your request body, then it is likely that the response has been tampered with and potentially exposed to fraud. The response should be rejected in that situation.
See below for the Safe Acceptance API flow including signature generation and validation.

- Customer clicks on Checkout button and requests for the checkout page
- Merchant backend generates the signature with the order details. This “Merchant signature” is for Xendit to verify that the sender of this request was the merchant and not a third party. At this stage, Xendit validates the Merchant signature using the shared secret
- Customer is brought to the checkout page where they provide payment details
- Customer clicks pay and the safe acceptance API is called using a form POST
- Xendit receives the payment request and redirects the customer to a page to provide further authentication if required
- Customer completes authentication and confirmation is sent to Xendit
- Xendit confirms the payment, generates a payment response and a signature unique to Xendit, and redirects the customer back to the merchant’s page. The “Xendit signature” is for the merchant to verify that the response was sent by Xendit and not a third party.
- Upon redirection by Xendit, customer’s browser loads merchant’s payment confirmation page and sends the payment response and Xendit signature to the merchant backend
- Merchant generates a new signature using the payment response data, and verifies that this new signature matches the Xendit signature
- Renders payment complete page with status of the payment
Test scenarios
Positive Scenarios

Negative Scenarios

Last Updated on 2023-05-19