where('tenant_codigo', $tenant->codigo) ->where('user_id', $request->user()->id) ->when($request->query('status'), function ($query, $status) { $query->where('status', $status); }) ->latest() ->paginateFromRequest() )->response(); } public function store(StorePurchaseRequest $request, Tenant $tenant, CheckoutService $checkoutService): JsonResponse { $data = $request->validated(); $purchase = $checkoutService->startCheckout( $tenant, $request->user()->id, $data ); return PurchaseResource::make($purchase)->response()->setStatusCode(201); } public function show(Request $request, Tenant $tenant, Purchase $compra): PurchaseResource { $compra = $this->resolveScopedPurchase($tenant, $request->user()->id, $compra); $compra->loadMissing(['items', 'cart.items']); $this->loadBuyables($compra->items); if ($compra->cart !== null) { $this->loadBuyables($compra->cart->items); } return PurchaseResource::make($compra); } public function paymentIntent(PaymentIntentRequest $request, Tenant $tenant, Purchase $compra): JsonResponse { $compra = $this->resolveScopedPurchase($tenant, $request->user()->id, $compra); $method = $request->validated('method'); $totalAmount = $compra->calculateCurrentTotalAmount(); $purchaseUpdate = [ 'payment_method' => $method, 'status' => Purchase::STATUS_PENDING_PAYMENT, 'total' => $totalAmount, ]; if ($method === 'transfer') { $purchaseUpdate['transfer_payer_dni'] = preg_replace('/\D+/', '', (string) $request->validated('transfer_payer_dni')); } $compra->update($purchaseUpdate); if ($method === 'transfer') { $telepagosService = new TelepagosIntegrationService; $telepagosService->forTenant($tenant->codigo); try { $accountInfo = $telepagosService->getAccountInfo(); return response()->json([ 'payment_method' => 'transfer', 'transfer_data' => [ 'titular' => $accountInfo['holder'] ?? null, 'cvu' => $accountInfo['cvu'] ?? null, 'alias' => $accountInfo['alias'] ?? null, 'cuit' => $accountInfo['cuit'] ?? null, 'entidad' => $accountInfo['entity'] ?? 'Telepagos S.A.', ], ]); } catch (\Exception $e) { return response()->json([ 'message' => 'Error getting account info: '.$e->getMessage(), ], 500); } } if ($method === 'qr') { $telepagosService = new TelepagosIntegrationService; $telepagosService->forTenant($tenant->codigo); try { Log::info("Generating QR for purchase ID: {$compra->id}, amount: {$totalAmount}"); $qrResponse = $telepagosService->generateQr( $totalAmount, 'Compra', "Compra #{$compra->id}" ); $telepagosQr = $compra->telepagosQr()->create([ 'qr_order_id' => (string) ($qrResponse['qr_order_id'] ?? ''), 'qr_code' => $qrResponse['qr_code'] ?? '', ]); } catch (\Exception $e) { return response()->json([ 'message' => 'Error generating QR: '.$e->getMessage(), ], 500); } return response()->json([ 'payment_method' => 'qr', 'qr_data' => [ 'qr_code' => $telepagosQr->qr_code, 'qr_order_id' => $telepagosQr->qr_order_id, ], ]); } return response()->json([ 'message' => 'Invalid payment method.', ], 400); } public function complete(Request $request, Tenant $tenant, Purchase $compra, CheckoutService $checkoutService): PurchaseResource { $compra = $this->resolveScopedPurchase($tenant, $request->user()->id, $compra); return PurchaseResource::make( $checkoutService->completePurchase($compra) ); } protected function resolveScopedPurchase(Tenant $tenant, int $userId, Purchase $purchase): Purchase { if ($purchase->tenant_codigo !== $tenant->codigo || $purchase->user_id !== $userId) { throw new NotFoundHttpException('Purchase not found for tenant.'); } return $purchase; } /** * @return list */ protected function loadBuyables(Collection $items): void { $items->load([ 'buyable' => function (MorphTo $morphTo): void { $morphTo->morphWith([ ProductVariant::class => [ 'product', 'definitions.productAttribute.attribute', 'attachments', ], Bundle::class => ['items.variant'], ]); }, ]); } }