6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nestjs-stripeモジュールで、NestJSからStripe APIを利用できるようにする

Posted at

NestJSを利用すると、REST APIやGraphQL APIに静的なファイル配信など、さまざまな機能を備えたサーバーを作成できます。

今回の記事では、NestJSでStripeを簡単に利用できるライブラリnestjs-stripeを紹介します。

NestJSプロジェクトのセットアップ

NestJSでアプリを作成するには、Nest CLIを利用します。

npm i -g @nestjs/cliでインストールしましょう。

その後、nest new <project-name>でセットアップを開始できます。

$ nest new example-nestjs-stripe
? Which package manager would you ❤️  to use? npm
✔ Installation in progress... ☕

🚀  Successfully created project example-nestjs-stripe
👉  Get started with the following commands:

$ cd example-nestjs-stripe
$ npm run start

                                         
                          Thanks for installing Nest 🙏
                 Please consider donating to our open collective
                        to help us maintain this package.
                                         
                                         
               🍷  Donate: https://opencollective.com/nest

Nest CLIをグローバルインストールしない場合

NestJSはAngularやIonicと同じく専用のCLIコマンドを開発で多用します。

そのため、もしグローバルインストールしたくない場合は、npm i -D @nestjs/cliでプロジェクトのnode_modules内にCLIを配置しましょう。

Stripeモジュールを追加

npm i nestjs-stripe stripeでNestJSモジュールとStripe SDKを追加します。

$ npm i nestjs-stripe stripe
success Saved 2 new dependencies.
info Direct dependencies
├─ nestjs-stripe@1.0.0
└─ stripe@9.8.0
info All dependencies
├─ nestjs-stripe@1.0.0
└─ stripe@9.8.0
✨  Done in 2.99s.

Stripe APIキーを環境変数経由で渡す

NestJSで環境変数を利用する場合、@nestjs/configモジュールを利用します。

$ npm i @nestjs/config

.env.localファイルを作成し、StripeのシークレットAPIキーを設定しましょう。

STRIPE_SECRET_API_KEY=sk_test_xxxx

続いてStripe APIを呼び出したいモジュールにStripeモジュールを設定します。
src/app.module.tsConfigModuleStripeModuleを追加しましょう。

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigService } from '@nestjs/config';
import { StripeModule } from 'nestjs-stripe';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: ['.env.local'],
    }),
    StripeModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        apiKey: configService.get('STRIPE_SECRET_API_KEY'),
        apiVersion: '2020-08-27',
      }),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

StripeのAPIを呼び出す

あとはStripeのAPIを呼び出したいServiceで@InjectStripeを実行するだけです。

src/app.service.tsを以下のように変更しましょう。


import { Injectable } from '@nestjs/common';
import { InjectStripe } from 'nestjs-stripe';
import Stripe from 'stripe';

@Injectable()
export class AppService {
  constructor(
    @InjectStripe() private readonly stripeClient: Stripe
  ) {}
  
  public async listProducts() {
    return this.stripeClient.products.list();
  }

  getHello(): string {
    return 'Hello World!';
  }
}

続いてlistProductsを呼び出すAPIをsrc/app.controller.tsに追加しましょう。

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('products')
  async listProducts() {
    return this.appService.listProducts();
  }
}

これで、Stripeに登録した商品データを取得するGET /productsAPIが完成しました。

Stripeモジュールをモックして、テストを書く

NestJSのモジュールを利用すると、Jestでのテストでモックがしやすくなるなどのメリットがあります。

Stripeモジュールをモックする

Stripeモジュールをモックするには、createTestingModuleを利用します。
まずはモック用のオブジェクトを用意しましょう。

const stripeMock = () => ({
  products: {
    list: jest.fn().mockImplementation(() => [
      {
        id: 'prod_xxx',
      },
    ]),
  },
});

続いて、createTestingModuleprovidersでモジュールをモックします。
また、一緒にmodule.getでモックしたクラスも取得しておきましょう。

import { Test, TestingModule } from '@nestjs/testing';
import { AppService } from './app.service';
import Stripe from 'stripe';

const stripeMock = () => {...}
 
describe('AppService', () => {
  let service: AppService;
  let stripe: Stripe;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        AppService,
        {
          provide: 'StripeToken',
          useFactory: stripeMock,
        },
      ],
    }).compile();

    service = module.get<AppService>(AppService);
    stripe = module.get<Stripe>('StripeToken');
  });
...

モックに対してテストを実行する

あとはテスト対象のメソッドを呼び出して、モックで設定した値を利用した結果をテストしましょう。
また、module.getしておけば、引数や呼び出し回数に関するテストも行えます。

  it('listProducts', async () => {
    await expect(service.listProducts()).resolves.toEqual([
      {
        id: 'prod_xxx',
      },
    ]);
    expect(stripe.products.list).toHaveBeenCalledWith({
      expand: ['data.default_price'],
    });
  });

参考リンク

[PR] Stripe開発者向け情報をQiitaにて配信中!

  • [Stripe Updates]:開発者向けStripeアップデート紹介・解説
  • ユースケース別のStripe製品や実装サンプルの紹介
  • Stripeと外部サービス・OSSとの連携方法やTipsの紹介
  • 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について週に2〜3本ペースで更新中です。

-> Stripe Organizationsをフォローして最新情報をQiitaで受け取る

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?