AegisPay is a gateway-agnostic TypeScript payment orchestration SDK. It provides the orchestration layer around payments: state management, idempotency, gateway routing, retries, circuit breakers, audit events, storage abstractions, and a typed gateway adapter contract.
AegisPay does not process real payments by itself. To process real payments, applications must implement and register their own gateway adapter in userland.
- Not a Stripe, Razorpay, PayU, Cashfree, PayPal, or bank integration.
- Not a PCI card vault. Do not send card numbers or CVV values into AegisPay metadata.
- Not a hosted checkout, payment page, or wallet.
- Not a guarantee of exactly-once delivery, zero data loss, or fixed availability. Those properties depend on the durable storage, lock, event, and gateway implementations you provide.
npm install aegispayThe package currently publishes a CommonJS build with TypeScript declarations. TypeScript consumers can use normal named imports.
import { AegisPay, MockGateway, PaymentStatus, RoutingStrategy } from 'aegispay';
const aegisPay = new AegisPay({
idempotency: { enabled: true },
routing: { strategy: RoutingStrategy.ROUND_ROBIN },
retry: { maxAttempts: 3 },
circuitBreaker: { failureThreshold: 5 },
});
aegisPay.registerGateway('mock-primary', new MockGateway({ gatewayName: 'mock-primary', successRate: 0.95 }));
aegisPay.registerGateway('mock-backup', new MockGateway({ gatewayName: 'mock-backup', successRate: 0.9 }));
const payment = await aegisPay.createPayment({
amount: 10000,
currency: 'INR',
customerId: 'customer_123',
orderId: 'order_123',
idempotencyKey: 'idem_123',
});
console.log(payment.status === PaymentStatus.SUCCEEDED);Amounts are integer minor units, such as paise or cents.
AegisPay: facade for creating payments and registering adapters.PaymentGatewayAdapter: typed contract future gateway integrations implement.PaymentStatus: strict lifecycle states fromINITIATEDthrough success, failure, cancellation, and refunds.IdempotencyStore: protects duplicate creates by key and request fingerprint.PaymentRepository,EventStore,LockManager,OutboxStore: storage extension points.RoutingStrategy: round-robin, weighted, priority, latency-based, success-rate-based, cost-based, or custom routing.RetryPolicyandCircuitBreaker: resilience primitives for retryable gateway failures.EventBus: emits sanitized audit events for application-level subscribers.
Adapters are implemented outside this package. AegisPay normalizes adapter results into success, failed, pending, requires_action, timeout, or gateway_error.
import {
GatewayChargeRequest,
GatewayChargeResult,
GatewayHealthResult,
PaymentGatewayAdapter,
} from 'aegispay';
class MyGatewayAdapter implements PaymentGatewayAdapter {
readonly name = 'my-gateway';
async charge(request: GatewayChargeRequest): Promise<GatewayChargeResult> {
// Implement the real gateway call in your application/package.
// AegisPay does not ship real gateway SDKs or credentials.
return {
status: 'success',
gatewayTransactionId: `txn_${request.paymentId}`,
rawResponse: {},
};
}
async healthCheck(): Promise<GatewayHealthResult> {
return { healthy: true };
}
}Skeletons for adapters named RazorpayGatewayAdapter, StripeGatewayAdapter, or PayUGatewayAdapter should live in your own application or package and map those providers into the same interface. Do not add their SDKs or secrets to AegisPay core.
MockGateway is for demos and tests. It never makes network calls.
new MockGateway({
gatewayName: 'mock-primary',
successRate: 0.9,
latencyMs: 20,
timeoutRate: 0.02,
failureRate: 0.03,
declineRate: 0.01,
pendingRate: 0.01,
deterministicMode: true,
seed: 42,
});ScenarioGateway provides deterministic test cases such as alwaysSuccess, alwaysFailure, alwaysTimeout, failNTimesThenSuccess, pendingThenSuccess, and slowGateway.
When idempotency is enabled, the same key with the same request fingerprint returns the first completed payment. The same key with a different fingerprint throws IdempotencyConflictError.
The default in-memory idempotency store is suitable for tests and single-process demos only. Multi-instance production deployments should provide a durable implementation backed by Redis, Postgres, or another system with atomic compare-and-set semantics.
Routing is adapter-name based, not provider-type based. A gateway can be selected by round-robin, configured weights, priority order, recent in-memory latency, recent in-memory success rate, configured cost, or a custom selector.
Retries are attempted only for retryable outcomes such as timeout and gateway_error. Declines and validation/authentication failures are not retried by default.
Circuit breakers track failures per registered gateway in memory. Applications that need shared breaker state across instances should provide their own coordination layer.
AegisPay emits sanitized events such as PaymentCreated, GatewaySelected, RetryScheduled, GatewayFailed, CircuitOpened, PaymentSucceeded, and PaymentFailed.
The SDK includes in-memory event bus and event store implementations. They are useful for tests and demos. Durable delivery can be implemented by adapting EventStore or OutboxStore to Kafka, SQS, NATS, Postgres, or another infrastructure component. AegisPay supports outbox-style extension but does not claim exactly-once event delivery.
Default implementations:
InMemoryPaymentRepositoryInMemoryIdempotencyStoreInMemoryEventStoreInMemoryEventBusInMemoryLockManagerInMemoryOutboxStore
These defaults are not durable and are not intended for multi-instance production systems.
- Keep gateway credentials in the application that implements the adapter, not in AegisPay.
- Do not store raw card numbers, CVV, authentication secrets, bearer tokens, or gateway API keys in payment metadata.
- Replace in-memory storage, lock, event, and outbox implementations before using multiple application instances.
- Treat local/mock benchmark results as local SDK behavior only, not payment gateway throughput claims.
- Add gateway-specific compliance, reconciliation, webhook verification, and settlement logic in userland.
Examples in examples/ run with mock or custom in-process adapters only:
basic-payment.tscustom-gateway-adapter.tsfailover-routing.tsidempotency.tscircuit-breaker.tsevents.ts
Contributions should keep the core gateway-agnostic. Real gateway adapters belong in separate packages or consuming applications unless the project explicitly chooses a plugin package boundary later.
MIT