Skip to content

✨ server: add rejection code to authorization declines#1051

Merged
cruzdanilo merged 1 commit into
mainfrom
rejection-code
May 28, 2026
Merged

✨ server: add rejection code to authorization declines#1051
cruzdanilo merged 1 commit into
mainfrom
rejection-code

Conversation

@nfmelendez
Copy link
Copy Markdown
Contributor

@nfmelendez nfmelendez commented May 28, 2026

Summary by CodeRabbit

Release Notes

  • New Features
    • Authorization declines now include structured rejection codes in error responses, providing clearer feedback for scenarios such as insufficient funds, frozen accounts, and permission denials.

Review Change Stack

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 28, 2026

🦋 Changeset detected

Latest commit: cd7514b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/server Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Walkthrough

This PR adds standardized rejectionCode fields to error responses in the Panda webhook handler. The PandaError class gains a typed rejectionCode property with values like "INSUFFICIENT_FUNDS", "NOT_PERMITTED", and "UNKNOWN". Error responses now include this code alongside the existing code field, and tests validate the new payload structure across authorization, liquidity, timeout, and notification scenarios.

Changes

Rejection codes for authorization declines

Layer / File(s) Summary
PandaError rejection code field
server/hooks/panda.ts
PandaError class constructor and type definition updated to include rejectionCode property typed as a union of standardized codes with default value "UNKNOWN".
Authorization and error scenarios with rejection codes
server/hooks/panda.ts
Error responses in the requested handler now include rejectionCode for card-not-found ("UNKNOWN"), frozen and non-active cards ("NOT_PERMITTED"), mutex timeout ("UNKNOWN"), and insufficient liquidity ("INSUFFICIENT_FUNDS"). Main error handler includes both code and rejectionCode in JSON response.
Test validation for rejection code responses
server/test/hooks/panda.test.ts
Authorization failure tests updated to assert exact error payload structure with both code and rejectionCode fields. New test coverage added for missing card, frozen card, and inactive card scenarios. Error path tests for insufficient liquidity, replay, tracing/collection failures, and push notification unknown errors validate the structured response shape.
Release documentation
.changeset/brisk-otter-tag.md
Changeset entry documents patch version bump for @exactly/server with note about rejection code addition to authorization declines.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • exactly/exa#790: Both PRs update server/test/hooks/panda.test.ts to assert response.json() contents for error handling paths, with overlapping test assertions for timeout and error scenarios.
  • exactly/exa#622: Both PRs modify card decline error handling in server/hooks/panda.ts for authorization failures (frozen, inactive, insufficient liquidity scenarios) and update corresponding test expectations in server/test/hooks/panda.test.ts.

Suggested reviewers

  • cruzdanilo
  • dieguezguille
  • franm91
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding rejection codes to authorization decline responses in the server.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rejection-code
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch rejection-code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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 adds rejection codes to authorization decline responses. It updates the PandaError class to accept a rejectionCode and includes this code in the JSON responses for various decline scenarios, such as inactive or frozen cards, insufficient funds, and timeouts. Corresponding unit tests have been added and updated to verify these changes. There are no review comments, and I have no feedback to provide.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/hooks/panda.ts (2)

1310-1319: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add trailing comma to parameter list.

The parameter list is missing a trailing comma after the last parameter. As per coding guidelines, trailing commas should be used in all structures including function parameters to maintain diff-friendliness.

📝 Proposed fix
 class PandaError extends Error {
   constructor(
     message: string,
     public statusCode: number,
-    public rejectionCode: "INSUFFICIENT_FUNDS" | "NOT_PERMITTED" | "UNKNOWN" = "UNKNOWN",
+    public rejectionCode: "INSUFFICIENT_FUNDS" | "NOT_PERMITTED" | "UNKNOWN" = "UNKNOWN",
   ) {
     super(message);
     this.name = "PandaError";
   }
 }

728-728: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider adding rejectionCode for API consistency.

This "card not found" error response at Line 728 (in the created/updated/completed action cases) does not include a rejectionCode field, while the similar error at Line 298 (in the requested action case) does include it.

This creates an inconsistent API where some error responses include rejectionCode and others don't. If the scope is intentionally limited to authorization declines (the requested action), consider documenting this distinction. Otherwise, for consistency, all error responses should include rejectionCode.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 259929ff-7286-4218-be49-2be1923b6b1a

📥 Commits

Reviewing files that changed from the base of the PR and between 04cff64 and cd7514b.

📒 Files selected for processing (3)
  • .changeset/brisk-otter-tag.md
  • server/hooks/panda.ts
  • server/test/hooks/panda.test.ts

Comment thread server/hooks/panda.ts
Comment thread server/hooks/panda.ts
@sentry
Copy link
Copy Markdown

sentry Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 73.48%. Comparing base (04cff64) to head (cd7514b).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/hooks/panda.ts 93.75% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1051      +/-   ##
==========================================
- Coverage   74.02%   73.48%   -0.55%     
==========================================
  Files         243      243              
  Lines       10931    10627     -304     
  Branches     3720     3555     -165     
==========================================
- Hits         8092     7809     -283     
+ Misses       2527     2505      -22     
- Partials      312      313       +1     
Flag Coverage Δ
e2e 72.30% <68.75%> (-1.72%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nfmelendez nfmelendez marked this pull request as ready for review May 28, 2026 18:13
@nfmelendez nfmelendez requested a review from cruzdanilo as a code owner May 28, 2026 18:13
@nfmelendez
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@cruzdanilo cruzdanilo merged commit cd7514b into main May 28, 2026
12 checks passed
@cruzdanilo cruzdanilo deleted the rejection-code branch May 28, 2026 19:15
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