Интеграция Braintree - не может получить доступ к javascript nonce в коде на стороне сервера - PullRequest
1 голос
/ 14 марта 2019

Я использую Braintree dropin в веб-форме ASP.Net, и у меня возникают проблемы с чтением одноразового номера, возвращенного из javascript. Он генерируется, но на моем серверном коде я не могу получить к нему доступ. Я подозреваю это происходит из-за того, что код на стороне сервера вызывается до завершения кода Javascript, но поскольку веб-разработка не моя сильная сторона, я не уверен.

Мой код на стороне клиента TestBrainTree.aspx:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="TestBrainTree2.aspx.vb" Inherits="eStore2.TestBrainTree2" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8">
  <script src="https://js.braintreegateway.com/web/dropin/1.16.0/js/dropin.min.js"></script>
</head>
<body>
   <form id="form1" runat="server"> 
       <div id="dropin-container"></div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True"></asp:ScriptManager>  
          <button id="btnSubmit">Request payment method</button>
        <asp:label id="lblResult" runat="server"></asp:label>
    <input id="payment_method_nonce" name="payment_method_nonce" type="hidden" />
    </form> 
  <script>
    var button = document.querySelector('#btnSubmit');

    braintree.dropin.create({
      authorization: '<%=clientToken%>',
      container: '#dropin-container'
    }, function (createErr, instance) {
      button.addEventListener('click', function () {
        instance.requestPaymentMethod(function (err, payload) {
          // Submit payload.nonce to your server
            document.querySelector('#payment_method_nonce').value = payload.nonce;
            alert(document.querySelector('#payment_method_nonce').value);
         });
      });
    });
  </script>
</body>
</html>

Строка alert(document.querySelector('#payment_method_nonce').value); показывает, что одноразовый номер был успешно создан. Мой серверный код TestBraintree2.aspx.vb:

Imports Braintree

Public Class TestBrainTree2
    Inherits System.Web.UI.Page

    '#Region page variables
    Public clientToken As String
    '#endregion

    Private gateway As BraintreeGateway = New BraintreeGateway With {
        .Environment = Braintree.Environment.SANDBOX,
                    .PublicKey = "XXXX",
                    .PrivateKey = "YYYY",
                    .MerchantId = "ZZZZ"
    }

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        ClientScript.GetPostBackEventReference(Me, String.Empty)

        If Not IsPostBack Then
            clientToken = gateway.ClientToken.Generate()
        Else
            Dim nonce As String = Request.Form("payment_method_nonce")
            Dim request2 = New TransactionRequest With {
                .Amount = 10D,
                .PaymentMethodNonce = nonce
            }
            Dim result As Result(Of Transaction) = gateway.Transaction.Sale(request2)

            If result.IsSuccess() Then
                lblResult.Text = String.Format("<b>Transaction id:</b>{0}", result.Target.Id)
            Else
                lblResult.Text = "Error"
            End If
        End If
    End Sub

End Class

Для безопасности спрятал мои ключи в коде выше. Проблема возникает в строке Dim nonce As String = Request.Form("payment_method_nonce"), где я ожидаю увидеть одноразовый номер, сгенерированный на стороне клиента, но он пуст.

1 Ответ

2 голосов
/ 14 марта 2019

Вы правы в том, что причина, по которой вы не видите nonce, заключается в том, что форма отправляется до того, как вы установили одноразовый номер.

Измените код внешнего интерфейса на следующий, чтобы решить эту проблему. Код запрещает отправку формы до тех пор, пока она не получит одноразовый номер. Получив одноразовый номер, он автоматически отправит форму.

<script>
  var form = document.querySelector('#form1');

  braintree.dropin.create({
    authorization: '<%=clientToken%>',
    container: '#dropin-container'
  }, function (createErr, instance) {
    form.addEventListener('submit', function (event) {
      event.preventDefault();

      instance.requestPaymentMethod(function (err, payload) {
        if (err) {
          console.log('Error', err);
          return;
        }

        // Add the nonce to the form and submit
        document.querySelector('#payment_method_nonce').value = payload.nonce;
        form.submit();
      });
    });
  });
</script>
...