E-Shop

Full e-commerce functionality for your Larapen site. Sell physical and digital products with a complete shopping cart, checkout flow, coupon system, order management, and merchant feed generation.

Product Management

Create products with variants, gallery images, sale prices, stock tracking, and SEO metadata. Supports internal, external, and digital product types.

Cart & Checkout

Session-based cart for guests, database-backed for authenticated users. Automatic cart merging on login. Guest checkout support.

Order Management

Complete order lifecycle with status tracking, payment status, stock management, email notifications, and digital download delivery.

Coupons & Discounts

Percentage or fixed-amount coupons with minimum order thresholds, usage limits, date ranges, and maximum discount caps.

Merchant Feeds

Generate product feeds for Google, Bing, Facebook, Amazon, TikTok, Yandex, and Baidu with customizable field mappings.

Structured Data

Automatic schema.org/Product JSON-LD output on product pages for rich search results. Supports variants, pricing, and availability.

Use Cases

Online Store

Sell physical products with inventory tracking, shipping calculations, and coupon discounts. Customers browse categories, add to cart, checkout, and track their orders.

Digital Product Sales

Sell downloadable files (eBooks, templates, software). Digital products skip shipping, and buyers receive time-limited download links after payment.

Affiliate / External Products

List products that link to external retailers. External products display a “Buy Now” button linking to the external URL instead of the internal cart flow.

Multi-Channel Commerce

Use the merchant feed system to syndicate your product catalog to Google Shopping, Facebook Commerce, Amazon, TikTok Shop, and other platforms.

Requirements

  • Larapen CMS v1.0.0 or later
  • PHP 8.3+
  • MySQL 8.0+
  • At least one payment gateway add-on (e.g. Stripe) for processing payments
Note: The shop add-on installs and runs without a payment gateway, but checkout will only work with Cash on Delivery (COD) unless a payment gateway add-on is active.

Installation

Step 1: Place the Add-on

Copy or symlink the shop folder into your Larapen "extensions/addons" directory:

Step 2: Activate the Add-on

Go to Admin → Add-ons → Installed Add-ons and activate E-Shop.

Step 3: Run Migrations

This creates the following tables: shop_products, shop_product_variants, shop_carts, shop_cart_items, shop_orders, shop_order_items, shop_transactions, shop_coupons, shop_product_feed_data, shop_category_feed_data, shop_merchant_feed_platforms, and shop_merchant_feed_field_mappings. Product categories use the core categories table with categorizable_type = 'product'.

Step 4: Set Permissions

The add-on registers 19 permissions (see Permissions). Assign them to admin roles via Admin → Users → Roles & Permissions.

Step 5: Configure

Navigate to Admin → Shop → Settings and configure currency, tax, shipping, and checkout options. See Configuration.

Configuration

All settings are managed in Admin → Shop → Settings (stored in the settings table, group shop). Defaults are defined in config/shop.php.

General

Setting Description Default
shop_order_prefix Prefix for generated order numbers (e.g. ORD-20260307-00000001). ORD
shop_products_per_page Number of products per page in the catalog listing. 12
shop_sidebar_position Sidebar position on listing pages: left, right, or none. right
shop_grid_columns Number of product columns per row in grid view (1–4). 3
shop_default_view_mode Initial product listing display mode: grid or list. grid
shop_guest_checkout Allow customers to checkout without creating an account. true

Tax

Setting Description Default
shop_tax_enabled Enable tax calculation on orders. false
shop_tax_rate Tax rate as a percentage (e.g. 20 for 20%). 0
shop_tax_inclusive Whether product prices already include tax. When enabled, the tax amount is extracted from prices rather than added on top. false

Shipping

Setting Description Default
shop_shipping_enabled Enable shipping charges on orders with physical products. true
shop_free_shipping_threshold Subtotal threshold for free shipping. Set to 0 to disable. 0
shop_shipping_flat_rate Flat shipping rate applied when the order does not qualify for free shipping. 10

Digital Products

