Skip to content

Add early validation for receipt ID format - #219

Merged
AnkanMisra merged 7 commits into
AnkanMisra:mainfrom
Jighnesh-Py13:fix/receipt-id-validation
Jun 18, 2026
Merged

Add early validation for receipt ID format#219
AnkanMisra merged 7 commits into
AnkanMisra:mainfrom
Jighnesh-Py13:fix/receipt-id-validation

Conversation

@Jighnesh-Py13

@Jighnesh-Py13 Jighnesh-Py13 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Closes #210

Summary

Adds early validation for receipt IDs in handleGetReceipt to reject malformed IDs before hitting the store layer.

Changes

  • Added isValidReceiptID helper to validate rcpt_ prefix and basic format
  • Updated handleGetReceipt to return 400 for malformed IDs
  • Ensures store is not queried for invalid requests

Behavior

  • Malformed IDs → 400 Bad Request
  • Well-formed but missing IDs → 404 Not Found
  • Valid IDs → normal lookup flow

Testing

  • Added/updated table-driven tests covering valid, malformed, and empty IDs
  • Verified with go test ./...

Non-breaking

No changes to receipt generation or x402 verification logic.

Summary by CodeRabbit

  • Bug Fixes
    • Receipt retrieval now validates receipt IDs against the documented rcpt_ + 12 lowercase-hex format before any lookup, returning HTTP 400 with error and message for invalid inputs.
    • HTTP 500 response payload was simplified while keeping 404 and success behavior unchanged.
  • Tests
    • Added/extended coverage for valid/invalid receipt ID formats and verified invalid requests don’t query the receipt store.
    • Updated receipt ID fixtures used by in-memory and Redis store tests.
  • Documentation
    • Updated the OpenAPI spec for the 400 response body and adjusted the 500 example message.

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

@Jighnesh-Py13 is attempting to deploy a commit to the ankanmisra's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@AnkanMisra, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 17 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e555b436-fb94-4f6c-9298-f288ab7b2ebe

📥 Commits

Reviewing files that changed from the base of the PR and between 171ca3f and 71f8171.

📒 Files selected for processing (6)
  • gateway/main.go
  • gateway/main_test.go
  • gateway/openapi.yaml
  • gateway/receipt_test.go
  • gateway/redis_receipt_store_test.go
  • web/src/lib/verify-receipt.ts
📝 Walkthrough

Walkthrough

Adds an isValidReceiptID validator (enforces rcpt_ + 12 lowercase hex chars) and uses it in GET /api/receipts/:id to return 400 for malformed IDs before querying the store. Keeps 404 for well-formed-but-missing receipts and 500 for internal errors. Adds a unit test and OpenAPI 400 response documentation.

Changes

Receipt ID Validation

Layer / File(s) Summary
Import and regex pattern
gateway/main.go
Adds regexp import and a precompiled receiptIDPattern enforcing ^rcpt_[a-f0-9]{12}$.
Validator function and handler integration
gateway/main.go
Adds isValidReceiptID(id string) bool which matches IDs against the precompiled regex; updates handleGetReceipt to validate :id up-front and return 400 with {"error":"invalid receipt id format","message":"invalid receipt id format"} for malformed IDs; preserves 404 for missing receipts and returns 500 with {"error":"failed to retrieve receipt"} for internal errors.
Validator in receipt creation
gateway/main.go
Updates validateReceipt to use isValidReceiptID for regex-based format validation instead of previous empty and prefix-only checks.
Test coverage, API documentation, and test fixtures
gateway/main_test.go, gateway/openapi.yaml, gateway/receipt_test.go, gateway/redis_receipt_store_test.go
Extends spyReceiptStore to track store Get calls; adds TestIsValidReceiptID table-driven test covering valid, malformed, empty, wrong-prefix, and length-mismatch cases; adds TestHandleGetReceipt_InvalidID_DoesNotHitStore to verify the store is not queried for malformed IDs; updates OpenAPI to document the 400 response schema (error and message fields) with example format description; lowercases the 500 example message; updates test fixtures in receipt_test.go and redis_receipt_store_test.go to use valid deterministic receipt IDs matching the new validation pattern.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AnkanMisra/MicroAI-Paygate#40: Both PRs touch the receipt lookup path in gateway/main.go (specifically handleGetReceipt and receipt ID handling for /api/receipts/:id), with this PR adding regex-based :id validation and related tests for that endpoint.

Suggested labels

level:intermediate

Suggested reviewers

  • AnkanMisra

Poem

