Braintree dropin表单问题 - 未生成nonce字符串

时间:2015-11-04 11:49:45

标签: javascript html asp.net-mvc forms braintree

我正在尝试使用braintree中的dropin form,但这会产生一种奇怪的行为。

我可以成功地将表单放在视图中:

<form id="createTransactionForm" method="post" action="#">
    <div id="payment-form"></div>
    <input type="submit" value="Test - Pay">
</form>

<script>

    var braintreeToken = @Html.Raw(Json.Encode(Model.brainTreeToken));

    braintree.setup(
        braintreeToken,
        "dropin", {
            container: "payment-form"
        });

    ...

结果如下:

Braintree DropIn UI Form

他们在documentation(第3段)中指出braintree.js will add a hidden input named payment_method_nonce to your form

在我的控制器上,我获得了捕获表单集合的action方法,并且表单集合中有一个payment_method_nonce键,其中一个空字符串作为值,但没有其他键,此处没有其他表单字段。我正在等待卡号和到期日期,如上图所示。

使用检查器,我看到braintree dropin使用嵌套表单创建HTML结构:

Nested forms

我的问题是,如何使用braintree dropin表单并在action方法中捕获所有表单输入值?

修改

好的,感谢@MikeMiller,我了解到我不需要在控制器方法中捕获CC值,只需要从它们生成的nonce字符串。但是,我得到一个空字符串。

根据他的建议,我尝试在表单中添加action属性的特定值:

<form id="createTransactionForm" method="post" action="@Url.Action("MyMethod", "MyController")">

但结果是相同的,是nonce的空字符串。

2 个答案:

答案 0 :(得分:3)

我使用以下代码(Laravel5刀片)。我的问题是使用jQuery提交表单 - 在表单中没有按钮元素,nonce值不会被填充。

<form id="checkout" method="post" action="{{URL('admin/checkout')}}">
<div id="payment-form"></div>
<br>
<div class="input-group">
    <div class="input-group-btn" >
        <div class="btn-group">
            <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" style="width:50px">
                <span data-bind="label" id="currency">&pound;</span>&nbsp;<span class="caret"></span>
            </button>
            <ul class="dropdown-menu" role="menu" style="min-width:50px">
                <li style="width:50px"><a href="GBP">&pound;</a></li>
                <li style="width:50px"><a href="USD">&dollar;</a></li>
                <li style="width:50px"><a href="EUR">&euro;</a></li>
            </ul>
        </div>
    </div>
    <input type="text" name="amount" id="amount" class="form-control" />


    <div class="input-group-btn">
        <button role="submit" class="btn  btn-primary btn-block" id="submit">Make Payment</button>
    </div>
</div>
</form>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
  braintree.setup("@braintreeClientToken", "dropin", {
    container: "payment-form",
    form: 'checkout'
  });
</script>

答案 1 :(得分:0)

当你得到一个空的nonce时,我遇到了同样的麻烦。但是,在我的情况下,我正在做'自定义'而不是'dropin'。我在各种场景中进行了大量测试,例如从仪表板创建静态标记化标记,或者在加载页面时动态生成标记。我怀疑它们有一些反欺诈措施,并且它创建了奇怪的场景,即使表单验证例程失败,表单也无论如何都会提交。或者,表单提交,你没有nonce。文档也非常混乱。所以,这是我最终解决的问题。 What they don't tell you in the docsonPaymentMethodReceived仅在表单提交操作上调用。我发现的另一个值得注意的发现是,如果我使用以下代码并将<input type="hidden" name="payment_method_nonce" id="payment_method_nonce" />添加到表单中,然后使用调用更新$('#token')隐藏字段替换下面的payment_method_nonce行 - Braintree API在表单提交之前将其删除!因此,修复此问题是将该隐藏字段重命名为“token”,然后在PHP中的表单提交代码中我可以处理$_POST['token']而不是$_POST['payment_method_nonce'],但将其视为nonce。

function invalidForm(){
    // use the Stripe or Braintree credit card form validator and any other form validations you want here
    // Braintree: https://github.com/braintree/card-validator
    // Stripe: https://github.com/stripe/jquery.payment
    // return a string value of the problem
    return '';
}

jQuery(document).ready(function(){

    $('FORM#checkout').append('<input type="hidden" id="token" name="token" />');
    // Generate the static client token from your dashboard > Account > My User > 
    // Authorizations > Tokenization Keys
    var clientToken = 'sandbox_555555_555555555555';
    braintree.setup(clientToken, 'custom', {
        id:'checkout',
        onPaymentMethodReceived: function (paymentMethod) {
            $('#btnPurchase').addClass('disabled').attr('disabled');
            var sErr = invalidForm();
            if (sErr) {
                alert(sErr); // obviously do something better than this
                $('#btnPurchase').removeClass('disabled').removeAttr('disabled');
                return false;
            } // else...
            $('#token').val(paymentMethod.nonce);
            $('FORM#checkout').submit();
            return true;
        }
    });
});