[保存版] Stripe APIチートシート

Stripe APIのチートシート(python)

#### **初期設定**
```python
import stripe
stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"  # 秘密キーを設定
```

#### **顧客(Customer)**
- **顧客を作成**
```python
customer = stripe.Customer.create(
  email="customer@example.com",
  description="My First Test Customer"
)
```
- **顧客情報を取得**
```python
customer = stripe.Customer.retrieve("cus_XXXXX")
```
- **顧客情報を更新**
```python
customer = stripe.Customer.modify(
  "cus_XXXXX",
  email="newemail@example.com"
)
```

#### **支払い方法(Payment Methods)**
- **カードの支払い方法を作成**
```python
payment_method = stripe.PaymentMethod.create(
  type="card",
  card={
    "number": "4242424242424242",
    "exp_month": 12,
    "exp_year": 2023,
    "cvc": "123"
  }
)
```
- **支払い方法を顧客に添付**
```python
payment_method_attached = stripe.PaymentMethod.attach(
  "pm_1FkUxe2eZvKYlo2C0JAaEdWV",
  customer="cus_XXXXX"
)
```

#### **チャージ(Charges)**
- **支払いを作成**
```python
charge = stripe.Charge.create(
  amount=2000,  # セント単位での金額
  currency="usd",
  source="tok_amex",  # トークンまたは支払い方法
  description="My First Test Charge"
)
```
- **支払いを取得**
```python
charge = stripe.Charge.retrieve("ch_XXXXX")
```

#### **請求書(Invoices)**
- **請求書を作成**
```python
invoice = stripe.Invoice.create(
  customer="cus_XXXXX",
  auto_advance=True  # 自動的に決済を試みる
)
```
- **請求書を決済**
```python
invoice = stripe.Invoice.pay("in_XXXXX")
```

#### **サブスクリプション(Subscription)**
- **サブスクリプションを作成**
```python
subscription = stripe.Subscription.create(
  customer="cus_XXXXX",
  items=[{"plan": "plan_XXXXX"}]
)
```
- **サブスクリプションを取得**
```python
subscription = stripe.Subscription.retrieve("sub_XXXXX")
```
- **サブスクリプションをキャンセル**
```python
subscription = stripe.Subscription.delete("sub_XXXXX")
```

#### **プラン(Plans)**
- **プランを作成**
```python
plan = stripe.Plan.create(
  amount=2000,
  currency="usd",
  interval="month",  # 課金周期
  product={"name": "Gold special"},  # プラン名
)
```

#### **イベント(Events)**
- **イベントを取得**
```python
event = stripe.Event.retrieve("evt_XXXXX")
```

#### **Connectアカウント**
- **アカウントを作成（Connect用）**
```python
account = stripe.Account.create(
  type="standard"
)
```

#### **支払いを処理**
- **顧客と支払い方法を使用して支払いを処理**
```python
payment_intent = stripe.PaymentIntent.create(
  amount=2000,
  currency='usd',
  customer='cus_XXXXX',
  payment_method='pm_XXXXX',
  off_session=True,
  confirm=True,
)
```

#### **支払い確認(Payment Intent)**
- **支払いインテントの確認**
```python
# PaymentIntentを前もって作成しておき、フロントエンドでカード情報を入力後、確認します
payment_intent = stripe.PaymentIntent.confirm(
    "pi_XXXXX",
    payment_method="pm_XXXXX"  # フロントエンドから送られたpayment_method ID
)
```

#### **リファンド(Refunds)**
- **支払いを返金**
```python
refund = stripe.Refund.create(
  charge="ch_XXXXX"
)
```

#### **支払い方法の検証(Payment Method Verification)**
- **銀行口座の検証**
```python
# 銀行口座支払い方法の場合は、検証手続きが必要な場合があります
stripe.PaymentMethod.verify(
    "pm_XXXXX",
    amounts=[32, 45]
)
```

#### **製品(Products)**
- **製品を作成**
```python
product = stripe.Product.create(
  name="Gold special",
  type="service"
)
```

#### **価格(Prices)**
- **価格を作成**
```python
price = stripe.Price.create(
  unit_amount=2000,
  currency="usd",
  recurring={"interval": "month"},
  product="prod_XXXXX"
)
```

#### **Webhooks**

```python
# これはWebhookエンドポイントの一例で、Flaskなどのウェブフレームワークで実装します。
# /webhookエンドポイントにPOSTリクエストとして送られたイベントを処理します。

from flask import Flask, request
import json

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def stripe_webhook():
    payload = request.get_data(as_text=True)
    sig_header = request.headers.get('Stripe-Signature')

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, webhook_secret
        )

    except ValueError as e:
        # 不正なペイロード
        return 'Invalid payload', 400
    except stripe.error.SignatureVerificationError as e:
        # 署名の検証エラー
        return 'Invalid signature', 400

    # イベントタイプに応じた処理
    if event['type'] == 'payment_intent.succeeded':
        payment_intent = event['data']['object']  # 支払い情報
        handle_payment_intent_succeeded(payment_intent)

    # 他のイベントタイプも同様に処理を追加

    return 'Success', 200

def handle_payment_intent_succeeded(payment_intent):
    # 支払い成功時の処理を実装
    pass

if __name__ == '__main__':
    app.run()
```

Webhookを扱う際は、Stripeから送られてくるリクエストが実際にStripeからのものであることを確認するために、署名を検証する必要があります。上記のコードには、その署名を検証する処理が含まれています。

これらのコードスニペットはStripe APIの基本的な利用方法を提供しており、実際のプロジェクトでは、適切なエラーハンドリングやセキュリティ対策を強化するための追加的なコードが必要になります。

#### エラーハンドリング
Stripe APIのリクエストは、さまざまな理由で失敗することがあります。以下にPythonでのエラーハンドリングの例を示します。

```python
try:
    # Stripe APIの呼び出し
    charge = stripe.Charge.create(
        amount=2000,
        currency="usd",
        source="tok_amex",
        description="My First Test Charge"
    )
except stripe.error.CardError as e:
    # カードエラー（不正なカード番号など）
    body = e.json_body
    err  = body.get('error', {})
    print(f"Status is: {e.http_status}")
    print(f"Type is: {err.get('type')}")
    print(f"Code is: {err.get('code')}")
    # エラーメッセージを表示
    print(f"Message is: {err.get('message')}")
except stripe.error.RateLimitError as e:
    # APIへのリクエストが多すぎるとき
    pass
except stripe.error.InvalidRequestError as e:
    # リクエストが不正（URLが間違っている、パラメータが欠けている等）
    pass
except stripe.error.AuthenticationError as e:
    # 認証に失敗した（APIキーが間違っている等）
    pass
except stripe.error.APIConnectionError as e:
    # ネットワーク通信エラー
    pass
except stripe.error.StripeError as e:
    # StripeのAPIエラー
    pass
except Exception as e:
    # その他のエラー
    print(f"An error occurred: {str(e)}")
```

エラーハンドリングは、APIリクエストが予期せぬ理由で失敗した場合にアプリケーションが適切に対応できるようにするために不可欠です。

#### セキュリティ対策
- Stripe APIキーなどの秘密情報は環境変数や秘密管理システムを使って管理します。
- HTTPSを使ってデータを暗号化し、通信の安全を確保します。
- リクエストの署名を検証して、WebhookがStripeから送られたものであることを確認します。