# Save cards for purchase later with the Android SDK (/sdk/android/save-without-purchase/cards)



Save customer credit or debit cards to charge them at a later time. For
example, you can offer a free trial and charge payers after the trial expires.
Payers don't need to be present when charged and no checkout is required.

Use the Android SDK to save a payer's credit or debit cards.

## Availability [#availability]

### See supported countries [#see-supported-countries]

* Australia
* Austria
* Belgium
* Bulgaria
* Canada
* China
* Cyprus
* Czech Republic
* Denmark
* Estonia
* Finland
* France
* Germany
* Hong Kong
* Hungary
* Ireland
* Italy
* Japan
* Latvia
* Liechtenstein
* Lithuania
* Luxembourg
* Malta
* Netherlands
* Norway
* Poland
* Portugal
* Romania
* Singapore
* Slovakia
* Slovenia
* Spain
* Sweden
* United Kingdom
* United States

## Know before you code [#know-before-you-code]

* To save payment methods, you must be able to identify payers uniquely. For         example, payers create an account and log in to your app.
* Complete the steps in [Get started](/api/rest/) to get         the following sandbox account information from the Developer Dashboard:
  * Your sandbox account login information
  * Your access token
* The Android SDK saves the following card types for purchase later:
  * American Express
  * Discover
  * Mastercard
  * Visa
* You'll need an existing         [advanced credit and debit](/sdk/android)         integration. PayPal must approve your business account for advanced credit         and debit card payments.

## How it works [#how-it-works]

PayPal encrypts payment method information and stores it in a digital vault
for that customer.

1. The payer saves their payment method.
2. For a first-time payer, PayPal creates a customer ID. Store this within your system for future use.
3. Use the customer ID to retrieve saved payment methods and add new ones for existing customers in your application.

The checkout process is now shorter because it uses saved payment information.

## 1. Set up account to save payments [#1-set-up-account-to-save-payments]

Set up your sandbox and live business accounts to save payment methods:

1. Log in to the Developer Dashboard.
2. Under **REST API apps**, select your app name.
3. Under **Sandbox App Settings** > **App Feature Options**, check **Accept payments**.
4. Expand **Advanced options**. Confirm that **Vault** is selected.

## 2. Add the CardPayments module to your app [#2-add-the-cardpayments-module-to-your-app]

Add the `CardPayments` package as a Gradle dependency in your app:

1. Groovy
2. Kotlin

Add the following dependency to your app's
`build.gradle` file.

<div className="pl-[1.625rem]" />

```groovy lineNumbers
dependencies {
  implementation 'com.paypal.android:card-payments:<CURRENT-VERSION>'
}
```

## 3. Add a button to initiate vault [#3-add-a-button-to-initiate-vault]

Add a button to your app's UI to save a card.

<div className="pl-[1.625rem]" />

```kotlin lineNumbers
Button(onClick ={
// Create a setup token on server-side (see next step)
}){
Text("Save Card")
}
```

## 4. Create a setup token [#4-create-a-setup-token]

From your server, create a setup token for cards that have:

* No verification
* 3D Secure verification

1. No verification
2. 3D Secure

### Request for new customer [#request-for-new-customer]

Generate a setup token with an empty `card` as its
`payment_source`. Later, you will attach card details to the
setup token in the SDK.

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v3/vault/setup-tokens'\\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -H "PayPal-Request-Id: REQUEST-ID"\\
 -d '{
      "payment_source": {
        "card": {}
      }
  }'
```

### Request for returning customer with saved payment [#request-for-returning-customer-with-saved-payment]

For a returning payer with previously stored payment sources, include the
PayPal-generated `customerId` in the request to save a
different payment method for the same customer.

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v3/vault/setup-tokens'\\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -H "PayPal-Request-Id: REQUEST-ID"\\
 -d '{
      "payment_source": {
        "card": {}
      }
      "customer": {
         "id": "llPdZofmwR"
      }
    }'
```

#### Modify the code [#modify-the-code]

1. Change `ACCESS-TOKEN` to your sandbox app's access token.
2. Change `REQUEST-ID` to a set of unique alphanumeric characters such as a timestamp.

### Response [#response]

The `card` payment source in the response is empty. You'll
attach additional information to the setup token in the steps that follow.

<div className="pl-[1.625rem]" />

```javascript lineNumbers
{
"id":"86S246162E316080B",
"customer":{
"id":"ZUzLMNMrJD"
},
"status":"CREATED",
"payment_source":{
"card":{}
},
"links":[{
"href":"https://api-m.sandbox.paypal.com/v3/vault/setup-tokens/86S246162E316080B",
"rel":"self",
"method":"GET",
"encType":"application/json"
}]
}
```

#### Note [#note]

1. `id` is the setup token ID.
2. For a first-time customer, this endpoint generates a new customer ID returned in `customer.id`.
3. For a returning customer, the customer ID in the response should match the customer ID passed into the request.

## 5. Implement vaulting in Android SDK [#5-implement-vaulting-in-android-sdk]

In the Android SDK, create a `CardVaultRequest` and use it to
invoke the `CardClient.vault()` method.

The **vault** method:

* Attaches a card to a setup token.
* Launches 3D Secure when a payment requires additional authentication.

### 1. Collect card payment details [#1-collect-card-payment-details]

Build a `Card` object with the buyer's card details:

<div className="pl-[1.625rem]" />

```kotlin lineNumbers
val card =Card(
  number ="4005519200000004",
  expirationMonth ="01",
  expirationYear ="2025",
  securityCode ="123",
  cardholderName ="Jane Smith",
  billingAddress =Address(
    streetAddress ="123 Main St.",
    extendedAddress ="Apt. 1A",
    locality ="City",
    region ="IL",
    postalCode ="12345",
    countryCode ="US"
)
)
```

