Skip to content

feat(#2236): EmbeddedPaymentElement example screen and rendering polish#2419

Open
realmeylisdev wants to merge 1 commit into
flutter-stripe:mainfrom
realmeylisdev:feat/embedded-payment-element-example
Open

feat(#2236): EmbeddedPaymentElement example screen and rendering polish#2419
realmeylisdev wants to merge 1 commit into
flutter-stripe:mainfrom
realmeylisdev:feat/embedded-payment-element-example

Conversation

@realmeylisdev
Copy link
Copy Markdown
Contributor

@realmeylisdev realmeylisdev commented May 21, 2026

Summary

Closes the remaining gaps from issue #2236 after PR #2239 shipped the EmbeddedPaymentElement widget. The implementation was merged but the issue stayed open because the example app had no demo, the widget reserved a 400pt blank area while loading, and the Android build.gradle carried dead duplicate Compose config that confused readers debugging Kotlin/Compose failures.

  • Example demo: new example/lib/screens/payment_sheet/embedded/embedded_payment_element_screen.dart covers both PaymentIntent and SetupIntent modes using the deferred confirm-handler pattern. Registered under the existing "Payment Sheet" section, restricted to iOS and Android.
  • Initial-render UX: replaces the 400pt blank placeholder in embedded_payment_element.dart with a 60pt area plus a centered CircularProgressIndicator overlay; AnimatedSize smoothly expands to the measured height once the native side reports it.
  • Docstring: explicit dartdoc clarifying that web and desktop throw UnsupportedError.
  • Gradle cleanup: removes the dead duplicate buildFeatures { compose true } block and the legacy kotlinCompilerExtensionVersion = '1.5.1' (irrelevant once org.jetbrains.kotlin.plugin.compose is applied), and adds a one-line comment explaining the Kotlin/Compose coupling.
  • Docs: new section in packages/stripe_android/README.md documenting the Kotlin/compose-compiler plugin requirement.
  • CHANGELOG: adds an ## Unreleased stanza citing issue Add support for Embedded Payment Element #2236 and PR Add EmbeddedPaymentElement support for Flutter #2239.
  • Wire-contract test: packages/stripe_platform_interface/test/embedded_payment_element_wire_contract_test.dart locks the IntentConfiguration and EmbeddedPaymentElementAppearance JSON shape (in the spirit of test: lock down PaymentSheet wire-format contract for @JsonKey renames #2418).

Reproducing steps (manual verification)

Run the example app on each platform and walk through the demo:

  1. cd example && flutter pub get
  2. Start the demo server (see example/server/README.md) so the deferred confirmHandler can hit /payment-intent-for-payment-sheet and /create-setup-intent.
  3. iOS simulator: flutter run -d ios. Tap Payment Sheet → Embedded Payment Element.
    • Pick Use PaymentIntent.
    • Expected (before this PR): ~400pt blank area below the buttons until the native element loaded.
    • Expected (after this PR): a small ~60pt area with a centered spinner appears immediately; once the native element reports its first height, the area smoothly expands to the real measured height.
    • Select a payment option (card 4242 4242 4242 4242, any future expiry, any CVC). The Pay button enables; tapping it calls controller.confirm() and shows the result string at the bottom.
  4. Repeat with Use SetupIntent to verify the setup-mode path through /create-setup-intent.
  5. Android emulator: flutter run -d emulator-5554. Repeat steps 3 and 4. Verify the spinner placeholder also appears on Android before the Compose view reports its first height.

Test plan

  • flutter test in packages/stripe_platform_interface — 29/29 pass, including 3 new wire-contract tests.
  • flutter analyze on touched files — clean (pre-existing warnings in _parseLoadingError lines remain; not touched by this PR).
  • Manual iOS simulator run of the new demo screen (PaymentIntent + SetupIntent).
  • Manual Android emulator run of the new demo screen (PaymentIntent + SetupIntent).
  • Confirm host-app build still succeeds against Kotlin 2.1.0 (the pinned version) after the Gradle cleanup.

Out of scope

  • Per-instance confirm-handler routing. While investigating I noticed that _StripeMethodChannel._confirmHandler is a single global slot written by both initPaymentSheet and the embedded widget's Stripe.instance.setConfirmHandler(...). If a host app keeps an active PaymentSheet and mounts an EmbeddedPaymentElement at the same time, the embedded widget overwrites the sheet's handler on initState and nulls it on dispose. Fixing this requires a platform-interface contract change and is a separate concern from the example/UX gaps this PR addresses. Happy to file a follow-up issue.
  • Web parity. Stripe.js does not expose a 1:1 "Embedded Payment Element" today, so web/desktop continue to throw UnsupportedError (now explicitly documented in the dartdoc).
  • Expanding EmbeddedPaymentElementAppearance. The Dart model exposes only row today; broader styling (primaryButton, etc.) lives on PaymentSheetAppearance. Out of scope here.

Closes #2236.

Summary by CodeRabbit

  • New Features

    • Embedded Payment Element now available for iOS and Android, enabling seamless payment collection within your app.
  • Bug Fixes

    • Eliminated unwanted blank area that appeared while loading native payment elements; now displays a loading indicator instead.
  • Documentation

    • Android apps using Embedded Payment Element must align with Kotlin 2.1.0.

Review Change Stack

…rendering polish

PR flutter-stripe#2239 shipped the EmbeddedPaymentElement widget, but issue flutter-stripe#2236 stayed
open because (a) the example app had no demo, (b) the widget reserved a
400pt blank area until the first onHeightChanged fired, and (c) the Android
build.gradle carried dead duplicate compose config that confused readers
debugging Kotlin/Compose failures.

- Adds example/lib/screens/payment_sheet/embedded/embedded_payment_element_screen.dart
  demonstrating PaymentIntent and SetupIntent modes with the deferred
  confirm-handler pattern.
- Registers the demo in screens.dart under the existing "Payment Sheet"
  section, restricted to iOS and Android.
- Replaces the 400pt initial-render placeholder with a 60pt area plus a
  centered CircularProgressIndicator overlay; AnimatedSize smoothly
  expands to the measured height once the native side reports it.
- Adds explicit dartdoc clarifying that web and desktop throw
  UnsupportedError.
- Removes the dead duplicate buildFeatures { compose true } block and the
  legacy kotlinCompilerExtensionVersion = '1.5.1' (irrelevant once
  org.jetbrains.kotlin.plugin.compose is applied).
- Documents the Kotlin/compose-compiler coupling in stripe_android/README.md.
- Adds CHANGELOG entry under Unreleased citing issue flutter-stripe#2236 and PR flutter-stripe#2239.
- Adds a wire-format contract test in stripe_platform_interface for
  IntentConfiguration and EmbeddedPaymentElementAppearance JSON shape.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e018441f-8213-4006-99ad-214565bbaf4a

📥 Commits

Reviewing files that changed from the base of the PR and between 8b8d0eb and 107996f.

📒 Files selected for processing (7)
  • example/lib/screens/payment_sheet/embedded/embedded_payment_element_screen.dart
  • example/lib/screens/screens.dart
  • packages/stripe/CHANGELOG.md
  • packages/stripe/lib/src/widgets/embedded_payment_element.dart
  • packages/stripe_android/README.md
  • packages/stripe_android/android/build.gradle
  • packages/stripe_platform_interface/test/embedded_payment_element_wire_contract_test.dart

📝 Walkthrough

Walkthrough

This PR adds Embedded Payment Element support to the Flutter Stripe SDK through a complete example implementation, core widget loading UX improvements, Android platform configuration, and test coverage for serialization contracts.

Changes

Embedded Payment Element example and UX improvements

Layer / File(s) Summary
Widget loading state and platform support documentation
packages/stripe/lib/src/widgets/embedded_payment_element.dart
Class docs clarified to specify UnsupportedError on web/desktop with iOS/Android-only support. build() method now displays a smaller 60pt CircularProgressIndicator placeholder while native element height is unknown, replacing the fixed 400pt fallback.
Example screen implementation with confirm handlers
example/lib/screens/payment_sheet/embedded/embedded_payment_element_screen.dart
Stateful widget lets users select between payment and setup intent modes. Wires EmbeddedPaymentElement to controller with intent configuration, payment method selection, error tracking, and status display. Implements _handlePaymentIntentConfirm() and _handleSetupIntentConfirm() to POST to backend endpoints, validate responses, and forward clientSecret to Stripe.instance.intentCreationCallback.
Example app route and navigation wiring
example/lib/screens/screens.dart
Adds import and "Embedded Payment Element" entry to payment sheet examples with Android/iOS support.
Android platform configuration and documentation
packages/stripe_android/android/build.gradle, packages/stripe_android/README.md
Inline comment ties Kotlin version to EmbeddedPaymentElement. Removes explicit composeOptions.kotlinCompilerExtensionVersion pinning; compose true remains enabled via later block. New README section documents Jetpack Compose requirement and pinned compose-compiler-gradle-plugin (Kotlin 2.1.0) with host app alignment guidance.
Changelog and wire-contract serialization tests
packages/stripe/CHANGELOG.md, packages/stripe_platform_interface/test/embedded_payment_element_wire_contract_test.dart
Unreleased section added documenting iOS/Android Embedded Payment Element support and loading placeholder fix. Test file validates IntentConfiguration and SetupPaymentSheetParameters JSON serialization, verifying nested configs and that Dart handler fields are not serialized.

Sequence Diagram

sequenceDiagram
  participant User
  participant EmbeddedPaymentElement
  participant ExampleScreen
  participant Backend
  participant StripeCallback

  User->>ExampleScreen: Select payment method & confirm
  ExampleScreen->>EmbeddedPaymentElement: controller.confirm()
  EmbeddedPaymentElement->>ExampleScreen: confirmHandler triggered
  ExampleScreen->>Backend: POST selected payment method
  Backend->>ExampleScreen: Return clientSecret
  ExampleScreen->>StripeCallback: intentCreationCallback(clientSecret)
  StripeCallback->>User: Display result message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • flutter-stripe/flutter_stripe#2239: Adds core EmbeddedPaymentElement and EmbeddedPaymentElementController widget/controller implementation with confirm-handler wiring; this PR extends it with example implementation, loading UX improvements, and test coverage.

Suggested labels

Awaiting response

Suggested reviewers

  • jonasbark
  • remonh87

Poem

🐰 A flutter of elements takes its flight,
Embedded payments, polished and bright,
With spinners that spin while heights align,
Example screens that flow and shine—
Android's Compose now plays along! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main changes: adding an EmbeddedPaymentElement example screen and improving the rendering UX with a progress indicator placeholder.
Linked Issues check ✅ Passed The PR directly addresses issue #2236 by implementing EmbeddedPaymentElement support with example screens, improving initial-render UX, adding documentation, and providing wire-contract tests.
Out of Scope Changes check ✅ Passed All changes are scoped to the EmbeddedPaymentElement feature: example screen, rendering improvements, documentation, gradle cleanup for Compose/Kotlin alignment, and wire-contract tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for Embedded Payment Element

1 participant