stdout:
Success. Updated the following files:
M /Users/fabianwesner/Herd/shop/specs/progress.md

type: update

unified_diff:
@@ -9,3 +9,3 @@
 - Status: in progress
-- Active slice: Phase 5 - remaining order API surfaces
+- Active slice: Phase 6 - remaining admin customer/content/settings surfaces
 - Started from: Laravel Livewire/Fortify starter kit with no shop domain tables or models present
@@ -29,6 +29,6 @@
 | Database schema | `specs/01-DATABASE-SCHEMA.md` | partial | Phase 1 tenancy/auth tables, Phase 2 catalog tables, Phase 3 theme/content/navigation tables, Phase 4 cart/checkout/pricing tables, and Phase 5 order/payment/fulfillment tables are implemented: customer_addresses, orders, order_lines, payments, refunds, fulfillments, fulfillment_lines. Search/analytics/app tables are still missing. |
-| Routes/API | `specs/02-API-ROUTES.md` | partial | Phase 1 auth routes plus catalog/cart/order UI routes exist: `/`, `/collections`, `/collections/{handle}`, `/products/{handle}`, `/cart`, `/checkout`, `/checkout/confirmation/{order}`, `/search`, `/pages/{handle}`, `/account`, `/account/orders/{order}`, `/admin/products`, `/admin/products/create`, `/admin/products/{product}/edit`, `/admin/collections`, `/admin/collections/create`, `/admin/collections/{collection}/edit`, `/admin/inventory`, `/admin/orders`, `/admin/orders/{order}`. Storefront REST API now includes cart line CRUD and checkout address/shipping/discount/payment-method selection under `/api/storefront/v1`. Storefront search/suggest, analytics, order lookup/payment processing APIs, and admin REST APIs are still missing. |
+| Routes/API | `specs/02-API-ROUTES.md` | partial | Phase 1 auth routes plus catalog/cart/order UI routes exist: `/`, `/collections`, `/collections/{handle}`, `/products/{handle}`, `/cart`, `/checkout`, `/checkout/confirmation/{order}`, `/search`, `/pages/{handle}`, `/account`, `/account/orders/{order}`, `/admin/products`, `/admin/products/create`, `/admin/products/{product}/edit`, `/admin/collections`, `/admin/collections/create`, `/admin/collections/{collection}/edit`, `/admin/inventory`, `/admin/orders`, `/admin/orders/{order}`. Storefront REST API now includes cart line CRUD, checkout address/shipping/discount/payment-method selection, checkout payment completion, and token-gated order lookup under `/api/storefront/v1`. Admin REST API now includes store-scoped order list/detail, fulfillment creation, and refund creation under `/api/admin/v1/stores/{store}`. Storefront search/suggest, analytics, app/webhook APIs, and broader admin REST surfaces are still missing. |
 | Admin UI | `specs/03-ADMIN-UI.md` | partial | Flux/Livewire admin catalog and operations shell now includes product index/form, collection index/form, inventory list, order index/detail, order search/status filters, bank-transfer payment confirmation, refund creation, fulfillment creation, and shipment status transitions with auth protection and store scoping. Customer/content/settings admin pages are still missing. |
 | Storefront UI | `specs/04-STOREFRONT-UI.md` | partial | Storefront layout, home, collections index/detail, product detail, search, breadcrumbs, price display, product cards, DB-backed pages, seeded navigation menus, cached theme settings, product add-to-cart persistence, cart drawer, cart page with discount and shipping estimates, checkout address/shipping/discount/payment-selection/order-submission UI, order confirmation, and customer order list/detail views render seeded and runtime data. |
-| Business logic | `specs/05-BUSINESS-LOGIC.md` | partial | `ResolveStore`, `BelongsToStore`, `StoreScope`, role checks, customer guard provider, catalog product lifecycle transitions, SKU uniqueness, variant matrix rebuilding, inventory reserve/release/commit/restock, automatic variant inventory, variant option mapping, media resize/cleanup job, `CartService`, `DiscountService`, `ShippingCalculator`, `TaxCalculator`, `PricingEngine`, checkout transitions through completion, checkout expiration, abandoned cart cleanup, session cart lookup, cart discount handoff to checkout, customer login cart merge, product add-to-cart mutations, `PaymentService`, mock PSP, idempotent order creation, checkout UI order submission, session/customer-gated order confirmation, customer order-history scoping, admin order action orchestration, `RefundService`, `FulfillmentService`, bank-transfer payment confirmation, and unpaid bank-transfer cancellation are implemented. |
+| Business logic | `specs/05-BUSINESS-LOGIC.md` | partial | `ResolveStore`, `BelongsToStore`, `StoreScope`, role checks, customer guard provider, catalog product lifecycle transitions, SKU uniqueness, variant matrix rebuilding, inventory reserve/release/commit/restock, automatic variant inventory, variant option mapping, media resize/cleanup job, `CartService`, `DiscountService`, `ShippingCalculator`, `TaxCalculator`, `PricingEngine`, checkout transitions through completion, checkout expiration, abandoned cart cleanup, session cart lookup, cart discount handoff to checkout, customer login cart merge, product add-to-cart mutations, `PaymentService`, mock PSP, idempotent order creation, checkout UI/API order submission, session/customer/token-gated order confirmation and lookup, customer order-history scoping, admin order UI/API action orchestration, `RefundService`, `FulfillmentService`, bank-transfer payment confirmation, and unpaid bank-transfer cancellation are implemented. |
 | Auth/security | `specs/06-AUTH-AND-SECURITY.md` | partial | Admin Livewire login/logout, customer guard/provider, customer login/register, login rate limiting, session hardening, and resource policies implemented. Customer password reset and Sanctum token auth still missing. |
@@ -36,3 +36,3 @@
 | Browser E2E plan | `specs/08-PLAYWRIGHT-E2E-PLAN.md` | partial | Manual Playwright MCP smoke coverage has verified storefront catalog browsing, product detail, add-to-cart, cart drawer/page, checkout through order completion, order confirmation, customer order list/detail, search, DB-backed content pages, seeded navigation, admin product/collection/inventory/order pages, admin fulfillment creation/shipping/delivery, and auth flows without console warnings/errors on successful pages. Automated browser tests are still missing. |
-| Roadmap phases | `specs/09-IMPLEMENTATION-ROADMAP.md` | in progress | Phase 1 foundation, Phase 2 catalog data/UI, Phase 3 theme/content/navigation data with storefront consumption, Phase 4 cart/checkout/pricing backend foundation, Phase 4 storefront cart/checkout UI through `payment_selected`, the Phase 4 cart/checkout REST API surface, cart-page estimates, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, Phase 5 storefront order completion/customer order surfaces, and Phase 5 admin order management are implemented. Remaining order APIs are next. |
+| Roadmap phases | `specs/09-IMPLEMENTATION-ROADMAP.md` | in progress | Phase 1 foundation, Phase 2 catalog data/UI, Phase 3 theme/content/navigation data with storefront consumption, Phase 4 cart/checkout/pricing backend foundation, Phase 4 storefront cart/checkout UI through `payment_selected`, the Phase 4 cart/checkout REST API surface, cart-page estimates, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, Phase 5 storefront order completion/customer order surfaces, Phase 5 admin order management, and Phase 5 order API surfaces are implemented. Phase 6 remaining admin dashboard/customer/content/settings surfaces are next. |

@@ -139,2 +139,12 @@
 - 2026-05-04: Playwright MCP verified a seeded storefront checkout order appears in `http://shop.test/admin/orders`, `http://shop.test/admin/orders/1` shows line items/payments/totals/refund and fulfillment controls, and admin fulfillment creation, mark shipped, and mark delivered work with no current console warnings/errors. `browser_logs` only returned older May 3 auth-page warnings from a previously fixed issue.
+- 2026-05-04: `mcp__laravel_boost__.application_info` reconfirmed Laravel 12.51.0, PHP 8.4, Livewire 4.1.4, Flux 2.12.0, Pest 4.3.2, and SQLite before the order API slice.
+- 2026-05-04: `mcp__laravel_boost__.search_docs` consulted Laravel 12 JSON API resources, form requests, validation, route model binding, auth/rate limiting, and Pest JSON testing docs before the order API changes.
+- 2026-05-04: `php artisan make:controller`, `php artisan make:request`, `php artisan make:resource`, `php artisan make:class`, and `php artisan make:test --pest` created the storefront/admin order API controllers, requests, resources, support token class, and tests.
+- 2026-05-04: `vendor/bin/pint --dirty --format agent` passed after the order API changes.
+- 2026-05-04: `php artisan test --compact tests/Feature/Api/StorefrontOrderApiTest.php tests/Feature/Api/AdminOrderApiTest.php` passed: 5 tests, 38 assertions.
+- 2026-05-04: `php artisan test --compact tests/Feature/Api tests/Feature/Cart tests/Feature/Checkout tests/Feature/Orders tests/Feature/Payments` passed after the order API changes: 43 tests, 278 assertions.
+- 2026-05-04: `php artisan route:list --path=api/storefront/v1 --except-vendor` showed 14 storefront API routes including checkout payment completion and token-gated order lookup.
+- 2026-05-04: `php artisan route:list --path=api/admin/v1 --except-vendor` showed 4 admin order API routes for order list/detail, fulfillment creation, and refund creation.
+- 2026-05-04: `php artisan test --compact` passed after the order API changes: 131 tests, 628 assertions.
+- 2026-05-04: `php artisan migrate:fresh --seed --no-interaction` passed after the order API changes.

