あなたが求めるStripeの体験
本文の状態
日本語全文を表示中
詳細モードで約15分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
Answer.AI
著者は既存のStripe SDKの開発者体験に不満を抱き、FastStripeを開発した。これはStripeのOpenAPI仕様を活用し、IDEとの統合やパラメータの自動補完、明確なドキュメントストリングを提供することで、よりクリーンで整理されたAPI利用を実現する。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
TL;DR
tldr: Stripe SDK で得ていた開発者体験に不満を感じ、より良いものとして FastStripe を作成しました。FastStripe は Stripe が公開した素晴らしい OpenAPI 仕様を活用して Stripe API の全機能をサポートしつつ、コードをよりクリーンにし、整理整頓を行い、IDE との統合も優れているため、パラメータの入力時に快適な補完機能を利用できます。また、関数の役割や各パラメータの意味を説明する明確なドキュストリング(docstrings)が用意されています。さらにヘルパー関数も追加されており、ワンタイム決済の実行は公式 SDK では約 25 行かかるものが FastStripe ではわずか 6 行で完了します。同様に、定期購読のセットアップについても、公式 SDK では約 25 行必要ですが、FastStripe では 9 行で実現可能です。
現在、すでに公開されており、ほぼ 1 ヶ月間にわたり弊社の内部アプリケーションを問題なく稼働させています。その間、複雑さを大幅に削減し続けてきました。使用を開始するには、pip install faststripe を実行し、最初のワンタイム決済リンクを作成するだけです:
from faststripe.core import StripeApi
sapi = StripeApi('your-key-here')
checkout = sapi.one_time_payment(product_name='Digital Course', amount_cents=49_99,
success_url='http://localhost:5001/success',
cancel_url='http://localhost:5001/cancel')
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1gQnoO5ezm5yFB47GZNWO6I...
私たちはまた、Stripe API の新しいバージョンごとに FastStripe を継続的に更新しています。
あなたがふさわしい Stripe エクスペリエンス
これが聞き慣れた話だと感じたら私を止めてください:人々のお金を集めたい、そしてそれを非常に簡単に実行できることを確認したい。まるで赤ん坊からキャンディを奪うように簡単です。もちろん、そのお金との交換として、その人が喜んでお金を支払ってくれるサービスや製品を提供したいと願うでしょう。これは以前は悪夢のようなものでしたし、一部の企業にとっては今でも悪夢のように感じられるかもしれません(咳、咳、Google)

Stripe はこのプロセスを非常に簡単にすると主張していますが、正直に言って、過去 8 ヶ月間に彼らの SDK(Software Development Kit:ソフトウェア開発キット)を使用しようとしたのは苦難の道でした。そしてそれは長い旅でした。あまりにも長く、またでこぼこしていたので、私はすぐにこれが実用にならないと悟りました。私が何を意味しているかをお見せしましょう。支払いを受け入れる典型的なプロセスは次のようになります。
import stripe
ステップ 0: Stripe API キーの設定
stripe.api_key = 'your-api-key'
ステップ 1: プロダクトの作成(パラメータを忘れないでください)
product = stripe.Product.create(name='Digital Course')
ステップ 2: プライスの作成(この関数にはどのようなパラメータが必要だったか?)
price = stripe.Price.create(product=product.id, unit_amount=4999, # 待て、これはセント単位ですかドル単位ですか?
currency='usd')
ステップ3:チェックアウトセッションの作成(ドキュメントを漁る時間)
checkout = stripe.checkout.Session.create(mode='payment', # 他のモードは何がある?
line_items=[{'price': price.id, 'quantity': 1}],
success_url='http://localhost:5001/success',
cancel_url='http://localhost:5001/cancel')
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a100gzzSnVxiOBse34iThOdq...
シンプルそうでしょう?そうです、パラメータが何であるかを知っていれば。しかし、もし私がこれらの記憶を全く持っていない奇妙な人物なら、ドキュメントストリングや実装の詳細を読むためにソースコードを確認しに行く必要があります。よし、それを実行しましょう!チェックアウトセッションを作成するための実際のソースコードは以下の通りです:
@classmethod
def create(cls, **params: Unpack["Session.CreateParams"]) -> "Session":
"""
チェックアウトセッションオブジェクトを作成します。
"""
return cast(
"Session",
cls._static_request(
"post",
cls.class_url(),
params=params,
),
)
まあひどい…支払い処理をアプリに統合するタイミングになると、この瞬間が何度も何度も繰り返されました。私がたどり着いた唯一の解決策は、彼らのウェブサイトに行って実際の API リファレンスドキュメントを確認することでした。もし興味があれば、これらのドキュメントがどのようなものかをご紹介します:

