Integrate card payments in Android apps

SDKCurrentAdvancedLast updated: December 7th 2023, @ 10:43:54 am


Accept PayPal, credit, and debit card payments in a web or native experience using the PayPal Mobile Android SDK. Use customizable PayPal buttons with your custom checkout UI to align with your business branding. For more implementation details, see the PayPal GitHub repository.

Know before you code

You need a developer account to get sandbox credentials:

  • PayPal uses REST API credentials which you can get from the developer dashboard.
  • Client ID: Authenticates your account with PayPal and identifies an app in your sandbox.
  • Client secret: Authorizes an app in your sandbox. Keep this secret safe and don’t share it.

Read Get started with PayPal APIs for more information.

You need a combination of PayPal and third-party tools:

  • Android SDK: Adds PayPal-supported payment methods for Android.
  • Orders REST API: Create, update, retrieve, authorize, and capture orders.

Use Postman to explore and test PayPal APIs.

1. Before you begin your integration

Check your account setup for advanced card payments

This integration requires a sandbox business account with the Advanced Credit and Debit Card Payments capability. Your account should automatically have this capability.

To confirm that Advanced Credit and Debit Card Payments are enabled for you, check your sandbox business account as follows:

  1. Log into the PayPal Developer Dashboard, toggle Sandbox, and go to Apps & Credentials.
  2. In REST API apps, select the name of your app.
  3. Go to Features > Accept payments.
  4. Select the Advanced Credit and Debit Card Payments checkbox and select Save Changes.

Note: If you created a sandbox business account through sandbox.paypal.com, and the advanced credit and debit card payments status for the account is disabled, complete the sandbox onboarding steps.

Check 3D Secure requirements

Add 3D Secure to reduce the chance of fraud and improve the payment experience by authenticating a cardholder through their card issuer.

Visit our 3D Secure page to see if 3D Secure is required in your region and learn more about implementing 3DS in your app.

2. Integrate the SDK into your app

The PayPal Mobile SDK is available through Maven Central. Add the mavenCentral repository to the build.gradle file of your project root:

1allprojects {
2 repositories {
3 mavenCentral()
4 }
5}

Snapshot builds

You can also use snapshot builds to test upcoming features before release. To include a snapshot build:

1. Add snapshots repository

Add the snapshots repository to the build.gradle file of your project root.

1allprojects {
2 repositories {
3 mavenCentral()
4 maven {
5 url 'https://oss.sonatype.org/content/repositories/snapshots/'
6 }
7 }
8}

2. Add snapshot to dependencies

Then, add a snapshot build by adding -SNAPSHOT to the current dependency version. For example, if you want to add a snapshot build for CardPayments, add the following:

1dependencies {
2 implementation 'com.paypal.android:card-payments:CURRENT-VERSION-SNAPSHOT'
3}

3. Payment integrations

Integrate 3 different types of payments using the PayPal Mobile SDK:

  • Card payments: Add card fields that align with your branding.
  • PayPal native payments: Launch a checkout page within your app, instead of a popup.
  • PayPal web payments: A lighter integration that launches a checkout page in a browser within your app.
  1. Card
  2. Native payments
  3. Web payments

Integrate with card payments

Build and customize the card fields to align with your branding.

1. Add card payments module to your app

Add the card-payments package dependency in your app's build.gradle file:

1dependencies {
2 implementation "com.paypal.android:card-payments:CURRENT-VERSION"
3}

2. Create CardClient

A CardClient helps you attach a card to a payment.

In your Android app:

  1. Use the CLIENT_ID to construct a CoreConfig.
  2. Construct a CardClient using your CoreConfig object.
1val config = CoreConfig("CLIENT_ID", environment = Environment.SANDBOX)
2
3val cardClient = CardClient(config)

3. Get Order ID

On your server:

  1. Create an ORDER_ID by using the Orders v2 API.
  2. Pass your ACCESS_TOKEN in the Authorization header. To get an ACCESS_TOKEN, use the Authentication API.

    Note: This access token is only for the sandbox environment. When you're ready to go live, request a live access token by changing the request sandbox endpoint to https://api-m.paypal.com/v1/oauth2/token.

  3. Pass the intent. You'll need to pass either AUTHORIZE or CAPTURE as the intent type. This type must match the /authorize or /capture endpoint you use to process your order.
  1. Sample request
  2. Sample response
1curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/' \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer ACCESS_TOKEN' \
4 --data-raw '{
5 "intent": "CAPTURE|AUTHORIZE",
6 "purchase_units": [
7 {
8 "amount": {
9 "currency_code": "USD",
10 "value": "5.00"
11 }
12 }
13 ]
14 }'

When a buyer starts a payment, send the ORDER_ID from your server to your client app.

4. Create card request

A CardRequest object:

  • Attaches a card to an ORDER_ID.
  • Launches 3D Secure when a payment requires additional authentication.

1. Collect card payment details

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

1val card = Card(
2 number = "4005519200000004",
3 expirationMonth = "01",
4 expirationYear = "2025",
5 securityCode = "123",
6 billingAddress = Address(
7 streetAddress = "123 Main St.",
8 extendedAddress = "Apt. 1A",
9 locality = "Anytown",
10 region = "CA",
11 postalCode = "12345",
12 countryCode = "US"
13 )
14)

Collecting a billing address can reduce the number of authentication challenges to customers.

2. Build CardRequest

Build a CardRequest with the card object and your ORDER_ID:

1val cardRequest = CardRequest(
2 orderID = "ORDER_ID",
3 card = card,
4 returnUrl = "myapp://return_url", // custom URL scheme needs to be configured in AndroidManifest.xml
5 sca = SCA.SCA_ALWAYS // default value is SCA.SCA_WHEN_REQUIRED
6)

3D Secure is supported for all card payments to comply with the Second Payment Services Directive (PSD2). PSD2 is a European Union regulation that introduces Strong Customer Authentication (SCA) and other security requirements.

Select your SCA launch option type using the sca parameter in the CardRequest initializer:

  • SCA.SCA_WHEN_REQUIRED launches an SCA challenge when applicable. This is enabled by default.
  • SCA.SCA_ALWAYS requires an SCA challenge for all card transactions.

3. Set up your app for browser switching

The sca challenge launches in a browser within your application. Your app needs to handle the browser switch between the sca challenge and the checkout page. Set up a return URL that returns to your app from the browser.

4. Create a return URL

Provide a returnUrl so the browser returns to your application after the sca challenge finishes.

The returnUrl should have the following format:

1myapp://return_url

The myapp:// portion of the returnUrl is a custom URL scheme that you need to register in your app's AndroidManifest.xml.

5. Add card payment activity to the Android manifest

Update your app's AndroidManifest.xml with details about the card payment activity that will return the user to your app after completing the SCA check. Include the following elements:

  1. Set the activity launchMode to singleTop.
  2. Set the android:scheme on the Activity that will be responsible for handling the deep link back into the app.
  3. Add an intent-filter.
  4. Register the myapp:// custom URL scheme in the intent-filter.

Note: android:exported is required if your app compile SDK version is API 31 (Android 12) or later.

1<activity
2 android:name=".MyCardPaymentActivity"
3 android:launchMode="singleTop"
4 android:exported="true"
5 >
6 <intent-filter>
7 <action android:name="android.intent.action.VIEW" />
8 <data android:scheme="myapp" />
9 <category android:name="android.intent.category.DEFAULT" />
10 <category android:name="android.intent.category.BROWSABLE" />
11 </intent-filter>
12</activity>

6. Connect the card payment activity

Add onNewIntent to your activity:

1override fun onNewIntent(newIntent: Intent?) {
2 super.onNewIntent(intent)
3 intent = newIntent
4}

5. Approve order

After your CardRequest has the card details, call cardClient.approveOrder() to process the payment.

1class MyCardPaymentActivity: FragmentActivity {
2 fun cardCheckoutTapped(cardRequest: CardRequest) {
3 cardClient.approveOrder(this, cardRequest)
4 }
5}

6. Handle payment result scenarios

Set up your ApproveOrderListener to handle successful payments, errors, cancellations, and 3D Secure transaction flows.

