Skip to content

feat: add decline code categorization and Stripe error integration#7

Merged
hideokamoto merged 2 commits intomainfrom
claude/review-feature-updates-01Szcu7sR6UL6yCmcQTMEDtN
Jan 22, 2026
Merged

feat: add decline code categorization and Stripe error integration#7
hideokamoto merged 2 commits intomainfrom
claude/review-feature-updates-01Szcu7sR6UL6yCmcQTMEDtN

Conversation

@hideokamoto
Copy link
Owner

@hideokamoto hideokamoto commented Nov 22, 2025

New Features

Decline Code Categorization

  • Add getDeclineCategory() to classify codes as SOFT_DECLINE or HARD_DECLINE
  • Add isHardDecline() helper to identify permanent declines
  • Add isSoftDecline() helper to identify temporary declines
  • Based on official Stripe documentation guidelines

Stripe Error Object Support

  • Add getMessageFromStripeError() for direct error object handling
  • Simplifies integration with Stripe SDK error handling

Implementation Details

  • Added category field to all 44 decline codes in database
  • Classification based on Stripe's soft/hard decline guidelines
  • Added DeclineCategory and StripeError types
  • Comprehensive test coverage with 34 passing tests
  • Updated documentation with usage examples

Testing

  • All tests passing (34/34)
  • TDD approach: Red-Green-Refactor cycle
  • Type-safe implementation with full TypeScript support

## New Features

### Decline Code Categorization
- Add `getDeclineCategory()` to classify codes as SOFT_DECLINE or HARD_DECLINE
- Add `isHardDecline()` helper to identify permanent declines
- Add `isSoftDecline()` helper to identify temporary declines
- Based on official Stripe documentation guidelines

### Stripe Error Object Support
- Add `getMessageFromStripeError()` for direct error object handling
- Simplifies integration with Stripe SDK error handling

## Implementation Details
- Added `category` field to all 44 decline codes in database
- Classification based on Stripe's soft/hard decline guidelines
- Added `DeclineCategory` and `StripeError` types
- Comprehensive test coverage with 34 passing tests
- Updated documentation with usage examples

## Testing
- All tests passing (34/34)
- TDD approach: Red-Green-Refactor cycle
- Type-safe implementation with full TypeScript support
@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Summary by CodeRabbit

リリースノート

  • 新機能

    • カードの拒否コードを分類・検査するためのAPI追加。ソフト拒否とハード拒否の判定が可能に。
    • Stripeエラーからユーザー向けメッセージを抽出するヘルパー関数追加。複数ロケール対応。
    • すべての拒否コードに分類情報を追加。
  • ドキュメント

    • 新機能の使用例とAPI リファレンスを README に追加。
  • テスト

    • 新APIの包括的なテストスイート追加。

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Stripe拒否コードの分類とエラーメッセージ抽出機能を追加するPRです。拒否コードをSOFT_DECLINEとHARD_DECLINEに分類する4つの新規パブリックAPI関数を導入し、全拒否コードデータに分類カテゴリフィールドを追加しました。

Changes

Cohort / File(s) Summary
新規型定義と型追加
src/types.ts
DeclineCategory型('SOFT_DECLINE' | 'HARD_DECLINE')の導入。DeclineCodeInfoにcategoryフィールド追加。StripeErrorインターフェース追加。
拒否コード分類API
src/index.ts
getDeclineCategory()、isHardDecline()、isSoftDecline()、getMessageFromStripeError()の4つの新規関数追加。DeclineCategory、StripeError型をエクスポート。
拒否コードデータ更新
src/data/decline-codes.ts
すべての拒否コードエントリにcategoryフィールド(SOFT_DECLINE or HARD_DECLINE)を追加。
包括的なテストスイート
src/index.test.ts
新規4関数の単体テスト、エッジケーステスト、locale処理('en'、'ja')検証、既存ユーティリティとの整合性確認。
ドキュメント更新
README.md
拒否コード分類とStripeエラーメッセージ抽出機能の使用方法、API参照を追加。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed プルリクエストのタイトルは、変更セットの主要な内容(decline code categorization と Stripe error integration の追加)を正確かつ簡潔に要約しており、リポジトリの履歴を確認する際に他のチームメンバーが変更内容を明確に理解できます。
Description check ✅ Passed プルリクエスト説明は、新機能(Decline Code Categorization と Stripe Error Object Support)、実装詳細、テスト情報に関する詳細な情報を提供しており、変更セットと密接に関連しています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/review-feature-updates-01Szcu7sR6UL6yCmcQTMEDtN

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @hideokamoto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the stripe-decline-codes library by introducing robust decline code categorization and improved integration with Stripe's error objects. These additions provide developers with clearer guidance on handling payment declines, enabling more intelligent retry logic and more user-friendly error messages, ultimately improving the payment experience.

