Checkout Card

The checkout card shows Stash Pay checkout in a native card over the host application. Results arrive through callbacks.

Checkout card on iPhone, unfolded iPhone Duo, and iPad

The checkout card is fully responsive on both platforms and adapts to the device type, state, and system appearance.

Open the card

Pass the checkout link generated on your backend and the view controller or activity showing the game to trigger the checkout dialog:

StashNative.sharedInstance().openCard(withURL: checkoutURL, from: self, config: nil)
StashNative.getInstance().openCard(activity, checkoutUrl, null);

Configuration

To optionally adjust the card configuration, pass StashNativeCardConfig (iOS) or StashNative.CardConfig (Android). Sizes are in points (iOS) or dp (Android).

We recommend keeping the default card dimensions unless your integration requires a different size.

Property Default Description
preferredContentWidth 400 Preferred width; full width on portrait phones
preferredContentHeight 560 Initial card height
maximumContentHeight 720 Expanded height; 0 removes the limit
edgeMargin 16 Screen edge spacing
allowDismiss true Allow swipe, outside tap, or Back dismissal
autoClose true Close after payment success or failure
orientationPreference Follow host Follow host or force portrait on phones
let config = StashNativeCardConfig()
config.allowDismiss = false
StashNative.sharedInstance().openCard(withURL: checkoutURL, from: self, config: config)
StashNative.CardConfig config = new StashNative.CardConfig();
config.allowDismiss = false;
StashNative.getInstance().openCard(activity, checkoutUrl, config);

Forcing Portrait Card

Portrait checkout card on iPhone, over an app locked to landscape

On phones, the SDK makes a best-effort attempt to render the checkout card as a portrait overlay for more comfortable text input. The host application continues running in landscape and does not need to support portrait.

config.orientationPreference = .portrait
config.orientationPreference = StashNative.CardConfig.ORIENTATION_PORTRAIT;

Portrait backdrop (Android)

Portrait checkout card on Android, over a backdrop image

Forcing a portrait card on Android phones may cause visual glitches in some host applications due to how Android handles screen orientation. To hide these artifacts, set an image backdrop before opening the card. Use a screenshot of the current app state or a custom image:

StashNative.setBackdropBitmap(backdrop); // or setBackdropBytes(pngOrJpegBytes)
StashNative.getInstance().openCard(activity, checkoutUrl, config);

Callbacks

These events go to the shared receiver; see Setting Callbacks.

Callback (iOS / Android) Fires when
stashNativeDidCompletePayment(withOrder:)
onPaymentSuccess(order)
Payment succeeds
stashNativeDidFailPayment()
onPaymentFailure()
Payment fails
stashNativeDidDismissCard()
onCardDismissed()
The user, checkout page, or app dismisses the card
stashNativeDidLoadPage(_:)
onPageLoaded(loadTimeMs)
Checkout loads (includes load time in milliseconds)
stashNativeDidEncounterNetworkError()
onNetworkError()
Checkout fails to load or loses its connection
stashNativeDidRequestExternalPayment(with:)
onExternalPayment(url)
Payment moves to the in-game browser
extension StoreViewController: StashNativeDelegate {
    func stashNativeDidCompletePayment(withOrder order: String?) {
        // Confirm the purchase on your backend, then grant items.
    }

    func stashNativeDidFailPayment() {
        // Update the store UI.
    }

    func stashNativeDidDismissCard() {
        // Resume the game.
    }
}
StashNative.getInstance().setListener(new StashNative.StashNativeListenerAdapter() {
    @Override
    public void onPaymentSuccess(String order) {
        // Confirm the purchase on your backend, then grant items.
    }

    @Override
    public void onPaymentFailure() {
        // Update the store UI.
    }

    @Override
    public void onCardDismissed() {
        // Resume the game.
    }
});

External Payment Scenarios

Some alternative payment methods (such as Klarna, Cash App, etc.) require the user to finish the purchase in an external browser or another app. onExternalPayment notifies the host application of this handoff. Handling it is optional unless your app needs to react to the handoff.

  • By default, the card closes and the payment continues in the in-game browser. The presentation ends with onBrowserDismissed instead of onCardDismissed, and the result arrives through the deep link.
  • When the page passes keepOpen, the browser opens over the card, which stays open for the player’s return. No browser event follows; the card ends with its own events and closes the browser with it.

Other

WebView debugging

During development, make checkout inspectable before opening the card:

StashNative.setInspectableWebViewsEnabled(true)
StashNative.setInspectableWebViewsEnabled(true);

Inspect it with Safari Web Inspector (iOS 16.4+) or chrome://inspect (Android). Keep it off in release builds.

Checking state

Check whether an SDK presentation is active and whether checkout is processing a payment. On iOS, read these values on the main thread.

let isPresented = StashNative.sharedInstance().isCurrentlyPresented
let isProcessing = StashNative.sharedInstance().isPurchaseProcessing
boolean isPresented = StashNative.getInstance().isCurrentlyPresented();
boolean isProcessing = StashNative.getInstance().isPurchaseProcessing();

Dismissing Card

Force dismiss the checkout card programmatically:

StashNative.sharedInstance().dismiss()
StashNative.getInstance().dismiss();