- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Django/Stripe SDK 创建了一个 stripe 订阅,因为该软件在欧洲,它使用了新的 SCA(强客户身份验证)。因此,首先我将来源附加到客户,然后我尝试订阅他们,它有效,但对于某些客户,我在 Stripe 控制面板上看到重复付款。
我已经联系了 Stripe,他们的客户支持推荐了以下内容,但我无法理解:
I see what you mean when you say the customers are being charged more than
once. The issue boils down to the API call requesting them to be added to a subscription is being sent more than once to Stripe from your server.To solve this on your end, you will need to make sure your system is sending a request only once. I would recommend checking your server to see where the requests are coming from. It may be an easy solve on that end once this is determined.
@login_required
def PaymentView(request):
profile = Profile.objects.filter(user=request.user).first()
try:
address = profile.address.get(address_type="home")
except:
address = None
user_membership = get_user_membership(request)
try:
selected_membership = get_selected_membership(request)
except:
return redirect(reverse("membership:select"))
publishKey = settings.STRIPE_PUBLISHABLE_KEY
if request.method == "POST":
# try:
source = request.POST.get('stripeSource', "")
amend = request.POST.get('amend', '')
'''
First we need to add the source for the customer
'''
if amend == "true":
customer = stripe.Customer.modify(
user_membership.stripe_customer_id,
source=source,
)
customer.save()
else:
customer = stripe.Customer.retrieve(
user_membership.stripe_customer_id)
try:
customer.source = source # 4242424242424242
customer.save()
except:
pass
'''
Now we can create the subscription using only the customer as we don't need to pass their
credit card source anymore
'''
stripe_subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{"plan": selected_membership.stripe_plan_id},
],
# billing="charge_automatically", #billing is depricated
collection_method="charge_automatically",
expand=['latest_invoice.payment_intent'],
# idempotency_key='FXZMav7BbtEui1Z3',
)
# subscription = djstripe.models.Subscription.sync_from_stripe_data(
# stripe_subscription
# )
if stripe_subscription.status == "active":
return redirect(reverse('membership:update-transactions',
kwargs={
'subscription_id': stripe_subscription.id
}))
elif stripe_subscription.status == "incomplete":
payment_intent = stripe_subscription.latest_invoice.payment_intent
if payment_intent.status == "requires_action":
messages.info(
request, "Your bank requires extra authentication")
context = {
"client_secret": payment_intent.client_secret,
"STRIPE_PUBLIC_KEY": settings.STRIPE_PUBLISHABLE_KEY,
"subscription_id": stripe_subscription.id
}
return render(request, "membership/3d-secure-checkout.html", context)
elif payment_intent.status == "requires_payment_method":
messages.warning(
request, "Your card has been failed or declined, Please try again")
context = {
'publishKey': publishKey,
'selected_membership': selected_membership,
'client_secret': client_secret,
'address': address,
'profile': profile,
'amend': "true"
}
return render(request, "membership/membership_payment.html", context)
else:
messages.info(
request, "Something went wrong. Please report to the website admin.")
context = {
'publishKey': publishKey,
'selected_membership': selected_membership,
# 'client_secret': client_secret,
'address': address,
'profile': profile,
'amend': "false"
}
return render(request, "membership/membership_payment.html", context)
@login_required
def updateTransactionRecords(request, subscription_id):
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
user_membership.membership = selected_membership
user_membership.save()
sub, created = Subscription.objects.get_or_create(
user_membership=user_membership)
sub.stripe_subscription_id = subscription_id
sub.active = True
email_content, e = EmailTemplate.objects.get_or_create(
email_tag='paid_subscription_success')
recepient = request.user.email
sender = settings.EMAIL_HOST_USER
send_mail(email_content.email_subject, email_content.email_body,
sender, [recepient])
sub.save()
try:
del request.session['selected_membership_type']
except:
pass
messages.info(request, 'Successfully created {} membership'.format(
selected_membership))
return redirect(reverse('membership:select'))
@login_required
def successful_membership(request):
selected_membership = request.session.get('selected_membership', "Free")
return render(request, 'membership/purchase_membership_success.html', context={"membership": selected_membership})
这是我的 js 的一部分:
<script src="https://js.stripe.com/v3/"></script>
<!-- script for the stripe form -->
<script type="text/javascript">
// Create a Stripe client.
var stripe = Stripe("{{ publishKey }}");
// Create an instance of Elements.
var elements = stripe.elements();
var cardButton = document.getElementById("card-button");
var cardholderName = document.getElementById("cardholder-name");
var cardElement = elements.create("card");
cardElement.mount("#card-element");
var line1 = document.getElementById("line1");
var line2 = document.getElementById("line2");
var city = document.getElementById("city");
var country = document.getElementById("country");
var postalCode = document.getElementById("postal_code");
var email = document.getElementById("email");
var ownerInfo = {
owner: {
name: cardholderName.value,
address: {
line1: line1.value,
line2: line2.value,
city: city.value,
postal_code: postalCode.value,
country: country.value
},
email: email.value
}
};
// Add an instance of the card Element into the `card-element` <div>.
// Handle real-time validation errors from the card Element.
cardElement.addEventListener("change", function (event) {
var displayError = document.getElementById("card-errors");
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = "";
}
});
// Handle form submission.
var form = document.getElementById("payment-form");
form.addEventListener("submit", function (event) {
event.preventDefault();
stripe.createSource(cardElement, ownerInfo).then(function (result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById("card-errors");
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
setTimeout(stripeSourceHandler(result.source), 3000);
//stripeSourceHandler(result.source);
}
});
});
// Submit the form with the source ID.
function stripeSourceHandler(source) {
var form = document.getElementById("payment-form");
var hiddenInput = document.createElement("input");
hiddenInput.setAttribute("type", "hidden");
hiddenInput.setAttribute("name", "stripeSource");
hiddenInput.setAttribute("value", source.id);
form.appendChild(hiddenInput);
// Insert the source ID into the form so it gets submitted to the server
// Submit the form
form.submit();
}
</script>
最佳答案
我已经通过在订阅之前检查用户是否有任何当前有效的订阅来解决这个问题,我不确定它首先发生的原因但我认为这是由于互联网速度或移动设备断开连接,所以 javascript 正在发送请求,但在它重定向用户之前,它会失去它的连接。
这是我用 stripe SDK 修复它的方法:
customer = stripe.Customer.retrieve(user_membership.stripe_customer_id)
if customer.subscriptions.total_count > 0:
for i in customer.subscriptions.data:
if i.plan['id'] == selected_membership.stripe_plan_id and i.plan['active'] == True:
messages.info(
request, "Your have already subscribed to this plan")
return redirect(reverse('membership:update-transactions',
kwargs={
'subscription_id': i.id
}))
else:
pass # Maybe we can check if users have a subscription that needs renewing
else:
如果有人有更清晰的代码,请与我分享。 😊
关于python - Stripe 订阅在 Django/Python 上创建重复支付,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58486973/
我对 Python-Django 和 web 开发还很陌生,我被困在这个使用 POST 创建新资源的特殊问题上。 我正在为 REST API 使用 Django REST 框架,我正在尝试创建一个新资
我已经使用 Django-storages 成功地将 Word 文档存储到 S3。 class Document(TitleSlugDescriptionModel, TimeStampedModel
我有 2 个关于模型代理的问题, 如何从模型对象创建代理对象? 如何从模型查询集创建代理查询集? 例如,假设我们定义了: from django.contrib.auth.models import
我想编写一个直接执行 HTTP 请求的单元测试(而不是使用 django.test.client.Client)。 如果您好奇为什么 - 那是因为我想测试我从 Django 应用程序公开的 Thrif
我为我的个人网站启动了一个 django 项目来学习 django。到目前为止,我已经将我的开发环境设置为我需要的一切,并遵循 this很棒的教程来创建一些基本的数据结构和模板。现在我想开始使用我之前
我已经阅读了很多关于如何在使用 Django 注册时添加额外字段的信息,例如 here 、 here 和 here 。代码片段是: forms.py(来自注册应用程序) class Registrat
我正在编写小型社交应用程序。功能之一是在网站标题中写入用户名。因此,例如,如果我登录并且我的名字是Oleg(用户名),那么我应该看到: Hello, Oleg | Click to edit prof
我有一个使用 Django 和 Django Rest 框架开发的应用程序。我想将 django-reversion 功能添加到我的应用程序中。 我已经尝试过http://django-reversi
我有一个简单的 HTML 表单,我没有使用 Django 表单,但现在我想添加一个选择。 选择最容易创建为 Django ChoiceField (与通过循环等手动创建选择相反),但是,如果没有在 D
我不明白为什么人们以两种方式编写外键,这样做的目的是什么?它们是相同还是不同? 我注意到有些人这样写: author = models.ForeignKey(Author, on_delete=mod
我想在我的 Django 应用程序中获取评论最多的十个帖子,但我做不到,因为我想不出合适的方法。 我目前正在使用 django 评论框架,并且我已经看到使用 aggregate or annotate
这对于 Django 1.2 仍然有效吗? Custom Filter in Django Admin on Django 1.3 or below 我已经尝试过,但管理类中的 list_filter
问题在于,当 django-compressor 编译为 .js 文件的 CoffeeScript 文件中引用 {{ STATIC_URL }} 时,它无法正确加载。 在我的 django 模板中,我
我正在尝试将一些字段从一个 django 模型移动到一个新模型。假设我有一个书籍模型: class Book(models.Model): title = models.CharField(max
我想在我的 Django 应用程序中获取评论最多的十个帖子,但我做不到,因为我想不出合适的方法。 我目前正在使用 django 评论框架,并且我已经看到使用 aggregate or annotate
目前我正在寻找在 Django 中实现访问控制。我已经阅读了有关内置权限的内容,但它并不关心每个对象的基础。例如,我想要“只有创建者可以删除自己的项目”之类的权限。所以我读到了 django-guar
嗨,我正在将我的 Django 模型的一个字段的值设置为其他模型的另一个字段的值。这个值应该是动态变化的。 这是我的第一个模型 class MainModel(AbstractBaseUser, Pe
我正在尝试为我的模型创建一个编辑表单。我没有使用模型表单,因为根据模型类型,用户可以使用不同的表单。 (例如,其中一个表单有 Tinymce 小部件,而另一个没有。) 有没有什么方法可以使用模型设置表
Django 模板中的搜索字段 如何在类似于此图像的 Django 模板中创建搜索字段 http://asciicasts.com/system/photos/1204/original/E354I0
根据 Django documentation ,如果 Django 安装激活了 AuthenticationMiddleware,HttpRequest 对象有一个“user”属性代表当前登录的用户
我是一名优秀的程序员,十分优秀!