そのようなドキュメントは、私の目を潤ませるほど美しいものです。ご自身でもご覧になりたい場合は、以下のリンクからアクセスできます。また、他のドキュメントもすべて紹介していますので、非常に書き込まれており、強くお勧めします。
しかし、これらのドキュメントへの頻繁なアクセスは、多くのコンテキストスイッチングを引き起こしました。これは開発者にとって最悪の敵であり、Stripe が開発者に提供するさまざまな方法や機能を探索する際にも、必ずしも優れた体験とは言えません。
私のチームメイトが、支払い機能を持つアプリをリリースしたいたびにこの経験をしなければならないとは思いたくありません。また、あなた、読者の皆様も、そうしてほしくありません。それは楽しいものではありません。数分で終わるはずの作業が、午後の時間を無駄にしてしまうのです。そこで私は、以前同僚だったアイザック(Answer 社の here に所属)が好んで呼ぶ「怒り駆動型開発(Rage-Driven Development: RDD)」を実装し、FastStripe を構築することを決意しました。それは、あなたが本当に受け取るべき Stripe の体験です。
FastStripe
上記の機能を FastStripe で実装するとどうなるか見てみましょう:
from faststripe.core import StripeApi
sapi = StripeApi('your-key-here')
checkout = sapi.one_time_payment(product_name='Digital Course', amount_cents=49_99,
success_url='http://localhost:5001/success',
cancel_url='http://localhost:5001/cancel')
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1u6skiy313rnW2pWwcPhqK5...
単一のメソッド呼び出しにより、内部では製品の作成または既存の製品の検索が行われ、価格の設定とデフォルト値を適切に設定したチェックアウトセッションが作成されます。さらに、より多くの制御権限を望む場合は、FastStripe によってフル機能の Stripe API にアクセス可能となり、おそらく今後一切使用することのないような特殊な API も利用できます(ちなみに、Stripe には気候変動対策製品専用の API が存在するってご存知ですか?このプロジェクトに取り組むまで私は知らなかったのですが、脳のその部分を何か有益な情報で埋めたいと強く願っています。しかし残念ながら…)。また、適切な IDE サポートも追加されているため、美しいタブ補完機能を利用できます。各パラメータを説明するドキュストリング(docstrings)も用意されており、より長く快適な開発環境で作業を進めることができます:
def one_time_payment(
self:StripeApi, product_name, amount_cents,
success_url, cancel_url, currency='usd', quantity=1, **kw):
'Create a simple one-time payment checkout'
_, price = self.priced_product(product_name, amount_cents, currency)
return self.checkout.sessions_post(
mode='payment', line_items=[dict(price=price.id, quantity=quantity)],
automatic_tax={'enabled': True}, success_url=success_url, cancel_url=cancel_url, **kw)
うさぎの穴へと潜る
もしあなたがまだここにおられるなら、あなたはレッドピル(真実の薬)を飲み、私が導く FastStripe の構築プロセスといううさぎの穴へとついてきてくれたと仮定します。では始めましょう!
これがすべてを可能にした要因について話しましょう。Stripe は、魂に祝福され、彼らの API 全体のための本当に美しい OpenAPI スペックを公開しました。さて、もしあなたが OpenAPI スペックに詳しくないなら、それは API と対話する方法の青写真のようなものです。これはすべてのエンドポイント、すべてのパラメータ、そして何をするものかや何を提供すべきかを説明する、それなりに人間に優しい記述までを含んでいます。そして Stripe のものは特に徹底しています。
さらに素晴らしいのは、これらのスペックが JSON または YAML で書かれているため、非常に簡単に解析できることです。数年前、私の CEO であるジェレミー・ハワードとハメル・フサインは、GitHub API 用の動的に Python SDK を生成するためにこれを行いました。それが ghapi です。
ghapi は GitHub API の全体を 100% 常に最新の状態に保ちます。OpenAPI スペックを Python 的な API に自動的に変換するため、ghapi は GitHub API の最新の変更点と常に同期されています。さらに、これがすべて動的に行われるため、パッケージ全体のサイズはわずか 35kB です!
そして私は考えました、もし私が Stripe に対して同じことができるなら、どんなに素晴らしい世界だろうかと。カーテンの裏側にあるコードについて少し注目しましょう。FastStripe はまず、Stripe の OpenAPI スペックのスナップショットを取得し、エンドポイント用の Python ファイルを作成することから始まります。このファイルは、そのスペックをよりクリーンな形式に変換します。この形式は、API へのパス、使用する HTTP メソッド(HTTP verb)、要約(これはドキュストリングの作成に使用されます)、そしてこのパスに関連するパラメータを表しています:
2025.05.28 バージョンの Stripe OpenAPI スペックから生成
eps = [
{
'path': '/v1/customers',
'verb': 'post',
'summary': '顧客を作成する',
'params': [
{'name': 'email', 'description': "顧客のメールアドレス"},
{'name': 'name', 'description': "顧客の氏名"},
# ... 20 以上の説明付きパラメータが続きます
]
},
# ... さらに数百のエンドポイントが続きます
]
次に、これらのエンドポイント記述を取得し、クラスの実行可能メソッド(__call__)のシグネチャとドキュストリングをオーバーライドする Python クラスを自動的に生成します。これにより、IDE 内で快適なタブ補完が可能になり、各パラメータや各エンドポイントが何を行うものか、また各パラメータが何を表すかを容易に確認できます。GhApi と同様に、Jupyter 環境で sapi.checkout のようなコマンドを実行すると、チェックアウトリソース下で実行可能なすべての操作が表示されます:
sapi.checkout
- checkout.sessions_get(created: 'str', customer: 'str', customer_details: 'str', ending_before: 'str', expand: 'str', limit: 'str', payment_intent: 'str', payment_link: 'str', starting_after: 'str', status: 'str', subscription: 'str'): すべてのチェックアウトセッションを一覧表示
- checkout.sessions_session_get(session, expand: 'str'): チェックアウトセッションを取得
- checkout.sessions_session_post(session, collected_information: dict = None, expand: list = None, metadata: object = None, shipping_options: object = None): チェックアウトセッションを更新
...
または、ルート sapi クラスに対して同じ操作を行うことで、すべてのリソースを検索することもできます:
sapi
- account
- accounts
- apple
- application
- apps
...
これにより、無数の API ドキュメントページを読み込むよりもはるかに簡単に Stripe API を探索できるようになります。
バージョン管理
FastStripe は、安定性と互換性を確保するために、Stripe の月次 API バージニングに従います。エンドポイントの変更時に既存のコードを壊す可能性がある最新のバージョンを自動的に使用するのではなく、FastStripe のリリースを特定の Stripe API バージョンに固定しています。例えば、FastStripe バージョン 2025.06.30.0 は、2025 年 6 月 30 日時点の Stripe API バージョンに対応しています。sapi.one_time_payment() のような新しい高レベルの利便性メソッドを追加した際に最終数字が増加しますが、最初の 3 つの数字は常に Stripe の API バージョンと一致します。
ヘルパー関数
でも、待ってください!さらにあります!FastStripe は OpenAPI 仕様の素晴らしさのおかげで、Stripe API の全体をサポートしています。ただし、より一般的な成功シナリオを合理化するために、いくつかのヘルパー関数も追加しています。sapi.one_time_payment() がその一例です。実は、イントロダクションでバニラ Stripe と FastStripe のコードの違いを示した際に、少し嘘をついてしまいました。より正確な Stripe 版は以下のようになります。
ステップ 1: プロダクトの作成または検索
products = stripe.Product.list(limit=100)
product = next((p for p in products if p.name == 'Digital Course'), None)
if not product:
product = stripe.Product.create(name='Digital Course')
100 件を超えるプロダクトがある場合のページネーション処理
pass
ステップ 2: プライスの作成または検索
prices = stripe.Price.list(product=product.id, limit=100)
price = next((p for p in prices if p.unit_amount == 4999), None)
if not price:
price = stripe.Price.create(
product=product.id,
unit_amount=4999,
currency='usd'
)
より詳細なページネーション処理
ステップ 3: チェックアウトセッションの作成
checkout = stripe.checkout.Session.create(
mode='payment',
line_items=[{'price': price.id, 'quantity': 1}],
success_url='http://localhost:5001/success',
cancel_url='http://localhost:5001/cancel'
)
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1y7FuflPm1o3jzOojiGpMHy...
FastStripe のバージョンは、バニラ版の Stripe が約 25 行(コメントを除く)のコードを要するのに対し、わずか 6 行のコードで同じことを実現しました。内部では、FastStripe が提供する priced_product や find_product などの他のヘルパー関数を使用して、ワンタイム支払い用の製品と関連価格を自動的に検索または作成します。サブスクリプションについても同様のヘルパー関数が用意されています:
checkout = sapi.subscription(
product_name='Pro Plan', amount_cents=19_99,
success_url='http://localhost:5001/welcome',
cancel_url='http://localhost:5001/pricing',
customer_email='joe@example.com'
)
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1r4kjOWpmM2OKicG7dF5t1e...
これもまた、FastStripe では 9 行で済むところを、バニラ版では約 25 行のコードが必要だったものです。
ページネーション
多くの REST API と同様に、Stripe アカウント下に作成した製品などのリソースを取得するには、ページネーション(Pagination)に対応する必要があります。Stripe の API は、1 つのリクエストごとに返される結果数を制限しており(例:10 件、25 件、100 件)、これは limit パラメータによって制御されます。実際には結果数がこれを超えることが多いため、次のデータチャンクを取得するために、starting_after や ending_before といったページネーションパラメータを使用して複数のリクエストを行う必要があります。
バニラの Stripe SDK は、これをカーソルベースのページネーションシステムとして公開しています。実際には、すべての製品、顧客、または請求書を取得したい場合、結果を手動でループして繰り返しリクエストを行う必要があります。
products = []
starting_after = None
while True:
resp = stripe.Product.list(limit=100, starting_after=starting_after)
products.extend(resp.data)
if not resp.has_more:
break
starting_after = resp.data[-1].id
break
len(products), products[0].keys()
(100,
dict_keys(['id', 'object', 'active', 'attributes', 'created', 'default_price', 'description', 'images', 'livemode', 'marketing_features', 'metadata', 'name', 'package_dimensions', 'shippable', 'statement_descriptor', 'tax_code', 'type', 'unit_label', 'updated', 'url']))
FastStripe は、すべての結果を自動的に取得するための簡単な方法を提供します。ghapi と同様に、FastStripe には paged 関数があり、これにより任意の Stripe ページネーションエンドポイントを、反復処理可能な Python ジェネレーターに変換します。
from faststripe.page import *
for p in paged(sapi.customers.get, limit=2):
print(len(p.data), p.data[0].keys())
break
2 dict_keys(['id', 'object', 'address', 'balance', 'created', 'currency', 'default_source', 'delinquent', 'description', 'discount', 'email', 'invoice_prefix', 'invoice_settings', 'livemode', 'metadata', 'name', 'next_invoice_sequence', 'phone', 'preferred_locales', 'shipping', 'tax_exempt', 'test_clock'])
また、ページ化されたデータも扱えるようになっています。これにより、すべてのページのアイテムをリスト形式で取得できます:
prods = pages(sapi.products.get, limit=100)
len(prods), prods[0].keys()
(658,
dict_keys(['id', 'object', 'active', 'attributes', 'created', 'default_price', 'description', 'images', 'livemode', 'marketing_features', 'metadata', 'name', 'package_dimensions', 'shippable', 'statement_descriptor', 'tax_code', 'type', 'unit_label', 'updated', 'url']))
FastStripe の始め方
もし、これまでの説明が興味深く、実際に試してみたいとお考えなら、以下の手順に従ってください。
- Stripe のセットアップ
Stripe アカウントを作成する
Stripe ダッシュボードにアクセスする
API キーセクションから「Secret key」を取得してください(開発用にはテストキーを使用してください)
- FastStripe のセットアップ
pip install faststripe
API を初期化します:
from faststripe.core import StripeApi
sapi = StripeApi('your-key-here')
チェックアウトセッションを作成します(ワンタイム決済の場合):
checkout = sapi.one_time_payment(product_name='Digital Course', amount_cents=49_99,
success_url='http://localhost:5001/success',
cancel_url='http://localhost:5001/cancel')
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1PxMDnqAbBYoqeNgdYyVxST...
または、サブスクリプションの場合:
checkout = sapi.subscription(
product_name='Pro Plan', amount_cents=19_99,
success_url='http://localhost:5001/welcome',
cancel_url='http://localhost:5001/pricing',
customer_email='joe@example.com'
)
print(checkout.url[:64] + "...")
https://billing.answer.ai/c/pay/cs_test_a1oTHsHFpEdQWIwHVb5Ghav0...
次のステップ
より多くの例については、完全なドキュメントをご覧ください。
機能のリクエストや問題の報告については、GitHub でのディスカッションに参加してください。
FastStripe はオープンソースであり、皆様のフィードバックを心から歓迎します。1 つのアプリを開発している方でも、1000 のアプリを構築している方でも、Stripe の統合が可能な限りスムーズになるよう努めています。
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み