简体   繁体   中英

Braintree dropin form issue - nonce string not being generated

I'm trying to use the dropin form from braintree but it produces a weird behaviour.

I can successfully place the form in a view:

<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"
        });

    ...

Here's the result:

Braintree DropIn UI表单

They state in their documentation (3rd paragraph) that braintree.js will add a hidden input named payment_method_nonce to your form .

On my controller, I got the action method to catch the form collection and there's a payment_method_nonce key in the form collection with an empty string as a value but no other keys, no other form fields are caught here. I was expecting the card number and the expiration date, as seen in the picture above.

Using the inspector, I see that the braintree dropin cretes an HTML structure with nested forms:

嵌套表格

My question is, how can I use the braintree dropin form and catch all their form input values in the action method?

EDIT

OK, so thanks to @MikeMiller, I learned that I don't need to catch the CC values in the controller method, just the nonce string that's supposedly generated from them. However, I am getting an empty string.

From his suggestion, I tried to add to the form a specific value for the action attribute:

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

But the result is the same, an empty string for the nonce.

I got mine working with the following code (Laravel5 blade). My issue was submitting the form with jQuery - without a button element in the form the nonce value doesnt get populated.

<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>

When you get an empty nonce, I was having the same trouble. However, in my case, I was doing 'custom' instead of 'dropin'. I did lots of tests in all kinds of scenarios, such as creating a static tokenization token from the dashboard, or generating one on the fly when the page loaded. They have some anti-fraud measures in place, I suspect, and it creates odd scenarios where the form submits no matter what, even if form validation routines fail. Or, the form submits and you get no nonce. The docs are also extremely confusing on this. So, this is the fix that I finally got going. What they don't tell you in the docs is that the onPaymentMethodReceived is only called on a form submit operation. The other remarkable discovery I made was that if I use the following code and add <input type="hidden" name="payment_method_nonce" id="payment_method_nonce" /> to the form and then replace the $('#token') line below with a call to update the payment_method_nonce hidden field -- the Braintree API erases it right before form submit! So, the fix on that is to rename that hidden field to "token" and then on the form submit code in PHP I can process $_POST['token'] instead of $_POST['payment_method_nonce'] , but treat it like a 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;
        }
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM