Laravel Cashier повторно пытается выставить отложенный счет после обновления карты

Я использую Laravel 5.3 с Cashier. Если клиент обновляет данные своей карты, как я могу проверить наличие незавершенного счета и попросить Stripe повторить попытку списания средств с новой карты? На данный момент я установил настройки для попыток в панели управления Stripe. Но насколько я понимаю, Stripe не пытается автоматически взимать плату с клиента, если он обновил данные своей карты, и ожидает даты следующей попытки, чтобы повторить попытку. Вот почему я хочу вручную попытаться списать с клиента счет по незавершенному счету, как только он обновит свою карту. Я читал документацию по кассе и страницу на Github, но этот случай там не рассматривается.

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

Может кто-нибудь мне помочь, пожалуйста.


person Neel    schedule 02.01.2017    source источник


Ответы (1)


После тестирования и разговора со службой поддержки Stripe я обнаружил проблему с текущим методом updateCard(), используемым в Laravel Cashier.

При использовании текущего метода updateCard() карта добавляется в список источников, а затем устанавливает новую карту как default_source. результат этого метода имеет 2 результата:

  1. В список добавляется несколько карточек, хотя последняя установлена ​​как default_source.

  2. При обновлении карты с помощью этого метода, если есть какие-либо неоплаченные счета (т.е. счета в состоянии past_due), они не списываются автоматически.

Чтобы Stripe повторил попытку списания средств с покупателя по всем счетам в состоянии 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();
    }

Я создал запрос на извлечение для этого добавления. Поскольку редактирование файла Billable напрямую для любых изменений не является хорошей идеей, если он не добавляется в Cashier, вы можете использовать следующее в файле контроллера, чтобы сделать это прямо оттуда:

$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();
}
person Neel    schedule 10.01.2017
comment
это работает с laravel 5.7? Я хочу списать оплату сразу после обновления данных карты - person Shankar S Bavan; 08.02.2021