Tipsi-stripe: How to detect user has cancelled paymentRequestWithCardForm

Created on 4 Apr 2018  路  10Comments  路  Source: tipsi/tipsi-stripe

When I am calling paymentRequestWithCardForm the library opens the form where you can add payment cards. This method return promise which gives me token etc when succesful. Here is an example:

try {
  const { tokenId } = await stripe.paymentRequestWithCardForm();
  // do stuff
} catch (error) {
  // show error message
}

The problem is that when user presses Cancel on the form the catch is fired. On iOS you get this response back:

{
  "line": 4075,
  "column": 26,
  "sourceURL": "http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false",
  "framesToPop": 1,
  "code": "-3",
  "nativeStackIOS": [
    "0   Myapp                               0x00000001056b0b06 RCTJSErrorFromCodeMessageAndNSError + 134",
    "1   Myapp                               0x0000000105644bc3 __41-[RCTModuleMethod processMethodSignature]_block_invoke_2.218 + 179",
    "2   Myapp                               0x0000000105493387 -[TPSStripeManager rejectPromiseWithCode:message:error:] + 167",
    "3   Myapp                               0x00000001054932aa -[TPSStripeManager rejectPromiseWithError:] + 186",
    "4   Myapp                               0x00000001054936de -[TPSStripeManager addCardViewControllerDidCancel:] + 190",
    "5   Myapp                               0x0000000105246829 -[STPAddCardViewController handleBackOrCancelTapped:] + 89",
    "6   UIKit                               0x0000000108f52972 -[UIApplication sendAction:to:from:forEvent:] + 83",
    "7   UIKit                               0x0000000109964290 __45-[_UIButtonBarTargetAction _invoke:forEvent:]_block_invoke + 154",
    "8   UIKit                               0x00000001099641c1 -[_UIButtonBarTargetAction _invoke:forEvent:] + 181",
    "9   UIKit                               0x0000000108f52972 -[UIApplication sendAction:to:from:forEvent:] + 83",
    "10  UIKit                               0x00000001090d1c3c -[UIControl sendAction:to:forEvent:] + 67",
    "11  UIKit                               0x00000001090d1f59 -[UIControl _sendActionsForEvents:withEvent:] + 450",
    "12  UIKit                               0x00000001090d0e86 -[UIControl touchesEnded:withEvent:] + 618",
    "13  UIKit                               0x0000000108fc8807 -[UIWindow _sendTouchesForEvent:] + 2807",
    "14  UIKit                               0x0000000108fc9f2a -[UIWindow sendEvent:] + 4124",
    "15  UIKit                               0x0000000108f6d365 -[UIApplication sendEvent:] + 352",
    "16  UIKit                               0x00000001098b9a1d __dispatchPreprocessedEventFromEventQueue + 2809",
    "17  UIKit                               0x00000001098bc672 __handleEventQueueInternal + 5957",
    "18  CoreFoundation                      0x000000010d4fd101 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17",
    "19  CoreFoundation                      0x000000010d59cf71 __CFRunLoopDoSource0 + 81",
    "20  CoreFoundation                      0x000000010d4e1a19 __CFRunLoopDoSources0 + 185",
    "21  CoreFoundation                      0x000000010d4e0fff __CFRunLoopRun + 1279",
    "22  CoreFoundation                      0x000000010d4e0889 CFRunLoopRunSpecific + 409",
    "23  GraphicsServices                    0x00000001105f89c6 GSEventRunModal + 62",
    "24  UIKit                               0x0000000108f515d6 UIApplicationMain + 159",
    "25  Myapp                               0x000000010523fc6f main + 111",
    "26  libdyld.dylib                       0x000000010ecf3d81 start + 1"
  ],
  "userInfo": {
    "NSLocalizedDescription": "Canceled by user"
  },
  "domain": "com.tipsi.TPSStripe"
}

From here I can use code -3 which means it was cancelled by user. But on Android when I press Cancel I get this response:

{
  "framesToPop": 1,
  "code": "AddCardDialogFragment"
}

So how I am suppose to know on Android when user has cancelled the modal? :D Or am I missing something?

bug

Most helpful comment

I used the following workaround:

Add <string name="gettipsi_user_cancel_dialog" translatable="false">-3</string> to android string resources as this is the string tipsi-stripe returns in case of user cancel on android.

stripe.paymentRequestWithCardForm(options).then((token) => {
  // Success
}).catch((error) => {
  const cancelAction = '-3';
  if((isAndroid && error.message === cancelAction) || (isIos && error.code === cancelAction)) {
    // Cancelled by user
  }
});

All 10 comments

We need to investigate it

@isnifer How this is going? :)

+1, it's quite confusing indeed. Does anyone know if the android code 'AddCardDialogFragment' is specific to the error of cancelling?

@henrikra @SamMatthewsIsACommonName

Not sure if this helps, I have my code set up a bit differently

    stripe.paymentRequestWithCardForm(options).then((token) => {
      // success
    }).catch((e) => {
      // error handling
      console.log(e.message);
    });

e.message in this case specifically says either 'Canceled by user' (ios) or 'User cancel dialog. No card added!' (Android)

@anthonywhiteman for me it does not sound very durable solution to check error message string and make some error logic based on that. I think there should be like error code which tells explicitly what went wrong.

I used the following workaround:

Add <string name="gettipsi_user_cancel_dialog" translatable="false">-3</string> to android string resources as this is the string tipsi-stripe returns in case of user cancel on android.

stripe.paymentRequestWithCardForm(options).then((token) => {
  // Success
}).catch((error) => {
  const cancelAction = '-3';
  if((isAndroid && error.message === cancelAction) || (isIos && error.code === cancelAction)) {
    // Cancelled by user
  }
});

@henrikra @hannta Hi, guys! It would be nice to check 5.6.0 with new common error codes. Did this fix your problems?

Thanks @isnifer looks like it fixes our use case 馃憤

@hannta Can this be closed then?

@hannta @henrikra I will close this issue. Feel free to open new one if issue still exists :)

Was this page helpful?
0 / 5 - 0 ratings