Django集成Stripe支付报错Invalid card object,求代码排查帮助
解决Stripe支付报错:"Invalid card object: must be a dictionary or a non-empty string"
根据你提供的代码和错误信息,核心问题出在前端Stripe.js创建支付Token时的字段命名错误,导致后端无法获取有效的Stripe Token,进而触发支付失败。下面是具体的排查和修复步骤:
1. 修复Stripe.js中的Card字段命名错误
在你的stripe.js文件里,构建card对象时使用了expMonth和expYear,但Stripe.js v2的API要求这两个字段的命名是**exp_month和exp_year**(小写加下划线)。这个错误会导致Stripe无法成功创建支付Token,最终response.id为空,后端拿到的stripe_id是空字符串,从而触发报错。
修改后的stripe.js代码片段:
$(function(){ $("#payment-form").submit(function() { console.log("#payment-form"); var form = this; var card = { number: $("#id_credit_card_number").val(), exp_month: $("#id_expiry_month").val(), // 修正字段名 exp_year: $("#id_expiry_year").val(), // 修正字段名 cvc: $("#id_cvv").val() }; Stripe.createToken(card, function(status, response) { console.log("#createToken"); if (status === 200) { $("#credit-card-errors").hide(); $("#id_stripe_id").val(response.id); // 移除敏感字段的name属性,避免提交到服务器 $("#id_credit_card_number").removeAttr('name'); $("#id_cvv").removeAttr('name'); $("#id_expiry_month").removeAttr('name'); $("#id_expiry_year").removeAttr('name'); form.submit(); } else { $("#stripe-error-message").text(response.error.message); $("#credit-card-errors").show(); $("#validate_card_btn").attr("disabled", false); } }); return false; }); });
2. 检查前端JS引入的冗余代码
在checkout.html的head_js块中,有一段空的script标签可能导致加载错误,建议将Stripe的publishableKey配置合并到正确的script标签中,修改为:
{% block head_js %} <script type="text/javascript" src="https://js.stripe.com/v2/"></script> <script type="text/javascript"> //<![CDATA[ Stripe.publishableKey = '{{ publishable }}'; // ]]> </script> <script type="text/javascript" src="{% static 'js/stripe.js' %}"></script> {% endblock %}
3. 后端代码的额外优化
虽然不是直接报错原因,但可以优化后端的Charge创建逻辑,提升代码健壮性:
- 修正
description字段的字符串拼接逻辑,当前代码的"Thank you..." and request.user.email在Python中会直接返回request.user.email,改为:description=f"Thank you for your contribution, {request.user.email}" - 添加对
stripe_id非空的前置检查,避免无效请求:if payment_form.is_valid(): stripe_token = payment_form.cleaned_data['stripe_id'] if not stripe_token: messages.error(request, "Failed to generate payment token.") return redirect(reverse('index')) # 后续创建Charge的代码
验证修复效果
完成上述修改后,使用测试卡号4242 4242 4242 4242进行测试:
- 提交表单时,前端会正确创建Stripe Token并赋值给隐藏的
stripe_id字段 - 后端拿到有效的Token后,即可成功发起Charge请求,完成支付流程
内容的提问来源于stack exchange,提问作者Darren
相关产品推荐
相关产品推荐