Setting Description Default
shop_digital_max_downloads Maximum number of times a digital product can be downloaded per purchase. Set to 0 for unlimited. 5
shop_digital_expiry_days Number of days after purchase before the download link expires. 30

Stock & Notifications

Setting Description Default
shop_low_stock_threshold Stock quantity at which products are flagged as low stock. 5
shop_notify_admin_on_order Send an email notification to admin users when a new order is placed. true
shop_notify_customer_on_order Send an order confirmation email to the customer. true

Environment Variables

Note: Environment variables are used as defaults. Settings saved in the admin panel override them.

Admin: Settings

The settings page (Shop → Settings) is organized into sections:

  • General: Order prefix, products per page, sidebar position, grid columns, default view mode, shop page title/subtitle/breadcrumb label.
  • Tax: Enable/disable tax, tax rate percentage, tax-inclusive pricing toggle.
  • Shipping: Enable/disable shipping, flat rate, free shipping threshold.
  • Checkout: Guest checkout toggle, require phone number, require shipping address.
  • Digital Products: Max downloads per purchase, download link expiry in days.
  • Stock: Low stock threshold.
  • Notifications: Admin notification on new order, customer order confirmation.

Admin: Products

The Products page (Shop → Products) manages your product catalog.

Products List

A paginated table showing:

  • Featured image (thumbnail)
  • Name and SKU
  • Category
  • Price (with sale price if applicable)
  • Stock quantity
  • Status (draft / published / archived)
  • Checkout type (internal / external)

Per-item actions: Edit, Delete. Bulk delete with checkbox selection.

Creating & Editing Products

The product form includes the following sections:

Basic Information

  • Name (translatable): product title displayed in the catalog.
  • Slug (translatable): URL-friendly identifier. Auto-generated from name if empty.
  • Short Description (translatable): summary shown on listing pages.
  • Description (translatable): full product description with WYSIWYG editor.
  • Category: select from product categories.
  • SKU: stock keeping unit identifier.
  • Status: Draft, Published, or Archived.
  • Published At: schedule publishing date.

Pricing

  • Price: regular product price.
  • Sale Price: optional discounted price (must be less than regular price to take effect).
  • Currency: set from the site’s default currency setting.

Inventory

  • Manage Stock: toggle stock tracking. When disabled, the product is always “in stock.”
  • Stock Quantity: current inventory count.

Checkout Type

  • Internal: standard add-to-cart checkout flow.
  • External: product links to an external URL. Cannot be added to cart. Stock tracking is disabled.

Images

  • Featured Image: primary product image (uses the media library).
  • Gallery Images: additional product images displayed on the detail page.

SEO

  • Meta Title (translatable)
  • Meta Description (translatable)

Feed Data

  • Brand, GTIN, MPN, Condition, Weight: used in merchant feed generation and schema.org structured data.
  • Custom Labels (0–4): for merchant feed segmentation.

Product Variants

Products can have multiple variants, each with its own:

  • Name (e.g. “Large, Red”)
  • SKU
  • Price (overrides product price if set)
  • Stock Quantity
  • Attributes (JSON: key-value pairs for size, color, etc.)
  • Active toggle

Variants are synced on product save. Removed variants are automatically deleted.

Digital Products

When Is Digital is enabled:

  • A Digital File upload field appears. Files are stored on the configured disk (default: local) under the digital-products path.
  • Shipping is automatically excluded for digital-only orders.
  • After payment, order items receive a time-limited download link.
  • Download attempts are tracked via download_count and enforced against shop_digital_max_downloads.
  • Download links expire after shop_digital_expiry_days.

External Products

When Checkout Type is set to External:

  • An External URL field appears.
  • The product cannot be added to the cart.
  • The front-end displays a “Buy Now” button linking to the external URL.
  • Stock management, digital file, and inventory fields are automatically disabled.

Admin: Categories

Product categories use the unified categories table with categorizable_type = 'product'. Categories are managed via Shop → Categories.

  • Name (translatable) and Slug (translatable, auto-generated).
  • Description (translatable) and Meta Title / Meta Description (translatable).
  • Parent Category: supports hierarchical nesting.
  • Position: ordering value.
  • Is Active toggle.
  • Featured Image via the media library.
  • Google Product Category: feed data for merchant feed generation (via shop_category_feed_data).

