Stripe ConnectとStripe Billing
Stripeには、マーケットプレイス、シェアリングエコノミー、プラットフォーム型のビジネスに向けの決済プラットフォームであるStripe Connectというサービスがあります。。例えば、オークションサービスのように出品者と落札者をつなぐサービスで、落札者からの入金を直接出品者に送金することが可能になります。プラットフォームでは、そこからStripeの決済手数料と、プラットフォームの利用手数料を徴収することができます。(Stripe Connectの解説はこの記事などを参照)
また、Subscription(継続課金)を行う為のStripe Billingという機能も用意されています。Stripe Billingは継続課金するサービス(Product)とそのプラン(Plan)を作成して、ユーザに定期的に課金することができます。(Stripe Billingの解説はこちら)
Stripe ConnectとStripe Billingを組み合わせ使うと、Subscriptionを提供するプラットフォームを作り、Stripe Connectを使ってユーザからの課金を、直接お店に送信しつつ、手数料を徴収する仕組みを実装することができます。
前提となるデータ
Stripe ConnectとStripe Billingに出てくるデータのモデルとそのIdは、次のようになります。Stripe Connectの決済フローは、Destination chargeとして、Custom Accountを使う前提で進めます。
- 課金されるユーザ/お客さん (Customer, CustomerId)
- 課金するお店/ベンダー (Custom Account, AccountId)
- 課金する製品/サービス (Product, ProductId)
- 課金プラン(Plan, PlanId)
- ユーザと課金プランを紐付けた継続課金(Subscription, SubscriptionId)
最終的に、PlanとCustomerを結びつけたSubscriptionを作成することをゴールとします。
Shared Customer
今回作るSubscriptionプラットフォームサービスは、UberやAirBnBのようなイメージで、利用するユーザ(課金されるユーザ/お客さん)とサービスを提供するユーザ(課金するお店/ベンダー )を直接結びつけ、都度課金ではなく継続課金(Subscription)を行うサービスです。例えば、毎月会費がある複数のクラブやグループを運営するようなサービスをイメージしてください。
Stripe BillingのSubscription機能を使って継続課金をし、Stripe Connectを使って入金されたお金からプラットフォームの手数料を引いて、クラブ/グループ/お店に直接送金します。
このケースでは、Product, Plan, Subscription, Customerの全てに同じAccoountIdを指定する必要があります。また、SubscriptionにはCustomerIdも指定する必要があります。
ここで、CustomerにAccoountIdを指定する必要があるということは、「課金されるユーザ/お客さん」が、「課金するお店/ベンダー」に紐づくということです。Customerと、AccountIdが紐づくと、「課金されるユーザ/お客さん」が、複数の「課金するお店/ベンダー 」が提供するサービスのSubscriptionを利用できないことになります。
ここで、Customerを複数のAccoountIdに紐付けるための**「Shared Customer」**の登場です。Shared Customerは、作成した「Customer」モデルの決済情報などのデータをそのまま引き継いて別の「Customer」モデルを作成することができます。「Customer」モデルのエイリアスです。
Shared Customerを作成するときに、AccoountIdを指定し、作成したShared CustomerをPlanに紐づけてSubscriptionを作成することで、Customerと、複数のCustom Accountが提供するPlanで継続課金をすることが可能となります。
実装
サンプルはNodeのコードです。
ProductとPlan
Subscriptionに必要なProductとPlanを作成します。これらは、Custom AccountのaccountId に紐付けます。
export const createProduct = async (name, description, accountId) => {
const product = await stripe.products.create({
name: name,
type: 'service',
statement_descriptor: description
}, {
stripe_account: accountId
});
return product;
}
export const createPlan = async(amount, name, productId, accoundId) => {
const plan = await stripe.plans.create({
amount: amount,
interval: "month",
product: productId,
nickname: name,
currency: "jpy",
}, {
stripe_account: accoundId
});
return plan;
};
Shared Customerの作成
Shared Customerを作成するには、customerId, accountIdを使ってcustomer tokenを作成します。そのcustomer tokenのidをcustomer作成時にsourceとして渡します。
const createCustomerToken = async (customerId, accountId) => {
const token = await stripe.tokens.create({
customer: customerId,
}, {
stripe_account: accountId,
});
return token;
}
export const createSharedCustomer = async(customerTokenId, accountId) => {
const customer = await stripe.customers.create({
description: "Shared customer",
source: customerTokenId,
}, {
stripe_account: accountId,
});
return customer;
}
上記2つの関数を使って実際にShared Customerを作成します。
const customerToken = await createCustomerToken(customerId, accountId);
const sharedCustomer = await createSharedCustomer(customerToken.id, accountId);
これで、subscriptionを作成する用意ができました。プラットフォームが徴収する手数料が決済額の10%だとすると、application_fee_percentに10を指定します。Shared CustomerのcustomerIdを使って以下の関数を呼びます。
export const createSubscription = async (customerId, plan, accoundId) => {
const subscription = stripe.subscriptions.create({
customer: customerId,
items: [{ plan: plan }],
application_fee_percent: 10,
}, {
stripe_account: accoundId
})
return subscription;
}
これで、毎月決まった金額を課金して、課金された金額からStripeの手数料とプラットフォームへの手数料を引いた金額がCustom Accountのユーザに送金されるようになります。
謝辞
SubscriptionとBillingが同時に使えないことに気がついて、StripeのUSのサポートチームに質問したところ、Shared Customerについて詳しく教えていただきました。ありがとうございます!!Stripeは丁寧にサポートしてくれるので、何かあれば問い合わせするのがおすすめです。