diff --git a/app/Domains/Catalog/Services/StockReservationService.php b/app/Domains/Catalog/Services/StockReservationService.php index c52f4ea..96d931b 100644 --- a/app/Domains/Catalog/Services/StockReservationService.php +++ b/app/Domains/Catalog/Services/StockReservationService.php @@ -343,9 +343,9 @@ class StockReservationService }); } - public function refreshForPurchase(Purchase $purchase, ?Carbon $expiresAt): void + public function clearExpirationForReview(Purchase $purchase): void { - DB::transaction(function () use ($purchase, $expiresAt): void { + DB::transaction(function () use ($purchase): void { /** @var Purchase $purchase */ $purchase = Purchase::query()->lockForUpdate()->findOrFail($purchase->getKey()); if ($purchase->stock_reservation_id === null) { @@ -363,7 +363,7 @@ class StockReservationService throw new StockReservationExpiredException; } - $reservation->update(['expires_at' => $expiresAt]); + $reservation->update(['expires_at' => null]); }); } diff --git a/app/Domains/Purchase/Controllers/PurchaseController.php b/app/Domains/Purchase/Controllers/PurchaseController.php index 118baa5..b175a48 100644 --- a/app/Domains/Purchase/Controllers/PurchaseController.php +++ b/app/Domains/Purchase/Controllers/PurchaseController.php @@ -93,7 +93,6 @@ class PurchaseController extends Controller PaymentIntentRequest $request, Tenant $tenant, Purchase $compra, - CheckoutService $checkoutService, PurchaseStateGuard $purchaseState, ): JsonResponse { $compra = $this->resolveScopedPurchase($tenant, $request->user()->id, $compra); @@ -103,7 +102,6 @@ class PurchaseController extends Controller : null; $updated = DB::transaction(function () use ( - $checkoutService, $compra, $method, $purchaseState, @@ -142,12 +140,6 @@ class PurchaseController extends Controller $purchaseUpdate['transfer_payer_dni'] = $transferPayerDni; } $purchase->update($purchaseUpdate); - $checkoutService->refreshReservationExpiration( - $purchase, - now()->addMinutes( - max(1, (int) config("purchase.payment_expiration_minutes.{$method}", 30)), - ), - ); return true; }); diff --git a/app/Domains/Purchase/Services/Checkout/CompleteCheckoutService.php b/app/Domains/Purchase/Services/Checkout/CompleteCheckoutService.php index d827020..61a4062 100644 --- a/app/Domains/Purchase/Services/Checkout/CompleteCheckoutService.php +++ b/app/Domains/Purchase/Services/Checkout/CompleteCheckoutService.php @@ -70,7 +70,7 @@ class CompleteCheckoutService $purchase->update([ 'status' => Purchase::STATUS_IN_REVIEW, ]); - $this->reservations->refreshForPurchase($purchase, null); + $this->reservations->clearExpirationForReview($purchase); return $this->loadPurchase($purchase); }); diff --git a/app/Domains/Purchase/Services/CheckoutService.php b/app/Domains/Purchase/Services/CheckoutService.php index c7e7bea..882e235 100644 --- a/app/Domains/Purchase/Services/CheckoutService.php +++ b/app/Domains/Purchase/Services/CheckoutService.php @@ -2,14 +2,12 @@ namespace App\Domains\Purchase\Services; -use App\Domains\Catalog\Services\StockReservationService; use App\Domains\Purchase\Models\Purchase; use App\Domains\Purchase\Services\Checkout\CompleteCheckoutService; use App\Domains\Purchase\Services\Checkout\EditCheckoutService; use App\Domains\Purchase\Services\Checkout\ReleaseCheckoutService; use App\Domains\Purchase\Services\Checkout\StartCheckoutService; use App\Domains\Tenant\Models\Tenant; -use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; /** @@ -24,7 +22,6 @@ class CheckoutService private readonly EditCheckoutService $editor, private readonly CompleteCheckoutService $completer, private readonly ReleaseCheckoutService $releaser, - private readonly StockReservationService $reservations, ) {} /** @param array $purchaseData */ @@ -78,9 +75,4 @@ class CheckoutService { return $this->releaser->expire($purchase); } - - public function refreshReservationExpiration(Purchase $purchase, ?Carbon $expiresAt): void - { - $this->reservations->refreshForPurchase($purchase, $expiresAt); - } } diff --git a/config/purchase.php b/config/purchase.php index 53037a9..6c3b101 100644 --- a/config/purchase.php +++ b/config/purchase.php @@ -2,10 +2,4 @@ return [ 'checkout_expiration_minutes' => (int) env('PURCHASE_CHECKOUT_EXPIRATION_MINUTES', 30), - - 'payment_expiration_minutes' => [ - 'qr' => (int) env('PURCHASE_QR_EXPIRATION_MINUTES', 15), - 'telepagos' => (int) env('PURCHASE_TELEPAGOS_EXPIRATION_MINUTES', 30), - 'transfer' => (int) env('PURCHASE_TRANSFER_EXPIRATION_MINUTES', 1440), - ], ]; diff --git a/tests/Feature/Integration/TelepagosWebhookTest.php b/tests/Feature/Integration/TelepagosWebhookTest.php index e588810..38b607c 100644 --- a/tests/Feature/Integration/TelepagosWebhookTest.php +++ b/tests/Feature/Integration/TelepagosWebhookTest.php @@ -60,9 +60,9 @@ class TelepagosWebhookTest extends TestCase ->assertJsonValidationErrors(['transfer_payer_dni']); } - public function test_transfer_payment_intent_persists_transfer_payer_dni_without_replacing_customer_dni(): void + public function test_transfer_payment_intent_persists_data_without_extending_checkout_expiration(): void { - config()->set('purchase.payment_expiration_minutes.transfer', 60); + config()->set('purchase.checkout_expiration_minutes', 30); $now = now()->startOfSecond(); $this->travelTo($now); @@ -106,7 +106,7 @@ class TelepagosWebhookTest extends TestCase $this->assertDatabaseHas('stock_reservations', [ 'id' => $purchase->stock_reservation_id, 'status' => 'active', - 'expires_at' => $now->copy()->addMinutes(60)->toDateTimeString(), + 'expires_at' => $now->copy()->addMinutes(30)->toDateTimeString(), ]); $this->travelBack(); diff --git a/tests/Feature/Purchase/StorePurchaseTest.php b/tests/Feature/Purchase/StorePurchaseTest.php index 054221d..8a667e5 100644 --- a/tests/Feature/Purchase/StorePurchaseTest.php +++ b/tests/Feature/Purchase/StorePurchaseTest.php @@ -796,12 +796,18 @@ class StorePurchaseTest extends TestCase public function test_it_updates_customer_data_for_a_pending_payment_purchase(): void { + config()->set('purchase.checkout_expiration_minutes', 30); + $now = now()->startOfSecond(); + $this->travelTo($now); + $this->createTenant('sonder', 'Sonder', 'sonder.com.ar'); $user = User::factory()->create(); $variant = $this->createVariantForTenant('sonder', 10, '50.00'); $purchase = $this->createCheckoutPurchase($user, 'sonder', $variant, 1); $purchase->update(['status' => Purchase::STATUS_PENDING_PAYMENT]); + $this->travel(10)->minutes(); + $this->actingAs($user, 'sanctum') ->patchJson("/api/tenants/sonder/compras/{$purchase->id}/customer-data", [ 'dni' => '987654321', @@ -818,6 +824,12 @@ class StorePurchaseTest extends TestCase 'status' => Purchase::STATUS_PENDING_PAYMENT, 'dni' => '987654321', ]); + $this->assertDatabaseHas('stock_reservations', [ + 'id' => $purchase->stock_reservation_id, + 'expires_at' => $now->copy()->addMinutes(30)->toDateTimeString(), + ]); + + $this->travelBack(); } public function test_checkout_items_are_immutable_and_editing_routes_are_unavailable(): void