Open9
FlutterWeb×Stripeで与信枠確保からの決済
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
cloud functions をつかう
secret_key を閉じたところに隠しておきたいので、基本は cloud functions で実装し、それをクライアントから呼び出すこととする。
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
stripeのsdkをつかう
functions の作業ディレクトリで実行
npm install stripe --save
importはこう
const stripe = require('stripe')('sk_test_...');
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
顧客データを作成して顧客idを獲得
const customer = await stripe.customers.create(
{
email: data.email
},
{
// 繰り返し実行されてもkeyが変わらなければ値が変化しない
idempotencyKey: data.idempotencyKey
}
);
これをfirestoreのUser情報に保存しておくと便利そう。
どんなパラメータを渡せるかは下記参照
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
カード情報を登録
UI を作るのが面倒なので Checkou tの setup mode というのを使わせていただく。
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'setup',
customer: '{{CUSTOMER_ID}}',
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
});
成功を非同期で検知するためには checkout.session.completed のWebhook が使えるらしい。
そこは調べて後述する。
とにかく customer にクレカ情報を紐づけられることが重要。
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
与信の確保
const paymentIntent = await stripe.paymentIntents.create({
amount: 1099,
currency: 'jpy',
payment_method_types: ['card'],
capture_method: 'manual',
payment_method: '{{PAYMENT_METHOD_ID}}',
customer: '{{CUSTOMER_ID}}', // 顧客データと紐づけたいときだけ
confirm: true, // すぐに実行したい場合
});
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
決済(キャプチャー)
枠を確保して実際にそれを売上とするのをcaptureというみたい。
const intent = await stripe.paymentIntents.capture(
data.paymentIntentId
);
return intent;
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
顧客情報の確認と変更
カスタマーポータルを使用するとよい。
const session = await stripe.billingPortal.sessions.create({
customer: '{{CUSTOMER_ID}}',
return_url: 'https://example.com/account',
});
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
カード情報を登録
const paymentMethod = await stripe.paymentMethods.create({
type: 'card',
card: {
number: '4242424242424242',
exp_month: 4,
exp_year: 2023,
cvc: '314',
},
});
![こんぶ](https://res.cloudinary.com/zenn/image/fetch/s--GjLjrucn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6640af3cc7.jpeg)
カード情報をカスタマーに紐づける
const paymentMethod = await stripe.paymentMethods.attach(
'pm_1KrFAQAMoVLSjIeBsxzocMXu',
{customer: 'cus_Hpzdch6cvLdNlN'}
);