@@ -166,2 +176,4 @@
 - Admin order actions deliberately delegate to `OrderService`, `RefundService`, and `FulfillmentService` so UI validation cannot bypass payment, refund, fulfillment, or inventory guards.
+- Storefront order lookup uses a deterministic HMAC access token derived from store/order identity so confirmation links can be token-gated without adding a new runtime column.
+- Admin order API routes currently use the existing session `auth` middleware and store-user membership checks because Sanctum is not installed yet.

@@ -177,3 +189,3 @@
 - Theme/page/navigation admin management UI is still missing even though the Phase 3 data layer, seeders, services, and storefront consumption exist.
-- Storefront search/suggest, analytics event, order lookup, checkout payment processing, and admin REST API endpoints are still missing.
+- Storefront search/suggest, analytics event capture, app/webhook APIs, and broader admin REST endpoints outside order management are still missing.
 - Automated browser tests from Spec 08 are still missing; current browser coverage is manual Playwright MCP smoke verification.
@@ -184,2 +196,2 @@

-Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer order views, and admin order management are implemented, with known auth/token, media UI, theme admin UI, remaining API, browser-test, and database CHECK constraint gaps tracked above.
+Not complete. Phase 1 foundation, Phase 2 catalog data/UI surfaces, Phase 3 storefront theme/content/navigation data, the Phase 4 cart/checkout/pricing backend foundation, cart/checkout storefront UI through order completion, cart-page estimates, cart/checkout REST APIs, Phase 5 order/payment backend foundation, Phase 5 refund/fulfillment services, customer order views, admin order management, and order API surfaces are implemented, with known auth/token, media UI, dashboard/customer/content/settings admin UI, search/analytics/app/webhook API, browser-test, and database CHECK constraint gaps tracked above.


output: {"output":"Success. Updated the following files:\nM /Users/fabianwesner/Herd/shop/specs/progress.md\n","metadata":{"exit_code":0,"duration_seconds":0.0}}


message: The progress record now matches the API surface that was added. I’m doing the final repository checks before committing: worktree status, whitespace diff check, and a quick diff summary.

phase: commentary


type: message

role: assistant

text: The progress record now matches the API surface that was added. I’m doing the final repository checks before committing: worktree status, whitespace diff check, and a quick diff summary.


command:
/bin/zsh
-lc
git diff --check

type: unknown

cmd: git diff --check

status: completed


command:
/bin/zsh
-lc
git diff --stat

cmd: git diff --stat

aggregated_output:
 .../Api/Storefront/V1/CheckoutController.php       | 33 ++++++++++++++++++++++
 routes/api.php                                     | 16 +++++++++++
 specs/progress.md                                  | 24 ++++++++++++----
 3 files changed, 67 insertions(+), 6 deletions(-)


command:
/bin/zsh
-lc
git status --short

cmd: git status --short

aggregated_output:
 M app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
 M routes/api.php
 M specs/progress.md
?? app/Http/Controllers/Api/Admin/
?? app/Http/Controllers/Api/Storefront/V1/OrderController.php
?? app/Http/Requests/Api/Admin/
?? app/Http/Requests/Api/Storefront/V1/CompleteCheckoutPaymentRequest.php
?? app/Http/Resources/Admin/
?? app/Http/Resources/Storefront/V1/OrderResource.php
?? app/Support/OrderAccessToken.php
?? tests/Feature/Api/AdminOrderApiTest.php
?? tests/Feature/Api/StorefrontOrderApiTest.php


output:
Chunk ID: ac2e0b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 130
Output:
 M app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
 M routes/api.php
 M specs/progress.md
?? app/Http/Controllers/Api/Admin/
?? app/Http/Controllers/Api/Storefront/V1/OrderController.php
?? app/Http/Requests/Api/Admin/
?? app/Http/Requests/Api/Storefront/V1/CompleteCheckoutPaymentRequest.php
?? app/Http/Resources/Admin/
?? app/Http/Resources/Storefront/V1/OrderResource.php
?? app/Support/OrderAccessToken.php
?? tests/Feature/Api/AdminOrderApiTest.php
?? tests/Feature/Api/StorefrontOrderApiTest.php


output:
Chunk ID: 8b570d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


output:
Chunk ID: 291860
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 69
Output:
 .../Api/Storefront/V1/CheckoutController.php       | 33 ++++++++++++++++++++++
 routes/api.php                                     | 16 +++++++++++
 specs/progress.md                                  | 24 ++++++++++++----
 3 files changed, 67 insertions(+), 6 deletions(-)


message: The whitespace check is clean. I’m scanning the actual API changes once before staging so the commit only captures the intended order endpoint work.


text: The whitespace check is clean. I’m scanning the actual API changes once before staging so the commit only captures the intended order endpoint work.


cmd: git diff -- app/Http/Controllers/Api/Storefront/V1/CheckoutController.php routes/api.php


cmd: sed -n '1,240p' app/Http/Controllers/Api/Admin/V1/OrderController.php


cmd: sed -n '1,220p' app/Http/Controllers/Api/Admin/V1/OrderFulfillmentController.php


cmd: sed -n '1,220p' app/Http/Controllers/Api/Admin/V1/OrderRefundController.php


cmd: sed -n '1,200p' app/Http/Controllers/Api/Storefront/V1/OrderController.php


cmd: sed -n '1,200p' app/Support/OrderAccessToken.php


command: sed -n '1,240p' app/Http/Controllers/Api/Admin/V1/OrderController.php

OrderController.php

type: read

aggregated_output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\V1\OrderResource;
use App\Models\Order;
use App\Models\Store;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Validation\Rule;

class OrderController extends Controller
{
    public function index(Request $request, Store $store): AnonymousResourceCollection
    {
        $this->authorizeStore($request, $store);

        $validated = $request->validate([
            'status' => ['nullable', Rule::in(['pending', 'paid', 'fulfilled', 'cancelled', 'refunded'])],
            'financial_status' => ['nullable', Rule::in(['pending', 'authorized', 'paid', 'partially_refunded', 'refunded', 'voided'])],
            'fulfillment_status' => ['nullable', Rule::in(['unfulfilled', 'partial', 'fulfilled'])],
            'query' => ['nullable', 'string', 'max:255'],
            'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
        ]);

        $orders = Order::withoutGlobalScopes()
            ->with('customer')
            ->withCount('lines')
            ->where('store_id', $store->getKey())
            ->when(data_get($validated, 'status'), fn (Builder $query, string $status) => $query->where('status', $status))
            ->when(data_get($validated, 'financial_status'), fn (Builder $query, string $status) => $query->where('financial_status', $status))
            ->when(data_get($validated, 'fulfillment_status'), fn (Builder $query, string $status) => $query->where('fulfillment_status', $status))
            ->when(data_get($validated, 'query'), function (Builder $query, string $search): void {
                $like = '%'.$search.'%';

                $query->where(function (Builder $query) use ($like): void {
                    $query
                        ->where('order_number', 'like', $like)
                        ->orWhere('email', 'like', $like)
                        ->orWhereHas('customer', fn (Builder $query) => $query->where('name', 'like', $like));
                });
            })
            ->latest('placed_at')
            ->latest('id')
            ->paginate((int) data_get($validated, 'per_page', 25));

        return OrderResource::collection($orders);
    }

    public function show(Request $request, Store $store, Order $order): OrderResource
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        return OrderResource::make($this->loadOrder($order));
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }

    private function loadOrder(Order $order): Order
    {
        return $order->load([
            'customer',
            'lines',
            'payments',
            'refunds',
            'fulfillments.lines',
        ])->loadCount('lines');
    }
}


command: sed -n '1,220p' app/Http/Controllers/Api/Admin/V1/OrderFulfillmentController.php

aggregated_output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Exceptions\InvalidFulfillmentOperationException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Admin\V1\CreateOrderFulfillmentRequest;
use App\Http\Resources\Admin\V1\FulfillmentResource;
use App\Models\Order;
use App\Models\Store;
use App\Services\FulfillmentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderFulfillmentController extends Controller
{
    public function store(CreateOrderFulfillmentRequest $request, Store $store, Order $order, FulfillmentService $fulfillments): FulfillmentResource|JsonResponse
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        try {
            $fulfillment = $fulfillments->create($order, $request->lineQuantities(), [
                'tracking_company' => $request->validated('tracking_company'),
                'tracking_number' => $request->validated('tracking_number'),
                'tracking_url' => $request->validated('tracking_url'),
            ]);

            return FulfillmentResource::make($fulfillment->load('lines'))
                ->response()
                ->setStatusCode(201);
        } catch (InvalidFulfillmentOperationException $exception) {
            return response()->json(['message' => $exception->getMessage()], 409);
        }
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }
}


command: sed -n '1,220p' app/Http/Controllers/Api/Admin/V1/OrderRefundController.php

