shippingRate; $shippingMethod = $shippingRate->shippingMethod; $cart = $shippingOptionRequest->cart; if (($shippingMethod->data['charge_by'] ?? 'cart_total') !== 'live') { return $this->resolveFixedPrice($shippingRate, $shippingMethod, $cart); } $postcode = $cart->shippingAddress?->postcode; if (! $postcode) { return null; } return $this->resolveLivePrice($shippingRate, $shippingMethod, $cart, $postcode); } private function resolveLivePrice(ShippingRate $shippingRate, $shippingMethod, $cart, string $postcode): ?ShippingOption { try { $destination = $this->areaResolver->resolve($postcode); $response = $this->client->call('ACS_Price_Calculation', [ 'Billing_Code' => config('acs.billing_code'), 'Acs_Station_Destination' => $destination->stationId, 'Weight' => $this->totalWeightInKg($cart), 'Pickup_Date' => now()->toDateString(), 'Charge_Type' => 2, ])->throwIfError(); } catch (AcsApiException $e) { report($e); return null; } $amount = (int) round(($response->valueOutput['Total_Ammount'] ?? 0) * 100); return new ShippingOption( name: $shippingMethod->name ?: $this->name(), description: $shippingMethod->description ?: $this->description(), identifier: $shippingRate->getIdentifier(), price: new Price($amount, $cart->currency, 1), taxClass: $shippingRate->getTaxClass(), taxReference: $shippingRate->getTaxReference(), meta: ['acs_station_destination' => $destination->stationId], ); } public function on(ShippingRate $shippingRate): self { $this->shippingRate = $shippingRate; return $this; } private function totalWeightInKg($cart): float { $weight = 0.0; foreach ($cart->lines->load('purchasable') as $line) { $variant = $line->purchasable; if (! $variant || ! $variant->weight_value) { continue; } $unit = $variant->weight_unit ?? 'kg'; $value = (float) $variant->weight_value; $weight += match ($unit) { 'g' => $value / 1000, 'lb' => $value * 0.45359237, 'oz' => $value * 0.0283495231, default => $value, // kg } * $line->quantity; } return max($weight, 0.5); // ACS minimum billable weight } }