Skip to content

About

A unified PaymentPackage for NestJs apps, that handles simple configs of different gateways through one single config file

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

@ciscode/PaymentKit

PaymentKit is a flexible payment orchestration package for NestJS, designed to integrate Stripe and PayPal payment gateways with minimal configuration. This package simplifies the payment lifecycle while exposing a unified API for payment creation, status retrieval, refunds, and webhook handling.

npm version License: MIT TypeScript


Features

  • Unified API: Easy-to-integrate payment flow for Stripe and PayPal
  • Next Action Handling: Automatic routing for client-side actions (client_secret for Stripe, redirect URL for PayPal)
  • Complete Webhook Support: Built-in webhook signature verification, event normalization, and routing for both gateways
  • Type-Safe: Full TypeScript support with strict mode enabled
  • Error Normalization: Gateway-specific errors mapped to unified error codes
  • Idempotency & Retry Safe: Built-in idempotency key support for safe retries
  • Hexagonal Architecture: Clean separation of concerns with ports & adapters pattern
  • Production Ready: 85%+ test coverage with comprehensive unit tests

Architecture

PaymentKit implements a Modular architecture:

  1. PaymentKitModule: The central module for registering and wiring all payment logic.
  2. PaymentsService: The service used by the host app to manage the payment lifecycle.
  3. Gateways:
    • StripeGateway: Handles Stripe-specific payment flow.
    • PaypalGateway: Handles PayPal-specific payment flow.
  4. Webhook Handler: Automatically handles incoming webhooks from Stripe/PayPal and triggers the appropriate actions based on gateway events.
  5. Error Handling: Maps gateway-specific errors to a unified error structure.
  6. Next Action: Facilitates the next step of the payment process (either redirect URL or client secret for Stripe).

Install & Run

  1. Install the package: In your NestJS application, install PaymentKit via npm:

    npm install @ciscode/paymentkit@latest
  2. Configure the payment module: Import the PaymentKitModule in your AppModule and pass the necessary configuration (PayPal/Stripe).

    import { Module } from '@nestjs/common';
    import { PaymentKitModule } from '@ciscode/paymentkit';
    
    @Module({
      imports: [
        PaymentKitModule.register({
          environment: process.env.PAYMENTKIT_ENVIRONMENT ?? 'sandbox',
          gateways: {
            paypal: { enabled: true },
            stripe: { enabled: true },
          },
          webhooks: { mode: 'internal' }, // Optionally set to 'external' if required
        }),
      ],
    })
    export class AppModule {}
  3. Create payment Use the PaymentsService to create a payment:

    import { Injectable } from '@nestjs/common';
    import { PaymentsService } from '@ciscode/paymentkit';
    import { CreatePaymentCommand } from '@ciscode/paymentkit';
    
    @Injectable()
    export class MyPaymentService {
      constructor(private readonly paymentsService: PaymentsService) {}
    
      async createPayment() {
        const command: CreatePaymentCommand = {
          gateway: 'paypal', // or 'stripe'
          amount: { amount: 1000, currency: 'USD' },
          metadata: { orderId: 'o_1' },
        };
    
        const result = await this.paymentsService.createPayment(command);
    
        if (result.nextAction?.type === 'redirect') {
          // Redirect the user to PayPal
          console.log('Redirect to PayPal: ', result.nextAction.url);
        } else if (result.nextAction?.type === 'client_secret') {
          // Process Stripe payment with client_secret
          console.log('Stripe client secret: ', result.nextAction.clientSecret);
        }
      }
    }
  4. Start the app Start your NestJS app as usual:

    npm run start

Environment Variables

Set the following environment variables for gateway configuration:

Required Variables

# Environment
PAYMENTKIT_ENVIRONMENT=sandbox  # 'sandbox' or 'production'
PAYMENTKIT_DEFAULT_CURRENCY=USD # Default currency code

# Stripe Configuration
PAYMENTKIT_STRIPE_ENABLED=true
PAYMENTKIT_STRIPE_SECRET_KEY=sk_test_...  # Use sk_live_... for production
PAYMENTKIT_STRIPE_WEBHOOK_SECRET=whsec_...  # For webhook signature verification

