【问题标题】:Previewing upcoming invoices with proration issues with Stripe [Java]使用 Stripe [Java] 预览即将出现的带有按比例分配问题的发票
【发布时间】:2021-04-15 05:48:09
【问题描述】:

我正在尝试预览即将开具的按比例收费的发票。

客户在第 1 天从 30 欧元/年计划更改为 65 欧元/年计划(对于按比例计算的日期很重要)。

根据文档here 应向客户收费:

  • -30 欧元旧计划的剩余时间
  • 新计划的剩余时间为 65 欧元

总共 35 欧元。下一张发票应该是 35 欧元。 使用 Java 库进行以下调用以获取即将到来的发票:

InvoiceUpcomingParams params = InvoiceUpcomingParams.builder()
        .setCustomer(userId)
        .setSubscription(subscriptionId)
        .addSubscriptionItem(
                InvoiceUpcomingParams.SubscriptionItem.builder()
                .setId(subscription.getItems().getData().get(0).getId())
                .setPrice(priceId)
                .build()
        ).setSubscriptionProrationDate(prorationDate)
        .build();

生成的发票具有以下属性:

  • 支付金额:0
  • 应付金额:9999
  • 剩余金额:9999
  • 小计:9999

...以及以下发票行(ID 已被混淆):

{
    "data": [
        {
            "amount": -3000,
            "currency": "eur",
            "description": "Unused time on xxxxx after 09 Jan 2021",
            "discount_amounts": [],
            "discountable": false,
            "discounts": [],
            "id": "---",
            "invoice_item": "---",
            "livemode": false,
            "metadata": {},
            "object": "line_item",
            "period": {
                "end": 1641756061,
                "start": 1610222989
            },
            "plan": {
                "active": true,
                "aggregate_usage": null,
                "amount": 3000,
                "amount_decimal": 3000,
                "billing_scheme": "per_unit",
                "created": 1598220277,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "interval": "year",
                "interval_count": 1,
                "livemode": false,
                "metadata": {},
                "nickname": null,
                "object": "plan",
                "product": "---",
                "tiers": null,
                "tiers_mode": null,
                "transform_usage": null,
                "trial_period_days": null,
                "usage_type": "licensed"
            },
            "price": {
                "active": true,
                "billing_scheme": "per_unit",
                "created": 1598220277,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "livemode": false,
                "lookup_key": null,
                "metadata": {},
                "nickname": null,
                "object": "price",
                "product": "---",
                "recurring": {
                    "aggregate_usage": null,
                    "interval": "year",
                    "interval_count": 1,
                    "trial_period_days": null,
                    "usage_type": "licensed"
                },
                "tiers": null,
                "tiers_mode": null,
                "transform_quantity": null,
                "type": "recurring",
                "unit_amount": 3000,
                "unit_amount_decimal": 3000
            },
            "proration": true,
            "quantity": 1,
            "subscription": "---",
            "subscription_item": "---",
            "tax_amounts": [],
            "tax_rates": [],
            "type": "invoiceitem",
            "unified_proration": null
        },
        {
            "amount": 6499,
            "currency": "eur",
            "description": "Remaining time on xxxx after 09 Jan 2021",
            "discount_amounts": [],
            "discountable": false,
            "discounts": [],
            "id": "---",
            "invoice_item": "---",
            "livemode": false,
            "metadata": {},
            "object": "line_item",
            "period": {
                "end": 1641756061,
                "start": 1610222989
            },
            "plan": {
                "active": true,
                "aggregate_usage": null,
                "amount": 6500,
                "amount_decimal": 6500,
                "billing_scheme": "per_unit",
                "created": 1598220248,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "interval": "year",
                "interval_count": 1,
                "livemode": false,
                "metadata": {},
                "nickname": null,
                "object": "plan",
                "product": "---",
                "tiers": null,
                "tiers_mode": null,
                "transform_usage": null,
                "trial_period_days": null,
                "usage_type": "licensed"
            },
            "price": {
                "active": true,
                "billing_scheme": "per_unit",
                "created": 1598220248,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "livemode": false,
                "lookup_key": null,
                "metadata": {},
                "nickname": null,
                "object": "price",
                "product": "---",
                "recurring": {
                    "aggregate_usage": null,
                    "interval": "year",
                    "interval_count": 1,
                    "trial_period_days": null,
                    "usage_type": "licensed"
                },
                "tiers": null,
                "tiers_mode": null,
                "transform_quantity": null,
                "type": "recurring",
                "unit_amount": 6500,
                "unit_amount_decimal": 6500
            },
            "proration": true,
            "quantity": 1,
            "subscription": "---",
            "subscription_item": "---",
            "tax_amounts": [],
            "tax_rates": [],
            "type": "invoiceitem",
            "unified_proration": null
        },
        {
            "amount": 6500,
            "currency": "eur",
            "description": "1 × xxxx (at €65.00 / year)",
            "discount_amounts": [],
            "discountable": true,
            "discounts": [],
            "id": "---",
            "invoice_item": null,
            "livemode": false,
            "metadata": {},
            "object": "line_item",
            "period": {
                "end": 1673292061,
                "start": 1641756061
            },
            "plan": {
                "active": true,
                "aggregate_usage": null,
                "amount": 6500,
                "amount_decimal": 6500,
                "billing_scheme": "per_unit",
                "created": 1598220248,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "interval": "year",
                "interval_count": 1,
                "livemode": false,
                "metadata": {},
                "nickname": null,
                "object": "plan",
                "product": "---",
                "tiers": null,
                "tiers_mode": null,
                "transform_usage": null,
                "trial_period_days": null,
                "usage_type": "licensed"
            },
            "price": {
                "active": true,
                "billing_scheme": "per_unit",
                "created": 1598220248,
                "currency": "eur",
                "deleted": null,
                "id": "---",
                "livemode": false,
                "lookup_key": null,
                "metadata": {},
                "nickname": null,
                "object": "price",
                "product": "---",
                "recurring": {
                    "aggregate_usage": null,
                    "interval": "year",
                    "interval_count": 1,
                    "trial_period_days": null,
                    "usage_type": "licensed"
                },
                "tiers": null,
                "tiers_mode": null,
                "transform_quantity": null,
                "type": "recurring",
                "unit_amount": 6500,
                "unit_amount_decimal": 6500
            },
            "proration": false,
            "quantity": 1,
            "subscription": "---",
            "subscription_item": "---",
            "tax_amounts": [],
            "tax_rates": [],
            "type": "subscription",
            "unified_proration": null
        }
    ],
    "has_more": false,
    "object": "list",
    "request_options": null,
    "request_params": null,
    "url": "---"
}

