0

我几乎完成了 3d Secure 2 工作流程 ( https://developer.globalpay.com/ecommerce/3d-secure-version2/browser-authentication#api ) 的实施,但我正在努力确定如何应对挑战流动。

除了挑战流程卡之外,所有卡片都可以使用,我的 iFrame 出现在我的最后,单击“继续”会触发对我的挑战 URL 的请求 - 我正在执行 API 文档中显示的代码(上面链接) 但我返回的 JSON 只是显示在 iFrame 中,而不是触发我的 javascript。请在下面找到我的 JS 和挑战流程的端点:

async function performPaymentFlow(type, cardDetails, personalDetails, orderID) {
    
    // Perform the check card on the information sent in
    var versionCheckData, authenticationData;
    try {
        // call the api to see whether the card is valid
        versionCheckData = await checkVersion('/api/Payments/CheckCard', { cardNumber: cardDetails.cardNumber });
        if (versionCheckData.IsError) {
            // show user error
        }

    }
    catch (e) {
        // show user error
    }

    // perform authentication
    // WITHIN THIS CALL THIS IS WHERE THE CHALLENGE IS SHOWN TO THE USER
    try {
        authenticationData = await initiateAuthentication('/api/Payments/Authenticate', {
            serverTransactionId: versionCheckData.serverTransactionId,
            methodUrlComplete: true,
            card: {
                expiryMonth: cardDetails.expiryMonth,
                expiryYear: cardDetails.expiryYear,
                securityCode: cardDetails.cv2,
                cardHolderName: cardDetails.cardName,
                cardNumber: cardDetails.cardNumber
            },
            challengeWindow: {
                displayMode: 'lightbox',
            },
            screenOptions: {
                colorDepth: screen.colorDepth,
                language: navigator.language,
                timezone: new Date().getTimezoneOffset()
            },
            personalDetails: personalDetails,
            type: type,
            orderID: orderID
        });

        if (authenticationData.IsError) {
            // show user error
        }
        else {
            // frictionless authentication success and authorization success
            if (authenticationData.result == "AUTHORIZATION_SUCCESS") {
                // complete
            }
            // challenge success
            else if (authenticationData.challenge.response.data.transStatus == "Y") {
            
                var serverTransactionId = authenticationData.challenge.response.data.threeDSServerTransID;

                var model = {
                    serverTransactionId: serverTransactionId,
                    card: cardDetails,
                    type: type
                };
                $.ajax({
                    type: "POST",
                    url: "/api/Booking/Authorize",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    data: JSON.stringify({ "model": model })
                }).done(function (authorizationResponse) {
                    if (authorizationResponse.IsError) {
                        // Show user errlr
                    }
                    else {
                       // complete
                    }
                });
            }

            // challenge failure
            else {
                // show user error
            }
        }
    }
    catch (e) {
        // show user error
    }
};

这是我的挑战 URL 的服务器端实现

public void Challenge()
        {
            // Get the data from the form
            var cres = HttpContext.Current.Request.Form["cres"];
            try
            {
                #region Instantiate the service
                ServicesContainer.ConfigureService(new GpEcomConfig
                {
                    MerchantId = Constants.realexuser,
                    AccountId = "internet",
                    SharedSecret = Constants.realexsecret,
                    MethodNotificationUrl = Constants.DomainName + "/api/Payments/MethodSetup",
                    ChallengeNotificationUrl = Constants.DomainName + "/api/Payments/Challenge",
                    MerchantContactUrl = Constants.DomainName + "/visit/find-us-and-faqs",
                    Secure3dVersion = Secure3dVersion.Two
                });
                #endregion

                #region data population and parsing
                byte[] data = Convert.FromBase64String(cres.Replace('-', '+').Replace('_', '/').PadRight(4 * ((cres.Length + 3) / 4), '='));

                string challengeUrlResponseString = Encoding.UTF8.GetString(data);

                dynamic challengeUrlResponse = JsonConvert.DeserializeObject(challengeUrlResponseString);

                var threeDSServerTransID = challengeUrlResponse.threeDSServerTransID; // af65c369-59b9-4f8d-b2f6-7d7d5f5c69d5
                var acsTransId = challengeUrlResponse.acsTransID; // 13c701a3-5a88-4c45-89e9-ef65e50a8bf9
                var messageType = challengeUrlResponse.messageType; // Cres
                var messageVersion = challengeUrlResponse.messageVersion; // 2.1.0
                var transStatus = challengeUrlResponse.transStatus; // Y
                #endregion

                // Package up the data and send it back to the user
                challengeUrlResponseString = JsonConvert.SerializeObject(new
                {
                    threeDSServerTransID = threeDSServerTransID,
                    transStatus = transStatus
                });
                SendResponse(challengeUrlResponseString);
                return;
            }
            // Uh oh - another error from the API
            catch (Exception exce)
            {
                // Return error to user
            }
        }

从此返回的 JSON 显示在 iframe 中,而不是返回到我的 JS,因此我可以继续流程,任何帮助将不胜感激。

4

1 回答 1

0

需要通知客户端该挑战步骤已完成。为此,挑战通知端点应响应:

<script src="globalpayments-3dsecure.js"></script>
<script>
    GlobalPayments.ThreeDSecure.handleChallengeNotification('"threeDSServerTransID":"threeDSServerTransID","transStatus":"transStatus"');
</script>

请确保包含 3DS JS 库。

于 2021-05-25T14:21:39.343 回答