Integration guide
Content Pay credits creators only for purchases your website reports. A redirect link on its own cannot see what happens at your checkout — your server must send a signed event for each qualifying order.
1. Register your website
In your business dashboard open My Websites → Register a website, confirm ownership, then run the initial compatibility checks with a product URL.
2. Configure the integration
An administrator issues test credentials first: a key ID and a signing secret. Reveal the secret from your website page and store it as a server-side environment variable. Never place it in browser code. Once testing passes, live credentials are issued and tracking is activated.
3. Keep the referral ID
When a shopper clicks a creator's link, Content Pay redirects them to your product page with a cp_ref query parameter:
https://shop.example.com/products/product-one?cp_ref=7b1e0c3a-5d2f-4f8e-9a51-2a0b7c4d9e10Save cp_ref (for example in a first-party cookie or the cart/session) and attach it to the order. If several referral IDs arrive, keep the most recent one — Content Pay applies last-click attribution within each product's attribution window.
4. Send a purchase event
After the order is confirmed (payment captured), POST a JSON event from your server:
POST /api/public/v1/events
Content-Type: application/json
X-ContentPay-Key: <key ID>
X-ContentPay-Timestamp: 1767225600
X-ContentPay-Signature: <hex HMAC-SHA256>
{
"event_id": "evt_100045_paid",
"website_id": "<your website ID>",
"external_order_id": "100045",
"referral_id": "7b1e0c3a-5d2f-4f8e-9a51-2a0b7c4d9e10",
"order_status": "completed",
"currency": "USD",
"order_value": 89.00,
"purchased_at": "2026-10-24T10:15:00Z",
"line_items": [
{ "product_id": "<Content Pay product ID>", "amount": 89.00, "quantity": 1 }
]
}Send events to your Content Pay site address, for example https://your-content-pay-domain/api/public/v1/events.
Required fields
event_id— unique per event. Re-sending the same ID is safely ignored.website_id— must match the credentials used.external_order_id— your order number. One commission per order and product, ever.referral_id— the savedcp_refvalue (omit if none).order_status—completed,paid,pending,failed,refunded,cancelledorchargeback.currency(3-letter code) andorder_value— the commission-eligible value, excluding tax and shipping if your terms say so.purchased_at— ISO 8601 time. Optional; defaults to the time received.line_items— optional. Use Content Pay product IDs for reliable multi-product attribution.
Commissions are always calculated by Content Pay using the product's configured rules — never from values in the request.
Authentication & signatures
Compute HMAC-SHA256(signing_secret, timestamp + "." + raw_body) as lowercase hex. The timestamp is Unix seconds and must be within 5 minutes of our clock.
// Node.js
import crypto from "node:crypto";
const body = JSON.stringify(event);
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac("sha256", process.env.CONTENT_PAY_SECRET)
.update(`${ts}.${body}`).digest("hex");
await fetch(url, { method: "POST", body, headers: {
"content-type": "application/json",
"x-contentpay-key": process.env.CONTENT_PAY_KEY_ID,
"x-contentpay-timestamp": ts,
"x-contentpay-signature": sig,
}});# PHP
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, getenv('CONTENT_PAY_SECRET'));Refunds & cancellations
Send a new event (new event_id, same external_order_id) with order_status set to refunded, cancelled or chargeback. The related commission is reversed according to the product's refund rule, and the change is kept in a history. Failed and pending orders never create commissions.
Testing with sandbox orders
Use your test credentials. Test events never appear in live totals. To complete the compatibility checklist, send:
- A
completedtest order with areferral_idfrom a real click, or a sandbox ID starting withcp_test_. - The exact same event again (same
event_id) — it must come back as a duplicate. - A
cancelledtest order — it must not create a commission.
Then press Request approval on your website page.
Responses
200 { "ok": true, "event_id": "…", "event_type": "purchase", "attribution": "attributed", "commissions_created": 1, "commissions_reversed": 0, "mode": "test" }
200 { "ok": true, "duplicate": true, "mode": "live" }Common errors
401 missing_auth_headers— one of the three headers is missing.401 invalid_credentials— unknown or revoked key ID.401 invalid_signature— wrong secret, body changed after signing, or clock skew over 5 minutes.422 validation_failed— seedetailsfor the field.403 website_mismatch—website_iddoesn't match the key.409 tracking_not_active— live events are refused until an administrator activates tracking.429 rate_limited— slow down and retry with the sameevent_id.
Every request appears under Integration health on your website page.