khalidadil
  • Joined on 2025-08-25

@khalidadil/surecart-commerce (0.1.0)

Published 2026-09-01 09:48:38 +00:00 by khalidadil

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)

  1. Checkout verbs are PATCH /checkouts/:id/<verb>/ — trailing slash, and finalize's processor_type + expand[]=payment_intent go in the query string; without the expand there is no client_secret to mount Stripe with.
  2. There is no "confirm" endpoint — GET /checkouts/:id?refresh_status=true syncs processor state and flips the checkout to paid.
  3. Tax is two-stage: address PATCH → estimated (state-level rate); finalize → calculated (street-level). Show "estimated" in the UI or the total "changes".
  4. ad_hoc_amount on a line item is silently ignored unless the price was created with ad_hoc: true — and shipping_amount is not writable at all. External shipping/discount amounts ride ad-hoc lines (CheckoutService.setExternalShipping, ops.ensureAdHocPrice).
  5. 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
Details
npm
2026-09-01 09:48:38 +00:00
0
49 KiB
Assets (1)
Versions (2) View all
0.2.0 2026-09-02
0.1.0 2026-09-01