> ## 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.

# Additional Support for Payment Methods

> Additional support features available for card, netbanking, wallets and more.

<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>

Use the Razorpay Android Custom SDK to integrate supported payment methods on the Checkout form of your Android app as per your business requirements. Here are some **additional methods** provided by the SDK for the integration and usage of payment methods:

* [Card Utilities](/docs/payments/payment-gateway/android-integration/custom/additional-features#card-utilities)
* [Validate VPA](/docs/payments/payment-gateway/android-integration/custom/additional-features#validate-vpa)
* [Fetch Logo](/docs/payments/payment-gateway/android-integration/custom/additional-features#logo)
* [Validate Data](/docs/payments/payment-gateway/android-integration/custom/additional-features#data-validation)
* [Custom `WebViewClient` and `WebChromeClient`](/docs/payments/payment-gateway/android-integration/custom/additional-features#custom-webviewclient-and-webchromeclient)
* [Save Customer Data](/docs/payments/payment-gateway/android-integration/custom/additional-features#save-customer-data)

<br />

## Card Utilities

You can use these methods for card payment method integration.

#### Fetch Card Network

The SDK provides a method to get the card network name of the provided card number. <br />

* At least 6 digits of the card number are required to identify the network. <br />
* Possible values returned by this method are, `visa`,  `mastercard`, `maestro16`, `amex`, `rupay`, `maestro`, `diners` and `unknown`.<br />
* If it is not able to identify the network it returns `unknown`.

```java Java theme={null}
razorpay.getCardNetwork(cardNumber);
```

## Card Number Validation

The SDK provides a checksum-based method to determine if the entered card number is valid or not.

```java Java theme={null}
razorpay.isValidCardNumber(cardNumber);
```

#### Fetch Card Number Length for Card Network

The SDK provides a method to get the length of the card number for a specific card network.

```java Java theme={null}
razorpay.getCardNetworkLength(cardNetworkName);
```

## Validate VPA

The SDK provides a method to determine if the entered Virtual Payment Address (VPA) is valid or not. A failure response is triggered when the `vpaAddress` is empty or the device is not connected to data to make the validation.

<CodeGroup>
  ```java Java theme={null}
  razorpay.isValidVpa("9000090000@ybl", new ValidateVpaCallback() {
              @Override
              public void onResponse(JSONObject response) {
                if(response.has("error")){
                      //VPA validation error: Invalid VPA
                  }else if(response.has("success")){
                      //VPA Validation Successful: Valid VPA
                  }
              }

              @Override
              public void onFailure() {
                 //called in cases where the vpaAddress is empty or when the device is not connected to data to make the validation. 
              }
  });
  ```

  ```java Valid VPA theme={null}
  {
    "vpa": "9000090000@okaxis",
    "success": true,
    "customer_name": null
  }
  ```

  ```java Invalid VPA theme={null}
  {
    "error": {
      "code": "BAD_REQUEST_ERROR",
      "description": "Invalid VPA. Please enter a valid Virtual Payment Address",
      "source": "customer",
      "step": "payment_initiation",
      "reason": "invalid_vpa",
      "metadata": {},
      "field": "vpa"
    }
  }
  ```
</CodeGroup>

## Logo

#### Fetch Bank Logo URL

The SDK provides a method to fetch the bank logo's URL, here `bankCode` is the code of bank, you will be able to get it from the response received in `onPaymentMethodsReceived` callback.

```java Java theme={null}
razorpay.getBankLogoUrl(bankCode);
```

#### Fetch Wallet Logo URL

The SDK provides a method to get the wallet logo's URL.

```java Java theme={null}
razorpay.getWalletLogoUrl(walletName);
```

#### Fetch Wallet Square Logo URL

The SDK provides a method to get the wallet's square-shaped logo's URL.

```java Java theme={null}
razorpay.getWalletSqLogoUrl(walletName);
```

## Data Validation

The SDK provides basic validation for the payment data `JSONObject`. In case of a validation error, the SDK returns an error map in the `onValidationError` callback function.

#### Sample Code

The sample code shown below describes a validation error on the `contact` field:

```java Java theme={null}
razorpay.validateFields(payload, new ValidationListener() {
   @Override
   public void onValidationSuccess() {
       try {
           webview.setVisibility(View.VISIBLE);
           outerBox.setVisibility(View.GONE);
           razorpay.submit(payload, PaymentOptions.this);
       } catch (Exception e) {
           Log.e("com.example", "Exception: ", e);
       }
   }

   @Override
   public void onValidationError(Map error) {
       Log.d("com.example", "Validation failed: " + error.get("field") + " " + error.get("description"));
       Toast.makeText(PaymentOptions.this, "Validation: " + error.get("field") + " " + error.get("description"), Toast.LENGTH_SHORT).show();
   }
});
```

## Custom WebViewClient and WebChromeClient

Our SDK sets an instance of `RazorpayWebViewClient` and `RazorpayWebChromeClient` to the WebView passed to facilitate bank page optimizations. If you want to set your own custom `WebViewClient` you have to extend `RazorpayWebViewClient` and pass it to our SDK.

<Warning>
  **Watch Out!**

  This step is optional and is only required when you want to set a custom `WebViewClient`/`WebChromeClient`
</Warning>

#### Sample Code

The sample code given below shows how to customize the `RazorpayWebViewClient`:

```java Java theme={null}
/**
 * Extend the RazorpayWebViewClient for your custom hooks
 */
razorpay.setWebviewClient(new RazorpayWebViewClient(razorpay){

  @Override
  public void onPageStarted(WebView view, String url, Bitmap favicon) {
      // Make sure you do not forget to call the super method
      super.onPageStarted(view, url, favicon);
      Log.d(TAG, "Custom client onPageStarted");
  }

  @Override
  public void onPageFinished(WebView view, String url) {
      // Make sure you do not forget to call the super method
      super.onPageFinished(view, url);
      Log.d(TAG, "Custom client onPageFinished");
  }
});
```

Similarly, you can set your own `WebChromeClient`:

```java Java theme={null}
/**
 * Extend the RazorpayWebChromeClient for your custom hooks
 */
razorpay.setWebChromeClient(new RazorpayWebChromeClient() {
	@Override
	public void onProgressChanged(WebView view, int newProgress) {
		// Make sure you do not forget to call the super method
		super.onProgressChanged(view, newProgress);
		customProgressBar.setProgress(newProgress);
	}
});
```

## Save Customer Data

You can associate card details with a saved customer or create payments using tokens for saved cards. To use this functionality, you must use [customer APIs](/docs/api/customers) at server side.

#### Create a Payment With New Card

While creating a payment with new card, you would need to pass the `customer_id` and `save` as extra fields, along with the other fields as shown below:

```java JAVA theme={null}
JSONObject data = new JSONObject();
data.put("amount", 29935);
data.put("customer_id", "cust_4lsdkfldlteskf");
data.put("save", 1);
data.put("method", "card");
data.put("card[name]", "Gaurav Kumar");
data.put("card[number]", "4386289407660153");
data.put("card[expiry_month]", "12");
data.put("card[expiry_year]", "20");
data.put("card[cvv]", "100");
```

#### Create a Payment With Existing Saved Card

To create a payment with an existing saved card, you have to pass the token instead of the card number, expiry and card holder's name fields as shown below:

```java JAVA theme={null}
JSONObject data = new JSONObject();
data.put("amount", 29935);
data.put("customer_id", "cust_4lsdkfldlteskf");
data.put("token", "token_4zwefDSCC829ma");
data.put("method", "card");
data.put("card[cvv]", "100");
```
