Laravel Cashier在卡更新后重新尝试待处理的发票

时间:2017-01-02 13:39:24

标签: laravel stripe-payments laravel-5.3 laravel-cashier

我正在使用带收银台的Laravel 5.3。如果客户更新了他们的卡详细信息,我如何检查是否有待处理的发票并要求Stripe重新尝试新卡上的费用?目前,我已在Stripe仪表板中设置了尝试设置。但据我所知,Stripe不会自动尝试向客户收取费用,如果他们更新了他们的卡详细信息并等待下一次尝试日期再次尝试。这就是为什么我想在他们更新卡时立即手动尝试向待定发票上的客户收费。我阅读了Cashier文档和Github页面,但这个案例不在那里。

$user->updateCard($token);
// Next charge customer if there is a pending invoice

请有人帮帮我。

1 个答案:

答案 0 :(得分:0)

在测试并与Stripe支持人员讨论后,我发现了Laravel Cashier中使用的当前updateCard()方法的问题。

使用当前的updateCard()方法,该卡会添加到来源列表中,然后将新卡设置为default_source。这种方法的结果有两个结果:

  1. 虽然最近的卡设置为default_source

  2. ,但会将多张卡添加到列表中
  3. 使用此方法更新信用卡时,如果有任何未付款的发票(即past_due状态的发票),则不会自动向其收费。

  4. 为了让条带重新尝试在past_due状态的所有发票上向客户收费,需要传递source参数。所以我创建了一个类似这样的新方法:

    public function replaceCard($token)
        {
            $customer = $this->asStripeCustomer();
            $token = StripeToken::retrieve($token, ['api_key' => $this->getStripeKey()]);
            // If the given token already has the card as their default source, we can just
            // bail out of the method now. We don't need to keep adding the same card to
            // a model's account every time we go through this particular method call.
            if ($token->card->id === $customer->default_source) {
                return;
            }
            //  Just pass `source: tok_xxx` in order for the previous default source 
            // to be deleted and any unpaid invoices to be retried
            $customer->source = $token;
            $customer->save();
            // Next we will get the default source for this model so we can update the last
            // four digits and the card brand on the record in the database. This allows
            // us to display the information on the front-end when updating the cards.
            $source = $customer->default_source
                        ? $customer->sources->retrieve($customer->default_source)
                        : null;
            $this->fillCardDetails($source);
            $this->save();
        }
    

    我为此添加创建了Pull request。由于直接编辑Billable文件以进行任何更改不是一个好主意,如果没有将其添加到Cashier,那么您可以在Controller文件中使用以下内容直接从那里执行:

    $user = Auth::User();
    
    $customer = $user->asStripeCustomer();
    $token = StripeToken::retrieve($token, ['api_key' => config('services.stripe.secret')]);
    
    if (!($token->card->id === $customer->default_source)) {
      $customer->source = $token;
      $customer->save();
      // Next synchronise user's card details and update the database
      $user->updateCardFromStripe();
    }