🐰 I hop the gateway with whiskers keen,
Sniffing rcpt_ and twelve hex sheen.
Malformed paths I gently shun,
So stores rest quiet — work is done.
Small checks at dusk, tidy dawn, code is fun.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding early validation for receipt ID format.
Description check ✅ Passed The description adequately covers the changes made, behavior expectations, and testing approach, addressing the core requirements.
Linked Issues check ✅ Passed All acceptance criteria from issue #210 are met: malformed IDs return 400, well-formed-but-missing IDs return 404, store is not queried for invalid IDs, and tests are added.
Out of Scope Changes check ✅ Passed All changes are scoped to receipt ID validation as specified in issue #210; no unrelated refactoring or unintended modifications present.

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

✨ 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 and usage tips.

@github-actions

Copy link
Copy Markdown

Hi @Jighnesh-Py13, thanks for opening this PR.

Every contribution helps MicroAI-Paygate grow. If you find the project useful, consider starring the repository — it helps others discover it.

Star MicroAI-Paygate on GitHub

Looking forward to reviewing this PR.

@github-actions github-actions Bot added go Pull requests that update go code type:testing Tests, coverage, fixtures, or validation-only work. labels Jun 10, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@gateway/main_test.go`:
- Around line 619-632: Replace the single-case TestHandleGetReceipt_InvalidID
with a table-driven test that iterates cases for empty ID (""), prefix-only
("rcpt_"), too-long ID (>128 chars), malformed ("foo"), and a valid ID
("rcpt_a1b2c3d4e5f6"); for each case use httptest.NewRecorder and
gin.CreateTestContext, set c.Params with the case id, call handleGetReceipt, and
assert both the expected HTTP status and that the response body contains the
expected error message (for invalid cases) or proceeds to store lookup for the
valid case; for the valid-case path mock or initialize the receipt store used by
handleGetReceipt so the handler reaches the lookup and you can assert the
successful path.

In `@gateway/main.go`:
- Around line 951-958: The handler rejects malformed receipt IDs using
isValidReceiptID in GET /api/receipts/{id} and returns 400 with
{"error":"invalid receipt id format","message":"receipt id must start with rcpt_
and contain an id"}; update gateway/openapi.yaml to add a 400 response for the
GET /api/receipts/{id} operation that documents this response (status 400) and
its response schema (error and message string properties and an example matching
the handler) so the OpenAPI spec matches the runtime behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 39cc227a-fcfd-41f0-ade5-697706e3bcab

📥 Commits

Reviewing files that changed from the base of the PR and between f2066d9 and 73eea63.

📒 Files selected for processing (2)
  • gateway/main.go
  • gateway/main_test.go

Comment thread gateway/main_test.go Outdated
Comment thread gateway/main.go
@github-actions github-actions Bot added documentation Improvements or additions to documentation type:docs Documentation, API docs, examples, or contributor docs. labels Jun 10, 2026

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
gateway/openapi.yaml (1)

243-255: ⚡ Quick win

Consider marking response fields as required.

The handler always returns both error and message fields (verified in gateway/main.go:952-955), so the schema should reflect that guarantee with required: [error, message].

📋 Proposed schema improvement
         "400":
           description: Invalid receipt ID format.
           content:
             application/json:
               schema:
                 type: object
+                required: [error, message]
                 properties:
                   error:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/openapi.yaml` around lines 243 - 255, Update the OpenAPI 400 response
schema for the receipt endpoint so it marks the returned fields as required: add
required: [error, message] to the schema under the "400" response; this aligns
the spec with the handler behavior that always returns both fields (see
gateway/main.go handler that sets error and message) and ensures clients treat
those properties as mandatory.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@gateway/openapi.yaml`:
- Around line 243-255: Update the OpenAPI 400 response schema for the receipt
endpoint so it marks the returned fields as required: add required: [error,
message] to the schema under the "400" response; this aligns the spec with the
handler behavior that always returns both fields (see gateway/main.go handler
that sets error and message) and ensures clients treat those properties as
mandatory.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 136de2ea-dd5d-4aa2-a778-1581bd2f7e45

📥 Commits

Reviewing files that changed from the base of the PR and between 73eea63 and 6933da3.

📒 Files selected for processing (1)
  • gateway/openapi.yaml

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
microai-paygate Ready Ready Preview, Comment Jun 18, 2026 6:58am

@AnkanMisra AnkanMisra added enhancement New feature or request good first issue Good for newcomers level:beginner Small, well-scoped work suitable for newer contributors. type:security Security, abuse resistance, secret safety, or payment integrity work. labels Jun 11, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6933da374c

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gateway/main.go Outdated
Comment thread gateway/main.go

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@coderabbitai coderabbitai Bot 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.

Caution

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

⚠️ Outside diff range comments (1)
gateway/main.go (1)

936-942: ⚠️ Potential issue | 🟡 Minor

Run gofmt on main_test.go and ratelimit.go before committing.

The receipt-id validation logic returning a 400 for malformed IDs is fine. go vet ./... reports no issues, but gofmt -l shows formatting still needed in:

  • main_test.go
  • ratelimit.go
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/main.go` around lines 936 - 942, Run gofmt on the unformatted Go
files reported by gofmt: reformat main_test.go and ratelimit.go (e.g. run `gofmt
-w main_test.go ratelimit.go`) and re-run `gofmt -l` to verify no files remain;
then stage and commit the formatted files so the repository passes formatting
checks—no functional changes needed to functions like isValidReceiptID.

Source: Coding guidelines

🧹 Nitpick comments (1)
gateway/main.go (1)

926-929: ⚡ Quick win

Pre-compile the regex for better performance.

regexp.MatchString compiles the pattern on every call. Since the pattern is constant, compile it once at package level to avoid repeated compilation overhead on every receipt lookup.

⚡ Proposed optimization

Add a package-level compiled regex:

+var receiptIDPattern = regexp.MustCompile(`^rcpt_[a-f0-9]{12}$`)
+
 func isValidReceiptID(id string) bool {
-	matched, _ := regexp.MatchString(`^rcpt_[a-f0-9]{12}$`, id)
-	return matched
+	return receiptIDPattern.MatchString(id)
 }

Note: MustCompile panics at startup if the pattern is invalid, which is appropriate for a constant pattern and provides earlier failure detection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/main.go` around lines 926 - 929, isValidReceiptID currently calls
regexp.MatchString which recompiles the pattern on every invocation; define a
package-level compiled regex (e.g., var receiptIDRe =
regexp.MustCompile(`^rcpt_[a-f0-9]{12}$`)) and update isValidReceiptID to use
receiptIDRe.MatchString(id) so the pattern is compiled once at startup and
reused.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@gateway/main.go`:
- Around line 936-942: Run gofmt on the unformatted Go files reported by gofmt:
reformat main_test.go and ratelimit.go (e.g. run `gofmt -w main_test.go
ratelimit.go`) and re-run `gofmt -l` to verify no files remain; then stage and
commit the formatted files so the repository passes formatting checks—no
functional changes needed to functions like isValidReceiptID.

---

Nitpick comments:
In `@gateway/main.go`:
- Around line 926-929: isValidReceiptID currently calls regexp.MatchString which
recompiles the pattern on every invocation; define a package-level compiled
regex (e.g., var receiptIDRe = regexp.MustCompile(`^rcpt_[a-f0-9]{12}$`)) and
update isValidReceiptID to use receiptIDRe.MatchString(id) so the pattern is
compiled once at startup and reused.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 29976426-9ac9-4ea8-94c7-0c4535839a5d

📥 Commits

Reviewing files that changed from the base of the PR and between 6933da3 and a7b4b92.

📒 Files selected for processing (2)
  • gateway/main.go
  • gateway/openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • gateway/openapi.yaml

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7b4b92056

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gateway/main.go Outdated
Comment thread gateway/main_test.go Outdated
Comment thread gateway/main_test.go Outdated
Comment thread gateway/main.go Outdated
Comment thread gateway/main.go Outdated

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Fix the codex bugs

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d155251b5

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gateway/main.go

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 5d155251b5

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ecffb9c50a

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread gateway/main_test.go
Comment thread gateway/main.go

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@github-actions github-actions Bot added the TypeScript TypeScript code label Jun 15, 2026

@AnkanMisra AnkanMisra left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This PR is 2 commits behind main. Please rebase or merge main into your branch.

@Jighnesh-Py13

Copy link
Copy Markdown
Contributor Author

Hi @AnkanMisra
Can you please check now if everything's alright.
Thanks

@AnkanMisra

Copy link
Copy Markdown
Owner

@codex review the pr

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 71f8171cc0

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@AnkanMisra AnkanMisra added the gssoc:approved Approved for GSSoC contribution label Jun 18, 2026
@AnkanMisra
AnkanMisra merged commit f88f0d9 into AnkanMisra:main Jun 18, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request go Pull requests that update go code good first issue Good for newcomers gssoc:approved Approved for GSSoC contribution level:beginner Small, well-scoped work suitable for newer contributors. type:docs Documentation, API docs, examples, or contributor docs. type:security Security, abuse resistance, secret safety, or payment integrity work. type:testing Tests, coverage, fixtures, or validation-only work. TypeScript TypeScript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate receipt ID format in handleGetReceipt before store lookup

2 participants