@duabalabs/sellub-client
Typed, framework-agnostic client for the Sellub commerce platform. Works in Node, browsers, edge runtimes and React Native.
Install
npm install @duabalabs/sellub-client
# or
pnpm add @duabalabs/sellub-clientSurface (0.8.0)
| Namespace | Methods |
|---|---|
externalPayments | initialize(input), verify(reference) |
subscriptions | start(input), status(subscriptionCode), byReference(reference), cancel(input), createPlan(input), listPlans(accountId) |
invoices | create(input), get(requestCode) |
shop | Shop API: getProducts, getCatalog, getProduct, getActiveOrder, addItemToOrder, adjustOrderLine, removeOrderLine, setCustomerForOrder, shipping/billing address, getEligibleShippingMethods, setOrderShippingMethod, transitionOrderToState, addPaymentToOrder, getOrderByCode, and raw query |
admin | Only when adminToken is passed (server-side): listChannels, listOrders, getOrder, cancelOrder, refundOrder, listSubscriptions |
createShopClient and createAdminClient are also exported on their own.
Authentication
Payment, subscription and invoice requests are sent with the
X-Sellub-Publishable-Key header. Create your key in the dashboard
(Studio → Integrate); it’s bound to your shop (its accountId, acct_…)
and pinned to your allowed origins.
import { createSellubClient } from "@duabalabs/sellub-client";
const sellub = createSellubClient({
baseUrl: "https://api.sellub.com",
publishableKey: process.env.SELLUB_PUBLISHABLE_KEY!,
});Take a one-off payment (donations, simple checkout)
const init = await sellub.externalPayments.initialize({
accountId: "acct_…",
email: "donor@example.com",
amount: 5000, // GHS 50.00 in pesewas
description: "May fundraiser",
callbackUrl: "https://acme-causes.org/donate/thanks",
});
if (init.success && init.authorizationUrl) {
window.location.href = init.authorizationUrl;
}On the callback page:
const result = await sellub.externalPayments.verify(reference);
if (result.success && result.status === "success") {
// mark donation as fulfilled
}Start a subscription
const start = await sellub.subscriptions.start({
accountId: "acct_…",
email: "user@example.com",
plan: { name: "Pro Monthly", amount: 9900, interval: "monthly" },
callbackUrl: "https://app.duabaconnect.com/billing",
});
window.location.href = start.authorizationUrl!;const s = await sellub.subscriptions.status("SUB_xxx");
if (s.success && s.status === "active") {
// grant access
}Create a hosted invoice
const inv = await sellub.invoices.create({
accountId: "acct_…",
email: "ops@buyer.com",
customerName: "Buyer Ltd.",
lineItems: [
{ name: "Migration setup", amount: 250000 },
{ name: "Training day", amount: 150000, quantity: 2 },
],
dueDate: "2026-06-30",
sendNotification: true,
});
console.log(inv.hostedUrl); // share with the customerErrors
Every method returns an object with success: boolean. On failure, error
contains a human-readable message; check it before acting on data.
const r = await sellub.subscriptions.start({...});
if (!r.success) {
console.error("Sellub error:", r.error);
return;
}Supplying your own fetch
Useful in older Node, custom edge runtimes or when injecting a tracing wrapper:
import undici from "undici";
const sellub = createSellubClient({
publishableKey: "pk_live_…",
fetch: undici.fetch,
});Server-side use
sellub-client is safe to call from a server. For server-only operations
(cancellations, refunds) use a secret key from the dashboard. Don’t ship
secret keys to a browser bundle.
Related
sellub-react—useSubscriptionhook over this client.sellub-webhooks— verify Sellub webhook deliveries.sellub-pricing— quote fees before you callinitialize.