Mobile SDK - Android

This document will guide you on how to install PowerBoard Android SDK and Integrate into your app.

Overview

The PowerBoard Android MobileSDK seamlessly integrates with PowerBoard services to easily build a payments flow in your Android app.

The SDK provides a customisable experience with pre-built UI widgets that handle and support various payment methods.

Once you have setup and initialised the MobileSDK in your application, you can use the MobileSDK widgets to access payment flows. These include interacting with GooglePay, Paypal, Afterpay and Click To Pay.

You can also complete 3DS challenges, capture addresses and tokenise card details.

Requirements

  • PowerBoard Android SDK: Github Repository
  • PowerBoard Account
  • Android API Level: 24 (Android 7.0) and above
  • Kotlin: 2.1.10+
  • Jetpack Compose: BOM 2024.12.01+
  • Android Gradle Plugin: 8.8.2+
  • Java: 17

Getting Started

The repository includes a sample application (sample/) that demonstrates how to integrate and use the PowerBoard Android Mobile SDK.

The example app showcases various features of the SDK and provides a practical guide for developers looking to implement PowerBoard payments in their own Android applications.

Configuration

The sample app uses a config.properties file to manage environment-specific settings.

Each build flavour has a corresponding config.properties file containing key-value pairs used during the build process. These values are injected into the app via build.gradle.

📘

Note:

You only need to create and configure the config.properties file for the flavours you are actively working on.

For example, if you are working on PreProduction and Production, you can omit the file for staging, as it is not required for your current build. Ensure the necessary configuration files are in place before running the app to avoid missing variable errors.

config.properties File

Flavours: The sample app supports three flavors: Staging, PreProduction and Production. You'll need to provide values for each flavor.

Location: Create a file named config.properties in the sample/src/[flavor] directory of the project.

Structure: The config.properties file should contain key-value pairs for each configuration setting.

Required Fields: The following fields are required in the config.properties file:

  • API_ACCESS_TOKEN: The PowerBoard API access token for the specified environment (e.g., PreProduction and Production). This token is used by the sample app to make direct calls to the PowerBoard API for tasks like creating customers or managing transactions.
  • WIDGET_ACCESS_TOKEN: The PowerBoard Widget/UI access token for the specified environment. This token is used by the PowerBoard SDK to authenticate and authorise the use of the pre-built UI widgets for payment processing.
  • GATEWAY_ID_MPGS: Your PowerBoard service ID for the MPGS (Mastercard Payment Gateway Services) gateway. This ID is required to process card payments, handle 3D Secure (3DS) authentication, and manage other card-related transactions.
  • GATEWAY_ID_PAY_PAL: Your PowerBoard service ID for the PayPal gateway. This ID is necessary to enable PayPal as a payment method within the sample app.
  • GATEWAY_ID_AFTER_PAY: Your PowerBoard service ID for the Afterpay gateway. This ID is required to enable Afterpay as a payment method.
  • GATEWAY_ID_CLICK_TO_PAY: Your PowerBoard service ID for the ClickToPay gateway. This ID is required to enable ClickToPay as a payment method.
  • GATEWAY_ID_GOOGLE_PAY: Your PowerBoard service ID for the Google Pay gateway. This ID is required to enable Google Pay as a payment method.
  • MERCHANT_IDENTIFIER: Your PowerBoard merchant identifier, which is required for Google Pay. This identifier is used to associate your transactions with your Google Pay merchant account.

Example config.properties:

# Authentication keys
API_ACCESS_TOKEN=your_api_access_token 
WIDGET_ACCESS_TOKEN=your_widget_access_token 
# Gateway keys
GATEWAY_ID_MPGS=your_gateway_id_mpgs 
GATEWAY_ID_PAY_PAL= your_gateway_id_pay_pal 
GATEWAY_ID_AFTER_PAY= your_gateway_id_after_pay 
GATEWAY_ID_CLICK_TO_PAY= your_gateway_id_click_to_pay 
GATEWAY_ID_GOOGLE_PAY= your_gateway_id_google_pay 
# Misc Gateway keys
MERCHANT_IDENTIFIER= your_merchant_identifier 

Installation

Step 1: Configure Repository Access

Add the JitPack repository to your project's settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://www.jitpack.io") }
    }
}

Step 2: Add SDK Dependency

Add the SDK dependency to your app's build.gradle.kts:

dependencies {
    implementation("com.github.CommBank-PowerBoard:powerboard-android-mobile-sdk:4.0.0")
}

Step 3: Configure Permissions

Add required permissions to your AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- Required for Google Pay -->
    <meta-data
        android:name="com.google.android.gms.wallet.api.enabled"
        android:value="true" />
        
    <application>
        <!-- Your app configuration -->
    </application>
</manifest>

SDK Initialisation

Initialise the SDK in your Application class:

import com.paydock.MobileSDK
import com.paydock.core.domain.model.Environment

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        
        MobileSDK.Builder()
            .environment(Environment.PRE_PRODUCTION) // or PRODUCTION
            .enableTestMode(false) // Only for Pre-Production Environment
            .build(this)
    }
}

Environment Configuration

The SDK supports two environments:

  • Environment.PRODUCTION: PowerBoard Production environment
  • Environment.PRE_PRODUCTION: PowerBoard Pre-Production environment designed for developers to perform integration of PowerBoard into their apps.

Available Widgets

The SDK provides the following pre-built widgets:

  • Card Details Widget
    • Collects and tokenises credit/debit card information.
  • Google Pay Widget
    • Integrates Google Pay payment method.
  • PayPal Widget
    • Provides PayPal checkout functionality.
  • PayPal Vault Widget
    • Enables saving PayPal payment sources for future use.
  • Afterpay Widget
    • Integrates Afterpay buy-now-pay-later service.
  • Address Details Widget
    • Collects billing and shipping address information.
  • Integrated 3DS Widget
    • Handles 3D Secure authentication challenges.

Widget Integration Examples

Card Details Widget

The CardDetailsWidget is used for collecting and tokenising card information:

import com.paydock.feature.card.presentation.CardDetailsWidget
import com.paydock.feature.card.domain.model.integration.CardDetailsWidgetConfig
import com.paydock.feature.card.domain.model.integration.SaveCardConfig

@Composable
fun PaymentScreen() {
    val config = CardDetailsWidgetConfig(
        accessToken = "your_widget_access_token",
        gatewayId = "your_gateway_id", // Optional
        collectCardholderName = true,
        actionText = "Pay Now",
        showCardTitle = true,
        allowSaveCard = SaveCardConfig(
            consentText = "Save this card for future purchases",
            privacyPolicy = SaveCardConfig.PrivacyPolicyConfig(
                privacyPolicyText = "Privacy Policy",
                privacyPolicyUrl = "https://your-site.com/privacy"
            )
        )
    )
    
    CardDetailsWidget(
        config = config,
        enabled = true,
        appearance = CardDetailsAppearanceDefaults.appearance()
    ) { result ->
        result.onSuccess { cardResult ->
            // Handle successful tokenization
            val token = cardResult.token
            val saveCard = cardResult.saveCard
            // Process payment with token
        }.onFailure { exception ->
            // Handle error
            Log.e("Payment", "Card tokenisation failed", exception)
        }
    }
}

Google Pay Widget

The GooglePayWidget integrates Google Pay:

import com.paydock.feature.googlepay.presentation.GooglePayWidget
import com.paydock.feature.googlepay.domain.model.GooglePayWidgetConfig
import org.json.JSONObject

@Composable
fun GooglePaySection() {
    val isReadyToPayRequest = JSONObject().apply {
        put("apiVersion", 2)
        put("apiVersionMinor", 0)
        put("allowedPaymentMethods", JSONArray().apply {
            put(JSONObject().apply {
                put("type", "CARD")
                put("parameters", JSONObject().apply {
                    put("allowedAuthMethods", JSONArray().apply {
                        put("PAN_ONLY")
                        put("CRYPTOGRAM_3DS")
                    })
                    put("allowedCardNetworks", JSONArray().apply {
                        put("AMEX")
                        put("MASTERCARD")
                        put("VISA")
                    })
                })
            })
        })
    }
    
    val paymentRequest = JSONObject().apply {
        put("apiVersion", 2)
        put("apiVersionMinor", 0)
        put("allowedPaymentMethods", isReadyToPayRequest.getJSONArray("allowedPaymentMethods"))
        put("transactionInfo", JSONObject().apply {
            put("totalPriceStatus", "FINAL")
            put("totalPrice", "10.00")
            put("currencyCode", "AUD")
        })
        put("merchantInfo", JSONObject().apply {
            put("merchantId", "your_merchant_id")
            put("merchantName", "Your Store")
        })
    }
    
    val config = GooglePayWidgetConfig(
        isReadyToPayRequest = isReadyToPayRequest,
        paymentRequest = paymentRequest
    )
    
    GooglePayWidget(
        config = config,
        tokenRequest = { tokenCallback ->
            // Obtain wallet token from your backend
            getWalletToken { result ->
                tokenCallback(result)
            }
        }
    ) { result ->
        result.onSuccess { chargeResponse ->
            // Handle successful payment
        }.onFailure { exception ->
            // Handle error
        }
    }
}