1class MyCardPaymentActivity: FragmentActivity, ApproveOrderListener {
2 fun cardCheckoutTapped(cardRequest: CardRequest) {
3 val result = cardClient.approveOrder(this, cardRequest)
4 }
5 fun setupCardClient() {
6 cardClient.listener = this
7 }
8 fun onApproveOrderSuccess(result: CardResult) {
9 // order was approved and is ready to be captured/authorized (see step 6)
10 }
11 fun onApproveOrderFailure(error: PayPalSDKError) {
12 // inspect 'error' for more information
13 }
14 fun onApproveOrderCanceled() {
15 // 3D Secure flow was canceled
16 }
17 fun onApproveOrderThreeDSecureWillLaunch() {
18 // 3D Secure flow will launch
19 }
20 fun onApproveOrderThreeDSecureDidFinish() {
21 // 3D Secure auth did finish successfully
22 }
23}

7. Authorize and capture order

Submit your ORDER_ID for authorization or capture when the PayPal Android SDK calls the onApproveOrderSuccess method.

Call the authorize endpoint of the Orders V2 API to place the money on hold:

Sample request: Authorize order

1curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID/authorize' \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer ACCESS_TOKEN' \
4 --data-raw ''

Call the capture endpoint of the Orders V2 API to capture the money immediately:

Sample request: Capture order

1curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID/capture' \
2 -H 'Content-Type: application/json' \
3 -H 'Authorization: Bearer ACCESS_TOKEN' \
4 --data-raw ''

8. Test integration

Before going live, test your integration in the sandbox environment.

Learn more about the following resources on the Card Testing page:

Note: Use the credit card generator to generate additional test credit cards for sandbox testing.

When prompted for required data for the sandbox business request, such as a phone number, enter any number that fits the required format. Because this is a sandbox request, the data doesn't have to be factual.

Before you go live, you'll need to complete live onboarding to be eligible to process cards with your live PayPal account.

Payment buttons and fraud protection

After you integrate a payment method, add a payment button to your page to start the payment process. You can also add fraud protection to your app.

  1. Payment buttons
  2. Fraud protection

Use PayPal buttons in your UI

The PaymentButtons module provides a set of PayPal-branded buttons to seamlessly integrate with PayPal web and native payments.

Follow these steps to add PayPal buttons to your integration:

1. Add PaymentButtons to your app

Add the payment-buttons package dependency in your app's build.gradle file:

1dependencies {
2 implementation "com.paypal.android:payment-buttons:CURRENT-VERSION"
3}

2. Create PayPal button

The PaymentButtons module provides 3 buttons that you can use in your application:

  • PayPalButton: A generic PayPal button.
  • PayPalPayLater: A PayPal button with a PayLater label.
  • PayPalCredit: A PayPal button with the PayPalCredit logo.

These buttons include customization options such as color, edges, size, and labels. Here's how to style the button corner radius:

ValueDescriptionButton
rectangleButton shape with sharp corners.
roundedRecommended
Button shape with rounded corner radius. The default button shape.
pillButton in pill shape.
customCornerRadiusCustomize the button's corner radius. The minimum value is 10 px and is applied to all 4 corners.

Add PayPalButton to your layout XML:

1<com.paypal.android.paymentbuttons.PayPalButton
2 android:id="@+id/paypal_button"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content"/>

3. Reference PayPal button

Add the PayPal button to your code:

1val payPalButton = findViewById<PayPalButton>(R.id.paypal_button)
2payPalButton.setOnClickListener {
3 // start the PayPal web or native
4}

Go live

If you have fulfilled the requirements for accepting Advanced Credit and Debit Card Payments for your business account, review the Move your app to production page to learn how to test and go live.

If this is your first time testing in a live environment, follow these steps:

  1. Log into the PayPal Developer Dashboard with your PayPal business account.
  2. Complete production onboarding so you can process card payments with your live PayPal business account.
  3. Request Advanced Credit and Debit Card Payments for your business account.

Important: The code for the integration checks eligibility requirements, so the payment card fields only display when the production request is successful.