Python で Stripe のログや Invoice 情報を収集する

この記事は [Stripe Advent Calendar 2018](https://adventar.org/calendars/3096) の12月7日のエントリーです。

Stripe を運用していて、一気にログを取得したい場合や次に来る定期支払いの Invoice をまとめて確認したい場合など、ダッシュボード経由だとなかなか思ったようにいかない事も多いかと思います。私は Python を使って処理してる事が多いのでその方法をまとめてみました。

# 準備
```
pip install stripe
```

Stripe の SDK をインストールします。

# API キーの取得
API リクエストでミスらないように、制限をかけた API キーを作成します。
Stripe のダッシュボードから作成可能です。「Restricted keys」というところで制限付きの API キーの作成をする事ができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125488/a4f73d84-08bc-f180-8726-4662e11c2f68.png)

LIVEキーを使ってゴリゴリやりすぎると事故った時に非常に怖いので、参照操作の場合は読み取りのみのアクセスをつけたキーで作業します。

# ログの一括取得（基本操作）
ログをまとめて取得する場合は、List all events を使うのが便利です。
https://stripe.com/docs/api/events/list

全体のコードはこんな感じになります。2018年11月のイベントを全て取得して、イベントのタイプを画面に表示する処理です。

``` get_log.py
import stripe
import datetime
import time

stripe.api_key = "rk_test_1xxxxxxxxxxxxxxxxxxxxxxx"

# 日付の文字列を Stripe API で使う UNIX タイムスタンプに変換する関数
def convert_to_time(formated_date):
    return int(time.mktime(datetime.datetime.strptime(formated_date, '%Y-%m-%d %H:%M:%S').timetuple()))

# 100件ずつリクエストして、次のデータがなくなるまで取得
starting_after = None
while True:
    result = stripe.Event.list(
        created = {
            'gte': convert_to_time('2018-11-1 00:00:00'),
            'lte': convert_to_time('2018-12-1 00:00:00')
        },
        starting_after=starting_after,
        limit=100
    )
    if len(result) == 0:
        break

    # 結果を出力
    for data in result['data']:
        starting_after = data['id']    # ここで Event の Object id を保持
        print(data['type'])

```

List event の API は1回のリクエストで取得できる上限件数が100件です。*starting_after* パラメータを指定してリクエストする事で、1件目に取得するデータを指定できます。データを表示するループの中で、Event の Object id を保持しておく事で、次のリクエストの時に続きからデータを取得する事ができるようになります。

他の Stripe の API も List 系のものは同じ考え方ですので、基本形としてマスターしておくと安心です。

イベントのタイプは公式ドキュメントに記載があります。
https://stripe.com/docs/api/events/types

全件のログを取得してみると、Stripe のデータ構造やイベントの発生する流れをより深く理解できるかと思います。


# ログの一括取得（応用形）
パラメータに type を指定する事で色々と絞り込みができます。

``` 成功したInvoice.py
    result = stripe.Event.list(
        created = {
            'gte': convert_to_time('2018-11-1 00:00:00'),
            'lte': convert_to_time('2018-11-10 00:00:00')
        },
        starting_after=starting_after,
        limit=100,
        type='invoice.payment_succeeded'
    )
```

``` Invoice関連.py
        type='invoice.payment*'
```

``` 顧客情報関連.py
        type='customer*'
```

このように、ワイルドカードも使えるので比較的柔軟に取得する事ができます。

# Invoice の集計
今後発生するInvoiceを確認して、集計したい場合は下記のようになります。直接 Upcoming の Invoice を List する方法が見つからなかったため、一度 Subscription のリストを取得して Customer 毎に取得しています。

``` amount_of_upcomming.py
count = 0
total = 0
while True:
    result = stripe.Subscription.list(
        starting_after=starting_after,
        limit=100
    )
    if len(result) == 0:
        break

    for data in result['data']:
        starting_after = data['id']
        invoices = stripe.Invoice.upcoming(
            customer=data['customer']
        )
        count = count + 1
        total = total + invoices['total']

print('人数: ' + str(count))
print('合計金額: ' + str(total))
```

# まとめ
Stripe では SDK を使うことで非常に簡単にデータを取得する事が可能となっています。既存のダッシュボードでも十分に強力な機能を持っていますが、独自のデータを集計したい場合にも、基本的なデータは全て API 経由で取得できます。

この辺りの柔軟さは開発者として非常にありがたいです。

# JP_Stripes 広島
JP_Stripes 広島は現在 Vol.3 まで開催済みです！登壇者が不足しているので、広島に来られる予定がある方、または在住の方で「喋っても良いよ！」という方はぜひご連絡をお待ちしております。