Skip to content

NestJS

Terminal window
npm install @sarrafjs/nestjs

Enable raw bodies when you bootstrap the app. Signatures are computed over the exact bytes:

const app = await NestFactory.create(AppModule, { rawBody: true });
import { SarrafModule } from "@sarrafjs/nestjs";
@Module({
imports: [
SarrafModule.forRoot({
client: { providers: { paymob: paymob({ /* … */ }), fawry: fawry({ /* … */ }) } },
}),
],
})
export class AppModule {}

client is either a Sarraf instance or the options to create one. To read keys from ConfigService:

SarrafModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
providers: { kashier: kashier({ merchantId: config.getOrThrow("KASHIER_MERCHANT_ID"), /* … */ }) },
}),
});

The module is global. Inject the client anywhere with @InjectSarraf():

@Injectable()
export class CheckoutService {
constructor(@InjectSarraf() private readonly pay: Sarraf) {}
}

The module serves POST /webhooks/:provider. Verified events go to every method marked @OnSarrafEvent():

import type { EventOf, SarrafEvent } from "@sarrafjs/core";
import { OnSarrafEvent } from "@sarrafjs/nestjs";
@Injectable()
export class OrdersService {
@OnSarrafEvent("payment.succeeded")
async paid(event: EventOf<"payment.succeeded">) { // a PaymentEvent, so event.payment is typed
await this.orders.markPaid(event.payment.reference); // dedupe on event.id
}
@OnSarrafEvent() // no types: every event
async log(event: SarrafEvent) { /* … */ }
}
Status When
200 Verified, and every matching handler finished
400 WEBHOOK_SIGNATURE_INVALID
404 Unknown provider
500 Missing raw body, processing failed, or a handler threw, so the provider retries

Handlers must be on singleton providers or controllers; request-scoped ones are ignored with a warning.

Options, on both forRoot and forRootAsync:

  • webhooks: { path: "payments/webhooks" } changes the route to POST /payments/webhooks/:provider.
  • webhooks: { mode: "ack-first" } answers 200 before running handlers. Errors are then only logged, so only enqueue work.
  • webhooks: false registers no controller. Call SarrafWebhooks.handle(provider, req) from your own controller instead; it throws the same HTTP exceptions.

Full example: examples/nestjs-shop.