Admin: Orders

The Orders page (Shop → Orders) provides a list of all customer orders.

Orders List

A paginated, filterable table showing:

  • Order Number (format: ORD-YYYYMMDD-00000001)
  • Customer name & email
  • Items count
  • Total (formatted with currency)
  • Status badge (pending, processing, completed, cancelled, refunded)
  • Payment Status badge (pending, paid, failed, refunded)
  • Date

Per-item actions: View, Delete.

Order Detail

The order detail page (Shop → Orders → {order}) shows:

  • Order summary card: order number, date, status, payment status, payment method.
  • Customer info: name, email, phone, billing address, shipping address.
  • Order items table: product name, SKU, price, quantity, total, digital badge, download info.
  • Financial summary: subtotal, discount, tax, shipping, total.
  • Coupon code (if applied).
  • Transactions list: gateway, transaction ID, amount, status, type (payment / refund).
  • Notes from the customer.

Status Updates

Admin can update order status and payment status via dropdown selectors:

  • Update Status: sends PATCH admin/shop/orders/{id}/status
  • Update Payment Status: sends PATCH admin/shop/orders/{id}/payment-status

Order Statuses

Status Description
pending Order placed but not yet processed or paid.
processing Order is being prepared / fulfilled.
completed Order has been fulfilled and delivered / downloaded.
cancelled Order was cancelled. Stock is automatically restored.
refunded Payment has been refunded to the customer.

Payment Statuses

Status Description
pending Awaiting payment.
paid Payment received and confirmed.
failed Payment attempt failed.
refunded Payment has been refunded.

Admin: Coupons

The Coupons page (Shop → Coupons) manages discount codes.

Coupon Fields

Field Description
code Unique coupon code entered by the customer at checkout.
type percentage or fixed discount.
value Discount amount (percentage points or fixed currency amount).
min_order_amount Minimum order subtotal required for the coupon to apply.
max_discount Maximum discount cap (useful for percentage coupons on large orders).
max_uses Total number of times this coupon can be used across all customers.
max_uses_per_user Maximum uses per individual user.
starts_at Coupon becomes valid after this date.
expires_at Coupon expires after this date.
is_active Enable/disable the coupon.

Validation Rules

A coupon is considered valid when all of the following are true:

  1. is_active is true.
  2. Current date is after starts_at (or starts_at is null).
  3. Current date is before expires_at (or expires_at is null).
  4. used_count is less than max_uses (or max_uses is null).

A coupon is applicable to an order when it is valid AND the order subtotal meets min_order_amount.

The discount calculation never exceeds the order subtotal.

Admin: Merchant Feeds

The Merchant Feeds page (Shop → Merchant Feeds) manages product feed generation for e-commerce advertising platforms.

Supported Platforms

Platform Format Key Settings
Google Merchant Center XML Merchant Center ID, Target Country, Content Language
Bing / Microsoft XML Merchant ID, Store ID
Facebook / Meta Commerce XML Commerce Account ID, Catalog ID
Amazon Product Ads XML Seller ID, Marketplace ID, Default Category
TikTok Shop CSV TikTok Shop ID
Yandex.Market YML Shop Name, Company Name
Baidu Commerce XML Merchant ID

Per-Platform Management

For each platform, admin can:

  • Enable/Disable: toggle feed generation on or off.
  • Configure Settings: merchant ID, API keys (encrypted), currency, cache TTL, include variants, include out-of-stock products.
  • Customize Field Mappings: map platform-specific feed fields to product data properties. Override default mappings, set default values, and apply transforms.
  • Generate Feed: manually trigger feed generation.
  • Preview Feed: view a sample of the generated output.
  • Validate Feed: check the feed for structural errors.

Artisan Command

Generates feeds for all enabled platforms. Can be scheduled via Laravel’s task scheduler for automatic periodic regeneration.

Feed URLs

Generated feeds are accessible at:

