Files
api/services/nginx/app/tests/Unit/Orders/OrdersRouteStripePaymentIntentLifecycleWiringTest.php
T
Jeppe B 30d860fdef Retire payment links and capture card payments (#327)
## Summary

- retire Stripe hosted payment-link creation routes used by POS and
order management
- automatically capture authorized payment intents rather than requiring
a separate manual capture action
- preserve ordinary terminal payment and payment-intent lifecycle
behavior
- add API and wiring regressions for payment-link retirement and
automatic capture

Paired frontend change:
https://github.com/copenhagentruckwash/pleno-vue/pull/233

## Verification

- focused backend unit suite: 2 tests, 36 assertions passed
- PHP syntax checks passed
- paired frontend unit and Playwright suites passed locally
- full required GitHub runner suites are required before this task may
enter Review or merge

## Security and operational notes

- no credentials, terminal secrets, or payment data are added
- no live Stripe account or physical terminal was exercised locally
- automatic merge remains gated on both paired PRs having passing
required checks and current branches
2026-07-27 19:09:37 +02:00

39 lines
2.7 KiB
PHP

<?php
it('wires mobile stripe payment intent routes to normalized lifecycle handling', function (): void {
$routeFile = dirname(__DIR__, 3) . '/routes/ordersRoute.php';
$content = file_get_contents($routeFile);
expect($content)->not->toBeFalse();
$start = strpos($content, "\$this->post('/orders/module/stripe/payment_intent'");
$end = strpos($content, "\$this->post('/orders/module/stripe/debug/simulate_payment'");
expect($start)->not->toBeFalse();
expect($end)->not->toBeFalse();
$stripeSection = substr($content, (int)$start, (int)$end - (int)$start);
expect($stripeSection)->toContain('buildStripePaymentIntentResponse(');
expect($stripeSection)->toContain('$expectedPaymentIntentAmount = $this->getStripePaymentIntentAmountForOrder($order, $tax_percentage ?? 0);');
expect($stripeSection)->toContain('isStripePaymentIntentReusable($storedPaymentIntent)');
expect($stripeSection)->toContain('doesStripePaymentIntentMatchOrder($storedPaymentIntent, $expectedPaymentIntentAmount, $tax_percentage ?? 0)');
expect($stripeSection)->toContain('$stripe->payment_intents->create(
$expectedPaymentIntentAmount,');
expect($stripeSection)->toContain("'reused' => true");
expect($stripeSection)->toContain("'message' => 'No active payment intent for this order.'");
expect($stripeSection)->toContain("'message' => 'Payment intent cleared successfully.'");
expect($stripeSection)->toContain("Stored payment intent is stale. Start the payment again.");
expect($stripeSection)->toContain("Payment intent has already been captured.");
expect($stripeSection)->toContain("Payment intent was cancelled. Start the payment again.");
expect($stripeSection)->toContain("Payment intent is not ready to capture.");
expect($stripeSection)->toContain("captureApprovedStripePaymentIntent(\$order, \$stripePaymentIntents, \$stripe)");
expect(substr_count($stripeSection, 'captureApprovedStripePaymentIntent('))->toBeGreaterThanOrEqual(4);
expect($stripeSection)->not->toContain("Order does not have a payment intent");
expect($content)->toContain('private function doesStripePaymentIntentMatchOrder(object $paymentIntent, int $expectedAmount, ?int $tax_percentage): bool');
expect($content)->toContain('private function captureApprovedStripePaymentIntent(orders_o $order, stripe_payment_intents_o $stripePaymentIntents, stripe $stripe): object');
expect($content)->toContain("paidWithStripe(\$paymentIntent->id);");
expect($content)->toContain('!isset($paymentIntent->amount) || (int)$paymentIntent->amount !== $expectedAmount');
expect($content)->toContain("\$storedTaxPercentage = \$metadata['tax_percentage'] ?? null;");
});