Android
Offer Affirm as a payment option on Android applications.
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, and using that checkout_token
to initiate a transaction.
This guide walks you through setting up the Android client on your checkout pages.
The Android SDK is available on Github.
1. Set up Affirm on Android
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.19'
}
With Maven
Add the Affirm dependency to your pom.xml file:
<dependency>
<groupId>com.affirm</groupId>
<artifactId>affirm-android-sdk</artifactId>
<version>2.0.19</version>
</dependency>
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 to send requests to the Affirm server.
Affirm.initialize(Affirm.Configuration.Builder("public key")
.setEnvironment(Affirm.Environment.SANDBOX)
.setMerchantName("merchant name")
.setReceiveReasonCodes("true")
.setLogLevel(Affirm.LOG_LEVEL_DEBUG)
.setCheckoutRequestCode(8001)
.setVcnCheckoutRequestCode(8002)
.setPrequalRequestCode(8003)
.build())
3. Render Affirm Checkout
Checkout creation is the process in which a customer uses Affirm to pay for a purchase in your app. You can create a checkout
object and launch the Affirm checkout using the 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);
The checkout object contains details about the order.
Amounts should be in dollar amounts represented as Floats.
4. Add Affirm promotional messaging
Affirm promotional messaging components---monthly payment messaging and educational modals---show customers how they can use Affirm to finance their purchases. Properly placed promotional messaging helps drive increased AOV and conversion.
Add monthly payment messaging
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"/>
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);
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
will use html style from Affirm server. You can add fonts by following the steps below, so you can customize the fonts in html.
1. Add a font file in the /res/font/
directory. Such as lacquer_regular.ttf.
2. Add a declaration for the font file. You can check the detail in typeface.
3. 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);
Tapping on the AffirmPromotionButton
automatically starts the prequalification flow. 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();
}
Fetch promotional message, then display it with your own TextView
.
TextView
.- You can get the promotional message via
fetchPromotion
, aSpannableString
object is returned after the request is successful. onPromotionClick
: This method handles events that click on the promotional message
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();
}
});
Calling the create
method will initiate the request, and call cancel
method to cancel the request.
@Override
protected void onStart() {
super.onStart();
promoRequest.create();
}
@Override
protected void onStop() {
promoRequest.cancel();
super.onStop();
}
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 will return success after a 10 second timeout.
- We will replace it using the HTTP API after the API is done.
5. Handle callbacks
Be sure to override onActivityResult
, then call the handleCheckoutData
method. It will return the checkout_token
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 some 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();
}
Once the checkout has been successfully confirmed by the user, the
AffirmCheckoutDelegate
object will receive acheckout_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.
Updated 10 months ago