【Stripe】超入門編：0から始める決済フォーム自動作成

この記事は、Iwaken Lab.アドベントカレンダー2023の18日目の記事です。

# ごあいさつ
(本当にただの挨拶なのでスキップ可)

こんにちは、ユーゴです。
今回は、イワケンラボのアドベントカレンダーの投稿です！！

本記事では、エンジニア向けにStripeの超入門編の導入をご紹介します。Stripeは、クレジットカード, コンビニ決済, 銀行振込など、様々な方法に対応できる決済サービスです。｢自営業で販売をしているが、オンライン決済に対応したい｣｢CV率を上げる施策の1つに、決済の多角化を取り入れたい｣といった人達のソリューションの1つとなります。

この記事を書こうと思い至った経緯として、｢Stripeの超入門的な解説がない！！｣ということがありました。どの記事を読んでも、｢サーバ立てましょう｣｢サンプルアプリを組み込みましょう｣と…

...しかし、__ナンモワカラン！！__

サーバの知識もないし、サンプルアプリを使うにしても決済フォームの作成フローが分からないからどうすればいいのかも全く分からない。

試行錯誤しているうちに、｢まずは手動で作ってみよう｣から、｢じゃあこれをAPIで自動化すれば良いのでは…？｣という糸口を掴み、なんとかStripeで決済フォームの自動作成を実現できました。

~~しかも、Stripe APIのドキュメントが非常に読みにくい~~

ということで、これからStripeを導入するエンジニア同志の為、超入門をここに書き記しておきます。

# この記事でわかること
コードでStripeのAPIを叩き、自動で決済フォームを作成する方法

