Documentation

Everything you need to integrate Matthews Aurora Solution Center into your application.

Overview

SCX (Solution Center Exchange) enables seamless integration between your application and the Matthews Aurora Solution Center product catalog using industry-standard PunchOut protocols.

Integration Flow
  1. Your application sends a setup request with customer credentials to SCX
  2. SCX authenticates your request, maps your customer ID to a Solution Center account, and creates a session
  3. SCX returns a session URL (e.g., /shop/{token}) that you redirect or embed
  4. User browses the catalog with their contract pricing and filtered catalog types
  5. User builds their cart and clicks "Return Cart"
  6. Cart data is returned to your application via your configured callback method (redirect, POST, iframe postMessage, or form POST)
Display Modes

Choose how the catalog appears to your users:

Redirect

Full-page redirect to SCX. Best for mobile and simple integrations.

Iframe

Embed the catalog within your application. Users never leave your interface.

Popup

Opens in a new window. Users can keep their main workflow visible.

Quick Start

Here's the simplest way to create a PunchOut session using the REST API:

curl -X POST https://scx.example.com/api/punchout/setup \ -H "X-Api-Key: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "customerId": "YOUR-CUSTOMER-ID", "serviceCenterId": "YOUR-SERVICE-CENTER", "returnUrl": "https://your-app.com/cart/receive" }'

Response:

{ "success": true, "sessionToken": "abc123def456...", "sessionUrl": "https://scx.example.com/shop/abc123def456", "expiresAt": "2024-01-15T12:30:00Z" }

Redirect the user to sessionUrl (or embed it in an iframe). When they complete their cart, the data will be returned to your returnUrl via your configured callback method.


Authentication

SCX supports multiple authentication methods. The method used depends on your integration protocol.

API Keys

The recommended authentication method for REST API integrations. Generate API keys in your partner portal.

# Header authentication (recommended) X-Api-Key: your-api-key-here # Or as Bearer token Authorization: Bearer your-api-key-here

API keys are stored as SHA-256 hashes. An 8-character prefix is used for fast lookup. You can configure expiration dates and scope keys to specific integrations via the partner portal.

Security Note: API keys should be kept secret and never exposed in client-side code. Rotate keys periodically and set expiration dates. The full key is only shown once at creation time.

Shared Secret (cXML & OCI)

For cXML integrations, authentication is done via shared secret in the cXML Sender credential:

<!-- In the cXML Sender credential --> <Sender> <Credential domain="NetworkId"> <Identity>your-partner-id</Identity> <SharedSecret>your-shared-secret</SharedSecret> </Credential> </Sender>

For OCI integrations, the shared secret is passed as the PASSWORD parameter:

PASSWORD=your-shared-secret

Basic Authentication

Standard HTTP Basic Auth is also supported. Provide your partner ID and shared secret as the username and password:

# Basic Auth (Base64 encoded partner-id:shared-secret) Authorization: Basic cGFydG5lci1pZDpzaGFyZWQtc2VjcmV0 # Using curl curl -u "partner-id:shared-secret" \ -X POST https://scx.example.com/api/punchout/setup

IP Whitelisting

For additional security, you can restrict API access to specific IP addresses. Configure allowed IPs in your integration settings.

# Supported formats 192.168.1.100 // Exact IP address 10.0.0.0/24 // CIDR notation (10.0.0.0 - 10.0.0.255) 203.0.113.0/28 // Smaller subnet ranges

If no IP whitelist is configured, requests are accepted from any IP address. When configured, requests from non-whitelisted IPs are rejected with an authentication error.


Protocols

Choose the protocol that best fits your technology stack and integration requirements.

REST API

Recommended for Modern Apps

JSON-based API for easy integration with any programming language.