For example: /feeds/products/google returns the Google Merchant Center XML feed.

Front-end: Product Catalog

Routes

MethodURLRoute NameDescription
GET /{locale}/shop shop.index.localized Product listing page
GET /{locale}/shop/category/{slug} shop.category.localized Category filtered listing
GET /{locale}/shop/product/{slug} shop.product.localized Product detail page

Non-localized variants (without {locale}) are also registered.

Product Listing Features

  • Category filtering via URL or sidebar links.
  • Search across product name, description, and SKU.
  • Sort by: newest, price (low/high), name, popularity (view count).
  • Price range filtering with min/max parameters.
  • Grid / List view toggle.
  • Pagination with configurable page size.

Product Detail Page

  • Product image gallery with featured image.
  • Price display with sale badge and discount percentage.
  • Variant selector (if variants exist).
  • Stock availability indicator.
  • Add to Cart button (or “Buy Now” link for external products).
  • Related products section (same category).
  • Schema.org JSON-LD structured data (via <x-shop-json-ld> component).

Front-end: Shopping Cart

Routes

MethodURLRoute NameDescription
GET /{locale}/shop/cart shop.cart.localized View cart
POST /{locale}/shop/cart/add shop.cart.add.localized Add item to cart
POST /{locale}/shop/cart/update shop.cart.update.localized Update item quantity
POST /{locale}/shop/cart/remove shop.cart.remove.localized Remove item from cart
POST /{locale}/shop/cart/clear shop.cart.clear.localized Clear entire cart
POST /{locale}/shop/cart/coupon shop.cart.coupon.localized Apply coupon code
DELETE /{locale}/shop/cart/coupon shop.cart.coupon.remove.localized Remove applied coupon

Cart Behavior

  • Guest carts: stored in the database, identified by a session-based ID (shop_cart session key).
  • Authenticated carts: stored by user_id. When a user logs in, their session cart is automatically merged into their user cart.
  • Stock validation: adding items checks available stock. If the requested quantity exceeds stock, an error is returned.
  • Max quantity: configurable per-item limit (default: 99).
  • External products cannot be added to the cart; an exception is thrown with a translatable message.
  • Cart count is shared with all views via a View Composer.

Cart Totals

The CartService calculates:

  • Subtotal: sum of (price × quantity) for all items.
  • Discount: coupon discount (percentage or fixed), capped at max_discount.
  • Tax: calculated on (subtotal - discount). Supports inclusive pricing (embedded tax extraction).
  • Shipping: flat rate, waived for digital-only orders or when subtotal meets free shipping threshold.
  • Total: subtotal - discount + tax + shipping.

Front-end: Checkout

Routes

MethodURLRoute NameDescription
GET /{locale}/shop/checkout shop.checkout.localized Checkout form
POST /{locale}/shop/checkout shop.checkout.process.localized Process checkout
GET /{locale}/shop/checkout/success/{orderNumber} shop.checkout.success.localized Order success page

Checkout Flow

  1. Cart validation: redirects to cart page if empty.
  2. Guest check: if guest checkout is disabled and user is not authenticated, redirects to login.
  3. Form display: billing info (name, email, phone), billing address, shipping address, order notes, payment method selector.
  4. Form submission via CheckoutRequest validation.
  5. Order creation: the OrderService::createFromCart() method:
    • Creates the order record with all totals.
    • Creates order items from cart items.
    • Generates download links for digital products.
    • Decrements stock for managed-stock products.
    • Increments coupon usage count.
    • Sends admin and customer email notifications.
  6. Payment processing: the order implements the Payable interface, allowing the core PaymentService to route to the selected payment gateway.
  7. Success page: displays order confirmation with order number and details.
Order Numbers: Generated automatically using the pattern {prefix}-{YYYYMMDD}-{zero-padded ID}. The prefix is configurable via shop_order_prefix.

Front-end: My Orders

Routes

MethodURLRoute NameDescription
GET /{locale}/shop/my-orders shop.orders.localized List user’s orders (auth required)
GET /{locale}/shop/my-orders/{orderNumber} shop.orders.show.localized Order detail (auth required)
GET /{locale}/shop/my-orders/{orderNumber}/download/{itemId} shop.orders.download.localized Download digital product (auth required)