# PayPal Configuration
PAYMENTKIT_PAYPAL_ENABLED=true
PAYMENTKIT_PAYPAL_CLIENT_ID=your-paypal-client-id
PAYMENTKIT_PAYPAL_SECRET=your-paypal-secret
PAYMENTKIT_PAYPAL_WEBHOOK_ID=your-webhook-id  # For webhook verification

Optional Variables

# Webhook Configuration
PAYMENTKIT_WEBHOOK_MODE=internal  # 'internal' (default) or 'external'

# Stripe Advanced
PAYMENTKIT_STRIPE_API_VERSION=2023-10-16  # Specific API version

# PayPal Advanced
PAYMENTKIT_PAYPAL_WEBHOOK_VERIFICATION_URL=https://api-m.paypal.com/v1/notifications/verify-webhook-signature

Security Note: Never commit secrets to version control. Use environment variables or secret management services.


Usage Example

This example creates a payment via PayPal or Stripe.

const command = {
  gateway: 'paypal', // or 'stripe'
## API Reference

### Core Methods

#### `createPayment(command: CreatePaymentCommand): Promise<CreatePaymentResult>`

Creates a new payment through the specified gateway.

#### `getPaymentStatus(query: GetPaymentStatusQuery): Promise<GetPaymentStatusResult>`

Retrieves the current status of a payment.

#### `refundPayment(command: RefundPaymentCommand): Promise<RefundPaymentResult>`

Processes a full or partial refund for a completed payment.

See [examples](./examples) directory for detailed usage patterns.

---

## Security Best Practices

1. **Webhook Verification**: PaymentKit includes built-in HMAC signature verification for both Stripe and PayPal webhooks
2. **Secret Management**: Never hardcode API keys - use environment variables or secret managers
3. **HTTPS Only**: Always use HTTPS in production for webhook endpoints
4. **Idempotency Keys**: Use unique idempotency keys to prevent duplicate charges
5. **Error Handling**: Never expose raw gateway errors to end users - use the normalized error codes

---

## Troubleshooting

### Payment Creation Fails

**Problem**: `createPayment` returns an error

**Solutions**:
- Verify environment variables are correctly set
- Check gateway is enabled in configuration
- Ensure amount is in correct format (integer cents for Stripe, dollars for PayPal)
- Verify API keys are valid for the environment (test/production)

### Webhooks Not Working

**Problem**: Webhook events not being received or verified

**Solutions**:
- Confirm webhook secret is correctly set in environment variables
- For Stripe: Use Stripe CLI for local testing: `stripe listen --forward-to localhost:3000/webhooks/stripe`
- For PayPal: Ensure webhook ID is registered in PayPal developer dashboard
- Check webhook endpoint is publicly accessible (use ngrok for local testing)
- Verify webhook signature verification is not failing (check logs)

### Gateway Not Configured Error

**Problem**: `Gateway not configured` error when creating payments

**Solutions**:
- Ensure gateway is enabled: `PAYMENTKIT_STRIPE_ENABLED=true`
- Verify all required environment variables for the gateway are set
- Check `PaymentKitModule.register()` configuration includes the gateway

---

## Performance

- **Average Latency**: 200-500ms per payment operation (depends on gateway API response time)
- **Webhook Processing**: < 50ms for signature verification and event normalization
- **Memory Footprint**: ~15MB base + gateway client overhead

---

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.

---

## Changelog

See [CHANGELOG.md](./CHANGELOG.md) for version history and release notes.

---

## License

MIT License - see [LICENSE](./LICENSE) for details.

---

## Maintainer

**Zaiid Moumni** ([@TheVlpha](https://github.com/Zaiidmo))

---

## Links

- [Documentation](./docs)
- [Examples](./examples)
- [GitHub Issues](https://github.com/CISCODE-MA/PaymentKit/issues)
- [npm Package](https://www.npmjs.com/package/@ciscode/paymentkit)

## Changelog

This package uses automated changelog generation. All releases are tagged and documented in the changelog.

---

## Known Issues & Limitations

• Stripe webhook signature verification is not included in this package. Please ensure your webhook handling is secure.
• Only supports Stripe PaymentIntent flow, not Checkout Sessions yet (we’ll add this in future versions).

---

## Maintainer

[TheVlpha](https://gihub.com/Zaiidmo)

About

A unified PaymentPackage for NestJs apps, that handles simple configs of different gateways through one single config file

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages