【问题标题】:Using ajax/jquery to pass stripe.js token to django使用 ajax/jquery 将 stripe.js 令牌传递给 django
【发布时间】:2018-02-18 04:20:32
【问题描述】:

我是一名初学者,正在实施条带以在我的 django 应用程序上处理付款。

我正在使用 dj-stripe,可以通过此设置创建客户并添加计划。

我想使用 stripe.js 来创建令牌,这样我就可以使用来自 stripe 的格式良好的卡片提交表单 (https://stripe.com/docs/elements/examples)。我不想使用 django 表单来收集卡详细信息,因为这些在布局上很难更改,并且从安全角度来看,我宁愿自己不使用 django 应用程序处理信用卡详细信息。

我设法让条带 javascript 表单工作,它以“令牌”的形式提供输出。我应该将 javascript 输出传递给我的 django 应用程序并将其附加给我的客户。

我认为这应该通过某种 jQuery / Ajax 设置来实现,但由于我是初学者,我不知道如何开始。我找到了this,但不知道如何适应我的需要。

我当前的设置打印在 payment.html Success! Your Stripe token is <span class="token"></span> 中编码的输出令牌。我尝试在这样的 jQuery 脚本中引用 token,但 token 在我的浏览器中出现错误 could not be read

我的 jQuery/AJAX 脚本尝试,之前添加到 payment.html 但未显示在下面的 payment.html 中:

<script type="text/javascript">
$(document).ready(function() {
    $.ajax({
        method: 'POST',
        url: '/payments/settings/',
        data: {'yourJavaScriptArrayKey': yourJavaScriptArray},
        success: function (data) {
             //this gets called when server returns an OK response
             alert("it worked!");
        },
        error: function (data) {
             alert("it didnt work");
        }
    });
});
</script>

payment.html:

<style> some styles regarding layout of the js-form</style>

<script src="https://js.stripe.com/v3/"></script>

<form>
  <div class="group">
    <label>
      <span>Name</span>
      <input name="cardholder-name" class="field" placeholder="Jane Doe" />
    </label>
    <label>
      <span>Phone</span>
      <input class="field" placeholder="(123) 456-7890" type="tel" />
    </label>
  </div>
  <div class="group">
    <label>
      <span>Card</span>
      <div id="card-element" class="field"></div>
    </label>
  </div>
  <button type="submit">Add Card</button>
  <div class="outcome">
    <div class="error" role="alert"></div>
    <div class="success">
      Success! Your Stripe token is <span class="token"></span>
    </div>
  </div>
</form>

<script type="text/javascript">

var stripe = Stripe('pk_test_xxxxxxxxxxxxxxxxxxxxxxxx');
var elements = stripe.elements();

var card = elements.create('card', {
  style: {
    base: {
      iconColor: '#666EE8',
      color: '#31325F',
      lineHeight: '40px',
      fontWeight: 300,
      fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
      fontSize: '15px',

      '::placeholder': {
        color: '#CFD7E0',
      },
    },
  }
});
card.mount('#card-element');

function setOutcome(result) {
  var successElement = document.querySelector('.success');
  var errorElement = document.querySelector('.error');
  successElement.classList.remove('visible');
  errorElement.classList.remove('visible');

  if (result.token) {
    // Use the token to create a charge or a customer
    // https://stripe.com/docs/charges
    successElement.querySelector('.token').textContent = result.token.id;
    successElement.classList.add('visible');
  } else if (result.error) {
    errorElement.textContent = result.error.message;
    errorElement.classList.add('visible');
  }
}

card.on('change', function(event) {
  setOutcome(event);
});

document.querySelector('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var form = document.querySelector('form');
  var extraDetails = {
    name: form.querySelector('input[name=cardholder-name]').value,
  };
  stripe.createToken(card, extraDetails).then(setOutcome);
});

</script>
<script>
// I am missing an AJAX/jQUERY script to pass the outcome of the javascript generated token
</script>

views.py

def payment(request):
    template = get_template('payment.html')
    context = {

    }
    # HERE THERE SHOULD BE SOME AJAX CALL
    return HttpResponse(template.render(context,request))

我的 AJAX/jQuery 脚本应该如何在我的 payment.html 中查看,以便它访问输出的令牌以及如何在我的 views.py 中调用此令牌?

【问题讨论】:

    标签: javascript jquery python django stripe-payments


    【解决方案1】:

    首先,我不喜欢您两次使用 setOutcome 的方式,一次用于卡的更改事件,然后再次尝试从条带获取令牌时。把这些东西分开:

    stripe.createToken(card, extraDetails).then(function(result) {
        if(result.error && result.error.message){
            // Do something with the errors
        }else{
            // Charge the card
            doCardCharge(result.token.id);
        }
    });
    

    使您的服务器响应成为 JSON 类型的对象。你的 doCardCharge 函数如下所示:

    function doCardCharge( stripeToken ){
        $.ajax({
            type: 'post',
            data: {
                // Add any other fields you need to here
                'name': $('input[name="cardholder-name"]').val(),
                'stripeToken':  stripeToken
            },
            cache: false,
            url: '/payments/settings/',
            dataType: 'json',
            success: function(data){
                if( data.server_errors ){
                    // There could be errors on the server
                }else if( data.status == 'success'){
                    // The charge was successful
                }else if( data.errors ){
                    // There were validation errors
                }else{
                    // There was some unknown error
                }
            },
            error: function(){
                // There was some sort of network error, or error on the server
            }
        });
    }
    

    假设你有某种输出缓冲来捕捉错误,如果你想将它们显示为data.server_errors。如果收费成功,您会将“成功”作为data.status 的值传回。如果服务器捕获到一个验证错误,例如某人的地址 = "2oi3n5o2i3n5o2i",那么您正在处理这些错误,因为您将它们设置为 data.errors 的值。

    还要注意,我为 ajax 响应声明了一个 dataType,这是因为 jQuery 试图智能地猜测响应类型,但我发现在很多情况下它并不那么智能。

    在 Django 中,当您需要在视图中获取发布的数据时,请查看以下获取方法:Django - taking values from POST request

    在 Django 中,您可以很容易地设置 JSON 类型的响应。以 Stack Overflow 页面为例:Creating a JSON response using Django and Python

    最后,如果您不知道发生了什么,有时查看开发人员控制台(在您的网络浏览器中)的网络选项卡会很有帮助。很多时候它会提供原始响应。

    【讨论】:

    • 加载了表单,可以看到在网络环境中创建的令牌,因此肯定朝着好的方向迈出了一步。现在正在努力解决 Django 不接受的 CSRF 令牌,因为使用 from 不是使用 forms.py 创建的,而是使用 JS / HTML 代码创建的。正在调查csrf_exempt,但我不知道这是否是好方法
    • link 指出免除 csrf 令牌是正确的方法。设置现在适用于您的反馈。快乐的人。
    • 我会从这里开始并决定在这种情况下 CSRF 是否是一个问题:owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
    猜你喜欢
    • 2017-04-12
    • 2016-08-19
    • 1970-01-01
    • 2016-06-22
    • 2018-09-27
    • 2019-09-21
    • 2023-04-02
    • 2010-10-18
    • 2018-03-03
    相关资源
    最近更新 更多