# Auto-login

How auto-login signs a punchout buyer in to their shop account with a signed single-use token, what to set in the portal and the plugin, and what happens when a piece is missing.

URL: https://punchout.dev/docs/plugins/auto-login/

Auto-login signs a punchout buyer in to their customer account in your shop at the start of a punchout, so they see their own prices and assortment instead of guest prices.

## What it solves

A buyer system signs in at punchout.dev with its buyer credential, not at your shop. Without auto-login the buyer lands in your shop as a guest. If your shop shows customer-specific prices, contract assortments or prices only after login, the guest cart carries the wrong prices into the requisition.

With auto-login, punchout.dev knows which shop customer each buyer credential stands for. At launch, it sends the browser to your shop's login endpoint with a short-lived signed token instead of a password. The shop plugin checks the token and signs that customer in.

## What you need

| Piece | Where |
| --- | --- |
| A login endpoint in the shop | One of the [shop plugins](https://punchout.dev/docs/plugins/), or [your own](https://punchout.dev/docs/plugins/custom/) |
| Auto-login switched on, with adapter, login path and customer reference | Portal, shop's **Auto-login** tab |
| The public key line in the plugin | Portal, Auto-login tab, section **Public keys** |
| A shop customer per buyer credential | Portal, **Buyers** tab, field **Shop customer reference** |
| A hosted launch | The buyer system uses the **OCI launch**, the **cXML PunchOutSetupRequest** or the **IDS Connect Roundtrip-URL** from the Embed tab |

:::note
A direct OCI launch, where the buyer system opens your shop's own address, never uses auto-login: nobody has checked a credential at that point. Use the hosted **OCI launch** URL from the Embed tab instead. The portal's test punchout does not use auto-login either.
:::

## Set it up

### 1. The portal's Auto-login tab

| Field | Meaning |
| --- | --- |
| Enable auto-login | Turns the redirect to your shop's login endpoint on. |
| Adapter | Shopware, Magento, WooCommerce or **Custom adapter**. It records which endpoint you run and changes nothing in the token. For WooCommerce and Magento the tab then shows that plugin's path and what each customer reference means there. |
| Login path | The endpoint's path on your shop, starting with `/`. The redirect goes to the first entry under **Allowed origins** on the General tab, followed by this path. |
| Customer reference | How every **Shop customer reference** of this shop is read: **Customer ID**, **Customer number** or **Email address**. |

What each kind means per platform:

| Customer reference | Shopware | WooCommerce | Magento |
| --- | --- | --- | --- |
| Customer ID | The customer's ID | The numeric WordPress user ID | The customer entity ID |
| Customer number | The customer number | The WordPress login name | Not supported, the buyer lands as a guest |
| Email address | The customer's email address | The user's email address | The customer's email address on the current website |

### 2. The public key line

The section **Public keys** on the same tab shows the public key line, for example `k1=…`. Paste it into the plugin's **Public key lines** setting. The plugin uses it to check the signature. It is a public key: it can check tokens but never create one.

If the section says "No signing key is configured. Without one, every punchout lands on the plain landing page.", there is no key to paste and auto-login cannot be set up.

If the section shows more than one line, paste all of them.

### 3. The mapping per buyer

On the **Buyers** tab, open a credential and fill in **Shop customer reference** ("Which shop account auto-login signs this buyer into."): the customer ID, customer number or email address of the shop account, matching the kind chosen on the Auto-login tab. A credential without it keeps landing as a guest, even when auto-login is on.

## The flow

1. **Launch.** The buyer system starts a hosted launch, and punchout.dev checks the buyer credential.
2. **Token.** If auto-login is on and the credential has a shop customer reference, punchout.dev issues a signed login token. It is valid for 120 seconds, can be used once and only in your shop. It names the customer and your **Landing path**.
3. **Redirect.** The browser goes to your shop's login path with the token, for example `https://shop.example/punchout-dev/login?token=…`.
4. **Login.** The plugin checks the token, finds exactly one matching customer and signs them in.
5. **Cart page.** The plugin redirects to your landing page. The punchout continues there, and the buyer shops signed in.

The token carries no secret. It travels through the buyer's browser, so it is short-lived, single-use and scoped to one shop, and it can only lead to a path on your own shop, never anywhere else.

## When a piece is missing

Auto-login never breaks a punchout.

| Situation | What happens |
| --- | --- |
| Auto-login off, no shop customer reference on the credential, or no signing key | The browser goes straight to the plain landing page and the buyer shops as a guest. |
| The plugin refuses the token | The plugin redirects to the landing page without a login. The punchout continues as a guest. |
| The Login path is wrong | The browser lands on whatever your shop serves at that path, usually its 404 page. |
| **Enable auto-login**, **Shop ID** or **Public key lines** is off or empty in the plugin | The plugin redirects to the landing page without a login. The punchout continues as a guest. |

:::note
Shopware: 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.
:::

## What the plugin logs

Each plugin writes one log line per refused token into the shop's own log, with a reason word. None of them logs the token or the customer.

| Platform | Log |
| --- | --- |
| Shopware 6 | Shopware log, level warning |
| Magento 2 | `var/log/system.log`, level info |
| WooCommerce | PHP error log, only with `WP_DEBUG` on |

These are the reason words you are most likely to see. The plugin skips a mistyped or truncated key line, so it shows up as `not_configured` or `kid_unknown`.

| Reason | Cause | Fix |
| --- | --- | --- |
| `not_configured` | Shop ID empty in the plugin, or no readable line in **Public key lines** | Fill in both |
| `disabled` | **Enable auto-login** is off in the plugin | Switch it on |
| `kid_unknown` | **Public key lines** lacks the current line from the portal, for example when only an old line is there | Paste the current line from the portal |
| `signature_invalid` | A line in **Public key lines** is wrong or outdated | Paste the current line from the portal |
| `audience` | The plugin's Shop ID differs from the shop that launched | Copy the Shop ID from the Embed tab |
| `expired` | The token arrived more than 120 seconds after it was issued, or the shop's clock runs fast | Start a new punchout. If it happens every time, synchronize the server clock. |
| `iat_future` | The shop's clock runs behind | Synchronize the server clock |
| `replay` | The token was already used (a reload, the back button), or the plugin's table for used tokens is missing | Start a new punchout. If it happens every time, recreate the table (see the platform page). |
| `customer_unresolved` | No active customer matches the reference, or more than one does | Check the **Shop customer reference** and the **Customer reference** kind |
| `administrator_refused` | WooCommerce: the mapped user is an administrator | Map to an ordinary customer account |
| `unsupported_ref_kind` | Magento: Customer reference is Customer number | Use Email address or Customer ID |

## Build your own endpoint

The token format, the checks in their order and the test vector are described in the [login token specification](https://punchout.dev/docs/plugins/custom/login-token/). The [Your own integration](https://punchout.dev/docs/plugins/custom/) page explains what to set in the portal for a custom endpoint.
