Partner Integrations

Shoppex Partner API

The Shoppex Partner API enables approved external partners to securely retrieve the available product catalog and create orders for existing Shoppex customers through server-to-server REST integrations. Requests are authenticated with API key plus HMAC signature headers.

HMAC authentication required. Every request must include X-Shoppex-Key, X-Shoppex-Timestamp, X-Shoppex-Nonce, and X-Shoppex-Signature. JSON requests must also include Content-Type: application/json.
The signature is calculated from METHOD, ROUTE, TIMESTAMP, NONCE, and the SHA256 hash of the raw body. ROUTE is the REST route without the domain, for example /shoppex-integrations/v1/products.

GET /wp-json/shoppex-integrations/v1/products

List products for external partners. If the authenticated partner has backorder enabled, the response includes all partner-visible products, including Supplier-origin products. If backorder is disabled, the response is limited to products with Shoppex warehouse stock: origin SC, or origin * when _stock_sc is greater than zero and WooCommerce stock status is instock. For origin *, the purchasable stock limit is _stock_sc.

GET
Endpoint path /wp-json/shoppex-integrations/v1/products
Full URL https://shop.shoppexcorp.com/wp-json/shoppex-integrations/v1/products

Required headers

  • X-Shoppex-Key: pk_demo_partner_key
  • X-Shoppex-Timestamp: 1775726400
  • X-Shoppex-Nonce: req-demo-001
  • X-Shoppex-Signature: hmac_sha256_signature_placeholder

Request attributes

Required attributes

  • None This endpoint does not require request body attributes.

Optional attributes

  • None No optional request body attributes are currently supported for this endpoint.

Request example

curl -X GET "https://shop.shoppexcorp.com/wp-json/shoppex-integrations/v1/products" \
  -H "X-Shoppex-Key: pk_demo_partner_key" \
  -H "X-Shoppex-Timestamp: 1775726400" \
  -H "X-Shoppex-Nonce: req-demo-001" \
  -H "X-Shoppex-Signature: hmac_sha256_signature_placeholder"
Implementation snippets
JavaScript Node.js
import crypto from 'node:crypto';

const baseUrl = 'https://your-shoppex-domain.com';
const partnerKey = 'YOUR_PARTNER_KEY';
const partnerSecret = 'YOUR_PARTNER_SECRET';
const method = 'GET';
const route = '/shoppex-integrations/v1/products';
const body = '';
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const message = [method, route, timestamp, nonce, bodyHash].join('\n');
const signature = crypto
  .createHmac('sha256', partnerSecret)
  .update(message)
  .digest('hex');

const response = await fetch(`${baseUrl}/wp-json/shoppex-integrations/v1/products`, {
  method,
  headers: {
    'Content-Type': 'application/json',
    'X-Shoppex-Key': partnerKey,
    'X-Shoppex-Timestamp': timestamp,
    'X-Shoppex-Nonce': nonce,
    'X-Shoppex-Signature': signature,
  },
});

const data = await response.json();
console.log(data);
PHP cURL
<?php
$baseUrl = 'https://your-shoppex-domain.com';
$partnerKey = 'YOUR_PARTNER_KEY';
$partnerSecret = 'YOUR_PARTNER_SECRET';
$method = 'GET';
$route = '/shoppex-integrations/v1/products';
$body = '';
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$bodyHash = hash('sha256', $body);
$message = implode("\n", [$method, $route, $timestamp, $nonce, $bodyHash]);
$signature = hash_hmac('sha256', $message, $partnerSecret);

$ch = curl_init($baseUrl . '/wp-json/shoppex-integrations/v1/products');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => $method,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Shoppex-Key: ' . $partnerKey,
        'X-Shoppex-Timestamp: ' . $timestamp,
        'X-Shoppex-Nonce: ' . $nonce,
        'X-Shoppex-Signature: ' . $signature,
    ],
]);

if ($body !== '') {
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}

$response = curl_exec($ch);
curl_close($ch);

echo $response;
Python requests
import hashlib
import hmac
import json
import time
import uuid
import requests

base_url = 'https://your-shoppex-domain.com'
partner_key = 'YOUR_PARTNER_KEY'
partner_secret = 'YOUR_PARTNER_SECRET'
method = 'GET'
route = '/shoppex-integrations/v1/products'
body = ''
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4())
body_hash = hashlib.sha256(body.encode()).hexdigest()
message = '\n'.join([method, route, timestamp, nonce, body_hash])
signature = hmac.new(
    partner_secret.encode(),
    message.encode(),
    hashlib.sha256
).hexdigest()

