Stripe Checkout Session高级集成:自定义税率与优惠券应用


Stripe Checkout Session高级集成:自定义税率与优惠券应用

本教程详细指导如何在stripe checkout session中集成自定义税率和折扣。文章将深入解析stripe api中`taxrate`和`coupon`对象的创建与应用,纠正常见的参数配置错误,并提供包含动态税费和优惠券处理的完整代码示例。旨在帮助开发者构建功能完善、符合业务需求的stripe支付流程。

1. 理解Stripe Checkout Session与集成需求

Stripe Checkout Session是Stripe提供的一种快速、安全地收集客户支付信息的方式。在构建电子商务应用时,往往需要根据业务逻辑动态应用税费和折扣。这要求开发者能够正确地创建和管理Stripe中的TaxRate(税率)和Coupon(优惠券)对象,并将其关联到Checkout Session。

原始代码尝试集成这些功能,但在discounts参数的格式上出现了错误,导致InvalidRequestError。本教程将纠正这些错误并提供一个健壮的集成方案。

2. 集成自定义税率(Tax Rates)

Stripe允许您创建自定义税率,并将其应用于Checkout Session中的商品。这些税率可以是包含性的(价格已含税)或排他性的(税费额外计算)。

2.1 创建Stripe TaxRate对象

在将税率应用于Checkout Session之前,您需要先在Stripe中创建TaxRate对象。这些对象定义了税率的百分比、显示名称、描述和管辖区域等信息。在实际应用中,通常会持久化这些税率(例如,存储在数据库中,并仅在需要时更新Stripe),而不是每次都动态创建。

import stripe

# 假设您的Order模型关联了Tax模型,Tax模型包含name, rate等字段
# order.tax.all() 返回一个Tax对象列表

tax_rate_ids = []
for tax_obj in order.tax.all():
    # 最佳实践:检查Stripe中是否已存在同名或同配置的TaxRate,避免重复创建
    # 简单示例中,我们假设每次都创建,但生产环境应优化此逻辑
    try:
        # 尝试查找已存在的税率,如果您的Tax模型中存储了Stripe TaxRate ID
        # 例如:if tax_obj.stripe_tax_rate_id: tax_rate_ids.append(tax_obj.stripe_tax_rate_id)
        # 否则,进行创建
        tax_rate = stripe.TaxRate.create(
            display_name=tax_obj.name,
            description=f"{tax_obj.name} ({tax_obj.rate}%)",
            percentage=tax_obj.rate, # 假设tax_obj.rate是百分比数值,如5.0代表5%
            inclusive=False,         # 设置为True表示价格已含税,False表示税费额外计算
            jurisdiction="US",       # 根据实际业务设置管辖区域,例如 "US", "EU", "CA" 等
        )
        tax_rate_ids.append(tax_rate.id)
    except stripe.error.StripeError as e:
        # 处理Stripe API错误
        print(f"Error creating tax rate: {e}")
        # 根据错误类型决定是否继续或抛出异常

2.2 将TaxRate应用于Checkout Session

创建TaxRate后,您可以通过两种主要方式将其应用于Checkout Session:

  1. 应用于单个line_item(推荐): 如果您的订单包含多个商品,且每个商品可能适用不同的税率,或者您希望更精细地控制税费,这是首选方法。
  2. 应用于整个Session: 如果所有商品都适用相同的税率,或者您只有一个代表整个订单的line_item,可以在Session级别应用。

在用户提供的代码中,只有一个line_item代表整个订单,因此将其应用于line_item是合适的。

Veo Veo

Google 最新发布的 AI 视频生成模型

Veo 567 查看详情 Veo
# ... (承接上述 tax_rate_ids 的创建) ...

line_items_data = [
    {
        'price_data': {
            'currency': 'usd',
            'unit_amount': order.get_total_cost() * 100, # Stripe金额以最小单位(美分)计
            'product_data': {
                'name': order.__str__(),
            },
        },
        'quantity': 1,
        'tax_rates': tax_rate_ids, # 将税率ID列表添加到line_item中
    },
]

