> ## Documentation Index
> Fetch the complete documentation index at: https://razorpay-881012b3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Business Seeks Customer Consent, Saves Card Details With Razorpay

> Procedure to follow if you plan to collect customer consent on your UI.

<div style={{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"0.35rem 0.9rem",border:"1px solid rgba(128,128,128,0.28)",borderRadius:"0.5rem",padding:"0.45rem 0.75rem",margin:"0 0 1.25rem",fontSize:"0.875rem"}}>
  <span style={{fontWeight:600}}>Available in</span>
  <span>🇮🇳 India</span>
</div>

Given below are the integration steps to save cards as tokens with card networks.

## New Card Workflow

New cards are the cards that are not saved with Razorpay previously. Follow the below integration steps:

1. [Changes on checkout UI.](#1-checkout-ui)
2. [Changes in integration code.](#2-integration-code)

## 1. Checkout UI

You should modify your user interface to explicitly receive customer consent for saving card details as tokens with card networks.

## 2. Integration Code

### 2.1 Create a Customer

You can create customers using the [Create a Customer API](/docs/api/customers). The `customer_id` received in the response should be passed in the Create Payment request.

### 2.2 Create Payment

Use the following code to **Create a Payment**.

```javascript Custom Checkout theme={null}
<script src="https://checkout.razorpay.com/v1/razorpay.js"></script>
  <button id="rzp-button1" style="background-color: #3399cc; color: white; font-size: 16px; font-family: sans-serif">Pay</button>
  <script>
       var razorpay = new Razorpay({
        key: "<YOUR_KEY_ID>",
        image: "https://i.imgur.com/n5tjHFD.jpg",
        name: "<name>",
       });
       var data = {
        amount: 6666,
        currency: "INR",
        order_id: "order_ISsp1ekSCHgoAw",
        email: "<email>",
        contact: <phone>,
        notes: {
          address: "Ground Floor, SJR Cyber, Laskar Hosur Road, Bengaluru",
        },
        customer_id: "cust_1Aa00000000001",
        save: 1,
        method: "card",
        card[number]: '4242424242424242',
        card[expiry_month]: '11',
        card[expiry_year]: '23',
        card[cvv]: '123',
        card[name]: '<name>'
       };

       document.getElementById("rzp-button1").onclick = function(){
        razorpay.createPayment(data);
        razorpay.on("payment.success", function(resp) {
          alert(resp.razorpay_payment_id)
          });
        razorpay.on("payment.error", function(resp){alert(resp.error.description)});
}
</script>
```

#### Request Parameters

`save` *mandatory*
: `integer` Determines whether Razorpay should save customer card details as tokens with the card networks. Possible values:

* `1`: Razorpay should save customer card details as tokens with the card networks. This will work only if explicit customer consent has been received from the customer.
* `0`: Razorpay should not save the card details.

`card` *mandatory*
: The details of the card that should be entered while making the payment.

`number`
: `string` Unformatted card number.

`name`
: `string` The name of the cardholder.

`expiry_month`
: `string` Expiry month for card in MM format.

`expiry_year`
: `string` Expiry year for card in YY format.

`cvv`
: `string` The card's CVV number.

<Info>
  **Handy Tips**

  * CVV is not required by default for tokenised cards across all networks.
  * CVV is optional for tokenised card payments. Do not pass dummy CVV values.
  * To implement this change, skip passing the `cvv` parameter entirely, or pass a `null` or empty value in the CVV field.
  * We recommend removing the CVV field from your checkout UI/UX for tokenised cards.
  * If CVV is still collected for tokenised cards and the customer enters a CVV, pass the entered CVV value to Razorpay.
</Info>

`customer_id` *mandatory*
: `string` Unique identifier of the customer. This can be obtained from the response of the previous step.

### 2.3 Fetch all Tokens of Customer

Fetch all tokens created for a customer using the API given below.

`GET /customers/:customer_id/tokens`

<CodeGroup>
  ```bash Curl theme={null}
  curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET] \
  -X GET https://api.razorpay.com/v1/customers/:customer_id/tokens
  ```

  ```php PHP theme={null}
  $api = new Api($key_id, $secret);
  $api->customer->fetch($customerId)->tokens()->all();
  ```

  ```python Python theme={null}
  import razorpay
  client = razorpay.Client(auth=("YOUR_ID", "YOUR_SECRET"))

  client.token.all(customerId)
  ```

  ```javascript Node.js theme={null}
  var instance = new Razorpay({ key_id: 'YOUR_KEY_ID', key_secret: 'YOUR_SECRET' })
  instance.customers.fetchTokens(customerId)
  ```

  ```ruby Ruby theme={null}
  require "razorpay"
  Razorpay.setup('YOUR_KEY_ID', 'YOUR_SECRET')

  customerId = "cust_1Aa00000000004"

  Razorpay::Customer.fetch(customerId).fetchTokens
  ```

  ```java Java theme={null}
  RazorpayClient razorpay = new RazorpayClient("[YOUR_KEY_ID]", "[YOUR_KEY_SECRET]");

  String customerId = "cust_DtHaBuooGHTuyZ";

  List<Customer> customer = instance.customers.fetchTokens(customerId);
  ```

  ```go Go theme={null}
  import ( razorpay "github.com/razorpay/razorpay-go" )
  client := razorpay.NewClient("YOUR_KEY_ID", "YOUR_SECRET")

  body, err := client.Token.All("<customerId>", nil, nil)
  ```

  ```json Response theme={null}
  {
    "entity" : "collection",
    "count" : 2,
    "items" : [
      {
        "id" : "token_4lsdksD31GaZ09",
        "entity" : "token",
        "method" : "card",
        "card" : {
          "entity" : "card",
          "last4" : 1111,
          "network" : "Visa",
          "emi" : true,
          "issuer" : "HDFC",
          "international": false,
          "sub_type": "consumer",
          "token_iin": "453335",
          "type": "credit"
        },
        "used_at" : 1473765044,
        "created_at" : 1473765044,
        "status": "active",
        "compliant_with_tokenisation_guidelines": true  // This is for Indian Cards only
      },
      {
        "id" : "token_4lsdksD31GaZ08",
        "entity" : "token",
        "method" : "card",
        "card" : {
          "entity" : "card",
          "last4" : 1111,
          "network" : "Visa",
          "emi" : true,
          "issuer" : "HDFC",
          "international": false,
          "sub_type": "consumer",
          "token_iin": "453325",
          "type": "credit"
        },
        "used_at" : 1473765044,
        "created_at" : 1473765044,
        "status": "active",
        "compliant_with_tokenisation_guidelines": true // This is for Indian Cards only
      }
    ]
  }
  ```
</CodeGroup>

#### Path Parameter

`customer_id`
: `string` Unique identifier of the customer.

#### Response Parameters

`id`
: `string` The unique identifier of the Razorpay token.

`entity`
: `string` The name of the entity. Here, it is `token`.

`method`
: `string` The type of saved instrument. In the current use case, the value is `card`.

`card`
: `object` The customer card details.

`last4`
: `string` The last 4 digits of the tokenised card.

`network`
: `string` The card network. Possible values:

* `Visa`
* `RuPay`
* `MasterCard`
* `American Express`
* `Diners Club` (Only available for private limited and registered businesses)
* `Maestro`
* `JCB`
* `Union Pay`

`issuer`
: `string` The 4-character issuer code unique to each issuing bank in India. For example, `HDFC`, `SBIN` and so on.

`type`
: `string` The type of card. Possible values:

* `credit`
* `debit`
* `prepaid`

`international`
: `boolean` Indicates whether the card is international (issued outside India) or domestic. Possible values:

* `true`: The card is international.
* `false`: The card is domestic.

`emi`
: `boolean` Indicates whether the card is eligible for EMI payments or not. Possible values:

* `true`: The card is eligible for EMI payments.
* `false`: The card is not eligible for EMI payments.

`sub_type`
: `string` The card sub\_type for the given IIN. Pricing of card payment may change on the basis of card type. Possible values:

* `consumer`
* `business`
* `unknown`

`compliant_with_tokenisation_guidelines`
: `boolean` Indicates whether the token is compliant with the RBI guidelines. Possible values:

* `true`: The token is compliant with RBI guidelines.
* `false`: The token is not compliant with RBI guidelines.

`status`
: `string` The overall status for the token. Possible values:

* `initiated`: The token attains this state after Razorpay has received the tokenisation request and is working with token service providers for creating the token.
* `active`: The token attains this state if the token is activated for at least one of the token service providers.
* `suspended`: The token attains this state if: <br />- The token is not activated for any one of the token service providers. <br />- The token is suspended for at least one of the token service providers.
* `deactivated`: The token attains this state if the token is not active/suspended for any one of the token service providers and is deactivated for at least one token service provider. Know about the complete list of [token states](/docs/payments/payment-methods/cards/token-hq/merchant-requestor/token-lifecycle).

### 2.4 Fetch Card Properties of an Existing Token

Use this API to retrieve card details such as network, issuer and so on for a given token.

`GET /customers/:customer_id/tokens/:token_id`

<CodeGroup>
  ```bash Curl theme={null}
  curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET]
  -X GET https://api.razorpay.com/v1/customers/:customer_id/tokens/:token_id
  ```

  ```java Java theme={null}
  RazorpayClient razorpay = new RazorpayClient("[YOUR_KEY_ID]", "[YOUR_KEY_SECRET]");

  String customerId = "cust_DtHaBuooGHTuyZ";

  String tokenId = "token_HouA2OQR5Z2jTL";

  Customer customer = razorpay.customers.fetchToken(customerId, tokenId)
  ```

  ```python Python theme={null}
  import razorpay
  client = razorpay.Client(auth=("YOUR_ID", "YOUR_SECRET"))

  client.token.fetch(customerId, tokenId)
  ```

  ```php PHP theme={null}
  $api = new Api($key_id, $secret);

  $api->customer->fetch($customerId)->tokens()->fetch($tokenId);
  ```

  ```ruby Ruby theme={null}
  require "razorpay"
  Razorpay.setup('YOUR_KEY_ID', 'YOUR_SECRET')

  customerId = "cust_1Aa00000000004"

  tokenId = "token_Hxe0skTXLeg9pF"

  Razorpay::Customer.fetch(customerId).fetchToken(tokenId)
  ```

  ```javascript Node.js theme={null}
  var instance = new Razorpay({ key_id: 'YOUR_KEY_ID', key_secret: 'YOUR_SECRET' })

  instance.customers.fetchToken(customerId, tokenId)
  ```

  ```go Go theme={null}
  import ( razorpay "github.com/razorpay/razorpay-go" )
  client := razorpay.NewClient("YOUR_KEY_ID", "YOUR_SECRET")

  body, err := client.Token.Fetch("<customerId>", "<tokenId>", nil, nil)
  ```

  ```json Response theme={null}
  {
    "id": "token_4lsdksD31GaZ09",
    "entity": "token",
    "method": "card",
    "card": {
      "entity": "card",
      "last4": 0153,
      "network": "Visa",
      "emi": true,
      "issuer": "HDFC",
      "international": false,
      "sub_type": "consumer",
      "token_iin": "453335",
      "type": "credit"
    },
    "used_at": 1473765044,
    "created_at": 1473765044,
    "status": "active",
    "compliant_with_tokenisation_guidelines": true  // This is for Indian Cards only
  }
  ```
</CodeGroup>

### Path Parameter

`customer_id`
: `string` Unique identifier of the customer.

`token_id`
: `string` Unique identifier of the token.

#### Response Parameters

`id`
: `string` The unique identifier of the Razorpay token.

`entity`
: `string` The name of the entity. Here, it is `token`.

`method`
: `string` The type of saved instrument. In the current use case, the value is `card`.

`card`
: `object` The customer card details.

`last4`
: `string` The last 4 digits of the tokenised card.

`network`
: `string` The card network. Possible values:

* `Visa`
* `RuPay`
* `MasterCard`
* `American Express`
* `Diners Club` (Only available for private limited and registered businesses)
* `Maestro`
* `JCB`
* `Union Pay`

`issuer`
: `string` The 4-character issuer code unique to each issuing bank in India. For example, `HDFC`, `SBIN` and so on.

`type`
: `string` The type of card. Possible values:

* `credit`
* `debit`
* `prepaid`

`international`
: `boolean` Indicates whether the card is international (issued outside India) or domestic. Possible values:

* `true`: The card is international.
* `false`: The card is domestic.

`emi`
: `boolean` Indicates whether the card is eligible for EMI payments or not. Possible values:

* `true`: The card is eligible for EMI payments.
* `false`: The card is not eligible for EMI payments.

`sub_type`
: `string` The card sub\_type for the given IIN. Pricing of card payment may change on the basis of card type. Possible values:

* `consumer`
* `business`
* `unknown`

`compliant_with_tokenisation_guidelines`
: `boolean` Indicates whether the token is compliant with the RBI guidelines. Possible values:

* `true`: The token is compliant with RBI guidelines.
* `false`: The token is not compliant with RBI guidelines.

`status`
: `string` The overall status for the token. Possible values:

* `initiated`: The token attains this state after Razorpay has received the tokenisation request and is working with token service providers for creating the token.
* `active`: The token attains this state if the token is activated for at least one of the token service providers.
* `suspended`: The token attains this state if: <br />- The token is not activated for any one of the token service providers. <br />- The token is suspended for at least one of the token service providers.
* `deactivated`: The token attains this state if the token is not active/suspended for any one of the token service providers and is deactivated for at least one token service provider. Know about the complete list of [token states](/docs/payments/payment-methods/cards/token-hq/merchant-requestor/token-lifecycle).

### 2.5 Create Payments Using Saved Card

After the card is saved, customers can quickly complete the payment for every subsequent online transaction by entering only the `cvv`.

```javascript Custom Checkout theme={null}
<script src="https://checkout.razorpay.com/v1/razorpay.js"></script>
  <button id="rzp-button1" style="background-color: #3399cc; color: white; font-size: 16px; font-family: sans-serif">Pay</button>
  <script>
       var razorpay = new Razorpay({
        key: "<YOUR_KEY_ID>",
        image: "https://i.imgur.com/n5tjHFD.jpg",
        name: "Crime Master Gogo",
       });
       var data = {
        amount: 6666,
        currency: "INR",
        email: "<email>",
        order_id: "order_ISsp1ekSCHgoAw",
        contact: 9123456780,
        notes: {
          address: "Ground Floor, SJR Cyber, Laskar Hosur Road, Bengaluru",
        },
        customer_id: "cust_1Aa00000000001",
        token: "token_4zwefDSCC829ma",
        method: "card",
        card[cvv]: '123'
       };

       document.getElementById("rzp-button1").onclick = function(){
        razorpay.createPayment(data);
        razorpay.on("payment.success", function(resp) {
          alert(resp.razorpay_payment_id)
          });
        razorpay.on("payment.error", function(resp){alert(resp.error.description)});
}
</script>
```

#### Request Parameters

`customer_id`
: `string` Unique identifier of the customer.

`token`
: `string` Unique identifier of the token saved with the card networks.

`card[cvv]`
: `string` CVV of the card.

<Info>
  **Handy Tips**

  * CVV is not required by default for tokenised cards across all networks.
  * CVV is optional for tokenised card payments. Do not pass dummy CVV values.
  * To implement this change, skip passing the `cvv` parameter entirely, or pass a `null` or empty value in the CVV field.
  * We recommend removing the CVV field from your checkout UI/UX for tokenised cards.
  * If CVV is still collected for tokenised cards and the customer enters a CVV, pass the entered CVV value to Razorpay.
</Info>

### 2.6 Delete Tokens

If the customers want to remove the saved cards from their respective accounts, use the following API to delete the tokens.

`DELETE /customers/:customer_id/tokens/:token_id`

<CodeGroup>
  ```bash Curl theme={null}
  curl -u [YOUR_KEY_ID]:[YOUR_KEY_SECRET] \
  -X DELETE https://api.razorpay.com/v1/customers/cust_1Aa00000000001/tokens/token_4zwefDSCC829ma
  ```

  ```java Java theme={null}
  RazorpayClient razorpay = new RazorpayClient("[YOUR_KEY_ID]", "[YOUR_KEY_SECRET]");

  String customerId = "cust_DtHaBuooGHTuyZ";

  String tokenId = "token_HouA2OQR5Z2jTL";

  Customer customer = razorpay.customers.deleteToken(customerId, tokenId);
  ```

  ```python Python theme={null}
  import razorpay
  client = razorpay.Client(auth=("YOUR_ID", "YOUR_SECRET"))

  client.token.delete(customerId, tokenId)
  ```

  ```php PHP theme={null}
  $api = new Api($key_id, $secret);

  $api->customer->fetch($customerId)->tokens()->delete($tokenId);
  ```

  ```ruby Ruby theme={null}
  require "razorpay"
  Razorpay.setup('YOUR_KEY_ID', 'YOUR_SECRET')

  customerId = "cust_1Aa00000000004"

  tokenId = "token_Hxe0skTXLeg9pF"

  Razorpay::fetch(customerId).deleteToken(tokenId)
  ```

  ```javascript Node.js theme={null}
  var instance = new Razorpay({ key_id: 'YOUR_KEY_ID', key_secret: 'YOUR_SECRET' })

  instance.customers.deleteToken(customerId, tokenId)
  ```

  ```go Go theme={null}
  import ( razorpay "github.com/razorpay/razorpay-go" )
  client := razorpay.NewClient("YOUR_KEY_ID", "YOUR_SECRET")

  body, err := client.Token.Delete("<customerId>", "<tokenId>", nil, nil)
  ```

  ```json Response theme={null}
  {
      "deleted": true
  }
  ```
</CodeGroup>

#### Path Parameters

`customer_id`
: `string` Unique identifier of the customer.

`token`
: `string` Token of the saved method that needs to be deleted.

### Delete Saved Card Details

Customers can delete their card details. Check this [demo](https://razorpay.com/flashcheckout/manage/) and follow the on-screen instructions.

## Existing Saved Card

* Existing cards are those cards whose details are saved with Razorpay on Razorpay servers.
* Razorpay saves the existing card details as network tokens if the customer provides explicit consent.
* The businesses signify customer consent by sending the `consent_to_save_card=1` parameter in the Create Payment request.

<Info>
  **Handy Tips**

  * To save the card details, you must share `consent_to_save_card=1` till 30 June 2022. You do not need to send it from 01 July 2022 onwards.
  * If you share `consent_to_save_card=0`, Razorpay will not save cards. You do not need to send it from 01 July 2022 onwards.
</Info>

* If the **customer does not provide consent**, the **card details are not saved**.

<Info>
  **Handy Tips**

  The existing card details are saved as network tokens whether the **Collect Consent from Customers** feature is enabled on the Dashboard or not, provided `consent_to_save_card=1`.
</Info>

Given below is the sample code:

```javascript Custom Checkout theme={null}
<script src="https://checkout.razorpay.com/v1/razorpay.js"></script>
  <button id="rzp-button1" style="background-color: #3399cc; color: white; font-size: 16px; font-family: sans-serif">Pay</button>
  <script>
       var razorpay = new Razorpay({
        key: "<YOUR_KEY_ID>",
        image: "https://i.imgur.com/n5tjHFD.jpg",
        name: "<name>",
       });
       var data = {
        amount: 6666,
        currency: "INR",
        email: "<email>",
        order_id: "order_ISsp1ekSCHgoAw",
        contact: 9123456780,
        notes: {
          address: "Ground Floor, SJR Cyber, Laskar Hosur Road, Bengaluru",
        },
        customer_id: "cust_1Aa00000000001",
        token: "token_4zwefDSCC829ma",
        method: "card",
        card[cvv]: '123',
        consent_to_save_card: 1
       };

       document.getElementById("rzp-button1").onclick = function(){
        razorpay.createPayment(data);
        razorpay.on("payment.success", function(resp) {
          alert(resp.razorpay_payment_id)
          });
        razorpay.on("payment.error", function(resp){alert(resp.error.description)});
}
</script>
```
