Set Up Android SDK

Offer Affirm as a payment option in Android applications. This guide walks you through setting up the Android client on your checkout pages.

Overview

Starting a payment with Affirm on an Android client consists of the following:

  • Creating a checkout form.
  • Tokenizing customer information to transmit it securely to your server.
  • Using the checkout_token to initiate a transaction.

The Android SDK is available on Github.

Steps

1. Set up Affirm on Android

Note: The Android SDK is open-source and fully documented.

With Gradle

To install the SDK, add affirm-merchant-sdk-android to the dependencies block of your app/build.gradle file:

apply plugin: 'com.android.application'

android { ... }

dependencies {
  // ...

  // Affirm Android SDK
  implementation 'com.affirm:affirm-android-sdk:2.0.7'
}

With Maven

Add the Affirm dependency to your pom.xml file:

<dependency>
  <groupId>com.affirm</groupId>
  <artifactId>affirm-android-sdk</artifactId>
  <version>2.0.1</version>
</dependency>
🚧

SDK Releases

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.


2. Initialize Affirm

Configure the SDK with your Affirm public API key so that it can make requests to the Affirm server:

Affirm.initialize(new Affirm.Configuration.Builder("public key")
      .setEnvironment(Affirm.Environment.SANDBOX)
      .setName("merchant name")
      .setUseVcn("true")
      .setReceiveReasonCodes("true")
      .setLogLevel(Affirm.LOG_LEVEL_DEBUG)
      .setCheckoutRequestCode(8001)
      .setVcnCheckoutRequestCode(8002)
      .setPrequalRequestCode(8003)
      .build()

3. Render Affirm Checkout

Checkout creation is the process by which a customer uses Affirm to pay for an in-app purchase. Create a checkout object and launch the Affirm checkout using this Checkout function:

final Checkout checkout = Checkout.builder()
        .setOrderId("order id")
        .setItems(items)
        .setBilling(shipping)
        .setShipping(shipping)
        .setShippingAmount(0f)
        .setTaxAmount(100f)
        .setTotal(1100f)
        .build();
 
Affirm.startCheckout(this, checkout, false);
🚧

Floats

The checkout object contains details about the order. Amounts should be dollar amounts represented as Floats.


4. Add promotional messaging

Affirm promotional messaging components show customers how they can use Affirm to finance their purchases. Properly placed promotional messaging helps drive increased AOV and conversion.

A. Monthly payment messaging:

1. To display promotional messaging, our SDK provides a AffirmPromotionButton class. To implement the AffirmPromotionButton:

<com.affirm.android.AffirmPromotionButton
    android:id="@+id/promo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/price"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="20dp"
    app:htmlStyling="false"
    app:affirmTextFont="@font/apercu_bold"
    app:affirmTextColor="@android:color/darker_gray"
    app:affirmTextSize="16sp"
    app:affirmColor="AffirmColorTypeBlue"
    app:affirmLogoType="AffirmDisplayTypeLogo"/>

2. Use one of the following implementation methods: 

// Option1 - Load via findViewById
AffirmPromotionButton affirmPromotionButton1 = findViewById(R.id.promo);
Affirm.configureWithAmount(affirmPromotionButton1, null, PromoPageType.PRODUCT, 1100, true);
// Option2 - Initialize by new
AffirmPromotionButton affirmPromotionButton2 = new AffirmPromotionButton(this);
((FrameLayout)findViewById(R.id.promo_container)).addView(affirmPromotionButton2);
Affirm.configureWithAmount(affirmPromotionButton2, null, PromoPageType.PRODUCT, 1100, true);

3. To style the promotional messaging button, we have two options:

Option 1: Use configWithLocalStyling to use the local styles on the string within the button:

// You can custom with the AffirmColor, AffirmLogoType, Typeface, TextSize, TextColor
affirmPromotionButton2.configWithLocalStyling(
                AffirmColor.AFFIRM_COLOR_TYPE_BLUE,
                AffirmLogoType.AFFIRM_DISPLAY_TYPE_LOGO,
                ResourcesCompat.getFont(this, R.font.apercu_bold),
                android.R.color.darker_gray,
                R.dimen.affirm_promotion_size);

Option 2: configWithHtmlStyling uses HTML Style from Affirm Server. You can add fonts by customizing the fonts in HTML:

  • First, add a font file in the /res/font/ directory, such as lacquer_regular.ttf.
  • Then, add a declaration for the font file. You can check the detail in typeface.
  • Lastly, use the font in the css file. You can check the detail in remote_promo.css.
// If you want to custom the style of promo message, should pass the local or remote url and the file of typeface declaration
affirmPromotionButton2.configWithHtmlStyling("file:///android_asset/remote_promo.css", typefaceDeclaration);

Note: Tapping on the AffirmPromotionButton automatically starts the prequalification flow.

4. If you want to handle errors, override onActivityResult so that Affirm can handle the result.

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    if (Affirm.handlePrequalData(this, requestCode, resultCode, data)) {
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

@Override
public void onAffirmPrequalError(String message) {
    Toast.makeText(this, "Prequal Error: " + message, Toast.LENGTH_LONG).show();
}

B. Fetch promotional message, then display it with your own TextView:

You can display the promotional message using fetchPromotion. This returns a SpannableString object after the request is successful.

To handle events that click on the promotional message, you can use onPromotionClick.

TextView promotionTextView = findViewById(R.id.promotionTextView);
    Affirm.PromoRequestData requestData = new Affirm.PromoRequestData.Builder(PRICE, true)
        .setPromoId(null)
        .setPageType(null)
        .build();

    promoRequest = Affirm.fetchPromotion(requestData, promotionTextView.getTextSize(), this, new PromotionCallback() {
        @Override
        public void onSuccess(@Nullable SpannableString spannableString, boolean showPrequal) {
            promotionTextView.setText(spannableString);
            promotionTextView.setOnClickListener(v -> Affirm.onPromotionClick(MainActivity.this, requestData, showPrequal));
        }
   
        @Override
        public void onFailure(@NonNull AffirmException exception) {
                   Toast.makeText(getBaseContext(), "Failed to get promo message, reason: " + exception.toString(), Toast.LENGTH_SHORT).show();
            }
        });

Call the create method to initiate the request, and call the cancel method to cancel the request.

@Override
    protected void onStart() {
        super.onStart();
        promoRequest.create();
    }

    @Override
    protected void onStop() {
        promoRequest.cancel();
        super.onStop();
    }

C. Track order confirmed:

The trackOrderConfirmed event triggers when a customer completes their purchase. Our SDK provides the AffirmTrack object to trigger the tracking:

final AffirmTrack affirmTrack = AffirmTrack.builder()
        .setAffirmTrackOrder(affirmTrackOrder)
        .setAffirmTrackProducts(affirmTrackProducts)
        .build();

Affirm.trackOrderConfirmed(MainActivity.this, trackModel());
  • Since there is no callback, it returns success after a 10-second timeout.
  • We replace it using the HTTP API after the API is done.

5. Handle Callbacks

Override onActivityResult, then call the handleCheckoutData method. This returns the checkout_token, which is required to initiate the transaction on your server.

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    if (Affirm.handleCheckoutData(this, requestCode, resultCode, data)) {
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

We also have additional handler functions available:

@Override
public void onAffirmCheckoutSuccess(@NonNull String token) {
    Toast.makeText(this, "Checkout token: " + token, Toast.LENGTH_LONG).show();
}
 
@Override
public void onAffirmCheckoutCancelled() {
    Toast.makeText(this, "Checkout Cancelled", Toast.LENGTH_LONG).show();
}
 
@Override
public void onAffirmCheckoutError(String message) {
    Toast.makeText(this, "Checkout Error: " + message, Toast.LENGTH_LONG).show();
}
👍

Checkout Token

Once the checkout has been successfully confirmed by the user, the AffirmCheckoutDelegate object receives a checkout_token. This token should be forwarded to your server, which should be used to authorize a charge on the user's account.


6. Create a charge

When a customer successfully completes a checkout, it is recorded as a new purchase attempt. This needs to be handled on your server-side to be fulfilled via our Charges API.


What's next?