Thin, dependency-free clients over the same REST API. Both add an Idempotency-Key to every write and retry 429, 5xx and network failures with the same key, so a retry can never apply twice. They are server-side libraries — an API key must never reach a browser.
Node.js / TypeScript
import { StickyTier, verifyWebhook } from "@stickytier/sdk";
const st = new StickyTier({ apiKey: process.env.STICKYTIER_KEY });
await st.events.send({ type: "order.paid", order_ref: "ORD-5001",
customer_ref: "CUST-1001", gross_cents: 249900, aggregate_version: 2 });
const { data: member } = await st.members.get("ref:CUST-1001");
// Checkout: hold points while the customer pays
const hold = await st.checkout.reserve(
{ member_id: "ref:CUST-1001", amount_cents: 50000, eligible_total_cents: 249900 }, "cart-88431");
await st.checkout.confirm(hold.data.id, "ORD-5001"); // or st.checkout.release(hold.data.id)Errors are StickyTierError with status, code (the error slug) and requestId.
PHP
$st = new \StickyTier\Client(getenv('STICKYTIER_KEY'));
$st->sendEvent(['type' => 'order.refunded', 'order_ref' => 'ORD-5001',
'refund_ref' => 'RF-220', 'refunded_cents' => 249900]);
$voucher = $st->findRedemptionByCode('RWD-7K2M-Q9XA'); // what a till doesSource for both lives in the sdk/ directory of the StickyTier repository until the packages are published.
Balance widget (browser)
Your server mints a member session token for the signed-in shopper — read-only, one member, 15 minutes — and the page hands it to the widget. The token opens only GET /v1/public/member, the one endpoint that allows cross-origin calls; it returns points, tier and referral code, never contact details.
// server
const { data } = await st.members.sessionToken("ref:CUST-1001");
<!-- page -->
<div data-stickytier-widget data-token="{{ data.token }}"
data-portal-url="https://rewards.yourstore.com" data-accent="#0f766e"></div>
<script src="https://stickytier.com/widget/stickytier-widget.js" async></script>Building your own UI or a mobile app? Call the endpoint directly with Authorization: Bearer smt_…. For a “My rewards” button that opens your hosted rewards page already signed in, use POST /v1/members/{id}/portal-links (single use, 5 minutes).
WooCommerce
StickyTier for WooCommerce is the reference integration: orders, cancellations and refunds become events (queued through Action Scheduler, retried without ever double-crediting), WordPress user ids become external_ref, and the balance widget appears in My Account and via the [stickytier_balance] shortcode. Install it, paste a key with the ingest, read and act scopes under WooCommerce → StickyTier, and start with a test key.
Status
Live API, event-processing and webhook status: stickytier.com/status.