Skip to content

fix(ack-pay): bind payment request token subject to its id - #181

Open
crazywriter1 wants to merge 2 commits into
agentcommercekit:mainfrom
crazywriter1:fix/payment-request-sub-id-binding
Open

fix(ack-pay): bind payment request token subject to its id#181
crazywriter1 wants to merge 2 commits into
agentcommercekit:mainfrom
crazywriter1:fix/payment-request-sub-id-binding

Conversation

@crazywriter1

@crazywriter1 crazywriter1 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Problem

createPaymentRequestToken always sets sub to the payment request id, and the create-side tests assert that. verifyPaymentRequestToken never checked the binding, so a validly signed token could carry a different sub and still verify.

That is the same class of gap #88 closed for receipts: the create path establishes a contract and the verify path did not enforce it.

Fix

After parsing the payload with paymentRequestSchema, reject the token when the JWT sub is missing or does not equal the parsed payment request id.

Tests

Added a regression test that signs a payment request with sub set to a different value and expects InvalidPaymentRequestTokenError with no cause, same pattern as the existing invalid-payload test.

Patch changeset included for @agentcommercekit/ack-pay.

AI usage

Per AI_POLICY.md, Cursor did the work: it found the create/verify asymmetry during a rescan of main, wrote the check and the test, and added the changeset. I read the diff before opening this.

Summary by CodeRabbit

  • Bug Fixes

    • Payment request tokens are now rejected when their subject does not match the payment request ID.
    • Invalid or mismatched token subjects now produce a clear verification error.
  • Documentation

    • Clarified that JWT subject claims must match the payment request ID.
  • Tests

    • Added coverage confirming mismatched token subjects fail verification.
  • Chores

    • Prepared a patch release for the payment request package.

createPaymentRequestToken always sets sub to the payment request id, but verifyPaymentRequestToken never checked that binding, so a validly signed token could carry a different sub and still verify.

Reject tokens whose JWT sub does not match the parsed payment request id, matching the contract the create path already enforces.
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: d691dbd5-4766-4046-ab7b-5c46e32e003c

📥 Commits

Reviewing files that changed from the base of the PR and between 109b369 and 605543e.

📒 Files selected for processing (2)
  • docs/ack-pay/payment-request-payload.mdx
  • packages/ack-pay/src/verify-payment-request-token.test.ts
💤 Files with no reviewable changes (1)
  • packages/ack-pay/src/verify-payment-request-token.test.ts

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


Walkthrough

Changes

Payment request token binding

Layer / File(s) Summary
Subject and payment request ID validation
packages/ack-pay/src/verify-payment-request-token.ts, packages/ack-pay/src/verify-payment-request-token.test.ts, docs/ack-pay/payment-request-payload.mdx, .changeset/payment-request-sub-id-binding.md
verifyPaymentRequestToken now rejects tokens when the JWT sub claim is not a string matching the parsed payment request id. The test fixture, documentation, and patch changeset reflect this requirement.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 60554

The change rejects payment request tokens whose subject does not match the payment request ID and documents that requirement; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: venables

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: binding the payment request token JWT subject to the payment request ID.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 …
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Comment thread packages/ack-pay/src/verify-payment-request-token.test.ts Outdated

@venables venables left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

With this change, now the paymentRequestToken row in docs/ack-pay/payment-request-payload.mdx:73 does not say the JWT sub claim must equal paymentRequest.id; a third-party issuer that follows the docs now fails verification.

Can you please add one sentence to that row that states the sub contract.

@crazywriter1

Copy link
Copy Markdown
Contributor Author

Thanks for the review sir. Good catch on both. Removed the redundant id in the test, and added a sentence to the paymentRequestToken row in payment-request-payload.mdx stating that the JWT sub claim must equal paymentRequest.id. @venables

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