使用Python的Stripe API PaymentIntent和计费

时间:2019-08-22 14:24:39

标签: python django stripe-payments

我尝试使用新的Stripe的PaymentIntent系统,以便在SCA在欧盟启动时准备就绪。

我只使用一次性付款。

我成功使用PaymentIntent following Stripe's documentation付款。但是我无法为每笔付款创建发票(我必须依法开具发票),并且尝试了很多事情。

但是首先,我认为我需要显示代码以介绍遇到的麻烦。

在我看来,我创建一个Stripe Session:

public_token = settings.STRIPE_PUBLIC_KEY    
stripe.api_key = settings.STRIPE_PRIVATE_KEY

stripe_sesssion = stripe.checkout.Session.create(
    payment_method_types=['card'],
    line_items=[{
        'name':'My Product',
        'description': description,
        'amount': amount,
        'currency': 'eur',
        'quantity': 1,
    }],
    customer=customer_id,
    success_url=f'{settings.SITE_URL}/ok.html',
    cancel_url=f'{settings.SITE_URL}/payment_error.html',
)

然后,用户单击我网页上的“购买”按钮,然后重定向到Stripe的Checkout页面。

enter image description here

在用户填写了他的支付卡信息之后,Stripe呼叫我的Webhook(根据触发的checkout.session.completed事件)。

这是我的 webhook功能代码

@csrf_exempt
def webhook_payment_demande(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None
    if settings.DEBUG is False:
        endpoint_secret = "whsec_xxx"
    else:
        endpoint_secret = "whsec_xxx"

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)

    # Handle the event
    if event['type'] == 'checkout.session.completed':
        stripe_session = event['data']['object']

        invoice_item = stripe.InvoiceItem.create(
            customer=customer_id,
            amount=str(amount),
            currency="eur",
            description=description
        )

        invoice = stripe.Invoice.create(
            customer=customer_id,
        )

        invoice_payment = stripe.Invoice.pay(
            invoice,
            source=card
        )

        [...] Deliver product by e-mail and stuff [...]
  • 如果我执行该代码,则付款将在第一次(PaymentIntent)时完成,但在第二次完成后才能最终确定我创建的发票。因此我的客户支付了两倍的费用。
  • 如果我删除了Invoice.pay功能,Stripe会在一小时后使用现有的支付卡向Stripe收取我的客户费用。
  • 如果我没有在Web挂钩函数中手动创建任何发票, 条纹不会自动创建一个。
  • 如果在第一个视图中创建发票,就在条纹之后 结帐会话,并且在我的客户填写他的卡信息之前,即使该客户向他收取了金额, 他没有完成付款(因为他有一张已存入的卡 条纹)。

我已经阅读了好几天的文档,但找不到一个很好的教程来进行一次具有SCA兼容性的一次性付款,然后再开具账单。

一个好人是否已经根据SCA的要求修复了自己的Stripe支付API系统,并找到了解决该问题的方法?

非常感谢您的帮助! :)

2 个答案:

答案 0 :(得分:1)

根据要求发布。使用.NET和React.js。 步骤:

在加载付款页面时,我通过我的API调用stripe创建一个Intent

var response = await _setupIntentService.CreateAsync(new SetupIntentCreateOptions
{
     PaymentMethodTypes = new List<string> { "card" },
     Usage = "off_session", // Allows card to be used later one
});
return response.ClientSecret;

然后使用条纹元素,呈现卡详细信息表单(在条纹文档网站上自行说明)。提交此表单后,请致电条纹以创建一种付款方式(React):

this.props.stripe.handleCardSetup(intent)
  .then((stripeResponse) => {
    submitSubscription(stripeResponse.setupIntent.payment_method);
  })

submitSubscription调用我的API。

如果客户存在,我将取消现有的付款方式

_paymentMethodService.ListAsync(new PaymentMethodListOptions { Limit = 1, CustomerId = customerId, Type = "card" });
if (paymentMethods.Any())
{
   await _paymentMethodService.DetachAsync(paymentMethods.First().Id, new PaymentMethodDetachOptions());
}

并附加新的付款方式,还为客户设置默认付款方式

var options = new PaymentMethodAttachOptions { CustomerId = customerId };
await _paymentMethodService.AttachAsync(paymentMethodId, options);
await _customerService.UpdateAsync(customer.Id, new CustomerUpdateOptions
{
    InvoiceSettings = new CustomerInvoiceSettingsOptions { DefaultPaymentMethodId = paymentMethodId }
});

如果客户不存在,请使用付款方式ID创建一个

 _customerService.CreateAsync(new CustomerCreateOptions
{
    Email = email,
    PaymentMethodId = paymentMethodId,
    InvoiceSettings = new CustomerInvoiceSettingsOptions { DefaultPaymentMethodId = paymentMethodId }
});

我正在使用Stripe详细记录的计划和订阅,但我的主要问题是我同时使用了来源和付款方式。如果您要支付off session,付款方式是旧的方式。

希望有帮助。

答案 1 :(得分:0)

您的代码正在通过Checkout创建一次性费用。您要寻找的是此处https://stripe.com/docs/receipts

中记录的电子邮件回执功能

这样,您可以在对帐户成功收取费用后向您的客户发送电子邮件,该费用应作为发票。您还可以通过查看费用的receipt_url属性直接链接到此电子邮件收据:https://stripe.com/docs/api/charges/object#charge_object-receipt_url