aggregated_output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Exceptions\InvalidRefundOperationException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Admin\V1\CreateOrderRefundRequest;
use App\Http\Resources\Admin\V1\RefundResource;
use App\Models\Order;
use App\Models\Store;
use App\Services\RefundService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderRefundController extends Controller
{
    public function store(CreateOrderRefundRequest $request, Store $store, Order $order, RefundService $refunds): RefundResource|JsonResponse
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        $payload = [
            'lines' => $request->lineQuantities(),
            'reason' => $request->validated('reason'),
            'restock' => (bool) $request->validated('restock', false),
        ];

        if ($request->validated('amount') !== null) {
            $payload['amount'] = $request->validated('amount');
        }

        try {
            $refund = $refunds->process($order, $payload);

            return RefundResource::make($refund)
                ->response()
                ->setStatusCode(201);
        } catch (InvalidRefundOperationException $exception) {
            return response()->json(['message' => $exception->getMessage()], 409);
        }
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }
}


command: sed -n '1,200p' app/Http/Controllers/Api/Storefront/V1/OrderController.php

aggregated_output:
<?php

namespace App\Http\Controllers\Api\Storefront\V1;

use App\Http\Controllers\Controller;
use App\Http\Resources\Storefront\V1\OrderResource;
use App\Models\Order;
use App\Models\Store;
use App\Support\OrderAccessToken;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function show(Request $request, string $orderNumber): OrderResource
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $order = Order::withoutGlobalScopes()
            ->with(['lines', 'payments', 'fulfillments.lines'])
            ->where('store_id', $store->getKey())
            ->where('order_number', urldecode($orderNumber))
            ->firstOrFail();

        abort_unless(OrderAccessToken::valid($order, $request->query('token')), 404);

        return OrderResource::make($order);
    }
}


command: git diff -- app/Http/Controllers/Api/Storefront/V1/CheckoutController.php routes/api.php

aggregated_output:
diff --git a/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php b/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
index d5831c77..837c758f 100644
--- a/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
+++ b/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
@@ -5,16 +5,20 @@
 use App\Exceptions\InsufficientInventoryException;
 use App\Exceptions\InvalidCheckoutTransitionException;
 use App\Exceptions\InvalidDiscountException;
+use App\Exceptions\PaymentFailedException;
 use App\Exceptions\UnserviceableShippingAddressException;
 use App\Http\Controllers\Controller;
 use App\Http\Requests\Api\Storefront\V1\ApplyCheckoutDiscountRequest;
+use App\Http\Requests\Api\Storefront\V1\CompleteCheckoutPaymentRequest;
 use App\Http\Requests\Api\Storefront\V1\SelectCheckoutPaymentRequest;
 use App\Http\Requests\Api\Storefront\V1\SetCheckoutAddressRequest;
 use App\Http\Requests\Api\Storefront\V1\SetCheckoutShippingRequest;
 use App\Http\Requests\Api\Storefront\V1\StoreCheckoutRequest;
 use App\Http\Resources\Storefront\V1\CheckoutResource;
+use App\Http\Resources\Storefront\V1\OrderResource;
 use App\Models\Cart;
 use App\Models\Checkout;
+use App\Models\Order;
 use App\Models\ShippingRate;
 use App\Services\CheckoutService;
 use App\Services\PricingEngine;
@@ -115,6 +119,30 @@ public function paymentMethod(SelectCheckoutPaymentRequest $request, Checkout $c
         }
     }

+    public function pay(CompleteCheckoutPaymentRequest $request, Checkout $checkout, CheckoutService $checkouts): OrderResource|JsonResponse
+    {
+        try {
+            if ($checkout->payment_method !== $request->validated('payment_method')) {
+                $checkout = $checkouts->selectPaymentMethod($checkout, (string) $request->validated('payment_method'));
+            }
+
+            $order = $checkouts->completeCheckout($checkout, [
+                'card_number' => $request->validated('card_number'),
+                'cardholder_name' => $request->validated('card_holder'),
+                'expiry' => $request->validated('card_expiry'),
+                'cvc' => $request->validated('card_cvc'),
+            ]);
+
+            return OrderResource::make($this->loadOrder($order))
+                ->response()
+                ->setStatusCode(200);
+        } catch (PaymentFailedException $exception) {
+            return response()->json(['message' => $exception->getMessage()], 402);
+        } catch (InsufficientInventoryException|InvalidCheckoutTransitionException $exception) {
+            return response()->json(['message' => $exception->getMessage()], 422);
+        }
+    }
+
     private function loadCheckout(Checkout $checkout): Checkout
     {
         $checkout = $checkout->load([
@@ -128,6 +156,11 @@ private function loadCheckout(Checkout $checkout): Checkout
         return $checkout;
     }

+    private function loadOrder(Order $order): Order
+    {
+        return $order->load(['lines', 'payments', 'fulfillments.lines']);
+    }
+
     /**
      * @return Collection<int, ShippingRate>
      */
diff --git a/routes/api.php b/routes/api.php
index ebfd57ab..b72541a1 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -1,8 +1,12 @@
 <?php

+use App\Http\Controllers\Api\Admin\V1\OrderController as AdminOrderController;
+use App\Http\Controllers\Api\Admin\V1\OrderFulfillmentController as AdminOrderFulfillmentController;
+use App\Http\Controllers\Api\Admin\V1\OrderRefundController as AdminOrderRefundController;
 use App\Http\Controllers\Api\Storefront\V1\CartController;
 use App\Http\Controllers\Api\Storefront\V1\CartLineController;
 use App\Http\Controllers\Api\Storefront\V1\CheckoutController;
+use App\Http\Controllers\Api\Storefront\V1\OrderController as StorefrontOrderController;
 use Illuminate\Support\Facades\Route;

 Route::middleware('store.resolve')
@@ -25,5 +29,17 @@
             Route::post('checkouts/{checkout}/apply-discount', [CheckoutController::class, 'applyDiscount'])->name('checkouts.apply-discount');
             Route::delete('checkouts/{checkout}/discount', [CheckoutController::class, 'destroyDiscount'])->name('checkouts.discount.destroy');
             Route::put('checkouts/{checkout}/payment-method', [CheckoutController::class, 'paymentMethod'])->name('checkouts.payment-method');
+            Route::post('checkouts/{checkout}/pay', [CheckoutController::class, 'pay'])->name('checkouts.pay');
+            Route::get('orders/{orderNumber}', [StorefrontOrderController::class, 'show'])->name('orders.show');
         });
     });
+
+Route::middleware(['auth', 'throttle:60,1'])
+    ->prefix('admin/v1/stores/{store}')
+    ->name('api.admin.v1.')
+    ->group(function (): void {
+        Route::get('orders', [AdminOrderController::class, 'index'])->name('orders.index');
+        Route::get('orders/{order}', [AdminOrderController::class, 'show'])->name('orders.show');
+        Route::post('orders/{order}/fulfillments', [AdminOrderFulfillmentController::class, 'store'])->name('orders.fulfillments.store');
+        Route::post('orders/{order}/refunds', [AdminOrderRefundController::class, 'store'])->name('orders.refunds.store');
+    });


output:
Chunk ID: 54f30a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1295
Output:
diff --git a/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php b/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
index d5831c77..837c758f 100644
--- a/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
+++ b/app/Http/Controllers/Api/Storefront/V1/CheckoutController.php
@@ -5,16 +5,20 @@
 use App\Exceptions\InsufficientInventoryException;
 use App\Exceptions\InvalidCheckoutTransitionException;
 use App\Exceptions\InvalidDiscountException;
+use App\Exceptions\PaymentFailedException;
 use App\Exceptions\UnserviceableShippingAddressException;
 use App\Http\Controllers\Controller;
 use App\Http\Requests\Api\Storefront\V1\ApplyCheckoutDiscountRequest;
+use App\Http\Requests\Api\Storefront\V1\CompleteCheckoutPaymentRequest;
 use App\Http\Requests\Api\Storefront\V1\SelectCheckoutPaymentRequest;
 use App\Http\Requests\Api\Storefront\V1\SetCheckoutAddressRequest;
 use App\Http\Requests\Api\Storefront\V1\SetCheckoutShippingRequest;
 use App\Http\Requests\Api\Storefront\V1\StoreCheckoutRequest;
 use App\Http\Resources\Storefront\V1\CheckoutResource;
+use App\Http\Resources\Storefront\V1\OrderResource;
 use App\Models\Cart;
 use App\Models\Checkout;
+use App\Models\Order;
 use App\Models\ShippingRate;
 use App\Services\CheckoutService;
 use App\Services\PricingEngine;
@@ -115,6 +119,30 @@ public function paymentMethod(SelectCheckoutPaymentRequest $request, Checkout $c
         }
     }

