Braintree 付款不适用于 AJAX 提交

Braintree payments won't work with AJAX submit

我有一个动态 AJAX 提交。我正在尝试使用 AJAX 将 Braintree (PayPal) 支付数据提交到 payment.php。不幸的是,布伦特里给我一个随机数错误。 Braintree 在提交时创建一个带有代码 (nonce) 的输入,但我的提交是在创建代码之前提交的。

Braintree 给了我一个创建代码的脚本

<script src="https://js.braintreegateway.com/v2/braintree.js"></script>

我使用类似

的东西
$(document).on("submit","form",function(event){
  if(!$(this).is("[action]")){
    event.preventDefault()
    formdata=new FormData(this)
    submit(this)
}

submit(this) 调用 ajax。我试图延迟提交,但没有任何效果。例如。如果我在提交期间调用 alert() ,代码将被添加并且提交工作正常;除了现在我有一个警报。问题是两个代码同时 运行 并且 Braintree 代码反应太慢。我还尝试将 link 重新定位在我的 JS 代码上方和下方,但没有成功。

如前所述here,我认为您应该使用 onPaymentMethodReceived 来自 BrainTree 的 GlobalSetup 的回调。您可以在下面的设置中配置此回调,而不是使用 jQuery 自行处理表单提交。

    braintree.setup("CLIENT-TOKEN-FROM-SERVER", "dropin", {
      container: "dropin-container",
      onPaymentMethodReceived: function (paymentMethod) {
        // Do some logic in here.
        // When you're ready to submit the form:
        myForm.submit();
      }
   });

当 Drop-in 生成 payment_method_nonce 时调用 onPaymentMethodReceived(作为表单提交的结果)。它将使用 paymentMethod 对象调用,该对象包含作为字符串的随机数。

您可以找到有关传递给 onPaymentMethodReceived 回调的 paymentMethod 对象的更多详细信息 here,它有一个名为 nonce 的 属性。

希望这对您有所帮助:)

我的解决方案是防止 AJAX 在收到 nonce 之前提交。希望这有帮助。

braintree.setup('TOKEN-HERE', "dropin", {
  container: "payment-form",
  onPaymentMethodReceived: (obj) ->
    $('form#checkout input#payment_method_nonce').val(obj['nonce'])
    frm = $('form#checkout')
    $.ajax
      type: frm.attr('method')
      url: frm.attr('action')
      data: frm.serialize()
})

$(document).on 'ajax:before', 'form#checkout', ->
  return false unless $('form#checkout input#payment_method_nonce').val()

我想做同样的事情,这就是我所做的。

  • 首先创建 dropin 并处理第 8 行之前的任何创建错误,
  • 然后阻止默认提交事件获取 payment_method_nonce ,
  • 最后使用这个方法 >> requestPaymentMethod( ) << 来分配 nonce 值。

就是这样,在发送之前不要忘记对表格进行序列化,希望这对您有所帮助

源代码在这里braintree payments set up your client

var form = document.querySelector('#payment-form');
var client_token = '{{ client_token }}';
console.log(client_token)
braintree.dropin.create({
  authorization: client_token,
  container: '#bt-dropin',
  paypal: { flow: 'vault' }
  }, 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
        // Submit payload.nonce to your server
        document.querySelector('#nonce').value = payload.nonce;
        //form.submit();
        submit_it(form );
      });
    });
  });


function submit_it(params) {
  params = $(params).serialize()
  $.ajax({
    type:'POST',
    url :  window.location +"checkout/",
    beforeSend: function(xhr, settings) {
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
      }
    },
    data:params,
    success: function(data){
      console.log("succeded");
      console.log(data)
    },
    complete: function (xhr, textStatus) {
      console.log(xhr.status);
      if ( xhr.status == 200) {
      //complete code
      }
    },
    error:function(){
      // Do something not that success-ish
      alert( "something gone wrong" );
    }
  });
}