Improved

Checkout SDK Updates — Web v1.4.1, Android v1.3.0

Web — v1.4.1 (2026-07-31)

View on GitHub

Added

  • Click to Pay (Mastercard SRC): New SpreedlyClickToPay entry point (exposed from the Hosted Fields bundle) for Mastercard Click to Pay checkout — identity lookup (recognized device / OTP / new user), Mastercard <src-card-list> / <src-otp-input> components driven by the SDK, checkout in a popup or embedded drawer (checkoutPresentation), and tokenization into a standard Spreedly payment method. Single-entry integration via config.fields: the SDK mounts its own hosted card fields (exposed as c2p.hostedFields), encrypts new-card PANs with Mastercard encryptCard inside the number iframe, and runs all tokenization in-iframe so the PAN/CVV never touch the merchant page. Legacy kebab-case C2P event names are preserved for migration; error events carry a machine-routable stage code. See docs/click-to-pay/.
  • Test SCA provider 3DS Global support: Transactions created with Spreedly's test SCA provider (sca_provider_type: "test") now run the 3DS Global flow. These carry no managed_order_token, so Forter is not involved — the SDK presents the challenge when the transaction supplies one and otherwise completes authentication server-side, emitting the same onChallenge / onSuccess / onError callbacks as the Forter flow.
  • Mandate passthrough (AC-62): Optional mandate field on the tokenization APIs — SubmitParams (Hosted Fields submit() and Express Checkout submitParams / updateSubmitParams) and the setupACHPayment config. Forwarded verbatim to Spreedly Core at payment_method.mandate and omitted when empty. Opaque by design via a new exported Mandate type (Record<string, unknown>) — Spreedly Core owns the mandate schema and validation.

Android — v1.3.0 (2026-07-30)

View on GitHub

Added

  • Click to Pay (clicktopay): Optional :clicktopay artifact with Mastercard WebView checkout (not present in the 1.2.0 artifact). Entry points: SpreedlyClickToPayCheckout (present, cancel, events, state, tokenize, lookup/OTP helpers), drop-in SpreedlyClickToPayButton / ClickToPayBrandedButton, and ClickToPaySavedCardsDetector for pre-checkout Remember-me recognition (tear down before present()). Sandbox new-user enrollment via ClickToPayCheckoutConfig.sandboxEnrollmentCard (in-memory only; rejected in production). Default UI uses MC src-card-list with native SPL CVV/pay; sheet chrome follows Spreedly.setGlobalTheme() via SpreedlyAdaptiveGlobalTheme (pay actions keep Mastercard SRC branding). WebView is hardened (Mastercard host allowlist, scheme deny-list, bridge method/size/forbidden-key guards, DCF popup policies); public CheckoutComplete carries metadata only (no PAN/CVV). See the Click to Pay Integration Guide.
  • Mandate passthrough on tokenization (payments-core, paymentsheet, hostedfields): Optional mandate on tokenize APIs and drop-in sheets, forwarded verbatim to Spreedly at payment_method.mandate and omitted when null or empty. Accepts a Map<String, Any?> (nested values preserved; pre-parsed JsonObject allowed). Spreedly owns schema validation; the SDK does not cap or validate mandate contents. Wire semantics follow ECMA-262 JSON.stringify (NaN / Infinitynull; Date / Instant / UUID / URL / URI → canonical string). Unrepresentable values or reference cycles fail tokenization with the offending key path. Mandate contents are never logged.

Breaking Changes

  • SpreedlyBottomSheet / SpreedlyBankAccountBottomSheet Compose signatures (paymentsheet): The optional trailing mandate changes the Compose-generated method name — recompile consumers against the new paymentsheet AAR. Kotlin callers using defaults are source-compatible; Java PaymentSheetJavaHelper.setupContent keeps prior overload arities.
  • Tokenize APIs gain trailing mandate (payments-core): Spreedly.createCreditCard / createPaymentMethod (and matching SpreedlyPaymentManager methods) take an optional mandate: Map<String, Any?>?. Kotlin defaults remain source-compatible; Java callers must pass null or a map.