- First release.
by Kavio Labs · for OpenCart 4.1.x
InPost Parcel Locker and courier for Polish shops: customers pick the Paczkomat at checkout (InPost map or a typed code), you create the ShipX shipment from the order page or at an order status, with cash on delivery and insurance in PLN, PDF or ZPL labels (normal or A6) and the tracking number read back into the order history by cron or webhook. You connect with your own InPost Parcel Manager token. ShipX has no price list for shoppers, so checkout prices are the ones you enter. A shipping extension with events and cron, no OCMOD.
InPost Parcel Locker and courier for Polish shops: customers pick the Paczkomat at checkout (InPost map or a typed code), you create the ShipX shipment from the order page or at an order status, with cash on delivery and insurance in PLN, PDF or ZPL labels (normal or A6) and the tracking number read back into the order history by cron or webhook. You connect with your own InPost Parcel Manager token. ShipX has no price list for shoppers, so checkout prices are the ones you enter. A shipping extension with events and cron, no OCMOD.
InPost Shipping & Labels works with OpenCart 4.1.0.4.
We list the builds we install and test on. “Tested” means the test plan ran on that build; “Supported” means the build is inside the supported range.
| Version | Range | Runs on | Status |
|---|---|---|---|
| OpenCart 4.1.0.x | 4.1.0.0 – 4.1.0.4 | PHP 8.1 – 8.3 | Tested on 4.1.0.4 |
| OpenCart 4.0.2.x | 4.0.2.0 – 4.0.2.3 | PHP 8.0 – 8.2 | Supported |
The Documentation tab covers the settings and every screen.
OpenCart 4.1.0.4. Tested on OpenCart 4.1.0.4. The Compatibility tab lists every version range.
No. They work through OpenCart events and standard extension types (modules, order totals, themes). No core file edits, no OCMOD patches, no theme template edits, so OpenCart updates and other extensions keep working.
One production store domain with every subdomain (www, shop., staging.), plus local development hosts such as localhost, *.local and *.test. A store on another domain needs its own license; a second-store license is 40% off. You have 14 days after installing to enter the key. 12 months of updates and support are included; after that the extension keeps working and renewals are 50% off. How licensing works
Yes. Ask for a full refund within 30 days of your first purchase, no reason needed: open a ticket or write to [email protected] with your order number. The money goes back to the card or bank account you paid with within 5 business days of approval. Refund policy
Open a ticket from your account, so your license details are attached. We answer Monday to Friday: bug reports within 1 business day, how-to questions within 2. Support policy. Not a customer yet? Ask a pre-sales question.
10 more answers about setup and daily use in the Documentation tab.
InPost Shipping & Labels connects your OpenCart 4 shop to the InPost ShipX API for shipments in Poland. Customers choose an InPost Parcel Locker (Paczkomat) or InPost Courier at checkout and pick the locker on the InPost map or by typing its code; you create the shipment from the order page (or let an order status do it); the label, the tracking number and the status come back into the order. You connect with your own InPost Parcel Manager token.

What it does
inpost_locker_standard and inpost_courier_standard. Other services (express, pallet, Allegro), dispatch orders, return labels and other countries are not covered.InPost, Paczkomat and Parcel Manager are trademarks of InPost sp. z o.o.; this extension is independent software and is not affiliated with or endorsed by InPost. The InPost logo is not used.
Requirements: OpenCart 4.1.0.x, PHP 7.4 or newer with cURL and OpenSSL, an InPost Parcel Manager account (a sandbox account for testing).
sandbox-manager.paczkomaty.pl) and the production Parcel Manager are separate systems with separate accounts and tokens. For the locker map also copy your Geowidget token (optional).kv_inpost.ocmod.zip and click Install.Uninstall: Extensions > Shipping > Uninstall removes the settings, the tokens, the shipments, the stored lockers and the log. Shipments already created stay at InPost and their tracking numbers stay in the order history.
Update: upload the new zip in the Installer; settings and tokens stay.

Checkout. Status, methods offered (Parcel Locker, Courier), prices for locker size A, B, C and the courier (store default currency, before tax; a method without a price is not offered), free shipping from, tax class, geo zone, sort order. The methods are offered for delivery addresses in Poland, for parcels that fit (locker: up to 25 kg and 64 x 38 x 41 cm).
Connection. Mode (test = InPost sandbox, live = production) and, per mode, the organization id, the API token (stored encrypted; leave empty to keep it, enter - to remove it) and the public Geowidget token. The webhook address with its secret key is shown here.
Parcels and labels. Locker size and courier box used when products have no length, width and height; sending method (parcel locker, any point, POP, branch, dispatch order); label format (PDF, ZPL) and size (normal, A6; courier shipments always get A6); the payment extension code that means cash on delivery (for example cod); insurance for every shipment.

