Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Woocommerce Laravel Package

jeffersongoncalves/laravel-woocommerce

A Laravel package that provides a simple wrapper for the WooCommerce REST API, letting you manage products, orders, customers, and other store data from your PHP application with a fluent, framework-friendly interface.

View on GitHub
Deep Wiki
Context7

Getting Started

It's a REST client, not an ORM — no Eloquent models, no local mirror. Everything is a synchronous HTTP call to your store, so design around that from day one.

  1. composer require the package, then php artisan vendor:publish to get the config file.
  2. In WooCommerce → Settings → Advanced → REST API, create a key with Read/Write (create a separate Read key for reporting/sync jobs). WooCommerce refuses keys over plain HTTP, so the store URL must be HTTPS.
  3. Fill .env: store URL, consumer key, consumer secret, and the REST namespace (pin it — wc/v3 is not guaranteed on older or heavily plugin-modified stores).
  4. Smoke test in tinker: fetch system status or a single product by ID, then list recent orders. If that works, auth and TLS are correct and everything else is just resource plumbing.

Look first at: the config file (it tells you what's overridable), the facade's resource methods, and the bundled Laravel Boost guidelines — for an HTTP client like this, the Boost skill file is effectively a better cheatsheet than the README, and it's the fastest way to get correct method names and payload shapes into an AI-assisted workflow.

First real use case: a read-only order dashboard — pull the last 50 orders, render totals and statuses. It exercises auth, pagination, currency parsing and date handling in one go, and breaks nothing in production.

Implementation Patterns

Fluent resource calls. Expect Woocommerce::products()->all() / find() / create() / update() / delete(), with nested resources under a parent (->variations($productId), ->notes($orderId), ->refunds($orderId)). Verify the exact signatures against the README or Boost guidelines before writing wrappers around them — at 1.0.0 the surface is stable enough to use but worth confirming once.

Paginate explicitly, never blindly. Ask for per_page => 100 and loop pages until you get a short page; read X-WP-TotalPages from the response if the package exposes it. An all() on a 40k-order store is 400+ sequential requests and will either time out or get you throttled.

Cache the read-heavy catalogue. Products, categories and tags change rarely: Cache::remember keyed by resource + query hash, 15–60 minute TTL. Skip the cache entirely for stock, price and order status — stale stock causes oversells.

Push-sync jobs, not request-time writes. Queue anything that writes. Resolve products by sku before creating (WooCommerce will happily create duplicates), use updateOrCreate-style logic, and give each job retry plus WithoutOverlapping so a slow store doesn't stack up parallel writers.

Batch for bulk, in chunks of 100. batch() is the right tool for importing 500 products, but it is not transactional — the response contains per-operation results and individual items can fail while the request returns 200. Always iterate and log the failures. Only collections with a /batch endpoint support it; reports and system status do not.

Receive webhooks yourself. The package manages webhook registrations; it does not ship an inbound receiver. Build the controller, verify the X-WC-Webhook-Signature HMAC-SHA256 against the raw body, respond 200 fast, and dispatch a job that fetches the order/product by ID — treat the webhook as a notification, not as the payload of record.

Wrap errors once. Catch Illuminate\Http\Client\RequestException, read code from the JSON body (woocommerce_rest_authentication_error, woocommerce_rest_invalid_product_id, …) and map it to your own exceptions. Retry 429/5xx with backoff; never retry a 4xx — it's a validation or auth problem and the retry just burns quota.

Test with Http::fake(). Because it's built on Laravel's HTTP client, you can assert the outgoing method, URL and JSON body, and replay captured real responses as fixtures. This is the single biggest maintainability win over hand-rolled cURL clients.

Gotchas and Tips

  • "Webhooks" is overloaded. The resource registers endpoints in WooCommerce; your app still needs an inbound route. Also remember to delete stale registrations when you rename a route.
  • Dates are a trap. date_created is store-local time with no offset; date_created_gmt is UTC. Persist the _gmt fields and convert for display. The after/before filters are ISO8601 interpreted in site timezone, not UTC.
  • Money comes back as strings. Don't float-math totals and refunds — use bcmath or integer minor units, and treat total as authoritative over summing line items.
  • Customer deletion is permanent — no trash. If the customer has orders you must pass reassign with a WordPress user ID to take ownership of their posts. Deleting without it fails.
  • Variation stock lives on the variation, not the parent product. Updating the parent's stock_quantity on a variable product silently does nothing useful. This is the most common inventory bug with this API.
  • meta_data is asymmetric. Read gives {id, key, value}; write wants [{key, value}], and writing to protected keys is silently ignored.
  • Order list defaults are narrow. Trashed orders are excluded, and you often need status=any to see pending/failed alongside completed.
  • Config cache bites. After changing .env, run config:cache again — and note the facade resolves one client, so per-request store switching (multi-store setups) needs you to override config and clear the resolved facade instance, or instantiate the client directly. Multi-store is the main architectural limitation to plan around.
  • Coupon code is globally unique. Creating a duplicate throws rather than merging; check first if you're syncing from an external system.
  • Debugging: log X-WP-Total/X-WP-TotalPages alongside each call, and use Telescope or a Http::globalRequestMiddleware to capture the actual URL — namespace and query-encoding mistakes (category wants an ID, not a slug) look like empty results, not errors.
  • Extension points: the publishable config (namespace/version pinning) and Laravel HTTP client macros are your hooks; there's no plugin/middleware system, so put cross-cutting concerns (logging, store switching, retry policy) in a thin service class you own rather than patching the package.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk