Configuración
Registras PaymentsModule.forRoot() en tu AppModule y le pasas las pasarelas que quieras activar. La librería no lee .env: la configuración de cada pasarela la construyes tú (normalmente desde tus propias variables de entorno — ver Variables de entorno).
Registro del módulo
import { Module } from '@nestjs/common'
import { EventEmitterModule } from '@nestjs/event-emitter'
import { TypeOrmModule } from '@nestjs/typeorm'
import { PaymentsModule, StripeGateway, RedsysGateway, PayPalGateway } from '@kaizen/payments-gateway'
@Module({
imports: [
EventEmitterModule.forRoot(),
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
autoLoadEntities: true,
synchronize: false,
}),
PaymentsModule.forRoot({
public_base_url: process.env.PUBLIC_BASE_URL!,
gateways: [
StripeGateway.register({
secret_key: process.env.STRIPE_SECRET_KEY!,
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET!,
}),
RedsysGateway.register({
merchant_code: process.env.REDSYS_MERCHANT_CODE!,
terminal: process.env.REDSYS_TERMINAL!,
secret_key: process.env.REDSYS_SECRET_KEY!,
environment: process.env.REDSYS_ENVIRONMENT as 'test' | 'production',
merchant_url: process.env.REDSYS_MERCHANT_URL!,
merchant_name: process.env.REDSYS_MERCHANT_NAME,
}),
PayPalGateway.register({
client_id: process.env.PAYPAL_CLIENT_ID!,
client_secret: process.env.PAYPAL_CLIENT_SECRET!,
webhook_id: process.env.PAYPAL_WEBHOOK_ID!,
environment: process.env.PAYPAL_ENVIRONMENT as 'sandbox' | 'production',
public_base_url: process.env.PUBLIC_BASE_URL!,
}),
],
}),
],
})
export class AppModule {}Los campos concretos de cada register() (claves, moneda, terminal, endpoints…) se documentan en la página de cada pasarela: Stripe, Redsys y PayPal.
public_base_url
Es la URL pública de tu API (p. ej. https://tu-dominio.com). La librería la usa para las pasarelas que necesitan una vuelta por el navegador: sirve la página de redirección de Redsys y construye la return_url de PayPal. En local suele ser http://localhost:3000.
Dos requisitos obligatorios
Ambos son estándar de NestJS, pero son imprescindibles para que la librería funcione:
1. autoLoadEntities: true
La librería registra sus entidades (Payment, Refund, WebhookEvent) con un forFeature interno. Con este flag el DataSource las reconoce sin que tengas que listarlas.
2. rawBody: true en el bootstrap
El controller de webhooks verifica la firma sobre el body crudo. Actívalo en main.ts:
// main.ts
const app = await NestFactory.create(AppModule, { rawBody: true }) WARNING
Sin rawBody: true, la verificación de firma de Stripe falla siempre con 400.
Qué le pasa a tu base de datos
No tienes que crear tablas ni correr migraciones tú. La primera vez que arranca tu app, la librería, sobre tu misma conexión:
- Crea el schema
paymentssi no existe. - Crea su tabla de control
payments.migrations(separada de la tuya). - Corre sus migraciones pendientes dentro de una transacción.
Es idempotente (arrancar N veces es seguro) y toca exclusivamente el schema payments: nunca usa synchronize global ni altera tus tablas.
Escuchar los eventos
import { Injectable } from '@nestjs/common'
import { OnEvent } from '@nestjs/event-emitter'
import { PaymentEventPayload } from '@kaizen/payments-gateway'
@Injectable()
export class MiPagosListener {
@OnEvent('payment.captured')
onCaptured(payload: PaymentEventPayload) {
// marca el pedido como pagado, envía email, etc.
}
@OnEvent('payment.failed')
onFailed(payload: PaymentEventPayload) {
// …
}
}Sigue con las Variables de entorno.