当我也要一次性支付费用时,如何处理Stripe Webhook来进行订阅付款?

时间:2020-06-09 16:45:49

标签: php stripe-payments stripe-subscriptions

我在具有订阅和一次性费用的应用中使用Stripes PHP SDK。

我正在通过Webhook跟踪以下事件:

// Handle the event
switch ($event->type) {
    // Fired for every payment, including subscriptions and one-offs
    case 'payment_intent.succeeded':
        $payment = $event->data->object;
        $this->handleOneOffPaymentSuccess($payment);
        break;
    // When a one-off payment fails
    case 'charge.failed':
        $payment = $event->data->object;
        $this->handleOneOffPaymentFailed($payment);
        break;
    case 'payment_intent.payment_failed':
        $payment = $event->data->object;
        $this->handleOneOffPaymentFailed($payment, 'The payment was not authorized (#Virtuoso-3)');
        break;
    // Subscription handling
    case 'invoice.payment_succeeded':
        $payment = $event->data->object;
        $this->handleSubscriptionPaymentSuccess($payment);
        break;
    // Subscription failure
    case 'invoice.payment_failed':
        $payment = $event->data->object; 
        $this->handleSubscriptionPaymentFailed($payment);
        break;
    // ... handle other event types
    default:
        // Unexpected event type
        http_response_code(400);
        exit();
}

一次性付款后,我得到payment_intent.succeeded。这包含我的元数据,因此我可以将商品标记为已购买。一切都很好。

进行订阅时,我得到一个invoice.payment_succeeded事件。这包含我的元字段数据,因此我可以将订阅标记为已付费。也很好。

但是,随着订阅的进行,我得到了一个payment_intent.succeeded事件。我想这是因为要收费。没关系,但是它不包含创建订阅时的任何元字段数据,因此我无法跟踪其用途。目前,它只是失败了,这似乎并不正确。

这是我创建订阅的方式:

$subscription = \Stripe\Subscription::create([
    'customer' => $payment_method->stripe_customer_id, 
    'items' => [
        [
            'plan' => App::environment('production') ? $user->userType->stripe_plan : $user->userType->stripe_plan_test,
        ],
    ],
    'expand' => ['latest_invoice.payment_intent'],
    'metadata' => [
        'internal_subscription_id' => $internalSubscription->id,
        'user_id' => $user_id,
    ]
]);

理想情况下,我希望user_id成为费用的一部分,然后我可以将其记录在用户名下,并向他们显示一次性费用。

有什么想法我要去哪里吗?

1 个答案:

答案 0 :(得分:0)

您在这里有几种选择:

  1. 检查invoice attribute on the payment intent object。与订阅付款相关时,该名称将设置为发票ID,一次性付款则为null。注意:如果您还使用一次性发票,则也需要处理该区别(检索发票并检查subscription属性)。
  2. 在一次性付款意向中设置一些metadata。例如,设置'metadata' => [ 'onetime' => 'true']并在事件处理程序中进行检查。