# 如果选择应用于整个Session(不推荐与line_item同时使用相同的税率)
# session = stripe.checkout.Session.create(
#     # ...
#     line_items=line_items_data,
#     tax_rates=tax_rate_ids, # 在Session级别应用税率
# )

3. 集成自定义折扣(Discounts/Coupons)

Stripe通过Coupon(优惠券)对象来管理折扣。您可以创建固定金额折扣或百分比折扣的优惠券,并将其应用于Checkout Session。

3.1 创建Stripe Coupon对象

与税率类似,优惠券也应该在Stripe中创建。在生产环境中,通常会有一个管理后台来创建和管理这些优惠券,并将其Stripe ID存储在您的数据库中。

import stripe

# 假设您的Order模型关联了Discount模型,Discount模型包含amount, name等字段
# order.discount.all() 返回一个Discount对象列表

discount_items = []
for discount_obj in order.discount.all():
    # 最佳实践:检查Stripe中是否已存在同名或同配置的Coupon,避免重复创建
    # 简单示例中,我们假设每次都创建,但生产环境应优化此逻辑
    try:
        # 创建一个Stripe Coupon
        # amount_off 是固定金额折扣,以最小单位(美分)计
        # percent_off 是百分比折扣,与amount_off互斥
        coupon = stripe.Coupon.create(
            amount_off=discount_obj.amount * 100, # 假设discount_obj.amount是美元金额
            duration='once', # 'once', 'repeating', 'forever'
            currency='usd',
            name=discount_obj.name,
        )
        discount_items.append({"coupon": coupon.id}) # 正确的格式是 {"coupon": "coupon_id"}
    except stripe.error.StripeError as e:
        # 处理Stripe API错误
        print(f"Error creating coupon: {e}")
        # 根据错误类型决定是否继续或抛出异常

3.2 将Coupon应用于Checkout Session

将优惠券应用于Checkout Session需要使用discounts参数。注意:原始代码中的discounts=[{"discounts": '{{COUPON_ID}}'}]是错误的,导致了InvalidRequestError。 正确的格式是一个包含字典的列表,每个字典都应该有一个"coupon"键,其值为优惠券的ID。

# ... (承接上述 discount_items 的创建) ...

session = stripe.checkout.Session.create(
    # ... 其他参数 ...
    discounts=discount_items, # 正确的优惠券应用方式
)

4. 完整集成示例代码

以下是结合了税率和折扣的优化后的完整代码示例,基于您提供的原始结构进行改进:

import stripe
from django.views import View
from django.http import JsonResponse
from .models import Order # 假设您的Order模型在此处定义

# 请替换为您的Stripe Secret Key
stripe.api_key = 'sk_test_YOUR_STRIPE_SECRET_KEY' # 务必使用环境变量或配置文件管理密钥

