先日firebase functionsとstripeのサンプルコードを公開したときに、
Cloud Functionsでの決済の実装にはidempotency_keyを利用した方が安全ですよ!
— nori 村本章憲 (@1amageek) June 3, 2019
てな感じで、noriさんにアドバイスを頂きました。その話をまとめます。
Cloud Functionsは複数回呼び出される可能性がある
Cloud Functionsは
— nori 村本章憲 (@1amageek) June 3, 2019
"複数回呼び出される可能性がある"
これはみんな知っておいてください!!!!!!#Firebase pic.twitter.com/ztU14Q48q1
なので、stripeで決済処理をする際、複数回叩かれて2重決済になったりしないように、対策が必要なわけです。
stripe.jsのidempotency_key
順当にstripeのドキュメントを見ていくと、idempotency_key
の実装については触れずに進んでいってしまうのですが、github.com/stripe/stripe-nodeのPassing-Optionsに書いてありました。
idempotentはべき等という意味で、べき等とは、ある操作を1回行っても複数回行っても結果が同じであることをいう概念です。つまりidempotency_key
をつければ、そのkeyがついたリクエストを複数行ったとしても1回だけの処理にしてくれるということです。
これをつけたコードがこちら。
exports.createStripeCharge = functions.https.onCall((data, context) => {
const customer = data.customerId;
const source = data.sourceId;
const amount = data.amount;
const idempotencyKey = data.idempotencyKey;
return stripe.charges.create({
customer: customer,
source: source,
amount: amount,
currency: "jpy",
{ idempotency_key: idempotencyKey } // これ!
})
});
すべてのstripe.jsのメソッドに対して、追加の引数として渡すとべき等にしてくれます。決済などの重複してはいけない処理にはつけた方が良さそうですね。