Payments
NanoSite ships real payments. Each store brings its own gateway account, configures it per store, and shoppers pay through the provider's own secure flow. Secrets are encrypted at rest and never sent to the browser.
Supported providers
| Provider | ID | Status | Flow |
|---|---|---|---|
| Manual / cash | manual |
Built-in | Authorizes and captures instantly; no configuration. Great for cash-on-delivery or testing, and always available as a fallback. |
| Stripe | stripe |
Supported | One-time payments via a PaymentIntent + client secret (Stripe Elements); subscriptions via hosted Checkout (mode=subscription) with a redirect. |
| PayPal | paypal |
Supported | Approval-based Orders v2: create order → buyer approves → server captures the payment. |
| PayFast | payfast |
Supported | Redirect to PayFast's hosted page; the ITN (Instant Transaction Notification) webhook finalizes the order. |
All four providers are implemented. A few provider-specific notes:
- PayPal requires an explicit capture step after the buyer approves (see below).
- PayFast refunds are not available through the API — issue them from the PayFast dashboard.
- Subscriptions are Stripe-only — see Products & subscriptions.
Per-store configuration
Payment providers are configured per store from the store admin. Each provider exposes a small set of config fields (secrets are marked as such and encrypted; public fields are exposed to the storefront):
- Stripe —
secretKey(secret),publishableKey(public),webhookSecret(secret; required for subscriptions). - PayPal —
clientId(public),clientSecret(secret),mode(sandbox/live), optionalwebhookId. - PayFast —
merchantId(public),merchantKey(secret), optionalpassphrase(secret),mode, and the notify/return/cancel URLs. - Manual — no configuration.
The admin sets which providers are enabled and which is the store's activeProvider. The storefront
only ever receives a public view of this config — never a secret.
The checkout flow
Checkout is atomic and provider-aware:
- The shopper calls checkout (
useCheckout) with their cart and, optionally, apaymentProvider. - The backend reserves inventory atomically, creates a
pendingorder with snapshotted line items, and calls the selected provider to create the payment. - What comes back depends on the provider:
- Manual captures synchronously — the order becomes
paidimmediately. - Stripe (one-time) returns a
clientSecret— confirm it in the browser with Stripe Elements. - Stripe (subscription), PayPal, and PayFast return a
redirectUrl— send the shopper there to complete payment.
- Manual captures synchronously — the order becomes
- Asynchronous providers finalize the order when their webhook confirms the payment.
If you pass a paymentProvider, it's validated against the store's enabled providers (a shopper can't
force manual). Omit it to use the store's activeProvider.
Capturing a PayPal payment
PayPal authorizes on approval and requires a capture:
import { useCaptureOrderPayment } from "@nanosite/ecommerce-sdk";
const capture = useCaptureOrderPayment();
await capture.mutateAsync({ orderId }); // POST /store/orders/:id/capture
Order & payment status
- Order status:
pending,paid,fulfilled,cancelled,refunded. - Payment status:
requires_action,authorized,captured,refunded,failed.
Orders finalize (or fail/refund) through the same webhook pipeline described in Webhooks & events.