Improved

Checkout SDK Updates — Web v1.8.0, Android v1.4.0

Web SDK — v1.8.0 (2026-09-28)

View on GitHub

Added

  • Optional CVV support in Hosted Fields via setCVVOptional(boolean) — an empty CVV passes client-side validation and an empty cvv value is sent at tokenization, while a typed CVV is still fully validated. Recache and Click to Pay are unaffected and always require a CVV.
  • Express Checkout optional/hidden CVV: init-time config on uiConfig.cardPaymentFormFields.verification_value (isRequired: false to show but not require, isHidden: true to not render), plus runtime setters setCVVOptional(boolean) and setCVVHidden(boolean).
  • Paze mount() / isMounted(): the SDK creates its own <paze-button> in paymentElements.paze with an optional buttonStyle; displayMode: 'dynamic' inserts it hidden until an eligible canCheckout().
  • Paze environmentKey config so a standalone Paze integration (no other Spreedly SDK on the page) can still be attributed to your environment.
  • New Paze events pazeButtonClicked (emitted by the SDK-owned button before getCheckoutOptions() runs) and pazeEligibilityChecked (emitted on every canCheckout() resolution with { eligible }).

Changed

  • Card brand logos now render in the card number field for both Hosted Fields and Express Checkout (Visa, Mastercard, Amex, Discover, Diners Club, JCB, Maestro, UnionPay, Elo; generic icon otherwise), replacing the text badge. No API change — existing hide toggles still work.
  • Hosted Fields inputs now set their own padding instead of inheriting the browser's, so text sits consistently across browsers (setStyles still overrides).
  • Breaking (Paze): the SDK now owns the <paze-button>. paymentElements: { paze: '<id>' } and a synchronous getCheckoutOptions are now required, and checkout() no longer starts a flow (START_FLOW is rejected — only CHANGE_CARD and CHANGE_SHIPPING_ADDRESS are supported). See docs/paze/INTEGRATION_GUIDE.md for migration steps.

Fixed

  • Hosted Fields: non-digit characters no longer flash in the card number and CVV inputs. No public API, event, or payload change.

Android SDK — v1.4.0 (2026-09-16)

View on GitHub

Changed

  • Compiles with Kotlin 2.1.20 (was 2.3.10) so React Native 0.82–0.86 hosts no longer need to pin Kotlin 2.3.10; AGP, Gradle, and Compose BOM are unchanged.
  • Custom loggers (setLogger) now receive already-sanitized tag, message, and throwable — no original exception type or PAN/CVV in log text.
  • Recache CVV and the in-flight spinner are no longer restored after rotation.

Breaking Changes

  • SpreedlyApiErrorDetail stored strings (rawErrorBody, messages, validation errors) are now capped and redacted and may not be valid JSON — use statusCode / errorKey / safeDescription(); do not parse rawErrorBody as wire JSON.
  • ACH account-number validation is ciphertext-only; a raw account number in callbacks or validators fails and will not tokenize — use SPLTextField(FormFieldType.ACCOUNT_NUMBER).
  • Plaintext digits on onCardNumberChange no longer set cardScheme — drive PAN through SPLTextField.

Deprecated

  • SpreedlyEncryption / Encryptor / FormFieldType.shouldEncrypt() are lint-deprecated and restricted to the library group — use SPLTextField for card and bank fields.

Fixed

  • Extensive Click to Pay fixes: leaked host-ingress threads on WebView detach, saved-card tokenization failures caused by over-redacted Mastercard flow/correlation IDs, missing CSP/allowlist hosts for Visa, Amex and Discover networks (identity lookup, enrollment, saved-card art, and fingerprinting), an invalid email/phone ending checkout instead of allowing retry, and stuck states after OTP-with-no-cards or a declined new card.

Security

  • Log-safe toString() for failed payment, 3DS challenge, and API-error results; LogSanitizer redaction of PAN-like digit runs (12+, including separated or embedded) and labeled CVV, including across the 8 KiB cap.
  • Click to Pay hardening: host WebView uses origin-checked messaging instead of JavascriptInterface; script-src CSP uses a SHA-256 hash instead of unsafe-inline with an explicit per-network host allowlist; the bridge origin check is narrowed back to Mastercard-only; CDN hosts are no longer valid main-frame navigation targets; and shouldInterceptRequest now enforces the navigation policy for main-frame POSTs.
  • FLAG_SECURE is retained until the last overlapping Spreedly screen closes (merchant-set flag preserved), and corrupt optional card/CVV/account ciphertext returns ValidationFailed instead of tokenizing empty values.