PunchOut Session API
Session erstellen
cXML PunchOut Setup Request
POST /v1/punchout/setup
Content-Type: application/xml
Request Body
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="1234567890" timestamp="2024-01-15T10:30:00Z">
<Header>
<From>
<Credential domain="NetworkId">
<Identity>buyer@company.com</Identity>
</Credential>
</From>
<To>
<Credential domain="DUNS">
<Identity>123456789</Identity>
</Credential>
</To>
<Sender>
<Credential domain="NetworkId">
<Identity>buyer@company.com</Identity>
<SharedSecret>SecretPassword123</SharedSecret>
</Credential>
</Sender>
</Header>
<Request>
<PunchOutSetupRequest operation="create">
<BuyerCookie>BUYER_COOKIE_123</BuyerCookie>
<Extrinsic name="UserEmail">user@company.com</Extrinsic>
<Extrinsic name="UserName">Max Mustermann</Extrinsic>
<Extrinsic name="CompanyCode">DE001</Extrinsic>
<BrowserFormPost>
<URL>https://erp.company.com/punchout/return</URL>
</BrowserFormPost>
<SupplierSetup>
<URL>https://api.punchflow.de/api/v1/punchout/catalog</URL>
</SupplierSetup>
</PunchOutSetupRequest>
</Request>
</cXML>
Response
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="response_123" timestamp="2024-01-15T10:30:01Z">
<Response>
<Status code="200" text="Success">
<PunchOutSetupResponse>
<StartPage>
<URL>https://shop.punchflow.de/session/START_123456?token=abc</URL>
</StartPage>
</PunchOutSetupResponse>
</Status>
</Response>
</cXML>
OCI PunchOut Setup
POST /v1/punchout/oci/setup
Content-Type: application/x-www-form-urlencoded
Request Parameters
HOOK_URL=https://erp.company.com/oci/return
USERNAME=buyer@company.com
PASSWORD=SecretPassword123
FUNCTION=CREATE_SESSION
LANGUAGE=de
CURRENCY=EUR
Response
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0;url=https://shop.punchflow.de/session/OCI_123456">
</head>
<body>
<p>Redirecting to shop...</p>
</body>
</html>
Session-Status abrufen
GET /v1/punchout/sessions/{session_id}
Authorization: Bearer YOUR_API_KEY
Response
{
"success": true,
"data": {
"session_id": "sess_123456",
"status": "active",
"protocol": "cxml",
"created_at": "2024-01-15T10:30:00Z",
"expires_at": "2024-01-15T11:30:00Z",
"buyer": {
"email": "buyer@company.com",
"name": "Max Mustermann",
"company": "Company GmbH"
},
"cart": {
"items_count": 3,
"total_amount": 1299.99,
"currency": "EUR"
},
"metadata": {
"buyer_cookie": "BUYER_COOKIE_123",
"return_url": "https://erp.company.com/punchout/return"
}
}
}
Warenkorb übertragen
cXML Order Message
POST /v1/punchout/transfer
Content-Type: application/xml
Request Body
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="order_123" timestamp="2024-01-15T10:45:00Z">
<Header>
<From>
<Credential domain="NetworkId">
<Identity>shop@punchflow.de</Identity>
</Credential>
</From>
<To>
<Credential domain="NetworkId">
<Identity>buyer@company.com</Identity>
</Credential>
</To>
<Sender>
<Credential domain="NetworkId">
<Identity>shop@punchflow.de</Identity>
</Credential>
</Sender>
</Header>
<Message>
<PunchOutOrderMessage>
<BuyerCookie>BUYER_COOKIE_123</BuyerCookie>
<PunchOutOrderMessageHeader operationAllowed="create">
<Total>
<Money currency="EUR">1299.99</Money>
</Total>
</PunchOutOrderMessageHeader>
<ItemIn quantity="2">
<ItemID>
<SupplierPartID>SKU-001</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="EUR">499.99</Money>
</UnitPrice>
<Description xml:lang="de">Premium Widget</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
<Classification domain="UNSPSC">12345678</Classification>
<ManufacturerName>WidgetCo</ManufacturerName>
<ManufacturerPartID>WID-001</ManufacturerPartID>
</ItemDetail>
</ItemIn>
<ItemIn quantity="1">
<ItemID>
<SupplierPartID>SKU-002</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="EUR">300.01</Money>
</UnitPrice>
<Description xml:lang="de">Standard Gadget</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
</ItemDetail>
</ItemIn>
</PunchOutOrderMessage>
</Message>
</cXML>
OCI Transfer
POST /v1/punchout/oci/transfer
Content-Type: application/x-www-form-urlencoded
Request Parameters
NEW_ITEM-DESCRIPTION[1]=Premium+Widget
NEW_ITEM-QUANTITY[1]=2
NEW_ITEM-UNIT[1]=EA
NEW_ITEM-PRICE[1]=499.99
NEW_ITEM-CURRENCY[1]=EUR
NEW_ITEM-LEADTIME[1]=5
NEW_ITEM-VENDORMAT[1]=SKU-001
NEW_ITEM-MATGROUP[1]=12345678
NEW_ITEM-MANUFACTURER[1]=WidgetCo
NEW_ITEM-MANUFACTMAT[1]=WID-001
NEW_ITEM-DESCRIPTION[2]=Standard+Gadget
NEW_ITEM-QUANTITY[2]=1
NEW_ITEM-UNIT[2]=EA
NEW_ITEM-PRICE[2]=300.01
NEW_ITEM-CURRENCY[2]=EUR
NEW_ITEM-VENDORMAT[2]=SKU-002
Session beenden
POST /v1/punchout/sessions/{session_id}/cancel
Authorization: Bearer YOUR_API_KEY
Response
{
"success": true,
"data": {
"session_id": "sess_123456",
"status": "cancelled",
"cancelled_at": "2024-01-15T10:50:00Z"
}
}
Session-Verlauf
GET /v1/punchout/sessions
Authorization: Bearer YOUR_API_KEY
Query Parameters
| Parameter | Typ | Beschreibung |
|---|---|---|
| status | string | Filter nach Status (active, completed, cancelled) |
| protocol | string | Filter nach Protokoll (cxml, oci) |
| from_date | datetime | Sessions ab diesem Datum |
| to_date | datetime | Sessions bis zu diesem Datum |
| page | integer | Seitennummer (default: 1) |
| limit | integer | Einträge pro Seite (max: 100) |
Response
{
"success": true,
"data": {
"sessions": [
{
"session_id": "sess_123456",
"status": "completed",
"protocol": "cxml",
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:45:00Z",
"buyer_email": "buyer@company.com",
"items_count": 3,
"total_amount": 1299.99,
"currency": "EUR"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"pages": 8
}
}
}
Session-Analytics
GET /v1/punchout/analytics
Authorization: Bearer YOUR_API_KEY
Query Parameters
| Parameter | Typ | Beschreibung |
|---|---|---|
| period | string | Zeitraum (day, week, month, year) |
| from_date | datetime | Start-Datum |
| to_date | datetime | End-Datum |
| group_by | string | Gruppierung (day, week, month) |
Response
{
"success": true,
"data": {
"summary": {
"total_sessions": 1250,
"completed_sessions": 980,
"conversion_rate": 78.4,
"average_cart_value": 899.50,
"total_revenue": 881510.00
},
"timeline": [
{
"date": "2024-01-01",
"sessions": 42,
"completed": 35,
"revenue": 29750.00
}
],
"top_products": [
{
"sku": "SKU-001",
"name": "Premium Widget",
"quantity": 245,
"revenue": 122497.55
}
]
}
}
Fehlerbehandlung
Häufige Fehler
Invalid Credentials
{
"success": false,
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Die Anmeldedaten sind ungültig",
"details": {
"protocol": "cxml",
"domain": "NetworkId"
}
}
}
Session Expired
{
"success": false,
"error": {
"code": "SESSION_EXPIRED",
"message": "Die Session ist abgelaufen",
"details": {
"session_id": "sess_123456",
"expired_at": "2024-01-15T11:30:00Z"
}
}
}
Invalid XML
{
"success": false,
"error": {
"code": "INVALID_XML",
"message": "Das XML-Dokument ist ungültig",
"details": {
"line": 15,
"column": 23,
"error": "Element 'ItemIn': Missing child element 'ItemID'"
}
}
}
Best Practices
Session-Timeout
- Standard-Timeout: 60 Minuten
- Konfigurierbar pro Merchant
- Automatische Verlängerung bei Aktivität
Sicherheit
- Validierung aller Credentials
- IP-Whitelisting möglich
- SSL/TLS erforderlich
- Session-Token mit JWT
Performance
- Asynchrone Verarbeitung großer Warenkörbe
- Caching von Produktdaten
- Batch-Updates unterstützt
Code-Beispiele
PHP
$client = new PunchFlowClient($apiKey);
// Session erstellen
$session = $client->punchout()->setupSession([
'protocol' => 'cxml',
'buyer_cookie' => 'BUYER_123',
'return_url' => 'https://erp.example.com/return'
]);
// Weiterleitung zum Shop
header('Location: ' . $session->getStartUrl());
Python
from punchflow import PunchFlowClient
client = PunchFlowClient(api_key)
# Session erstellen
session = client.punchout.setup_session(
protocol='cxml',
buyer_cookie='BUYER_123',
return_url='https://erp.example.com/return'
)
# Weiterleitung zum Shop
redirect(session.start_url)
Node.js
const client = new PunchFlowClient(apiKey);
// Session erstellen
const session = await client.punchout.setupSession({
protocol: 'cxml',
buyerCookie: 'BUYER_123',
returnUrl: 'https://erp.example.com/return'
});
// Weiterleitung zum Shop
res.redirect(session.startUrl);