+    public function pay(CompleteCheckoutPaymentRequest $request, Checkout $checkout, CheckoutService $checkouts): OrderResource|JsonResponse
+    {
+        try {
+            if ($checkout->payment_method !== $request->validated('payment_method')) {
+                $checkout = $checkouts->selectPaymentMethod($checkout, (string) $request->validated('payment_method'));
+            }
+
+            $order = $checkouts->completeCheckout($checkout, [
+                'card_number' => $request->validated('card_number'),
+                'cardholder_name' => $request->validated('card_holder'),
+                'expiry' => $request->validated('card_expiry'),
+                'cvc' => $request->validated('card_cvc'),
+            ]);
+
+            return OrderResource::make($this->loadOrder($order))
+                ->response()
+                ->setStatusCode(200);
+        } catch (PaymentFailedException $exception) {
+            return response()->json(['message' => $exception->getMessage()], 402);
+        } catch (InsufficientInventoryException|InvalidCheckoutTransitionException $exception) {
+            return response()->json(['message' => $exception->getMessage()], 422);
+        }
+    }
+
     private function loadCheckout(Checkout $checkout): Checkout
     {
         $checkout = $checkout->load([
@@ -128,6 +156,11 @@ private function loadCheckout(Checkout $checkout): Checkout
         return $checkout;
     }

+    private function loadOrder(Order $order): Order
+    {
+        return $order->load(['lines', 'payments', 'fulfillments.lines']);
+    }
+
     /**
      * @return Collection<int, ShippingRate>
      */
diff --git a/routes/api.php b/routes/api.php
index ebfd57ab..b72541a1 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -1,8 +1,12 @@
 <?php

+use App\Http\Controllers\Api\Admin\V1\OrderController as AdminOrderController;
+use App\Http\Controllers\Api\Admin\V1\OrderFulfillmentController as AdminOrderFulfillmentController;
+use App\Http\Controllers\Api\Admin\V1\OrderRefundController as AdminOrderRefundController;
 use App\Http\Controllers\Api\Storefront\V1\CartController;
 use App\Http\Controllers\Api\Storefront\V1\CartLineController;
 use App\Http\Controllers\Api\Storefront\V1\CheckoutController;
+use App\Http\Controllers\Api\Storefront\V1\OrderController as StorefrontOrderController;
 use Illuminate\Support\Facades\Route;

 Route::middleware('store.resolve')
@@ -25,5 +29,17 @@
             Route::post('checkouts/{checkout}/apply-discount', [CheckoutController::class, 'applyDiscount'])->name('checkouts.apply-discount');
             Route::delete('checkouts/{checkout}/discount', [CheckoutController::class, 'destroyDiscount'])->name('checkouts.discount.destroy');
             Route::put('checkouts/{checkout}/payment-method', [CheckoutController::class, 'paymentMethod'])->name('checkouts.payment-method');
+            Route::post('checkouts/{checkout}/pay', [CheckoutController::class, 'pay'])->name('checkouts.pay');
+            Route::get('orders/{orderNumber}', [StorefrontOrderController::class, 'show'])->name('orders.show');
         });
     });
+
+Route::middleware(['auth', 'throttle:60,1'])
+    ->prefix('admin/v1/stores/{store}')
+    ->name('api.admin.v1.')
+    ->group(function (): void {
+        Route::get('orders', [AdminOrderController::class, 'index'])->name('orders.index');
+        Route::get('orders/{order}', [AdminOrderController::class, 'show'])->name('orders.show');
+        Route::post('orders/{order}/fulfillments', [AdminOrderFulfillmentController::class, 'store'])->name('orders.fulfillments.store');
+        Route::post('orders/{order}/refunds', [AdminOrderRefundController::class, 'store'])->name('orders.refunds.store');
+    });


output:
Chunk ID: ec473e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 818
Output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\V1\OrderResource;
use App\Models\Order;
use App\Models\Store;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Validation\Rule;

class OrderController extends Controller
{
    public function index(Request $request, Store $store): AnonymousResourceCollection
    {
        $this->authorizeStore($request, $store);

        $validated = $request->validate([
            'status' => ['nullable', Rule::in(['pending', 'paid', 'fulfilled', 'cancelled', 'refunded'])],
            'financial_status' => ['nullable', Rule::in(['pending', 'authorized', 'paid', 'partially_refunded', 'refunded', 'voided'])],
            'fulfillment_status' => ['nullable', Rule::in(['unfulfilled', 'partial', 'fulfilled'])],
            'query' => ['nullable', 'string', 'max:255'],
            'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
        ]);

        $orders = Order::withoutGlobalScopes()
            ->with('customer')
            ->withCount('lines')
            ->where('store_id', $store->getKey())
            ->when(data_get($validated, 'status'), fn (Builder $query, string $status) => $query->where('status', $status))
            ->when(data_get($validated, 'financial_status'), fn (Builder $query, string $status) => $query->where('financial_status', $status))
            ->when(data_get($validated, 'fulfillment_status'), fn (Builder $query, string $status) => $query->where('fulfillment_status', $status))
            ->when(data_get($validated, 'query'), function (Builder $query, string $search): void {
                $like = '%'.$search.'%';

                $query->where(function (Builder $query) use ($like): void {
                    $query
                        ->where('order_number', 'like', $like)
                        ->orWhere('email', 'like', $like)
                        ->orWhereHas('customer', fn (Builder $query) => $query->where('name', 'like', $like));
                });
            })
            ->latest('placed_at')
            ->latest('id')
            ->paginate((int) data_get($validated, 'per_page', 25));

        return OrderResource::collection($orders);
    }

    public function show(Request $request, Store $store, Order $order): OrderResource
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        return OrderResource::make($this->loadOrder($order));
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }

    private function loadOrder(Order $order): Order
    {
        return $order->load([
            'customer',
            'lines',
            'payments',
            'refunds',
            'fulfillments.lines',
        ])->loadCount('lines');
    }
}


output:
Chunk ID: 4e597e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 451
Output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Exceptions\InvalidFulfillmentOperationException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Admin\V1\CreateOrderFulfillmentRequest;
use App\Http\Resources\Admin\V1\FulfillmentResource;
use App\Models\Order;
use App\Models\Store;
use App\Services\FulfillmentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderFulfillmentController extends Controller
{
    public function store(CreateOrderFulfillmentRequest $request, Store $store, Order $order, FulfillmentService $fulfillments): FulfillmentResource|JsonResponse
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        try {
            $fulfillment = $fulfillments->create($order, $request->lineQuantities(), [
                'tracking_company' => $request->validated('tracking_company'),
                'tracking_number' => $request->validated('tracking_number'),
                'tracking_url' => $request->validated('tracking_url'),
            ]);

            return FulfillmentResource::make($fulfillment->load('lines'))
                ->response()
                ->setStatusCode(201);
        } catch (InvalidFulfillmentOperationException $exception) {
            return response()->json(['message' => $exception->getMessage()], 409);
        }
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }
}


output:
Chunk ID: a7f1e8
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 450
Output:
<?php

namespace App\Http\Controllers\Api\Admin\V1;

use App\Exceptions\InvalidRefundOperationException;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Admin\V1\CreateOrderRefundRequest;
use App\Http\Resources\Admin\V1\RefundResource;
use App\Models\Order;
use App\Models\Store;
use App\Services\RefundService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class OrderRefundController extends Controller
{
    public function store(CreateOrderRefundRequest $request, Store $store, Order $order, RefundService $refunds): RefundResource|JsonResponse
    {
        $this->authorizeStore($request, $store);
        $this->abortUnlessOrderBelongsToStore($order, $store);

        $payload = [
            'lines' => $request->lineQuantities(),
            'reason' => $request->validated('reason'),
            'restock' => (bool) $request->validated('restock', false),
        ];

        if ($request->validated('amount') !== null) {
            $payload['amount'] = $request->validated('amount');
        }

        try {
            $refund = $refunds->process($order, $payload);

            return RefundResource::make($refund)
                ->response()
                ->setStatusCode(201);
        } catch (InvalidRefundOperationException $exception) {
            return response()->json(['message' => $exception->getMessage()], 409);
        }
    }

    private function authorizeStore(Request $request, Store $store): void
    {
        abort_unless($request->user()?->stores()->whereKey($store->getKey())->exists(), 403);

        app()->instance('current_store', $store);
    }

    private function abortUnlessOrderBelongsToStore(Order $order, Store $store): void
    {
        abort_unless((int) $order->store_id === $store->getKey(), 404);
    }
}


output:
Chunk ID: 128ff0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 217
Output:
<?php

namespace App\Http\Controllers\Api\Storefront\V1;

use App\Http\Controllers\Controller;
use App\Http\Resources\Storefront\V1\OrderResource;
use App\Models\Order;
use App\Models\Store;
use App\Support\OrderAccessToken;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function show(Request $request, string $orderNumber): OrderResource
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $order = Order::withoutGlobalScopes()
            ->with(['lines', 'payments', 'fulfillments.lines'])
            ->where('store_id', $store->getKey())
            ->where('order_number', urldecode($orderNumber))
            ->firstOrFail();

        abort_unless(OrderAccessToken::valid($order, $request->query('token')), 404);

        return OrderResource::make($order);
    }
}


command: sed -n '1,200p' app/Support/OrderAccessToken.php

aggregated_output:
<?php

namespace App\Support;

use App\Models\Order;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;

class OrderAccessToken
{
    public static function make(Order $order): string
    {
        return hash_hmac('sha256', self::payload($order), self::key());
    }

    public static function valid(Order $order, ?string $token): bool
    {
        if ($token === null || $token === '') {
            return false;
        }

        return hash_equals(self::make($order), $token);
    }

    private static function payload(Order $order): string
    {
        return implode('|', [
            $order->store_id,
            $order->getKey(),
            $order->order_number,
            $order->created_at?->timestamp ?? 0,
        ]);
    }

    private static function key(): string
    {
        $key = (string) Config::get('app.key');

        return Str::startsWith($key, 'base64:')
            ? base64_decode(Str::after($key, 'base64:'), true) ?: $key
            : $key;
    }
}


output:
Chunk ID: 39a73c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 252
Output:
<?php

namespace App\Support;

use App\Models\Order;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;

class OrderAccessToken
{
    public static function make(Order $order): string
    {
        return hash_hmac('sha256', self::payload($order), self::key());
    }

    public static function valid(Order $order, ?string $token): bool
    {
        if ($token === null || $token === '') {
            return false;
        }

        return hash_equals(self::make($order), $token);
    }

    private static function payload(Order $order): string
    {
        return implode('|', [
            $order->store_id,
            $order->getKey(),
            $order->order_number,
            $order->created_at?->timestamp ?? 0,
        ]);
    }

    private static function key(): string
    {
        $key = (string) Config::get('app.key');

        return Str::startsWith($key, 'base64:')
            ? base64_decode(Str::after($key, 'base64:'), true) ?: $key
            : $key;
    }
}


cmd: sed -n '1,220p' app/Http/Requests/Api/Admin/V1/CreateOrderFulfillmentRequest.php


cmd: sed -n '1,240p' app/Http/Requests/Api/Admin/V1/CreateOrderRefundRequest.php


cmd: sed -n '1,200p' app/Http/Requests/Api/Storefront/V1/CompleteCheckoutPaymentRequest.php


cmd: sed -n '1,260p' app/Http/Resources/Admin/V1/OrderResource.php


cmd: sed -n '1,260p' app/Http/Resources/Storefront/V1/OrderResource.php


cmd: sed -n '1,260p' tests/Feature/Api/AdminOrderApiTest.php


command: sed -n '1,220p' app/Http/Requests/Api/Admin/V1/CreateOrderFulfillmentRequest.php

aggregated_output:
<?php

namespace App\Http\Requests\Api\Admin\V1;

use Illuminate\Foundation\Http\FormRequest;

class CreateOrderFulfillmentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'line_items' => ['required', 'array', 'min:1'],
            'line_items.*.order_line_id' => ['required', 'integer'],
            'line_items.*.quantity' => ['required', 'integer', 'min:1'],
            'tracking_company' => ['nullable', 'string', 'max:255'],
            'tracking_number' => ['nullable', 'string', 'max:255'],
            'tracking_url' => ['nullable', 'url', 'max:2048'],
        ];
    }

    /**
     * @return array<int, int>
     */
    public function lineQuantities(): array
    {
        return collect($this->validated('line_items'))
            ->mapWithKeys(fn (array $line): array => [(int) $line['order_line_id'] => (int) $line['quantity']])
            ->all();
    }
}


output:
Chunk ID: e47898
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 278
Output:
<?php

namespace App\Http\Requests\Api\Admin\V1;

use Illuminate\Foundation\Http\FormRequest;

class CreateOrderFulfillmentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'line_items' => ['required', 'array', 'min:1'],
            'line_items.*.order_line_id' => ['required', 'integer'],
            'line_items.*.quantity' => ['required', 'integer', 'min:1'],
            'tracking_company' => ['nullable', 'string', 'max:255'],
            'tracking_number' => ['nullable', 'string', 'max:255'],
            'tracking_url' => ['nullable', 'url', 'max:2048'],
        ];
    }

    /**
     * @return array<int, int>
     */
    public function lineQuantities(): array
    {
        return collect($this->validated('line_items'))
            ->mapWithKeys(fn (array $line): array => [(int) $line['order_line_id'] => (int) $line['quantity']])
            ->all();
    }
}


command: sed -n '1,240p' app/Http/Requests/Api/Admin/V1/CreateOrderRefundRequest.php

aggregated_output:
<?php

namespace App\Http\Requests\Api\Admin\V1;

use Illuminate\Foundation\Http\FormRequest;

class CreateOrderRefundRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'amount' => ['nullable', 'integer', 'min:1'],
            'reason' => ['nullable', 'string', 'max:500'],
            'restock' => ['sometimes', 'boolean'],
            'line_items' => ['nullable', 'array'],
            'line_items.*.order_line_id' => ['required_with:line_items', 'integer'],
            'line_items.*.quantity' => ['required_with:line_items', 'integer', 'min:1'],
        ];
    }

    /**
     * @return array<int, int>
     */
    public function lineQuantities(): array
    {
        return collect($this->validated('line_items', []))
            ->mapWithKeys(fn (array $line): array => [(int) $line['order_line_id'] => (int) $line['quantity']])
            ->all();
    }
}


output:
Chunk ID: 424080
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 275
Output:
<?php

namespace App\Http\Requests\Api\Admin\V1;

use Illuminate\Foundation\Http\FormRequest;

class CreateOrderRefundRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'amount' => ['nullable', 'integer', 'min:1'],
            'reason' => ['nullable', 'string', 'max:500'],
            'restock' => ['sometimes', 'boolean'],
            'line_items' => ['nullable', 'array'],
            'line_items.*.order_line_id' => ['required_with:line_items', 'integer'],
            'line_items.*.quantity' => ['required_with:line_items', 'integer', 'min:1'],
        ];
    }

    /**
     * @return array<int, int>
     */
    public function lineQuantities(): array
    {
        return collect($this->validated('line_items', []))
            ->mapWithKeys(fn (array $line): array => [(int) $line['order_line_id'] => (int) $line['quantity']])
            ->all();
    }
}


command: sed -n '1,260p' app/Http/Resources/Admin/V1/OrderResource.php

aggregated_output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class OrderResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'store_id' => $this->store_id,
            'order_number' => $this->order_number,
            'email' => $this->email,
            'customer' => $this->whenLoaded('customer', fn () => $this->customer ? [
                'id' => $this->customer->id,
                'name' => $this->customer->name,
                'email' => $this->customer->email,
            ] : null),
            'status' => $this->status?->value,
            'financial_status' => $this->financial_status?->value,
            'fulfillment_status' => $this->fulfillment_status?->value,
            'payment_method' => $this->payment_method?->value,
            'currency' => $this->currency,
            'subtotal_amount' => $this->subtotal_amount,
            'discount_amount' => $this->discount_amount,
            'shipping_amount' => $this->shipping_amount,
            'tax_amount' => $this->tax_amount,
            'total_amount' => $this->total_amount,
            'lines_count' => $this->whenCounted('lines'),
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'product_id' => $line->product_id,
                'variant_id' => $line->variant_id,
                'title' => $line->title_snapshot,
                'sku' => $line->sku_snapshot,
                'quantity' => $line->quantity,
                'unit_price_amount' => $line->unit_price_amount,
                'total_amount' => $line->total_amount,
            ])->values()),
            'payments' => $this->whenLoaded('payments', fn () => $this->payments->map(fn ($payment): array => [
                'id' => $payment->id,
                'provider' => $payment->provider,
                'method' => $payment->method?->value,
                'provider_payment_id' => $payment->provider_payment_id,
                'status' => $payment->status?->value,
                'amount' => $payment->amount,
                'currency' => $payment->currency,
            ])->values()),
            'refunds' => RefundResource::collection($this->whenLoaded('refunds')),
            'fulfillments' => FulfillmentResource::collection($this->whenLoaded('fulfillments')),
            'shipping_address' => $this->shipping_address_json,
            'billing_address' => $this->billing_address_json,
            'placed_at' => $this->placed_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


command: sed -n '1,260p' app/Http/Resources/Storefront/V1/OrderResource.php

aggregated_output:
<?php

namespace App\Http\Resources\Storefront\V1;

use App\Enums\PaymentMethod;
use App\Support\OrderAccessToken;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class OrderResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_number' => $this->order_number,
            'access_token' => OrderAccessToken::make($this->resource),
            'email' => $this->email,
            'status' => $this->status?->value,
            'financial_status' => $this->financial_status?->value,
            'fulfillment_status' => $this->fulfillment_status?->value,
            'payment_method' => $this->payment_method?->value,
            'currency' => $this->currency,
            'subtotal_amount' => $this->subtotal_amount,
            'discount_amount' => $this->discount_amount,
            'shipping_amount' => $this->shipping_amount,
            'tax_amount' => $this->tax_amount,
            'total_amount' => $this->total_amount,
            'shipping_address' => $this->shipping_address_json,
            'billing_address' => $this->billing_address_json,
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'title' => $line->title_snapshot,
                'sku' => $line->sku_snapshot,
                'quantity' => $line->quantity,
                'unit_price_amount' => $line->unit_price_amount,
                'total_amount' => $line->total_amount,
            ])->values()),
            'payments' => $this->whenLoaded('payments', fn () => $this->payments->map(fn ($payment): array => [
                'id' => $payment->id,
                'provider' => $payment->provider,
                'method' => $payment->method?->value,
                'status' => $payment->status?->value,
                'amount' => $payment->amount,
                'currency' => $payment->currency,
            ])->values()),
            'fulfillments' => $this->whenLoaded('fulfillments', fn () => $this->fulfillments->map(fn ($fulfillment): array => [
                'id' => $fulfillment->id,
                'status' => $fulfillment->status?->value,
                'tracking_company' => $fulfillment->tracking_company,
                'tracking_number' => $fulfillment->tracking_number,
                'tracking_url' => $fulfillment->tracking_url,
                'shipped_at' => $fulfillment->shipped_at?->toIso8601String(),
                'delivered_at' => $fulfillment->delivered_at?->toIso8601String(),
            ])->values()),
            'bank_transfer_instructions' => $this->payment_method === PaymentMethod::BankTransfer ? [
                'bank_name' => 'Mock Bank AG',
                'bic' => 'COBADEFFXXX',
                'iban' => 'DE89 3704 0044 0532 0130 00',
                'reference' => $this->order_number,
                'amount' => $this->total_amount,
                'currency' => $this->currency,
            ] : null,
            'placed_at' => $this->placed_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


