今日は、Destiation Charge の返金処理を見ていく。
ベースの Destination Charge
下の API 呼び出しを、ベースの Destination charge として想定する。
curl https://api.stripe.com/v1/payment_intents \
-d amount=1000 \
-d application_fee_amount=200 \
-d "transfer_data[destination]"="acct_xxxx" \
...
資金フローは、下図のようになる。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
| ^ | ^ . ^
| | | | 200 . |
| | | | . |
| | | [TXN3][Application Fee]<-+ |
| | | . | |
| 1000 964 | | 1000 . 200 | | 800
v | | . | |
[Charge] | v . | |
[TXN1]-----------+ [TXN2] 1000 . [TXN4]-----+
| [Transfer]---------->[Charge2]
| 36 .
v .
Stripe
収支は下表のようになる。
Transaction | Payment Methond | Platform Account | Connected Account | Stripe |
---|---|---|---|---|
Charge | -1000 | +964 | 0 | 36 |
Transfer | 0 | -1000 | 1000 | 0 |
Applecation Fee | 0 | +200 | -200 | 0 |
収支 | -1000 | +164 | +800 | +36 |
Refunds API を呼び出す
次のように Refunds API を呼び出す。多くの場合、この呼び出しではやりたいことができないのだけれど、資金フローとデータモデルは、もっともシンプルだ。
curl https://api.stripe.com/v1/refunds \
-u sk_xxxx: \
-d payment_intent=pi_xxxx \
-d "expand[]"=balance_transaction
{
"id": "re_xxxx",
"object": "refund",
"amount": 1000,
"balance_transaction": {
"id": "txn_5",
"amount": -1000,
"fee": 0,
"net": -1000,
...
},
"charge": "ch_xxxx",
"payment_intent": "pi_xxxx",
...
}
資金フローは、下のようになる。
Distination Charge 時点のフロー矢印と、Blanace Transaction は割愛してある。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
^ | .
| | .
|1000 1000| .
| | .
| v .
[Refund][TXN5]👈 .
: .
: .
[Charge] [Transfer] [Charge2]
Refund オブジェクトは、Charge オブジェクトに関連づいている。Charge によって発生した取引を、逆向きに移動する取引だ。
Charge は Payment Method から Platform Account に資金を移動した。Refund は Platform Account から Payment Method に資金を移動する。Connected Account の残高には影響しない。
収支は下表になる。
Transaction | Payment Methond | Platform Account | Connected Account | Stripe |
---|---|---|---|---|
Charge | -1000 | +964 | 0 | 36 |
Transfer | 0 | -1000 | 1000 | 0 |
Applecation Fee | 0 | +200 | -200 | 0 |
Refund | +1000 | -1000 | 0 | 0 |
収支 | 0 | -836 | 800 | 36 |
Platform Account 残高から返金するので、赤字だ。Connected Account は支払いを受けたままなので、黒字だ。
おそらく、サービスレベルで想定している資金フローではないだろう。
Transfer を戻す
Connected Acocunt に Transfer で移動した資金を、逆向きに動かすには、次のように呼び出す。
curl https://api.stripe.com/v1/refunds \
-u sk_xxxx: \
-d payment_intent=pi_xxxx \
...
curl https://api.stripe.com/v1/transfers/tr_xxxx/reversals \
-u sk_xxxx: \
...
または、次にような一発呼び出しもできる。発生する副作用は同じだ。ただし、上の呼び出しでは、API 呼び出しごとに amount
を個別に指定できるが、下の呼び出しでは自動的に計算される。このアドベントカレンダーの主なトピックではないので、省略する。
curl https://api.stripe.com/v1/refunds \
-u sk_xxxx: \
-d payment_intent=pi_xxxx \
-d reverse_transfer=true \
-d "expand[]"=balance_transaction \
-d "expand[]"="transfer_reversal.balance_transaction" \
-d "expand[]"="transfer_reversal.destination_payment_refund" \
...
{
"id": "re_xxxx",
"amount": 1000,
"balance_transaction": {
"id": "txn_5",
"net": -1000,
...
},
"charge": "ch_xxxx",
"transfer_reversal": {
"id": "trr_xxxx",
"object": "transfer_reversal",
"amount": 1000,
"balance_transaction": {
"id": "txn_6",
"amount": 1000,
"fee": 0,
"net": 1000,
"source": "tr_xxxx",
...
},
"destination_payment_refund": {
"id": "pyr_xxxx",
"amount": 1000,
"charge": "py_xxxx",
...
},
}
}
Transfer Reversal オブジェクトが、Tranfer オブジェクトを巻き戻す。その資金は、pyr_xxxx という ID の Refund オブジェクトからだ。これは、決済時の Charge に対応する。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
^ | ^ .
| | | .
|1000 1000| | 1000 .
| | | .
| v | .
[Refund][TXN5] | .
: [TXN6] 👇 1000 . 👇
: [Transfer Reversal]<----[Refund2]
: : : .
: : : .
[Charge] [Transfer] [Charge2]
Connected Account の立場から、Refund2 を見てみよう。
curl https://api.stripe.com/v1/refunds/pyr_xxxx \
-u sk_xxxx: \
-H "Stripe-Account:acct_xxxx" \
-d "expand[]"=balance_transaction
{
"id": "pyr_xxxx",
"object": "refund",
"amount": 1000,
"balance_transaction": {
"id": "txn_7",
"net": -1000,
"source": "py_xxxx",
...
},
"source_transfer_reversal": "trr_xxxx"
...
}
資金フローは下図のようになる。Refund2 に関連する Balance Transaction は、Connected Account の残高を 1000 円減らして、Transfer Reversal に移動させている。その先には、Platform Account がある。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
^ | ^ . |
| | | . |
|1000 1000| | 1000 . | 1000
| | | . |
| v | . |
[Refund][TXN5] | . 👇 |
: [TXN6] 1000 .[TXN7]<------+
: [Transfer Reversal]<----[Refund2]
: : : .
: : : .
[Charge] [Transfer] [Charge2]
収支は、下表のようになる。
Transaction | Payment Methond | Platform Account | Connected Account | Stripe |
---|---|---|---|---|
Charge | -1000 | +964 | 0 | 36 |
Transfer | 0 | -1000 | 1000 | 0 |
Applecation Fee | 0 | +200 | -200 | 0 |
Refund | +1000 | -1000 | 0 | 0 |
Reversal | 0 | +1000 | -1000 | 0 |
収支 | 0 | 164 | -200 | 36 |
Conncted Acount の残高がマイナスになる。これは、決済時に Application Fee として引かれた 200 円がそのままだからだ。
Application Fee を戻す
Application Fee を、Platform Account から Connected Account に返すには、以下のように API を呼び出す。
curl https://api.stripe.com/v1/refunds \
-u sk_xxxx: \
-d payment_intent=pi_xxxx \
...
curl https://api.stripe.com/v1/transfers/tr_xxxx/reversals \
-u sk_xxxx: \
...
curl https://api.stripe.com/v1/application_fees/fee_xxxx/refunds \
-u sk_xxxx: \
...
または、次にように一発で呼び出してもよい。
curl https://api.stripe.com/v1/refunds \
-u sk_xxxx: \
-d payment_intent=pi_xxxx \
-d reverse_transfer=true \
-d refund_application_fee=true \
...
レスポンスは refund_application_fee
の副作用の結果を返さない。そこで、別の API を呼び出す。
curl https://api.stripe.com/v1/application_fees/fee_xxxx/refunds \
-u sk_xxxx: \
...
{
"id": "fr_xxxx",
"amount": 200,
"balance_transaction": "txn_7",
...
}
Balance Transaction が展開できないので、明示的に取得する。
curl https://api.stripe.com/v1/balance_transactions/txn_7 \
-u sk_xxxx: \
...
{
"id": "txn_7",
"amount": -200,
"fee": 0,
"net": -200,
...
}
資金フローは下図のようになる。Balance Transaction の行き先がいまいち分からない。いや分かるんだけど、レスポンスは保持していない。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
^ | ^ | . |
| | | | 200 . | 1000
| | | v . |
| | | [TXN8] . |
| | | [Application Fee Refund]👈 |
| | | : . |
|1000 1000| | [Application Fee] . |
| | | . |
| v | 1000 . |
[Refund][TXN5] | . |
: [TXN6] 1000 .[TXN7]<------+
: [Transfer Reversal]<----[Refund2]
: : : .
: : : .
[Charge] [Transfer] [Charge2]
Connected Account の観点からデータを取得してみる。
curl https://api.stripe.com/v1/balance_transactions \
-u sk_xxxx: \
-H "Stripe-Account: acct_xxxx" \
);
{
"id": "txn_8",
"amount": 200,
"fee": 0,
"net": 200,
...
}
資金フローは下図のようになる。
Buyer Platform . Seller
Card Bank . Bank
: .
Payment Method Platform Account . Connected Account
^ | ^ | . ^ |
| | | | 200 . 200 | | 1000
| | | v . | |
| | | [TXN8] . [TXN9]👈 |
| | | [Application Fee Refund] |
| | | : . |
|1000 1000| | [Application Fee] . |
| | | . |
| v | 1000 . |
[Refund][TXN5] | . |
: [TXN6] 1000 .[TXN7]<------+
: [Transfer Reversal]<----[Refund2]
: : : .
: : : .
[Charge] [Transfer] [Charge2]
収支をまとめると下表になる。
Transaction | Payment Methond | Platform Account | Connected Account | Stripe |
---|---|---|---|---|
Charge | -1000 | +964 | 0 | 36 |
Transfer | 0 | -1000 | 1000 | 0 |
Applecation Fee | 0 | +200 | -200 | 0 |
Refund | +1000 | -1000 | 0 | 0 |
Reversal | 0 | +1000 | -1000 | 0 |
Applecation Fee Refund | 0 | +200 | -200 | 0 |
収支 | 0 | -36 | 0 | 36 |
まとめ
Destination Charge の返金を見てきた。決済が発生したときの手数料をどうするのか。は、また今度。明日はチャージバックを見ていく。