kintoneプラグインのAPIプロキシー機能を使って、プラグインからStripe APIを呼び出す方法

kintoneには外部サービスとの連携をスムーズに実現するための拡張機能・プラグインが用意されています。

https://kintone-sol.cybozu.co.jp/integrate/

この仕組みを利用して、kintoneとStripeを連携することが可能です。

ただし、Stripeの情報にkintoneからアクセスするには、StripeのAPIキーを拡張機能・プラグインに渡す必要があります。

この記事では、「StripeのAPIキーを、kintoneの拡張機能・プラグインで安全に保存・利用する方法」を紹介します。

## 基本的な作り方の流れ

保存・利用する仕組みは、大まかに３つのステップで用意します。

- `@kintone/create-plugin`でプラグインをセットアップ
- [Proxy config](https://cybozu.dev/ja/kintone/docs/js-api/plugins/set-config-for-proxy/)を利用して、StripeのAPIキーを保存する仕組みを用意
- [Proxy config](https://cybozu.dev/ja/kintone/docs/js-api/plugins/set-config-for-proxy/)に保存したAPIキーを利用して、Stripe APIを呼び出す

### プラグインのセットアップ

まずはプラグインをセットアップします。

ここでは、`create-plugin`パッケージを利用します。

https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/


```bash
$ npx @kintone/create-plugin hello-kintone-plugin-ts --lang ja --template modern


  
kintoneプラグインのプロジェクトを作成するために、いくつかの質問に答えてください :)
では、はじめましょう！


  
? プラグインの英語名を入力してください [1-64文字] hello-kintone-plugin-ts
? プラグインの説明を入力してください [1-200文字] hello-kintone-plugin-ts
? 日本語をサポートしますか？ Yes
? プラグインの日本語名を入力してください [1-64文字] (省略可) 
? プラグインの日本語の説明を入力してください [1-200文字] (省略可) 
? 中国語をサポートしますか？ No
? プラグインの英語のWebサイトURLを入力してください (省略可) 
? プラグインの日本語のWebサイトURLを入力してください (省略可) 
? モバイルページをサポートしますか？ Yes
? @kintone/plugin-uploaderを使いますか？ Yes
依存ライブラリをインストールします
(⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂⠂) ⠙ idealTree:hello-kintone-plugin-ts: sill idealTree buildDeps
```

セットアップが完了した後は、プロジェクトのディレクトリで以下のコマンドを起動しましょう。

```bash
npm run upload \
--base-url https://YOUR_SPACE_NAME.cybozu.com \
--username user@example.com \
--password YOUR_PASSWORD
--watch
```

このコマンドを実行中は、`npm run build`でアプリをビルドすることでプラグインを自動的にアップロードしてくれます。

### 1: プラグイン設定画面を用意する

プラグインの設定画面を実装して、APIキー登録などの設定ができる画面を作りましょう。

`plugin/html/config.html`を次のように変更します。

```html
<section class="settings">
  <h2 class="settings-heading">Stripe API連携</h2>
  <p class="kintoneplugin-desc">Stripeと連携するためのAPIキーを設定します</p>
  <form class="js-submit-settings" id="js-submit-settings">
    <p class="kintoneplugin-row">
      <label for="message">
        Secret API KEY:
        <input type="text" id="stripe-secret-api-key" class="js-text-message kintoneplugin-input-text">
      </label>
    </p>
    <p class="kintoneplugin-row">
        <button type="button" class="js-cancel-button kintoneplugin-button-dialog-cancel">Cancel</button>
        <button class="kintoneplugin-button-dialog-ok" id="plugin-submit">Save</button>
    </p>
  </form>
</section>
```

`npm run build`でビルドし、アップロードしましょう。

設定画面のテキストが変われば変更完了です。

![スクリーンショット 2023-01-13 19.19.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/3c2ae391-b396-d0d5-6e7e-7af7c1cf22c8.png)

### 2: APIキー保存機能を作成する

続いて保存機能を追加します。

`src/js/config.ts`を次のように変更し、APIプロキシーを登録しましょう。

```typescript
const PLUGIN_ID = kintone.$PLUGIN_ID;

const form = document.querySelector(".js-submit-settings");
const cancelButton = document.querySelector(".js-cancel-button");
const messageInput =
  document.querySelector<HTMLInputElement>(".js-text-message");
if (!(form && cancelButton && messageInput)) {
  throw new Error("Required elements do not exist.");
}

form.addEventListener("submit", (e) => {
  e.preventDefault();
  const secretAPIKeyField = document.getElementById("stripe-secret-api-key");
  if (!secretAPIKeyField) return;
  const secretAPIKeyFieldValue = (secretAPIKeyField as HTMLInputElement).value;
  if (!secretAPIKeyFieldValue) return;
  const stripeAPIUrl = "https://api.stripe.com/v1";
  const requestHeader = {
    Authorization: `Bearer ${secretAPIKeyFieldValue}`,
  };
  kintone.plugin.app.setProxyConfig(stripeAPIUrl, "GET", requestHeader, {});
  kintone.plugin.app.setProxyConfig(
    stripeAPIUrl,
    "POST",
    {
      ...requestHeader,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    {}
  );
  alert("Saved");
});
cancelButton.addEventListener("click", () => {
  window.location.href = "../../" + kintone.app.getId() + "/plugin/";
});
```

`npm run build`でビルド・アップロードを完了したのち、設定画面にてStripeのシークレットAPIキーを保存しましょう。

次の画面・メッセージが表示されれば保存成功です。

![スクリーンショット 2023-01-13 19.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/f955a9db-ecf0-4925-bc57-d3fa932fffcb.png)


### 3: アプリの設定を更新する

アプリ設定画面で、アプリの更新を行いましょう。

![スクリーンショット 2023-01-13 19.23.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/7a766c15-4099-08a2-3b45-85ddfc349c6a.png)

[アプリの更新]をクリックして数秒待機すれば完了です。

この操作を行わないと、設定画面で登録したAPIキーが反映されませんのでご注意ください。

### 4: Stripe APIを呼び出す

APIキーの登録が完了したので、Stripe APIを呼び出しましょう。

`src/js/desktop.ts`に次のコードを追加します。

```typescript
kintone.events.on("app.record.index.show", async () => {
  const customers = await new Promise<
    Array<{
      id: string;
    }>
  >((resolve, reject) => {
    kintone.plugin.app.proxy(
      PLUGIN_ID,
      `https://api.stripe.com/v1/customers`,
      "GET",
      {},
      {},
      (response) => {
        const result = JSON.parse(response);
        if (!result.data) return [];
        resolve(result.data);
      },
      (e) => {
        console.log(e);
        reject(e);
      }
    );
  });
  const kintoneSpaceElement = kintone.app.getHeaderSpaceElement();
  const simpleTextElement = document.createElement("p");
  simpleTextElement.innerText = `Stripeには、${customers.length}件の顧客データが存在します。`;
  kintoneSpaceElement?.appendChild(simpleTextElement);
});
```

`npm run build`でビルド・アップロードを完了すると、アプリの一覧ページにStripe APIの実行結果が表示されます。

![スクリーンショット 2023-01-13 19.34.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/c25d4608-eec1-45ea-a155-99f21200486f.png)

## Stripe APIは、SDKを利用せずに呼び出す

APIプロキシー機能を利用するため、Stripe APIはSDKを利用せずに呼び出します。

たとえば「特定の顧客IDに紐づく、`open`ステータスの請求書」は次のように取得します。

```typescript
  const invoices = await new Promise((resolve, reject) => {
    const params = new URLSearchParams({
      customer: "cus_xxx",
      status: "open",
    });
    kintone.plugin.app.proxy(
      PLUGIN_ID,
      `https://api.stripe.com/v1/invoices?${params}`,
      "GET",
      {},
      {},
      (response) => {
        const result = JSON.parse(response);
        if (!result.data) return [];
        resolve(result.data);
      },
      (e) => {
        console.log(e);
        reject(e);
      }
    );
  });
```

SDKを利用しないため、APIドキュメントの`curl`を参考にリクエスト内容を組み立てましょう。

https://stripe.com/docs/api

## おわりに

Stripe APIをkintoneから呼び出すための、APIキー管理について紹介しました。

請求管理やサブスクリプションの契約管理などでkintoneをお使いの場合、Stripeのデータとの連携やアクションの設定で、よりバックオフィス業務を効率化することができます。

また、Stripeには決済や収益管理といったお金の流れをスムーズ・自動化するための仕組みを、複数用意しています。

![スクリーンショット 2023-08-03 17.45.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/22f71b2c-7379-00d1-1c16-9c4eb7a67e4b.png)
https://stripe.com/jp/use-cases/finance-automation



## 参考資料

https://developer.cybozu.io/hc/ja/articles/360019834671-kintone%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-Part2-%E6%83%85%E5%A0%B1%E3%81%AE%E9%9A%A0%E5%8C%BF%E6%96%B9%E6%B3%95%E7%B7%A8-

https://developer.cybozu.io/hc/ja/articles/203661160-kintone-%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3JavaScript-API-