4
2

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.

kintoneAdvent Calendar 2022

Day 23

Stripeの請求書や顧客データを取得・表示するkintoneプラグインを作ってみた

Posted at

この記事は、kintoneアドベントカレンダー23日目の記事です。

JP_Stripesコミュニティなどで、「バックオフィス業務に使うkintoneと、請求処理に利用するStripeの相性が良いのでは?」という声を聞くことが増えてきました。

以前JP_Stripesイベントにて、Stripeからkintoneに接続する方法を紹介しましたので、今回はkintoneからStripeのデータにアクセスすることに挑戦してみます。

Stripe Appsとkintoneの連携に挑戦した際の資料はこちら

使用するkintoneサンプルアプリ

今回は顧客リストアプリを利用します。

ダミーのデータを登録した状態で作成できますので、こちらも活用しましょう。

スクリーンショット 2022-12-23 18.24.58.png

kintoneプラグインをセットアップする

はじめにプラグインをセットアップします。

@kintone/create-pluginコマンドを利用しましょう。

$ 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

セットアップに成功すれば、次のようなメッセージが表示されます。


Success! Created hello-kintone-plugin at hello-kintone-plugin

npm start

  ファイルの変更を監視してプラグインのzipを自動的に作成するプロセスを起動します
  その後、@kintone/plugin-uploaderにより、プラグインのzipは自動的にアップロードされます

npm run build

  プラグインのzipを作成します

npm run lint

  ESLintを使ってJavaScriptのソースコードをチェックします

まずは次のコマンドを実行してください
その後、あなたのkintone環境の情報を入力してください

  cd hello-kintone-plugin
  npm start

kintoneプラグイン開発をはじめましょう!
開発に関する情報はcybozu developer network:

  https://developer.cybozu.io

プラグインをアップロードする

プラグインを動かすには、kintone側へのアップロードが必要です。

コマンドを実行して、初期状態のアプリをアップロードしましょう。

$ npm run build
$ npm run upload

--watchオプションを付けることで、npm run buildに成功すると自動でアップロードしてくれます。

また、ユーザー名などの情報をワンライナーで設定することもできます。

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

kintoneプラグインからStripeの情報を取得する

Stripe SDKをこの方法でセットアップしたアプリに追加すると、以下のビルドエラーが発生します。

ERROR in ./node_modules/stripe/lib/utils.js 4:15-32
Module not found: Error: Can't resolve 'crypto' in '/Users/sandbox/kintone/hello-kintone-plugin-ts/node_modules/stripe/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

そのため今回はExpress.jsで次のようなAPIを用意しました。

app.use((request, response, next) => {
    response.header('Access-Control-Allow-Origin', '*');
    response.header('Access-Control-Allow-Methods', 'GET');
    response.header(
      'Access-Control-Allow-Headers',
      'Content-Type, Stripe-Signature'
    );
    if (request.method.toLocaleUpperCase() === 'OPTIONS') {
      return response.send(200);
    }
    next();
});

app.get('/customer/invoice', async (req, res) => {
  const { data: customers } = await stripe.customers.list({ email: req.query.email });
  if (!customers) return res.send(404);
  const { data: invoices } = await stripe.invoices.list({ customer: customer.id });
  res.json(invoices);
});

あとはsrc/js/desktop.tsなどに作成したAPIを呼び出すコードを実装します。

const PLUGIN_ID = kintone.$PLUGIN_ID;

kintone.events.on("app.record.detail.show", async (event) => {
  const email = event.record["メールアドレス"]?.value;
  if (!email) return;
  const config = kintone.plugin.app.getConfig(PLUGIN_ID);
  const gaia = document.getElementById("record-gaia");
  if (!gaia) return;
  const invoices = await new Promise((resolve, reject) => {
    kintone.plugin.app.proxy(
      PLUGIN_ID,
      `https://YOUR_EXPRESS_API_URL.com/customer/invoices?email=${email}`,
      "GET",
      {},
      {},
      (response) => {
        const result = JSON.parse(response);
        resolve(result);
      },
      (e) => {
        console.log(e);
        reject(e);
      }
    );
  });

  const tableElement = document.createElement("table");
  tableElement.setAttribute("class", "recordlist-gaia");
  tableElement.setAttribute("style", "table-layout: fixed;");
  const tableBodyElement = document.createElement("tbody");
  tableBodyElement.innerHTML = `
<thead>
  <tr>
    <th class="recordlist-header-cell-gaia label-2170 recordlist-header-sortable-gaia">請求書番号</th>
    <th class="recordlist-header-cell-gaia label-2170 recordlist-header-sortable-gaia">請求金額</th>
    <th class="recordlist-header-cell-gaia label-2170 recordlist-header-sortable-gaia">PDF</th>
  </tr>
</thead>
  `;
  (invoices as any).forEach((invoice: any) => {
    const invoiceElement = document.createElement("tr");
    invoiceElement.setAttribute("class", "recordlist-row-gaia");
    invoiceElement.innerHTML = `
    <td class="recordlist-cell-gaia recordlist-single_line_text-gaia value-2178">
      <span class="control-label-text-gaia">${invoice.number}</span>
    </td>
    <td class="recordlist-cell-gaia recordlist-single_line_text-gaia value-2178">
      <span>${invoice.amount_due.toLocaleString()} ${invoice.currency.toLocaleUpperCase()}</span>
    </td>
    <td class="recordlist-cell-gaia recordlist-single_line_text-gaia value-2178">
      <a href="${invoice.invoice_pdf}">Open</a>
    </td>
    `;
    tableBodyElement.appendChild(invoiceElement);
  });
  tableElement.appendChild(tableBodyElement);
  gaia.appendChild(tableElement);
});

このコードをアップロードすると、[顧客リストアプリ]の顧客詳細ページにて、レコードのメールアドレスからStripe上にある請求書のデータを一覧表示できます。

スクリーンショット 2022-12-23 18.23.20.png

本格的な組み込みに向けて

kintoneとStripeを連携させるシンプルなサンプルを紹介しました。

kintone.plugin.app.proxykintone.plugin.app.setProxyConfigを利用することで、連携したいデータを個別に設定したり、StripeのAPIキーを管理画面から登録できるようにすることも可能です。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?