Create Session
POST /api/punchout/setup Content-Type: application/json X-Api-Key: your-api-key { "customerId": "FH-12345", "serviceCenterId": "SC-001", // optional "returnUrl": "https://your-app.com/cart", "displayMode": "redirect", // redirect, iframe, popup "operation": "create", // create, edit, inspect "buyerCookie": "your-session-ref", // optional tracking ID "browserFormPostUrl": "https://...", // optional, for cXML-style form POST "sessionPingUrl": "https://...", // optional, keep-alive ping URL "metadata": { // optional key-value pairs "orderId": "PO-12345" } }
Get Session Status
GET /api/punchout/session/{token} X-Api-Key: your-api-key
Get Session Response
{ "token": "abc123...", "status": "Active", // Active, Completed, Expired, Cancelled "customerId": "FH-12345", "serviceCenterId": "SC-001", "expiresAt": "2024-01-15T14:30:00Z", "createdAt": "2024-01-15T10:30:00Z", "cartData": "{ ... }" // JSON string with cart contents }
Update Cart
PUT /api/punchout/session/{token}/cart X-Api-Key: your-api-key Content-Type: application/json { "items": [ { "productId": "PROD-001", "sku": "SKU-12345", "name": "Tribute Memorial", "quantity": 2, "unitPrice": 99.99, "currency": "USD" } ], "subtotal": 199.98, "currency": "USD" }
Complete Session
POST /api/punchout/session/{token}/complete X-Api-Key: your-api-key

cXML

Enterprise Standard

Industry-standard protocol for enterprise procurement systems like Ariba, Coupa, and Jaggaer.

PunchOut Setup Request
POST /api/cxml Content-Type: text/xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.053/cXML.dtd"> <cXML payloadID="unique-id" timestamp="2024-01-15T10:30:00-05:00"> <Header> <From> <Credential domain="NetworkId"> <Identity>buyer-id</Identity> </Credential> </From> <To> <Credential domain="NetworkId"> <Identity>SCX</Identity> </Credential> </To> <Sender> <Credential domain="NetworkId"> <Identity>your-partner-id</Identity> <SharedSecret>your-shared-secret</SharedSecret> </Credential> </Sender> </Header> <Request> <PunchOutSetupRequest operation="create"> <BuyerCookie>session-id-from-your-system</BuyerCookie> <Extrinsic name="CustomerID">FH-12345</Extrinsic> <Extrinsic name="ServiceCenterID">SC-001</Extrinsic> <Extrinsic name="SessionPingUrl">https://your-app.com/ping</Extrinsic> <BrowserFormPost> <URL>https://your-app.com/cxml/receive</URL> </BrowserFormPost> </PunchOutSetupRequest> </Request> </cXML>
cXML Extrinsic Fields

SCX extracts customer and session data from Extrinsic elements. The following names are recognized (case-insensitive):

Extrinsic NameDescription
CustomerIDYour external customer identifier (required)
ServiceCenterIDService center identifier (optional)
SessionPingUrlURL for session keep-alive pings (optional)
FirstName, LastNameBuyer's name (optional, stored as metadata)
UserEmailBuyer's email address (optional)
UniqueNameBuyer's unique identifier (optional)
BusinessUnitBuyer's business unit (optional)
CostCenterBuyer's cost center (optional)
cXML Setup Response
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.053/cXML.dtd"> <cXML payloadID="response-id" timestamp="2024-01-15T10:30:01-05:00"> <Response> <Status code="200" text="OK">Success</Status> <PunchOutSetupResponse> <StartPage> <URL>https://scx.example.com/shop/abc123def456</URL> </StartPage> </PunchOutSetupResponse> </Response> </cXML>
Custom Field Mapping: Partners can configure custom XPath-like field names for CustomerID and ServiceCenterID extraction via integration settings, allowing compatibility with non-standard cXML implementations.

OCI (Open Catalog Interface)

SAP Compatible

For SAP and systems using OCI-based procurement. Supports both GET and POST requests.

Setup Request
GET /api/oci? HOOK_URL=https://your-app.com/oci/receive& USERNAME=your-partner-id& PASSWORD=your-shared-secret& CUSTOMER_ID=FH-12345& SERVICE_CENTER_ID=SC-001& FUNCTION=CREATE
OCI Parameters
ParameterRequiredDescription
HOOK_URLYesURL where cart data will be form-POSTed
USERNAMENoBuyer identifier (for logging)
PASSWORDYesShared secret for authentication
CUSTOMER_IDYesYour external customer identifier
SERVICE_CENTER_IDNoService center identifier
FUNCTIONNoOperation type (see below). Default: CREATE
OCI Functions
FunctionDescription
CREATEStart a new shopping session (default)
EDITResume and edit an existing cart. Send current items as NEW_ITEM-* parameters.
INSPECTView a cart in read-only mode
VALIDATEValidate items and return current catalog data/pricing. Send items as NEW_ITEM-MATNR[n] parameters.
BACKGROUND_SEARCHSearch the catalog by keyword. Use the SEARCHSTRING parameter. Returns up to 100 matching items.
Background Search Example
GET /api/oci? HOOK_URL=https://your-app.com/oci/receive& PASSWORD=your-shared-secret& CUSTOMER_ID=FH-12345& FUNCTION=BACKGROUND_SEARCH& SEARCHSTRING=memorial

Cart data is returned as OCI form fields (NEW_ITEM-*) auto-POSTed to your HOOK_URL via a self-submitting HTML form.


Operations

All protocols support three operation types for managing PunchOut sessions:

Create

Start a new shopping session with an empty cart. This is the default operation.

Edit

Resume a session with a pre-populated cart. The user can add, remove, or modify items before returning.

Inspect

View a cart in read-only mode. The user can browse but cannot modify items. A "Close" button replaces "Return Cart".

For Edit and Inspect operations, include the existing cart items in your setup request. In REST, use the existingCartItems array. In cXML, include ItemOut elements. In OCI, send NEW_ITEM-* parameters.


Cart Return

When the user completes their cart, data is returned to your application. The delivery method depends on your configured callback method and protocol.

JSON Format (REST API)

For redirect and HTTP POST callback methods, cart data is sent as JSON:

POST {your-return-url} Content-Type: application/json { "sessionToken": "abc123...", "customerId": "98765", "serviceCenterId": "42", "items": [ { "productId": "PROD-001", "sku": "SKU-12345", "name": "Tribute Memorial", "description": "Premium tribute memorial product", "quantity": 2, "unitPrice": 99.99, "currency": "USD", "unitOfMeasure": "EA", "imageUrl": "https://...", "attributes": { "color": "Blue", "size": "Large" } } ], "subtotal": 199.98, "currency": "USD" }

For redirect callbacks, the session token is appended as a query parameter: {returnUrl}?token={token}

PostMessage (iframe Mode)

When using iframe display mode with PostMessage callback, cart data is sent via window.postMessage to the parent window:

// Message posted to parent window { "type": "scx-cart-return", "data": { "sessionToken": "abc123...", "customerId": "98765", "serviceCenterId": "42", "items": [ ... ], "subtotal": 199.98, "currency": "USD" } }

Listen for the message in your application:

window.addEventListener("message", function(event) { if (event.data.type === "scx-cart-return") { const cart = event.data.data; console.log("Cart received:", cart.items); // Process the cart data } });
cXML PunchOutOrderMessage

For cXML integrations, cart data is returned as a PunchOutOrderMessage document, form-posted to your BrowserFormPost URL as the field cXML-urlencoded.

<cXML payloadID="..." timestamp="..." xml:lang="en-US"> <Header>...</Header> <Message> <PunchOutOrderMessage> <BuyerCookie>your-buyer-cookie</BuyerCookie> <PunchOutOrderMessageHeader operationAllowed="edit"> <Total> <Money currency="USD">199.98</Money> </Total> </PunchOutOrderMessageHeader> <ItemIn quantity="2"> <ItemID> <SupplierPartID>SKU-12345</SupplierPartID> <SupplierPartAuxiliaryID>token:PROD-001</SupplierPartAuxiliaryID> </ItemID> <ItemDetail> <UnitPrice> <Money currency="USD">99.99</Money> </UnitPrice> <Description xml:lang="en-US">Tribute Memorial</Description> <UnitOfMeasure>EA</UnitOfMeasure> <Classification domain="UNSPSC">39121031</Classification> </ItemDetail> </ItemIn> </PunchOutOrderMessage> </Message> </cXML>
UNSPSC Classification: SCX automatically maps product item types to UNSPSC codes. If no mapping is configured, the default code 99999999 is used. UOM (Unit of Measure) values are resolved using partner-specific mappings with a global fallback, defaulting to EA.
OCI Format

For OCI integrations, cart data is returned as standard OCI form fields auto-submitted to your HOOK_URL:

NEW_ITEM-DESCRIPTION[1]=Tribute Memorial NEW_ITEM-MATNR[1]=PROD-001 NEW_ITEM-QUANTITY[1]=2 NEW_ITEM-UNIT[1]=EA NEW_ITEM-PRICE[1]=99.99 NEW_ITEM-CURRENCY[1]=USD NEW_ITEM-VENDOR[1]=SCX NEW_ITEM-VENDORMAT[1]=SKU-12345 NEW_ITEM-MATGROUP[1]=39121031 // UNSPSC code NEW_ITEM-LONGTEXT_1:132[]=Product description

Webhooks

Receive real-time HTTP notifications when events occur in your PunchOut sessions. Configure webhooks in your partner portal.

Event Types
EventDescription
session.startedA new PunchOut session was created
session.completedA session was completed with cart data returned
session.expiredA session expired without completion
cart.updatedThe cart contents were modified during a session
Webhook Payload
POST {your-webhook-url} Content-Type: application/json X-SCX-Signature: sha256=abcdef123456... X-SCX-Event: session.completed X-SCX-Delivery-Id: d290f1ee-6c54-4b01-90e6... X-SCX-Timestamp: 1705312200 { "id": "d290f1ee-6c54-4b01-90e6...", "event": "session.completed", "timestamp": "2024-01-15T10:30:00Z", "data": { "sessionId": "...", "customerId": "98765", "serviceCenterId": "42", "items": [ { "sku": "SKU-12345", "name": "Tribute Memorial", "quantity": 2, "unitPrice": 99.99 } ], "subtotal": 199.98, "currency": "USD", "completedAt": "2024-01-15T10:35:00Z" } }
Verifying Signatures

Verify webhook authenticity by computing an HMAC-SHA256 signature of the raw request body using your webhook signing secret:

// Compute expected signature const crypto = require('crypto'); const expectedSig = 'sha256=' + crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex'); // Compare with X-SCX-Signature header if (expectedSig === req.headers['x-scx-signature']) { // Signature valid — process the webhook }
Retry Policy: Failed webhook deliveries are retried with exponential backoff (1 min, 5 min, 30 min). After the maximum number of retries (configurable per webhook), the delivery is marked as failed.

Error Handling

When a request fails, the response includes an error message and error code to help diagnose the issue.

REST API Error Response
{ "success": false, "error": "Customer ID not found in partner mappings", "errorCode": "INVALID_CUSTOMER" }
Error Codes
Error CodeDescription
AUTH_FAILEDInvalid API key, shared secret, or credentials
MISSING_CUSTOMER_IDThe customerId field was not provided
INVALID_CUSTOMERCustomer ID not found in partner mappings
INVALID_SERVICE_CENTERService center not found for the given customer
cXML Error Response
<cXML> <Response> <Status code="401" text="Unauthorized">Authentication failed</Status> </Response> </cXML>
Session Timeout

Sessions expire after 4 hours by default. Expired sessions cannot be completed and return an error. Use the SessionPingUrl feature to implement keep-alive pings—SCX will ping the provided URL every 60 seconds while the session is active.

Need Help?

Our team is here to help you integrate Solution Center into your application.

Contact Us
An unhandled error has occurred. Reload X

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.