Stripe: Card declined
Stripeでカード決済が拒否された場合の原因と対処法
概要
Stripeでクレジットカード決済が拒否された際のエラーハンドリング方法です。
エラーメッセージ
```json { “error”: { “code”: “card_declined”, “decline_code”: “insufficient_funds”, “message”: “Your card has insufficient funds.” } } ```
原因
- 残高不足: insufficient_funds
- カード期限切れ: expired_card
- CVV不一致: incorrect_cvc
- 不正検知: fraudulent
- 発行会社の拒否: do_not_honor
解決策
1. エラーコード別の対応
```javascript try { const paymentIntent = await stripe.paymentIntents.create({ amount: 1000, currency: ‘jpy’, payment_method: paymentMethodId, confirm: true, }); } catch (err) { switch (err.code) { case ‘card_declined’: switch (err.decline_code) { case ‘insufficient_funds’: return { error: ‘残高が不足しています。別のカードをお試しください。’ }; case ’expired_card’: return { error: ‘カードの有効期限が切れています。’ }; case ‘incorrect_cvc’: return { error: ‘セキュリティコードが正しくありません。’ }; default: return { error: ‘カードが拒否されました。’ }; } case ’expired_card’: return { error: ‘カードの有効期限が切れています。’ }; default: return { error: ‘決済処理中にエラーが発生しました。’ }; } } ```
2. 3Dセキュア認証
```javascript const paymentIntent = await stripe.paymentIntents.create({ amount: 1000, currency: ‘jpy’, payment_method: paymentMethodId, confirmation_method: ‘manual’, confirm: true, return_url: ‘https://example.com/return', });
if (paymentIntent.status === ‘requires_action’) { // 3Dセキュア認証が必要 return { requiresAction: true, clientSecret: paymentIntent.client_secret, }; } ```
3. リトライロジック
```javascript async function processPayment(paymentMethodId, retries = 2) { for (let i = 0; i <= retries; i++) { try { return await stripe.paymentIntents.create({…}); } catch (err) { if (err.type === ‘StripeCardError’ && i < retries) { await new Promise(r => setTimeout(r, 1000)); continue; } throw err; } } } ```
よくある間違い
- エラーメッセージをそのままユーザーに表示
- decline_codeを確認しない
- テストカードを本番で使用
関連エラー
関連エラー
この記事は役に立ちましたか?