Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

spree-shipping-fulfillment

/spree-shipping-fulfillment

Buduje i dostosowuje wysyłkę i realizację zamówień w Spree: metody, strefy, stawki, Stock::Estimator, magazyny, kalkulatory, zwroty i integrację z API przewoźników UPS, FedEx i ShipStation.

Licencja
MIT
Ostatnia zmiana repozytorium
14.09.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
1
Przestarzałość

Brak sygnałów. Repozytorium zmienione 14.09.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Buduje i dostosowuje wysyłkę i realizację zamówień w Spree: metody, strefy, stawki, Stock::Estimator, magazyny, kalkulatory, zwroty i integrację z API przewoźników UPS, FedEx i ShipStation.

Oryginalny opis (EN)

Build and customize Spree's shipping and fulfillment — ShippingMethod, ShippingCategory, Zone/ZoneMember, ShippingRate, the Stock::Estimator service, StockLocation/StockItem/StockMovement, multi-shipment orders, ShippingCalculator classes (FlatRate, FlatPercentItemTotal, PerItem, FlexiRate), shipment state machine, returns (ReturnAuthorization → CustomerReturn → Reimbursement → Refund), and integrating carrier APIs (UPS, FedEx, ShipStation). Use when configuring shipping rules, building fulfillment integrations, or debugging shipping-rate calculations.

Jak działa

  1. Before writing code
  2. Conceptual Architecture
  3. Implementation Guidance
Sekcje z nagłówków SKILL.md, w oryginale · 239 linii, 953 słów
Podgląd SKILL.md
---
name: spree-shipping-fulfillment
description: Build and customize Spree's shipping and fulfillment — ShippingMethod, ShippingCategory, Zone/ZoneMember, ShippingRate, the Stock::Estimator service, StockLocation/StockItem/StockMovement, multi-shipment orders, ShippingCalculator classes (FlatRate, FlatPercentItemTotal, PerItem, FlexiRate), shipment state machine, returns (ReturnAuthorization → CustomerReturn → Reimbursement → Refund), and integrating carrier APIs (UPS, FedEx, ShipStation). Use when configuring shipping rules, building fulfillment integrations, or debugging shipping-rate calculations.
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
---

# Spree Shipping & Fulfillment

## Before writing code

**Fetch live docs**:
1. Fetch https://spreecommerce.org/docs/developer/core-concepts/architecture (shipping section) for the current model graph.
2. Inspect `Spree::Stock::Estimator` and `Spree::Stock::Splitter` in the live `spree` gem source.
3. Check the live `Spree::ShippingMethod` source for column names and associations.
4. For carrier integrations, search community gems (`spree-active-shipping`, `spree-ups`, `spree-fedex`) — verify which are maintained for v5.
5. Check release notes for any shipping-related changes (Markets in v5.4 affect shipping availability per region).

## Conceptual Architecture

### The Core Models

| Model | Purpose |
|-------|---------|
| **`ShippingMethod`** | Named shipping option (UPS Ground, FedEx 2-Day) |
| **`ShippingRate`** | Computed cost option offered to the user during checkout |
| **`ShippingCategory`** | Categorize products by shipping needs (Hazmat, Frozen, Standard) |
| **`Zone`** / **`ZoneMember`** | Geographic regions a method ships to |
| **`Shipment`** | A subset of order items shipped together from one StockLocation |
| **`InventoryUnit`** | One unit of a Variant in a Shipment |
| **`StockLocation`** | Physical/logical warehouse |
| **`StockItem`** | Count of a Variant in a StockLocation |
| **`StockMovement`** | Append-only ledger of stock changes |
| **`StockTransfer`** | Move stock between StockLocations |

### Why Multiple Shipments per Order?

If an order's items span multiple `StockLocation`s, Spree creates one `Shipment` per location. The `Spree::Stock::Splitter` allocates items by stock availability and configured policy (closest, fastest, cheapest, etc.).

### ShippingMethod Availability

