BreX900 / mek-packages

10 stars 13 forks source link

Error message given by stripe during payment verification #56

Open batuhanseckinnn opened 5 months ago

batuhanseckinnn commented 5 months ago

Hi @BreX900

No matter what reason the payment fails, PlatformException is constantly thrown and it does not contain the error message coming from stripe.

I think it is already stated in the codes that this part is not fully verified. As a result of my tests, while it works smoothly on Android devices, we cannot catch the error on iOS devices.

Screenshot 2024-02-14 at 14 58 26

When I catch the error it looks like this

Screenshot 2024-02-14 at 14 54 59

I leave a simple code block so you can reproduce the error. If there is a point I missed and you can help me, I would be very happy.

  Future<void> payment(
    String clientSecret,
  ) async {
    try {
      // insufficient_funds
      terminal?.setSimulatorConfiguration(const SimulatorConfiguration(
          simulatedCard: SimulatedCard.fromTestCardNumber("4000000000009995")));

      PaymentIntent? paymentIntent =
          await terminal?.retrievePaymentIntent(clientSecret);

      PaymentIntent? processablePaymentIntent =
          await terminal?.collectPaymentMethod(paymentIntent!);

      await terminal?.confirmPaymentIntent(processablePaymentIntent!);
    } on TerminalException catch (e) {
      print(e);
    } on PlatformException catch (e) {
      print(e);
    } catch (e) {
      print(e);
    }
  }

mek_stripe_terminal version : 3.2.1 flutter version : 3.16.0

ahsinirshad22 commented 4 months ago

Hi @BreX900 @batuhanseckinnn

The issue is at await terminal?.confirmPaymentIntent(processablePaymentIntent!);

we are just passing payment intent into confirm payment intent. But as per stripe documentation a return_url also should be provided. It's my request to plugin owner to add this functionality init bcz currently we only can pass single parameter. One of my client is also facing same issue.

Thanks and Regards Ahsin Irshad https://www.ahsinirshad.com

BreX900 commented 4 months ago

Could you share the documentation you are talking about? If I haven't implemented those parameters they probably don't exist in the native android/ios sdk. If so, please provide the official documentation and I will implement it Note: I avoid implementing parameters/methods that exist in only one of the two SDKs

https://docs.stripe.com/terminal/quickstart

batuhanseckinnn commented 4 months ago

@BreX900

Changing the onConfirmPaymentIntent method in the TerminalPlugin.swift file as follows seems to solve the issue.

  func onConfirmPaymentIntent(
        _ paymentIntentId: String
    ) async throws -> PaymentIntentApi {
        let paymentIntent = try _findPaymentIntent(paymentIntentId)
        do {
            let (intent, error) = await Terminal.shared.confirmPaymentIntent(paymentIntent)
            if let error {
                if let paymentIntent = error.paymentIntent {
                    _paymentIntents[paymentIntent.stripeId!] = paymentIntent
                }
                throw error.toPlatformError(apiError: error.requestError, paymentIntent: error.paymentIntent)
            }
            return intent!.toApi()
        } catch let error as PlatformError {          // Added line
            throw error                               // Added line
        } catch let error as NSError {
            throw error.toPlatformError()
        }
    }
throw error.toPlatformError(apiError: error.requestError, paymentIntent: error.paymentIntent)

After the thrown PlatformError is caught by NSError, the information collected while PlatformError is recreated is lost.

ahsinirshad22 commented 4 months ago

@BreX900 Sorry for the late reply.

Here is the confirm payment intent official docs url.

https://docs.stripe.com/api/payment_intents/confirm

In more parameters section you will find return url. Note that this return url is mandatory in case payments where 3d secure is enabled or redirect based payments. In your onConfirmPaymentIntent function you can add a optional parameter of return url. If someone pass a return url to it you will send it with paymentConfirm api call if not you can skip the parameter.

This is my understanding as of now.

Thanks and Regards Ahsin Irshad https://ahsinirshad.com