Skip to content

Conversation

@programmeraditya
Copy link

@programmeraditya programmeraditya commented Oct 13, 2025

What This Adds

Implements the new Embedded Payment Element from Stripe's mobile SDKs. Lets you embed the payment UI inline instead of using modal sheets.

Changes

  • New EmbeddedPaymentElement widget with iOS/Android platform views
  • EmbeddedPaymentElementController to call confirm() and clearPaymentOption()
  • Callbacks for payment selection, height changes, loading failures, form sheet completion, and immediate actions
  • Works with both payment and setup intents

Status

iOS ✅

Works. Platform view renders properly, confirm() returns the result, all callbacks fire. Tested with cards, Apple Pay, Link, PayPal, Revolut Pay.

Android ✅

Works. Platform view renders properly, confirm() returns the result, all callbacks fire. Tested with cards, Google Pay, Link, PayPal, Revolut Pay.

Quick Example

EmbeddedPaymentElement(
  intentConfiguration: IntentConfiguration(
    mode: IntentMode.paymentMode(amount: 5000, currencyCode: 'USD'),
    confirmHandler: (paymentMethod, shouldSave, callback) async {
      // Get client secret from your backend
      callback(IntentCreationCallbackParams(clientSecret: secret));
    },
  ),
  configuration: SetupPaymentSheetParameters(
    merchantDisplayName: 'My Store',
    customerId: customerId,
    customerEphemeralKeySecret: ephemeralKey,
  ),
  controller: controller,
  onPaymentOptionChanged: (option) => print('Payment method selected'),
)

React Native docs: https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=react-native

…irm()

Changes confirm() method to return payment result instead of void,
allowing Flutter apps to detect payment failures without relying solely
on callbacks.

- Modified EmbeddedPaymentElementController.confirm() return type
- Updated embedded_payment_element.dart to capture method channel result
- iOS implementation complete with result dictionary
- Android implementation incomplete (help wanted)

Fixes detection of payment failures (insufficient funds, card declined, etc.)
Follows React Native SDK pattern where confirm() returns result status.
- Added onConfirmResult callback property to EmbeddedPaymentElementView
- Modified resultCallback to invoke Flutter method channel callback
- Updated platform view to set callback before calling confirm()
- Callback returns Map with status and optional error message
- Matches iOS implementation for consistent cross-platform behavior
…errors

- Removed updateConfiguration and updateIntentConfiguration from method channel handler
- These methods were unused and causing Dynamic type mismatch compile errors
- Configuration is set once during initialization and doesn't need updates
- Added Jetpack Compose BOM and core dependencies (ui, foundation, runtime)
- Updated Kotlin from 1.8.0 to 1.9.0 for Compose compatibility
- Added Compose build features and compiler extension version
- Fixes 'Unresolved reference' errors for Box, requiredHeight, foundation
- Required for EmbeddedPaymentElement which uses Compose UI
- Read kotlinVersion from rootProject.ext with fallback
- Check kotlinMajor version to conditionally load compose plugin
- Fixes Kotlin 2.0 compose compiler requirement
- Cast entry.value to Dynamic for ViewManager methods
- Change array.size() to array.size (property not function)
- Fixes Kotlin 2.0 compilation errors
Android would crash when intentConfiguration was provided. Fixed by updating how payment data is passed to native code.
Fixed compilation errors in Bundle handling and upgraded Gradle to 8.11.1 to match React Native SDK.
Bundle.getBundle() throws ClassCastException when value is a string. Wrapped in try-catch to mirror React Native's ReadableMap behavior.
Changed from try-catch to type check with Bundle.get() to avoid Android logging warnings when color values are strings.
Height changes were sent to wrong channel. Widget now receives events
directly from platform view instead of global emitter.

Added callbacks for all events:
- onHeightChanged
- onPaymentOptionChanged
- onLoadingFailed
- onRowSelectionImmediateAction
- onFormSheetConfirmComplete

Matches iOS behavior.
@jonasbark
Copy link
Member

jonasbark commented Oct 17, 2025

It looks really good upon first inspection, thanks for all the effort!

I was hesitant to add it due to the Compose requirement, but I think it's a transitive dependency of stripe-android anyway.

Will have a closer look soon

Copy link
Member

@remonh87 remonh87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked it from the dart side and looks good to me only I think dart format did create a bigger change than needed

thank you for this great contribution. I will wait for @jonasbark feedback before integrating it

black,
automatic,
}
enum ApplePayButtonStyle { white, whiteOutline, black, automatic }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What command did you run for dart format?

Looks like quite some changes were made due formatter

Comment on lines +700 to +704
@override
void setConfirmHandler(ConfirmHandler? handler) {
_confirmHandler = handler;
}

Copy link

@tara-pogancev tara-pogancev Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When opening the code locally, I get an error for WebStripe class:
"Missing concrete implementation of 'abstract class StripePlatform extends PlatformInterface. setConfirmHandler'."

I fixed it via quick fix, but should this change for web package be in the PR as well?

@programmeraditya
Copy link
Author

programmeraditya commented Nov 24, 2025

Hello @remonh87
Is there any update on when this PR can be merged?

@remonh87
Copy link
Member

@jonasbark can you take a look at it as well?

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.

4 participants