Orders and tracking. Order status that creates the shipment at InPost (only orders with an InPost method), order status when the tracking number arrives, e-mail the customer, debug log. Cron: */10 * * * * php /path/to/opencart/cron.php or the secret address shown on the tab.
Shipments. The latest shipments with order, InPost shipment, service, tracking number and state; tick rows and download one file with their labels.
API log. Errors and warnings; with the debug log on, every request and response. The token is masked.
Checkout. The customer chooses InPost Parcel Locker or InPost Courier. For the locker option a card appears below it: Choose a parcel locker opens the InPost map (or the code field); without a locker the choice is refused. The chosen locker is shown next to the method and stored with the order.

Create the shipment. Open the order, tab InPost, press Create shipment at InPost. InPost answers at once with the shipment (status created) and buys the offer a moment later. The tab shows the shipment, its service and state. For orders placed without the picker (or by phone) enter the locker code on the tab and press Set locker.

Tracking and label. Press the refresh button, wait for the cron (hourly; open shipments every 30 minutes) or let the webhook trigger it: the extension reads the shipment, downloads the label once InPost has confirmed it and writes the tracking number and the InPost tracking link to the order history. The print button opens the label (PDF) or downloads it (ZPL).

Cancel. The red button cancels the shipment while InPost has not confirmed it. After that InPost refuses and the extension shows its message.
Many orders. Settings > Shipments: tick shipments and download one file with the labels (a zip when lockers and courier are mixed).

