providerForNewCheckout()) ->toBe(PaymentProvider::Payone); }); it('reads the active provider for new checkouts from the settings switch', function () { Setting::setContentBySlug(PaymentProviderManager::SETTING_SLUG, 'stripe', 'text'); expect(app(PaymentProviderManager::class)->providerForNewCheckout()) ->toBe(PaymentProvider::Stripe); }); it('falls back to payone for unknown switch values', function () { Setting::setContentBySlug(PaymentProviderManager::SETTING_SLUG, 'klarna', 'text'); expect(app(PaymentProviderManager::class)->providerForNewCheckout()) ->toBe(PaymentProvider::Payone); }); // --- Bestandsvorgänge: Anbieter aus der Spalte, schalterunabhängig --- it('backfills existing abos with payone as their provider', function () { $abo = makeMeAbo(); expect($abo->fresh()->payment_provider)->toBe('payone'); }); it('resolves the provider of an existing abo from its column even when the switch says stripe', function () { Setting::setContentBySlug(PaymentProviderManager::SETTING_SLUG, 'stripe', 'text'); $abo = makeMeAbo(); expect(app(PaymentProviderManager::class)->providerFor($abo->fresh())) ->toBe(PaymentProvider::Payone); }); it('resolves a stripe abo and a stripe shopping payment from their columns', function () { $abo = makeMeAbo(); $abo->update(['payment_provider' => 'stripe']); $payment = new ShoppingPayment(['payment_provider' => 'stripe']); $manager = app(PaymentProviderManager::class); expect($manager->providerFor($abo->fresh()))->toBe(PaymentProvider::Stripe) ->and($manager->providerFor($payment))->toBe(PaymentProvider::Stripe); }); // --- Gateway-Auflösung --- it('resolves the payone gateway adapter for the payone provider', function () { $gateway = app(PaymentProviderManager::class)->gateway(PaymentProvider::Payone); expect($gateway)->toBeInstanceOf(PayoneGateway::class) ->and($gateway)->toBeInstanceOf(PaymentGatewayInterface::class) ->and($gateway->provider())->toBe(PaymentProvider::Payone); }); it('resolves the stripe gateway adapter for the stripe provider', function () { $gateway = app(PaymentProviderManager::class)->gateway(PaymentProvider::Stripe); expect($gateway)->toBeInstanceOf(StripeGateway::class) ->and($gateway)->toBeInstanceOf(PaymentGatewayInterface::class) ->and($gateway->provider())->toBe(PaymentProvider::Stripe); }); // --- AboChargeResult-Mapping --- it('maps an approved payone result to a successful charge result', function () { $result = AboChargeResult::fromPayoneResult( PayonePaymentResult::fromResponse(['status' => 'APPROVED', 'txid' => 'tx-123']) ); expect($result->success)->toBeTrue() ->and($result->provider)->toBe(PaymentProvider::Payone) ->and($result->status)->toBe('APPROVED') ->and($result->transactionId)->toBe('tx-123') ->and($result->errorMessage)->toBeNull(); }); it('maps a declined payone result with its error messages', function () { $result = AboChargeResult::fromPayoneResult(PayonePaymentResult::fromResponse([ 'status' => 'ERROR', 'errormessage' => 'Card declined', 'customermessage' => 'Bitte andere Karte verwenden.', ])); expect($result->success)->toBeFalse() ->and($result->status)->toBe('ERROR') ->and($result->errorMessage)->toBe('Card declined') ->and($result->customerMessage)->toBe('Bitte andere Karte verwenden.'); }); // --- PayoneGateway delegiert 1:1 an den bestehenden Service --- it('delegates abo charges to the payone payment service', function () { $abo = new UserAbo; $order = new ShoppingOrder; $shoppingUser = new ShoppingUser; $service = Mockery::mock(PayonePaymentService::class); $service->shouldReceive('chargeAbo') ->once() ->with($abo, $order, $shoppingUser, 1999, 'EUR') ->andReturn(PayonePaymentResult::fromResponse(['status' => 'APPROVED', 'txid' => 'tx-9'])); $result = (new PayoneGateway($service))->chargeAbo($abo, $order, $shoppingUser, 1999, 'EUR'); expect($result->success)->toBeTrue() ->and($result->transactionId)->toBe('tx-9'); }); // --- Cron-Dispatch: Stripe-Abos laufen NICHT durch den PAYONE-Pfad (S4.4) --- it('routes stripe abos in the cron to the stripe gateway instead of payone', function () { $abo = makeMeAbo(); $abo->update(['payment_provider' => 'stripe']); $userOrder = new UserMakeOrder($abo->fresh()); $reflection = new ReflectionClass($userOrder); foreach (['shopping_user' => new ShoppingUser, 'shopping_order' => new ShoppingOrder] as $property => $value) { $prop = $reflection->getProperty($property); $prop->setValue($userOrder, $value); } // Ohne gespeicherte Stripe-PaymentMethod liefert das Gateway ein // ERROR-Ergebnis (kein PAYONE-Aufruf, keine Exception). $response = $userOrder->makePayment(); expect($response['status'])->toBe('ERROR') ->and($response['provider'])->toBe('stripe') ->and($response['customermessage'])->toBe(__('payment.stripe_abo_payment_method_missing')); });