Braintree JSv3 payment_method_nonce HostedFields 的价值不佳

Braintree JSv3 payment_method_nonce Value Bad With HostedFields

我在这里查看了一些具有相同问题但在不同情况下无法为我提供特定问题的答案的帖子...

我在 Django 项目中使用 Braintree JSv2,一切正常。由于我已经迁移到 Braintree 的 v3,我现在唯一的问题似乎是输入到 "payment_method_nonce" 的值不存在...

这是应该转储 payment_method_nonce 值的代码:

document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;

下面是应该在 python 端获取它的代码:

client_payment_nonce = request.POST['payment_method_nonce']

在我的开发环境中提交此文件时,我收到 "payment_method_nonce" 的错误 (MultiValueDictKeyError)

我正在使用 Django 1.9 和 Python 2.7。我还使用 Braintree 提供的 example 使用 HostedFields 进行简单集成...

小试

所以我在我的表单中手动添加了一个名称为 "payment_method_nonce" 的输入字段,只是为了看看没有字段是否会导致某些问题。我知道它是由 Braintree 注入的,但只是测试一个想法。似乎 payment_method_nonce 的值应该是我的随机数,但我没有在输入框中输入任何内容,它仍然返回为 null。

表单和 HostedFields 的完整片段

<form action="/booking/" method="post" id="checkout_form">
                    {% csrf_token %}
                <div class="payment">
                    <span>Payment</span>
                        <!--input elements for user card data-->
                        <div class="hosted-fields" id="card-number"></div>

                        <div class="hosted-fields" id="postal-code"></div>

                        <div class="hosted-fields" id="expiration-date"></div>

                        <div class="hosted-fields" id="cvv"></div>

                        <div class="btns">
                            <input type="hidden" name="payment_method_nonce">
                            <input type="submit" value="Complete Booking" id="pay-button">
                        </div>
                </div>
            </form>

注意:我刚刚将 payment_method_nonce 字段更改为 type="hidden" 而不是 type="text" 但仍然具有相同的效果......

<!-- load the required client component -->
    <script src="https://js.braintreegateway.com/web/3.15.0/js/client.min.js"></script>
    <!-- load the hosted fields component -->
    <script src="https://js.braintreegateway.com/web/3.15.0/js/hosted-fields.min.js"></script>
    <!-- Braintree setup -->
    <script>
        var client_token = "{{ request.session.braintree_client_token }}"
        var form = document.querySelector('#checkout-form');
        var submit = document.querySelector('input[type="submit"]');

        braintree.client.create({
            authorization: client_token
        }, function (clientErr, clientInstance) {
            if (clientErr) {
                // Handle error in client creation
                return;
            }
            braintree.hostedFields.create({
                client: clientInstance,
                styles: {
                    'input': {
                        'font-size': '14px'
                    },
                    'input.invalid': {
                        'color': 'red'
                    },
                    'input.valid': {
                        'color': 'green'
                    }
                },
                fields: {
                    number: {
                        selector: '#card-number',
                        placeholder: 'Credit Card Number'
                    },
                    cvv: {
                        selector: '#cvv',
                        placeholder: '123'
                    },
                    expirationDate: {
                        selector: '#expiration-date',
                        placeholder: '10/2019'
                    },
                    postalCode: {
                        selector: '#postal-code',
                        placeholder: '10014'
                    }
                }
            }, function (hostedFieldsErr, hostedFieldsInstance) {
                if (hostedFieldsErr) {
                    // handle error in Hosted Fields creation
                    return;
                }

                submit.removeAttribute('disabled');

                form.addEventListener('submit', function (event) {
                    event.preventDefault();

                    hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
                        if (tokenizeErr) {
                            // handle error in Hosted Fields tokenization
                            return;
                        }
                        // Put `payload.nonce` into the `payment_method_nonce`
                        document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
                        document.querySelector('input[id="pay-button"]').value = "Please wait...";
                        form.submit();
                    });
                }, false);
            });
        });
    </script>

注意document.querySelector('input[id="pay-button"]').value = "Please wait..."; 行不会触发(我知道这一点是因为按钮不会更改值)。也许这些 querySelector 行不起作用?

发现新东西

我没有输入任何信息就回到了我的页面并点击了提交按钮。在 Braintree 的 v2 中,在填写所有字段之前我无法单击提交按钮......也许我表单中的值甚至没有被发送到 braintree 以接收随机数,这就是为什么有一个空字符串被退回..?

故事的寓意

检查您的代码...多次。正如 C Joseph 所指出的,我的 form ID 与我的 var form 所引用的不同......

<form action="/booking/" method="post" id="checkout_form">

var form = document.querySelector('#checkout-form');