set('admin_access.secrets_key', 'base64:'.base64_encode(random_bytes(32))); withStripeSecret(); Http::preventStrayRequests(); }); it('asks Stripe for a setup intent bound to the customer', function () { Http::fake(['api.stripe.com/v1/setup_intents' => Http::response([ 'id' => 'seti_1', 'client_secret' => 'seti_1_secret_abc', ])]); $intent = app(HttpStripeClient::class)->createSetupIntent('cus_42'); expect($intent['client_secret'])->toBe('seti_1_secret_abc'); Http::assertSent(fn ($request) => $request['customer'] === 'cus_42' // Off-session, weil die nächste Abbuchung ohne den Kunden läuft. Ohne // dieses Feld verlangt Stripe bei jeder Verlängerung eine Freigabe, // die zu dem Zeitpunkt niemand geben kann — genau der Fall, der in die // Mahnung führt. && $request['usage'] === 'off_session'); }); it('makes a payment method the customer default', function () { Http::fake(['api.stripe.com/v1/customers/cus_42' => Http::response(['id' => 'cus_42'])]); app(HttpStripeClient::class)->setDefaultPaymentMethod('cus_42', 'pm_9'); // Der Kern: eine Karte zu hinterlegen genügt nicht, sie muss die VORGABE // werden. Sonst bucht Stripe weiter mit der kaputten ab, und der Kunde // steht im nächsten Monat wieder in der Mahnung. Http::assertSent(fn ($request) => $request->method() === 'POST' && $request['invoice_settings']['default_payment_method'] === 'pm_9'); }); it('reads back the card in force', function () { Http::fake(['api.stripe.com/v1/customers/cus_42*' => Http::response([ 'id' => 'cus_42', 'invoice_settings' => ['default_payment_method' => [ 'id' => 'pm_9', 'card' => ['brand' => 'visa', 'last4' => '4242', 'exp_month' => 5, 'exp_year' => 2031], ]], ])]); $card = app(HttpStripeClient::class)->defaultPaymentMethod('cus_42'); expect($card['last4'])->toBe('4242') ->and($card['brand'])->toBe('visa') ->and($card['exp_year'])->toBe(2031); }); it('answers null when no card is on file, rather than half an array', function () { // Ein Kunde, der über eine Rechnung bezahlt hat, ohne eine Karte zu // hinterlegen, ist der Normalfall — nicht der Ausnahmefall. Http::fake(['api.stripe.com/v1/customers/cus_42*' => Http::response([ 'id' => 'cus_42', 'invoice_settings' => ['default_payment_method' => null], ])]); expect(app(HttpStripeClient::class)->defaultPaymentMethod('cus_42'))->toBeNull(); });