Punchout and EDI
Both flows hang off a trading partner record (Settings → Integrations, or POST /admin/trading-partners): a protocol (cxml, edi_x12 or edifact), a transport, the partner's identity, a shared secret, and the customer company the partner acts for. Buyers with a company admin role can also generate their own cXML credentials from the storefront under Settings → Procurement integration.
cXML punchout
Punchout lets a buyer in Ariba, Coupa, SAP or a similar system open your storefront inside their procurement session, fill a cart, and return it as a requisition.
1. Setup
The procurement system posts a PunchOutSetupRequest:
POST /punchout/setup
Content-Type: text/xml
- The sender identity is read from
Header/Sender/Credential/Identityand must match a trading partner; theSharedSecretin that credential must match the partner's secret (compared in constant time, and an empty stored secret never matches). BrowserFormPost/URLis required — it is where the cart is returned.BuyerCookieand theoperationattribute are stored on the session.
The response is a PunchOutSetupResponse whose StartPage/URL is https://<api host>/punchout/start/{session}. Sessions expire after PUNCHOUT_TTL (default one hour).
2. Shopping
The procurement system opens the start URL in the buyer's browser. Sokisoko creates or reuses a cart for the partner's customer, issues a storefront session bound to that customer, and redirects to the storefront in punchout mode — the buyer sees their contract pricing and catalog visibility exactly as a signed-in buyer would. Append ?format=json to the start URL to receive { "token", "cart_id", "cart_public_id", "session" } instead of a redirect if you drive the storefront yourself.
3. Transfer
When the buyer checks out in punchout mode, the storefront calls:
POST /punchout/transfer/{session}
which returns an HTML form that auto-posts a PunchOutOrderMessage to the BrowserFormPost URL. Each cart line becomes an item with SupplierPartID (the SKU), description, unit of measure, quantity and unit price. The procurement system turns that into a purchase order, which typically comes back as an EDI 850 (below) or a cXML OrderRequest.
X12 EDI
Inbound purchase orders (850)
POST /edi/inbound/{partnerID}
X-EDI-Secret: <the partner's shared secret>
Content-Type: text/plain
ISA*00*…~GS*PO*…~ST*850*0001~BEG*00*SA*PO-2026-0142**20260905~…
- Authentication is the partner's shared secret in
X-EDI-Secret; a partner with no secret cannot ingest (fail closed). Inactive partners are refused. - Segments end with
~, elements are separated by*. - The raw document is stored first and deduplicated on the PO number — a second delivery of the same PO answers
409 duplicate. - Every line's part number must match a product SKU. If any line does not, nothing is created and the response is
422 unknown_skunaming the SKU — all or nothing. - On success an order is created for the partner's customer with the PO number, and the response body is an 855 acknowledgement.
Outbound documents
Staff (or an integration with the right scopes) generate outbound documents from an order or invoice:
POST /admin/edi/856— an ASN (ship notice) from a shipmentPOST /admin/edi/810— an invoice
Both are returned as X12 text and recorded. GET /admin/edi/documents lists every inbound and outbound document with its direction, type, control number and status; the console shows the same log under Settings → Integrations. Our sender id on outbound documents is EDI_SENDER_ID.