Android — SPayLater Widget Installation

This guide walks you through adding the SPayLater Promotional Widget to your Android app. Once installed, the widget automatically shows instalment pricing alongside your product prices, helping customers see that SPayLater is available at checkout.

What this does

The ShopeePay Merchant SDK adds a native Android view that displays "Buy Now, Pay Later with SPayLater" messaging on your Homepage, Category, and Product Detail Pages. Installation is a developer task — the steps below are written so you can hand them to your Android developer with everything they need.

Before you start

  • Access Key — your unique SPayLater plugin key. Get it from your ShopeePay account manager if you don't have one yet.
  • Store ID — the unique ID for your store in the ShopeePay system. Same source as above.
  • An Android developer — the steps below require someone who can edit your app's build.gradle and Kotlin/Java source files.
  • Market knowledge — know the country, currency, and language your app targets (e.g. Malaysia / MYR / EN) so the SDK is initialized correctly.

Merchant tip: Send your developer this page along with your Access Key and Store ID. That is everything they need to complete the installation.

Installation steps

Step 1 — Get the SDK file from your account manager

The SDK is distributed as an .aar file. It is not published to Maven Central or any public repository. Contact your ShopeePay account manager to receive the latest shopeepay-merchant-sdk.aar file.

Once you have the file, create a libs/ folder in your Android module directory (the same level as your src/ folder) and copy the .aar file there.

Step 2 — Add the SDK to your project

Open your module-level build.gradle and add the SDK as a file dependency:

build.gradle
dependencies {
    implementation files("libs/shopeepay-merchant-sdk.aar")
}

After saving the file, click Sync Project with Gradle Files in Android Studio to apply the change.

The SDK depends on the following third-party libraries. If your app already includes them, no changes are needed. If not, add them to the same dependencies block:

build.gradle — third-party dependencies (add if not already present)
dependencies {
    implementation "com.squareup.okhttp3:okhttp:3.12.1"
    implementation "com.google.code.gson:gson:2.10.1"
    implementation "com.github.bumptech.glide:glide:4.13.2"
    implementation "androidx.core:core-ktx:1.10.1"
    implementation "androidx.recyclerview:recyclerview:1.3.2"
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}

Step 3 — Initialize the SDK

In your Application class (the class that extends android.app.Application), add the following inside onCreate(). Replace the placeholder values with your real credentials and target market settings:

Application startup
val config = ShopeePayMerchantConfig.Builder()
    .context(applicationContext)
    .accessKey("YOUR_ACCESS_KEY")
    .env(Environment.SANDBOX) // switch to Environment.LIVE for production
    .country(Country.MY)
    .currency(Currency.MYR)
    .language(Language.EN)
    .build()

ShopeePayMerchantSdk.init(config)

Change Country, Currency, and Language to match your target market. Use Environment.LIVE when submitting your production build.

Step 4 — Place the widget on your pages

For each page where you want to show SPayLater messaging, add the view to your layout XML and call render() in the corresponding Activity or Fragment.

Layout XML — add this view wherever you want the widget to appear, typically just below the product price:

Page layout
<com.shopeepay.merchant.sdk.biz.installment.ShopeePayMerchantView
    android:id="@+id/shopeePayMerchantView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Activity / Fragment code — call render() after the view is available, for example in onCreate() or onViewCreated():

Page code
merchantView.render(
    storeExtId = "YOUR_STORE_ID",
    productId = "product-id",
    amount = 129900L, // price in smallest currency unit (e.g. cents)
    pageType = ShopeePayMerchantPageType.PRODUCT_PAGE
)

Category pages with RecyclerView — batch pre-fetch — if your category or listing page uses a RecyclerView, calling render() inside onBindViewHolder triggers a separate network request per item. To avoid this, call ShopeePayMerchantSdk.requestData() once with the full list of visible products before the list is bound:

Category page — batch pre-fetch for RecyclerView
ShopeePayMerchantSdk.requestData(
    SPPMerchantInfoRequest(
        storeExtId = "YOUR_STORE_ID",
        pageType = ShopeePayMerchantPageType.CATEGORY_PAGE,
        productInfoList = products.map { product ->
            SPPMerchantInfo(
                productId = product.id,
                amount = product.price
            )
        }
    )
)

After requestData() completes, call render() in onBindViewHolder as normal — the SDK serves each item's data from its local cache, so the widget loads instantly without additional network calls.

Step 5 — Repeat for each page type

Repeat Step 4 for every page where you want to show SPayLater messaging. Change pageType to match the page you're working on: ShopeePayMerchantPageType.HOME_PAGE for your Homepage, ShopeePayMerchantPageType.CATEGORY_PAGE for listing pages, and ShopeePayMerchantPageType.PRODUCT_PAGE for Product Detail Pages. On the Homepage you do not need to pass productId or amount.

