I've narrowed down the problem a little. The docs claim that swapAndInvoice should throw the IncompletePayment exception, but as far as I can tell it never does that.
swapAndInvoice eventually calls this code in vendor/laravel/cashier/src/Subscription.php
public function invoice(array $options = [])
{
try {
return $this->user->invoice(array_merge($options, ['subscription' => $this->stripe_id]));
} catch (IncompletePayment $exception) {
// Set the new Stripe subscription status immediately when payment fails...
$this->fill([
'stripe_status' => $exception->payment->invoice->subscription->status,
])->save();
throw $exception;
}
}
This all looks like a good idea... But I don't see anywhere that the function $this->user->invoice() (defined in Billable.php) can throw an IncompletePayment exception.
Am I on the right track?