Skip to Content
SellubSDKssellub-pricing

@duabalabs/sellub-pricing

Pure-TypeScript pricing engine behind Sellub’s plans, commission and fee math. Same code path runs in the server, the dashboard and 3rd-party integrations so quotes match invoices.

npm

Install

pnpm add @duabalabs/sellub-pricing

Modules

ModuleExports
plansSellerPlan, SellerPlanVariant, PLAN_CATALOG, ALL_PLANS, getMonthlyPricePesewas, getDirectCommissionPercent
commissionresolveCommissionRate({ plan, variant?, source, sellerOverridePercent? })
attributionAttributionSource, ALL_ATTRIBUTION_SOURCES, isMarketplaceAttributed, parseAttributionSource
feescalculateOrderFees(input), applyRefund
addonsADDONS, ALL_ADDONS, calculatePerformanceAdFee
currencyformatMinor, formatPercent, pesewasToGhs, ghsToPesewas, DEFAULT_CURRENCY
educationEDUCATION, ALL_EDUCATION — seller-facing explanations of plans and fees

Everything is tree-shakeable — import only what you need. All amounts are integers in pesewas (GHS × 100).

Plan catalog

import { PLAN_CATALOG, SellerPlan } from "@duabalabs/sellub-pricing"; PLAN_CATALOG[SellerPlan.MARKETPLACE]; //=> { plan: 'MARKETPLACE', label: 'Sell on Sellub', isFree: true, directCommissionPercent: 5, … }
PlanVariants (monthly)Direct rateMarketplace-attributed rate
MARKETPLACEfree5%—
CUSTOM_DOMAINStarter GHS 250 · Pro GHS 6003% · 2%4.5%
COMMERCE_APIDeveloper GHS 500 · Growth GHS 1,500 · Enterprise (contact sales)1.5% · 1% · 1%3.5%

Resolve effective commission

import { resolveCommissionRate, SellerPlan, SellerPlanVariant, AttributionSource, } from "@duabalabs/sellub-pricing"; resolveCommissionRate({ plan: SellerPlan.CUSTOM_DOMAIN, variant: SellerPlanVariant.CUSTOM_DOMAIN_PRO, source: AttributionSource.SELLER_DIRECT_DOMAIN, }); //=> { ratePercent: 2, basis: "direct", overrideApplied: false } resolveCommissionRate({ plan: SellerPlan.MARKETPLACE, source: AttributionSource.MARKETPLACE_SEARCH, sellerOverridePercent: 6, }); //=> { ratePercent: 6, basis: "override", overrideApplied: true }

Quote order fees

import { calculateOrderFees, SellerPlan, SellerPlanVariant, AttributionSource } from "@duabalabs/sellub-pricing"; const quote = calculateOrderFees({ grossAmountPesewas: 50_000, // GHS 500 plan: SellerPlan.CUSTOM_DOMAIN, variant: SellerPlanVariant.CUSTOM_DOMAIN_STARTER, source: AttributionSource.SELLER_DIRECT_DOMAIN, }); quote.commissionRatePercent; // 3 quote.commissionAmountPesewas; // 1_500 quote.sellerPayoutPesewas; // 48_500

sellerPayoutPesewas is gross − commission — exactly what Sellub’s Paystack split pays the seller. paymentProcessingFeePesewas is optional: Sellub pays Paystack’s fee, so when you pass it, it comes out of platformRevenuePesewas (commission − fee, negative when the fee is the larger), never out of the seller’s payout. (Before 1.1.0 it was subtracted from the payout.)

Attribution-aware billing

On the paid plans, a sale that came through the Sellub marketplace is billed at the plan’s marketplace rate; a sale on the seller’s own domain, app or link at the direct rate. isMarketplaceAttributed tells the two apart:

import { isMarketplaceAttributed, parseAttributionSource } from "@duabalabs/sellub-pricing"; isMarketplaceAttributed(AttributionSource.MARKETPLACE_HOMEPAGE); // true parseAttributionSource("seller_direct_domain"); // AttributionSource.SELLER_DIRECT_DOMAIN parseAttributionSource("nonsense"); // null

Sources: marketplace_search, marketplace_category, marketplace_homepage, marketplace_recommendation (marketplace rate) and seller_direct_storefront, seller_direct_domain, seller_direct_link, external_api, external_app, ad_campaign, social_campaign (direct rate).

Format minor units

import { formatMinor, formatPercent } from "@duabalabs/sellub-pricing"; formatMinor(5_000); // "GHS 50.00" formatMinor(5_000, { compact: true }); // "GHS 50" formatPercent(2.5); // "2.5%"

Why this lives in npm (not the server)

The same math has three callers:

  1. The Sellub Vendure server (sellub-pricing-plugin) — persists the breakdown.
  2. The Sellub dashboard — shows plans, prices and rates.
  3. Your integration — quotes “you’ll be charged X commission” in your UI.

By shipping it on npm, all three stay in lock-step. Bumping this package is the single source of truth for a rate change.

  • sellub-pricing-plugin — the server plugin that consumes this package and persists the resulting OrderFeeBreakdown.
  • sellub-types — shared types for webhooks and API results.
Last updated on