Skip to content

Commit 145e5d4

Browse files
Fix Android shimmer not hiding in embedded payment element
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.
1 parent 8784de2 commit 145e5d4

File tree

2 files changed

+74
-45
lines changed

2 files changed

+74
-45
lines changed

packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeSdkEmbeddedPaymentElementPlatformView.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ class StripeSdkEmbeddedPaymentElementPlatformView(
2626
init {
2727
channel.setMethodCallHandler(this)
2828

29+
embeddedView.onHeightChanged = { height ->
30+
channel.invokeMethod("onHeightChanged", mapOf("height" to height.toDouble()))
31+
}
32+
33+
embeddedView.onPaymentOptionChanged = { paymentOption ->
34+
channel.invokeMethod("onPaymentOptionChanged", mapOf("paymentOption" to paymentOption))
35+
}
36+
37+
embeddedView.onLoadingFailed = { message ->
38+
channel.invokeMethod("embeddedPaymentElementLoadingFailed", mapOf("message" to message))
39+
}
40+
41+
embeddedView.onRowSelectionImmediateAction = {
42+
channel.invokeMethod("embeddedPaymentElementRowSelectionImmediateAction", null)
43+
}
44+
45+
embeddedView.onFormSheetConfirmComplete = { result ->
46+
channel.invokeMethod("embeddedPaymentElementFormSheetConfirmComplete", result)
47+
}
48+
2949
creationParams?.let { params ->
3050
val configMap = params["configuration"] as? Map<*, *>
3151
val intentConfigMap = params["intentConfiguration"] as? Map<*, *>

packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/EmbeddedPaymentElementView.kt

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ class EmbeddedPaymentElementView(
6565
val rowSelectionBehaviorType = mutableStateOf<RowSelectionBehaviorType?>(null)
6666

6767
var onConfirmResult: ((Map<String, Any?>) -> Unit)? = null
68+
var onHeightChanged: ((Float) -> Unit)? = null
69+
var onPaymentOptionChanged: ((Map<String, Any?>?) -> Unit)? = null
70+
var onLoadingFailed: ((String) -> Unit)? = null
71+
var onRowSelectionImmediateAction: (() -> Unit)? = null
72+
var onFormSheetConfirmComplete: ((Map<String, Any>) -> Unit)? = null
6873

6974
private val reactContext get() = context as ThemedReactContext
7075
private val events = Channel<Event>(Channel.UNLIMITED)
@@ -202,45 +207,45 @@ class EmbeddedPaymentElementView(
202207
}
203208
},
204209
resultCallback = { result ->
205-
val map =
206-
Arguments.createMap().apply {
207-
when (result) {
208-
is EmbeddedPaymentElement.Result.Completed -> {
209-
putString("status", "completed")
210-
}
210+
val resultMap = when (result) {
211+
is EmbeddedPaymentElement.Result.Completed ->
212+
mapOf("status" to "completed")
213+
is EmbeddedPaymentElement.Result.Canceled ->
214+
mapOf("status" to "canceled")
215+
is EmbeddedPaymentElement.Result.Failed ->
216+
mapOf("status" to "failed", "error" to (result.error.message ?: "Unknown error"))
217+
}
211218

212-
is EmbeddedPaymentElement.Result.Canceled -> {
213-
putString("status", "canceled")
214-
}
219+
onConfirmResult?.invoke(resultMap)
215220

216-
is EmbeddedPaymentElement.Result.Failed -> {
217-
putString("status", "failed")
218-
putString("error", result.error.message ?: "Unknown error")
221+
onFormSheetConfirmComplete?.invoke(resultMap) ?: run {
222+
val map =
223+
Arguments.createMap().apply {
224+
when (result) {
225+
is EmbeddedPaymentElement.Result.Completed -> {
226+
putString("status", "completed")
227+
}
228+
is EmbeddedPaymentElement.Result.Canceled -> {
229+
putString("status", "canceled")
230+
}
231+
is EmbeddedPaymentElement.Result.Failed -> {
232+
putString("status", "failed")
233+
putString("error", result.error.message ?: "Unknown error")
234+
}
219235
}
220236
}
221-
}
222-
223-
// Call Flutter method channel result callback
224-
onConfirmResult?.invoke(
225-
when (result) {
226-
is EmbeddedPaymentElement.Result.Completed ->
227-
mapOf("status" to "completed")
228-
is EmbeddedPaymentElement.Result.Canceled ->
229-
mapOf("status" to "canceled")
230-
is EmbeddedPaymentElement.Result.Failed ->
231-
mapOf("status" to "failed", "error" to (result.error.message ?: "Unknown error"))
232-
}
233-
)
234-
235-
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
237+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementFormSheetConfirmComplete(map)
238+
}
236239
},
237240
).confirmCustomPaymentMethodCallback(confirmCustomPaymentMethodCallback)
238241
.rowSelectionBehavior(
239242
if (type == RowSelectionBehaviorType.Default) {
240243
EmbeddedPaymentElement.RowSelectionBehavior.default()
241244
} else {
242245
EmbeddedPaymentElement.RowSelectionBehavior.immediateAction {
243-
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementRowSelectionImmediateAction()
246+
onRowSelectionImmediateAction?.invoke() ?: run {
247+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementRowSelectionImmediateAction()
248+
}
244249
}
245250
},
246251
)
@@ -266,15 +271,15 @@ class EmbeddedPaymentElementView(
266271
when (result) {
267272
is EmbeddedPaymentElement.ConfigureResult.Succeeded -> reportHeightChange(1f)
268273
is EmbeddedPaymentElement.ConfigureResult.Failed -> {
269-
// send the error back to JS
270274
val err = result.error
271275
val msg = err.localizedMessage ?: err.toString()
272-
// build a RN map
273-
val payload =
274-
Arguments.createMap().apply {
275-
putString("message", msg)
276-
}
277-
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementLoadingFailed(payload)
276+
onLoadingFailed?.invoke(msg) ?: run {
277+
val payload =
278+
Arguments.createMap().apply {
279+
putString("message", msg)
280+
}
281+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementLoadingFailed(payload)
282+
}
278283
}
279284
}
280285
}
@@ -292,11 +297,13 @@ class EmbeddedPaymentElementView(
292297
LaunchedEffect(embedded) {
293298
embedded.paymentOption.collect { opt ->
294299
val optMap = opt?.toWritableMap()
295-
val payload =
296-
Arguments.createMap().apply {
297-
putMap("paymentOption", optMap)
298-
}
299-
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementDidUpdatePaymentOption(payload)
300+
onPaymentOptionChanged?.invoke(optMap) ?: run {
301+
val payload =
302+
Arguments.createMap().apply {
303+
putMap("paymentOption", optMap)
304+
}
305+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementDidUpdatePaymentOption(payload)
306+
}
300307
}
301308
}
302309

@@ -356,11 +363,13 @@ class EmbeddedPaymentElementView(
356363
}
357364

358365
private fun reportHeightChange(height: Float) {
359-
val params =
360-
Arguments.createMap().apply {
361-
putDouble("height", height.toDouble())
362-
}
363-
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementDidUpdateHeight(params)
366+
onHeightChanged?.invoke(height) ?: run {
367+
val params =
368+
Arguments.createMap().apply {
369+
putDouble("height", height.toDouble())
370+
}
371+
requireStripeSdkModule().eventEmitter.emitEmbeddedPaymentElementDidUpdateHeight(params)
372+
}
364373
}
365374

366375
// APIs

0 commit comments

Comments
 (0)