【发布时间】:2021-03-29 14:15:51
【问题描述】:
当我尝试向 stripe 发送付款时,我收到一条错误消息:“无效的卡对象:必须是字典或非空字符串。”
付款金额为 5 欧元。我正在使用信用卡号 4242 4242 4242 4242 来测试付款。我可以看到除了“stripe_id”之外,条纹的“Post”参数都是正确的。我一直在尝试查看“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})
这是终端中的输出:
Method isn't post...
[18/Dec/2020 23:24:26] "GET /checkout/ HTTP/1.1" 200 5957
checkout...
Payment form is valid...
Just about to charge the customer...
Internal Server Error: /checkout/
Traceback (most recent call last):
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/ubuntu/environment/issuetracker/checkout/views.py", line 29, in checkout
card=payment_form.cleaned_data['stripe_id']
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/stripe/api_resources/abstract/createable_api_resource.py", line 22, in create
response, api_key = requestor.request("post", url, params, headers)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/stripe/api_requestor.py", line 122, in request
resp = self.interpret_response(rbody, rcode, rheaders)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/stripe/api_requestor.py", line 373, in interpret_response
self.handle_error_response(rbody, rcode, resp.data, rheaders)
File "/home/ubuntu/environment/issuetracker/foo/lib/python3.6/site-packages/stripe/api_requestor.py", line 152, in handle_error_response
raise err
stripe.error.InvalidRequestError: Request req_KWiO7eNBrSt4ph: Invalid card object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'
[18/Dec/2020 23:24:40] "POST /checkout/ HTTP/1.1" 500 104672
这里是 stripe.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;
});
});
支付失败时我的页面截图如下:
【问题讨论】:
标签: python django stripe-payments