Skip to content

Apple Pay no longer works with confirmPayment() #2282

@luanalbineli

Description

@luanalbineli

Describe the bug
After we upgraded the lib's version from 11.3.0 to 12.0.2 we're no longer able to use confirmPayment() to complete the purchase using Apple Pay. It now throws a PlatformException with the Invalid Params message.

To Reproduce
Steps to reproduce the behavior:

  1. Launches the Apple Pay wallsheet to create the payment intent:
final paymentMethod = await Stripe.instance
    .createPlatformPayPaymentMethod(
      params: PlatformPayPaymentMethodParams.applePay(
        applePayParams: ApplePayParams(
          cartItems: [
            ApplePayCartSummaryItem.immediate(
              label: 'Label',
              amount: '10.90',
            ),
          ],
          merchantCountryCode: 'IT',
          currencyCode: 'EUR',
        ),
      ),
    );
  1. Create the payment intent to get the secret.
  2. Confirm the payment:
await Stripe.instance.confirmPayment(
  paymentIntentClientSecret: 'secret_from_previous_step',
)
  1. Observe a failure with exception:
PlatformException(Invalid Params, , , null) - #0      JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:168:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:367:18)
<asynchronous suspension>
#2      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:567:43)
<asynchronous suspension>
#3      MethodChannelStripe.confirmPayment (package:stripe_platform_interface/src/method_channel_stripe.dart:132:20)
<asynchronous suspension>
#4      Stripe.confirmPayment (package:flutter_stripe/src/stripe.dart:374:29)

Expected behavior
The payment to be successfully processed using Apple Pay.

Smartphone / tablet

  • Device: iPhone 9 (it should happen with any device)
  • OS: iOS 16 (same from device)
  • Package version: 12.0.2
  • Flutter version 3.35.3

Additional context
The confirmPayment() method on Swift seems to be validating if the method channel is sending the params argument on the most recent versions:

func confirmPayment(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    guard let arguments = call.arguments as? FlutterMap,
          let paymentIntentClientSecret = arguments["paymentIntentClientSecret"] as? String,
          let options = arguments["options"] as? NSDictionary,
          let params = arguments["params"] as? NSDictionary else {
        result(FlutterError.invalidParams)
        return
    }
    
    confirmPayment(
        paymentIntentClientSecret: paymentIntentClientSecret,
        params: params,
        options: options,
        resolver: resolver(for: result),
        rejecter: rejecter(for: result)
    )
}

On version 11.3.0 the property could be nullable:

func confirmPayment(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    guard let arguments = call.arguments as? FlutterMap,
          let paymentIntentClientSecret = arguments["paymentIntentClientSecret"] as? String,
          let options = arguments["options"] as? NSDictionary else {
        result(FlutterError.invalidParams)
        return
    }
    let params = arguments["params"] as? NSDictionary
    confirmPayment(
        paymentIntentClientSecret: paymentIntentClientSecret,
        params: params,
        options: options,
        resolver: resolver(for: result),
        rejecter: rejecter(for: result)
    )
}

On the method channel implementation, this property can be nullable as well:

  @override
  Future<PaymentIntent> confirmPayment(
    String paymentIntentClientSecret,
    PaymentMethodParams? params,
    PaymentMethodOptions? options,
  ) async {
    final result = await _methodChannel
        .invokeMapMethod<String, dynamic>('confirmPayment', {
          'paymentIntentClientSecret': paymentIntentClientSecret,
          'params': params?.toJson(),
          'options': options?.toJson() ?? {},
        });

    return ResultParser<PaymentIntent>(
      parseJson: (json) => PaymentIntent.fromJson(json),
    ).parse(result: result!, successResultKey: 'paymentIntent');
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds triageNeeds triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions