Stripe Connect + Subscriptions でサブスクプラットフォームを作る

この記事は [JP_Stripes Advent Calendar 2019](https://adventar.org/calendars/4333) 25日目の記事です🎉

## はじめに
この記事は、決済サービス **Stripe** の **Connect** という機能と **Subscriptions** 機能を組み合わせて、

「**サブスクリプションビジネスのプラットフォームサービスを作ろう**」

という記事です。

いきなりなんのことだ！
という方も、１つずつ説明するのでご安心ください🙆‍♀️

### 「サブスクリプションビジネスのプラットフォームサービス」とは
サブスクリプションは「定期購入」とか定期課金と呼ばれるものです。

「毎月1000円の動画見放題サービス」
「毎月10000円で美味しい日本酒が送られてくるサービス」

など様々なサービスがありますね。

これらのプラットフォーム版、つまり

**サブスクのサービスを提供したいけど**
**自分たちで構築するほどのお金がない、スキルがない**

ようなお店に向けて、「売上の n% 払ってくれれば、うちのサービス上でサブスクリプションできますよ」というのが「サブスクリプションビジネスのプラットフォームサービス」です！

今回取り組んでいる具体的なビジネスモデルについては、以下の資料で説明していますので、ご興味があればぜひご一読ください。
[Stripe Connect with Subscriptions で サブスクプラットフォーマー になろう](https://www.slideshare.net/TomoeTeshima/stripe-connect-with-subscriptions)

### Stripe Connect とは
**Stripe Connect** は、オンライン決済サービス「Stripe」が提供する「**プラットフォームのための決済インフラ**」です。
Connect を使うと、楽天、BASE のようなマーケットプレイスの決済システムを手軽に構築できます。

Connect については @y_toku さんの以下の記事がめちゃめちゃわかりやすいので、ご参考ください🙌
[Stripe Connect 101](https://qiita.com/y_toku/items/7bfa42793801dfc5415d)

### Subscriptions とは
Stripe を使用して **定期課金** する仕組みです。
通常は 「Stripe Billing」という名前になっていますが、 Connect と組み合わせる場合のみ「Subscriptions」とドキュメント上でも表記されていたので、これに倣っています。

## Connect + Subscriptions を組み合わせる
ここからが本題です！

Connect + Subscriptions を組み合わせると、以下のようなことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/ad5f003e-2553-28b0-dfe3-f77056cd260c.png)

画像ではお客さん１人とお店１件のみ記載していますが、実際には多対多の関係で、Stripe を使って構築したサービスが、その間をつなぐプラットフォームの役割を果たします。

### Connect 上での Subscription 登録までの手順
Connect 上で Subscriptions を登録するためには、 Connectアカウント（プラットフォームに紐づけられた、各店舗の子アカウント）に紐づく Customer と plan が必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/43da544e-da4f-85e9-995a-0e1d6618825e.png)

以下で順に説明します。
Stripe　では各言語に SDK が用意されていますが、~~まだ実装できてないので~~みんながわかるように cURL で書いています🙌

#### 子アカウントを登録する
サービスのアカウントに紐づく、お店の子アカウント（Connect アカウント）を登録します。
サービス上で、お店に利用登録をしてもらい API で叩きにいくイメージです。（Connect のアカウントタイプは Custom を想定）

```bash
curl https://api.stripe.com/v1/accounts \
  -u sk_で始まる API キー: \
  -d type=custom \
  -d country=JP \
  -d email="hogehoge_shop@example.com" \
  -d "requested_capabilities[]"=card_payments \
  -d "requested_capabilities[]"=transfers
```

アカウントを有効にするには、上記以外にも会社名や登記番号、また担当者の登録が必要になりますが、ここでは省略します。

#### plan を登録する
「単品の牛乳」「牛乳とヨーグルトのセット」のようなプランを、子アカウントに対して登録します。
サービス上でお店向けの管理画面からお店の担当者に入力してもらい、サービスから Stripe へ API で登録するイメージです。

```bash
curl https://api.stripe.com/v1/plans \
  -u sk_で始まる API キー: \
  -d amount=200 \
  -d currency=jpy \
  -d interval=week \
  -d "product[name]"="Milk set" \
  -H "Stripe-Account: acct_で始まるお店の子アカウントID"
```

#### Customer を登録する
お店を利用するお客さんを、子アカウントに対して登録します。
ユーザーが登録したタイミングや注文しようとしたタイミングで呼び出すイメージです。

```bash
curl https://api.stripe.com/v1/customers \
  -u sk_で始まる API キー: \
  -d description="田中さん" \
  -H "Stripe-Account: acct_で始まるお店の子アカウントID"
```

続いてクレジットカード情報も登録します。
クレジットカード情報のソースには `Stripe Elements` でトークン化されたものを指定しています。

```bash
curl https://api.stripe.com/v1/customers/cus_で始まるカスタマーID/sources \
  -u sk_で始まる API キー: \
  -d source=tok_で始まるカード情報のトークン \
  -H "Stripe-Account: acct_で始まるお店の子アカウントID"
```

#### Subscriptions を登録する
いよいよ Subscriptions の登録です。
お客さんがサービス上で注文した際に呼び出すイメージです。
ここでは、プラットフォーム手数料として10%をもらうことにしています。

```bash
curl https://api.stripe.com/v1/subscriptions \
  -u sk_で始まる API キー: \
  -d customer=cus_で始まるカスタマーID \
  -d "items[0][plan]"=plan_で始まるプランID \
  -d "items[0][quantity]"=3 \
  -d "expand[]"="latest_invoice.payment_intent" \
  -d application_fee_percent=10 \
  -H "Stripe-Account: acct_で始まるお店の子アカウントID"
```

これで、 週200円のプラン3つを田中さんが注文したことになるので、毎週600円が田中さんのクレジットカードに請求され、そのうちの10%=60円が、プラットフォームの売上として入ることになります！

## まとめ
ここまでの内容をちゃんと実装できれば、サブスクリプションプラットフォームが完成する、はずです・・・！！
サービス内でサブスクリプションの注文や変更を管理したり、バッチで毎週請求したり、お店へ売上を振り込んだりする手間がなくなるので、こんなサービスを作りたい人にとってはかなりの恩恵が得られると思います🙋‍♀️
今回のサービスが完成したらまたどこかでご報告しますので、生暖かく見守っていただけると幸いです。