【问题标题】:Django stripe.error: Invalid card object: must be a dictionary or a non-empty stringDjango stripe.error:无效的卡片对象:必须是字典或非空字符串
【发布时间】:2021-03-26 03:24:53
【问题描述】:

我正在尝试进行 Stripe 付款,但每次尝试付款时都会收到 InvalidRequestError。

付款金额为 5 欧元。我正在使用信用卡号 4242 4242 4242 4242 测试付款。

我的表单是有效的,但是当它向 Stripe 发送付款请求时,我收到了错误,并且它看起来像 stripe_id 是空白的。有什么想法吗?

checkout.html:

{% extends "base.html" %}
{% load static from staticfiles %}
{% load bootstrap_tags %}

{% block head_js %}
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript" src="">
    //<![CDATA[
    Stripe.publishableKey = '{{ publishable }}';
   // ]]>
</script>
<script type="text/javascript" src="{% static 'js/stripe.js' %}"></script>
{% endblock %}

{% block content %}

<form action="{% url 'checkout' %}" method="post" id="payment-form" class="col-md-6 col-md-offset-3">
    <legend>Payment Details</legend>

    <div id="credit-card-errors" style="display: none;">
        <div class="alert-message block-message error" id="stripe-error-message"></div>
    </div>

    <div class="form-group col-md-6">
        {{ payment_form|as_bootstrap }}
    </div>

    {% csrf_token %}
    <div class="form-group col-md-12">
        <input class=" btn btn-primary" id="submit_payment_btn" name="commit" type="submit" value="Submit Payment of 5 Euros">
    </div>
</form>

{% endblock %}

forms.py:

from django import forms

class MakePaymentForm(forms.Form):
    print("MakePaymentForm...")
    MONTH_CHOICES = [(i, i) for i in range(1, 12)]
    YEAR_CHOICES = [(i, i) for i in range(2019, 2040)]
    
    credit_card_number = forms.CharField(label='Credit Card Number', required=False)
    cvv = forms.CharField(label ='Security Code (CVV)', required=False)
    expiry_month = forms.ChoiceField(label="Month",choices=MONTH_CHOICES, required=False)
    expiry_year = forms.ChoiceField(label='year',choices=YEAR_CHOICES, required=False)
    stripe_id = forms.CharField(widget=forms.HiddenInput,  required=False)

views.py:

from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import MakePaymentForm
from tickets.forms import TicketsForm
from tickets.models import Ticket
from django.conf import settings
from accounts.views import login, index 
from django.utils import timezone
import stripe
# Create your views here.

stripe.api_key = settings.STRIPE_SECRET

@login_required()
def checkout(request):
    if request.method == "POST":
        payment_form = MakePaymentForm(request.POST)
        print("checkout...")

        if  payment_form.is_valid():
            print("Payment form is valid...")
            try:
                print("Just about to charge the customer...")
                customer = stripe.Charge.create(
                    amount=500,
                    currency="EUR",
                    description="Thank you for your contribution, it will really help our site" and request.user.email,
                    card=payment_form.cleaned_data['stripe_id']
                )
            except stripe.error.CardError:
                messages.error(request, "Your card was declined!")
            
            if customer.paid:
                print("Customer has paid...")
                messages.error(request, "You have successfully paid")
                return redirect(reverse('index'))
            else:
                messages.error(request, "Unable to take payment")
                return redirect(reverse('index'))
        else:
            print("There are errors...")
            print(payment_form.errors)
            messages.error(request, "We were unable to take a payment with that card!")
    else:
        print("Method isn't post...")
        payment_form = MakePaymentForm()

    return render(request, "checkout.html", {"payment_form": payment_form, "publishable": settings.STRIPE_PUBLISHABLE})

这是终端中的输出:

[14/Dec/2020 22:47:40] "GET /checkout/ HTTP/1.1" 200 5688
checkout...
There are errors...
<ul class="errorlist"><li>stripe_id<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
[14/Dec/2020 22:47:51] "POST /checkout/ HTTP/1.1" 200 5850

这里是 stipe.js:

$(function(){
    $("#payment-form").submit(function() {
        console.log("#payment-form");
        var form = this;
        var card = {
            number: $("#id_credit_card_number").val(),
            expMonth: $("#id_expiry_month").val(),
            expYear: $("#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);

            // Prevent the credit card details from being submitted
            // to our server
            $("#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;
    });
});

以下是我提交付款后的错误:

InvalidRequestError 1

InvalidRequestError 2

The Terminal

【问题讨论】:

  • 你确定createToken成功了吗?即,您是否知道stripe_id 令牌ID 在提交到您的后端之前已被设置?即,是createToken 的问题还是您的表单数据发布有问题?
  • 我怎么知道它是否成功?
  • 通过在您的 javascript 中调试请求。可能带有日志记录和网络请求检查。
  • 好的,我去试试。
  • 我在javascript中添加了一个console.log并且没有任何输出,所以我认为它没有被调用。知道为什么吗?

标签: django stripe-payments


【解决方案1】:

我找到了答案,现在信用卡付款正常。我没有在标头中包含 jQuery CDN,所以没有正确调用 stripe.js!

【讨论】:

    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 2019-01-16
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多