Package Exports
- @tjoc/payments
- @tjoc/payments/dist/index.js
- @tjoc/payments/dist/index.mjs
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@tjoc/payments) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@tjoc/payments
Status: candidate — not yet adopted by any portfolio product. Source review required before first consumer wires it in.
Multi-provider payments router for the tjoc.dev portfolio. Implements the strategy defined in ADR 0015.
Portfolio payments strategy (ADR 0015)
| Use case | Provider |
|---|---|
| Card / subscription payments (default) | Stripe |
| Nigerian NUBAN bank transfer | conchpay (Phase 1 — in build) |
| International stablecoin payments | conchpay (Phase 2) |
| All other cases | Stripe unless explicitly documented |
Paystack in star.club is grandfathered. New products do not add Paystack or a direct stablecoin processor — route through this package / conchpay instead.
Installation
pnpm add @tjoc/paymentsBefore adopting: run a source review to confirm which provider adapters are fully implemented and tested. The routing logic in this README reflects ADR 0015; the actual implementation may predate that decision and require alignment.
Quick start — Stripe (default provider)
import { PaymentRouter, StripeProvider } from '@tjoc/payments';
const stripeProvider = new StripeProvider({
apiKey: process.env.STRIPE_SECRET_KEY!,
});
const paymentRouter = new PaymentRouter({
providers: { primary: stripeProvider },
routing: { defaultProvider: 'stripe' },
});
const transaction = await paymentRouter.createPayment({
amount: 9.00,
currency: 'USD',
customerId: 'cust_123',
description: 'Pro subscription',
});Provider adapters
StripeProvider
import { StripeProvider } from '@tjoc/payments';
const stripe = new StripeProvider({
apiKey: process.env.STRIPE_SECRET_KEY!,
webhookHandlers: {
'payment_intent.succeeded': async (event) => { /* ... */ },
'payment_intent.payment_failed': async (event) => { /* ... */ },
},
});PaystackProvider (grandfathered — star.club only)
import { PaystackProvider } from '@tjoc/payments';
const paystack = new PaystackProvider({
secretKey: process.env.PAYSTACK_SECRET_KEY!,
publicKey: process.env.PAYSTACK_PUBLIC_KEY!,
webhookSecret: process.env.PAYSTACK_WEBHOOK_SECRET,
});New products should not use
PaystackProviderdirectly. For Nigerian payment needs, the roadmap points to a conchpay adapter (Phase 1).
PaymentRouter API
// Payments
createPayment(options: CreatePaymentOptions, context?: PaymentContext): Promise<Transaction>
confirmPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
cancelPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
getPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
// Customers
createCustomer(data: Partial<Customer>, context?: PaymentContext): Promise<Customer>
updateCustomer(customerId: string, data: Partial<Customer>, context?: PaymentContext): Promise<Customer>
getCustomer(customerId: string, context?: PaymentContext): Promise<Customer>
deleteCustomer(customerId: string, context?: PaymentContext): Promise<boolean>
// Subscriptions
createSubscription(options: CreateSubscriptionOptions, context?: PaymentContext): Promise<Subscription>
updateSubscription(subscriptionId: string, data: Partial<Subscription>, context?: PaymentContext): Promise<Subscription>
cancelSubscription(subscriptionId: string, context?: PaymentContext): Promise<Subscription>
getSubscription(subscriptionId: string, context?: PaymentContext): Promise<Subscription>
listCustomerSubscriptions(customerId: string, context?: PaymentContext): Promise<Subscription[]>
// Webhooks
handleWebhook(provider: string, body: unknown, signature: unknown): Promise<void>Error handling
import { PaymentProviderError, ConfigurationError } from '@tjoc/payments';
try {
const transaction = await paymentRouter.createPayment(options);
} catch (error) {
if (error instanceof PaymentProviderError) {
console.error('Provider error:', error.code, error.message);
} else if (error instanceof ConfigurationError) {
console.error('Config error:', error.message);
}
}Environment variables
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
# star.club only (grandfathered)
PAYSTACK_SECRET_KEY=sk_live_...
PAYSTACK_PUBLIC_KEY=pk_live_...
PAYSTACK_WEBHOOK_SECRET=...Roadmap
- Phase 1: conchpay adapter — Nigerian NUBAN bank transfers
- Phase 2: conchpay adapter — international stablecoin payments
- First consumer: wisecv (ADR 0007 Phase 4) or next new product needing payments
Development
pnpm build # tsup → dist/
pnpm test # jest
pnpm test:coverage # jest --coverage
pnpm typecheck # tsc --noEmit