| Item | Value |
|---|---|
| Extension code | kv_inpost (type shipping) |
| Settings | shipping_kv_inpost_* |
| PHP namespace | KavioLabs\KvInpost (shared core in system/library/ of the extension) |
| Tables | kv_inpost_points (locker of an order), kv_inpost_shipments, kv_inpost_log |
| Checkout route | extension/kv_inpost/shipping/kv_inpost (model getQuote, codes kv_inpost.locker, kv_inpost.courier) |
| Session | kv_inpost_point (the locker chosen at checkout) |
| Trigger | Action |
|---|---|
catalog/view/checkout/shipping_method/after | adds the locker picker (script and style) to the shipping method block |
catalog/controller/checkout/shipping_method.save/after | refuses the locker method without a locker; adds the locker to the method name |
catalog/model/checkout/order.addOrder/after, editOrder/after | stores the chosen locker with the order |
catalog/model/checkout/order.addHistory/after | creates the shipment at the chosen order status |
admin/view/sale/order_info/before | adds the InPost tab to the order page |
admin/controller/common/header/before | licence check |
| OpenCart cron, hourly | extension/kv_inpost/shipping/kv_inpost.cron reads shipments back |
| Secret address | .webhook&k=<key> (GET 200, POST makes the extension read the shipment of the event) |
php81 tests/unit.php and php83 tests/unit.php (149 checks) against tests/mock-server/server.js (a stand-in built from the official ShipX documentation) and a scratch MariaDB database; every request body is checked against the documented shape (docShape). node tests/e2e.js runs the browser flow on an OpenCart 4.1.0.4 dev store (88 checks). Not tested against a live InPost account.
Hidden setting shipping_kv_inpost_base_url points the extension to the mock; it is honoured for loopback hosts only.
What the extension does, against the official InPost documentation (space "PL" at dokumentacja-inpost.atlassian.net, read November 2026). The extension is proven against a local mock that follows these pages (unit and browser tests); it has not been run against your InPost account until you test the connection.
| Topic | Documented behaviour | What the extension does | |||
|---|---|---|---|---|---|
| Hosts | Production https://api-shipx-pl.easypack24.net, sandbox https://sandbox-api-shipx-pl.easypack24.net (separate Parcel Manager accounts) | Test mode uses the sandbox, Live mode production. Credentials are stored per mode | |||
| Authentication | Authorization: Bearer <token>; the organization id is part of the path (Parcel Manager > My Account > API) | Token and organization id are entered on the Connection tab, token sealed with AES-256-GCM | |||
| Test connection | GET /v1/organizations/:id | Used as the connection test; shows the organization name | |||
| Create shipment | POST /v1/organizations/:id/shipments (simplified mode); asynchronous: the answer has status created, no tracking number | Sends receiver, parcels, service, custom_attributes, cod, insurance, reference; stores the shipment as "created" and completes it when InPost confirms | |||
| Services | inpost_locker_standard, inpost_courier_standard (and others) | These two. Other services (Allegro, express, pallet) are not offered | |||
| Parcel Locker | custom_attributes.target_point (required), parcels: {"template": "small"}; sending_method | target_point from the locker chosen at the checkout; template A/B/C from product box sizes (default size setting); sending_method from a setting (default parcel_locker) | |||
| Locker receiver | receiver.phone and receiver.email required | Phone normalised to 9 digits; an order without a valid Polish mobile number is refused with a clear log message and nothing is sent | |||
| Courier | receiver address, parcels with dimensions (mm) and weight (kg) | Street and house number split from the address, post code NN-NNN, dimensions from product box sizes or the default size setting | |||
| Sender | Optional; the organization's data is used by default | Never sent: the organization data of the token is used | |||
| COD / insurance | cod and insurance objects (amount, currency); insurance is required for courier shipments with COD | Orders paid with the chosen payment method send the order total as COD in PLN; courier + COD is always insured; optional insurance at order total | |||
| Label | `GET /v1/shipments/:id/label?format=pdf\ | zpl\ | epl&type=normal\ | A6 once the status is confirmed or later; courier has no normal` type (A6) | PDF or ZPL, normal or A6 (courier always A6). The documentation lists no A4 label type, so there is none |
| Cancel | DELETE /v1/shipments/:id, only in created or offers_prepared | Cancel button on the order tab while the shipment is "created"; an invalid_action answer is shown as is | |||
| Tracking | GET /v1/tracking/:tracking_number (public, 45 days, not available on the sandbox) | The extension reads the shipment resource (GET /v1/shipments/:id, status and tracking number) so it also works in the sandbox; statuses are mapped to created, in transit, delivered, problem, canceled | |||
| Webhooks | Events shipment_confirmed, shipment_status_changed, offers_prepared; not signed; sent from 91.216.25.0/24; the address must answer GET with 200 | The URL contains a secret key; a request without it is rejected. An event only makes the extension read the shipment again, its body is never trusted. GET answers 200 | |||
| Points | Public Points API, Geowidget v5 (<inpost-geowidget>, token from Parcel Manager) | Geowidget v5 in a dialog inside the shipping method dialog (token is public and entered on the Connection tab); without a token the customer types the locker code, which is checked with GET /v1/points/:name | |||
| Errors | {status, error, message, details}, e.g. validation_failed with details per field | Messages are shown with the field details; 4xx answers are not retried, network errors, 429 and 5xx are | |||
| Rate limits | Not stated on the pages we read | Back-off retries (GET, DELETE, 429); a shipment creation is never repeated after a network error or 5xx, so it cannot be created twice |
Dispatch orders (courier pick-up), return labels, other ShipX services and countries, the InPost International and "InPost Pay" products.
Trademark: InPost, Paczkomat and Parcel Manager are trademarks of InPost sp. z o.o.; this extension is not affiliated with or endorsed by InPost. The InPost logo is not used.
No. ShipX has no public price list for shop customers; the prices at checkout are the ones you enter in the settings.
Yes, with the InPost Geowidget when you enter your public Geowidget token. Without a token the customer types the locker code (for example KRA010), which is checked against the InPost Points API.
Poland only (delivery addresses in Poland, services locker standard and courier standard).
Name the payment extension that means cash on delivery (code cod for the OpenCart one). Orders paid with it are sent with the order total as COD in PLN. Courier COD shipments are always insured because InPost requires it.
InPost buys the offer asynchronously; the answer has status "created" and no number. The number and the label arrive with the next read (refresh button, cron or webhook).
Yes: choose Test mode. The sandbox has no public tracking resource, which is why the extension reads the shipment itself.
No. The official documentation lists normal and A6 only.
No, OpenCart 4.1 only.
No. A shipping extension, events and cron.
No. InPost, Paczkomat and Parcel Manager are trademarks of InPost sp. z o.o. The InPost logo is not used.
Buy with confidence
This product was tested on this build. Builds we did not test are not listed.
Updates and support are included in the price. The product keeps working afterwards; renewing is optional.
How licensing worksIf it is not what you expected, tell us within 30 days and we refund the order.
Refund policyPay by card, Apple Pay or Google Pay on Stripe's secure page. Your card number never reaches our server.
Ask a pre-sales questionSold by Kavio Labs Software Limited, registered in England and Wales No. 17532441. About us
More for OpenCart
Server-side tracking for OpenCart 4.x and 3.0.x: purchases, refunds, add to cart, checkout, product views and leads go from your server to the free official GA4 Measurement Protocol, Meta Conversions API and TikTok Events API, deduplicated with the browser pixels through shared event ids. Consent-aware, SHA-256 hashed customer data, order status mapping, queue with retries, test mode and an event log. No paid relay, events only, no OCMOD.
The department store theme for OpenCart 4.x and 3.0.x: colour-coded departments, a department list beside the hero slider with two side promos, a big search with a department selector, tabbed product blocks, a 2 + 1 + 2 offer grid, deals of the day with real countdowns, a department showcase, a promotions band and a three-column product page with a sticky buy box. Four styles (Meridian, Harbor, Citrus, Night) and your own colours on top. Events only, no core changes.
Stop AI crawlers, scrapers, vulnerability scanners and unwanted countries before OpenCart 4.x or 3.0.x builds a page. Googlebot and Bingbot are verified by DNS and always allowed; 50+ bots get one switch each; country rules use free GeoIP databases and can close only the checkout; IP and network lists, rate limits, honeypots and the cart flood fix; a one-second challenge instead of a captcha; learning mode, dashboard, log, IP tester and Cloudflare export. No core changes, no OCMOD.