Stripe-phpを使って決済型プラットフォームを開発しようと思うんだけど、単純な決済にStripeを使ったことはあっても、いざプラットフォームで使うとなると色々とわからないことが出てきたので調べたことをまとめてみた
前提条件
- Elementsは使わない
- Connectを使わないとStripeアカウントから子アカウント(店子/マーチャント)への送金が出来ない
- Stripe-phpを利用する
- 最終的にLaravelのフレームワークで構築する
- CheckOutは使わない
- PaymentLinksは使わない
以上を大前提としてStripeで用意されている便利機能は使わないことにした。
自由度の高いフルスクラッチで構築出来る方が好ましい
マルチプラットフォームを制作する上で必要になることの定義
マルチプラットフォームを制作するにあたって必要になること
- ユーザー登録
- ユーザー情報
- ユーザー情報更新
- ユーザーの本人確認
- ユーザーの本人確認書類ファイルのアップロード
- ユーザーの口座情報
- ユーザーの商品登録
- ユーザー商品の決済
- ユーザー商品の決済の返金処理
- ユーザーのクレジットカード情報
- ユーザーのサブスク構築
- 顧客登録
- 顧客一覧
- 顧客情報
- 顧客の支払い情報(クレカや銀行口座など)
- プラットフォームからユーザー&顧客への資金移動(返金処理や手数料)
- 不正ユーザーの対応(支払い拒否や払い戻し)
とりあえず思いつく限り以上の通り
Connectを使わずにマルチプラットフォーム化する方法
最初にStripeの技術担当者と話をした結果、Connectを使わないとマルチプラットフォームは出来ないとの回答を頂いたが、2度目に別の担当と話した際に「2者間取引の場合」はその限りではないとのこと。
業種やサイトの形態に応じて「審査部が判断」するとのことでしたが、開発中の段階では判断して貰う術がないので、PayJPとStripeと両方対応出来るように作っておいた方が良さそう
こちらについてはPayJPさんの方にも事前に確認をとっておいた方が良いだろう
2者間取引でプラットフォームを完結させる方法は「ポイント制度」を用いる方法。
サイト内通貨としてポイントを販売し、販売者が獲得したポイントを換金→振り込みの流れを作れば良い。
税務的にも合法だしStripeなどの決済業者がOKして貰えれば「預かり金」として銀行口座から対応出来るので、個人への支払いだからと言って源泉徴収を取る必要もないらいい→税理士談
またポイントであればサイト内でのやり取りにおいて「投げ銭」も問題ないようだ。
参考: 資金決済法に抵触しない投げ銭サービスの作り方
Connectの知識
これが非常にややこしくて良くわからん
Docsを見てるけど必要な情報が点在しているような状態だったのでブログにまとめることにしたきっかけになった
まずConnectのアカウントがないと連結アカウント(店子/マーチャント/販売店)への銀行送金が出来ない。
アカウントへの送金も出来ないので、一旦プラットフォームの銀行口座に入金されてから個別に振り込み送金しなきゃならなくなるので管理が非常に煩雑になる可能性を危惧した。
ExpressとCustomアカウントは別途料金が掛かり1アカウント毎に月額200円+送金の際に0.25%の費用が掛かる。
連結アカウント制作が参入障壁になる可能性が高いのでCustomアカウントが最適だろう
多少の費用は掛かるが、わざわざStripeアカウントを店子さんに作れと言うのは違う気がする。
Connectの料金詳細(公式ページ)
https://stripe.com/jp/connect/pricing
Connectを使ってCustomアカウントを作成する場合は全ての作業をプラットフォームのAPIで完結出来る
一番ややこしい本人確認情報の取り扱い
ユーザー(連結アカウント)がプラットフォームに登録して支払いと販売を開始するには本人確認情報の提出が済まないと機能しない。プラットフォームに登録して直ぐにプラットフォームのサービスを使えないのではユーザーにとって不満が生まれる。
ここのページに本人確認をAPIで扱う情報が書かれているが何をどこまで確認すれば良いのか?
またビジネスタイプ(業種)によって取得する情報も変わってくる
と言うことは・・・業種によって提出させるフォームを分岐させる必要がありそうだ。
これについては再三問い合わせて聞いてみたが詳細は伝えられないと具体的な回答を貰えなかった。
作る側としては事前にどのような情報が必要になるのかフォームを用意しておかないといけないところだが・・・
どちらにしてもConnectの場合だとユーザー登録後すぐにサービスを利用して貰うことが難しいのでConnectの使い所は限られてきそう。
金融系のサービスやより厳格さを求めるサービスであるならばConnectのデメリットは問題にならないと思う
だけど、少額なサービスを展開する場合Connectの手数料もそうだけど煩雑な回答しか貰えないままで開発コストを掛けるわけにはいかないのも現状で問題である
商品登録とプラン制作の注意点
少しびっくりした部分だけど、商品制作って他のASPだと商品名や価格や色などのバリエーションを一緒に制作するもんだと思っていたけど、Stripeの商品制作(CreateProduct)には価格を設定するパラメーターが無い。
これは別途 価格設定のメソッドを実行して後から関連付けてやる必要がある
こうすることで価格やカラーバリエーションを用意に設定出来て商品画像を商品から変更するだけで一括での変更も可能になる。
プランについても同じように先に商品を作ってからプランを制作する流れでサブスクを設定出来る
これも月額の料金設定と年額の料金設定を作る際に同じ情報をいくつも入力する必要がなくなる利便性を考慮した結果だと思う。
さらにプランの削除はプランだけを削除しても当然のように商品情報だけは残る。
価格設定のない商品だけ残っても仕方ないのだけど、単品販売で利用している可能性を考えると妥当な挙動でしょう。
トランファーでユーザーの銀行口座に送金
Stripeアカウント内の残高から、指定された銀行口座に資金を送金できます。
銀行口座の詳細を安全に保存し、将来のトランスファーのために再利用できます。
トランスファーが完了したときにWebhookを受信できます。
ただし、トランスファーAPIを使用するには、Stripeアカウントに十分な残高があることを確認する必要があり、トランスファーが完了するまでには数日間かかる場合があるため注意が必要。
\Stripe\Stripe::setApiKey('SECRET_API_KEY');
$amount = 100; // 送金する金額(単位はセント)
$currency = 'usd'; // 通貨
$destinationAccountId = 'DESTINATION_ACCOUNT_ID'; // 送金先のアカウントID
$transfer = \Stripe\Transfer::create([
'amount' => $amount,
'currency' => $currency,
'destination' => $destinationAccountId,
]);
echo $transfer;
上記に対して送金元のアカウントIDが必要になる
返金処理
Stripe PHPの create_refund
メソッドのサンプルコードです。全てのパラメータを含んでいます。
\Stripe\Stripe::setApiKey('sk_test_************');
$refund = \Stripe\Refund::create([
'charge' => 'ch_************',
'amount' => 1000,
'reason' => 'requested_by_customer',
'metadata' => [
'order_id' => '12345'
]
]);
APIキーを設定し、charge
に返金する対象のチャージID、amount
に返金する金額、reason
に返金の理由、metadata
にメタデータを指定しています。必要に応じて、これらの値の変更が必要。
返金金額が入力されない場合は自動的に全額返金処理になる。
※ 返金となった場合もStripeに支払った決済手数料は返金されません。
実装保留分
ChatGPTに聞いてみたけどちょっと違うかな?と言うような回答を得たので保留コードとして保存する
Q.Stripe-phpでプラットフォームのユーザーの商品の決済処理のサンプルコードを作って下さい
以下はStripeのTransfer APIを使用してプラットフォームのアカウントバランスに資金を追加し、それをプラットフォームのユーザーに送金するためのサンプルコードです。これにより、Stripe Connectを使用せずにプラットフォームのユーザーに直接支払いを行うことができます。
// トランスファーAPIを初期化する
$transfer = \Stripe\Transfer::create([
'amount' => 1000, // 送金する金額
'currency' => 'jpy', // 通貨
'destination' => '{{USER_ID}}', // 送金先のユーザーID
'transfer_group' => '{{TRANSFER_GROUP_ID}}', // トランスファーグループID
]);
// 送金が完了したら、アカウントバランスから金額を引き落とす
$balance_transaction = \Stripe\BalanceTransaction::create([
'amount' => -1000, // 引き落とす金額
'currency' => 'jpy',
'source' => $transfer->id,
'description' => 'Transfer to {{USER_ID}}',
]);
また、リクエストパラメータをカスタマイズすることもできます。以下は、カスタマイズ可能なパラメータの一部です。
amount
: 送金する金額currency
: 通貨destination
: 送金先のユーザーIDtransfer_group
: トランスファーグループIDsource_transaction
: 送金元のトランザクションID
返金を作成する場合は、以下のサンプルコードを使用してください。
// 返金を作成する
$refund = \Stripe\Refund::create([
'charge' => '{{CHARGE_ID}}', // 返金するチャージID
'amount' => 1000, // 返金する金額
]);
// カスタマイズ可能なパラメータ:
// - 'metadata': 返金に関するメタデータ
// - 'reason': 返金理由
注意: StripeのAPIを使用する前に、必ず公式ドキュメントを確認してください。また、Stripeのウェブフックを使用することで、送金や返金の処理の状態を自動的に通知することができます。
Q.Stripe-phpでプラットフォームのマーチャントの商品の決済処理のサンプルコードを作って下さい
以下は、Stripe PHPライブラリを使用してプラットフォームのマーチャントの商品の決済処理を行うためのサンプルコードです。このコードは、プラットフォームがマーチャントの商品を販売し、決済を処理する場合に使用できます。
// Stripe PHPライブラリを読み込む
require_once('vendor/autoload.php');
// Stripe APIキーを設定する
\Stripe\Stripe::setApiKey('sk_test_XXXXXXXXXXXXXXXXXXXXXXXX');
// カスタマーオブジェクトを作成する
$customer = \Stripe\Customer::create([
'email' => 'customer@example.com',
'source' => 'tok_visa', // カードトークン
]);
// プラットフォームアカウントにトランザクションを作成する
$charge = \Stripe\Charge::create([
'amount' => 1000, // 金額(日本円)
'currency' => 'jpy', // 通貨
'source' => $customer->default_source, // カードトークン
'application_fee_amount' => 200, // プラットフォーム手数料(日本円)
'description' => 'マーチャントの商品の決済', // 説明
'transfer_data' => [
'destination' => '{{マーチャントのアカウントID}}', // マーチャントのアカウントID
],
], [
'stripe_account' => '{{プラットフォームのアカウントID}}', // プラットフォームのアカウントID
]);
// トランザクションのステータスをチェックする
if ($charge->status == 'succeeded') {
// 成功時の処理
} else {
// 失敗時の処理
}
このコードでは、$customer
オブジェクトを作成し、source
にカードトークンを設定しています。次に、プラットフォームアカウントにトランザクションを作成し、transfer_data
にマーチャントのアカウントIDを設定しています。
このコードは、StripeのTransfer APIを使用して、プラットフォームアカウントからマーチャントのアカウントに直接資金を送金することができます。ただし、このAPIを使用する場合は、Stripe Connectのアカウントを作成して、接続しておく必要があります。
このサンプルコードは、実際のアプリケーションに組み込む前に、Stripeの公式ドキュメントを参照し、適切な手順を確認することをお勧めします。また、StripeのWebhooksを使用して自動通知を受け取ることも重要です。