# 対象読者
・Stripe **ナンモワカラン** の人
・オンライン決済 **ナンモワカラン** の人
・サーバ構築 **ナンモワカラン** の人
・WebAPIを叩くのは **わかる** 人 (GAS, js, C#, Pythonでもなんでも良い)

# 注意事項
本記事は、Stripeを始めるエンジニアに向けた導入です。記事で紹介するのは、最低限の動作をさせるためのサンプルです。
決済処理が絡むので、**プライバシーポリシー, 返金処理, その他設定など、各個人の判断と責任で実装してください。**

# 目次
[1. Stripeの登録](#1-stripeの登録)
[2. (任意) 手動オペレーションを学ぼう](#2-任意-手動オペレーションを学ぼう)
[3. APIで決済フォームを自動作成する](#3-apiで決済フォームを自動作成する)
[4. Webhookで決済イベントを検知](#4-webhookで決済イベントを検知)
[5. まとめ](#5-まとめ)

# 1. Stripeの登録
まずは、Stripeの管理画面にアクセスするため、アカウントを作成します。
アカウント作成は[【こちら】](https://www.googleadservices.com/pagead/aclk?sa=L&ai=DChcSEwiBz9WXp_CCAxU_bA8CHd59CmkYABABGgJ0Yg&ase=2&gclid=Cj0KCQiAyKurBhD5ARIsALamXaFmhi0QK4WJ_XW5OS7u7JqlO9QsrnCLBs18pZVTFvRIwnyiD5efk9QaAjc1EALw_wcB&ohost=www.google.com&cid=CAESVuD2ETe5OAcPlA_JAizRwDowXk16-cDAw-IbCUgZbgteGDr0mcJpJYrpCerJxXSJBuzLTfxHlU8TnxOP6KFjp6skh4mP1BJMDJ4MeDLEfqagG0PmOiCR&sig=AOD64_1fH8oHj-6zi8mJyKtuQ2Q0D6AnWA&nis=4&adurl&ved=2ahUKEwi_us-Xp_CCAxWJpVYBHR4NCoEQqyQoAHoECAoQCw)

#### (1) メールを登録
![アカウント作成_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/0edd7976-abec-7e54-5431-8b0825198783.png)

#### (2) メールを確認する
![アカウント作成_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/6873bf16-bbff-17c2-7ef9-68a82e9a16dc.png)

#### (3) 「支払いの受け取りを設定する」を押す
![アカウント作成_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/e631ca96-b503-8743-66b8-2cf1baf65b91.png)

#### (4) (任意) 支払い設定を完了させる
私の場合は、面倒だったのでスキップしました。もちろん、後からでもできます。
というか、本番環境にする時に登録が必須条件になるため、今後登録を促されます。

![アカウント作成_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/49800384-a204-d9e2-a74f-6ccc6adf403f.png)

# 2. (任意) 手動オペレーションを学ぼう
## 2-1. はじめに
この手順では、どのように決済フォームが作成されるのかを、手作業で確認します。

結論から言うと、以下の手順に従って作成されます。

**(1) 商品情報, 金額情報を追加する**
**(2) 支払いリンク, 請求書などを作成する**

この項目は任意ですが、「ゼロ 〜 決済フォーム」までのフローを直接確認できるので、コードを書く時も理解しやすくなります。任意とは書きましたが、GUIからAPIの実行結果を確認できる点でも、一度GUI上での手動オペレーションの確認をオススメします。

## 2-2. 商品情報, 金額情報を追加する
### 2-2-1. データの解説
「商品情報」と「金額情報」は、実は別れています。1つの商品に、複数の金額パターンを設定できるよう、ユニットが分けられているのです。とはいえ、手動のときはそれほど意識しなくてもよく、APIを叩くときに意識することになります。

### 2-2-2. 作成する
#### (1) 管理画面を開きます
左のメニューバーがあれば、どのページからでも良いです。

![img_00汎用_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/ba719aa2-088d-d6cd-5924-9cd4b3ebe4e8.png)

#### (2) ｢その他 → 商品カタログ｣を選択します

![img_商品情報_商品カタログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/d420c1c3-e29f-1ec3-4e7c-cf169660abf7.png)


#### (3) ｢商品を追加｣をクリックします

![img_商品情報_追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/dae14ef5-3207-f3c0-d8da-468528164b22.png)


※初回だけ違うGUIだった気もするので、「新規作成する」的なボタンがあれば、そちらを押してみてください。

#### (4) 商品情報を埋めていきます
私は今回、以下のように設定してみました。(個人的にスタンダードな請求形式)
完了したら、「商品を保存」を押してください。

![img_商品情報_設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/19e83a05-69e1-a142-d450-8802b5f20518.png)


## 2-3. 支払いリンク, 請求書などを作成する
### 2-3-1. 違い
以下に、支払いリンクと請求書が、どの決済に対応しているかを示します。

| |クレカ|コンビニ|銀行|
|---|---|---|---|
|支払いリンク|○|×|×|
|請求書|○|○|○|

請求書の方が、様々な決済に対応しています。
請求書は物理的なものではなく、電子上で配布されます。また、支払いリンクと同様に、URLから決済画面に飛ぶことができます。

そのため、請求書の方が圧倒的に有利だと思うのですが、請求書のデメリットは何なのでしょうか...？ここまでは調査できておりません。

### 2-3-2. 作成する：支払いリンク
支払いリンクと言いましたが、正しくは｢payment links｣です。

#### (1) 管理画面を開きます
左にメニューバーがあれば、どこからでもOKです。

![img_00汎用_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/3cb270d6-0f49-fd75-75fd-b5ff738f4876.png)

#### (2) ｢その他 → payment links｣を選択します

![img_支払いリンク_ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/dddca659-a94a-9eab-39a3-281a79a9e284.png)

#### (3) ｢新規｣をクリックします
初回だけGUIが違った気がするので、「新規作成する」的なボタンがあれば、そちらを押してみてください。

![img_支払いリンク_追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/0cc73fe1-06f6-40cd-c214-49910f34f28a.png)

#### (4) 支払い情報を埋めていきます
まず、2-2で作った商品を選択します。
注) たまに空欄を押しても、商品が出てこないことがあります。その時は、「F5でブラウザ更新をする」「空欄に商品名を直接入力する」など試してみてください。

![img_支払いリンク_設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/7e630f45-c5b1-82fa-2304-c248c93e66e1.png)

今回は、他に設定していません。「リンクを作成」を押して、完了させましょう。

![img_支払いリンク_設定_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/28e42cd7-cd42-7644-70df-85f0327110ef.png)

コピーして、ページを開きます。

![img_支払いリンク_リンク_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/dc6e0a72-8ddb-f1c0-62e4-5fad8c66d256.png)

決済フォームが確認できました。

![img_支払いリンク_リンク_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/5b6e1f9f-aa8a-d929-4249-e689b9e108eb.png)

### 2-3-3. 作成する：請求書
請求書と言いましたが、正しくは｢Invoice｣です。

#### (1) ホーム画面へ
左にメニューバーがあればOKです

![img_00汎用_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/65596af1-56e0-428d-4252-5b4ee9013ba8.png)

#### (2) 「その他 → インボイス」を選択します

![img_インボイス_ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/05e39be1-a8ed-f2ba-2a2c-e42948a75d78.png)

#### (3) 「テストの請求書を作成」をクリックします
初回のGUIが違った気がするので、「新規作成する」的なものがあれば押してみてください。

![img_インボイス_追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/025efd87-cb7a-2ded-a343-a2357dc1d76c.png)

#### (4) 請求書の設定をします。
顧客は、テスト用のアカウントを作成してみてください。

![img_インボイス_設定_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/65375867-f6dd-201d-0cc8-72f0e6e16139.png)

**テスト環境の場合、自分のメアドを入れてください。**
それ以外は、後でエラーが出ます。

![img_インボイス_設定_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/10a8e5f4-e78c-9573-43da-4ec354b6c9e0.png)

ラインアイテムでは、先ほど作成した商品を選択してください。

![img_インボイス_設定_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/cdab502e-741f-ef28-5a74-260e7312dc6e.png)

決済方法は、「決済手段を管理する」から変更できます。

![img_インボイス_設定_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/9b2512cb-365b-0a03-23e1-773b85c7c15e.png)

・顧客
・ラインアイテム
・支払いの回収
あたりが設定できれば、最低限OKでしょう。あとは必要に応じて、設定してみてください。

完了したら、「請求書をレビュー」をクリックします。

![img_インボイス_設定_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/eedb97de-7b48-7e27-ad9c-d6b410606fa8.png)

CCはつけなくて良いでしょう。そのまま「請求書を送信する」を押してください。
顧客情報で自分のメアドを入れていないと、ここでエラーが出ます。

![img_インボイス_設定_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/55d63e02-4657-ef51-2d65-86372ddd4e6c.png)

ちなみに、私は自分宛にメールを送ったのですが、かなり遅延して届きました。テスト環境のせいでしょうか？
メールが届くのは期待せず、管理画面からリンクを取得しましょう。

![img_インボイス_リンク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/f10e110d-63ed-df77-cf47-08545fcf09fd.png)

決済フォームが確認できました。

![img_インボイス_リンク_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/3596ef28-658a-853a-3244-8f82767bb7e6.png)

コンビニ決済のテストは、「コンビニ決済」から情報を入力していき、行けるところまで行ったら放置、で10分ほど待つと決済が完了しています。

銀行振込のテストは、こちらにいい記事がありました。
[Stripe Elementsで、カード決済と銀行振込の両方をサポートする決済処理を実装する](https://qiita.com/hideokamoto/items/2e5619f73cd829f48a24#%E9%8A%80%E8%A1%8C%E6%8C%AF%E8%BE%BC%E3%82%92%E3%83%86%E3%82%B9%E3%83%88%E3%81%99%E3%82%8B)


# 3. APIで決済フォームを自動作成する
いよいよ、StripeのAPIを叩いていきます。
今回は、例として私が手馴れているGASを使っていきます。もちろん、ご自身の馴染みの言語でOKです。

## 3-1. 商品情報を作成する
APIは以下となります。
`https://api.stripe.com/v1/products`

Payloadのサンプルは、以下です。(必須：name)

```js
let payload = {
      "id": "prod_xxxxxxxxxxx", // 「prod_」は慣習？ 後部は任意。
      "active": true, // 商品が購入可能な状態か
      "description": "テスト商品です", // 商品の説明
      "name": "テスト商品" // 商品名
    }
```

パラメータ全体は、以下の通りです。

```js
let options = {
      'method': 'post',
      'headers': {
        'Authorization': 'Bearer ' + secretKey, // secretKeyには秘密鍵を入れましょう
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      'payload': payload
  };
```

秘密鍵による認証をお忘れなく。

(リファレンス：https://stripe.com/docs/api/products)

ちなみに、公式ドキュメントに従ってパラメータを投げても、｢invalid_params_error｣だったか｢unknown_params_error｣みたいなのが返ってきます。
単純な回避策として、エラーが出たら、指摘されたパラメータを抜いてみましょう。

## 3-2. 金額情報を設定する
APIは以下となります。
`https://api.stripe.com/v1/prices`

Payloadのサンプルは、以下です。

```js
var payload = {
      "active": true, // この金額による支払いが有効か
      "billing_scheme": "per_unit", // "per_unit"は固定額、"tiered"は従課金
      "currency": "jpy", // 通貨単位
      "product": "prod_xxxxxxxxxxx", // 対象となる商品のIDを指定
      "unit_amount_decimal": "1" // 商品1つあたりの金額。浮動小数でも可能。指定はstringなので注意
    }
```

パラメータ全体は、以下の通りです。

```js
let options = {
      'method': 'post',
      'headers': {
        'Authorization': 'Bearer ' + secretKey, // secretKeyには秘密鍵を入れましょう
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      'payload': payload
  };
```

(リファレンス：https://stripe.com/docs/api/prices)

# 4. Webhookで決済イベントを検知
## 4-1. 余談
クレジットカード決済をWebhookで検知できるのは、分かります。電子的な決済の代表格なので。
個人的にすごいなと思ったのが、コンビニ決済や銀行振込もWebhookで検知できてしまいます。現金によるやり取り、セキュリティ的な面から、直感的に不可能だと思い込んでいました。

## 4-2. Webhookの受信側を作成
こちらも、私は簡単なGASで作っていきます。
詳しくないですが、AWSのAPI Gateway×lambdaとかでも簡単にできるのではないでしょうか。

ここの細かい説明は省きます。postされたデータを出力してくれるアプリを作ります。
一応コードも載せておきます。

```js
function doPost(e){
  let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1") //ログを出したいシート名を指定
  sheet.appendRow([e.postData.getDataAsString()])
}
```

あとは、ウェブアプリとしてデプロイします。
GAS以外の方は、ウェブアプリという名前じゃなくても、実際に動く状態ならなんでもいいです。

## 4-3. Webhookの送信側を設定
#### (1) 管理画面から、「開発者」をクリック
![img_webhook_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/f704a2ff-b3c5-8bfa-cd05-693a7915b620.png)

#### (2) 開発者ページから、「Webhook」をクリック
![img_webhook_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/8b3b4cb5-786e-67ee-b616-b7d7a0ae7ad7.png)

#### (3) 「エンドポイントを追加」をクリック
![img_webhook_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/0cae7543-1201-0cb1-1755-89d1a971b45c.png)

#### (4) Webhookの設定する
まず、パラメータをpostするURLを貼り付けましょう。

![img_webhook_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/ffd188c3-5bda-12cd-aeb8-47f0d6ab6367.png)

次に、リッスンするイベントを追加します。**必要なイベントは、ご自身のプロダクトに合わせて選定してください。**

![img_webhook_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/9eed1a20-74e2-9e06-f625-7768566f82cf.png)

例えば、「checkout.session.completed」は、支払いリンク(payment links)での決済が完了したときに起動します。
![img_webhook_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/728194e1-daf0-a7ac-059a-0aff1759b325.png)

設定が完了したら、「イベントを追加」をクリックします。

![img_webhook_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/47413742-074c-f95b-6d79-b8508efd0597.png)

#### (5) 決済処理を試す
あとは、支払いリンク(payment links)や請求書(invoice)を作成し、テスト支払いをしてみましょう。
GASで試した人は、以下のような情報が取得できていれば成功です。

![img_webhook_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/93dca48d-8a7b-8b14-9ef6-d5c886717909.png)

# 5. まとめ
いかがだったでしょうか。今回は、Stripeの超入門編の導入を解説しました。
Stripeは国際的で、かなり有名な気がします。しかし、意外と求めている記事が見つからなかったので、この機会に自分で書いてみることにしました。
世の中でStripeナンモワカランの人の役に立てれば幸いです。

また、私はしばしUnityエンジニアと思われがちですが、インターン先で社内SEもやったり、GAS, Pythonなども触っています。今回、イメージ払拭できたでしょうか...？！

明日は時化さん(`@tksht261`)の記事です！お楽しみに〜