74 lines
3.1 KiB
PHP
74 lines
3.1 KiB
PHP
<?php
|
|
|
|
use App\Services\Stripe\HttpStripeClient;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
/**
|
|
* Der Stripe-Client konnte bislang alles außer dem, was ein Kunde selbst
|
|
* braucht: seine Karte tauschen. Ohne diese drei Aufrufe mahnt jeder spätere
|
|
* Mahnlauf jemanden, der die Ursache gar nicht beheben kann.
|
|
*/
|
|
beforeEach(function () {
|
|
// Der Secret Key ist ein STRIKTER Tresoreintrag — `config()` greift dort
|
|
// bewusst nicht, damit ein Testkauf bei fehlendem Testschlüssel nicht
|
|
// still den Live-Schlüssel benutzt. Also die vorhandene Vorrichtung.
|
|
config()->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();
|
|
});
|