stripe-integration
StripeのPayment処理統合をマスターし、チェックアウト・サブスクリプション・Webhook・返金処理を含むPCIに準拠した堅牢な決済フローを構築します。
description の原文を見る
Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.
SKILL.md 本文
Stripe Integration
Stripe の決済処理統合をマスターし、チェックアウト、サブスクリプション、ウェブフック、返金を含む堅牢で PCI コンプライアント決済フローを実装します。
このスキルを使用しないケース
- タスクが Stripe 統合と無関係の場合
- このスコープ外の異なるドメインやツールが必要な場合
手順
- 目標、制約、必要なインプットを明確にする
- 関連するベストプラクティスを適用し、結果を検証する
- 実行可能なステップと検証方法を提供する
- 詳細な例が必要な場合は、
resources/implementation-playbook.mdを開く
このスキルを使用するケース
- ウェブ/モバイルアプリケーションに決済処理を実装する場合
- サブスクリプション課金システムを設定する場合
- ワンタイム決済と定期的な課金を処理する場合
- 返金と異議申し立てを処理する場合
- 顧客の決済方法を管理する場合
- ヨーロッパの決済に SCA (Strong Customer Authentication) を実装する場合
- Stripe Connect を使用したマーケットプレイス決済フローを構築する場合
コアコンセプト
1. 決済フロー
Checkout Session (ホスト型)
- Stripe がホストする決済ページ
- PCI コンプライアンス負担が最小限
- 最速の実装
- ワンタイム決済と定期決済をサポート
Payment Intents (カスタム UI)
- 決済 UI に完全なコントロール
- PCI コンプライアンスには Stripe.js が必要
- より複雑な実装
- より優れたカスタマイズオプション
Setup Intents (決済方法を保存)
- 課金なしで決済方法を収集
- サブスクリプションと将来の決済に使用
- 顧客の確認が必要
2. ウェブフック
重要なイベント:
payment_intent.succeeded: 決済完了payment_intent.payment_failed: 決済失敗customer.subscription.updated: サブスクリプション変更customer.subscription.deleted: サブスクリプションキャンセルcharge.refunded: 返金処理invoice.payment_succeeded: サブスクリプション決済成功
3. サブスクリプション
コンポーネント:
- Product: 販売する商品
- Price: 価格と頻度
- Subscription: 顧客の定期決済
- Invoice: 各請求サイクルで生成
4. 顧客管理
- 顧客レコードの作成と管理
- 複数の決済方法を保存
- 顧客メタデータの追跡
- 請求詳細の管理
クイックスタート
import stripe
stripe.api_key = "sk_test_..."
# チェックアウトセッションを作成
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': 'usd',
'product_data': {
'name': 'Premium Subscription',
},
'unit_amount': 2000, # $20.00
'recurring': {
'interval': 'month',
},
},
'quantity': 1,
}],
mode='subscription',
success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url='https://yourdomain.com/cancel',
)
# ユーザーを session.url にリダイレクト
print(session.url)
決済実装パターン
パターン 1: ワンタイム決済 (ホスト型チェックアウト)
def create_checkout_session(amount, currency='usd'):
"""ワンタイム決済チェックアウトセッションを作成します。"""
try:
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': currency,
'product_data': {
'name': 'Purchase',
'images': ['https://example.com/product.jpg'],
},
'unit_amount': amount, # セント単位の金額
},
'quantity': 1,
}],
mode='payment',
success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url='https://yourdomain.com/cancel',
metadata={
'order_id': 'order_123',
'user_id': 'user_456'
}
)
return session
except stripe.error.StripeError as e:
# エラーを処理
print(f"Stripe error: {e.user_message}")
raise
パターン 2: カスタム Payment Intent フロー
def create_payment_intent(amount, currency='usd', customer_id=None):
"""カスタムチェックアウト UI 用の payment intent を作成します。"""
intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
customer=customer_id,
automatic_payment_methods={
'enabled': True,
},
metadata={
'integration_check': 'accept_a_payment'
}
)
return intent.client_secret # フロントエンドに送信
# フロントエンド (JavaScript)
"""
const stripe = Stripe('pk_test_...');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
const {error, paymentIntent} = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: cardElement,
billing_details: {
name: 'Customer Name'
}
}
}
);
if (error) {
// エラーを処理
} else if (paymentIntent.status === 'succeeded') {
// 決済成功
}
"""
パターン 3: サブスクリプション作成
def create_subscription(customer_id, price_id):
"""顧客のサブスクリプションを作成します。"""
try:
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{'price': price_id}],
payment_behavior='default_incomplete',
payment_settings={'save_default_payment_method': 'on_subscription'},
expand=['latest_invoice.payment_intent'],
)
return {
'subscription_id': subscription.id,
'client_secret': subscription.latest_invoice.payment_intent.client_secret
}
except stripe.error.StripeError as e:
print(f"Subscription creation failed: {e}")
raise
パターン 4: カスタマーポータル
def create_customer_portal_session(customer_id):
"""顧客がサブスクリプションを管理するためのポータルセッションを作成します。"""
session = stripe.billing_portal.Session.create(
customer=customer_id,
return_url='https://yourdomain.com/account',
)
return session.url # ここに顧客をリダイレクト
ウェブフック処理
セキュアなウェブフックエンドポイント
from flask import Flask, request
import stripe
app = Flask(__name__)
endpoint_secret = 'whsec_...'
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.data
sig_header = request.headers.get('Stripe-Signature')
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError:
# 無効なペイロード
return 'Invalid payload', 400
except stripe.error.SignatureVerificationError:
# 無効な署名
return 'Invalid signature', 400
# イベントを処理
if event['type'] == 'payment_intent.succeeded':
payment_intent = event['data']['object']
handle_successful_payment(payment_intent)
elif event['type'] == 'payment_intent.payment_failed':
payment_intent = event['data']['object']
handle_failed_payment(payment_intent)
elif event['type'] == 'customer.subscription.deleted':
subscription = event['data']['object']
handle_subscription_canceled(subscription)
return 'Success', 200
def handle_successful_payment(payment_intent):
"""成功した決済を処理します。"""
customer_id = payment_intent.get('customer')
amount = payment_intent['amount']
metadata = payment_intent.get('metadata', {})
# データベースを更新
# 確認メールを送信
# 注文を処理
print(f"Payment succeeded: {payment_intent['id']}")
def handle_failed_payment(payment_intent):
"""失敗した決済を処理します。"""
error = payment_intent.get('last_payment_error', {})
print(f"Payment failed: {error.get('message')}")
# 顧客に通知
# 注文ステータスを更新
def handle_subscription_canceled(subscription):
"""サブスクリプションキャンセルを処理します。"""
customer_id = subscription['customer']
# ユーザーアクセスを更新
# キャンセルメールを送信
print(f"Subscription canceled: {subscription['id']}")
ウェブフックベストプラクティス
import hashlib
import hmac
def verify_webhook_signature(payload, signature, secret):
"""ウェブフック署名を手動で検証します。"""
expected_sig = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_sig)
def handle_webhook_idempotently(event_id, handler):
"""ウェブフックが正確に 1 回処理されるようにします。"""
# イベントが既に処理されているかチェック
if is_event_processed(event_id):
return
# イベントを処理
try:
handler()
mark_event_processed(event_id)
except Exception as e:
log_error(e)
# Stripe は失敗したウェブフックを再試行します
raise
顧客管理
def create_customer(email, name, payment_method_id=None):
"""Stripe 顧客を作成します。"""
customer = stripe.Customer.create(
email=email,
name=name,
payment_method=payment_method_id,
invoice_settings={
'default_payment_method': payment_method_id
} if payment_method_id else None,
metadata={
'user_id': '12345'
}
)
return customer
def attach_payment_method(customer_id, payment_method_id):
"""決済方法を顧客にアタッチします。"""
stripe.PaymentMethod.attach(
payment_method_id,
customer=customer_id
)
# デフォルトに設定
stripe.Customer.modify(
customer_id,
invoice_settings={
'default_payment_method': payment_method_id
}
)
def list_customer_payment_methods(customer_id):
"""顧客のすべての決済方法をリストします。"""
payment_methods = stripe.PaymentMethod.list(
customer=customer_id,
type='card'
)
return payment_methods.data
返金処理
def create_refund(payment_intent_id, amount=None, reason=None):
"""返金を作成します。"""
refund_params = {
'payment_intent': payment_intent_id
}
if amount:
refund_params['amount'] = amount # 部分返金
if reason:
refund_params['reason'] = reason # 'duplicate', 'fraudulent', 'requested_by_customer'
refund = stripe.Refund.create(**refund_params)
return refund
def handle_dispute(charge_id, evidence):
"""異議申し立てを証拠で更新します。"""
stripe.Dispute.modify(
charge_id,
evidence={
'customer_name': evidence.get('customer_name'),
'customer_email_address': evidence.get('customer_email'),
'shipping_documentation': evidence.get('shipping_proof'),
'customer_communication': evidence.get('communication'),
}
)
テスト
# テストモードキーを使用
stripe.api_key = "sk_test_..."
# テストカード番号
TEST_CARDS = {
'success': '4242424242424242',
'declined': '4000000000000002',
'3d_secure': '4000002500003155',
'insufficient_funds': '4000000000009995'
}
def test_payment_flow():
"""完全な決済フローをテストします。"""
# テスト顧客を作成
customer = stripe.Customer.create(
email="test@example.com"
)
# payment intent を作成
intent = stripe.PaymentIntent.create(
amount=1000,
currency='usd',
customer=customer.id,
payment_method_types=['card']
)
# テストカードで確認
confirmed = stripe.PaymentIntent.confirm(
intent.id,
payment_method='pm_card_visa' # テスト決済方法
)
assert confirmed.status == 'succeeded'
リソース
- references/checkout-flows.md: 詳細なチェックアウト実装
- references/webhook-handling.md: ウェブフックセキュリティと処理
- references/subscription-management.md: サブスクリプションライフサイクル
- references/customer-management.md: 顧客と決済方法の処理
- references/invoice-generation.md: 請求書生成と課金
- assets/stripe-client.py: 本番環境対応 Stripe クライアントラッパー
- assets/webhook-handler.py: 完全なウェブフックプロセッサ
- assets/checkout-config.json: チェックアウト設定テンプレート
ベストプラクティス
- 常にウェブフックを使用: クライアント側の確認のみに依存しない
- べき等性: ウェブフックイベントをべき等に処理する
- エラーハンドリング: すべての Stripe エラーを適切に処理する
- テストモード: 本番環境に移行する前にテストキーで十分にテストする
- メタデータ: メタデータを使用して Stripe オブジェクトをデータベースにリンク
- 監視: 決済成功率とエラーを追跡する
- PCI コンプライアンス: サーバー上で生のカードデータを処理しない
- SCA 対応: ヨーロッパの決済に 3D Secure を実装する
よくある落とし穴
- ウェブフック検証なし: 常にウェブフック署名を検証する
- ウェブフックイベントの欠落: すべての関連ウェブフックイベントを処理する
- ハードコードされた金額: セント/最小通貨単位を使用する
- 再試行ロジックなし: API 呼び出しに再試行を実装する
- テストモードを無視: テストカードですべてのエッジケースをテストする
制限事項
- このスキルは、上記で説明されているスコープに明確に一致するタスクでのみ使用してください。
- 出力を環境固有の検証、テスト、または専門家のレビューの代替として扱わないでください。
- 必要なインプット、権限、安全境界、または成功基準が不明な場合は、停止して明確化を求めてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- sickn33
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。