--- title: "Pay and save (tokenizing the card)" slug: "create-a-token" updated: 2025-10-02T05:55:49Z published: 2025-10-02T05:55:49Z canonical: "docs.xendit.co/create-a-token" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.xendit.co/llms.txt > Use this file to discover all available pages before exploring further. # Pay and save (tokenizing the card) > [!WARNING] > You need to be fully PCI-DSS level 1 compliant to be allowed to do full PAN integrations > > Reach out to Xendit support in case you would like to see this flow activated, we will ask you to provide proof of PCI-DSS compliance. This guide is applicable for PCI-DSS level 1 compliant merchants who store their card details with Xendit. *These scenarios all create* ***tokens****, which can be used in follow up transactions.* This describes how to create at token for one of the following scenarios: - One click (store a card for a customer, for customer initiated transactions) - Using a stored card (token) for a transaction Request - POST `/v3/payment_requests` ```json {  "reference_id": "YOUR_REFERENCE_ID",  "type": "PAY_AND_SAVE",  "country": "ID",  "currency": "IDR",  "request_amount": 10000,  "capture_method": "AUTOMATIC",  "channel_code": "CARDS",  "customer": {        "reference_id": "YOUR_CUSTOMER_REFERENCE_ID",        "type": "INDIVIDUAL",        "email": "test@yourdomain.com",        "mobile_number": "+6212345678",        "individual_detail": {            "given_names": "Lorem",            "surname": "Ipsum"        }    },  "channel_properties": {    "card_details": {            "card_number": "4000000000001091",            "cvn": "123",            "cardholder_first_name": "cardHolderFirstName",            "cardholder_last_name": "cardHolderLastName",            "cardholder_email": "edrich@xendit.co",            "expiry_month": "12",            "expiry_year": "2029"        },    "failure_return_url": "https://xendit.co/failure",    "success_return_url": "https://xendit.co/success",    "statement_descriptor": "Goods"  },  "description": "Description example",  "metadata": {    "metametadata": "Your meta data"  } } ``` Response - POST `/v3/payment_requests` ```json {    "payment_request_id": "pr-UNIQUE_PAYMENT_REQUEST_ID",    "country": "ID",    ....    "type": "PAY_AND_SAVE",    "actions": [        {            "type": "REDIRECT_CUSTOMER",            "descriptor": "WEB_URL",            "value": "https://redirect.xendit.co/authentications/68c3b6cef51176d7246173ea/render?api_key=xnd_public_development_kSJeNzbAo6DEkX1poFWVLBsmR0nJ8WnjpdQpf4dfIPXgDBltJmH7CZGVUfWWI"        }    ] } ``` **2. Store the payment_request_id and redirect to the authentication page** Redirect your customer to the [authentication page](/docs/authentication-3ds2) provided by the `action_url` from the response object. This is where the cardholder completes the 3D Secure authentication. **3. 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`. **4. 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. When successful, this response will contain a `payment_token_id` which you can use for [follow up transactions](/docs/create-a-token#follow-up-transaction-using-a-token). ## Retrieving the card token If the payment is successful the card token will be retrievable by listening to the webhook and is called `payment_token_id`. It can also be retrieved by making a GET request with the `payment_request_id` to `/v3/payment_requests`. Request - GET `/v3/payment_requests/YOUR_PAYMENT_REQUEST_ID` Response ```json {    "payment_request_id": "pr-YOUR_PAYMENT_REQUEST_ID",    "country": "ID",    "currency": "IDR",    "business_id": "YOUR_BUSINESS_ID",    "reference_id": "YOUR_REFERENCE_ID",    "description": "Description examples",    "created": "2025-09-10T05:59:42.148Z",    "updated": "2025-09-10T06:00:05.032Z",    "status": "SUCCEEDED",    "capture_method": "AUTOMATIC",    "latest_payment_id": "py-YOUR_PAYMENT_ID",    //....    //This is the field needed for follow up transactions:    "payment_token_id": "pt-YOUR_PAYMENT_TOKEN_ID",    "type": "PAY_AND_SAVE",    "actions": [] } ``` ## Follow up transaction using a token: Request - POST `/v3/payment_requests` (this sample request, skips authentication (3DS)). ```json {    "country": "ID",    "currency": "IDR",    "request_amount": 300000,    "reference_id": "YOUR_REFERENCE_ID",    "type": "PAY",    "payment_token_id":"pt-YOUR_PAYMENT_TOKEN_ID",    "channel_properties": {        "skip_three_ds": true,        "success_return_url": "https://xendit.co/success",        "failure_return_url": "https://xendit.co/failure"    } } ``` This will lead to an authentication or, in this case of `skip_three_ds: true` a transaction. Response - POST `/v3/payment_requests` ```json {    "payment_request_id": "pr-UNIQUE_PAYMENT_REQUEST_ID",    "country": "ID",    "currency": "IDR",    "business_id": "YOUR_BUSINESS_ID",    "reference_id": "YOUR_REFERENCE_ID",    ....    "channel_properties": {        ....        "card_on_file_type": "CUSTOMER_UNSCHEDULED",        "transaction_sequence": "SUBSEQUENT"    },    "payment_token_id": "pt-YOUR_PAYMENT_TOKEN_ID", // The payment token ID used in the payment request    "type": "PAY",    "actions": [] } ```