@khalidadil/surecart-commerce (0.1.0)
Installation
@khalidadil:registry=npm install @khalidadil/surecart-commerce@0.1.0"@khalidadil/surecart-commerce": "0.1.0"About this package
@khalidadil/surecart-commerce
Headless SureCart commerce toolkit for Node: typed REST client, the checkout
state machine with server-side safety rails, webhook verification/dispatch, an
Express adapter, and a React storefront kit (Stripe Connect specifics included).
Extracted from the verified surecart-poc; every hard-won API quirk is encoded
in code, not lore.
@khalidadil/surecart-commerce(core) — zero-dependency:SureCartClient(Bearer auth,expand[]=params, retry/backoff),SureCartResources,CheckoutService, money helpers (minor-unit exponents — no naive/100), webhook verify + dispatcher.…/express—createSureCartRouter(service)+createSureCartWebhookRoute(dispatcher)(raw-body mount, signatures verify on the actual bytes). Peer: express.…/react—createStorefrontApi,useSureCartCheckout(draft resume, debounced sync),StripePaymentForm(Stripe Connect init:loadStripe(pk, { stripeAccount })),resumeCheckoutFromUrl(3DS/redirect returns). Peers: react, @stripe/*.…/ops—ensureProduct/ensureAdHocPrice(idempotent seeding),runTaxSurvey(self-cleaning),evaluateNexus+ 2026 thresholds data.
Install
Hosted on the private Gitea npm registry:
npm config set @khalidadil:registry https://git.kadil.dev/api/packages/khalidadil/npm/
npm install @khalidadil/surecart-commerce
Server quickstart
import express from 'express';
import { SureCartClient, SureCartResources, CheckoutService } from '@khalidadil/surecart-commerce';
import { createSureCartRouter } from '@khalidadil/surecart-commerce/express';
const service = new CheckoutService(
new SureCartResources(new SureCartClient({ apiToken: process.env.SURECART_API_TOKEN! })),
{ mode: 'test' }, // 'live' only when you mean it — drives live_mode AND processor gating
);
const app = express();
app.use('/api/surecart', createSureCartRouter(service));
The secret token stays server-side, live_mode is forced from mode (clients
can never set it), update fields are whitelisted, and validateLineItems lets
the host enforce price allowlists.
Storefront quickstart
import { createStorefrontApi, useSureCartCheckout, StripePaymentForm, resumeCheckoutFromUrl }
from '@khalidadil/surecart-commerce/react';
const api = createStorefrontApi({ baseUrl: '/api/surecart' });
// on app load: resumeCheckoutFromUrl(api) — mandatory for 3DS / redirect returns
// in checkout: const { checkout, setContact, finalize, confirmPaid } = useSureCartCheckout(lines, { api });
A complete host lives in examples/express-react-store
— it imports only the package (enforced by a purity test) and has been driven
end-to-end in a real browser: mock-processor and Stripe 4242 payments, live
two-stage tax (estimated → calculated), and redirect resume.
The five API facts that bite (from the POC, verified live)
- Checkout verbs are
PATCH /checkouts/:id/<verb>/— trailing slash, and finalize'sprocessor_type+expand[]=payment_intentgo in the query string; without the expand there is noclient_secretto mount Stripe with. - There is no "confirm" endpoint —
GET /checkouts/:id?refresh_status=truesyncs processor state and flips the checkout topaid. - Tax is two-stage: address PATCH →
estimated(state-level rate); finalize →calculated(street-level). Show "estimated" in the UI or the total "changes". ad_hoc_amounton a line item is silently ignored unless the price was created withad_hoc: true— andshipping_amountis not writable at all. External shipping/discount amounts ride ad-hoc lines (CheckoutService.setExternalShipping,ops.ensureAdHocPrice).- The API forces the account currency onto prices and checkouts — one store = one currency. Multi-currency = one store per currency.
More: docs/probe-findings.md · docs/overnight-brief.md · the full lifecycle write-up lives in the Obsidian SureCart POC reference.
Development
npm install
npm run build # tsc → dist/
npm test # unit (mocked fetch) — includes the purity gate
npm run test:live # TEST-MODE smoke vs the real API; needs SURECART_API_TOKEN in .env
Live tests force live_mode: false, reuse the tagged POC product, and clean up
after themselves (cancel checkouts, archive probe prices).
Dependencies
Development Dependencies
| ID | Version |
|---|---|
| @stripe/react-stripe-js | ^3.1.1 |
| @stripe/stripe-js | ^5.5.0 |
| @types/express | ^4.17.21 |
| @types/react | ^18.3.18 |
| express | ^4.21.2 |
| react | ^18.3.1 |
| react-dom | ^18.3.1 |
| tsx | ^4.19.2 |
| typescript | ^5.7.3 |
Peer Dependencies
| ID | Version |
|---|---|
| @stripe/react-stripe-js | >=2.0.0 |
| @stripe/stripe-js | >=2.0.0 |
| express | ^4.18.0 || ^5.0.0 |
| react | >=18 |