Skip to content

fix(billing): tolerate Razorpay notes:[] (polymorphic) in webhook entities#274

Merged
mastermanas805 merged 4 commits into
masterfrom
fix/razorpay-notes-array-unmarshal
Jun 7, 2026
Merged

fix(billing): tolerate Razorpay notes:[] (polymorphic) in webhook entities#274
mastermanas805 merged 4 commits into
masterfrom
fix/razorpay-notes-array-unmarshal

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Found by the live payment failure test

Driving the Razorpay bank-sim Failure button produced a payment.failed webhook with notes:[], and the api logged:

billing.payment.failed.parse_failed: json: cannot unmarshal array into Go struct
field rzpPaymentEntity.notes of type map[string]string

So handlePaymentFailed swallowed the event and the immediate payment-failure handling (SendPaymentFailed) never ran. (Tier correctly stayed free — a failed payment never carries subscription.charged — so the bug is the missing failure notification, not a false upgrade.)

Fix

Razorpay's notes is polymorphic: object when populated, [] when empty. New rzpNotes type with UnmarshalJSON tolerating object / empty-array / null, used by both the subscription and payment entities. Test: TestRzpNotes_ToleratesArrayObjectAndNull.

🤖 Generated with Claude Code

claude and others added 4 commits June 7, 2026 12:05
…ities

Razorpay's `notes` field is polymorphic: an OBJECT when populated, an empty
ARRAY ([]) when absent. The structs used map[string]string, so a payment.failed
webhook carrying notes:[] failed to parse:
  json: cannot unmarshal array into Go struct field rzpPaymentEntity.notes of type map[string]string
→ handlePaymentFailed swallowed the event and the immediate payment-failure
handling (SendPaymentFailed) never ran. Found by the live failure-path test
(bank-sim 'Failure' button → payment.failed with notes:[]).

New rzpNotes type with UnmarshalJSON that tolerates object / empty-array / null
(decoding only the object form), used by both the subscription and payment
entities. Tier-upgrade safety is unaffected (a failed payment never carried a
subscription.charged); this restores the failure-NOTIFICATION path.

Test: TestRzpNotes_ToleratesArrayObjectAndNull (notes:[] / {} / null / object).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… value)

100%-patch: a notes object with a non-string value exercises the decode-error
path in rzpNotes.UnmarshalJSON (billing.go:1372-1373).
@mastermanas805 mastermanas805 merged commit 3d6dc38 into master Jun 7, 2026
18 checks passed
@mastermanas805 mastermanas805 deleted the fix/razorpay-notes-array-unmarshal branch June 7, 2026 07:38
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