response = requests.request(
    method,
    base_url + '/wp-json/shoppex-integrations/v1/products',
    headers={
        'Content-Type': 'application/json',
        'X-Shoppex-Key': partner_key,
        'X-Shoppex-Timestamp': timestamp,
        'X-Shoppex-Nonce': nonce,
        'X-Shoppex-Signature': signature,
    },
    timeout=30,
)

print(response.status_code)
print(response.json())

Successful response example

[
    {
        "id": 12345,
        "name": "Demo SC Product",
        "price": "19.99",
        "stock_quantity": 24,
        "stock_sc": 24,
        "origen": "SC",
        "upc": "000000000001"
    },
    {
        "id": 67890,
        "name": "Demo Dual-Origin Product",
        "price": "49.99",
        "stock_quantity": 8,
        "stock_sc": 8,
        "origen": "*",
        "upc": "000000000002"
    }
]

Error response example

{
    "code": "partner_auth_invalid_signature",
    "message": "The HMAC signature does not match.",
    "data": {
        "status": 401
    }
}

Possible error codes

Code Reason
401 Missing HMAC headers, invalid timestamp, expired timestamp, reused nonce, invalid key, or incorrect signature.
403 The partner does not have the products.read permission.

POST /wp-json/shoppex-integrations/v1/create-order

Create order through the Shoppex customer associated with the authenticated partner. The request body sends the partner order ID and items only; customer email, billing, and shipping are loaded from the WordPress customer configured for that partner. The order amount must satisfy the partner business rule configured in Shoppex. When backorder is disabled, Supplier-origin products are rejected, and origin * products can only be purchased when WooCommerce stock status is instock and up to their _stock_sc quantity. Vendor assignment preserves any seller already stored on the customer; if no local assignment exists, Shoppex checks Google Sheets/Make by customer email and only then uses internal rotation. Tony Hurtado and Adrian Borgo are excluded from new automatic rotation assignments. After the WooCommerce order is created, the SellerCloud send is queued in the background and does not revalidate local stock or SellerCloud availability.

POST
Endpoint path /wp-json/shoppex-integrations/v1/create-order
Full URL https://shop.shoppexcorp.com/wp-json/shoppex-integrations/v1/create-order

Required headers

  • Content-Type: application/json
  • X-Shoppex-Key: pk_demo_partner_key
  • X-Shoppex-Timestamp: 1775726400
  • X-Shoppex-Nonce: req-demo-001
  • X-Shoppex-Signature: hmac_sha256_signature_placeholder

Request attributes

Required attributes

  • items Array of products to include in the order. It must contain at least one item.
  • items[].product_id WooCommerce product ID. The product must exist.
  • items[].quantity Quantity to purchase. It must be greater than zero.
  • id_order_partner Order ID from the partner external system. It is saved in WooCommerce and sent to SellerCloud in each item Notes field.

Optional attributes

  • comments Optional partner comment or note. If provided, it is added after the partner order ID note.
  • tax_id Optional fiscal metadata. It is not required to create the order.
  • resale_tax Optional fiscal metadata. It is not required to create the order.

Request example

curl -X POST "https://shop.shoppexcorp.com/wp-json/shoppex-integrations/v1/create-order" \
  -H "Content-Type: application/json" \
  -H "X-Shoppex-Key: pk_demo_partner_key" \
  -H "X-Shoppex-Timestamp: 1775726400" \
  -H "X-Shoppex-Nonce: req-demo-001" \
  -H "X-Shoppex-Signature: hmac_sha256_signature_placeholder" \
  -d '{
    "items": [
        {
            "product_id": 12345,
            "quantity": 2
        }
    ],
    "id_order_partner": "PARTNER-ORDER-12345",
    "comments": "Demo order created by an external partner integration."
}'
Implementation snippets
JavaScript Node.js
import crypto from 'node:crypto';

const baseUrl = 'https://your-shoppex-domain.com';
const partnerKey = 'YOUR_PARTNER_KEY';
const partnerSecret = 'YOUR_PARTNER_SECRET';
const method = 'POST';
const route = '/shoppex-integrations/v1/create-order';
const body = JSON.stringify({
    "items": [
        {
            "product_id": 12345,
            "quantity": 2
        }
    ],
    "id_order_partner": "PARTNER-ORDER-12345",
    "comments": "Demo order created by an external partner integration."
});
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const message = [method, route, timestamp, nonce, bodyHash].join('\n');
const signature = crypto
  .createHmac('sha256', partnerSecret)
  .update(message)
  .digest('hex');