PayPal Widget

The PayPalWidget provides PayPal integration:

import com.paydock.feature.paypal.checkout.presentation.PayPalWidget
import com.paydock.feature.paypal.checkout.domain.model.integration.PayPalWidgetConfig

@Composable
fun PayPalSection() {
    val config = PayPalWidgetConfig(
        requestShipping = true
    )
    
    PayPalWidget(
        config = config,
        tokenRequest = { tokenCallback ->
            // Obtain wallet token from your backend
            getWalletToken { result ->
                tokenCallback(result)
            }
        }
    ) { result ->
        result.onSuccess { chargeResponse ->
            // Handle successful payment
        }.onFailure { exception ->
            // Handle error
        }
    }
}

Afterpay Widget

The AfterpayWidget integrates Afterpay:

import com.paydock.feature.afterpay.presentation.AfterpayWidget
import com.paydock.feature.afterpay.domain.model.integration.AfterpaySDKConfig
import java.util.Locale

@Composable
fun AfterpaySection() {
    val config = AfterpaySDKConfig(
        config = AfterpaySDKConfig.AfterpayConfiguration(
            minimumAmount = "1.00",
            maximumAmount = "1000.00",
            currency = "AUD",
            language = Locale.getDefault().language,
            country = Locale.getDefault().country
        ),
        options = AfterpaySDKConfig.CheckoutOptions(
            pickup = false,
            buyNow = true,
            shippingOptionRequired = true
        )
    )
    
    AfterpayWidget(
        config = config,
        tokenRequest = { tokenCallback ->
            // Obtain wallet token from your backend
            getWalletToken { result ->
                tokenCallback(result)
            }
        },
        selectAddress = { address, provideShippingOptions ->
            // Handle address selection
            val shippingOptions = getShippingOptionsForAddress(address)
            provideShippingOptions(shippingOptions)
        },
        selectShippingOption = { shippingOption, provideUpdate ->
            // Handle shipping option selection
            val update = calculateShippingUpdate(shippingOption)
            provideUpdate(update)
        }
    ) { result ->
        result.onSuccess { chargeResponse ->
            // Handle successful payment
        }.onFailure { exception ->
            // Handle error
        }
    }
}

Address Details Widget

The AddressDetailsWidget collects address information:

import com.paydock.feature.address.presentation.AddressDetailsWidget
import com.paydock.feature.address.domain.model.integration.BillingAddress

@Composable
fun AddressSection() {
    var selectedAddress by remember { mutableStateOf<BillingAddress?>(null) }
    
    AddressDetailsWidget(
        address = selectedAddress, // Pre-populate if available
        appearance = AddressDetailsAppearanceDefaults.appearance()
    ) { billingAddress ->
        selectedAddress = billingAddress
        // Use the address for payment processing
    }
}

3D Secure Widget

The Integrated3DSWidget handles 3DS authentication:

import com.paydock.feature.threeDS.integrated.presentation.Integrated3DSWidget
import com.paydock.feature.threeDS.common.domain.integration.ThreeDSConfig

@Composable
fun ThreeDSSection(threeDSToken: String) {
    val config = ThreeDSConfig(token = threeDSToken)
    
    Integrated3DSWidget(
        config = config,
        appearance = ThreeDSAppearanceDefaults.appearance()
    ) { result ->
        result.onSuccess { threeDSResult ->
            // Handle successful 3DS authentication
            val authenticationResult = threeDSResult.result
            // Continue with payment flow
        }.onFailure { exception ->
            // Handle 3DS authentication failure
        }
    }
}

PayPal Vault Widget

The PayPalSavePaymentSourceWidget enables saving PayPal payment sources:

import com.paydock.feature.paypal.vault.presentation.PayPalSavePaymentSourceWidget
import com.paydock.feature.paypal.vault.domain.model.integration.PayPalVaultConfig

