支払いに関連するデータモデル

購入者が販売者から、商品(製品やサービス)を受け取り、対価として代金を支払う。というケースの、資金の動きは下図のようになる。

Buyer -> Seller

Card(クレジットカード、略してクレカ)と銀行口座(Bank Account)を介して資金が移動するので、下図のように考えられる。

Buyer      Seller
Card  -> Bank Account

Stripe が入ると、こうなる。

Buyer      Seller
Card     Bank Account
  |          ^
  v          |
----------------
     Stripe

もうちょっと見ていこう。Stripe 内では、クレカを Payment Method というオブジェクトで抽象化する。

販売者に関しては、Accountという概念がある。ユーザーアカウントというよりも、Stripe 内にある仮想的な口座のようなもの、と考えるほうが近い。

Card から Stripe に資金が動くんだけど、アスキーアートできれいに描けないので Card = Payment Method と考える。

Buyer             Seller
Card              Bank Account
  :                  ^
  :                  |
Payment Method -> Account

Bank Account と (Stripe) Account が並ぶとややこしいので、以降、Bank Account のことを Bank と表記する。

Buyer             Seller
Card              Bank
  :                  ^
  :                  |
Payment Method -> Account

Payment Intent

Payment Method から Account に資金を移動する、つまり「支払い」をするには、Payment Intent というオブジェクトを使う。状態を持つオブジェクトでもあり、副作用のあるメソッド的なものもある。

具体的な呼び出しはこうなる。

request
curl https://api.stripe.com/v1/payment_intents \
  -d amount=2000 \
  -d payment_method=pm_card_visa \
  ...

pm_card_visa は test mode で使えるテスト用の Payment Method の ID で、基本的に必ず決済は成功する。資金フローで見ると下図になる。

Buyer                               Seller
Card                                Bank
  :
  :
Payment Method ->[Payment Intent]-> Account

成功すると、Payment Method から 2000 円の支払いをさせて、Account に移動する。クレカから 2000 円を決済して、Account に一時的にためているというわけだ。

Charge と Balance Transaction

Payment Intent の実行が成功すると、Charge と Balance Transaction というオブジェクトが自動的に作られて、関連づけられる。

  • Payment Intent は支払い(決済)のライフサイクルを管理する
  • Charge は、クレカによる決済を表す
  • Balance Transaction は、Account 残高の変化を表す
Buyer                                                  Seller
Card                                                   Bank
  :
Payment Method -> [Charge] -> [Balance Transaction] -> Account
                     :                |
               [Payment Intent]       v fee
                                    Stripe

API で GET すると以下のような JSON が返ってくる。残高増減の金額に関する項目を抜き出した。

curl https://api.stripe.com/v1/payment_intents/pi_xxxx \
  -u sk_xxxx: \
  -d "expand[]"=charges.data.balance_transaction \
  -G

{
  "id": "pi_xxxx",
  "charges": {
    "object": "list",
    "data": [
      {
        "id": "ch_xxxx",
        "payment_method": "pm_xxxx",
        "balance_transaction": {
          "id": "txn_xxxx",
          "amount": 1099,  # Buyer が支払った金額
          "fee": 40,  # Stripe の決済手数料
          "net": 1059,  # Account 残高の増加
          ...

ここまでの資金フローだけを見ると、Payment Intent、Charge、Balance Transaction があるので冗長に思える。けれど会計処理や Connect で効いてくるので、我慢して欲しい。

手数料の動きも含めると、資金フローはこうなる。

Buyer                                                        Seller
Card                                                         Bank account
  :             1099                                  1059
Payment Method ------> [Charge][Balance Transaction] ------> Account
                         :                |
                         :                | 40
                   [Payment Intent]       v
                                        Stripe

まとめ

今回は、支払いの実装方法と、その副作用を見ていった。この時点ではまだ銀行口座に資金は移動していない。それは明後日に。明日は、利用可能という概念を見ていく。