JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 59
  • Score
    100M100P100Q77341F
  • License MIT

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/payments

Before 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 PaystackProvider directly. 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