A ShippingMethod is offered for a Shipment if:
- The ShippingMethod's Zones include the destination
- The Variants' ShippingCategories overlap with the ShippingMethod's allowed categories
- The ShippingMethod is enabled for the current Store
- (v5.4+) The Market for the destination allows this ShippingMethod

### Shipping Calculators

Polymorphic `Calculator` (same base class as promotion/tax calculators):

| Calculator | Math |
|------------|------|
| `Spree::Calculator::Shipping::FlatRate` | Fixed cost |
| `Spree::Calculator::Shipping::FlatPercentItemTotal` | % of cart |
| `Spree::Calculator::Shipping::PerItem` | Per-item flat |
| `Spree::Calculator::Shipping::FlexiRate` | Tiered by total |
| `Spree::Calculator::Shipping::PriceSack` | Free over threshold |
| `Spree::Calculator::Shipping::DigitalDelivery` | Free for digital |

Carrier-API calculators (UPS, FedEx, USPS) come from community gems — they compute rates by calling the carrier's API live.

### Stock::Estimator

`Spree::Stock::Estimator.new(order).shipping_rates(package)` returns the ShippingRate options for a given Package. Replaceable via `Spree::Dependencies`:

```ruby
Spree::Dependencies.shipping_rate_estimator = MyCustomEstimator
```

This is the canonical extension point for custom shipping logic — preferable to decorating the model.

### Shipment State Machine

```
pending → ready → shipped
              ↓
            canceled
```

- `pending` — awaiting payment / stock
- `ready` — paid and stocked, ready to fulfill
- `shipped` — `shipped_at` set, tracking number captured
- `canceled` — canceled with order

### Returns Flow

```
ReturnAuthorization (authorized | canceled)
  └── ReturnItem[]
       ↓
CustomerReturn (when physically received)
  └── ReturnItem[]
       ↓
Reimbursement (pending | reimbursed | errored)
  └── Refund (against original Payment)
   OR StoreCredit
```

## Implementation Guidance

### Setting Up Shipping for a New Store

```ruby
# A US zone
us = Spree::Zone.create!(name: 'US')
us.zone_members.create!(zoneable: Spree::Country.find_by(iso: 'US'))

# A shipping category
standard = Spree::ShippingCategory.find_or_create_by!(name: 'Standard')

# A shipping method
method = Spree::ShippingMethod.create!(
  name: 'Standard Shipping',
  display_on: 'both',
  shipping_categories: [standard],
  zones: [us],
  tax_category: Spree::TaxCategory.find_by(name: 'Shipping')
)
method.calculator = Spree::Calculator::Shipping::FlatRate.new(preferred_amount: 5.00)
method.save!

# A stock location
loc = Spree::StockLocation.create!(
  name: 'Main Warehouse',
  default: true,
  active: true,
  country: Spree::Country.find_by(iso: 'US')
)
```

### Customizing Shipping Rate Selection

If you need custom logic (e.g., "always offer free shipping for Gold customers"):

**Option A — Subscribe to events** (preferred when reacting):

```ruby
class FreeGoldShippingSubscriber < Spree::Subscriber
  subscribes_to 'order.recalculate'
  on 'order.recalculate', :apply_free_shipping
end
```

**Option B — Swap the Estimator** (preferred when modifying rate generation):

```ruby
class MyEstimator < Spree::Stock::Estimator
  def shipping_rates(package, frontend_only = true)
    rates = super
    rates.each { |r| r.cost = 0 } if package.order.user&.gold_tier?
    rates
  end
end

# config/initializers/spree.rb
Spree::Dependencies.shipping_rate_estimator = MyEstimator
```

### Adding a Carrier API Integration

Community gems for UPS/FedEx/USPS exist; verify v5 compatibility before adoption. The pattern:

1. Add a `Spree::Calculator::Shipping::CarrierName` calculator
2. Calculator's `compute(package)` calls the carrier's rate API
3. Authenticate with carrier credentials stored in Rails credentials
4. Cache rates for the cart's lifetime to avoid repeat API calls

### Tracking Numbers and Webhooks

When the fulfillment provider ships:

```ruby
shipment.update!(tracking: 'TRACKING123', shipped_at: Time.current)
shipment.ship!
# Fires shipment.shipped event → webhook → customer email
```

### Stock Management

```ruby
# Increase stock
stock_item.adjust_count_on_hand(10)

# Decrease (validates sufficient stock)
stock_item.reduce_count_on_hand(2)

# Transfer between locations
Spree::StockTransfer.create!(
  source_location: loc_a,
  destination_location: loc_b,
  stock_movements_attributes: [
    { quantity: 5, stock_item_id: source_item.id }
  ]
)
```

### Backorders

If `track_inventory` is on and stock hits zero, Spree marks the InventoryUnit as `backordered`. The shipment goes into `backorder` state until stock returns.

To disable backorders globally:
```ruby
Spree::Config[:allow_backorders] = false
```

Verify the exact preference name in current config.

### Returns Workflow

```ruby
# Customer requests return
ra = Spree::ReturnAuthorization.create!(
  order: order,
  return_items_attributes: items.map { |i| { inventory_unit_id: i.id } },
  stock_location: order.shipments.first.stock_location
)
ra.authorize!

# Warehouse receives
cr = Spree::CustomerReturn.create!(
  return_items: ra.return_items,
  stock_location: ra.stock_location
)

# Reimburse
reimb = Spree::Reimbursement.create!(
  customer_return: cr,
  order: order,
  return_items: cr.return_items
)
reimb.perform!  # creates Refunds and/or StoreCredits
```

### Common Pitfalls

- **Missing ShippingCategory** on a Product → no ShippingMethod can match → checkout fails at `delivery`.
- **Zone doesn't include the country** → no ShippingMethod offered.
- **Multiple StockLocations with overlapping inventory** → unexpected multi-shipment splits. Configure `propagate_all_variants` or pin to a primary location.
- **Carrier API rate-limited during checkout** → cache rates, fall back to flat rate on error.
- **Forgetting to fire `shipped!`** when manually marking a shipment — no event, no email, no webhook.
- **Stock movements without going through `adjust_count_on_hand`** — bypasses the ledger and breaks reconciliation.

Always verify model relationships and calculator names against the live source — shipping is one of the most decoupled subsystems and has community gems that vary in v5 readiness.

Wersje

W bazie nie ma innych skilli o nazwie spree-shipping-fulfillment.

Migawka bazy z 28.10.2026 · wersja paczki e6f14a44b456 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100spree-data-model
    Opisuje model danych Spree: katalog, ceny, graf zamówień, magazyn, wysyłkę, promocje, tożsamość, podatki oraz model Markets i Store w v5.4+.
  • 100spree-fulfillment
    Obsługuje realizację zamówień w Spree 6: fulfillmenty, metody dostawy, strefy, stawki przewoźników, etykiety i śledzenie przesyłek.
  • 100spree-checkout
    Wdraża checkout Spree: maszynę stanów zamówienia, płatności i wysyłki, przepływ zwrotów, checkout gościa i API checkoutu V3.
  • 100spree-upgrade-5-to-6
    Prowadzi migrację aplikacji ze Spree 5.x do Spree 6.0 i naprawia kod, który przestał działać po aktualizacji.
  • 90fluentcart-shipping-tax
    Implementuje i audytuje wysyłkę i podatki we FluentCart: strefy, metody i klasy wysyłki, dopasowanie adresu, stawki podatkowe, ceny brutto i netto, podatek złożony, walidację EU VAT i odwrotne obciążenie.
  • 100shipstation-webhooks
    Odbiera i weryfikuje webhooki ShipStation: zabezpieczanie endpointów bez podpisu tajnym tokenem w URL, pobieranie cienkiego ładunku resource_url z Basic auth i obsługa zdarzeń ORDER_NOTIFY, SHIP_NOTIFY i FULFILLMENT_SHIPPED.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.