# Shopware 6

Install and configure the punchout.dev plugin for Shopware 6.7, run the setup self-test and fix a missing cart marker or a failed login.

URL: https://punchout.dev/docs/plugins/shopware/

The punchout.dev plugin for Shopware 6.7 prints the script tag, marks the cart page for punchout.dev and signs punchout buyers in to their customer account.

## Requirements

| Requirement | Value |
| --- | --- |
| Shopware | 6.7 (`>=6.7 <6.8`) |
| PHP extensions | `sodium`, `json` |
| Plugin | `PunchoutDev`, version 2.0.1 or newer |
| Download | `PunchoutDev-<version>.zip` from the shop's **Embed** tab in the portal (Shop platform: Shopware) |

## Install

### In the Administration

1. Download the plugin from the portal's **Embed** tab.
2. In the Shopware Administration, upload the zip in the extension management under **Extensions**.
3. Install and activate **punchout.dev**.

### On the command line

Unpack the zip into `custom/plugins`. It contains one folder, so the plugin lands in `custom/plugins/PunchoutDev`. Then run:

```bash
bin/console plugin:refresh
bin/console plugin:install --activate PunchoutDev
bin/console cache:clear
```

`plugin:install` runs the plugin's migration, which creates the table the plugin needs to accept each login token only once. Without that table every auto-login fails and the buyer continues as a guest.

## Configure

In the Administration, open **Extensions** and choose **Configure** on the **punchout.dev** entry. You can set every value per sales channel.

### Snippet card

| Setting | Value |
| --- | --- |
| Embed the snippet | On (default). Off prints no script tag at all. |
| Snippet URL | `https://js.punchout.dev/pob.js`, from the portal's Embed tab. Empty prints nothing. |
| API base URL (optional) | Leave empty. |

### Auto-login card

| Setting | Value |
| --- | --- |
| Enable auto-login | On (default). |
| Shop ID | The **Shop ID** from the portal's Embed tab. |
| Public key lines | Every line from the portal's Auto-login tab, section **Public keys**, one per line. Lines starting with `#` and blank lines are ignored. |

:::caution
The **Shop ID** sits in the Auto-login card, but the script tag needs it too: the plugin prints it as `data-shop-id`. Fill it in even if you do not use auto-login. Without it, the plugin prints no script tag.
:::

The same values from the command line:

```bash
bin/console system:config:set PunchoutDev.config.snippetUrl https://js.punchout.dev/pob.js
bin/console system:config:set PunchoutDev.config.tenantId pob_live_…
bin/console system:config:set PunchoutDev.config.publicKeys "k1=…"
bin/console cache:clear
```

The plugin prints this tag on every storefront page, in the block `base_body_script`:

```html
<script async src="https://js.punchout.dev/pob.js" data-shop-id="pob_live_…"></script>
```

## What the plugin marks

On the cart page the plugin wraps the Twig block `page_checkout_cart_product_table` in `<div data-punchout-cart>`. That block renders the line-item table and nothing else: the order summary, the promotion form and the checkout button stay outside. The plugin prints the marker even when **Embed the snippet** is off. On its own, the marker does nothing.

## Auto-login

The plugin's login endpoint is `GET /punchout-dev/login?token=…`. Set up the portal side on the shop's **Auto-login** tab:

| Portal field | Value |
| --- | --- |
| Adapter | Shopware |
| Login path | `/punchout-dev/login` for a shop at the domain root. A shop in a sub-folder prefixes its path, for example `/shop/public/punchout-dev/login`. |
| Customer reference | Customer ID, Customer number or Email address. All three work on Shopware. |

Then give each buyer credential its **Shop customer reference** on the **Buyers** tab: the customer's ID, customer number or email address, as chosen above.

After the login, the plugin redirects to the landing path as it is, without adding the shop's base path. For a shop in a sub-folder, the **Landing path** on the General tab must include the sub-folder, for example `/shop/public/checkout/cart`.

The plugin signs a customer in only when exactly one active customer matches. Guest accounts never match, and a customer bound to another sales channel does not match either. The customer ID works with or without dashes. The full flow is on the [Auto-login](https://punchout.dev/docs/plugins/auto-login/) page.

## Setup self-test

1. On the shop's **Setup** tab in the portal, create a setup link (valid 60 minutes by default).
2. Put 2 or 3 different products in the cart.
3. Open the cart page with the setup link.

With the plugin in place, the panel shows "Shop plugin detected — the cart is already marked." before you click. Click **Detect cart**, and the result names the source **Shop plugin**. Confirm with **Yes, that's it**. The test proves that the marker is on the page and that the tag runs with the right Shop ID, and it completes the **Cart detected** step in the portal. Nothing else is stored for the cart, because punchout.dev reads the marker on every punchout.

## Update

Download the new zip from the Embed tab, unpack it over `custom/plugins/PunchoutDev`, then:

```bash
bin/console plugin:refresh
bin/console plugin:update PunchoutDev
bin/console cache:clear
```

### Coming from PunchoutNinja 1.x

Version 2.0.0 is a new plugin to Shopware: uninstall `PunchoutNinja` and delete its folder before installing `PunchoutDev`, and never run both. Nothing is carried over: enter both cards again and change the **Login path** on the portal's Auto-login tab to `/punchout-dev/login`.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| No `pob.js` tag in the page source | **Embed the snippet** off, or **Snippet URL** or **Shop ID** empty for this sales channel | Switch **Embed the snippet** on and fill in both values, then `bin/console cache:clear` |
| The setup panel reports **Preset** or **Detected automatically** instead of **Shop plugin** | The marker did not reach the page: the theme overrides `page_checkout_cart_product_table` without calling `parent()`, or the storefront cache is stale | Call `parent()` in the theme's block, then `bin/console cache:clear` |
| Every login is rejected with reason `replay` | The plugin's table for used login tokens is missing | `bin/console plugin:update PunchoutDev` |
| Every login is rejected with reason `expired` | The shop's clock runs fast | Synchronize the server clock |
| The buyer lands on a 404 page | The portal's **Login path** does not match the route, often after the move from 1.x | Set it to `/punchout-dev/login`, with the sub-folder prefix if any |
| Auto-login does nothing and the buyer shops as a guest | Auto-login is on in the portal, but **Enable auto-login** is off or **Shop ID** / **Public key lines** are empty in the plugin (reason `disabled` or `not_configured`). The plugin redirects to the landing page without a login. | Fill in the Auto-login card, or turn auto-login off on the portal's Auto-login tab |

:::note
When auto-login was switched off or unconfigured on the plugin side, plugin 2.0.0 redirected to `/` instead of the landing page, and the punchout was lost. Update to 2.0.1 or newer.
:::

The plugin writes one warning per refused login token to the Shopware log, with a reason word. It never logs the token or the customer. The reason words are listed on the [Auto-login](https://punchout.dev/docs/plugins/auto-login/) page.

For more, see [Troubleshooting](https://punchout.dev/docs/troubleshooting/).

## Full README

The plugin's README covers the token checks, the security notes and the development self-test: [Shopware plugin README](https://punchout.dev/docs/plugins/shopware/readme/).