简而言之,发票行包含以下内容:

  • 2021 年 1 月 9 日之后 xxxxx 上的未使用时间:-3000
  • 2021 年 1 月 9 日之后 xxxxx 的剩余时间:6499
  • 1 × xxxxx(65.00 欧元/年):6500

问题 1

我认为这是错误的。根据文档here,费用应为:64.99 - 30 = 34.99 欧元

现在,如果我通过实际订阅更新,Stripe 生成的发票确实是 34.99 欧元。因此,我如何调用即将到来的发票 API 或它返回的内容似乎有问题。

我错过了什么?我应该自己从 amountDue 中扣除订阅的价格吗?

【问题讨论】:

    标签: java stripe-payments


    【解决方案1】:

    这是 Upcoming Invoice 端点的预期行为。看看the documentation for previewing a proration,它显示了您在示例结果中看到的相同内容:

    您可以展开下面的示例响应来查看:

    • 在第 36-38 行以先前价格计算未使用时间的贷方。
    • 在第 107-109 行以新价格花费的时间成本。
    • 第 276-279 行发票的新小计和总计。

    您正在预览即将到来的发票,这意味着它将为当前期间的更改下一个期间的常规金额开具发票。当前期间的更改有两个订单项,下一个期间的更改有一个订单项。

    现在,如果我进行实际订阅更新,Stripe 生成的发票确实是 34.99 欧元。

    听起来您正在进行此更改,然后立即生成发票,而不是等待通常会因订阅而生成的发票。

    【讨论】:

    • 嗨 Justin,关于 cmets 的 SO 规则很可笑,请参阅下面的回答。
    【解决方案2】:

    我可以看到文档示例确实遵循相同的模式。它包含 3 行。 2 个按比例收费,1 个按实际项目收费。

    因此,要点是即将发出的发票(在订阅续订日期)将包括按比例分配的费用和新的分期付款费用。

    因此,如果我想向我的客户展示他们升级/降级后即将收到的发票的外观现在,我必须手动从响应中减去商品价格。

    生成的发票是 34.99,因为我开具发票的时间大致与即将到来的发票预览同时修改订阅项目的价格。

    【讨论】:

      【解决方案3】:

      刚刚遇到同样的问题。通过将 proration_behavior 设置为“always_invoice”,我设法获得了正确的即将发出的发票(即 2 行用于回扣,1 行用于新费用)

      【讨论】:

        【解决方案4】:

        只是想扩展@Rich Harvey 的答案,以防其他人遇到这个问题。

        实际发票和预览发票不同的原因是您在实际将更改应用到订阅时设置了proration_behavior: "always_invoice",因此立即创建了仅包含按比例金额的发票。

        但是,在您的预览中,更改将应用​​于下一张发票,因此收取订阅的全价 + 按比例分配的金额。

        要解决此问题,只需为发票预览设置 subscription_proration_behavior = 'always_invoice'

        InvoiceUpcomingParams params = InvoiceUpcomingParams.builder()
                .setCustomer(userId)
                .setSubscription(subscriptionId)
        
                .addSubscriptionItem(
                        InvoiceUpcomingParams.SubscriptionItem.builder()
                        .setId(subscription.getItems().getData().get(0).getId())
                        .setPrice(priceId)
                        .build()
                ).setSubscriptionProrationDate(prorationDate)
                .setSubscriptionProrationBehavior('always_invoice')
                .build();
        

        查看Documentation.setSubscriptionProrationBehavior()

        【讨论】:

          猜你喜欢
          • 2019-06-04
          • 1970-01-01
          • 2019-09-08
          • 2013-11-10
          • 2020-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-29
          相关资源
          最近更新 更多