command: sed -n '1,200p' app/Http/Requests/Api/Storefront/V1/CompleteCheckoutPaymentRequest.php

aggregated_output:
<?php

namespace App\Http\Requests\Api\Storefront\V1;

use Illuminate\Foundation\Http\FormRequest;

class CompleteCheckoutPaymentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'payment_method' => ['required', 'in:credit_card,paypal,bank_transfer'],
            'card_number' => ['required_if:payment_method,credit_card', 'string'],
            'card_holder' => ['required_if:payment_method,credit_card', 'string', 'max:255'],
            'card_expiry' => ['required_if:payment_method,credit_card', 'string', 'max:20'],
            'card_cvc' => ['required_if:payment_method,credit_card', 'string', 'max:10'],
        ];
    }
}


output:
Chunk ID: 21c1d0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 217
Output:
<?php

namespace App\Http\Requests\Api\Storefront\V1;

use Illuminate\Foundation\Http\FormRequest;

class CompleteCheckoutPaymentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /**
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'payment_method' => ['required', 'in:credit_card,paypal,bank_transfer'],
            'card_number' => ['required_if:payment_method,credit_card', 'string'],
            'card_holder' => ['required_if:payment_method,credit_card', 'string', 'max:255'],
            'card_expiry' => ['required_if:payment_method,credit_card', 'string', 'max:20'],
            'card_cvc' => ['required_if:payment_method,credit_card', 'string', 'max:10'],
        ];
    }
}


output:
Chunk ID: 4c3891
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 718
Output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class OrderResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'store_id' => $this->store_id,
            'order_number' => $this->order_number,
            'email' => $this->email,
            'customer' => $this->whenLoaded('customer', fn () => $this->customer ? [
                'id' => $this->customer->id,
                'name' => $this->customer->name,
                'email' => $this->customer->email,
            ] : null),
            'status' => $this->status?->value,
            'financial_status' => $this->financial_status?->value,
            'fulfillment_status' => $this->fulfillment_status?->value,
            'payment_method' => $this->payment_method?->value,
            'currency' => $this->currency,
            'subtotal_amount' => $this->subtotal_amount,
            'discount_amount' => $this->discount_amount,
            'shipping_amount' => $this->shipping_amount,
            'tax_amount' => $this->tax_amount,
            'total_amount' => $this->total_amount,
            'lines_count' => $this->whenCounted('lines'),
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'product_id' => $line->product_id,
                'variant_id' => $line->variant_id,
                'title' => $line->title_snapshot,
                'sku' => $line->sku_snapshot,
                'quantity' => $line->quantity,
                'unit_price_amount' => $line->unit_price_amount,
                'total_amount' => $line->total_amount,
            ])->values()),
            'payments' => $this->whenLoaded('payments', fn () => $this->payments->map(fn ($payment): array => [
                'id' => $payment->id,
                'provider' => $payment->provider,
                'method' => $payment->method?->value,
                'provider_payment_id' => $payment->provider_payment_id,
                'status' => $payment->status?->value,
                'amount' => $payment->amount,
                'currency' => $payment->currency,
            ])->values()),
            'refunds' => RefundResource::collection($this->whenLoaded('refunds')),
            'fulfillments' => FulfillmentResource::collection($this->whenLoaded('fulfillments')),
            'shipping_address' => $this->shipping_address_json,
            'billing_address' => $this->billing_address_json,
            'placed_at' => $this->placed_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


output:
Chunk ID: 51cf42
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 833
Output:
<?php

namespace App\Http\Resources\Storefront\V1;

use App\Enums\PaymentMethod;
use App\Support\OrderAccessToken;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class OrderResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_number' => $this->order_number,
            'access_token' => OrderAccessToken::make($this->resource),
            'email' => $this->email,
            'status' => $this->status?->value,
            'financial_status' => $this->financial_status?->value,
            'fulfillment_status' => $this->fulfillment_status?->value,
            'payment_method' => $this->payment_method?->value,
            'currency' => $this->currency,
            'subtotal_amount' => $this->subtotal_amount,
            'discount_amount' => $this->discount_amount,
            'shipping_amount' => $this->shipping_amount,
            'tax_amount' => $this->tax_amount,
            'total_amount' => $this->total_amount,
            'shipping_address' => $this->shipping_address_json,
            'billing_address' => $this->billing_address_json,
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'title' => $line->title_snapshot,
                'sku' => $line->sku_snapshot,
                'quantity' => $line->quantity,
                'unit_price_amount' => $line->unit_price_amount,
                'total_amount' => $line->total_amount,
            ])->values()),
            'payments' => $this->whenLoaded('payments', fn () => $this->payments->map(fn ($payment): array => [
                'id' => $payment->id,
                'provider' => $payment->provider,
                'method' => $payment->method?->value,
                'status' => $payment->status?->value,
                'amount' => $payment->amount,
                'currency' => $payment->currency,
            ])->values()),
            'fulfillments' => $this->whenLoaded('fulfillments', fn () => $this->fulfillments->map(fn ($fulfillment): array => [
                'id' => $fulfillment->id,
                'status' => $fulfillment->status?->value,
                'tracking_company' => $fulfillment->tracking_company,
                'tracking_number' => $fulfillment->tracking_number,
                'tracking_url' => $fulfillment->tracking_url,
                'shipped_at' => $fulfillment->shipped_at?->toIso8601String(),
                'delivered_at' => $fulfillment->delivered_at?->toIso8601String(),
            ])->values()),
            'bank_transfer_instructions' => $this->payment_method === PaymentMethod::BankTransfer ? [
                'bank_name' => 'Mock Bank AG',
                'bic' => 'COBADEFFXXX',
                'iban' => 'DE89 3704 0044 0532 0130 00',
                'reference' => $this->order_number,
                'amount' => $this->total_amount,
                'currency' => $this->currency,
            ] : null,
            'placed_at' => $this->placed_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


command: sed -n '1,260p' tests/Feature/Api/AdminOrderApiTest.php

aggregated_output:
<?php

use App\Enums\FinancialStatus;
use App\Enums\FulfillmentStatus;
use App\Enums\PaymentStatus;
use App\Models\Fulfillment;
use App\Models\InventoryItem;
use App\Models\Order;
use App\Models\OrderLine;
use App\Models\Payment;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function adminOrderApiStore(): Store
{
    return Store::query()->where('handle', 'acme-fashion')->firstOrFail();
}

function adminOrderApiUser(): User
{
    return User::query()->where('email', 'admin@acme.test')->firstOrFail();
}

/**
 * @return array{0: Order, 1: OrderLine, 2: ProductVariant}
 */
function adminOrderApiOrder(Store $store, array $orderAttributes = [], int $quantity = 2, int $unitPrice = 2500): array
{
    $product = Product::factory()
        ->withDefaultVariant($unitPrice)
        ->create(['store_id' => $store->getKey()]);
    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->firstOrFail();

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 10,
            'quantity_reserved' => 0,
        ]);

    $total = $quantity * $unitPrice;
    $order = Order::factory()->paid()->create(array_merge([
        'store_id' => $store->getKey(),
        'subtotal_amount' => $total,
        'shipping_amount' => 0,
        'tax_amount' => 0,
        'total_amount' => $total,
        'email' => 'buyer@example.test',
    ], $orderAttributes));
    $line = OrderLine::factory()->create([
        'order_id' => $order->getKey(),
        'product_id' => $product->getKey(),
        'variant_id' => $variant->getKey(),
        'title_snapshot' => 'Admin API Product',
        'sku_snapshot' => 'ADMIN-API-001',
        'quantity' => $quantity,
        'unit_price_amount' => $unitPrice,
        'total_amount' => $total,
    ]);

    Payment::factory()->create([
        'order_id' => $order->getKey(),
        'status' => $order->financial_status === FinancialStatus::Pending ? PaymentStatus::Pending : PaymentStatus::Captured,
        'amount' => $total,
        'currency' => $order->currency,
    ]);

    return [$order, $line, $variant];
}

