verifyBuyer function locks up the second time it is called

I am having some problems using the verifyBuyer function to do SCA authentication. There are 3 issues that I am having.

I am in the sandbox. The first time I call the function, the SCA screen appears and prompts me for the code for my test card. I type in 123456 as per the instructions and the function returns the token which I then pass to the Square server and it lets me add the card just fine. This is all working ok.

However, the problems begin when a user either hits the Cancel button on the SCA screen, or if they type in an incorrect code and fail the authentication.

The main issue that I am experiencing is that after a failure (e.g. due to an incorrect code being entered), if the user then tries again for the second time, the verifyBuyer is called again but this time the SCA window never appears and the function never returns. It seems to be going into some kind of infinite loop or it is otherwise waiting for something to happen before it returns but it never happens and so it never returns, no matter how long I wait. From this point onwards, the entire payment system on my app is broken because any subsequent calls to verifyBuyer result in the error ‘An issue occurred while verifying the buyer. A verification request is already in progress’.

The second issue (which might not be an actual issue) is that if the user types in an incorrect code the verifyBuyer still returns a token as if everything was fine, but then when I try adding the card using the token it obviously fails. I can handle this error manually on my server and return an error message, but why is verifyBuyer generating a token when the code is wrong? Should it not be failing and returning an error instead?

The third issue is when the user clicks Cancel. An exception is throw when this happens, which I catch, but then the error message says ‘An issue occurred while verifying the buyer The verification was not successful: verf:CA4SELND5nqtcxHjsKfccwR9cmMgACgB’. This is then displayed to the user on the error box below the card details input. This error seems completely unsuitable though since all the person did was click on Cancel. There should never have been an attempt to verify the buyer when the cancel button was pressed, so why throw an error? Also, why make the error so confusing for the end user? Someone using the site is not going to understand what that error means and it will be confusing to them making them think that verification was attempted and failed even though they cancelled it.

Also, I have also witness the first issue happen (the lock up after subsequent calls to verifyBuyer) after the cancel button has been pressed, but this seems to happen intermittently where as after a failure it happens every single time.

:wave: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

https://developer.squareup.com/docs/sca-overview-web
https://developer.squareup.com/docs/sca-overview
Troubleshoot In-App Payments SDK Problems

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

Is this with our In-App Payments SDK or the Web Payments SDK? Also if a customer enters incorrect values for the verification token we won’t throw an error. This is because were not verifying the information being passed in. The bank will at the time of the charge which is why you get a token every time.

As for a token being created when verification is canceled this is also expected because not all payments will be challenged. We always try to process the payment which is why it won’t stop you from trying to process the payment. As for the error that’s being displayed you can change the styling to display another error message. :slightly_smiling_face:

Hi Bryan, ok that is fair enough about the error messages. Thank you for the quick reply :slight_smile:

Regarding the main issue though, this is with the Web Payments SDK and the javascript file I am using is “https://sandbox.web.squarecdn.com/v1/square.js

I have been working on the app today and it seems that the issue is intermittent. What seems to be happening is that sometimes when calling the verifyBuyer it will send a request to the bank server to get the SCA screen (in this case its the Square one since it is the sandbox) but if for some reason there is a network problem or it otherwise fails to get the SCA screen then it just hangs forever and never times out or returns.

When this happens is the same source being passed to verifyBuyer? :slightly_smiling_face:

It can happen whether it is either the same, or different.

Hi Bryan,

Today I have accidentally stumbled upon a way to replicate the same issue that I am experiencing 100% of the time.

First of all, here is the function I am using:

    try {
        const result = await window.card.tokenize();
        if (result.status === 'OK') {
            var postcode = result.details.billing.postalCode;
            window.paymentInstance.invokeMethodAsync('PaymentErrorMessage', '', 'Contacting Bank - Please Wait...', '', true);
            // https://developer.squareup.com/reference/sdks/web/payments/objects/StoreVerifyBuyerDetails
            // https://developer.squareup.com/docs/web-payments/sca

            const verificationDetails = {
                intent: 'STORE',
                billingContact: {
                    addressLines: ['123 Main Street', 'Apartment 1'],
                    familyName: 'Doe',
                    givenName: 'John',
                    email: '[email protected]',
                    countryCode: 'GB',
                    phone: '3214563987',
                    state: 'LND',
                    city: 'London',
                    postalCode: 'WC2N 5DU',
                },
            };

            try {
                // Attempt to verify the buyer
                const verificationResults = await payments.verifyBuyer(
                    result.token,
                    verificationDetails
                );
                window.paymentInstance.invokeMethodAsync('SetPostCode', postcode);
                window.paymentInstance.invokeMethodAsync('ShowPleaseWait');

                console.log('Verification succeeded', verificationResults);
                window.paymentInstance.invokeMethodAsync('AddNewCard', result.token, verificationResults.token, verificationResults.userChallenged);


            } catch (error) {
                // If verification fails, call a failure handler function
                let result = error.message.startsWith('An issue occurred while verifying the buyer\n  The verification was not successful: verf:');
                // Avoid showing the unneeded error when a user clicks cancel on the SCA screen
                if (result === false) {
                    //window.showError(`Error: ${error.message}`);
                    window.paymentInstance.invokeMethodAsync('PaymentErrorMessage', error.name, error.message, error.stack);
                }
            }
        } else {
            window.paymentInstance.invokeMethodAsync('PaymentErrorMessage', '', result.errors[0].message, '');
        }
    } catch (e) {
        if (e.message) {
            //window.showError(`Error: ${e.message}`);
            window.paymentInstance.invokeMethodAsync('PaymentErrorMessage', e.name, e.message, e.stack);
        } else {
            window.paymentInstance.invokeMethodAsync('PaymentErrorMessage', '', 'Something went wrong', '');
        }
    }

    window.paymentInstance.invokeMethodAsync('EnableButtons');
}

The ‘window.paymentInstance.invokeMethodAsync’ methods are javascript interop calls to C# .net functions (I’m creating a hosted Blazor WASM app). They just pass basic info like error messages etc.

With that code, the SCA window opens most of the time, but occasionally I get the lockup. However today I changed the code so that it used user added values and I discovered something that causes the lockup every single time.

Change this line:

addressLines: ['123 Main Street', 'Apartment 1'],

To this:

addressLines: ['123 Main Street', null],

so that there is a null value as if no address line 2 was entered (which is how I accidentally discovered it). Now when you run that code and verifyBuyer is called it will just lock up and never return and the SCA screen will never appear, just like I am experiencing.

The card details I used (which actually dont seem to matter to be honest) were from the SCA testing in the Web Payments SDK section of your site and were:
Visa EU: 4310 0000 0020 1019
csv: 111
Expiry: whatever, but I just put 11/28
postcode: whatever. I put 11111

However I will note that I was 100% seeing this at times yesterday when the address line 2 was hard coded in there, so there is a chance that this is another separate thing that is causing the same symptom. But either way, if there is an issue it should return gracefully with a useful error message, not lock up and never work again.

One other thing. Today I am seeing another issue with the SCA screen. It appears, but then if I click either the Cancel or the Authenticate button I get this error and I cannot continue:

In my console I see this:
POST https://api.squareupsandbox.com/tds-ds-acs-sim/acs/challenge/otp 500 (Internal Server Error)

I’m reaching out to the team about this. :slightly_smiling_face:

The team deployed a fix for this and its working as expected. :slightly_smiling_face:

Hi Bryan,

That was quick! :slightly_smiling_face:

I’ve just taken a look at the 500 error is now gone. Thank you. However my original problem remains.

call verifyBuyer → SCA screen opens → Add an invalid code and click Authenticate → Transaction/Store failure → Try calling verifyBuyer again with exact same details → SCA screen never appears and card payment is forever broken from that point onwards.