Collecting a billing address can reduce the probability of an authentication
challenge.

### 2. Build CardVaultRequest [#2-build-cardvaultrequest]

Build a `CardVaultRequest` with the `card` object and
your `SETUP-TOKEN`:

<div className="pl-[1.625rem]" />

```javascript lineNumbers
val cardVaultRequest =CardVaultRequest(
  setupTokenID ="SETUP-TOKEN",
  card = card
)
```

### 3. Call the vault function [#3-call-the-vault-function]

After your `CardVaultRequest` has the card details and
`setupTokenID`, call `cardClient.vault()` to process the
payment.

<div className="pl-[1.625rem]" />

```kotlin lineNumbers
val config =CoreConfig(clientID ="CLIENT_ID", environemnt =.live)
val cardClient =CardClient(config = config)
cardClient.cardVaultListener =object: CardVaultListener {
overridefunonVaultSuccess(result: CardVaultResult){
// Vaulting has been approved and is ready to be used to create a paymentToken or vaultID
// The CardVaultResult contains a setupTokenID string used to create the paymentToken from your server
// Make sure you pass the cardVaultResult.setupTokenID to your server
}
overridefunonVaultFailure(error: PayPalSDKError){
// Handle error
}
}
cardClient.vault(context, cardVaultRequest)
```

## 6. Create a payment token with the vault setup token ID [#6-create-a-payment-token-with-the-vault-setup-token-id]

Convert the setup token to a payment token that can be used to process a
transaction:

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v3/vault/payment-tokens'\\
 -H "Content-Type: application/json"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -H "PayPal-Request-Id: REQUEST-ID"\\
 -d '{
      "payment_source": {
          "token": {
              "id": "VAULT-SETUP-TOKEN",
              "type": "SETUP_TOKEN"
          }
      }
  }'
```

### Modify the code [#modify-the-code-1]

1. Change `ACCESS-TOKEN` to your sandbox app's access token.
2. Change `REQUEST-ID` to a set of unique alphanumeric character such as a timestamp.
3. Change `VAULT-SETUP-TOKEN` to the value passed from the client.
4. Save the resulting `payment token` returned from the API to use in future transactions.

## 7. Show saved payment methods to returning payers [#7-show-saved-payment-methods-to-returning-payers]

When a payer returns to your app, you can show the payer's saved payment
methods with the Payment Method Tokens API.

### List all saved payment methods [#list-all-saved-payment-methods]

Make the server-side list all
[payment tokens API call](/api/payment-tokens/v3/customer-payment-tokens-get)
[payment tokens API call](/api/payment-tokens/v3/customer-payment-tokens-get)
to retrieve payment methods saved to a payer's PayPal-generated customer ID.
Based on this list, you can show all saved payment methods to a payer to
select during checkout.

> **Note:** **Important:** Don't expose payment method token IDs on the
> client side. To protect your payers, create separate IDs for each token and
> use your server to correlate them.

#### Sample request: List all saved payment methods [#sample-request-list-all-saved-payment-methods]

<div className="pl-[1.625rem]" />

```bash lineNumbers
curl -L -X GET "https://api-m.sandbox.paypal.com/v3/vault/payment-tokens?customer_id=CUSTOMER-ID"\\
 -H "Content-Type: application/json"\\
 -H "Accept-Language: en_US"\\
 -H "Authorization: Bearer ACCESS-TOKEN"\\
 -H "PayPal-Request-Id: REQUEST-ID"
```

#### Modify the code [#modify-the-code-2]

* Change `CUSTOMER-ID` to a PayPal-generated customer ID.
* Change `ACCESS-TOKEN` to your sandbox app's access token.
* Change `REQUEST-ID` to a set of unique alphanumeric character such as a time stamp.

### Show saved card to payer [#show-saved-card-to-payer]

Display the saved card to the payer and use the Orders API to make another
transaction. Use the vault ID the payer selects as an input to the
[Orders API to capture the payment](/api/payment-tokens/v3).

We recommend showing the card brand and the last 4 digits.

<img src="https://www.paypalobjects.com/devdoc/visa-example.png" alt="Visa,ending,in,1234" />

## 8. Test your integration [#8-test-your-integration]

Run the following tests in the PayPal sandbox to ensure that you can save
cards.

### Save payment [#save-payment]

1. In your app, initiate the vault.
2. Create a setup token with an empty card.
3. Call the vault function in the SDK with setup token and card details.
4. Create a payment token with the updated setup token.
5. Store the PayPal-generated customer ID in your system.
6. Log in to [sandbox](https://www.sandbox.paypal.com/) with your merchant account and verify the transaction.
7. Return to your app and initiate another transaction. Use the PayPal-generated payment token as a payment source.
8. Verify that the transaction captures successfully without having to complete PayPal Web Checkout again.

## Next steps [#next-steps]

* [Test and go live](/sdk/js/production) with this integration.
* Change the credentials and API URLs from         `api-m.sandbox.paypal.com` to `api-m.paypal.com` when         going live with your integration.
* You can         [create orders](/api/orders/v2/orders-create) without the         `payment_source.paypal.attributes.vault` for subsequent or         recurring transactions.
* You can         [get a payment token](/api/payment-tokens/v3/payment-tokens-get),         [list all payment tokens](/api/payment-tokens/v3/customer-payment-tokens-get),         [delete a payment token](/api/payment-tokens/v3/payment-tokens-delete), and more with the Payment Method Tokens API.