const response = await fetch(`${baseUrl}/wp-json/shoppex-integrations/v1/create-order`, {
  method,
  headers: {
    'Content-Type': 'application/json',
    'X-Shoppex-Key': partnerKey,
    'X-Shoppex-Timestamp': timestamp,
    'X-Shoppex-Nonce': nonce,
    'X-Shoppex-Signature': signature,
  },
  body,
});

const data = await response.json();
console.log(data);
PHP cURL
<?php
$baseUrl = 'https://your-shoppex-domain.com';
$partnerKey = 'YOUR_PARTNER_KEY';
$partnerSecret = 'YOUR_PARTNER_SECRET';
$method = 'POST';
$route = '/shoppex-integrations/v1/create-order';
$body = json_encode(array (
  'items' => 
  array (
    0 => 
    array (
      'product_id' => 12345,
      'quantity' => 2,
    ),
  ),
  'id_order_partner' => 'PARTNER-ORDER-12345',
  'comments' => 'Demo order created by an external partner integration.',
), JSON_UNESCAPED_SLASHES);
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$bodyHash = hash('sha256', $body);
$message = implode("\n", [$method, $route, $timestamp, $nonce, $bodyHash]);
$signature = hash_hmac('sha256', $message, $partnerSecret);

$ch = curl_init($baseUrl . '/wp-json/shoppex-integrations/v1/create-order');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => $method,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Shoppex-Key: ' . $partnerKey,
        'X-Shoppex-Timestamp: ' . $timestamp,
        'X-Shoppex-Nonce: ' . $nonce,
        'X-Shoppex-Signature: ' . $signature,
    ],
]);

if ($body !== '') {
    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}

$response = curl_exec($ch);
curl_close($ch);

echo $response;
Python requests
import hashlib
import hmac
import json
import time
import uuid
import requests

base_url = 'https://your-shoppex-domain.com'
partner_key = 'YOUR_PARTNER_KEY'
partner_secret = 'YOUR_PARTNER_SECRET'
method = 'POST'
route = '/shoppex-integrations/v1/create-order'
body = json.dumps({
    "items": [
        {
            "product_id": 12345,
            "quantity": 2
        }
    ],
    "id_order_partner": "PARTNER-ORDER-12345",
    "comments": "Demo order created by an external partner integration."
}, separators=(",", ":"))
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4())
body_hash = hashlib.sha256(body.encode()).hexdigest()
message = '\n'.join([method, route, timestamp, nonce, body_hash])
signature = hmac.new(
    partner_secret.encode(),
    message.encode(),
    hashlib.sha256
).hexdigest()

response = requests.request(
    method,
    base_url + '/wp-json/shoppex-integrations/v1/create-order',
    headers={
        'Content-Type': 'application/json',
        'X-Shoppex-Key': partner_key,
        'X-Shoppex-Timestamp': timestamp,
        'X-Shoppex-Nonce': nonce,
        'X-Shoppex-Signature': signature,
    }, data=body,
    timeout=30,
)

print(response.status_code)
print(response.json())

Successful response example

{
    "success": true,
    "order_id": 98765,
    "order_key": "wc_order_demo_key",
    "order_detail_url": "https://shop.shoppexcorp.com/order-detail/?order_id=98765&key=wc_order_demo_key",
    "source": "partner_integration",
    "partner_order_id": "PARTNER-ORDER-12345"
}

Error response example

{
    "success": false,
    "code": "partner_customer_billing_incomplete",
    "message": "The customer user configured for this partner does not have complete billing information."
}

Possible error codes

Code Reason
400 Invalid payload, missing items, missing id_order_partner, incomplete customer billing/shipping data, or invalid product quantity.
401 Missing HMAC headers, invalid timestamp, expired timestamp, reused nonce, invalid key, or incorrect signature.
403 The partner does not have the orders.create permission, does not have an associated WordPress customer, the associated customer is inactive, the order amount does not satisfy the partner business rule, or the order contains backorder products while backorder is disabled.
404 The configured customer user or one of the requested products was not found.
409 The same id_order_partner was already used by this partner.