command: cat app/Enums/DiscountType.php app/Enums/DiscountValueType.php; sed -n '1,180p' database/migrations/*create_discounts_table.php 2>/dev/null; rg -n "TaxSettings|provider|shipping|expires|abandoned_cart|bank_transfer" app database specs/05-BUSINESS-LOGIC.md | sed -n '1,240p'

type: unknown

stdout:
<?php

namespace App\Enums;

enum DiscountType: string
{
    case Code = 'code';
    case Automatic = 'automatic';
}
<?php

namespace App\Enums;

enum DiscountValueType: string
{
    case Percent = 'percent';
    case Fixed = 'fixed';
    case FreeShipping = 'free_shipping';
}
zsh:1: no matches found: database/migrations/*create_discounts_table.php
specs/05-BUSINESS-LOGIC.md:80:products, collections, customers, orders, carts, checkouts, discounts, shipping_zones, themes, pages, navigation_menus, analytics_events, analytics_daily, webhook_subscriptions, inventory_items, search_queries.
specs/05-BUSINESS-LOGIC.md:98:| Manage shipping/tax | Yes | Yes | No | No |
specs/05-BUSINESS-LOGIC.md:105:- Register gate definitions in a service provider.
specs/05-BUSINESS-LOGIC.md:241:| **Release** | Checkout expires or is abandoned | No change | -quantity | None |
specs/05-BUSINESS-LOGIC.md:369:    + shipping if taxable (Section 8)"]
specs/05-BUSINESS-LOGIC.md:371:    discounted_subtotal + shipping + tax_total"]
specs/05-BUSINESS-LOGIC.md:382:| `shipping` | integer (cents) | Shipping cost |
specs/05-BUSINESS-LOGIC.md:385:| `total` | integer (cents) | Final amount: discounted_subtotal + shipping + taxTotal |
specs/05-BUSINESS-LOGIC.md:406:- Recalculate on every significant state change: address change (may affect tax/shipping zones), shipping method change, discount code change.
specs/05-BUSINESS-LOGIC.md:415:**Enum:** `App\Enums\CheckoutStatus` - values: `started`, `addressed`, `shipping_selected`, `payment_selected`, `completed`, `expired`
specs/05-BUSINESS-LOGIC.md:421:    addressed --> shipping_selected : Shipping method chosen
specs/05-BUSINESS-LOGIC.md:422:    shipping_selected --> payment_selected : Payment method selected
specs/05-BUSINESS-LOGIC.md:428:    shipping_selected --> expired : Timeout (24h)
specs/05-BUSINESS-LOGIC.md:431:    note right of shipping_selected : Triggers pricing recalculation
specs/05-BUSINESS-LOGIC.md:447:- `shipping_address` with required fields:
specs/05-BUSINESS-LOGIC.md:465:2. Save email and shipping_address_json on the checkout.
specs/05-BUSINESS-LOGIC.md:466:3. Copy shipping address to billing_address_json by default (can be overridden later).
specs/05-BUSINESS-LOGIC.md:467:4. Recalculate pricing (shipping zones and tax regions may change based on address).
specs/05-BUSINESS-LOGIC.md:471:#### Transition: addressed -> shipping_selected
specs/05-BUSINESS-LOGIC.md:473:**Method:** `setShippingMethod(checkout, shippingRateId)`
specs/05-BUSINESS-LOGIC.md:476:- A valid shipping_rate_id that belongs to a shipping zone matching the checkout's shipping address.
specs/05-BUSINESS-LOGIC.md:477:- **Skip condition:** If no cart lines have `requires_shipping = true` on their variant, skip this step. Set status to `shipping_selected` with shipping_method_id = null and shipping_amount = 0.
specs/05-BUSINESS-LOGIC.md:480:1. Resolve available shipping zones for the address (see Section 9).
specs/05-BUSINESS-LOGIC.md:482:3. Save shipping_method_id on the checkout.
specs/05-BUSINESS-LOGIC.md:483:4. Recalculate pricing with the selected shipping rate.
specs/05-BUSINESS-LOGIC.md:484:5. Transition status to `shipping_selected`.
specs/05-BUSINESS-LOGIC.md:487:#### Transition: shipping_selected -> payment_selected
specs/05-BUSINESS-LOGIC.md:492:- All previous data is valid (address, shipping method).
specs/05-BUSINESS-LOGIC.md:494:- `paymentMethod` must be one of: `credit_card`, `paypal`, `bank_transfer`.
specs/05-BUSINESS-LOGIC.md:499:3. Set `expires_at` on the checkout to current time + 24 hours.
specs/05-BUSINESS-LOGIC.md:532:       ELSE IF checkout.payment_method = 'bank_transfer':
specs/05-BUSINESS-LOGIC.md:553:       - Link to order, provider = 'mock', method = checkout.payment_method
specs/05-BUSINESS-LOGIC.md:554:       - provider_payment_id = mock reference ID
specs/05-BUSINESS-LOGIC.md:560:       // Note: for bank_transfer, inventory stays reserved until admin confirms payment
specs/05-BUSINESS-LOGIC.md:632:**Enum:** `App\Enums\DiscountValueType` - values: `percent`, `fixed`, `free_shipping`
specs/05-BUSINESS-LOGIC.md:638:| `free_shipping` | Override shipping amount to 0 | No monetary discount on items. `value_amount` is ignored. |
specs/05-BUSINESS-LOGIC.md:737:- The TaxCalculationRequest contains: line items (with discounted amounts), shipping amount, shipping address, store tax settings.
specs/05-BUSINESS-LOGIC.md:740:**Service:** `App\Services\TaxCalculator` - orchestrates provider selection and delegates to the appropriate implementation.
specs/05-BUSINESS-LOGIC.md:749:1. Match shipping address against shipping zones (same zone matching algorithm as shipping - see Section 9.1).
specs/05-BUSINESS-LOGIC.md:800:- Sends line items and shipping address to Stripe Tax API.
specs/05-BUSINESS-LOGIC.md:801:- Stores the full response in `checkouts.tax_provider_snapshot_json` for audit.
specs/05-BUSINESS-LOGIC.md:833:    zones = load all shipping zones for store
specs/05-BUSINESS-LOGIC.md:862:For the matched zone, return all active shipping rates (`is_active = 1`). Calculate cost for each:
specs/05-BUSINESS-LOGIC.md:878:        IF line.variant.requires_shipping = true:
specs/05-BUSINESS-LOGIC.md:902:A range without `max_amount` matches all subtotals above `min_amount` (useful for "free shipping over X" rules).
specs/05-BUSINESS-LOGIC.md:913:- If no line in the cart has `requires_shipping = true` on its variant, the shipping step is skipped entirely.
specs/05-BUSINESS-LOGIC.md:914:- shipping_amount = 0 in the pricing result.
specs/05-BUSINESS-LOGIC.md:915:- The checkout transitions directly past `shipping_selected` (set status to `shipping_selected` with shipping_method_id = null).
specs/05-BUSINESS-LOGIC.md:923:If a validated discount has `value_type = 'free_shipping'`:
specs/05-BUSINESS-LOGIC.md:924:- Override the calculated shipping amount to 0.
specs/05-BUSINESS-LOGIC.md:925:- The shipping method is still selected (for fulfillment routing), but the customer is not charged.
specs/05-BUSINESS-LOGIC.md:947:**Enum:** `App\Enums\PaymentMethod` - values: `CreditCard` (`credit_card`), `Paypal` (`paypal`), `BankTransfer` (`bank_transfer`)
specs/05-BUSINESS-LOGIC.md:953:| `bank_transfer` | No charge at checkout. Order created with `financial_status = pending`. Admin manually confirms payment receipt. | Deferred - admin confirms payment |
specs/05-BUSINESS-LOGIC.md:957:When payment_method is `credit_card`, the mock provider inspects the card number submitted in the checkout form to determine the outcome:
specs/05-BUSINESS-LOGIC.md:966:The mock provider does **not** validate card expiry, CVC, or cardholder name. These fields exist in the UI for realism but are ignored by the backend.
specs/05-BUSINESS-LOGIC.md:1016:When `payment_method = bank_transfer`, the order confirmation page and email display mock bank transfer details:
specs/05-BUSINESS-LOGIC.md:1030:Admin users can confirm that a bank transfer payment has been received via a "Confirm Payment" button on the order detail page (visible only when `payment_method = bank_transfer` AND `financial_status = pending`).
specs/05-BUSINESS-LOGIC.md:1038:6. If all order lines are digital (`requires_shipping = false`): auto-create fulfillment with `status = delivered` (see Section 11.7).
specs/05-BUSINESS-LOGIC.md:1046:- Finds orders where `payment_method = bank_transfer` AND `financial_status = pending` AND `placed_at < (now - configurable days)`.
specs/05-BUSINESS-LOGIC.md:1047:- Configurable timeout: `store_settings.settings_json` key `bank_transfer_cancel_days`, default = 7.
specs/05-BUSINESS-LOGIC.md:1077:| `bank_transfer` | `pending` | `pending` | Reserve only (reserved incremented, on_hand unchanged) | `pending` |
specs/05-BUSINESS-LOGIC.md:1150:    5. On provider confirmation:
specs/05-BUSINESS-LOGIC.md:1173:**CRITICAL:** A fulfillment cannot be created unless the order's `financial_status` is `paid` or `partially_refunded`. This prevents shipping goods before payment is confirmed.
specs/05-BUSINESS-LOGIC.md:1260:| `bank_transfer` | Inventory reserved only (reserved incremented) | Inventory committed (on_hand decremented, reserved decremented) | No inventory change |
specs/05-BUSINESS-LOGIC.md:1266:When a payment is confirmed (either instant for credit_card/paypal, or via admin confirmation for bank_transfer):
specs/05-BUSINESS-LOGIC.md:1268:1. Check if **all** order lines reference variants with `requires_shipping = false` (digital products).
specs/05-BUSINESS-LOGIC.md:1283:**CSV columns:** `order_number`, `created_at`, `status`, `financial_status`, `fulfillment_status`, `customer_email`, `customer_name`, `subtotal_amount`, `discount_amount`, `shipping_amount`, `tax_amount`, `total_amount`, `currency`, `shipping_method`, `tracking_number`
specs/05-BUSINESS-LOGIC.md:1313:- Configure a dedicated `customers` provider using the Customer model.
specs/05-BUSINESS-LOGIC.md:1606:| `FulfillmentShipped` | Send shipping notification email with tracking info, dispatch webhooks (`order.fulfilled` if fully fulfilled) |
specs/05-BUSINESS-LOGIC.md:1645:| TaxCalculator | `App\Services` | Tax calculation orchestration (delegates to providers) |
specs/05-BUSINESS-LOGIC.md:1679:| DiscountValueType | Percent (`percent`), Fixed (`fixed`), FreeShipping (`free_shipping`) |
specs/05-BUSINESS-LOGIC.md:1681:| CheckoutStatus | Started (`started`), Addressed (`addressed`), ShippingSelected (`shipping_selected`), PaymentSelected (`payment_selected`), Completed (`completed`), Expired (`expired`) |
specs/05-BUSINESS-LOGIC.md:1682:| PaymentMethod | CreditCard (`credit_card`), Paypal (`paypal`), BankTransfer (`bank_transfer`) |
specs/05-BUSINESS-LOGIC.md:1700:| PricingResult | subtotal (int), discount (int), shipping (int), taxLines (array of TaxLine), taxTotal (int), total (int), currency (string) | Complete pricing calculation output |
specs/05-BUSINESS-LOGIC.md:1702:| TaxCalculationRequest | lineItems (array), shippingAmount (int), address (Address), taxSettings (object) | Input for tax providers |
specs/05-BUSINESS-LOGIC.md:1703:| TaxCalculationResult | taxLines (array of TaxLine), totalAmount (int) | Output from tax providers |
specs/05-BUSINESS-LOGIC.md:1707:| RefundResult | success (bool), providerRefundId (string), status (string) | Refund processing result |
specs/05-BUSINESS-LOGIC.md:1709:| ShippingRate | id (int), name (string), amount (int, cents), type (string) | Calculated shipping rate option |
app/ValueObjects/TaxCalculationRequest.php:5:use App\Models\TaxSettings;
app/ValueObjects/TaxCalculationRequest.php:14:        public int $shippingAmount,
app/ValueObjects/TaxCalculationRequest.php:16:        public TaxSettings $settings,
app/ValueObjects/PricingResult.php:8:    public function __construct(public int $subtotal, public int $discount, public int $shipping, public array $taxLines, public int $taxTotal, public int $total, public string $currency) {}
app/ValueObjects/PricingResult.php:12:        return ['subtotal' => $this->subtotal, 'discount' => $this->discount, 'shipping' => $this->shipping, 'tax_lines' => array_map(fn (TaxLine $line): array => $line->toArray(), $this->taxLines), 'tax' => $this->taxTotal, 'total' => $this->total, 'currency' => $this->currency];
app/Services/PricingEngine.php:7:use App\Models\TaxSettings;
app/Services/PricingEngine.php:12:    public function __construct(private readonly DiscountService $discounts, private readonly ShippingCalculator $shipping, private readonly TaxCalculator $taxes) {}
app/Services/PricingEngine.php:16:        $checkout->load(['cart.lines.variant.product.collections', 'shippingRate']);
app/Services/PricingEngine.php:47:        $shippingAmount = $checkout->shippingRate !== null && ! $freeShipping ? $this->shipping->calculate($checkout->shippingRate, $cart) : 0;
app/Services/PricingEngine.php:48:        $taxSettings = TaxSettings::withoutGlobalScopes()->firstOrCreate(['store_id' => $checkout->store_id], ['default_rate_basis_points' => 0]);
app/Services/PricingEngine.php:53:            $taxLines = [...$taxLines, ...$this->taxes->calculate($lineAmount, $taxSettings, $checkout->shipping_address_json ?? [])->lines];
app/Services/PricingEngine.php:56:        if ($shippingAmount > 0) {
app/Services/PricingEngine.php:57:            $taxLines = [...$taxLines, ...$this->taxes->calculate($shippingAmount, $taxSettings, $checkout->shipping_address_json ?? [])->lines];
app/Services/PricingEngine.php:63:        $total = max(0, $discountedSubtotal + $shippingAmount + ($pricesIncludeTax ? 0 : $taxTotal));
app/Services/PricingEngine.php:64:        $result = new PricingResult($subtotal, $discountAmount, $shippingAmount, $taxLines, $taxTotal, $total, $cart->currency);
app/Services/ShippingCalculator.php:41:        $lines = $lines->filter(fn ($line): bool => (bool) $line->variant->requires_shipping);
app/Services/RefundService.php:16:    public function __construct(private readonly PaymentProvider $provider, private readonly InventoryService $inventory, private readonly AuditLogger $audit) {}
app/Services/RefundService.php:73:            $result = $this->provider->refund($payment, $amount);
app/Services/RefundService.php:74:            $refund = $order->refunds()->create(['payment_id' => $payment->getKey(), 'amount' => $amount, 'status' => $result->successful ? 'processed' : 'failed', 'provider_refund_id' => $result->reference, 'reason' => $reason, 'restock' => $restock, 'lines_json' => $lines !== [] ? $lines : null]);
app/Services/Tax/StripeTaxProvider.php:15:        if (($request->settings->provider_config_json['fallback'] ?? 'allow') === 'block') {
app/Services/Tax/ManualTaxProvider.php:29:        if ($request->shippingAmount > 0) {
app/Services/Tax/ManualTaxProvider.php:31:                ? $this->extractInclusive($request->shippingAmount, $rate)
app/Services/Tax/ManualTaxProvider.php:32:                : $this->roundTax($request->shippingAmount, $rate);
app/Services/TaxCalculator.php:6:use App\Models\TaxSettings;
app/Services/TaxCalculator.php:12:    public function __construct(private readonly ?TaxProvider $provider = null) {}
app/Services/TaxCalculator.php:14:    public function calculate(int $amount, TaxSettings $settings, array $address): TaxResult
app/Services/TaxCalculator.php:16:        return ($this->provider ?? new \App\Services\Tax\ManualTaxProvider)->calculate(new TaxCalculationRequest([['amount' => $amount]], 0, $address, $settings));
app/Services/CheckoutService.php:17:    public function __construct(private readonly PricingEngine $pricing, private readonly ShippingCalculator $shipping, private readonly InventoryService $inventory) {}
app/Services/CheckoutService.php:29:        return Checkout::create(['store_id' => $cart->store_id, 'cart_id' => $cart->getKey(), 'customer_id' => $customer?->getKey(), 'status' => CheckoutStatus::Started, 'email' => $email, 'discount_code' => $cart->discount_code, 'expires_at' => now()->addHours(24)]);
app/Services/CheckoutService.php:39:        $checkout->update(['shipping_address_json' => $address, 'billing_address_json' => $useShippingAsBilling ? $address : $billing, 'status' => CheckoutStatus::Addressed]);
app/Services/CheckoutService.php:51:            throw new \LogicException('Checkout must have an address before selecting shipping.');
app/Services/CheckoutService.php:55:            $checkout->update(['shipping_rate_id' => null, 'shipping_method_id' => null, 'status' => CheckoutStatus::ShippingSelected]);
app/Services/CheckoutService.php:62:        if ($checkout->shipping_address_json === null) {
app/Services/CheckoutService.php:63:            throw new \LogicException('An address is required before selecting shipping.');
app/Services/CheckoutService.php:66:        $rate = $checkout->shipping_address_json === null ? null : $this->shipping->getAvailableRates($checkout->store, $checkout->shipping_address_json)->firstWhere('id', $rateId);
app/Services/CheckoutService.php:69:            throw new \InvalidArgumentException('The selected shipping method is unavailable.');
app/Services/CheckoutService.php:72:        $checkout->update(['shipping_rate_id' => $rate->getKey(), 'shipping_method_id' => $rate->getKey(), 'status' => CheckoutStatus::ShippingSelected]);
app/Services/CheckoutService.php:81:        Validator::make(['method' => $method], ['method' => ['required', 'in:credit_card,paypal,bank_transfer']])->validate();
app/Services/CheckoutService.php:85:        if ($checkout->shipping_address_json === null) {
app/Services/CheckoutService.php:89:        if ($this->requiresShipping($checkout) && $checkout->shipping_rate_id === null) {
app/Services/CheckoutService.php:90:            throw new \LogicException('A shipping method is required before selecting payment.');
app/Services/CheckoutService.php:94:            throw new \LogicException('Checkout must have a selected shipping method before selecting payment.');
app/Services/CheckoutService.php:106:            $checkout->update(['payment_method' => $method, 'status' => CheckoutStatus::PaymentSelected, 'expires_at' => now()->addHours(24)]);
app/Services/CheckoutService.php:136:        return $checkout->cart->lines->contains(fn ($line): bool => (bool) $line->variant->requires_shipping);
app/Services/PaymentService.php:18:    public function __construct(private readonly PaymentProvider $provider, private readonly InventoryService $inventory, private readonly OrderService $orders, private readonly PricingEngine $pricing) {}
app/Services/PaymentService.php:38:            $result = $this->provider->charge($checkout, $method, $details);
app/Services/PaymentService.php:54:            Payment::create(['order_id' => $order->getKey(), 'provider' => 'mock', 'provider_payment_id' => $result->reference, 'method' => $method, 'status' => $result->status, 'amount' => $order->total_amount, 'currency' => $order->currency, 'raw_json' => ['reference' => $result->reference, 'message' => $result->message]]);
app/Services/OrderService.php:29:            $checkout->load(['cart.lines.variant.product', 'cart.lines.variant.inventory', 'shippingRate']);
app/Services/OrderService.php:36:            $totals = $checkout->totals_json ?? ['subtotal' => 0, 'discount' => 0, 'shipping' => 0, 'tax' => 0, 'total' => 0, 'currency' => $checkout->cart->currency];
app/Services/OrderService.php:59:                'shipping_address_json' => $checkout->shipping_address_json,
app/Services/OrderService.php:63:                'shipping_amount' => $totals['shipping'] ?? 0,
app/Services/OrderService.php:103:                if ($checkout->cart->lines->every(fn ($line): bool => ! $line->variant->requires_shipping)) {
app/Services/OrderService.php:150:        if ($order->payment_method !== 'bank_transfer' || $order->financial_status !== FinancialStatus::Pending) {
app/Services/OrderService.php:167:            if ($order->lines->every(fn ($line): bool => ! $line->variant?->requires_shipping)) {
database/factories/StoreInvitationFactory.php:25:            'expires_at' => now()->addDays(7),
app/Jobs/CancelUnpaidBankTransferOrders.php:19:        $days = (int) config('shop.bank_transfer_expiry_days', 7);
app/Jobs/CancelUnpaidBankTransferOrders.php:20:        Order::withoutGlobalScopes()->where('payment_method', 'bank_transfer')->where('financial_status', FinancialStatus::Pending)->where('placed_at', '<', now()->subDays($days))->with('lines.variant.inventory')->each(fn (Order $order): mixed => $orders->cancel($order, 'Bank transfer payment expired.'));
app/Jobs/GenerateOrderExport.php:29:                ->with(['customer', 'checkout.shippingRate'])
app/Jobs/GenerateOrderExport.php:38:            fputcsv($handle, ['order_number', 'created_at', 'status', 'financial_status', 'fulfillment_status', 'customer_email', 'customer_name', 'subtotal_amount', 'discount_amount', 'shipping_amount', 'tax_amount', 'total_amount', 'currency', 'shipping_method', 'tracking_number']);
app/Jobs/GenerateOrderExport.php:51:                    $order->shipping_amount,
app/Jobs/GenerateOrderExport.php:55:                    $order->checkout?->shippingRate?->name,
app/Jobs/GenerateOrderExport.php:65:            $expiresAt = now()->addHour();
app/Jobs/GenerateOrderExport.php:67:            $this->export->update(['status' => 'completed', 'row_count' => $orders->count(), 'storage_key' => $key, 'download_url' => Storage::disk('public')->url($key), 'download_expires_at' => $expiresAt, 'completed_at' => now()]);
app/Jobs/ExpireAbandonedCheckouts.php:20:        Checkout::withoutGlobalScopes()->whereNotIn('status', [CheckoutStatus::Completed, CheckoutStatus::Expired])->where('expires_at', '<', now())->with('cart.lines.variant.inventory')->each(function (Checkout $checkout) use ($inventory): void {
app/Http/Controllers/Api/PlatformController.php:61:            ['role' => $data['role'], 'invited_at' => now(), 'expires_at' => now()->addDays(7), 'accepted_at' => null],
app/Http/Controllers/Api/PlatformController.php:64:        return response()->json(['data' => ['email' => $invitation->email, 'role' => $invitation->role, 'invited_at' => $invitation->invited_at, 'expires_at' => $invitation->expires_at]], 201);
app/Http/Controllers/Api/PlatformController.php:117:        return response()->json(['upload_url' => $uploadUrl, 'method' => 'PUT', 'headers' => ['Content-Type' => $data['content_type']], 'storage_key' => $storageKey, 'media_id' => $media->getKey(), 'expires_at' => now()->addMinutes(10)], 201);
app/Http/Controllers/Api/StorefrontCartController.php:103:        $lines = $cart->lines->map(fn ($line): array => ['id' => $line->id, 'variant_id' => $line->variant_id, 'product_title' => $line->variant->product->title, 'variant_title' => $line->variant->title, 'sku' => $line->variant->sku, 'quantity' => $line->quantity, 'unit_price_amount' => $line->unit_price_amount, 'line_subtotal_amount' => $line->line_subtotal_amount, 'line_discount_amount' => $line->line_discount_amount, 'line_total_amount' => $line->line_total_amount, 'image_url' => $line->variant->product->media->first()?->url, 'requires_shipping' => $line->variant->requires_shipping, 'available_quantity' => $line->variant->inventory?->availableQuantity() ?? 0])->values()->all();
app/Http/Controllers/Api/StorefrontCheckoutController.php:24:    public function __construct(private readonly CheckoutService $checkouts, private readonly PricingEngine $pricing, private readonly ShippingCalculator $shipping, private readonly DiscountService $discounts, private readonly PaymentService $payments) {}
app/Http/Controllers/Api/StorefrontCheckoutController.php:57:        $useShippingAsBilling = $request->boolean('use_shipping_as_billing', true);
app/Http/Controllers/Api/StorefrontCheckoutController.php:60:            $checkout = $this->checkouts->setAddress($checkout, $data['shipping_address'] ?? [], $data['billing_address'] ?? null, $useShippingAsBilling);
app/Http/Controllers/Api/StorefrontCheckoutController.php:70:    public function shippingMethod(Request $request, int $checkoutId): JsonResponse
app/Http/Controllers/Api/StorefrontCheckoutController.php:72:        $data = $request->validate(['shipping_method_id' => ['required', 'integer'], 'shipping_rate_id' => ['nullable', 'integer']]);
app/Http/Controllers/Api/StorefrontCheckoutController.php:74:            $checkout = $this->checkouts->setShippingMethod($this->checkout($checkoutId), $data['shipping_rate_id'] ?? $data['shipping_method_id']);
app/Http/Controllers/Api/StorefrontCheckoutController.php:109:            'payment_method' => ['required', 'string', 'in:credit_card,paypal,bank_transfer'],
app/Http/Controllers/Api/StorefrontCheckoutController.php:130:            $payload['bank_transfer_instructions'] = ['bank_name' => 'Mock Bank AG', 'iban' => 'DE89 3704 0044 0532 0130 00', 'bic' => 'COBADEFFXXX', 'reference' => $order->order_number, 'amount_formatted' => number_format($order->total_amount / 100, 2, '.', '').' '.$order->currency];
app/Http/Controllers/Api/StorefrontCheckoutController.php:138:        $data = $request->validate(['payment_method' => ['required', 'in:credit_card,paypal,bank_transfer']]);
app/Http/Controllers/Api/StorefrontCheckoutController.php:152:        $checkout = Checkout::query()->with(['cart.lines.variant.product', 'shippingRate'])->findOrFail($checkoutId);
app/Http/Controllers/Api/StorefrontCheckoutController.php:169:        $rates = $checkout->shipping_address_json === null ? collect() : $this->shipping->getAvailableRates(app('current_store'), $checkout->shipping_address_json);
app/Http/Controllers/Api/StorefrontCheckoutController.php:171:        return ['id' => $checkout->id, 'store_id' => $checkout->store_id, 'cart_id' => $checkout->cart_id, 'customer_id' => $checkout->customer_id, 'status' => $checkout->status, 'email' => $checkout->email, 'payment_method' => $checkout->payment_method, 'shipping_address_json' => $checkout->shipping_address_json, 'billing_address_json' => $checkout->billing_address_json, 'shipping_method_id' => $checkout->shipping_rate_id, 'discount_code' => $checkout->discount_code, 'lines' => $checkout->cart->lines->map(fn ($line): array => ['variant_id' => $line->variant_id, 'product_title' => $line->variant->product->title, 'variant_title' => $line->variant->title, 'sku' => $line->variant->sku, 'quantity' => $line->quantity, 'unit_price_amount' => $line->unit_price_amount, 'line_total_amount' => $line->line_total_amount])->all(), 'totals' => $totals, 'available_shipping_methods' => $rates->map(fn ($rate): array => ['id' => $rate->id, 'name' => $rate->name, 'type' => $rate->type, 'price_amount' => $rate->price_amount, 'currency' => $rate->currency, 'estimated_days_min' => $rate->estimated_days_min, 'estimated_days_max' => $rate->estimated_days_max])->all(), 'expires_at' => $checkout->expires_at, 'created_at' => $checkout->created_at];
app/Http/Controllers/Api/StorefrontOrderController.php:20:        return response()->json(['order_number' => $order->order_number, 'status' => $order->status, 'financial_status' => $order->financial_status, 'fulfillment_status' => $order->fulfillment_status, 'email' => $order->email, 'currency' => $order->currency, 'placed_at' => $order->placed_at, 'lines' => $order->lines->map(fn ($line): array => ['title_snapshot' => $line->title_snapshot, 'variant_title' => $line->variant_title, 'sku_snapshot' => $line->sku_snapshot, 'quantity' => $line->quantity, 'unit_price_amount' => $line->unit_price_amount, 'total_amount' => $line->line_total_amount])->all(), 'totals' => ['subtotal_amount' => $order->subtotal_amount, 'discount_amount' => $order->discount_amount, 'shipping_amount' => $order->shipping_amount, 'tax_amount' => $order->tax_amount, 'total_amount' => $order->total_amount], 'shipping_address' => $order->shipping_address_json, 'billing_address' => $order->billing_address_json, 'fulfillments' => $order->fulfillments->map(fn ($fulfillment): array => ['id' => $fulfillment->id, 'status' => $fulfillment->status, 'tracking_company' => $fulfillment->tracking_company, 'tracking_number' => $fulfillment->tracking_number, 'tracking_url' => $fulfillment->tracking_url])->all()]);
database/seeders/DatabaseSeeder.php:21:            TaxSettingsSeeder::class,
app/Http/Controllers/Api/AdminController.php:22:use App\Http\Requests\UpdateTaxSettingsRequest;
app/Http/Controllers/Api/AdminController.php:34:use App\Models\TaxSettings;
app/Http/Controllers/Api/AdminController.php:220:    public function shippingZones(int $storeId): JsonResponse
app/Http/Controllers/Api/AdminController.php:254:        return response()->json(['data' => ShippingRate::create([...$data, 'shipping_zone_id' => $zoneId, 'price_amount' => $price, 'currency' => $currency, 'config_json' => $config, 'is_active' => $data['is_active'] ?? true])], 201);
app/Http/Controllers/Api/AdminController.php:261:        return response()->json(['data' => TaxSettings::withoutGlobalScopes()->firstOrCreate(['store_id' => $storeId])]);
app/Http/Controllers/Api/AdminController.php:264:    public function updateTaxSettings(UpdateTaxSettingsRequest $request, int $storeId): JsonResponse
app/Http/Controllers/Api/AdminController.php:268:        $settings = TaxSettings::withoutGlobalScopes()->updateOrCreate(['store_id' => $storeId], [...$data, 'provider_config_json' => $data['config_json']]);
app/Http/Controllers/Api/AdminController.php:408:        return response()->json(['data' => ['id' => $export->getKey(), 'status' => $export->status, 'format' => $export->format, 'row_count' => $export->row_count, 'download_url' => $export->download_url, 'download_expires_at' => $export->download_expires_at, 'created_at' => $export->created_at, 'completed_at' => $export->completed_at, 'error_message' => $export->error_message]]);
database/seeders/OrderSeeder.php:46:            ['customer_id' => $customer?->getKey(), 'currency' => 'EUR', 'status' => $orderData['status'], 'financial_status' => $orderData['financial_status'], 'fulfillment_status' => $orderData['fulfillment_status'], 'payment_method' => $orderData['payment_method'], 'email' => $customer?->email ?? $orderData['customer'], 'shipping_address_json' => $address, 'billing_address_json' => $address, 'subtotal_amount' => $orderData['subtotal_amount'], 'discount_amount' => $orderData['discount_amount'], 'shipping_amount' => $orderData['shipping_amount'], 'tax_amount' => $orderData['tax_amount'], 'total_amount' => $orderData['total_amount'], 'placed_at' => $orderData['placed_at'], 'metadata' => ['seed_fixture' => true]],
database/seeders/OrderSeeder.php:83:        $payment = $order->payments()->create(['provider' => 'mock', 'provider_payment_id' => $orderData['provider_payment_id'], 'method' => $orderData['payment_method'], 'status' => $orderData['payment_status'], 'amount' => $orderData['total_amount'], 'currency' => 'EUR']);
database/seeders/OrderSeeder.php:91:            $order->refunds()->create(['payment_id' => $payment->getKey(), 'amount' => $orderData['refund']['amount'], 'reason' => $orderData['refund']['reason'], 'status' => RefundStatus::Processed, 'restock' => false, 'provider_refund_id' => $orderData['refund']['provider_refund_id'], 'lines_json' => $refundLines]);
database/seeders/OrderSeeder.php:109:            array_merge($base, ['order_number' => '#1001', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(2), 'lines' => [['handle' => 'classic-cotton-t-shirt', 'variant' => 'S / White', 'quantity' => 2]], 'subtotal_amount' => 4998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 798, 'total_amount' => 5497, 'provider_payment_id' => 'mock_test_order1001', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:110:            array_merge($base, ['order_number' => '#1002', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(10), 'lines' => [['handle' => 'organic-hoodie', 'variant' => 'M', 'quantity' => 1], ['handle' => 'classic-cotton-t-shirt', 'variant' => 'L / Black', 'quantity' => 1]], 'subtotal_amount' => 8498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1357, 'total_amount' => 8997, 'provider_payment_id' => 'mock_test_order1002', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'DHL', 'tracking_number' => 'DHL1234567890', 'shipped_at' => now()->subDays(8), 'delivered_at' => now()->subDays(2), 'line_indexes' => [0, 1]]]),
database/seeders/OrderSeeder.php:111:            array_merge($base, ['order_number' => '#1003', 'customer' => 'jane@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Partial, 'placed_at' => now()->subDays(5), 'lines' => [['handle' => 'premium-slim-fit-jeans', 'variant' => '32 / Blue', 'quantity' => 1], ['handle' => 'leather-belt', 'variant' => 'L/XL / Brown', 'quantity' => 1]], 'subtotal_amount' => 11498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1836, 'total_amount' => 11997, 'provider_payment_id' => 'mock_test_order1003', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Shipped, 'tracking_company' => 'DHL', 'tracking_number' => 'DHL9876543210', 'shipped_at' => now()->subDays(3), 'delivered_at' => null, 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:112:            array_merge($base, ['order_number' => '#1004', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Cancelled, 'financial_status' => FinancialStatus::Refunded, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(15), 'lines' => [['handle' => 'classic-cotton-t-shirt', 'variant' => 'M / Navy', 'quantity' => 1]], 'subtotal_amount' => 2499, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 399, 'total_amount' => 2998, 'provider_payment_id' => 'mock_test_order1004', 'payment_status' => PaymentStatus::Refunded, 'refund' => ['amount' => 2998, 'reason' => 'Customer requested cancellation', 'provider_refund_id' => 'mock_re_test_order1004', 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:113:            array_merge($base, ['order_number' => '#1005', 'customer' => 'jane@example.com', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Pending, 'financial_status' => FinancialStatus::Pending, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subHours(2), 'lines' => [['handle' => 'leather-belt', 'variant' => 'S/M / Black', 'quantity' => 1]], 'subtotal_amount' => 3499, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 559, 'total_amount' => 3998, 'provider_payment_id' => 'mock_test_order1005', 'payment_status' => PaymentStatus::Pending]),
database/seeders/OrderSeeder.php:114:            array_merge($base, ['order_number' => '#1006', 'customer' => 'michael@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'running-sneakers', 'variant' => 'EU 42 / Black', 'quantity' => 1]], 'subtotal_amount' => 11999, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1916, 'total_amount' => 12498, 'provider_payment_id' => 'mock_test_order1006', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:115:            array_merge($base, ['order_number' => '#1007', 'customer' => 'sarah@example.com', 'payment_method' => PaymentMethod::Paypal, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(20), 'lines' => [['handle' => 'v-neck-linen-tee', 'variant' => 'M / Beige', 'quantity' => 2], ['handle' => 'wool-scarf', 'variant' => 'Grey', 'quantity' => 1]], 'subtotal_amount' => 9997, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1596, 'total_amount' => 10496, 'provider_payment_id' => 'mock_test_order1007', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'DHL', 'tracking_number' => 'DHL1112223334', 'shipped_at' => now()->subDays(18), 'delivered_at' => now()->subDays(12), 'line_indexes' => [0, 1]]]),
database/seeders/OrderSeeder.php:116:            array_merge($base, ['order_number' => '#1008', 'customer' => 'david@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::PartiallyRefunded, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(12), 'lines' => [['handle' => 'cargo-pants', 'variant' => '32 / Khaki', 'quantity' => 1], ['handle' => 'graphic-print-tee', 'variant' => 'L', 'quantity' => 1]], 'subtotal_amount' => 8498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1357, 'total_amount' => 8997, 'provider_payment_id' => 'mock_test_order1008', 'payment_status' => PaymentStatus::Captured, 'refund' => ['amount' => 2999, 'reason' => 'Item returned', 'provider_refund_id' => 'mock_re_test_order1008', 'line_indexes' => [1]], 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'UPS', 'tracking_number' => 'UPS5556667778', 'shipped_at' => now()->subDays(10), 'delivered_at' => now()->subDays(4), 'line_indexes' => [0, 1]]]),
database/seeders/OrderSeeder.php:117:            array_merge($base, ['order_number' => '#1009', 'customer' => 'emma@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(3), 'lines' => [['handle' => 'canvas-tote-bag', 'variant' => 'Natural', 'quantity' => 1], ['handle' => 'bucket-hat', 'variant' => 'S/M / Black', 'quantity' => 1]], 'subtotal_amount' => 4498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 718, 'total_amount' => 4997, 'provider_payment_id' => 'mock_test_order1009', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:118:            array_merge($base, ['order_number' => '#1010', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::Paypal, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'cashmere-overcoat', 'variant' => 'M / Camel', 'quantity' => 1]], 'subtotal_amount' => 49999, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 7983, 'total_amount' => 50498, 'provider_payment_id' => 'mock_test_order1010', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:119:            array_merge($base, ['order_number' => '#1011', 'customer' => 'james@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(25), 'lines' => [['handle' => 'striped-polo-shirt', 'variant' => 'XL', 'quantity' => 1]], 'subtotal_amount' => 2799, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 447, 'total_amount' => 3298, 'provider_payment_id' => 'mock_test_order1011', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'FedEx', 'tracking_number' => 'FX9998887776', 'shipped_at' => now()->subDays(23), 'delivered_at' => now()->subDays(20), 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:120:            array_merge($base, ['order_number' => '#1012', 'customer' => 'lisa@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(4), 'lines' => [['handle' => 'chino-shorts', 'variant' => '34 / Navy', 'quantity' => 2]], 'subtotal_amount' => 7998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1277, 'total_amount' => 8497, 'provider_payment_id' => 'mock_test_order1012', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:121:            array_merge($base, ['order_number' => '#1013', 'customer' => 'robert@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'wide-leg-trousers', 'variant' => 'M', 'quantity' => 1], ['handle' => 'wool-scarf', 'variant' => 'Burgundy', 'quantity' => 1]], 'subtotal_amount' => 7998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1277, 'total_amount' => 8497, 'provider_payment_id' => 'mock_test_order1013', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:122:            array_merge($base, ['order_number' => '#1014', 'customer' => 'anna@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(14), 'lines' => [['handle' => 'gift-card', 'variant' => '50 EUR', 'quantity' => 1]], 'subtotal_amount' => 5000, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 798, 'total_amount' => 5000, 'provider_payment_id' => 'mock_test_order1014', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => null, 'tracking_number' => null, 'shipped_at' => now()->subDays(14), 'delivered_at' => now()->subDays(14), 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:123:            array_merge($base, ['order_number' => '#1015', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now(), 'lines' => [['handle' => 'classic-cotton-t-shirt', 'variant' => 'M / White', 'quantity' => 1, 'discount_amount' => 250, 'discount_id' => $discountId], ['handle' => 'graphic-print-tee', 'variant' => 'M', 'quantity' => 1, 'discount_amount' => 300, 'discount_id' => $discountId]], 'subtotal_amount' => 5498, 'discount_amount' => 550, 'shipping_amount' => 499, 'tax_amount' => 790, 'total_amount' => 5447, 'provider_payment_id' => 'mock_test_order1015', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:132:            ['store_id' => $storeId, 'order_number' => '#5001', 'customer' => 'techfan@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(6), 'lines' => [['handle' => 'pro-laptop-15', 'variant' => '512GB', 'quantity' => 1], ['handle' => 'usb-c-cable-2m', 'variant' => 'Default', 'quantity' => 1]], 'subtotal_amount' => 121298, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 121298, 'provider_payment_id' => 'mock_test_order5001', 'payment_status' => PaymentStatus::Captured],
database/seeders/OrderSeeder.php:133:            ['store_id' => $storeId, 'order_number' => '#5002', 'customer' => 'gadgetlover@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(2), 'lines' => [['handle' => 'wireless-headphones', 'variant' => 'Black', 'quantity' => 1]], 'subtotal_amount' => 14999, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 14999, 'provider_payment_id' => 'mock_test_order5002', 'payment_status' => PaymentStatus::Captured],
database/seeders/OrderSeeder.php:134:            ['store_id' => $storeId, 'order_number' => '#5003', 'customer' => 'techfan@example.com', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Pending, 'financial_status' => FinancialStatus::Pending, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subHours(4), 'lines' => [['handle' => 'monitor-stand', 'variant' => 'Default', 'quantity' => 1]], 'subtotal_amount' => 4999, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 4999, 'provider_payment_id' => 'mock_test_order5003', 'payment_status' => PaymentStatus::Pending],
database/factories/CheckoutFactory.php:30:            'shipping_address_json' => ['first_name' => fake()->firstName(), 'last_name' => fake()->lastName(), 'address1' => fake()->streetAddress(), 'city' => fake()->city(), 'country_code' => 'DE', 'zip' => fake()->postcode()],
database/factories/CheckoutFactory.php:32:            'shipping_rate_id' => null,
database/factories/CheckoutFactory.php:33:            'shipping_method_id' => null,
database/factories/CheckoutFactory.php:36:            'tax_provider_snapshot_json' => null,
database/factories/CheckoutFactory.php:38:            'expires_at' => now()->addDay(),
database/factories/CheckoutFactory.php:49:        return $this->state(['status' => CheckoutStatus::Expired, 'expires_at' => now()->subHour()]);
database/factories/CheckoutFactory.php:64:        return $this->state(['payment_method' => 'bank_transfer']);
app/Livewire/Admin/Developers/Index.php:55:        $expiresAt = empty($data['tokenExpiresAt']) ? null : CarbonImmutable::parse($data['tokenExpiresAt']);
app/Livewire/Admin/Developers/Index.php:56:        $this->plainTextToken = auth()->user()->createToken($data['tokenName'], $abilities, $expiresAt)->plainTextToken;
app/Http/Requests/StoreProductRequest.php:51:            'variants.*.requires_shipping' => ['nullable', 'boolean'],
app/Http/Requests/UpdateDiscountRequest.php:30:            'value_type' => ['sometimes', 'in:fixed,percent,free_shipping'],
app/Http/Requests/StoreDiscountRequest.php:30:            'value_type' => ['required', 'in:fixed,percent,free_shipping'],
app/Http/Requests/StoreDiscountRequest.php:31:            'value_amount' => ['required_unless:value_type,free_shipping', 'integer', 'min:0'],
database/seeders/ProductSeeder.php:60:                ['title' => $variantTitle, 'sku' => $sku, 'barcode' => null, 'price_amount' => $price, 'compare_at_amount' => $productData['compare_at'], 'currency' => 'EUR', 'cost_amount' => null, 'weight_grams' => $productData['weight_g'], 'weight_g' => $productData['weight_g'], 'requires_shipping' => $productData['requires_shipping'], 'is_default' => $position === 0, 'status' => $productData['variant_status'], 'metadata' => []],
database/seeders/ProductSeeder.php:157:        return ['title' => $title, 'handle' => $handle, 'sku_prefix' => $skuPrefix, 'vendor' => $vendor, 'product_type' => $productType, 'tags' => $tags, 'description_html' => '<p>'.str_replace('.', '. ', $title).' is made for comfortable everyday use with thoughtful details.</p>', 'status' => $status, 'published_at' => $publishedAt ?? now(), 'price' => $price, 'compare_at' => $compareAt, 'weight_g' => $weight, 'inventory' => $inventory, 'policy' => $policy, 'requires_shipping' => $requiresShipping, 'variant_status' => $status === ProductStatus::Archived ? VariantStatus::Archived : VariantStatus::Active, 'options' => collect($options)->map(fn (array $values, string $name): array => ['name' => $name, 'values' => $values])->values()->all(), 'collections' => $collections];
database/seeders/ShippingSeeder.php:46:                ['shipping_zone_id' => $zone->getKey(), 'name' => $rate['name']],
database/seeders/ShopSeeder.php:25:            TaxSettingsSeeder::class,
database/seeders/ShopSeeder.php:62:            ['title' => 'Default', 'sku' => 'ACME-LEGACY-SOLD-OUT', 'price_amount' => 3999, 'compare_at_amount' => null, 'currency' => 'EUR', 'weight_grams' => 250, 'weight_g' => 250, 'requires_shipping' => true, 'is_default' => true, 'status' => VariantStatus::Active, 'metadata' => []],
database/seeders/TaxSettingsSeeder.php:6:use App\Models\TaxSettings;
database/seeders/TaxSettingsSeeder.php:9:class TaxSettingsSeeder extends Seeder
database/seeders/TaxSettingsSeeder.php:17:            TaxSettings::withoutGlobalScopes()->updateOrCreate(
database/seeders/TaxSettingsSeeder.php:19:                ['mode' => 'manual', 'provider' => 'none', 'prices_include_tax' => true, 'config_json' => ['default_rate_bps' => 1900], 'default_rate_basis_points' => 1900, 'rates_json' => ['DE' => 1900], 'provider_config_json' => []],
app/Http/Requests/UpdateProductRequest.php:52:            'variants.*.requires_shipping' => ['sometimes', 'boolean'],
app/Http/Requests/UpdateTaxSettingsRequest.php:8:class UpdateTaxSettingsRequest extends FormRequest
app/Http/Requests/UpdateTaxSettingsRequest.php:25:        return ['mode' => ['required', 'in:manual,provider'], 'provider' => ['required_if:mode,provider', 'nullable', 'in:none,stripe_tax'], 'prices_include_tax' => ['required', 'boolean'], 'config_json' => ['required', 'array'], 'default_rate_basis_points' => ['sometimes', 'integer', 'min:0', 'max:10000'], 'rates_json' => ['sometimes', 'array'], 'provider_config_json' => ['sometimes', 'array']];
database/migrations/2026_08_20_000000_create_shop_schema.php:116:            $table->boolean('requires_shipping')->default(true);
database/migrations/2026_08_20_000000_create_shop_schema.php:261:        Schema::create('shipping_zones', function (Blueprint $table): void {
database/migrations/2026_08_20_000000_create_shop_schema.php:271:        Schema::create('shipping_rates', function (Blueprint $table): void {
database/migrations/2026_08_20_000000_create_shop_schema.php:273:            $table->foreignId('shipping_zone_id')->constrained()->cascadeOnDelete();
database/migrations/2026_08_20_000000_create_shop_schema.php:283:            $table->index(['shipping_zone_id', 'is_active']);
database/migrations/2026_08_20_000000_create_shop_schema.php:291:            $table->json('provider_config_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:374:            $table->json('shipping_address_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:376:            $table->foreignId('shipping_rate_id')->nullable()->constrained('shipping_rates')->nullOnDelete();
database/migrations/2026_08_20_000000_create_shop_schema.php:379:            $table->json('tax_provider_snapshot_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:380:            $table->timestamp('expires_at')->nullable()->index();
database/migrations/2026_08_20_000000_create_shop_schema.php:398:            $table->json('shipping_address_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:402:            $table->unsignedInteger('shipping_amount')->default(0);
database/migrations/2026_08_20_000000_create_shop_schema.php:436:            $table->string('provider')->default('mock');
database/migrations/2026_08_20_000000_create_shop_schema.php:437:            $table->string('provider_payment_id')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:443:            $table->index(['provider', 'provider_payment_id']);
database/migrations/2026_08_20_000000_create_shop_schema.php:544:            $table->timestamp('expires_at')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:581:            'checkouts', 'cart_lines', 'carts', 'discounts', 'tax_settings', 'shipping_rates',
database/migrations/2026_08_20_000000_create_shop_schema.php:582:            'shipping_zones', 'search_queries', 'search_settings', 'navigation_items',
app/Livewire/Admin/Discounts/Form.php:118:            'valueType' => ['required', 'in:percent,fixed,free_shipping'],
app/Livewire/Admin/Discounts/Form.php:119:            'valueAmount' => ['nullable', 'integer', 'min:0', 'required_unless:valueType,free_shipping'],
database/factories/ProductVariantFactory.php:27:            'requires_shipping' => true,
database/factories/ProductVariantFactory.php:45:        return $this->state(['requires_shipping' => false, 'weight_grams' => 0, 'weight_g' => 0]);
database/factories/ShippingRateFactory.php:23:            'shipping_zone_id' => ShippingZoneFactory::new(),
database/factories/OrderFactory.php:21:        return ['store_id' => Store::factory(), 'customer_id' => Customer::factory(), 'order_number' => '#'.fake()->unique()->numberBetween(1001, 9999), 'currency' => 'EUR', 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'payment_method' => 'credit_card', 'email' => fake()->safeEmail(), 'shipping_address_json' => $address, 'billing_address_json' => $address, 'subtotal_amount' => 4998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 798, 'total_amount' => 5497, 'placed_at' => now(), 'metadata' => []];
database/factories/OrderFactory.php:66:        return $this->state(['payment_method' => 'bank_transfer']);
database/factories/RefundFactory.php:30:            'provider_refund_id' => 'mock_re_'.fake()->unique()->bothify('????????????????????'),

formatted_output:
Warning: truncated output (original token count: 13207)
Total output lines: 260

<?php

namespace App\Enums;

enum DiscountType: string
{
    case Code = 'code';
    case Automatic = 'automatic';
}
<?php

namespace App\Enums;

enum DiscountValueType: string
{
    case Percent = 'percent';
    case Fixed = 'fixed';
    case FreeShipping = 'free_shipping';
}
zsh:1: no matches found: database/migrations/*create_discounts_table.php
specs/05-BUSINESS-LOGIC.md:80:products, collections, customers, orders, carts, checkouts, discounts, shipping_zones, themes, pages, navigation_menus, analytics_events, analytics_daily, webhook_subscriptions, inventory_items, search_queries.
specs/05-BUSINESS-LOGIC.md:98:| Manage shipping/tax | Yes | Yes | No | No |
specs/05-BUSINESS-LOGIC.md:105:- Register gate definitions in a service provider.
specs/05-BUSINESS-LOGIC.md:241:| **Release** | Checkout expires or is abandoned | No change | -quantity | None |
specs/05-BUSINESS-LOGIC.md:369:    + shipping if taxable (Section 8)"]
specs/05-BUSINESS-LOGIC.md:371:    discounted_subtotal + shipping + tax_total"]
specs/05-BUSINESS-LOGIC.md:382:| `shipping` | integer (cents) | Shipping cost |
specs/05-BUSINESS-LOGIC.md:385:| `total` | integer (cents) | Final amount: discounted_subtotal + shipping + taxTotal |
specs/05-BUSINESS-LOGIC.md:406:- Recalculate on every significant state change: address change (may affect tax/shipping zones), shipping method change, discount code change.
specs/05-BUSINESS-LOGIC.md:415:**Enum:** `App\Enums\CheckoutStatus` - values: `started`, `addressed`, `shipping_selected`, `payment_selected`, `completed`, `expired`
specs/05-BUSINESS-LOGIC.md:421:    addressed --> shipping_selected : Shipping method chosen
specs/05-BUSINESS-LOGIC.md:422:    shipping_selected --> payment_selected : Payment method selected
specs/05-BUSINESS-LOGIC.md:428:    shipping_selected --> expired : Timeout (24h)
specs/05-BUSINESS-LOGIC.md:431:    note right of shipping_selected : Triggers pricing recalculation
specs/05-BUSINESS-LOGIC.md:447:- `shipping_address` with required fields:
specs/05-BUSINESS-LOGIC.md:465:2. Save email and shipping_address_json on the checkout.
specs/05-BUSINESS-LOGIC.md:466:3. Copy shipping address to billing_address_json by default (can be overridden later).
specs/05-BUSINESS-LOGIC.md:467:4. Recalculate pricing (shipping zones and tax regions may change based on address).
specs/05-BUSINESS-LOGIC.md:471:#### Transition: addressed -> shipping_selected
specs/05-BUSINESS-LOGIC.md:473:**Method:** `setShippingMethod(checkout, shippingRateId)`
specs/05-BUSINESS-LOGIC.md:476:- A valid shipping_rate_id that belongs to a shipping zone matching the checkout's shipping address.
specs/05-BUSINESS-LOGIC.md:477:- **Skip condition:** If no cart lines have `requires_shipping = true` on their variant, skip this step. Set status to `shipping_selected` with shipping_method_id = null and shipping_amount = 0.
specs/05-BUSINESS-LOGIC.md:480:1. Resolve available shipping zones for the address (see Section 9).
specs/05-BUSINESS-LOGIC.md:482:3. Save shipping_method_id on the checkout.
specs/05-BUSINESS-LOGIC.md:483:4. Recalculate pricing with the selected shipping rate.
specs/05-BUSINESS-LOGIC.md:484:5. Transition status to `shipping_selected`.
specs/05-BUSINESS-LOGIC.md:487:#### Transition: shipping_selected -> payment_selected
specs/05-BUSINESS-LOGIC.md:492:- All previous data is valid (address, shipping method).
specs/05-BUSINESS-LOGIC.md:494:- `paymentMethod` must be one of: `credit_card`, `paypal`, `bank_transfer`.
specs/05-BUSINESS-LOGIC.md:499:3. Set `expires_at` on the checkout to current time + 24 hours.
specs/05-BUSINESS-LOGIC.md:532:       ELSE IF checkout.payment_method = 'bank_transfer':
specs/05-BUSINESS-LOGIC.md:553:       - Link to order, provider = 'mock', method = checkout.payment_method
specs/05-BUSINESS-LOGIC.md:554:       - provider_payment_id = mock reference ID
specs/05-BUSINESS-LOGIC.md:560:       // Note: for bank_transfer, inventory stays reserved until admin confirms payment
specs/05-BUSINESS-LOGIC.md:632:**Enum:** `App\Enums\DiscountValueType` - values: `percent`, `fixed`, `free_shipping`
specs/05-BUSINESS-LOGIC.md:638:| `free_shipping` | Override shipping amount to 0 | No monetary discount on items. `value_amount` is ignored. |
specs/05-BUSINESS-LOGIC.md:737:- The TaxCalculationRequest contains: line items (with discounted amounts), shipping amount, shipping address, store tax settings.
specs/05-BUSINESS-LOGIC.md:740:**Service:** `App\Services\TaxCalculator` - orchestrates provider selection and delegates to the appropriate implementation.
specs/05-BUSINESS-LOGIC.md:749:1. Match shipping address against shipping zones (same zone matching algorithm as shipping - see Section 9.1).
specs/05-BUSINESS-LOGIC.md:800:- Sends line items and shipping address to Stripe Tax API.
specs/05-BUSINESS-LOGIC.md:801:- Stores the full response in `checkouts.tax_provider_snapshot_json` for audit.
specs/05-BUSINESS-LOGIC.md:833:    zones = load all shipping zones for store
specs/05-BUSINESS-LOGIC.md:862:For the matched zone, return all active shipping rates (`is_active = 1`). Calculate cost for each:
specs/05-BUSINESS-LOGIC.md:878:        IF line.variant.requires_shipping = true:
specs/05-BUSINESS-LOGIC.md:902:A range without `max_amount` matches all subtotals above `min_amount` (useful for "free shipping over X" rules).
specs/05-BUSINESS-LOGIC.md:913:- If no line in the cart has `requires_shipping = true` on its variant, the shipping step is skipped entirely.
specs/05-BUSINESS-LOGIC.md:914:- shipping_amount = 0 in the pricing result.
specs/05-BUSINESS-LOGIC.md:915:- The checkout transitions directly past `shipping_selected` (set status to `shipping_selected` with shipping_method_id = null).
specs/05-BUSINESS-LOGIC.md:923:If a validated discount has `value_type = 'free_shipping'`:
specs/05-BUSINESS-LOGIC.md:924:- Override the calculated shipping amount to 0.
specs/05-BUSINESS-LOGIC.md:925:- The shipping method is still selected (for fulfillment routing), but the customer is not charged.
specs/05-BUSINESS-LOGIC.md:947:**Enum:** `App\Enums\PaymentMethod` - values: `CreditCard` (`credit_card`), `Paypal` (`paypal`), `BankTransfer` (`bank_transfer`)
specs/05-BUSINESS-LOGIC.md:953:| `bank_transfer` | No charge at checkout. Order created with `financial_status = pending`. Admin manually confirms payment receipt. | Deferred - admin confirms payment |
specs/05-BUSINESS-LOGIC.md:957:When payment_method is `credit_card`, the mock provider inspects the card number submitted in the checkout form to determine the outcome:
specs/05-BUSINESS-LOGIC.md:966:The mock provider does **not** validate card expiry, CVC, or cardholder name. These fields exist in the UI for realism but are ignored by the backend.
specs/05-BUSINESS-LOGIC.md:1016:When `payment_method = bank_transfer`, the order confirmation page and email display mock bank transfer details:
specs/05-BUSINESS-LOGIC.md:1030:Admin users can confirm that a bank transfer payment has been received via a "Confirm Payment" button on the order detail page (visible only when `payment_method = bank_transfer` AND `financial_status = pending`).
specs/05-BUSINESS-LOGIC.md:1038:6. If all order lines are digital (`requires_shipping = false`): auto-create fulfillment with `status = delivered` (see Section 11.7).
specs/05-BUSINESS-LOGIC.md:1046:- Finds orders where `payment_method = bank_transfer` AND `financial_status = pending` AND `placed_at < (now - configurable days)`.
specs/05-BUSINESS-LOGIC.md:1047:- Configurable timeout: `store_settings.settings_json` key `bank_transfer_cancel_days`, default = 7.
specs/05-BUSINESS-LOGIC.md:1077:| `bank_transfer` | `pending` | `pending` | Reserve only (reserved incremented, on_hand unchanged) | `pending` |
specs/05-BUSINESS-LOGIC.md:1150:    5. On provider confirmation:
specs/05-BUSINESS-LOGIC.md:1173:**CRITICAL:** A fulfillment cannot be created unless the order's `financial_status` is `paid` or `partially_refunded`. This prevents shipping goods before payment is confirmed.
specs/05-BUSINESS-LOGIC.md:1260:| `bank_transfer` | Inventory reserved only (reserved incremented) | Inventory committed (on_hand decremented, reserved decremented) | No inventory change |
specs/05-BUSINESS-LOGIC.md:1266:When a payment is confirmed (either instant for credit_card/paypal, or via admin confirmation for bank_transfer):
specs/05-BUSINESS-LOGIC.md:1268:1. Check if **all** order lines reference variants with `requires_shipping = false` (digital products).
specs/05-BUSINESS-LOGIC.md:1283:**CSV columns:** `order_number`, `created_at`, `status`, `financial_status`, `fulfillment_status`, `customer_email`, `customer_name`, `subtotal_amount`, `discount_amount`, `shipping_amount`, `tax_amount`, `total_amount`, `currency`, `shipping_method`, `tracking_number`
specs/05-BUSINESS-LOGIC.md:1313:- Configure a dedicated `customers` provider using the Customer model.
specs/05-BUSINESS-LOGIC.md:1606:| `FulfillmentShipped` | Send shipping notification email with tracking info, dispatch webhooks (`order.fulfilled` if fully fulfilled) |
specs/05-BUSINESS-LOGIC.md:1645:| TaxCalculator | `App\Services` | Tax calculation orchestration (delegates to providers) |
specs/05-BUSINESS-LOGIC.md:1679:| DiscountValueType | Percent (`percent`), Fixed (`fixed`), FreeShipping (`free_shipping`) |
specs/05-BUSINESS-LOGIC.md:1681:| CheckoutStatus | Started (`started`), Addressed (`addressed`), ShippingSelected (`shipping_selected`), PaymentSelected (`payment_selected`), Completed (`completed`), Expired (`expired`) |
specs/05-BUSINESS-LOGIC.md:1682:| PaymentMethod | CreditCard (`credit_card`), Paypal (`paypal`), BankTransfer (`bank_transfer`) |
specs/05-BUSINESS-LOGIC.md:1700:| PricingResult | subtotal (int), discount (int), shipping (int), taxLines (array of TaxLine), taxTotal (int), total (int), currency (string) | Complete pricing calculation output |
specs/05-BUSINESS-LOGIC.md:1702:| TaxCalculationRequest | lineItems (array), shippingAmount (int), address (Address), taxSettings (object) | Input for tax providers |
specs/05-BUSINESS-LOGIC.md:1703:| TaxCalculationResult | taxLines (array of TaxLine), totalAmount (int) | Output from tax providers |
specs/05-BUSINESS-LOGIC.md:1707:| RefundResult | success (bool), providerRefundId (string), status (string) | Refund processing result |
specs/05-BUSINESS-LOGIC.md:1709:| ShippingRate | id (int), name (string), amount (int, cents), type (string) | Calculated shipping rate option |
app/ValueObjects/TaxCalculationRequest.php:5:use App\Models\TaxSettings;
app/ValueObjects/TaxCalculationRequest.php:14:        public int $shippingAmount,
app/ValueObjects/TaxCalculationRequest.php:16:        public TaxSettings $settings,
app/ValueObjects/PricingResult.php:8:    public function __construct(public int $subtotal, public int $discount, public int $shipping, public array $taxLines, public int $taxTotal, public int $total, public string $currency) {}
app/ValueObjects/PricingResult.php:12:        return ['subtotal' => $this->subtotal, 'discount' => $this->discount, 'shipping' => $this->shipping, 'tax_lines' => array_map(fn (TaxLine $line): array => $line->toArray(), $this->taxLines), 'tax' => $this->taxTotal, 'total' => $this->total, 'currency' => $this->currency];
app/Services/PricingEngine.php:7:use App\Models\TaxSettings;
app/Services/PricingEngine.php:12:    public function __construct(private readonly DiscountService $discounts, private readonly ShippingCalculator $shipping, private readonly TaxCalculator $taxes) {}
app/Services/PricingEngine.php:16:        $checkout->load(['cart.lines.variant.product.collections', 'shippingRate']);
app/Services/PricingEngine.php:47:        $shippingAmount = $checkout->shippingRate !== null && ! $freeShipping ? $this->shipping->calculate($checkout->shippingRate, $cart) : 0;
app/Services/PricingEngine.php:48:        $taxSettings = TaxSettings::withoutGlobalScopes()->firstOrCreate(['store_id' => $checkout->store_id], ['default_rate_basis_points' => 0]);
app/Services/PricingEngine.php:53:            $taxLines = [...$taxLines, ...$this->taxes->calculate($lineAmount, $taxSettings, $checkout->shipping_address_json ?? [])->lines];
app/Services/PricingEngine.php:56:        if ($shippingAmount > 0) {
app/Services/PricingEngine.php:57:            $taxLines = [...$taxLines, ...$this->taxes->calculate($shippingAmount, $taxSettings, $checkout->shipping_address_json ?? [])->lines];
app/Services/PricingEngine.php:63:        $total = max(0, $discountedSubtotal + $shippingAmount + ($pricesIncludeTax ? 0 : $taxTotal));
app/Services/PricingEngine.php:64:        $result = new PricingResult($subtotal, $discountAmount, $shippingAmount, $taxLines, $taxTotal, $total, $cart->currency);
app/Services/ShippingCalculator.php:41:        $lines = $lines->filter(fn ($line): bool => (bool) $line->variant->requires_shipping);
app/Services/RefundService.php:16:    public function __construct(private readonly PaymentProvider $provider, private readonly InventoryService $inventory, private readonly AuditLogger $audit) {}
app/Services/RefundService.php:73:            $result = $this->provider->refund($payment, $amount);
app/Services/RefundService.php:74:            $refund = $order->refunds()->create(['payment_id' => $payment->getKey(), 'amount' => $amount, 'status' => $result->successful ? 'processed' : 'failed', 'provider_refund_id' => $result->reference, 'reason' => $reason, 'restock' => $restock, 'lines_json' => $lines !== [] ? $lines : null]);
app/Services/Tax/StripeTaxProvider.php:15:        if (($request->settings->provider_config_json['fallback'] ?? 'allow') === 'block') {
app/Services/Tax/ManualTaxProvider.php:29:        if ($request->shippingAmount > 0) {
app/Services/Tax/ManualTaxProvider.php:31:                ? $this->extractInclusive($request->shippingAmount, $rate)
app/Services/Tax/ManualTaxProvider.php:32:                : $this->roundTax($request->shippingAmount, $rate);
app/Services/TaxCalculator.php:6:use App\Models\TaxSettings;
app/Services/TaxCalculator.php:12:    public function __construct(private readonly ?TaxProvider $provider = null) {}
app/Services/TaxCalculator.php:14:    public function calculate(int $amount, TaxSettings $settings, array $address): TaxResult
app/Services/TaxCalculator.php:16:        return ($this->provider ?? new \App\Services\Tax\ManualTaxProvider)->calculate(new TaxCalculationRequest([['amount' => $amount]], 0, $address, $settings));
app/Services/CheckoutService.php:17:    public function __construct(private readonly PricingEngine $pricing, private readonly ShippingCalculator $shipping, private readonly InventoryService $inventory) {}
app/Services/CheckoutService.php:29:        return Checkout::create(['store_id' => $cart->store_id, 'cart_id' => $cart->getKey(), 'customer_id' => $customer?->getKey(), 'status' => CheckoutStatus::Started, 'email' => $email, 'discount_code' => $cart->discount_code, 'expires_at' => now()->addHours(24)]);
app/Services/CheckoutService.php:39:        $checkout->update(['shipping_address_json' => $address, 'billing_address_json' => $useShippingAsBilling ? $address : $billing, 'status' => CheckoutStatus::Addressed]);
app/Services/CheckoutService.php:51:            throw new \LogicException('Checkout must have an address before selecting shipping.');
app/Services/CheckoutService.php:55:            $checkout->update(['shipping_rate_id' => null, 'shipping_method_id' => null, 'status' => CheckoutStatus::ShippingSelected]);
app/Services/CheckoutService.php:62:        if ($checkout->shipping_address_json === null) {
app/Services/CheckoutService.php:63:            throw new \LogicException('An address is required before selecting shipping.');
app/Services/CheckoutService.php:66:        $rate = $checkout->shipping_address_json === null ? null : $this->shipping->getAvailableRates($checkout->store, $checkout->shipping_address_json)->firstWhere('id', $rateId);
app/Services/CheckoutService.php:69:            throw new \InvalidArgumentException('The selected shipping method is unavailable.');
app/Services/CheckoutService.php:72:        $checkout->update(['shipping_rate_id' => $rate->getKey(), 'shipping_method_id' => $rate->getKey(), 'status' => CheckoutStatus::ShippingSelected]);
app/Services/CheckoutService.php:81:        Validator::make(['method' => $method], ['method' => ['required', 'in:credit_card,paypal,bank_transfer']])->validate();
app/Services/CheckoutService.php:85:        if ($checkout->shipping_address_json === null) {
app/Services/CheckoutService.php:89:        if ($this->requiresShipping($checkout) && $checkout->shipping_rate_id === null) {
app/Services/CheckoutService.php:90:            throw new \LogicException('A shipping method is required before selecting payment.');
app/Services/CheckoutService.php:94:            throw new \LogicException('Checkout must have a selected shipping method before selecting payment.');
app/Services/CheckoutService.php:106:            $checkout->update(['payment_method' => $method, 'status' => CheckoutStatus::PaymentSelected, 'expires_at' => now()->addHours(24)]);
app/Services/CheckoutService.php:136:        return $checkout->cart->lines->contains(fn ($line): bool => (bool) $line->variant->requires_shipping);
app/Services/PaymentService.php:18:    public function __construct(private readonly PaymentProvider $provider, private readonly InventoryService $inventory, private readonly OrderService $orders, private readonly PricingEngine $pricing) {}
app/Services/PaymentService.php:38:            $result = $this->provider->charge($checkout, $method, $details);
app/Services/PaymentService.php:54:            Payment::create(['order_id' => $order->getKey(), 'provider' => 'mock', 'provider_payment_id' => $result->reference, 'method' => $method, 'status' => $result->status, 'amount' => $order->total_amount, 'currency' => $order->currency, 'raw_json' => ['reference' => $result->reference, 'message' => $result->message]]);
app/Services/OrderService.php:29:            $checkout->load(['cart.lines.variant.product', 'cart.lines.variant.inventory', 'shippingRate']);
app/Services/OrderService.php:36:            $totals = $checkout->totals_json ?? ['subtotal' => 0, 'discount' => 0, 'shipping' => 0, 'tax' => 0, 'total' => 0, 'currency' => $checkout->cart->currency];
app/Services/OrderService.php:59:                'shipping_address_json' => $checkout->shipping_address_json,
app/Services/OrderService.php:63:                'shipping_amount' => $totals['shipping'] ?? 0,
app/Services/OrderService.php:103:                if ($checkout->cart->lines->every(fn ($line): bool => ! $line->variant->requires_shipping)) {
app/Services/OrderService.php:150:        if ($order->payment_method !== 'bank_transfer' || $order->financial_status !== FinancialStatus::Pending) {
app/Services/OrderService.php:167:            if ($order->lines->every(fn ($line): bool => ! $line->variant?->requires_shipping)) {
database/factories/StoreInvitationFactory.php:25:            'expires_at' => now()->addDays(7),
app/Jobs/CancelUnpaidBankTransferOrders.php:19:        $days = (int) config('shop.bank_transfer_expiry_days', 7);
app/Jobs/CancelUnpaidBankTransferOrders.php:20:        Order::withoutGlobalScopes()->where('payment_method', 'bank_transfer')->where('financial_status', FinancialStatus::Pending)->where('placed_at', '<', now()->subDays($days))->with('lines.variant.inventory')->each(fn (Order $order): mixed => $orders->cancel($order, 'Bank transfer payment expired.'));
app/Jobs/GenerateOrderExport.php:29:                ->with(['customer', 'checkout.shippingRate'])
app/Jobs/GenerateOrderExport.php:38:            fputcsv($handle, ['order_number', 'created_at', 'status', 'financial_status', 'fulfillment_status', 'customer_email', 'customer_name', 'subtotal_amount', 'discount_amount', 'shipping_amount', 'tax_amount', 'total_amount', 'currency', 'shipping_method', 'tracking_number']);
app/Jobs/GenerateOrderExport.php:51:                    $order->shipping_amount,
app/Jobs/GenerateOrderExport.php:55:                    $order->checkou…3207 tokens truncated…tus::Cancelled, 'financial_status' => FinancialStatus::Refunded, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(15), 'lines' => [['handle' => 'classic-cotton-t-shirt', 'variant' => 'M / Navy', 'quantity' => 1]], 'subtotal_amount' => 2499, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 399, 'total_amount' => 2998, 'provider_payment_id' => 'mock_test_order1004', 'payment_status' => PaymentStatus::Refunded, 'refund' => ['amount' => 2998, 'reason' => 'Customer requested cancellation', 'provider_refund_id' => 'mock_re_test_order1004', 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:113:            array_merge($base, ['order_number' => '#1005', 'customer' => 'jane@example.com', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Pending, 'financial_status' => FinancialStatus::Pending, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subHours(2), 'lines' => [['handle' => 'leather-belt', 'variant' => 'S/M / Black', 'quantity' => 1]], 'subtotal_amount' => 3499, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 559, 'total_amount' => 3998, 'provider_payment_id' => 'mock_test_order1005', 'payment_status' => PaymentStatus::Pending]),
database/seeders/OrderSeeder.php:114:            array_merge($base, ['order_number' => '#1006', 'customer' => 'michael@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'running-sneakers', 'variant' => 'EU 42 / Black', 'quantity' => 1]], 'subtotal_amount' => 11999, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1916, 'total_amount' => 12498, 'provider_payment_id' => 'mock_test_order1006', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:115:            array_merge($base, ['order_number' => '#1007', 'customer' => 'sarah@example.com', 'payment_method' => PaymentMethod::Paypal, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(20), 'lines' => [['handle' => 'v-neck-linen-tee', 'variant' => 'M / Beige', 'quantity' => 2], ['handle' => 'wool-scarf', 'variant' => 'Grey', 'quantity' => 1]], 'subtotal_amount' => 9997, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1596, 'total_amount' => 10496, 'provider_payment_id' => 'mock_test_order1007', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'DHL', 'tracking_number' => 'DHL1112223334', 'shipped_at' => now()->subDays(18), 'delivered_at' => now()->subDays(12), 'line_indexes' => [0, 1]]]),
database/seeders/OrderSeeder.php:116:            array_merge($base, ['order_number' => '#1008', 'customer' => 'david@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::PartiallyRefunded, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(12), 'lines' => [['handle' => 'cargo-pants', 'variant' => '32 / Khaki', 'quantity' => 1], ['handle' => 'graphic-print-tee', 'variant' => 'L', 'quantity' => 1]], 'subtotal_amount' => 8498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1357, 'total_amount' => 8997, 'provider_payment_id' => 'mock_test_order1008', 'payment_status' => PaymentStatus::Captured, 'refund' => ['amount' => 2999, 'reason' => 'Item returned', 'provider_refund_id' => 'mock_re_test_order1008', 'line_indexes' => [1]], 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'UPS', 'tracking_number' => 'UPS5556667778', 'shipped_at' => now()->subDays(10), 'delivered_at' => now()->subDays(4), 'line_indexes' => [0, 1]]]),
database/seeders/OrderSeeder.php:117:            array_merge($base, ['order_number' => '#1009', 'customer' => 'emma@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(3), 'lines' => [['handle' => 'canvas-tote-bag', 'variant' => 'Natural', 'quantity' => 1], ['handle' => 'bucket-hat', 'variant' => 'S/M / Black', 'quantity' => 1]], 'subtotal_amount' => 4498, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 718, 'total_amount' => 4997, 'provider_payment_id' => 'mock_test_order1009', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:118:            array_merge($base, ['order_number' => '#1010', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::Paypal, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'cashmere-overcoat', 'variant' => 'M / Camel', 'quantity' => 1]], 'subtotal_amount' => 49999, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 7983, 'total_amount' => 50498, 'provider_payment_id' => 'mock_test_order1010', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:119:            array_merge($base, ['order_number' => '#1011', 'customer' => 'james@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(25), 'lines' => [['handle' => 'striped-polo-shirt', 'variant' => 'XL', 'quantity' => 1]], 'subtotal_amount' => 2799, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 447, 'total_amount' => 3298, 'provider_payment_id' => 'mock_test_order1011', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => 'FedEx', 'tracking_number' => 'FX9998887776', 'shipped_at' => now()->subDays(23), 'delivered_at' => now()->subDays(20), 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:120:            array_merge($base, ['order_number' => '#1012', 'customer' => 'lisa@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(4), 'lines' => [['handle' => 'chino-shorts', 'variant' => '34 / Navy', 'quantity' => 2]], 'subtotal_amount' => 7998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1277, 'total_amount' => 8497, 'provider_payment_id' => 'mock_test_order1012', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:121:            array_merge($base, ['order_number' => '#1013', 'customer' => 'robert@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDay(), 'lines' => [['handle' => 'wide-leg-trousers', 'variant' => 'M', 'quantity' => 1], ['handle' => 'wool-scarf', 'variant' => 'Burgundy', 'quantity' => 1]], 'subtotal_amount' => 7998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 1277, 'total_amount' => 8497, 'provider_payment_id' => 'mock_test_order1013', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:122:            array_merge($base, ['order_number' => '#1014', 'customer' => 'anna@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(14), 'lines' => [['handle' => 'gift-card', 'variant' => '50 EUR', 'quantity' => 1]], 'subtotal_amount' => 5000, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 798, 'total_amount' => 5000, 'provider_payment_id' => 'mock_test_order1014', 'payment_status' => PaymentStatus::Captured, 'fulfillment' => ['status' => FulfillmentShipmentStatus::Delivered, 'tracking_company' => null, 'tracking_number' => null, 'shipped_at' => now()->subDays(14), 'delivered_at' => now()->subDays(14), 'line_indexes' => [0]]]),
database/seeders/OrderSeeder.php:123:            array_merge($base, ['order_number' => '#1015', 'customer' => 'customer@acme.test', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now(), 'lines' => [['handle' => 'classic-cotton-t-shirt', 'variant' => 'M / White', 'quantity' => 1, 'discount_amount' => 250, 'discount_id' => $discountId], ['handle' => 'graphic-print-tee', 'variant' => 'M', 'quantity' => 1, 'discount_amount' => 300, 'discount_id' => $discountId]], 'subtotal_amount' => 5498, 'discount_amount' => 550, 'shipping_amount' => 499, 'tax_amount' => 790, 'total_amount' => 5447, 'provider_payment_id' => 'mock_test_order1015', 'payment_status' => PaymentStatus::Captured]),
database/seeders/OrderSeeder.php:132:            ['store_id' => $storeId, 'order_number' => '#5001', 'customer' => 'techfan@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Fulfilled, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Fulfilled, 'placed_at' => now()->subDays(6), 'lines' => [['handle' => 'pro-laptop-15', 'variant' => '512GB', 'quantity' => 1], ['handle' => 'usb-c-cable-2m', 'variant' => 'Default', 'quantity' => 1]], 'subtotal_amount' => 121298, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 121298, 'provider_payment_id' => 'mock_test_order5001', 'payment_status' => PaymentStatus::Captured],
database/seeders/OrderSeeder.php:133:            ['store_id' => $storeId, 'order_number' => '#5002', 'customer' => 'gadgetlover@example.com', 'payment_method' => PaymentMethod::CreditCard, 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subDays(2), 'lines' => [['handle' => 'wireless-headphones', 'variant' => 'Black', 'quantity' => 1]], 'subtotal_amount' => 14999, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 14999, 'provider_payment_id' => 'mock_test_order5002', 'payment_status' => PaymentStatus::Captured],
database/seeders/OrderSeeder.php:134:            ['store_id' => $storeId, 'order_number' => '#5003', 'customer' => 'techfan@example.com', 'payment_method' => PaymentMethod::BankTransfer, 'status' => OrderStatus::Pending, 'financial_status' => FinancialStatus::Pending, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'placed_at' => now()->subHours(4), 'lines' => [['handle' => 'monitor-stand', 'variant' => 'Default', 'quantity' => 1]], 'subtotal_amount' => 4999, 'discount_amount' => 0, 'shipping_amount' => 0, 'tax_amount' => 0, 'total_amount' => 4999, 'provider_payment_id' => 'mock_test_order5003', 'payment_status' => PaymentStatus::Pending],
database/factories/CheckoutFactory.php:30:            'shipping_address_json' => ['first_name' => fake()->firstName(), 'last_name' => fake()->lastName(), 'address1' => fake()->streetAddress(), 'city' => fake()->city(), 'country_code' => 'DE', 'zip' => fake()->postcode()],
database/factories/CheckoutFactory.php:32:            'shipping_rate_id' => null,
database/factories/CheckoutFactory.php:33:            'shipping_method_id' => null,
database/factories/CheckoutFactory.php:36:            'tax_provider_snapshot_json' => null,
database/factories/CheckoutFactory.php:38:            'expires_at' => now()->addDay(),
database/factories/CheckoutFactory.php:49:        return $this->state(['status' => CheckoutStatus::Expired, 'expires_at' => now()->subHour()]);
database/factories/CheckoutFactory.php:64:        return $this->state(['payment_method' => 'bank_transfer']);
app/Livewire/Admin/Developers/Index.php:55:        $expiresAt = empty($data['tokenExpiresAt']) ? null : CarbonImmutable::parse($data['tokenExpiresAt']);
app/Livewire/Admin/Developers/Index.php:56:        $this->plainTextToken = auth()->user()->createToken($data['tokenName'], $abilities, $expiresAt)->plainTextToken;
app/Http/Requests/StoreProductRequest.php:51:            'variants.*.requires_shipping' => ['nullable', 'boolean'],
app/Http/Requests/UpdateDiscountRequest.php:30:            'value_type' => ['sometimes', 'in:fixed,percent,free_shipping'],
app/Http/Requests/StoreDiscountRequest.php:30:            'value_type' => ['required', 'in:fixed,percent,free_shipping'],
app/Http/Requests/StoreDiscountRequest.php:31:            'value_amount' => ['required_unless:value_type,free_shipping', 'integer', 'min:0'],
database/seeders/ProductSeeder.php:60:                ['title' => $variantTitle, 'sku' => $sku, 'barcode' => null, 'price_amount' => $price, 'compare_at_amount' => $productData['compare_at'], 'currency' => 'EUR', 'cost_amount' => null, 'weight_grams' => $productData['weight_g'], 'weight_g' => $productData['weight_g'], 'requires_shipping' => $productData['requires_shipping'], 'is_default' => $position === 0, 'status' => $productData['variant_status'], 'metadata' => []],
database/seeders/ProductSeeder.php:157:        return ['title' => $title, 'handle' => $handle, 'sku_prefix' => $skuPrefix, 'vendor' => $vendor, 'product_type' => $productType, 'tags' => $tags, 'description_html' => '<p>'.str_replace('.', '. ', $title).' is made for comfortable everyday use with thoughtful details.</p>', 'status' => $status, 'published_at' => $publishedAt ?? now(), 'price' => $price, 'compare_at' => $compareAt, 'weight_g' => $weight, 'inventory' => $inventory, 'policy' => $policy, 'requires_shipping' => $requiresShipping, 'variant_status' => $status === ProductStatus::Archived ? VariantStatus::Archived : VariantStatus::Active, 'options' => collect($options)->map(fn (array $values, string $name): array => ['name' => $name, 'values' => $values])->values()->all(), 'collections' => $collections];
database/seeders/ShippingSeeder.php:46:                ['shipping_zone_id' => $zone->getKey(), 'name' => $rate['name']],
database/seeders/ShopSeeder.php:25:            TaxSettingsSeeder::class,
database/seeders/ShopSeeder.php:62:            ['title' => 'Default', 'sku' => 'ACME-LEGACY-SOLD-OUT', 'price_amount' => 3999, 'compare_at_amount' => null, 'currency' => 'EUR', 'weight_grams' => 250, 'weight_g' => 250, 'requires_shipping' => true, 'is_default' => true, 'status' => VariantStatus::Active, 'metadata' => []],
database/seeders/TaxSettingsSeeder.php:6:use App\Models\TaxSettings;
database/seeders/TaxSettingsSeeder.php:9:class TaxSettingsSeeder extends Seeder
database/seeders/TaxSettingsSeeder.php:17:            TaxSettings::withoutGlobalScopes()->updateOrCreate(
database/seeders/TaxSettingsSeeder.php:19:                ['mode' => 'manual', 'provider' => 'none', 'prices_include_tax' => true, 'config_json' => ['default_rate_bps' => 1900], 'default_rate_basis_points' => 1900, 'rates_json' => ['DE' => 1900], 'provider_config_json' => []],
app/Http/Requests/UpdateProductRequest.php:52:            'variants.*.requires_shipping' => ['sometimes', 'boolean'],
app/Http/Requests/UpdateTaxSettingsRequest.php:8:class UpdateTaxSettingsRequest extends FormRequest
app/Http/Requests/UpdateTaxSettingsRequest.php:25:        return ['mode' => ['required', 'in:manual,provider'], 'provider' => ['required_if:mode,provider', 'nullable', 'in:none,stripe_tax'], 'prices_include_tax' => ['required', 'boolean'], 'config_json' => ['required', 'array'], 'default_rate_basis_points' => ['sometimes', 'integer', 'min:0', 'max:10000'], 'rates_json' => ['sometimes', 'array'], 'provider_config_json' => ['sometimes', 'array']];
database/migrations/2026_08_20_000000_create_shop_schema.php:116:            $table->boolean('requires_shipping')->default(true);
database/migrations/2026_08_20_000000_create_shop_schema.php:261:        Schema::create('shipping_zones', function (Blueprint $table): void {
database/migrations/2026_08_20_000000_create_shop_schema.php:271:        Schema::create('shipping_rates', function (Blueprint $table): void {
database/migrations/2026_08_20_000000_create_shop_schema.php:273:            $table->foreignId('shipping_zone_id')->constrained()->cascadeOnDelete();
database/migrations/2026_08_20_000000_create_shop_schema.php:283:            $table->index(['shipping_zone_id', 'is_active']);
database/migrations/2026_08_20_000000_create_shop_schema.php:291:            $table->json('provider_config_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:374:            $table->json('shipping_address_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:376:            $table->foreignId('shipping_rate_id')->nullable()->constrained('shipping_rates')->nullOnDelete();
database/migrations/2026_08_20_000000_create_shop_schema.php:379:            $table->json('tax_provider_snapshot_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:380:            $table->timestamp('expires_at')->nullable()->index();
database/migrations/2026_08_20_000000_create_shop_schema.php:398:            $table->json('shipping_address_json')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:402:            $table->unsignedInteger('shipping_amount')->default(0);
database/migrations/2026_08_20_000000_create_shop_schema.php:436:            $table->string('provider')->default('mock');
database/migrations/2026_08_20_000000_create_shop_schema.php:437:            $table->string('provider_payment_id')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:443:            $table->index(['provider', 'provider_payment_id']);
database/migrations/2026_08_20_000000_create_shop_schema.php:544:            $table->timestamp('expires_at')->nullable();
database/migrations/2026_08_20_000000_create_shop_schema.php:581:            'checkouts', 'cart_lines', 'carts', 'discounts', 'tax_settings', 'shipping_rates',
database/migrations/2026_08_20_000000_create_shop_schema.php:582:            'shipping_zones', 'search_queries', 'search_settings', 'navigation_items',
app/Livewire/Admin/Discounts/Form.php:118:            'valueType' => ['required', 'in:percent,fixed,free_shipping'],
app/Livewire/Admin/Discounts/Form.php:119:            'valueAmount' => ['nullable', 'integer', 'min:0', 'required_unless:valueType,free_shipping'],
database/factories/ProductVariantFactory.php:27:            'requires_shipping' => true,
database/factories/ProductVariantFactory.php:45:        return $this->state(['requires_shipping' => false, 'weight_grams' => 0, 'weight_g' => 0]);
database/factories/ShippingRateFactory.php:23:            'shipping_zone_id' => ShippingZoneFactory::new(),
database/factories/OrderFactory.php:21:        return ['store_id' => Store::factory(), 'customer_id' => Customer::factory(), 'order_number' => '#'.fake()->unique()->numberBetween(1001, 9999), 'currency' => 'EUR', 'status' => OrderStatus::Paid, 'financial_status' => FinancialStatus::Paid, 'fulfillment_status' => FulfillmentStatus::Unfulfilled, 'payment_method' => 'credit_card', 'email' => fake()->safeEmail(), 'shipping_address_json' => $address, 'billing_address_json' => $address, 'subtotal_amount' => 4998, 'discount_amount' => 0, 'shipping_amount' => 499, 'tax_amount' => 798, 'total_amount' => 5497, 'placed_at' => now(), 'metadata' => []];
database/factories/OrderFactory.php:66:        return $this->state(['payment_method' => 'bank_transfer']);
database/factories/RefundFactory.php:30:            'provider_refund_id' => 'mock_re_'.fake()->unique()->bothify('????????????????????'),