見出し画像

LINEbot×Stripeで、サブスク課金をノーコード実装した話

LINE公式アカウントで自社サービスを提供するときに
サブスク型のサービスにしたくて、四苦八苦しながらサブスク課金をノーコードツールのみで実装したことがありました。

該当のサービスはクローズしてしまったのですが、今後もこの方法は使うことがある気がしたので、自分への備忘録も兼ねて書き残します。

そもそも、何がそんなに難しいのか

Stripeといえば、ノーコード決済サービスの金字塔(僕が勝手に言っています)ですよね。

WEBサイト中のリンク先に、Stripeで発行したURLを設定するだけで決済が実装できるお手軽さ。

つまり、LINEのリッチメニューとかに決済用のURLを貼っておけば
LINE公式アカウントでStripeを使った決済をすることは可能なんです。

「誰が、どのプランを決済をしてくれたかが分からなくてよければ」

誰がどのプランで契約してくれているかが分からなければ、プランごとのサービスをユーザーに提供することができない。
つまり、Stripeの決済サービスを使ってくれた人が誰で、なんのプランを決済してくれたかを分かるようにしない限り、サービスが成立しないんです。

正直、サブスク型のサービスをやめようかと思ったくらいです。

最終的に、どんな風にデータが溜まる?

データの最終形態を先にお見せいたします。

statusだけ命名規則のルールが違う…

カラムの説明

  • originalCheckoutId:決済ごとに発行されるユニークなIDです。

  • idToken:LINE公式アカウント(LIFF)から取得できる、ユーザー情報の一つです。idTokenを用いて、下記のlineUserIdを取得します。(※idTokenは変動するので、保管する理由はあまり無いです)

  • lineUserId:LINE公式アカウントでユーザーごとに割り振られているIDです。

  • planName:自社サービスで提供しているプランの名前です。

  • status:決済のステータスです。payingが決済途中(もとい、カート落ち)、completeが決済完了を指しています。

このデータが持てていれば、誰がどのプランを決済したかが分かるため
ユーザーに対して適切なサービスを提供することが可能です。

データの大まかな流れ

データの流れとしては、大きく2つに分かれます。

originalCheckoutIdを発行して、データベースに格納する

シナリオの後半が分岐しているのは、プランごとに処理を変えているためです。
もっと良いやり方がある気がします。

originalCheckoutIdを参照して、誰が決済したかを確定する

もっと良いやり方が(略)

全てのデータの流れを説明するのは、煩雑になってしまうかと思うので
キモになる部分だけ切り出して記載します。

実装の詳細

LIFFで、idTokenとプランを取得する

今回は「スタンダードプラン」というものにユーザーが登録する
というていで話を進めていきます。

まず、LINE上で「スタンダードプランに加入する」リンクを踏むと、下記のようなリダイレクトページに飛ばしていました。

リダイレクトしてる風

このページ、実は仮の姿です。
本当は、こんな姿をしています。
DisplayNoneで見えなくしているだけです。

こちらをLIFFで開くと
・idToken
・planName
が自動で入力される寸法です。

そして、全ての項目が記入されたら、フォームのボタンが自動で押される仕組みになっています。

<script>$("#planName").val("{{wf {"path":"name","type":"PlainText"\} }}");</script>
<script>
liff
  .init({
    liffId: "liffidが入るよ", // Use own liffId
  })
  .then(() => {
    const idToken = liff.getIDToken();
    document.querySelector("#idToken").innerText = idToken;
    let hangoutButton = document.getElementById("buttonGoPlan");
    hangoutButton.click();
  })
  .catch((err) => {
    console.log(err.code, err.message);
  });
</script>

ユーザー側からは、ただ決済ページにリダイレクトしているように見せかけて、フォームを送信させています。

入力された内容を、Webhookで受け取る

上記で取得したデータをmakeというiPaaSツールで、Webhooksを使って投げ込んでいます。

これで、make上でデータを取り扱えるようになりました。

originalCheckoutIdを発行する

決済を管理するために、ユニークなIDを発行しています。

乱数+タイムスタンプをoriginalCheckoutIdとして使っていました。
937889117_1680539865のようなIDが出来上がります。

originalCheckoutIdをパラメータに持たせて、決済ページにリダイレクトさせる

ここがキモの部分です。
この機能があるのを探すのにクソ苦労しました。

決済ページに遷移する際に、client_reference_idを持たせて決済すると、決済が行われた際にデータとして引き継ぐことができます。

決済ページにリダイレクトしたユーザーを、payingのステータスとしてデータベースに格納する

idTokenを使って、lineUserIdを取得したのち
それらをデータベースに格納しておきます。

これで、あとは決済してもらうのを待つばかりです。

決済されたoriginalCheckoutIdを参照して、誰が決済してくれたかを判別する

決済されたデータのなかに、client_reference_idが保持されているので、そのIDを元にデータベースを検索します。

無事に誰が決済してくれたかが判明しました!

あとは、payingのステータスをcompletに変更して完了です。

セキュリティ面は改善余地あり

おそらく、エンジニアの方からみると無理矢理感があると思うのですが
なんとか無事に実装できたケースを紹介しました。

かなりしつこく検証をしたのもあって、サービス運営中は一度もエラーが起きることなく稼働してくれていたのはちょっと嬉しかったです。

おそらく、今後もLINE公式アカウントをインターフェイスとしてサービスを作ることがあるかと思うので、今回の反省点を生かせるようにしてみます。

ノーコードで遊んでみたおすすめ記事


この記事が気に入ったらサポートをしてみませんか?