# Coupa (cXML)

Which punchout URL, domain, identity and shared secret to enter for a punchout.dev shop in Coupa or any other cXML buyer system, and how to test the connection.

URL: https://punchout.dev/docs/buyer-systems/coupa-cxml/

This page shows a Coupa administrator how to set up a punchout.dev shop as a cXML punchout supplier in Coupa. The steps carry over to any other buyer system that speaks cXML.

## What you need

| Item | Value |
| --- | --- |
| Punchout URL | `https://api.punchout.dev/v1/cxml/setup/<shop id>` |
| Domain | The credential domain Coupa sends, agreed with the shop owner |
| Identity | The credential identity Coupa sends, agreed with the shop owner |
| Shared secret | Generated by the portal, or one you chose (at least 16 characters) |

The shop owner finds the URL on the shop's Embed tab under **Launch URLs for the buying system** and creates the credential on the Buyers tab. If you already chose a shared secret in Coupa, the shop owner picks **Enter my own** and stores the same value.

If the shop owner limits **Allowed return hosts**, give them the host name of Coupa's return address.

## What to enter in Coupa

In Coupa the punchout settings are typically part of the supplier record. Depending on how your instance is run, your Coupa administrator fills them in, or the supplier does so in the Coupa Supplier Portal. Labels vary by release, and Coupa's documentation shows the current screen. The table therefore maps the fields by meaning:

| Coupa field (by meaning) | Enter |
| --- | --- |
| Punchout URL | `https://api.punchout.dev/v1/cxml/setup/<shop id>` |
| Protocol | cXML |
| Domain | The agreed domain, for example `NetworkID` or `DUNS` |
| Identity | The agreed identity |
| Shared secret | The credential's secret |

Enter the domain as agreed, upper and lower case included: `DUNS` and `duns` are two different domains.

The punchout opens the shop's landing page and returns a cart. Item-level landing (Level 2) is enabled on request.

## Test the punchout

1. Open the supplier's punchout from a new requisition in Coupa.
2. Put two or three items in the shop's cart and open the cart page.
3. Check the items the panel lists and click **Transfer to procurement system**.
4. Launch again and click **Back to procurement system**.

## What a successful test looks like

- The shop opens with the punchout panel, which reads "Punchout active".
- On the cart page the panel lists the items with quantity and price.
- After the transfer, the items appear in the Coupa cart with part number, description, unit, price and currency.
- After **Back to procurement system**, Coupa closes the punchout without adding anything.

punchout.dev hands prices over the way Coupa expects. The shop owner decides in the portal whether they arrive gross or net. If you need them the other way, ask the shop owner to change **Price quality** on the General tab.

## When the test fails

| What Coupa reports | Cause | What to do |
| --- | --- | --- |
| `Authentication failed` | The domain, identity or shared secret does not match, or the credential is disabled | Compare all three with the shop owner, including case |
| `Unknown tenant or credentials` | The Shop ID in the punchout URL is wrong, or the shop is inactive | Copy the URL again from the shop owner |
| `Invalid PunchOutSetupRequest` | Most often the shop does not allow Coupa's return address | Give the shop owner the host name; they add it to **Allowed return hosts** |
| `Supplier not enabled for productive punchout` | The shop is still in its Sandbox | Nothing on your side. See [Plans and Sandbox](https://punchout.dev/docs/account/plans-and-sandbox/) |

Other problems show up in the shop:

- **The shop opens without the punchout panel.** The shop forwards the browser to an address that is not registered for punchout.dev, for example with or without `www.`. The shop owner adds that address under **Allowed origins**.
- **The transfer button does nothing.** The shop's Content-Security-Policy blocks Coupa's return host. The shop owner allows it in that policy.
- **The transfer fails after a long pause.** A punchout lasts four hours. Launch again.
