他社の SaaS に「Stripe と繋ぐ」ボタンを付けたい。Connect の OAuth を使えばいい。
そう思ってドキュメントを開いた。
こう書いてあった。
新しい Connect 拡張機能は作成できなくなりました。
Connect 拡張機能。私が使おうとしていた Connect OAuth とは、別のものだ。
そこで手が止まった。別物だと分かった上で、じゃあ自分が使おうとしているほうは今どうなっているのか、が分からない。
読み進めて、順番はこうだと分かった。作れなくなったのは拡張機能のほう。OAuth は今も動く。ただし新規のプラットフォームには勧められていない。
紛らわしいので、分けて書く。
そもそも何を作ろうとしていたか
Stripe の決済失敗を検知して、お客さんに連絡してカードを更新してもらうツールを作ろうとしている。
使う側の事業者には、自分の Stripe アカウントを繋いでもらう必要がある。方式は 2 つあると思っていた。
制限付き API キーを発行してコピペしてもらうか、OAuth で「Stripe と接続」を押してもらうか。
後者のほうが圧倒的に楽だ。キーの発行も、Webhook の登録も、signing secret のコピペも要らない。利用者がやることはボタン 1 回になる。
だから OAuth で行くつもりだった。
2022 年に置き換わっていた
Connect 拡張機能を Stripe Apps に移行する にこうある。
Stripe Apps は、2022 年以降、Stripe を他のツールと連携するための推奨手段として Connect 拡張機能に取って代わりました。
新しい Connect 拡張機能は作成できなくなりました。旧 Connect 拡張機能に関する記載はすべて Stripe Partner Directory から削除されました。
2 文目のほうが効く。作れないだけでなく、既存のものも一覧から消されている。
私が読んでいた「Connect OAuth で繋ぐ」という記事群は、この移行より前のものだった。
素の OAuth は動く。ただし勧められていない
ここが紛らわしい。
https://connect.stripe.com/oauth/authorize は今も生きている。Connect OAuth リファレンス も残っている。ダッシュボードから client_id も発行できる。書けば動く。
拡張機能が作れなくなったことと、OAuth が動くことは、両立している。公式にもそう書いてある。
Extensions では、OAuth の動作に変更はありません。
(Standard アカウントでの OAuth の使用)
ただし同じページの冒頭に、もう一行ある。
新しい Connect プラットフォームには OAuth の使用は推奨されていません。
動く。でも新規には勧めていない。そしてそれで作ったものは Stripe App Marketplace にも Partner Directory にも載らない。
「作れる」「勧められている」「見つけてもらえる」が、全部別々の話だった。ドキュメントが消されずに残っているので、検索から入ると 1 つ目しか見えない。
Stripe App にしても、実装はほとんど変わらなかった
認可 URL を差し替えて、マニフェストを書く。それで済むだろうと思っていた。
connect.stripe.com/oauth/authorize ではなく、marketplace.stripe.com/oauth/v2/authorize を使う。アプリマニフェスト(stripe-app.json)に権限とリダイレクト先を書いて、stripe apps upload で上げる。
身構えていたのは、その先の認証だった。
Stripe App の OAuth は、アクセストークンの有効期限が 1 時間、リフレッシュトークンが 1 年で、交換のたびに更新される(OAuth 2.0)。素の Connect OAuth は stripe_user_id を保存して Stripe-Account ヘッダに乗せるだけなので、トークンの寿命を気にする場所が無い。載るのと引き換えに、繋いだ事業者ごとにリフレッシュトークンを暗号化して持つ運用が増えるのだと思った。
増えるかどうかは、自分で選べた。
マニフェストの stripe_api_access_type で決まる。
{
"stripe_api_access_type": "platform" | "oauth" | "restricted_api_key"
}
platform がデフォルトだ。サーバー側のロジックを追加する に、その中身が書いてある。
リクエストを認証するには、既存の加盟店アカウント API キーを使用して Stripe と対話し、ユーザーの
stripeAccountIdを指定します。
自分のシークレットキーに Stripe-Account ヘッダを足して叩く。素の Connect OAuth で「トークンの寿命を気にする場所が無い」と言っていた、あの形と同じだ。 移行ドキュメントにも書いてある。
ほとんどの旧 Connect 拡張機能では、
platformまたはoauthオプションを使用すると、最小限の変更で既存の Stripe 連携をそのまま置き換えることができます。
拍子抜けした。実装の話は、ここで終わってしまった。
ダッシュボード内の UI も要らなかった
ダッシュボード内の UI は必須ではない。 公開手順 にこうある。
アプリがデータ連携のみを行う場合 (ケイパビリティタイプ =
data_integration) で、UI を必要としない場合は、アプリ ドロワーコンテンツを含めないでください。代わりに、stripe-app.jsonファイルでui_extensionビューを空のままにします。
"ui_extension": []
公式が挙げている UI なしの実例は HubSpot だ。UI を作らずに載れる。
書くものが減っていく。
手が止まったのは、コードじゃなく掲載要件のほうだった
同じページで 3 つ引っかかった。「要件と制限」に 2 つと、リスティングの必須フィールドに 1 つ。
リスティングは英語のみ。 追加言語は問い合わせが必要。日本の事業者向けのツールを作っているのに、ストアの説明文は英語しか置けない。日本語で書いた LP の文言を、そのまま持っていくことができない。
公開できるアプリは 1 アカウントにつき 1 つ。
これが一番重い。
一人会社でプロダクトを 2 つ目、3 つ目と出していくつもりなら、いつか必ずぶつかる。しかもぶつかったときに直す場所が、コードの中に無い。Stripe のアカウントをどう分けるか、という話になる。 決済を受けているアカウントは、後から気軽に割れない。
stripe-app.json を書き換えれば済む話ではなかった。要件のページに 1 行あるだけだ。
料金は隠れた手数料なしで開示し、マーケット外の価格と一致させる。 これは歓迎だ。ストアに書いた額とサイトに書いた額が食い違うことがなくなる。
審査は提出から 4 営業日以内に、承認かフィードバックのメールが来る。落ちても詳細なフィードバックが来る。
コードを 1 行も書く前に気づけた
これを調べたとき、まだリポジトリを作っただけの状態だった。
もし先に作り始めていたら、動くものができてから「載らない」と分かることになる。認可 URL とマニフェストなら、書けば済む。1 アカウント 1 アプリは書いて済む場所が無い。
既に繋いだ利用者がいる状態で移行するなら、その全員に権限の再認証をお願いすることになる。移行そのものはサービスを止めずに済む、と公式は書いている。止まらないのは救いだが、お願いする相手がいる時点で、選べる幅は狭い。
手戻りがゼロで済んだのは、たまたま調べる順番が先だっただけだ。
いつもこの順番で調べているわけではない。今回は「作る前に決めることを決める」と先に宣言していたので、そのついでに掲載要件まで見に行った。それだけの理由だった。
公式ドキュメントは、更新されるより先に古い記事のほうが検索で上に出る。「〜で繋ぐ」系の記事を読んだら、その方式が今も推奨されているかを、公式で 1 回確かめたほうがいい。
churndown — Stripe の決済失敗を検知して、日本語で連絡し、カードの更新画面まで案内するツールです。まだコードはありません。
30 日後に、作るか作らないかを登録数で決めます。どちらに転んでも結果はこの連載に書きます。
この記事について
一人会社で SaaS を作りながら、経営の判断を Claude Code に手伝わせている記録の続きです。決済リカバリーのツールを作る(か、やめる)ところまでを書いています。
前: 【#17】「回収できたら 10%」の原価を、先に計算した
arecore.net の中の人です。受託開発・SES・自社プロダクト開発をやっています。ご相談・フィードバックは arecore.net からどうぞ。