python Djangoでstripe connectのテストをしてみた。

# はじめに
カスタマーが商品を登録し、ユーザが商品を買うという構成のプラットフォームでは、ユーザが商品を購入したとき、クレジットカードで支払い、その支払に対して、手数料を引いた金額をカスタマーの銀行口座へ入金するパターンがあると思います。（ありますよね??）

このようなとき、stripe connectを用い、カスタマーを管理することで、実現できます。
今回は、stripe connect による支払い、入金のフローテストを python + Djangoで実装したので、紹介したいと思います。

git: [Washington-Ksea/django-stripe-connect](https://github.com/Washington-Ksea/django-stripe-connect)

※　ほとんど、ドキュメントを参考にし、プログラムを他の人に確認してもらったわけではないので、参考程度でお願いいたします。

# stripe connectの基礎

stripe connect の基礎に関しては、以下の記事を参照してください。
stripeへの登録等の方法も書いてあります。
本記事では、pythonでどのようにして、実装できるかということに着目しています。

+ [Stripe初心者のための基本的な使い方（Rails編）](https://qiita.com/ryouzi/items/6ee8f277471aa3b02f7b)
+ [Stripe Connect 101](https://qiita.com/y_toku/items/7bfa42793801dfc5415d)
+ [stripe api](https://stripe.com/docs/api)

# python djangoの基礎

以下の本を参考にしてください。
だいたいの基礎は、この本と、Qiita記事等で、カバーできると思います。

+ [現場で使える Django の教科書《基礎編》&《実践編》【紙の本】2冊セット（技術書典6バージョン）](https://booth.pm/ja/items/1059917)

# 導入

stripeをpipでインストール

```python
pip install stripe
```
※その他、導入に必要な事項は、djangoの基礎的な部分なので、上記の本などを参考にしてください。

# テストフロー

基本的なフローを、djangoのview.pyに書きました。

STRIPE_SECRET_KEYは、setting.pyに設定した、秘密鍵です。
　※git等にアップロードする際は、.envファイルに書き、django-environ等のパッケジージで読み込みます。

今回のフローでは、
1. Customアカウントの作成
2. アカウント情報の更新
3. 銀行口座の登録
4. 本人証明
5. ユーザからの支払い

1〜4は、カスタマーによる商品登録時に登録すべき処理です。
5はユーザによる支払い処理です。

2に記載されている、CONNECTED_STRIPE_ACCOUNT_ID = "acct_1F6KiGB3268k39y4"は、1のアカウント作成により、作成されるので、まず、1のみを行って取得してください。

```python:view.py

from django.shortcuts import render
from django.views.generic import TemplateView

from config.settings import STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, BASE_DIR

import stripe
import time
import os

stripe.api_key = STRIPE_SECRET_KEY

...

class ShopView(TemplateView):
    template_name='home.html'

    def get_context_data(self, **kwargs):
        context = super(ShopView, self).get_context_data(**kwargs)
        
        #https://stripe.com/docs/api/errors/handling #エラーハンドリング(今回は実装していません。)

        ####################################
        # 1. Customアカウント作成
        ####################################

        account = create_custom_account()
       
        ####################################
        # 2. アカウント情報の更新
        ####################################
    
        CONNECTED_STRIPE_ACCOUNT_ID = "acct_1F6KiGB3268k39y4"
        
        update_custom_account(CONNECTED_STRIPE_ACCOUNT_ID)
        
        ####################################
        # 3. 銀行口座の登録
        ####################################

        create_bank_account(CONNECTED_STRIPE_ACCOUNT_ID)
        update_payouts_schedule(CONNECTED_STRIPE_ACCOUNT_ID)

        ####################################
        # 4. 本人証明
        ####################################
        
        image_path = os.path.join(BASE_DIR, "static", "identify.png")
        
        upload_identity_verification_file(CONNECTED_STRIPE_ACCOUNT_ID, image_path)

        ####################################
        # 5. 支払い
        ####################################

        charge_user(CONNECTED_STRIPE_ACCOUNT_ID, 5000, 500)

        return context
    
```

# 1. Customアカウントの作成

以下のプログラムでアカウントを作成します。
account内には、今後、情報登録等に使用するid(以下、acct_id)情報が入っています。

また、安全性のため、トークンの発行が追加で必要で、以下に参考にしてください。
token-account: https://stripe.com/docs/connect/account-tokens

```python
def create_custom_account():    
    account = stripe.Account.create(
        type="custom",
        country="JP",
        email="test@test.com", #user email
        business_type="individual",
    )
    return account
```

# 2. アカウント情報の更新

プラットフォームから銀行口座に入金するために必要な情報をaccount情報に付加します。
上記に上げたqiitaの記事の内容では、登録できない部分もあったので、登録する情報のフォーマットはドキュメントや実際に出力して確認してみてください。
また、プログラム内で書く変数に格納した情報は、テスト用に準備されたものを格納しています。
（この内容で、実際に入金処理が行われることは確認しました。）




```python
def get_custom_account(acct_id):
    account = stripe.Account.retrieve(acct_id)
    return account

def update_custom_account(acct_id):
    account = get_custom_account(acct_id)
    print(account)

    #アカウント情報の更新
    res = stripe.Account.modify(
        acct_id,
        individual ={
            'first_name':'田中',
            'last_name':"太郎",
            'first_name_kana':"ﾀﾅｶ",
            'last_name_kana':"ﾀﾛｳ",
            'first_name_kanji':"田中",
            'last_name_kanji':"太郎",
            'phone':"+8109001020993",
            'gender':"male", #male or female
            'address_kanji':{
                "country":"JP",
                "state":"東京都",
                "city":"渋谷区",
                "town":"神宮前　1丁目",
                "line1":"5-8",
                "line2":"神宮前タワービルディング 22F",
                "postal_code":"1500001",
            },
            'address_kana':{
                "country": "JP", # 2-letter country code
                "postal_code": "1500001", # Zip/Postal Code
                "state": "ﾄｳｷﾖｳﾄ", # Prefecture
                "city": "ｼﾌﾞﾔ", # City/Ward
                "town": "ｼﾞﾝｸﾞｳﾏｴ 1-", # Town/cho-me
                "line1": "5-8", # Block/Building number
                "line2": "ｼﾞﾝｸﾞｳﾏｴﾀﾜｰﾋﾞﾙﾃﾞｨﾝｸﾞ22F", # Building details (optional)
            },
            'dob':{
                "day":"01",
                "month":"01",
                "year":"1900"
            },
            
        },
        tos_acceptance = {
            "date":int(time.time()),  #=> 1399605420   # 経過秒数を整数で取得
            "ip":"8.8.8.8"            #グローバルIPアドレスを入力
        }
    )
```

# 3. 銀行口座の登録

```python
def create_bank_account(acct_id):
    account = stripe.Account.create_external_account(
        acct_id,
        external_account = {
            "object":"bank_account",
            "account_number":"00012345",
            "routing_number":"1100000", #銀行コード + 支店
            "account_holder_name":"タナカタロウ",
            "account_holder_type":"individual",
            "currency":"jpy",
            "country":"JP"
        }
    )
```

# 4. 本人証明

img_pathは、証明書の画像へのパスです。

```python
def upload_identity_verification_file(acct_id, img_path):
    #https://stripe.com/docs/connect/identity-verification-api
    with open(img_path, "rb") as fp:
        res = stripe.FileUpload.create(
            purpose='identity_document',
            file=fp,
            stripe_account=acct_id
        )
        verification_id = res["id"]

        res = stripe.Account.modify(
            acct_id,
            individual ={ "verification" :{
                "document":{
                    "front": verification_id
                }
            }})
```

# 5. ユーザからの支払い

amountが、商品の料金です。
application_feeがプラットフォーム（運営）の儲けになります。

```python
def charge_user(acct_id, amount, application_fee):
    #https://stripe.com/docs/connect/direct-charges#collecting-fees
    charge = stripe.Charge.create(
        amount=amount,
        currency='jpy',
        description='charge',
        source="tok_visa",  #request.POST['stripeToken']
        application_fee_amount=application_fee,
        stripe_account=acct_id
    )
    
```

# 最後に

pythonでstripe connectを扱う記事でした。
この他にも、javascript側での処理や、Djangoで受け取ったrequestからstripeに反映するなどもあります。
しかし、stirpe実装の最初の第一歩として、皆さんの参考になれば良いと想います。