class CreateCheckoutSessionOrderView(View):
    def get(self, request, *args, **kwargs):
        order_id = self.kwargs["order_id"]
        DOMAIN: str = 'http://127.0.0.1:8000' # 生产环境请使用您的实际域名

        try:
            order = Order.objects.get(id=order_id)
        except Order.DoesNotExist:
            return JsonResponse({'error': 'Order not found'}, status=404)

        # --- 1. 处理自定义税率 ---
        tax_rate_ids = []
        for tax in order.tax.all(): # 假设order关联了多个Tax对象
            try:
                # 在生产环境中,您应该查询数据库或Stripe来获取已存在的TaxRate ID
                # 避免每次都创建新的TaxRate
                tax_rate = stripe.TaxRate.create(
                    display_name=tax.name,
                    description=f"{tax.name} ({tax.rate}%)",
                    percentage=tax.rate, # 假设tax.rate是百分比,如5.0代表5%
                    jurisdiction="US",   # 根据实际业务设置
                    inclusive=False,     # 设为True则价格含税,False则税费额外计算
                    active=True,         # 确保税率是激活状态
                )
                tax_rate_ids.append(tax_rate.id)
            except stripe.error.StripeError as e:
                print(f"Error creating Stripe TaxRate for {tax.name}: {e}")
                # 根据业务需求处理错误,例如跳过此税率或返回错误

        # --- 2. 处理自定义折扣 ---
        discounts_list = []
        for discount in order.discount.all(): # 假设order关联了多个Discount对象
            try:
                # 在生产环境中,您应该查询数据库或Stripe来获取已存在的Coupon ID
                # 避免每次都创建新的Coupon
                coupon = stripe.Coupon.create(
                    amount_off=discount.amount * 100, # amount_off以最小货币单位(美分)计
                    duration='once', # 'once', 'repeating', 'forever'
                    currency='usd',
                    name=discount.name,
                )
                discounts_list.append({"coupon": coupon.id}) # 正确的折扣参数格式
            except stripe.error.StripeError as e:
                print(f"Error creating Stripe Coupon for {discount.name}: {e}")
                # 根据业务需求处理错误

        # --- 3. 创建Stripe Checkout Session ---
        try:
            session = stripe.checkout.Session.create(
                payment_method_types=['card'],
                line_items=[
                    {
                        'price_data': {
                            'currency': 'usd',
                            'unit_amount': order.get_total_cost() * 100, # 总金额以最小货币单位计
                            'product_data': {
                                'name': order.__str__(),
                                'images': [order.get_thumbnail_url()] if hasattr(order, 'get_thumbnail_url') else [], # 可选:添加商品图片
                            },
                        },
                        'quantity': 1,
                        'tax_rates': tax_rate_ids, # 将收集到的税率ID应用于line_item
                    },
                ],
                payment_intent_data={
                    'metadata': {
                        'order_id': order.id,
                    },
                },
                mode='payment',
                success_url=DOMAIN + '/success/?session_id={CHECKOUT_SESSION_ID}', # 推荐添加session_id参数
                cancel_url=DOMAIN + '/cancel/',
                discounts=discounts_list, # 将收集到的折扣应用于Session
            )
            return JsonResponse({'id': session.id})

        except stripe.error.StripeError as e:
            # 捕获Stripe API可能抛出的所有错误
            print(f"Error creating Stripe Checkout Session: {e}")
            return JsonResponse({'error': str(e)}, status=500)
        except Exception as e:
            # 捕获其他未知错误
            print(f"An unexpected error occurred: {e}")
            return JsonResponse({'error': 'An unexpected error occurred'}, status=500)

5. 注意事项与最佳实践

  1. Stripe API Key管理: 永远不要将您的Stripe Secret Key硬编码到代码中。使用环境变量、Django设置文件或专门的密钥管理服务来安全地存储和访问它。
  2. Stripe对象持久化: 在生产环境中,频繁地创建TaxRate和Coupon对象是不高效且不必要的。
    • 税率: 通常税率是相对稳定的。您可以在Stripe仪表板中创建它们一次,然后将它们的Stripe ID存储在您的数据库中(例如,在您的Tax模型中添加stripe_tax_rate_id字段)。在创建Checkout Session时,直接从数据库中检索这些ID。
    • 优惠券: 优惠券可能更具动态性。对于预设的优惠券,同样可以存储其Stripe ID。对于用户输入的促销码,您需要使用PromotionCode对象,它链接到Coupon。
  3. 错误处理: 务必捕获stripe.error.StripeError及其子类,以便优雅地处理Stripe API调用失败的情况,并向用户提供有意义的反馈。
  4. 金额单位: Stripe API要求所有金额都以最小货币单位(例如,美元为美分,欧元为欧分)表示。请确保在传递unit_amount和amount_off时进行正确的转换(例如,乘以100)。
  5. success_url中的session_id: 在success_url中添加?session_id={CHECKOUT_SESSION_ID}是一个很好的实践。当客户成功完成支付后,Stripe会将实际的Session ID填充到此URL中,您的成功页面可以使用此ID来检索Session详情并验证支付状态。
  6. 测试: 在将代码部署到生产环境之前,务必在Stripe的测试模式下进行彻底测试,以确保税费和折扣的计算和应用符合预期。
  7. Webhook: 对于更复杂的订单流程(例如,需要更新订单状态、发送确认邮件等),强烈建议设置Stripe Webhook来监听支付事件(如checkout.session.completed)。

总结

