Connect your point-of-sale catalog, warehouse stock, and sales history with your online shop. Sell POS products on the web, keep inventory in sync automatically, and view counter and web sales side-by-side in a single unified history.
One-Click Publish
Push any POS product to the online shop from the POS product edit page. Price, description, and images are copied automatically.
Live Stock Sync
When stock changes in the designated online warehouse, the linked shop product quantity updates instantly, no manual steps required.
Order Mirroring
Paid shop orders are automatically recorded in POS sales history so reports and stock movements stay consistent across channels.
Category Mapping
Map each POS product category to a shop category once. Publishing a product uses the mapping to place it in the right shop category.
Automatic Unpublish
Soft-deleting a POS product sets the linked shop product to draft. Restoring the POS product re-publishes it automatically.
Sale Reversal
Cancelling or refunding a shop order voids the mirrored POS sale and restores stock movements through the POS movement log.
Use Cases
Brick-and-Click Retail
You run a physical store with a POS system and want to sell the same products online. The bridge lets you manage your catalog once in POS and publish products to the shop without duplicating data entry. Inventory stays in sync automatically.
Unified Sales Reporting
Both counter sales and web orders appear in the POS sales history under the same
reports. Web orders are tagged with the web channel so you can filter
them separately from in-store transactions.
Selective Online Catalog
Not every POS product needs to be sold online. The bridge is opt-in per product: you control which items are published, with the option to override price, sale price, and shop category at publish time.
Requirements
- Larapen CMS v1.0.0 or later
- PHP 8.3+
- MySQL 8.0+
- POS add-on installed and active
- Shop add-on installed and active
Installation
Step 1: Upload the Add-on
In the admin panel, go to Admin → Extensions → Add-ons and click the Upload Add-on button. Select the add-on’s ZIP file: the system extracts it automatically and the add-on appears in the installed add-ons list.
Step 2: Activate the Add-on
Find POS ↔ Shop Bridge in the list and click Activate. Its migrations, seeders (if any) and permissions are set up automatically.
Step 3: Configure
Navigate to Admin → POS ↔ Shop Bridge to configure shared products, stock synchronization, and catalog mirroring between POS and Shop. See Configuration.
Purchase Code (License Key)
POS ↔ Shop Bridge is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate POS ↔ Shop Bridge in Admin panel → Add-ons.
Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.
| Platform / Marketplace | How you get the purchase code | Where to find it again |
|---|---|---|
| bedigit.com Store In-site purchase (Shop) |
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. | My Account → My Licenses on bedigit.com |
| Gumroad | Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. | The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com |
| Envato Market CodeCanyon |
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. | Envato account → Downloads → License certificate & purchase code |
1. bedigit.com Store (in-site purchase)
- As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
- It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
- The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
- The matching invoice is under My Account → My Orders.
2. Gumroad
- A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
- The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
- When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library → your purchase on gumroad.com.
- Use the same email address on bedigit.com as on Gumroad: your keys are then linked to your account automatically and listed under My Account → My Licenses, even if you register after the purchase. You can also add a Gumroad key manually from My Account → My Gumroad Licenses.
3. Envato Market (CodeCanyon)
- Envato purchase codes are issued and delivered by Envato Market, never emailed by us, so there is nothing to look for in your spam folder: you retrieve the code from your Envato account.
- Log in to your Envato / CodeCanyon account, open the Downloads page, find the item, and choose License certificate & purchase code from the Download dropdown. The code is written in that certificate.
- An Envato purchase code looks like
12345678-90ab-cdef-1234-567890abcdef(8-4-4-4-12 characters). It never changes, and renewing item support does not issue a new one. - Official Envato article: Where Is My Purchase Code?
Configuration
All settings are managed in Admin → POS ↔ Shop Bridge (stored in the
settings table, group pos_shop_bridge).
| Setting key | Description | Default |
|---|---|---|
pos_shop_bridge_enabled |
Master toggle. When disabled, no stock sync or order mirroring occurs. | false |
pos_shop_bridge_warehouse_id |
ID of the POS warehouse treated as the online stock source. Only this warehouse’s quantities are pushed to linked shop products. | - |
pos_shop_bridge_auto_publish |
When enabled, creating a new POS product automatically creates a draft shop product, provided a category mapping exists for the product’s POS category. | false |
Admin: Bridge Settings
The settings page (POS ↔ Shop Bridge → Bridge Settings) has two sections:
General Settings
- Enable bridge: master on/off toggle for all automatic synchronisation. Disabling this stops stock sync and order mirroring without removing any data. You can still manually publish and unpublish products while the bridge is disabled.
- Online warehouse: select the POS warehouse that represents your online stock. Only quantity changes in this warehouse are pushed to linked shop products. Typically this is a warehouse named “Online” or “Web Store”.
- Auto-publish new POS products: when enabled, saving a new POS product creates a draft shop product automatically. A category mapping must exist for the product’s POS category, otherwise the auto-publish is silently skipped.
Category Mapping
See Category Mapping below.
Admin: Category Mapping
The category mapping table associates each POS product category with a shop category. This mapping is used when publishing a POS product: the bridge looks up the POS category and places the resulting shop product in the corresponding shop category.
Adding a Mapping
- At the bottom of the Bridge Settings page, locate the Category Mapping section.
- Select a POS category and a Shop category from the dropdowns.
- Click Add mapping.
Removing a Mapping
Click the delete icon next to any row in the mapping table. Removing a mapping does not affect products already published; it only affects future publish operations.
Mapping and Publish Overrides
When publishing a POS product, you can manually specify a Shop category override in the Publish panel. This overrides the category mapping for that single product without changing the mapping table.
Admin: Publishing Products
Publishing makes a POS product available as a shop product on the storefront.
How to Publish
- Go to POS → Products and open any product for editing.
- In the sidebar, locate the Publish to Shop panel injected by the bridge.
- Optionally override the shop category, price, sale price, and status (Draft or Published).
- Click Publish.
The bridge will:
- Create a new shop product (or update the existing linked one).
- Copy the product name, slug, and description from POS (all translatable locales).
- Set the stock quantity to the current stock in the online warehouse.
- Copy the POS featured image to the shop product (configurable).
Publish Panel Fields
| Field | Description |
|---|---|
| Shop category | Override the category mapping for this product. Leave empty to use the mapping from bridge settings. |
| Price override | The price charged on the shop. Defaults to the POS selling price when left empty. |
| Sale price | Optional discounted shop price. Leave empty for no sale price. |
| Status | Published makes the product visible on the storefront immediately. Draft creates the shop product but keeps it hidden. |
Re-publishing
Clicking Publish on a product that is already linked updates the existing shop product. The stock quantity, name, and description are refreshed. Any overrides supplied in the panel are applied again.
Unpublishing
Click Unpublish in the publish panel to set the linked shop product’s status to Draft. The shop product row is kept in the database; it is not deleted. Re-publishing will make it visible again.
Shop Product Badge
On the Shop products list page, products that were synced from POS display a “Synced from POS” badge. Clicking the badge or the product row takes you to the standard shop product edit page.
POS Sale Link on Shop Orders
On the Shop order detail page, if the order has a mirrored POS sale record, a “View POS sale” link is shown, taking the admin directly to the corresponding POS sale.
Automation: Stock Synchronisation
Stock is synchronised automatically whenever the quantity of a product in the online warehouse changes.
How it Works
- A stock movement is recorded in POS (sale, purchase, adjustment, transfer).
- The POS
warehouse_productsrow for the online warehouse is updated. - The
WarehouseProductStockObserverdetects the change. - The bridge reads the new quantity and writes it to
shop_products.stock_quantityusingwithoutEventsto avoid triggering secondary observers.
When Sync Does Not Run
- The bridge is disabled (
pos_shop_bridge_enabledis off). - No online warehouse has been configured.
- The changed warehouse is not the configured online warehouse.
- The shop product does not have
stock_source = 'pos'(i.e. it was not published via the bridge).
Automation: Order Mirroring
When a shop order is paid, the bridge creates a corresponding record in the POS sales history. This allows managers to see all revenue, web and counter, in a single view.
Mirroring Trigger
The OrderBridgeObserver watches for changes to shop_orders.payment_status.
When it changes to paid, the bridge calls createPosSaleFromShopOrder().
What Gets Created
- A
pos_salesrow withchannel = 'web'and the shop order’s financial totals (subtotal, discount, tax, total). - A
pos_sale_itemsrow for each order item whose shop product is linked to a POS product. Items without a POS link are skipped. - A
pos_sale_paymentsrow matching the shop payment method. - Stock movement records via the POS
MovementService.
Sale Number Format
The mirrored POS sale number is prefixed with WEB- followed by the shop order
number (e.g. WEB-ORD-20260419-00000001). The prefix is configurable in
config/bridge.php.
Payment Method Mapping
| Shop payment method | POS payment method |
|---|---|
cash, cod, cash_on_delivery |
Cash |
card, credit_card, debit_card |
Card |
| any other value | Other |
Idempotency
If a POS sale already exists for a given shop order, calling
createPosSaleFromShopOrder() returns the existing record without creating
a duplicate. This protects against accidental double-mirroring if the payment status
is toggled more than once.
Sale Reversal
When a shop order is cancelled or its payment status changes to
refunded, the bridge calls reversePosSaleForShopOrder(),
which voids the linked POS sale via the POS SaleService::void() method.
This restores stock movements in the POS movement log.
Automation: POS Product Lifecycle
The PosProductBridgeObserver keeps the shop product status in sync with
the POS product lifecycle.
| POS product event | Effect on linked shop product |
|---|---|
| Soft-deleted (archived) | Status set to Draft (hidden from storefront). |
| Restored (unarchived) | Status set to Published and published_at refreshed. |
| Force-deleted (permanent) | No action. The shop product remains as-is (the foreign key uses nullOnDelete, so pos_product_id becomes null). |
Updating
Method 1: Admin Panel Upload (Recommended)
- Download the latest
.zipfile of this add-on. - Go to Admin panel → Add-ons and click the Upload button.
- Select or drag the
.zipfile into the upload area. - A confirmation prompt will show the current and new version numbers. Click Replace to proceed.
- Go to Admin panel → System Update (
/admin/update) to apply any pending database migrations.
Method 2: Manual File Replacement
Step 1: Replace Files
Replace the add-on directory with the new version.
Step 2: Run Migrations
php artisan migrate
Step 3: Clear Caches
php artisan optimize:clear
Uninstallation
Switching an add-on off without losing anything is a deactivation: go to Admin panel → Add-ons, find POS ↔ Shop Bridge and click Deactivate.
- Its routes, views, admin menu entries and permissions stop being registered, and its front-end pages stop answering.
- Its database tables and all the data they hold are kept, and its files stay under
extensions/addons/pos-shop-bridge/. Nothing is deleted. - The purchase code recorded at activation is kept too, so activating the add-on again does not ask for it.
- Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.
Click Activate on the same card to switch it back on. Pending migrations are re-run, assets are republished, and the add-on picks up exactly where it left off.
Removing
Removing is permanent and destroys the add-on's data. The Remove button only appears on a deactivated add-on, so removal is always two steps:
- Deactivate POS ↔ Shop Bridge (see Uninstallation).
- Click Remove on its card and confirm the prompt.
The admin panel then, in one pass:
- runs the add-on's uninstall hook, if it ships one, while its code is still on disk;
- revokes the permissions declared in its
addon.json; - rolls back its migrations (this drops its database tables and every row they hold) and purges its entries from the
migrationstable, so a later reinstall migrates from scratch; - deletes its published assets:
public/addons/pos-shop-bridge/,public/vendor/pos-shop-bridge/andstorage/app/public/addons/pos-shop-bridge/; - deletes the add-on directory
extensions/addons/pos-shop-bridge/; - deletes its row in the
addonstable (the recorded purchase code goes with it) and clears the application cache.
Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/pos-shop-bridge/. In that last case, give that user write permission on the directory and on its parent, then try again.
Deleting the folder over FTP or SSH is not equivalent: the add-on's tables, its entries in the migrations table and its addons row are all left behind, and its card stays in the list. Use Remove in the admin panel instead.
Troubleshooting
Bridge has no effect after activation
- Confirm both the POS and Shop add-ons are active in Admin → Add-ons.
- Check that
pos_shop_bridge_enabledis toggled on in Bridge Settings. - Ensure the online warehouse has been selected.
Publish fails: “Missing category mapping”
- The POS product has a category, but no mapping exists for it in the Bridge Settings category mapping table.
- Either add a mapping for that POS category, or specify a shop category override in the Publish panel when publishing the product.
Stock is not syncing to the shop
- Verify that
pos_shop_bridge_enabledis on. - Confirm the correct warehouse is set as the online warehouse. Stock changes in other warehouses are ignored.
- Check that the shop product has
stock_source = 'pos'. Products not published via the bridge havestock_source = 'manual'and are not synced.
Shop order is not appearing in POS sales history
- The bridge only creates a POS sale when the shop order’s
payment_statuschanges topaid. Verify the order has been paid. - Check that the order contains at least one item whose shop product is linked to a POS product
(
pos_product_idis not null). - Verify the online warehouse is configured. Without it the bridge logs a warning and skips mirroring.
- Check the Laravel log for
[pos-shop-bridge]warning messages.
Mirrored POS sale shows $0 for items from a non-linked product
Only order items whose shop product has a pos_product_id link are included in
the mirrored sale. Items for products published independently (without the bridge) are excluded
from the POS sale items. The overall order totals (subtotal, tax, total) are still mirrored
accurately from the shop order.
Auto-publish did not create a shop product for a new POS product
- Confirm
pos_shop_bridge_auto_publishis enabled. - Check that a category mapping exists for the new POS product’s category. Auto-publish is silently skipped if no mapping is found.
POS product soft-delete did not set shop product to draft
- The observer only reacts to soft-deletes (archives). A force-delete (permanent removal)
does not change the shop product status: the
pos_product_idis set tonullby the database foreign key constraint.
POS ↔ Shop Bridge v1.0.0: Part of the Larapen CMS platform.
© BeDigit. All rights reserved.