test('admin order api lists and shows store scoped orders', function (): void {
    $store = adminOrderApiStore();
    [$order] = adminOrderApiOrder($store, [
        'order_number' => '#8001',
        'email' => 'alpha@example.test',
    ]);
    $otherStore = Store::factory()->create();
    adminOrderApiOrder($otherStore, [
        'order_number' => '#9001',
        'email' => 'other@example.test',
    ]);

    $this->getJson("/api/admin/v1/stores/{$store->getKey()}/orders")
        ->assertUnauthorized();

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders?query=alpha")
        ->assertOk()
        ->assertJsonPath('data.0.order_number', '#8001')
        ->assertJsonMissing(['order_number' => '#9001']);

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}")
        ->assertOk()
        ->assertJsonPath('data.order_number', '#8001')
        ->assertJsonPath('data.lines.0.title', 'Admin API Product');
});

test('admin order api creates refunds and fulfillments', function (): void {
    $store = adminOrderApiStore();
    [$order, $line] = adminOrderApiOrder($store, quantity: 2, unitPrice: 2500);
    $user = adminOrderApiUser();

    $this->actingAs($user)
        ->postJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}/refunds", [
            'amount' => 1000,
            'reason' => 'Customer return',
        ])
        ->assertCreated()
        ->assertJsonPath('data.amount', 1000)
        ->assertJsonPath('data.status', 'processed');

    expect($order->refresh()->financial_status)->toBe(FinancialStatus::PartiallyRefunded);

    $this->actingAs($user)
        ->postJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}/fulfillments", [
            'line_items' => [
                ['order_line_id' => $line->getKey(), 'quantity' => 1],
            ],
            'tracking_company' => 'DHL',
            'tracking_number' => 'DHL123',
        ])
        ->assertCreated()
        ->assertJsonPath('data.status', 'pending')
        ->assertJsonPath('data.lines.0.quantity', 1);

    $fulfillment = Fulfillment::query()->where('order_id', $order->getKey())->firstOrFail();

    expect($order->refresh()->fulfillment_status)->toBe(FulfillmentStatus::Partial)
        ->and($fulfillment->tracking_number)->toBe('DHL123');
});

test('admin order api rejects orders outside the requested store', function (): void {
    $store = adminOrderApiStore();
    $otherStore = Store::factory()->create();
    [$otherOrder] = adminOrderApiOrder($otherStore, [
        'order_number' => '#9001',
    ]);

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$otherOrder->getKey()}")
        ->assertNotFound();
});


output:
Chunk ID: c19a5b
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1329
Output:
<?php

use App\Enums\FinancialStatus;
use App\Enums\FulfillmentStatus;
use App\Enums\PaymentStatus;
use App\Models\Fulfillment;
use App\Models\InventoryItem;
use App\Models\Order;
use App\Models\OrderLine;
use App\Models\Payment;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function adminOrderApiStore(): Store
{
    return Store::query()->where('handle', 'acme-fashion')->firstOrFail();
}

function adminOrderApiUser(): User
{
    return User::query()->where('email', 'admin@acme.test')->firstOrFail();
}

/**
 * @return array{0: Order, 1: OrderLine, 2: ProductVariant}
 */
function adminOrderApiOrder(Store $store, array $orderAttributes = [], int $quantity = 2, int $unitPrice = 2500): array
{
    $product = Product::factory()
        ->withDefaultVariant($unitPrice)
        ->create(['store_id' => $store->getKey()]);
    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->firstOrFail();

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 10,
            'quantity_reserved' => 0,
        ]);

    $total = $quantity * $unitPrice;
    $order = Order::factory()->paid()->create(array_merge([
        'store_id' => $store->getKey(),
        'subtotal_amount' => $total,
        'shipping_amount' => 0,
        'tax_amount' => 0,
        'total_amount' => $total,
        'email' => 'buyer@example.test',
    ], $orderAttributes));
    $line = OrderLine::factory()->create([
        'order_id' => $order->getKey(),
        'product_id' => $product->getKey(),
        'variant_id' => $variant->getKey(),
        'title_snapshot' => 'Admin API Product',
        'sku_snapshot' => 'ADMIN-API-001',
        'quantity' => $quantity,
        'unit_price_amount' => $unitPrice,
        'total_amount' => $total,
    ]);

    Payment::factory()->create([
        'order_id' => $order->getKey(),
        'status' => $order->financial_status === FinancialStatus::Pending ? PaymentStatus::Pending : PaymentStatus::Captured,
        'amount' => $total,
        'currency' => $order->currency,
    ]);

    return [$order, $line, $variant];
}

test('admin order api lists and shows store scoped orders', function (): void {
    $store = adminOrderApiStore();
    [$order] = adminOrderApiOrder($store, [
        'order_number' => '#8001',
        'email' => 'alpha@example.test',
    ]);
    $otherStore = Store::factory()->create();
    adminOrderApiOrder($otherStore, [
        'order_number' => '#9001',
        'email' => 'other@example.test',
    ]);

    $this->getJson("/api/admin/v1/stores/{$store->getKey()}/orders")
        ->assertUnauthorized();

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders?query=alpha")
        ->assertOk()
        ->assertJsonPath('data.0.order_number', '#8001')
        ->assertJsonMissing(['order_number' => '#9001']);

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}")
        ->assertOk()
        ->assertJsonPath('data.order_number', '#8001')
        ->assertJsonPath('data.lines.0.title', 'Admin API Product');
});

test('admin order api creates refunds and fulfillments', function (): void {
    $store = adminOrderApiStore();
    [$order, $line] = adminOrderApiOrder($store, quantity: 2, unitPrice: 2500);
    $user = adminOrderApiUser();

    $this->actingAs($user)
        ->postJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}/refunds", [
            'amount' => 1000,
            'reason' => 'Customer return',
        ])
        ->assertCreated()
        ->assertJsonPath('data.amount', 1000)
        ->assertJsonPath('data.status', 'processed');

    expect($order->refresh()->financial_status)->toBe(FinancialStatus::PartiallyRefunded);

    $this->actingAs($user)
        ->postJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$order->getKey()}/fulfillments", [
            'line_items' => [
                ['order_line_id' => $line->getKey(), 'quantity' => 1],
            ],
            'tracking_company' => 'DHL',
            'tracking_number' => 'DHL123',
        ])
        ->assertCreated()
        ->assertJsonPath('data.status', 'pending')
        ->assertJsonPath('data.lines.0.quantity', 1);

    $fulfillment = Fulfillment::query()->where('order_id', $order->getKey())->firstOrFail();

    expect($order->refresh()->fulfillment_status)->toBe(FulfillmentStatus::Partial)
        ->and($fulfillment->tracking_number)->toBe('DHL123');
});

test('admin order api rejects orders outside the requested store', function (): void {
    $store = adminOrderApiStore();
    $otherStore = Store::factory()->create();
    [$otherOrder] = adminOrderApiOrder($otherStore, [
        'order_number' => '#9001',
    ]);

    $this->actingAs(adminOrderApiUser())
        ->getJson("/api/admin/v1/stores/{$store->getKey()}/orders/{$otherOrder->getKey()}")
        ->assertNotFound();
});


cmd: sed -n '1,220p' app/Http/Resources/Admin/V1/FulfillmentResource.php


cmd: sed -n '1,180p' app/Http/Resources/Admin/V1/RefundResource.php


cmd: sed -n '1,320p' tests/Feature/Api/StorefrontOrderApiTest.php


command: sed -n '1,180p' app/Http/Resources/Admin/V1/RefundResource.php

aggregated_output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class RefundResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_id' => $this->order_id,
            'payment_id' => $this->payment_id,
            'amount' => $this->amount,
            'reason' => $this->reason,
            'status' => $this->status?->value,
            'provider_refund_id' => $this->provider_refund_id,
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


command: sed -n '1,220p' app/Http/Resources/Admin/V1/FulfillmentResource.php

aggregated_output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class FulfillmentResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_id' => $this->order_id,
            'status' => $this->status?->value,
            'tracking_company' => $this->tracking_company,
            'tracking_number' => $this->tracking_number,
            'tracking_url' => $this->tracking_url,
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'order_line_id' => $line->order_line_id,
                'quantity' => $line->quantity,
            ])->values()),
            'shipped_at' => $this->shipped_at?->toIso8601String(),
            'delivered_at' => $this->delivered_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


output:
Chunk ID: 1b2854
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 284
Output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class FulfillmentResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_id' => $this->order_id,
            'status' => $this->status?->value,
            'tracking_company' => $this->tracking_company,
            'tracking_number' => $this->tracking_number,
            'tracking_url' => $this->tracking_url,
            'lines' => $this->whenLoaded('lines', fn () => $this->lines->map(fn ($line): array => [
                'id' => $line->id,
                'order_line_id' => $line->order_line_id,
                'quantity' => $line->quantity,
            ])->values()),
            'shipped_at' => $this->shipped_at?->toIso8601String(),
            'delivered_at' => $this->delivered_at?->toIso8601String(),
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


output:
Chunk ID: 77da97
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 187
Output:
<?php

namespace App\Http\Resources\Admin\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class RefundResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'order_id' => $this->order_id,
            'payment_id' => $this->payment_id,
            'amount' => $this->amount,
            'reason' => $this->reason,
            'status' => $this->status?->value,
            'provider_refund_id' => $this->provider_refund_id,
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}


