Skip to content

@gj-kit/toss-payments-nestjs recipes

Each code block reuses a public-contract example already type-checked in the package README.

Build the core configuration first, then register the module once for typed injection.

Outcome: One Nest provider that injects a typed payment kit.

Application-owned boundary: Build the core payment config, register it once, and preserve raw request bytes for webhook routes.

import { orThrow } from '@gj-kit/toss-payments';
import { defineTossPaymentsConfig, parseApiSecretKey } from '@gj-kit/toss-payments/server';
import { TossPaymentsModule } from '@gj-kit/toss-payments-nestjs';
declare const apiSecretFromEnv: string; // Read this once from your server environment.
const config = defineTossPaymentsConfig({
secretKey: orThrow(parseApiSecretKey(apiSecretFromEnv)),
});
export const payments = TossPaymentsModule.forRoot(config);

2. Inject only flows the configuration wired

Section titled “2. Inject only flows the configuration wired”

Recover the configuration-specific type so an unwired billing flow has no property.

The commented line is a real TS2339: this config wired no BillingKeyStore, so the injected kit has no billing property at all — even though the value arrived through an untyped DI token.

import { Injectable } from '@nestjs/common';
import { orThrow } from '@gj-kit/toss-payments';
import { defineTossPaymentsConfig, parseApiSecretKey, type OrderStore } from '@gj-kit/toss-payments/server';
import { InjectTossPayments, TossPaymentsModule, type TossPaymentsFor } from '@gj-kit/toss-payments-nestjs';
declare const SECRET: string; // the app owns this (process.env)
declare const orders: OrderStore; // the app owns this (its own DB adapter)
export const tossConfig = defineTossPaymentsConfig({ secretKey: orThrow(parseApiSecretKey(SECRET)), orders });
export type AppToss = TossPaymentsFor<typeof tossConfig>;
export const tossModule = TossPaymentsModule.forRoot(tossConfig);
@Injectable()
export class PaymentsService {
constructor(@InjectTossPayments() private readonly toss: AppToss) {}
order = () => this.toss.confirm.createOrder({ amount: 9_900, orderName: 'Pro' });
// this.toss.billing — TS2339: the config wired no BillingKeyStore, so there is no property.
}

Use the complete API reference for every export and import path.