SellubDevelopersCommerce API (Tier-3)

Commerce API (Tier-3)

The Commerce API plan unlocks a programmatic surface for partners that want to embed Sellub checkout, fulfilment and payouts directly into their own apps, websites or back-office systems.

It is implemented by the sellub-commerce-api-plugin in sellub-server and sits on top of the standard Vendure Shop API. Sandbox and live keys, webhook delivery, plan-subscription lifecycle and per-order attribution are all owned by this plugin.

Commerce API access requires a Tier-3 plan (COMMERCE_API). Set the seller’s plan in the dashboard (Sellers → seller → Plan & pricing) before issuing keys.

API key issuance

Two key environments are issued per seller:

EnvironmentScopeChannel
sandboxTest orders, test webhooksPer-seller sandbox channel
liveReal orders, real webhooks, payoutsSeller’s live storefront channel

Keys are 32-byte URL-safe random tokens prefixed with the environment, e.g. sk_live_…, sk_test_…. Only the hash is persisted; the plaintext is shown once at creation.

Admin API

mutation IssueCommerceApiKey($sellerId: ID!, $environment: SellubKeyEnvironment!) {
  sellubIssueApiKey(sellerId: $sellerId, environment: $environment) {
    id
    environment
    plaintextKey   # shown once
    last4
    createdAt
  }
}
 
mutation RevokeCommerceApiKey($keyId: ID!) {
  sellubRevokeApiKey(keyId: $keyId) {
    id
    revokedAt
  }
}

Clients authenticate with:

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The plugin resolves the seller, plan and channel from the key on every request and rejects sandbox keys when hitting live endpoints (and vice-versa).

Plan subscriptions

A SellubPlanSubscription row tracks the active plan for a seller. The lifecycle matches the rest of Sellub’s billing model:

active → grace_period → downgraded
                      → cancelled
  • active — paid, all entitlements honoured.
  • grace_period — auto-renew failed once; entitlements still honoured for up to 7 days.
  • downgraded — grace expired; seller falls back to the marketplace plan automatically.
  • cancelled — explicit cancellation by admin or self-serve.

Admin queries

query SellerActivePlanSubscription($sellerId: ID!) {
  sellubPlanSubscriptions(sellerId: $sellerId) {
    id plan variant status startDate expiryDate
    autoRenew priceAtPurchase renewalCount failedRenewalAttempts
  }
}

Webhook signing

Every webhook delivered by sellub-commerce-api-plugin carries an HMAC-SHA256 signature so partners can verify authenticity without trusting transport security alone.

Headers

Sellub-Event:     order.placed
Sellub-Event-Id:  evt_01HX9F…
Sellub-Timestamp: 1714050000
Sellub-Signature: t=1714050000,v1=4f4d…

Signed payload

${eventId}.${timestamp}.${rawJsonBody}

The v1 value is the lowercase hex of HMAC_SHA256(secret, signedPayload). secret is the seller’s webhook signing secret, rotated independently of API keys.

Verification (Node)

import crypto from "node:crypto";
 
function verify(req, secret) {
  const sig = req.headers["sellub-signature"];
  const ts  = req.headers["sellub-timestamp"];
  const id  = req.headers["sellub-event-id"];
  const v1  = sig.split(",").find(p => p.startsWith("v1=")).slice(3);
 
  // 5-minute tolerance to defeat replay attacks
  if (Math.abs(Date.now()/1000 - Number(ts)) > 300) throw new Error("stale");
 
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${id}.${ts}.${req.rawBody}`)
    .digest("hex");
 
  if (!crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) {
    throw new Error("bad signature");
  }
}

Delivery semantics

  • At-least-once — partners must dedupe on Sellub-Event-Id.
  • Retention — every delivery (success and failure) is retained for 90 days.
  • Backoff schedule30s, 2m, 10m, 1h, 6h, 24h then mark dead.
  • Manual replay — admin can replay any event from the dashboard.

Rate limits

PlanRequests / minWebhook concurrency
Developer1205
Growth60025
EnterpriseCustomCustom

Error envelope

All Commerce API errors use Vendure’s standard ErrorResult union plus plugin-specific result types (SellubApiKeyInvalidError, SellubPlanInsufficientError, SellubKeyEnvironmentMismatchError).

See also