Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crash when using apple pay #25

Open
abdallahkadour opened this issue Mar 29, 2023 · 2 comments
Open

App crash when using apple pay #25

abdallahkadour opened this issue Mar 29, 2023 · 2 comments

Comments

@abdallahkadour
Copy link

abdallahkadour commented Mar 29, 2023

Error:

***** Fatal JavaScript exception - application has been terminated. *****
NativeScript encountered a fatal error: Uncaught Error: The data couldn’t be read because it isn’t in the correct format.
at
PKPaymentAuthorizationViewControllerDelegateImpl.paymentAuthorizationViewControllerDidAuthorizePaymentHandler(file: src/webpack:/vois-mgov/node_modules/@nativescript/apple-pay/payment-authorization-view-controller-delegate.ios.js:43:0)
(CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Uncaught Error: The data couldn’t be read because it isn’t in the correct format.
at
PKPaymentAuthorizationViewControllerDelegateImpl.paymentAuthorizationViewControllerDidAuthorizePaymentHandler(file: src/webpack:/vois-mgov/node_modules/@nativescript/apple-pay/payment-authorization-view-controller-delegate.ios.js:43:0)
', reason: '(null)'
*** First throw call stack:
(
0   CoreFoundation                      0x00007fff20406d44 __exceptionPreprocess + 242
1   libobjc.A.dylib                     0x00007fff201a4a65 objc_exception_throw + 48
2   NativeScript                        0x000000010610de7e __copy_helper_block_e8_32o + 0
3   libdispatch.dylib                   0x00007fff201148e4 _dispatch_call_block_and_release + 12
4   libdispatch.dylib                   0x00007fff20115b25 _dispatch_client_callout + 8
5   libdispatch.dylib                   0x00007fff20123043 _dispatch_main_queue_drain + 1050
6   libdispatch.dylib                   0x00007fff20122c1b _dispatch_main_queue_callback_4

code:

const MERCHANTID = '388333172821828292929';
const SomeIdentifierFromPaymentProvider = '89290109290129912088';

export const onApplePayTap = async (args?: any) => {
  //try {
  // just ensuring this runs only on iOS
  if (isIOS) {
    const applePayBtn = args.object as ApplePayBtn

    // setup the event listeners for the delegate for apple pay for our button
    applePayBtn.once(ApplePayEvents.DidAuthorizePaymentHandler, async (args: any) => {
      console.log('in authorize handler')
      console.log(ApplePayEvents.DidAuthorizePaymentHandler)

      // this is where you do backend processing with your payment provider (Stripe, PayPal, etc.)
      // this payload is just a sample, your payload to a provider will likely be different
      // you can see here how to access the encrypted values from Apple Pay inside the `args.data.paymentData`
      const payloadToBackend = {
        transaction_type: 'purchase',
        merchant_ref: args.data.paymentData.header.transactionId,
        method: '3DS',
        '3DS': {
          merchantIdentifier: SomeIdentifierFromPaymentProvider,
          data: args.data.paymentData.data,
          signature: args.data.paymentData.signature,
          version: args.data.paymentData.version,
          header: args.data.paymentData.header
        }
      }

      const result = true //await this.someHttpMethodToYourProviderBackend(payloadToBackend)

      if (result) {
        // need this to call when the payment is successful to close the payment sheet correctly on iOS
        args.completion(ApplePayTransactionStatus.Success)
        // now you can follow through with your user flow since the transaction has been successful with your provider
      } else {
        // payment failed on the backend, so show the FAILURE to close the Apple Pay sheet
        args.completion(ApplePayTransactionStatus.Failure)
      }
    })

    // these are the items your customer is paying for
    const paymentItems = ([
      {
        amount: 20.5,
        label: 'Balance',
        type: ApplePayPaymentItemType.Final
      }
    ] as unknown) as ApplePayItems[]

    const request = {
      paymentItems,
      merchantId: MERCHANTID // the merchant ID for this app
      merchantCapabilities: ApplePayMerchantCapability.ThreeDS,
      countryCode: 'US',
      currencyCode: 'USD',
      shippingContactFields: [ApplePayContactFields.Name, ApplePayContactFields.PostalAddress],
      billingContactFields: [ApplePayContactFields.Name, ApplePayContactFields.PostalAddress],
      supportedNetworks: [
        ApplePayNetworks.Amex,
        ApplePayNetworks.Visa,
        ApplePayNetworks.Discover,
        ApplePayNetworks.MasterCard
      ]
    } as ApplePayRequest

    // `createPaymentRequest` will call into the Apple Pay SDK and present the user with the payment sheet for the configuration provided
    await applePayBtn.createPaymentRequest(request).catch((err) => {
      console.log('Apple Pay Error', err)
    })
  }
@abdallahkadour
Copy link
Author

abdallahkadour commented Mar 29, 2023

The reason that payment in the following function is an empty object:

 /**
     * Tells the delegate that the user has authorized the payment request and asks for a result.
     * @param controller
     * @param payment
     * @param completion
     */
    PKPaymentAuthorizationViewControllerDelegateImpl.prototype.paymentAuthorizationViewControllerDidAuthorizePaymentHandler = function (controller, payment, completion) {

The function is defined the file payment-authorization-view-controller-delegate.ios.js

Any idea?

@kakha13
Copy link

kakha13 commented Jan 5, 2024

You need to use real device with Sandbox test account and everything works great

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

No branches or pull requests

2 participants