command: sed -n '1,320p' tests/Feature/Api/StorefrontOrderApiTest.php

aggregated_output:
<?php

use App\Enums\CheckoutStatus;
use App\Models\Checkout;
use App\Models\InventoryItem;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function storefrontOrderApiStore(): Store
{
    return Store::query()->where('handle', 'acme-fashion')->firstOrFail();
}

function storefrontOrderApiVariant(Store $store): ProductVariant
{
    $product = Product::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('handle', 'classic-cotton-t-shirt')
        ->firstOrFail();

    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->oldest('position')
        ->firstOrFail();

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 20,
            'quantity_reserved' => 0,
        ]);

    return $variant->refresh();
}

/**
 * @return array{0: int, 1: ProductVariant}
 */
function storefrontOrderApiCheckout(object $testCase, string $remoteAddress = '10.0.0.41'): array
{
    $store = storefrontOrderApiStore();
    $variant = storefrontOrderApiVariant($store);
    $api = fn () => $testCase->withServerVariables(['REMOTE_ADDR' => $remoteAddress])->withHeader('Host', 'shop.test');

    $cartId = $api()
        ->postJson('/api/storefront/v1/carts')
        ->assertCreated()['data']['id'];

    $api()
        ->postJson("/api/storefront/v1/carts/{$cartId}/lines", [
            'variant_id' => $variant->getKey(),
            'quantity' => 1,
        ])
        ->assertCreated();

    $checkoutId = $api()
        ->postJson('/api/storefront/v1/checkouts', [
            'cart_id' => $cartId,
            'email' => 'buyer@example.test',
        ])
        ->assertCreated()['data']['id'];

    $addressResponse = $api()
        ->putJson("/api/storefront/v1/checkouts/{$checkoutId}/address", [
            'shipping_address' => [
                'first_name' => 'Test',
                'last_name' => 'Buyer',
                'address1' => 'Main Street 1',
                'city' => 'Berlin',
                'country' => 'DE',
                'postal_code' => '10115',
            ],
        ])
        ->assertOk();

    $api()
        ->putJson("/api/storefront/v1/checkouts/{$checkoutId}/shipping-method", [
            'shipping_rate_id' => $addressResponse['data']['available_shipping_rates'][0]['id'],
        ])
        ->assertOk();

    return [$checkoutId, $variant];
}

test('storefront order api pays a checkout and exposes token-gated order lookup', function (): void {
    [$checkoutId] = storefrontOrderApiCheckout($this);
    $api = fn () => $this->withServerVariables(['REMOTE_ADDR' => '10.0.0.41'])->withHeader('Host', 'shop.test');

    $payResponse = $api()
        ->postJson("/api/storefront/v1/checkouts/{$checkoutId}/pay", [
            'payment_method' => 'credit_card',
            'card_number' => '4242 4242 4242 4242',
            'card_holder' => 'Test Buyer',
            'card_expiry' => '12/30',
            'card_cvc' => '123',
        ]);

    $payResponse
        ->assertOk()
        ->assertJsonPath('data.order_number', '#1001')
        ->assertJsonPath('data.financial_status', 'paid')
        ->assertJsonCount(1, 'data.lines');

    $token = $payResponse['data']['access_token'];

    $api()
        ->getJson('/api/storefront/v1/orders/%231001?token='.$token)
        ->assertOk()
        ->assertJsonPath('data.order_number', '#1001')
        ->assertJsonPath('data.total_amount', $payResponse['data']['total_amount']);

    $api()
        ->getJson('/api/storefront/v1/orders/%231001?token=bad-token')
        ->assertNotFound();
});

test('storefront order api returns payment failures and releases reservations', function (): void {
    [$checkoutId, $variant] = storefrontOrderApiCheckout($this, '10.0.0.42');
    $api = fn () => $this->withServerVariables(['REMOTE_ADDR' => '10.0.0.42'])->withHeader('Host', 'shop.test');

    $api()
        ->postJson("/api/storefront/v1/checkouts/{$checkoutId}/pay", [
            'payment_method' => 'credit_card',
            'card_number' => '4000 0000 0000 0002',
            'card_holder' => 'Test Buyer',
            'card_expiry' => '12/30',
            'card_cvc' => '123',
        ])
        ->assertStatus(402);

    $checkout = Checkout::withoutGlobalScopes()->findOrFail($checkoutId);
    $inventory = InventoryItem::withoutGlobalScopes()->where('variant_id', $variant->getKey())->firstOrFail();

    expect($checkout->status)->toBe(CheckoutStatus::ShippingSelected)
        ->and($inventory->quantity_reserved)->toBe(0);
});


output:
Chunk ID: 89eef0
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1213
Output:
<?php

use App\Enums\CheckoutStatus;
use App\Models\Checkout;
use App\Models\InventoryItem;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->withoutVite();
    $this->seed(DatabaseSeeder::class);
});

function storefrontOrderApiStore(): Store
{
    return Store::query()->where('handle', 'acme-fashion')->firstOrFail();
}

function storefrontOrderApiVariant(Store $store): ProductVariant
{
    $product = Product::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('handle', 'classic-cotton-t-shirt')
        ->firstOrFail();

    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->oldest('position')
        ->firstOrFail();

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 20,
            'quantity_reserved' => 0,
        ]);

    return $variant->refresh();
}

/**
 * @return array{0: int, 1: ProductVariant}
 */
function storefrontOrderApiCheckout(object $testCase, string $remoteAddress = '10.0.0.41'): array
{
    $store = storefrontOrderApiStore();
    $variant = storefrontOrderApiVariant($store);
    $api = fn () => $testCase->withServerVariables(['REMOTE_ADDR' => $remoteAddress])->withHeader('Host', 'shop.test');

    $cartId = $api()
        ->postJson('/api/storefront/v1/carts')
        ->assertCreated()['data']['id'];

    $api()
        ->postJson("/api/storefront/v1/carts/{$cartId}/lines", [
            'variant_id' => $variant->getKey(),
            'quantity' => 1,
        ])
        ->assertCreated();

    $checkoutId = $api()
        ->postJson('/api/storefront/v1/checkouts', [
            'cart_id' => $cartId,
            'email' => 'buyer@example.test',
        ])
        ->assertCreated()['data']['id'];

    $addressResponse = $api()
        ->putJson("/api/storefront/v1/checkouts/{$checkoutId}/address", [
            'shipping_address' => [
                'first_name' => 'Test',
                'last_name' => 'Buyer',
                'address1' => 'Main Street 1',
                'city' => 'Berlin',
                'country' => 'DE',
                'postal_code' => '10115',
            ],
        ])
        ->assertOk();

    $api()
        ->putJson("/api/storefront/v1/checkouts/{$checkoutId}/shipping-method", [
            'shipping_rate_id' => $addressResponse['data']['available_shipping_rates'][0]['id'],
        ])
        ->assertOk();

    return [$checkoutId, $variant];
}

test('storefront order api pays a checkout and exposes token-gated order lookup', function (): void {
    [$checkoutId] = storefrontOrderApiCheckout($this);
    $api = fn () => $this->withServerVariables(['REMOTE_ADDR' => '10.0.0.41'])->withHeader('Host', 'shop.test');

    $payResponse = $api()
        ->postJson("/api/storefront/v1/checkouts/{$checkoutId}/pay", [
            'payment_method' => 'credit_card',
            'card_number' => '4242 4242 4242 4242',
            'card_holder' => 'Test Buyer',
            'card_expiry' => '12/30',
            'card_cvc' => '123',
        ]);

    $payResponse
        ->assertOk()
        ->assertJsonPath('data.order_number', '#1001')
        ->assertJsonPath('data.financial_status', 'paid')
        ->assertJsonCount(1, 'data.lines');

    $token = $payResponse['data']['access_token'];

    $api()
        ->getJson('/api/storefront/v1/orders/%231001?token='.$token)
        ->assertOk()
        ->assertJsonPath('data.order_number', '#1001')
        ->assertJsonPath('data.total_amount', $payResponse['data']['total_amount']);

    $api()
        ->getJson('/api/storefront/v1/orders/%231001?token=bad-token')
        ->assertNotFound();
});

test('storefront order api returns payment failures and releases reservations', function (): void {
    [$checkoutId, $variant] = storefrontOrderApiCheckout($this, '10.0.0.42');
    $api = fn () => $this->withServerVariables(['REMOTE_ADDR' => '10.0.0.42'])->withHeader('Host', 'shop.test');

    $api()
        ->postJson("/api/storefront/v1/checkouts/{$checkoutId}/pay", [
            'payment_method' => 'credit_card',
            'card_number' => '4000 0000 0000 0002',
            'card_holder' => 'Test Buyer',
            'card_expiry' => '12/30',
            'card_cvc' => '123',
        ])
        ->assertStatus(402);

    $checkout = Checkout::withoutGlobalScopes()->findOrFail($checkoutId);
    $inventory = InventoryItem::withoutGlobalScopes()->where('variant_id', $variant->getKey())->firstOrFail();

    expect($checkout->status)->toBe(CheckoutStatus::ShippingSelected)
        ->and($inventory->quantity_reserved)->toBe(0);
});