> ## Documentation Index
> Fetch the complete documentation index at: /llms.txt
> Use this file to discover all available pages before exploring further.

# NestJS

> Accept mobile money payments in your NestJS application with the Simiz module.

The Simiz NestJS module provides a fully typed, dependency-injection-friendly way to integrate mobile money payments into your NestJS application. It includes a service for creating transactions, a guard for webhook signature verification, and DTOs for request validation.

## Prerequisites

| Requirement   | Minimum version                              |
| ------------- | -------------------------------------------- |
| NestJS        | 10.0                                         |
| Node.js       | 18.0                                         |
| Simiz account | [Create one free](https://simiz.io/register) |

<Warning>
  You need your Simiz API keys before configuring the module. Find them in **Dashboard > Settings > API Keys**.
</Warning>

## Installation

<Steps>
  <Step title="Install the packages">
    ```bash
    npm install @simiz/nestjs @simiz/node-sdk
    ```
  </Step>

  <Step title="Import the module">
    Register the Simiz module in your `AppModule`:

    ```typescript
    import { SimizModule } from '@simiz/nestjs';

    @Module({
      imports: [
        SimizModule.forRoot({
          apiKey: process.env.SIMIZ_API_KEY,
          environment: process.env.SIMIZ_ENVIRONMENT as 'sandbox' | 'production',
          webhookSecret: process.env.SIMIZ_WEBHOOK_SECRET,
        }),
      ],
    })
    export class AppModule {}
    ```

    Or use `forRootAsync` for dynamic configuration:

    ```typescript
    SimizModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        apiKey: config.getOrThrow('SIMIZ_API_KEY'),
        environment: config.getOrThrow('SIMIZ_ENVIRONMENT'),
        webhookSecret: config.getOrThrow('SIMIZ_WEBHOOK_SECRET'),
      }),
    }),
    ```
  </Step>

  <Step title="Set environment variables">
    ```env
    SIMIZ_API_KEY=smz_test_xxxxxxxxxxxx
    SIMIZ_ENVIRONMENT=sandbox
    SIMIZ_WEBHOOK_SECRET=whsec_xxxxxxxxxxxx
    ```
  </Step>
</Steps>

## Usage

### Inject the service

```typescript
import { SimizService } from '@simiz/nestjs';

@Injectable()
export class PaymentService {
  constructor(private readonly simiz: SimizService) {}

  async createPayment(dto: CreatePaymentDto) {
    const transaction = await this.simiz.createTransaction({
      amount: dto.amount,
      currency: 'XAF',
      phone_number: dto.phoneNumber,
      provider: dto.provider,
      description: dto.description,
      metadata: { orderId: dto.orderId },
    });

    return { checkoutUrl: transaction.checkout_url };
  }

  async getPayment(transactionId: string) {
    return this.simiz.getTransaction(transactionId);
  }
}
```

### Webhook controller

```typescript
import { SimizWebhookGuard, SimizWebhookPayload } from '@simiz/nestjs';

@Controller('webhooks')
export class WebhookController {
  @Post('simiz')
  @UseGuards(SimizWebhookGuard)
  async handleWebhook(@Body() payload: SimizWebhookPayload) {
    switch (payload.event) {
      case 'transaction.completed':
        // Handle successful payment
        break;
      case 'transaction.failed':
        // Handle failed payment
        break;
      case 'refund.completed':
        // Handle refund
        break;
    }
  }
}
```

The `SimizWebhookGuard` automatically verifies the HMAC-SHA256 signature.

### DTOs

The package includes built-in DTOs for request validation:

```typescript
import { CreateTransactionDto, TransactionResponseDto } from '@simiz/nestjs';
```

## Supported payment methods

| Method           | Type         | Status      |
| ---------------- | ------------ | ----------- |
| Orange Money     | Mobile Money | Available   |
| MTN Mobile Money | Mobile Money | Available   |
| Wave             | Mobile Money | Coming Soon |
| Moov Money       | Mobile Money | Coming Soon |

## Supported currencies

| Currency                  | Code | Countries                                                                   |
| ------------------------- | ---- | --------------------------------------------------------------------------- |
| Central African CFA Franc | XAF  | Cameroon, Central African Republic, Chad, Congo, Equatorial Guinea, Gabon   |
| West African CFA Franc    | XOF  | Benin, Burkina Faso, Ivory Coast, Guinea-Bissau, Mali, Niger, Senegal, Togo |

## Webhook events

| Event                   | Description            |
| ----------------------- | ---------------------- |
| `transaction.created`   | Transaction initiated  |
| `transaction.completed` | Payment successful     |
| `transaction.failed`    | Payment failed         |
| `transaction.cancelled` | Cancelled by customer  |
| `transaction.expired`   | Payment window expired |
| `refund.created`        | Refund initiated       |
| `refund.completed`      | Refund completed       |
| `refund.failed`         | Refund failed          |

## Test mode

Set the following environment variables:

```env
SIMIZ_API_KEY=smz_test_xxxxxxxxxxxx
SIMIZ_ENVIRONMENT=sandbox
```

The module connects to `sandbox.api.simiz.io` and no real money is charged.

<Card title="Full sandbox documentation" icon="flask" href="/en/guides/sandbox-testing">
  See all test numbers and scenarios in the Sandbox Testing guide.
</Card>

## Troubleshooting

<Tabs>
  <Tab title="Webhook signature invalid">
    **Solutions:**

    * Verify `SIMIZ_WEBHOOK_SECRET` is set correctly
    * Ensure no middleware is parsing the body before the guard (use raw body)
    * Enable raw body in your NestJS app: `app.useBodyParser('raw', { type: 'application/json' })`
  </Tab>

  <Tab title="Module not injecting">
    **Solutions:**

    * Ensure `SimizModule.forRoot()` is imported in the root module
    * If using `forRootAsync`, verify the factory returns all required fields
    * Check that the module is global or imported in the consuming module
  </Tab>

  <Tab title="API key errors">
    **Solutions:**

    * Verify the environment variable is loaded correctly
    * Ensure you are using the correct key for the environment
    * Check that the key has not been revoked
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="Node.js SDK" icon="js" href="/sdks/nodejs/overview">
    Explore the underlying Node.js SDK for advanced usage.
  </Card>

  <Card title="Webhook Verification" icon="shield-check" href="/en/core-concepts/webhooks/overview">
    Learn about webhook configuration and signature verification.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Explore the full Simiz API.
  </Card>

  <Card title="Support" icon="headset" href="https://support.simiz.io">
    Need help? Contact our support team.
  </Card>
</CardGroup>

## Changelog

<Accordion title="Version history" defaultOpen>
  | Version | Date       | Changes                                                    |
  | ------- | ---------- | ---------------------------------------------------------- |
  | `1.0.0` | 2026-03-01 | Initial release — mobile money payments, webhooks, sandbox |
</Accordion>