通过本教程,您应该已经掌握了在Stripe Checkout Session中正确集成自定义税率和折扣的方法。关键在于理解Stripe TaxRate和Coupon对象的创建,以及在stripe.checkout.Session.create方法中line_items的tax_rates参数和discounts参数的正确格式。遵循最佳实践,特别是关于Stripe对象持久化和错误处理,将有助于构建一个稳定、高效的支付系统。

以上就是Stripe Checkout Session高级集成:自定义税率与优惠券应用的详细内容,更多请关注其它相关文章!


# json  # 天猫seo入口  # 正在播放seo探花  # 陕西整站网站推广工具  # 抛出  # 是一个  # 您可以  # 数据库中  # 子类  # 多个  # 每次都  # 自定义  # 应用于  # 您的  # 币  # js  # go  # 编码  # app  # session  # ai  # 环境变量  # 配置文件  # django  # api调用  # cos  # re  # 宁夏外贸营销推广  # 沾益区网站建设内容  # 健康推广网站  # 网站建设用户登录源码  # 金华双十一推广营销方案  # 安顺商城网站推广方案  # 泰州网站优化推荐 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: 手机耗电快是什么原因 延长手机电池续航时间的设置方法【详解】  《地下城堡4:骑士与破碎编年史》墓穴挑战125攻略  发博客与长微博技巧  在J*a中如何实现类的继承与方法重用_OOP继承方法重用技巧分享  作业帮网页版不用下载入口 在线问老师快速答疑  C++如何将字符串转换为大写或小写_C++ transform函数的使用技巧  谷歌浏览器官方镜像获取方法_谷歌浏览器网页版入口极速直达  酷狗音乐多音轨设置教程  优化长HTML属性值:SonarQube警告与实用策略  Linux如何开发轻量级数据服务模块_Linux服务化设计  掌握Go App Engine项目结构与GOPATH:包管理与导入实践  《一起考教师》账号注销方法  如何在CSS中清除浮动解决背景颜色不包裹内容问题_clear after技巧  12306不能订票的时间段是固定的吗? | 节假日购票时间有无变化  Coolpad5890 ROM刷机包  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  Golang如何操作指针参数_Go pointer参数传递规则  鲁班大师乓乓皮肤获取方法  店铺如何关联视频号推广?视频号推广有什么用?  J*aScript包管理器_Npm与Yarn对比  如何取消数字签名  吃完饭就犯困是什么原因 餐后嗜睡如何缓解  《密马》发布账号方法  PHP多语言网站的实现:会话管理与翻译函数优化教程  Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法  Win10输入法不见了怎么办 Win10找回语言栏图标教程  京东快递物流信息不更新怎么办_物流停滞原因与处理方法  Python中处理嵌套字典与列表的数据提取与过滤教程  歌词怎么展示在|直播|间视频号?有什么注意事项?  《崩坏:星穹铁道》3.6版本异相仲裁打法及配队推荐  Python高效统计字典嵌套列表值在目标列表中的出现次数  PointNet++语义分割模型中类别变更引发的断言错误及标签处理策略  Win11怎么录屏_Windows 11自带Xbox Game Bar录制视频  汽水音乐官方网站登录入口_汽水音乐网页版进入链接  国际经济与贸易就业方向解析  windows10怎么关闭自动安装应用_windows10禁止推广应用下载  申通快件单号查询平台 申通包裹物流动态跟踪  《单词速记宝》设置学习计划方法  苹果电脑如何快速查看电池状态 苹果电脑电池信息快捷方法  QQ网页版官方账号登录入口 QQ网页版网页版入口快速导航  微信客户端怎么查看二维码_微信客户端个人二维码查看方法  iPhone16Plus参数配置如何调整声音_iPhone16Plus参数配置声音调整详细方法  《偃武》甘宁技能详解  抖音作品被限流怎么办 抖音内容优化与流量恢复方法  cad视图选项卡不见了怎么办_cad视图标签恢复显示方法  可米酷漫画在线阅读入口_ 可米酷漫画官网直达链接  PHP中实现JSON数据数组分页的教程  《万兴喵影》导出视频方法  顺丰快递单号查询寄件人 顺丰寄件人查询入口  SQLAlchemy 2.0 与 Pydantic 模型类型安全集成指南 

 2025-12-14

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.