Digital Downloads

For digital products, the download is allowed when all conditions are met:

  • The order item is marked as is_digital with a download_link.
  • The order has been paid (payment_status = 'paid').
  • The download link has not expired (download_expires_at is in the future).
  • The download count has not reached the maximum (shop_digital_max_downloads).

Each successful download increments download_count.

Front-end: Order Tracking

GET /{locale}/shop/order/track
Description

Guest order tracking. Customers enter their order number and billing email to view order status without logging in.

Query Parameters
order_number Required The order number (e.g. ORD-20260307-00000001)
email Required Billing email used during checkout

Payment Flow

  1. Customer selects a payment method on the checkout page.
  2. The checkout controller creates the order via OrderService::createFromCart().
  3. The PaymentService routes the order to the selected gateway.
  4. The gateway processes the payment (redirect to external page, card form, etc.).
  5. On success, the gateway calls order->markAsPaid() which sets status to completed and payment status to paid, then clears the cart.
  6. On failure, the gateway calls order->markPaymentFailed().
  7. Customer is redirected to the success URL or back to checkout.

Transactions

Payment gateways create Transaction records to track payment events:

  • Type: payment or refund
  • Status: pending, completed, or failed
  • Gateway info: gateway name, gateway transaction ID, amount, currency
  • Metadata: JSON field for gateway-specific data

Updating

Step 1: Replace Files

Replace the add-on directory with the new version.

Step 2: Run Migrations

Step 3: Clear Caches

Step 4: Rebuild Assets

Backup first: Always back up your database before running migrations on a production system.

Troubleshooting

Products not appearing in the catalog

  • Ensure the product status is Published (not Draft or Archived).
  • Check published_at: if set, it must be in the past.
  • Verify the product has at least a name set for the current locale.

Add to Cart fails: “Insufficient stock”

  • Check that stock_quantity is greater than the requested quantity.
  • If the item is already in the cart, the combined quantity must not exceed available stock.
  • Disable Manage Stock on the product to always treat it as in-stock.

Cannot add external product to cart

This is by design. External products (checkout_type = 'external') redirect to an external URL. They cannot be added to the internal cart. On the front-end, a “Buy Now” link is shown instead of the Add to Cart button.

Coupon not applying

  • Verify the coupon is_active is true.
  • Check starts_at and expires_at dates.
  • Confirm the order subtotal meets min_order_amount.
  • Check if used_count has reached max_uses.

Checkout fails: no payment gateways available

  • Install and activate at least one payment gateway add-on (e.g. Stripe).
  • Cash on Delivery (COD) is available as a built-in option when the shop is active.
  • Verify the payment gateway is configured correctly in its settings.

Digital download returns 403 or “Download not available”

  • Confirm the order payment_status is paid.
  • Check if the download has expired (download_expires_at).
  • Check if the maximum download count has been reached.
  • Verify the digital file exists on the configured storage disk at the stored path.

Merchant feed returns empty or 404

  • Ensure the platform is enabled in Shop → Merchant Feeds.
  • Run php artisan shop:generate-feeds to regenerate feeds.
  • Check that published products exist with is_digital = false or include_out_of_stock is enabled.
  • Verify the feed URL: /feeds/products/{platformKey} (e.g. /feeds/products/google).

Tax calculation seems incorrect

  • If using tax-inclusive pricing, the tax is extracted from (not added to) the subtotal. For a 20% rate on a $120 subtotal: tax = $120 - ($120 / 1.20) = $20.
  • For tax-exclusive pricing, tax is calculated as: (subtotal - discount) × rate / 100.
  • Verify the shop_tax_rate setting is the correct percentage (e.g. 20 for 20%, not 0.20).

Cart not merging after login

  • The session cart is identified by the shop_cart session key. If the session was cleared before login, the guest cart cannot be found.
  • Merging happens in CartService::mergeSessionCart() on the first cart access after login.

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket