Skip to content

Fix manual refund validation error when entering negative amounts #3107

Closed
shivam-pawar-7217 wants to merge 1 commit intofossasia:devfrom
shivam-pawar-7217:fix/refund-workflow-3096
Closed

Fix manual refund validation error when entering negative amounts #3107
shivam-pawar-7217 wants to merge 1 commit intofossasia:devfrom
shivam-pawar-7217:fix/refund-workflow-3096

Conversation

@shivam-pawar-7217
Copy link
Copy Markdown
Contributor

Fixes #3096

The Problem

When trying to process refunds manually, you get an error:
"The refunds you selected do not match the selected total refund amount."

Root causes:

  • Form was accepting negative values without validation
  • Decimal precision wasn't normalized before comparing amounts
  • Negative amounts could create phantom refund records

Fixes

Manual refund validation layer:

  • Added negative value checks on all refund input fields
  • Fixed currency rounding/precision before amount comparison
  • Better error messages showing what was selected vs what was expected
  • Prevented invalid refund records from being created
  • Added logging and regression tests

Notes

Stripe webhook refund syncing is handled by the eventyay-stripe plugin (separate repo).
If Stripe webhooks aren't syncing refunds:

  1. Verify plugin webhook endpoint is registered in Stripe dashboard
  2. Check plugin logs/issues if the endpoint is registered but failing

This PR focuses on unblocking manual refund processing immediately.

Copilot AI review requested due to automatic review settings March 31, 2026 07:22
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @shivam-pawar-7217, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@shivam-pawar-7217
Copy link
Copy Markdown
Contributor Author

Follow-up: Stripe Webhook Refund Sync

@mariobehling - This PR fixes the manual refund validation layer.

For Stripe webhook refund syncing (charge.refunded events → order refunds), that's handled by the eventyay-stripe plugin. If that's still not working, it may need a separate issue/PR in the eventyay-stripe repository.

Should we verify that part is working correctly or create a follow-up issue for it?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes manual refund validation issues in the control order refund flow, primarily addressing negative refund inputs and precision mismatches that caused erroneous “selected vs expected” validation failures.

Changes:

  • Added validation to reject negative refund values across manual, gift card, offsetting, provider-specific, and per-payment refund inputs.
  • Normalized totals with currency rounding before comparing refund_selected vs full_refund, and enhanced mismatch error output with the computed amounts.
  • Added/updated regression tests for negative manual and negative gift card refund inputs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
app/eventyay/control/views/orders.py Adds negative-value validation, rounds totals before comparison, improves mismatch error message, and logs mismatches.
app/tests/tickets/control/test_orders.py Updates refund validation expectations and adds a regression test ensuring negative gift card input does not create gift cards.
Comments suppressed due to low confidence (1)

app/eventyay/control/views/orders.py:1041

  • The gift card is created immediately when giftcard_value > 0, before validating that is_valid is still true and that refund_selected == full_refund. If the request later fails validation or the totals don’t match, this leaves a newly issued gift card without a corresponding successful refund. Defer gift card issuance (and related OrderRefund creation) until after the final validation passes (or wrap the whole operation in a transaction and only commit on success), and add a regression test for the mismatch path.
                    refund_selected += giftcard_value
                    giftcard = self.request.organizer.issued_gift_cards.create(
                        expires=self.request.organizer.default_gift_card_expiry,
                        currency=self.request.event.currency,
                        testmode=self.order.testmode,

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

app/eventyay/control/views/orders.py:1045

  • issued_gift_cards.create(...) is executed immediately when giftcard_value > 0, even if later validation fails (e.g., another field is invalid) or if refund_selected != full_refund. In those failure paths the OrderRefund objects are never saved, but the GiftCard record has already been created, leaving an orphaned/phantom gift card. Consider deferring gift card creation until after refund_selected == full_refund and is_valid is confirmed (or wrap the whole operation in an atomic transaction and roll back/delete the gift card on failure).
                    refund_selected += giftcard_value
                    giftcard = self.request.organizer.issued_gift_cards.create(
                        expires=self.request.organizer.default_gift_card_expiry,
                        currency=self.request.event.currency,
                        testmode=self.order.testmode,
                    )
                    giftcard.log_action('eventyay.giftcards.created', user=self.request.user, data={})

@shivam-pawar-7217 shivam-pawar-7217 force-pushed the fix/refund-workflow-3096 branch from c35309c to f9bd087 Compare March 31, 2026 10:25
@mariobehling
Copy link
Copy Markdown
Member

This PR does not have a screenshot or screencast showing before and after. Hence closing this for now.

@github-project-automation github-project-automation bot moved this from Backlog to Done in Eventyay Next Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Ticket refund functionality not working (Stripe and manual refund errors)

3 participants