Developer note — exact SDK parameters and third-party dependencies

ShopeePayMerchantConfig.Builder() parameters

ParameterTypeDescription
accessKeyStringSPL plugin key provided by ShopeePay
envEnvironmentEnvironment.SANDBOX for testing; Environment.LIVE for production
countryCountryCountry enum value, e.g. Country.MY, Country.TH, Country.ID
currencyCurrencyCurrency enum value, e.g. Currency.MYR, Currency.THB, Currency.IDR
languageLanguageLanguage enum value, e.g. Language.EN, Language.TH, Language.ID

render() parameters

ParameterTypeDescription
storeExtIdStringYour Store ID from ShopeePay
productIdStringYour product's SKU or ID; not required on the Homepage
amountLongProduct price in smallest currency unit (e.g. cents); not required on the Homepage
pageTypeShopeePayMerchantPageTypeHOME_PAGE, CATEGORY_PAGE, or PRODUCT_PAGE

requestData() — SPPMerchantInfoRequest fields

FieldTypeDescription
storeExtIdStringYour Store ID from ShopeePay
pageTypeShopeePayMerchantPageTypePage context for the batch pre-fetch (e.g. CATEGORY_PAGE)
productInfoListList<SPPMerchantInfo>List of products to pre-fetch; each entry takes productId (String) and amount (Long)

The SDK depends on OkHttp, Gson, Glide, core-ktx, RecyclerView, and ConstraintLayout. If these are already in your app's build.gradle, no additional changes are needed. If not, add them as shown in Step 2. For full SDK documentation, refer to the Confluence developer guide provided by your ShopeePay account manager.

Configuration

SettingWhere to set itNotes
Access KeyaccessKey() in BuilderRequired. Provided by your ShopeePay account manager.
Environmentenv() in BuilderUse SANDBOX for development and testing; switch to LIVE before your production release.
Country / Currency / LanguageBuilder enumsMust match the market your SPayLater agreement covers. Using a mismatched country will result in no widget being rendered.
Store IDstoreExtId in render()Required on every page type.
Page placementpageType in render()Controls which variant of the widget is shown. Use the correct page type for each screen.
StylingNot configurableThe widget renders with SPayLater's standard styling. Custom colors or fonts are not supported to maintain brand consistency.

How to verify the installation

  1. Build and run your app in SANDBOX mode on a real device or emulator.
  2. Navigate to a page where you placed the widget (Homepage, Category, or Product page).
  3. Confirm the "Buy Now, Pay Later with SPayLater" messaging appears at the expected position — typically just below the product price.
  4. On a Product page, tap the ⓘ info icon next to the instalment line. A pop-up should appear listing the available instalment plans and monthly amounts.
  5. Once everything looks correct in SANDBOX, update the Builder to Environment.LIVE and submit your production build.

Troubleshooting

SymptomLikely causeFix
Widget is blank / not visibleSDK not initialized before the Activity rendersMake sure ShopeePayMerchantSdk.init() is called in Application.onCreate(), not in an Activity or Fragment.
Build fails after adding the .aarGradle sync not run or file path incorrectConfirm the shopeepay-merchant-sdk.aar file is in the libs/ folder and click Sync Project with Gradle Files.
Widget shows but no instalment priceWrong country/currency settings or amount not passedDouble-check Country, Currency, and confirm you are passing amount in smallest currency units (e.g. cents not dollars).
Tenor pop-up does not openpageType mismatchThe tenor pop-up only appears when pageType is set to PRODUCT_PAGE. Check you are not using HOME_PAGE or CATEGORY_PAGE on your PDP.
Widget visible in SANDBOX but not in LIVEMerchant or store not yet live in ShopeePay's systemContact your ShopeePay account manager to confirm your store is activated for LIVE.

FAQ

Do I need to update the widget when prices change?

No. Just call render() with the current price each time the page loads. The widget calculates the instalment line dynamically based on the amount you pass.

What happens if SPayLater is unavailable in the customer's region?

The widget renders nothing and takes up no space. If the configured country does not have an active SPayLater program, the SDK view collapses to zero height automatically — no empty box will appear on your page.

Can I customize the widget's colors or fonts?

No. The widget uses SPayLater's standard visual style and cannot be themed. This is intentional — the consistent look is a trust signal for customers, and customization would require regulatory review of the modified messaging.

How do I switch from SANDBOX to LIVE for my production release?

Change env(Environment.SANDBOX) to env(Environment.LIVE) in your Builder configuration, rebuild, and submit. Your Access Key is the same across both environments — no new credentials are needed.

I have more than one store ID. Can the widget handle multiple stores?

The SDK is initialized once with a single configuration. If you need to show different store IDs on different screens, you can call render() with a different storeExtId per screen — the configuration set at initialization (Access Key, country, etc.) applies globally, but the Store ID is set per render call.