🐙

Stripe の PaymentIntent 使って Capture する方法

2023/07/04に公開

タイトルがダサ過ぎて笑える。

(...)

まぁ、普通に考えたらこれ(↓)でキャプチャできると思うじゃないですかぁ。

キャプチャする方法
const paymentIntent = await stripe.paymentIntents.capture(
  paymentIntentId,
  { amount_to_capture: captureAmount }
);

普通に出来るんですけどね。

でも、これを実行する前に paymentIntent を create する必要があるんです。

そのコードがこちら

PaymentIntent 作成処理
const paymentIntent = await stripe.paymentIntents.create({
  amount: amount, // 決済金額
  currency: 'jpy',
  payment_method: paymentMethodId,
  customer: stripeCustomerId,
  confirm: true,
  capture_method: 'manual',
  payment_method_types: ['card'],
})

上記2つ使ってオーソリとクリアリング処理が出来ますよと。

エラーになった箇所

PaymentIntent 作成処理
const paymentIntent = await stripe.paymentIntents.create({
  ...
  capture_method: 'manual',
  confirm: true,
  ...
})

まず confirm: true にするかどうか問題。

アナタはどうする?

ちなみに、Stripe api を見るとこんな感じです。

confirm optional
Set to true to attempt to confirm this PaymentIntent immediately. This parameter defaults to false. When creating and confirming a PaymentIntent at the same time, parameters available in the confirm API may also be provided.

翻訳:
この PaymentIntent をすぐに確認するには、true に設定します。 このパラメータのデフォルトは false です。 PaymentIntent の作成と確認を同時に行う場合、確認 API で使用可能なパラメータも提供される場合があります。

https://stripe.com/docs/api/payment_intents/create

いや、普通にこれ true にしたら勝手に決済確定しちゃうんじゃない!?
って思うよね。

まぁ、普通に決済確定しちゃうんだけどね。
もし、下記がないと普通に決済確定処理になる。

capture_method: 'manual',

だから、ずっーーーーっとエラーが起こった。

じゃあ、どうするのか?
オーソリのドキュメントを見てみた。

https://stripe.com/docs/payments/place-a-hold-on-a-payment-method

↓ 下記はスクショです。

これ見てもどうやら決済がキャプチャできない
これの原因は別にあるだろうなぁと思って confirm: true にしたら出来た。(気がする)

capture と confirm の違いがあるらしい

capture
https://stripe.com/docs/api/payment_intents/capture

confirm
https://stripe.com/docs/api/payment_intents/confirm

こんなん最初から分かるかい!!
って感じやけど、

現状の理解だと、confirm は決済した金額をそのまま決済出来る

つまりオーソリの段階で ¥10,000 で PaymentIntent を作成したら
confirm ではその決済を確定する事かキャンセルする事かしか出来ない。

もちろん、オーソリ処理だから決済手数料はかからない。

でも、減額した金額を決済したい場合とかあるよね。

僕が作ってる飲食店のアプリとかだと、
お客さんに合わせて減額したりする場合があるから
減額した金額を決済したいわけ。

それを使うには capture だった。

まぁ、一番上でも書いたけどもう一度貼る。

キャプチャする方法
const paymentIntent = await stripe.paymentIntents.capture(
  paymentIntentId,
  { amount_to_capture: captureAmount }
);

amount_to_capture で決済額を調整できるらしい。

注意1: PaymentIntentを作成した金額以上は決済できない
注意2: capture は1回きり。減額で取りこぼした金額を再度キャプチャは出来ない

Discussion