@Composable
fun PayPalVaultSection() {
    val config = PayPalVaultConfig(
        accessToken = "your_widget_access_token",
        gatewayId = "your_paypal_gateway_id",
        actionText = "Link PayPal Account"
    )
    
    PayPalSavePaymentSourceWidget(
        config = config,
        enabled = true,
        appearance = PayPalPaymentSourceAppearanceDefaults.appearance()
    ) { result ->
        result.onSuccess { vaultResult ->
            // Handle successful PayPal account linking
            val token = vaultResult.token
            val email = vaultResult.email
            // Save payment source for future use
        }.onFailure { exception ->
            // Handle error
            Log.e("PayPalVault", "Linking failed", exception)
        }
    }
}

Configuration Reference

Card Details Widget Configuration

data class CardDetailsWidgetConfig(
    val accessToken: String,                    // Required: Widget access token
    val gatewayId: String? = null,             // Required: Gateway identifier
    val collectCardholderName: Boolean = true,  // Collect cardholder name
    val actionText: String = "Submit",          // Button text
    val showCardTitle: Boolean = true,          // Show card section title
    val allowSaveCard: SaveCardConfig? = null,  // Save card configuration
    val schemeSupport: SupportedSchemeConfig = SupportedSchemeConfig() // Card scheme validation
)

Google Pay Widget Configuration

data class GooglePayWidgetConfig(
    val isReadyToPayRequest: JSONObject,  // Google Pay readiness check
    val paymentRequest: JSONObject        // Payment request details
)

PayPal Widget Configuration

data class PayPalWidgetConfig(
    val requestShipping: Boolean = true   // Request shipping information
)

Afterpay Configuration

data class AfterpaySDKConfig(
    val config: AfterpayConfiguration,    // Main configuration
    val options: CheckoutOptions? = null  // Additional options
)

data class AfterpayConfiguration(
    val minimumAmount: String? = null,    // Minimum transaction amount
    val maximumAmount: String,            // Maximum transaction amount
    val currency: String,                 // Transaction currency
    val language: String = Locale.getDefault().language,
    val country: String = Locale.getDefault().country
)

PayPal Vault Configuration

data class PayPalVaultConfig(
    val accessToken: String,              // Required: Access token
    val gatewayId: String,               // Required: Gateway identifier
    val actionText: String? = null,       // Optional: Custom button text
    val icon: ButtonIcon? = ButtonIcon.DrawableRes(R.drawable.ic_link) // Optional: Custom icon
)

3DS Configuration

data class ThreeDSConfig(
    val token: String                    // Required: 3DS authentication token
)

Error Handling

Common Exception Types

The SDK provides specific exception types for different scenarios:

// Card-related exceptions
import com.paydock.core.domain.error.exceptions.CardException

// Google Pay exceptions
import com.paydock.core.domain.error.exceptions.GooglePayException

// PayPal exceptions
import com.paydock.core.domain.error.exceptions.PayPalException

// Afterpay exceptions
import com.paydock.core.domain.error.exceptions.AfterpayException

// 3DS exceptions
import com.paydock.core.domain.error.exceptions.Integrated3DSException

Error Handling Example

CardDetailsWidget(config = config) { result ->
    result.onFailure { exception ->
        when (exception) {
            is CardException.ValidationException -> {
                // Handle validation errors
                showError("Please check your card details")
            }
            is CardException.NetworkException -> {
                // Handle network errors
                showError("Network error. Please try again.")
            }
            is CardException.TokenizationException -> {
                // Handle tokenization errors
                showError("Unable to process card. Please try again.")
            }
            else -> {
                // Handle other errors
                showError("An unexpected error occurred")
            }
        }
    }
}

Testing

Test Mode Configuration

Enable test mode for non-production environments:

MobileSDK.Builder()
    .environment(Environment.STAGING)
    .enableTestMode(true) // Only available for non-production
    .build(this)

Running the Sample App

  1. Clone the Repository: bash git clone https://github.com/CommBank-PowerBoard/powerboard-android-mobile-sdk.git
  2. Open in Android Studio: Open the sample/ directory in Android Studio.
  3. Select a Build Variant: In Android Studio, go to Build > Select Build Variant... and choose one of the following:
    1. preprodDebug
    2. prodDebug
  4. Run the App: Click the "Run" button (green play icon) in Android Studio to build and run the sample app on an emulator or a connected device.