yevheniionipko / react-native-apple-payment

Apple Pay for React Native
MIT License
15 stars 9 forks source link

Cancel Apple Pay #5

Closed db-flutterwave closed 1 year ago

db-flutterwave commented 1 year ago

This now allows you to know when a request to pay with apple pay is cancelled.

How this is achieved is by setting up paymentAuthorizationViewControllerDidFinish on the ApplePay class, this is called when the user either completes payment or cancels the apple pay sheet. Within this method we call self.resolve("PAYMENT_CANCELLED")

See here for more detail on this method (https://developer.apple.com/documentation/passkit/pkpaymentauthorizationviewcontrollerdelegate).

There is one exception to this step-by-step procedure: The pay authorization view controller calls the paymentAuthorizationViewControllerDidFinish(_:) method as soon as the user cancels a payment without authorizing a payment request, or when a payment is canceled after timing out. The controller can call this method at any time.

There's a catch to it though and that is, the promise resolve will be called twice if the user completes payment because we are also calling self.resolve in the paymentAuthorizationViewController method, the solution is to unset the resolve property on the ApplePay class after paymentAuthorizationViewController is called.

This works because if the user cancels payment, only paymentAuthorizationViewControllerDidFinish is called but if the user makes payment paymentAuthorizationViewController is first called and then paymentAuthorizationViewControllerDidFinish get's called.

Example

User Cancels Payment

System Calls -> paymentAuthorizationViewControllerDidFinish

User Attempts Making Payment

System Calls -> paymentAuthorizationViewController Then System Call -> paymentAuthorizationViewControllerDidFinish

Usage

With this the user can now perform the following to know if the Apple Pay Payment was cancelled.

const result = await paymentHandler.initApplePay();
if (result === "CANCELLED_PAYMENT") {
  return handleApplePayCancel()
}
if (result === "COULD_NOT_FIND_TOKEN") {
  return handleApplePayTokenError()
}
return doSomethingWithTheToken(result)