Run the sample app
The SDK's repository ships a complete Compose app, the :app module, that exercises every feature: card, Google Pay, PayPal, Klarna, redirection methods, gift cards and co-payment, saved cards, BNPL simulation, session refresh, and the confirmation of a payment after a redirect. It is the reference to read next to the guides, and a quick way to check that a sandbox session behaves as expected before writing your own screen.
Get it
git clone https://github.com/UpStreamPay/purse-headless-checkout-android.git
cd purse-headless-checkout-android
./gradlew :app:installDebug # Gradle provisions its own JDK; an emulator or device must be connected
The build needs nothing from your machine besides the Android SDK Android Studio installs. The app depends on the SDK modules of the repository, so it always runs against the checked-out version; check out a release tag (git checkout v0.1.0) to match the artifacts you depend on.
Give it a session
The first screen takes a client session. Create one with your sandbox credentials as in Your first payment with Purse, open the Developer disclosure on the Store setup screen, paste the widget.data string and tap Use this widget.data. The screen then shows the decoded session under Session details, and the methods it offers in the method picker.
The New session button mints a session through a development server internal to Purse and does nothing outside Purse's network. Merchants paste their own widget.data.
What each screen shows
| Screen | Exercises |
|---|---|
| Store setup | PurseHeadlessCheckout.init, the decoded session, the method list with each item's disabled state, and presets choosing which methods the store shows |
| Checkout | setSession (refresh), one row per primary method and saved token, the payment element of the selected one, gift card entry with balance check and slices, the split and isPaymentFulfilled, the Pay button, BNPL simulation preview |
| Result | The four PaymentOutcomes mapped to authorized, failed or unconfirmed. Its developer panel has a Get transactions button that reads the session through Purse's internal development server |
The result screen deliberately does not trust a return from a redirect: it reads the session's transactions through Purse's internal development server, standing in for a merchant backend, and only for a session created with New session. With a pasted widget.data, the return stays unconfirmed in the app. In your own app, confirm the payment on your backend, through webhooks or Get a client session.
Which methods appear
The session decides. The app declares all four artifacts, so any method your entity offers is usable: a card vaulted by Purse, Google Pay, PayPal, Klarna, any method configured in redirection mode, and every gift card issuer the SDK ships. Klarna's Maven repository and deep link are already set up in the app's settings.gradle.kts and manifest, which you can copy.
Where to look in the code
| File | Shows |
|---|---|
DemoController.kt | Building the checkout, selecting items, wiring one PaymentElementListener per item, submitting, mapping outcomes |
CheckoutScreen.kt | Rendering rows and the selected payment element, gift card forms, the split |
SimulationPreview.kt | A complete rendering of a simulateLoan answer |
ResultScreen.kt | Rendering an outcome, and the developer panel's transactions read |
A minified release build of the same app (./gradlew :app:assembleRelease) runs in the repository's CI with the SDK's consumer R8 rules, so what you see is the path a release build of your app takes.