django - 布伦特里付款表格不起作用 | Django

标签 django forms braintree

我正在尝试按照“Django 示例 3”一书构建 Braintree 付款表单,但无法填写该表单:

enter image description here

如您所见,表单显示在浏览器中,但无法编辑这 3 个字段。实际上就像“图像”一样显示。

在我的模板下面:

{% extends "shop/base.html" %}

{% block title %}Pay by credit card{% endblock %}

{% block content %}
    <h1>Pay by credit card</h1>
    <form id="payment" method="post">
        <label for="card-number">Card Number</label>
        <div id="card-number" class="field"></div>
        
        <label for="cvv">CVV</label>
        <div id="cvv" class="field"></div>
        
        <label for="expiration-date">Expiration Date</label>
        <div id="expiration-date" class="field"></div>
        
        <input type="hidden" id="nonce" name="payment_method_nonce"
        value="">
        {% csrf_token %}
        <input type="submit" value="Pay">
    </form>

<!-- includes the Braintree JS client SDK -->
<script src="https://js.braintreegateway.com/web/3.44.2/js/client.
min.js"></script>
<script src="https://js.braintreegateway.com/web/3.44.2/js/hostedfields.
min.js"></script>

<script>
    var form = document.querySelector('#payment');
    var submit = document.querySelector('input[type="submit"]');

braintree.client.create({ 
 authorization: '{{ client_token }}'
}, function (clientErr, clientInstance) {
if (clientErr) {
    console.error(clientErr);
    return;
  }

braintree.hostedFields.create({
client: clientInstance,
styles: {
    'input': {'font-size': '13px'},
    'input.invalid': {'color': 'red'},
    'input.valid': {'color': 'green'}
  },
fields: {
    number: {selector: '#card-number'},
    cvv: {selector: '#cvv'},
    expirationDate: {selector: '#expiration-date'}
  }
}, function (hostedFieldsErr, hostedFieldsInstance) {
  if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
  }

submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
    event.preventDefault();
    
    hostedFieldsInstance.tokenize(function (tokenizeErr,
payload) {
    if (tokenizeErr) {
        console.error(tokenizeErr);
        return;
    }
    // set nonce to send to the server
    document.getElementById('nonce').value = payload.nonce;
    // submit form
    document.getElementById('payment').submit();
    });
   }, false);
  });
});
</script>
{% endblock %}

书上是这么说的:

“这是显示付款表单并处理付款的模板。 您为信用卡输入定义容器而不是元素 字段:信用卡号、CVV 号和到期日期。就是这样 您指定 Braintree JavaScript 客户端将在 iframe 中呈现的字段。 您还包括一个名为 payment_method_nonce 的元素 Braintree 生成 token 随机数后,将用于将其发送到您的 View JavaScript 客户端。”

有什么帮助吗?

最佳答案

我在阅读这本书时遇到了同样的问题,我最终解决了这个问题,这是我的解决方法。您应该使用 Drop-in UI 这是一个现成的支付 UI,提供了最快的方式来集成 Braintree 并开始安全地接受付款,然后使用:

https://js.braintreegateway.com/web/dropin/1.18.0/js/dropin.min.js

而不是:

<script src="https://js.braintreegateway.com/web/3.44.2/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.44.2/js/hostedfields.min.js"></script>

process.html中执行以下操作:

{% extends "shop/base.html" %} 

{% block title %} Pay by credit card {% endblock %}

{% block sidenavigation %}



{% endblock %}

{% block content %}
<h1>Pay by credit card</h1>

<!-- includes the Braintree JS client SDK -->

<script src="https://js.braintreegateway.com/web/dropin/1.18.0/js/dropin.min.js"></script>

<form autocomplete="off">
  {% if braintree_error %}
    <div class="alert alert-danger fade in">
        <button class="close" data-dismiss="alert">&times;</button>
        {{ braintree_error|safe }}
    </div>
  {% endif %}
  <div class="braintree-notifications"></div>
  <div id="braintree-dropin"></div>
  <input style="background-color: #0783ca" id="submit-button" class="btn btn-success btn-lg btn-block" type="button" value="Pay now!" />
</form>

<script>
  var braintree_client_token = "{{ client_token}}";
  var button = document.querySelector('#submit-button');

  braintree.dropin.create({
    authorization: "{{client_token}}",
    container: '#braintree-dropin',
    card: {
      cardholderName: {
          required: false
      }
    }
  }, function (createErr, instance) {
      button.addEventListener('click', function () {
          instance.requestPaymentMethod(function (err, payload) {
              $.ajax({
                  type: 'POST',
                  url: '{% url "payment:process" %}',
                  data: {
                    'paymentMethodNonce': payload.nonce,
                    'csrfmiddlewaretoken': '{{ csrf_token }}'}
              }).done(function (result) {
                 //do accordingly
              });
          });
      });
  });
</script>

{% endblock %}

payment/views.py

def payment_process(request):
    """The view that processes the payment"""
    order_id = request.session.get('order_id')


    order = get_object_or_404(Order, id=order_id)

    total_cost = order.get_total_cost()


    if request.method == 'POST':
        # retrieve nonce 
        # retrieve nonce
        nonce = request.POST.get('paymentMethodNonce', None)

        # # create User 
        customer_kwargs = {
            "first_name": order.first_name,
            "last_name": order.last_name,
            "email": order.email
        }
        customer_create = gateway.customer.create(customer_kwargs)
        customer_id = customer_create.customer.id

        #create and submit transaction
        
        result = gateway.transaction.sale({
            'amount': f'{total_cost:.2f}',
            'payment_method_nonce': nonce,
            'options': {
                'submit_for_settlement': True
            }
        })

        print(result)
        if result.is_success:
            #mark the order as paid 

            order.paid = True
            
            # store the unique transaction id 
            order.braintree_id = result.transaction.id
            order.save()

            return redirect('payment:done')
        else:
            return redirect('payment:canceled')
    else:
        # generate token
        client_token = gateway.client_token.generate()

        return render(
            request,
            'payment/process.html',
            {
                'order':order,
                'client_token': client_token
            }
        )

正如您所注意到的,我们在结果成功后使用ajax,您应该做一些事情。希望对您有帮助

关于django - 布伦特里付款表格不起作用 | Django ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63082733/

相关文章:

python - Django : How to handle css/js specific to a template tag?

javascript - ExtJS 4.0、Django 和 ExtDirect

php - wamp 服务器 2.0 在我注销后丢失一条记录

javascript - 将按钮类型从按钮更改为提交

java - com.acti.braintreegateway.exceptions.UnexpectedException : Could not verify SSL certificate for URL

python - quantize() 和 str.format() 有什么区别?

Django 休息框架 : is it possible to modify a Serializer class at runtime?

forms - 当文件包含在GSP表单中时,Grails不会更新数据对象吗?

php - 使用 laravel/cashier-braintree/Laravel 5.2 在 Braintree 中订阅

python - 在 Django-Oscar 中通过 Paypal 处理付款