Install with composer require bigperson/laravel-exchange1c, then publish the config and migrations: php artisan vendor:publish --provider="Bigperson\Exchange1C\Providers\Exchange1CServiceProvider" (some versions require publishing --tag=config and --tag=migrations separately). Run php artisan migrate and confirm the package tables don't collide with your existing ones before migrating in anything but a fresh DB.
Open config/exchange1c.php first. This is where the exchange credentials, the route prefix (default something like exchange1c), the storage path for uploaded XML, and the model/table mapping live. Set the login/password via .env rather than hardcoding — 1C will send them as HTTP Basic on every call.
Look at the controller/router that dispatches ?type=catalog|sale&mode=checkauth|init|file|import|query|success. That switch statement is the actual protocol surface; every debugging session ends up there. src/Exchange1C.php (or the bound service) holds the import logic.
On the 1C side, configure "Обмен с сайтом" (CommerceML 2) with the URL https://yoursite/exchange1c, the same login/password, and enable catalog and/or order exchange. 1C drives the handshake — it calls checkauth, then init, then uploads import.xml/offers.xml via file, then calls import.
First use case: get a catalog import working end to end. Point 1C at the site, run "Выгрузить товары" once, and verify rows land in the package's categories/products/offers/prices tables. If you don't want to click through 1C yet, simulate it with curl using a cookie jar:
curl -c /tmp/1c.txt -u admin:secret 'https://site.test/exchange1c?type=catalog&mode=checkauth'
curl -b /tmp/1c.txt -c /tmp/1c.txt -u admin:secret 'https://site.test/exchange1c?type=catalog&mode=init'
curl -b /tmp/1c.txt -u admin:secret -F '[email protected]' -F 'filename=import.xml' \
'https://site.test/exchange1c?type=catalog&mode=file'
curl -b /tmp/1c.txt -u admin:secret 'https://site.test/exchange1c?type=catalog&mode=import'
A plain-text success/failure body is the protocol; if you get HTML or a redirect, your middleware/auth is intercepting the exchange route.
Product/Category/Offer/Price/Stock models are shaped by what 1C sends (GUID, name, XML structure), not by what your storefront needs. The most common pattern is: let the package land the raw rows, then sync them into your own Product/Offer models via a listener or a post-import pass, so you keep your slugs, media, translations, and search index under your control.product, category, offer, order, etc.) at your own Eloquent class. Subclass the package model and override it in config — that's how you add accessors, scopes, or extra columns without touching vendor code. Keep the table and column contract intact or the import silently drops fields.Ид) with updateOrCreate, and put a unique index on that column. GUIDs are strings like a1b2c3d4-...; never cast them to integers.import step rather than editing vendor files. Check src/ for the events actually dispatched in your pinned version before building on them — the README is thin on this.type=sale&mode=query is what 1C calls to pull orders. Point the order model at your real orders, or replace the query, and make sure the returned document has 1C's expected structure: order number, date, status, customer requisites, line items with product GUIDs, quantities, and prices. Product GUIDs must match what was imported, or 1C will reject the line items.file step just stores XML, but the import step can take minutes for 10k+ offers, and 1C will time out. A common pattern is: let file store the archive, then either raise timeouts aggressively or hand the parse to a queued job and return success early (1C is a synchronous client — it won't retry gracefully, so returning success before parsing is safe only if the parse is reliable).tests/fixtures/ and write a feature test per mode (checkauth → init → file with UploadedFile → import). Add a dedicated route_prefix per environment so staging and prod don't share sessions. For the exchange routes, the built-in auth is Basic against the config credentials — don't add your normal auth middleware on top.products or orders tables, the published migrations can collide. Read them before running; either rename the package tables in config or scope it to a fresh schema.SESSION_COOKIE, load balancers without sticky sessions, or a cookie domain mismatch) breaks init → file and shows up as a confusing auth failure on step two, not step one.file step shape. 1C sends multipart with a filename field, not a normal filename part. If you write middleware or a proxy, don't strip multipart fields. Check permissions on the storage path the config points at — silent write failures surface as a failure on import, not on file.offers.xml was uploaded, or the catalog import failed halfway), the offer is dropped without a loud error. Diff counts after each import: products in, offers in, offers skipped.offers.xml can carry several price types (retail, wholesale) and warehouses. Decide in config which one drives your storefront price and stock; otherwise you'll get whichever one happens to be parsed last.failure says nothing about why..env, and if possible restrict the route by IP to the 1C server. Don't reuse the password anywhere else.composer.json, read the issue tracker before upgrading Laravel, and keep your customizations in your own models/listeners rather than patched vendor files. Everything you need for day-to-day work — config, models, and the mode controller — is in src/ and config/; fork those two entry points rather than the whole package.How can I help you explore Laravel packages today?