Highlights

  • Decline Code Categorization: Introduced functions (getDeclineCategory, isHardDecline, isSoftDecline) to classify Stripe decline codes as 'SOFT_DECLINE' (temporary, retryable) or 'HARD_DECLINE' (permanent, not retryable), based on official Stripe documentation.
  • Stripe Error Object Integration: Added getMessageFromStripeError to directly extract localized user-facing messages from Stripe error objects, streamlining error handling and providing clearer feedback to users.
  • Data Enrichment: All 44 existing Stripe decline codes in the library's data have been updated with a new category field to support the new categorization features.
  • Type Safety & Documentation: New TypeScript types (DeclineCategory, StripeError) were introduced, and the README.md was updated with detailed usage examples and API references for the new functionalities.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces excellent new features for categorizing Stripe decline codes into soft and hard declines, and for easily extracting messages from Stripe error objects. The implementation is clean, well-tested, and properly documented. I have one suggestion to improve the type safety of the example code in the README to better align with modern TypeScript practices.

README.md Outdated
Comment on lines 161 to 175
} catch (error) {
if (error.type === 'StripeCardError') {
// Get localized message directly from error object
const userMessage = getMessageFromStripeError(error, 'ja');

// Check if retry is recommended
if (error.decline_code && isHardDecline(error.decline_code)) {
// Ask for a different payment method
console.log('Please use a different card');
} else {
// Retry is possible
console.log('You may retry this payment');
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example for handling Stripe errors in the catch block could be improved to demonstrate safer TypeScript practices. In modern TypeScript (with useUnknownInCatchVariables: true), the error variable in a catch block is of type unknown. Accessing its properties directly (e.g., error.type) is unsafe and will cause a type error. The example should show a safe way to handle this, for instance by using a type assertion.

This also requires importing the StripeError type:

import { getMessageFromStripeError, isHardDecline, StripeError } from 'stripe-decline-codes';
Suggested change
} catch (error) {
if (error.type === 'StripeCardError') {
// Get localized message directly from error object
const userMessage = getMessageFromStripeError(error, 'ja');
// Check if retry is recommended
if (error.decline_code && isHardDecline(error.decline_code)) {
// Ask for a different payment method
console.log('Please use a different card');
} else {
// Retry is possible
console.log('You may retry this payment');
}
}
}
} catch (rawError) {
// In modern TypeScript, the catch variable is `unknown`. It's safer to cast it.
const error = rawError as StripeError;
if (error.type === 'StripeCardError') {
// Get localized message directly from error object
const userMessage = getMessageFromStripeError(error, 'ja');
// Check if retry is recommended
if (error.decline_code && isHardDecline(error.decline_code)) {
// Ask for a different payment method
console.log('Please use a different card');
} else {
// Retry is possible
console.log('You may retry this payment');
}
}
}

@hideokamoto
Copy link
Owner Author

@coderabbitai resolve

@coderabbitai
Copy link

coderabbitai bot commented Dec 31, 2025

✅ Actions performed

Comments resolved.

…-updates-01Szcu7sR6UL6yCmcQTMEDtN

## Merge Details
- Resolved test file location conflict (tests/ → src/)
- Integrated new categorization and Stripe error tests into src/index.test.ts
- Fixed TypeScript type safety in README examples (catch block error handling)
- All 66 tests passing (32 existing + 34 new)

## Changes Applied
- Moved tests from tests/index.test.ts to src/index.test.ts
- Added comprehensive property-based tests for new features
- Updated README examples to use proper type assertions for Stripe errors
- Fixed error.type check to use 'card_error' instead of 'StripeCardError'
@hideokamoto hideokamoto merged commit 36a3a31 into main Jan 22, 2026
4 checks passed
@hideokamoto hideokamoto deleted the claude/review-feature-updates-01Szcu7sR6UL6yCmcQTMEDtN branch January 22, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants