Add email notifications for economically unviable refunds #88

Merged
russellballestrini merged 3 commits from feature/economically-unviable-refund-emails into master 2025-10-03 16:54:18 -04:00
russellballestrini commented 2025-10-03 16:41:55 -04:00 (Migrated from git2.unturf.com)

Enhanced the refund email system to properly notify users when their
cryptocurrency refunds cannot be processed due to being economically
unviable (too small to cover network transaction fees).

Changes:

  • Updated send_refund_email() to differentiate between "no refund address"
    and "economically unviable" scenarios with appropriate messaging
  • Added email notifications in crypto watcher for all NOT_REFUNDED status
    transitions due to economic viability:
    • Duplicate payment processing (line ~1770)
    • Expired payment processing (line ~2145)
    • Underpayment processing (line ~2905)
    • Passive monitoring refund retries (line ~3280)
  • Added proper error handling for email sending to prevent disruption
  • All economically unviable refund tests pass with no regressions

Users now receive clear explanations when refunds are too small to send
rather than being left without notification.

Summary by CodeRabbit

  • New Features
    • Automatic refund notification emails for duplicate payments, expired invoices, underpayments, and other refund outcomes, including passive/monitoring paths.
    • Updated subject lines and messages for "economically unviable" (too-small) refunds, referencing the received amount.
    • Emails sent with shop-domain context when available, with safe fallbacks.
    • Email send failures are logged and handled so refund processing continues.
Enhanced the refund email system to properly notify users when their cryptocurrency refunds cannot be processed due to being economically unviable (too small to cover network transaction fees). Changes: - Updated send_refund_email() to differentiate between "no refund address" and "economically unviable" scenarios with appropriate messaging - Added email notifications in crypto watcher for all NOT_REFUNDED status transitions due to economic viability: * Duplicate payment processing (line ~1770) * Expired payment processing (line ~2145) * Underpayment processing (line ~2905) * Passive monitoring refund retries (line ~3280) - Added proper error handling for email sending to prevent disruption - All economically unviable refund tests pass with no regressions Users now receive clear explanations when refunds are too small to send rather than being left without notification. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Automatic refund notification emails for duplicate payments, expired invoices, underpayments, and other refund outcomes, including passive/monitoring paths. * Updated subject lines and messages for "economically unviable" (too-small) refunds, referencing the received amount. * Emails sent with shop-domain context when available, with safe fallbacks. * Email send failures are logged and handled so refund processing continues. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
russellballestrini (Migrated from git2.unturf.com) scheduled this pull request to auto merge when all checks succeed 2025-10-03 16:42:03 -04:00
coderabbitai commented 2025-10-03 16:42:06 -04:00 (Migrated from git2.unturf.com)

⚠️ WARNING

Rate limit exceeded

@russellballestrini has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 9 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 125d8726bb and 7ff744e0df.

📒 Files selected for processing (1)
  • make_post_sell/lib/mail.py (1 hunks)

Walkthrough

Adds refund-related email notifications across crypto refund paths, builds shop-context email requests (using DummyRequest when needed), wraps email sends in try/except with logging, and updates NOT_REFUNDED email content to reflect “economically unviable” refunds with adjusted subject/message.

Changes

Cohort / File(s) Summary
Crypto watcher refund email integration
make_post_sell/lib/crypto_watcher/__init__.py
Inserts refund email dispatches across duplicate/expired/underpayment/refund paths. Constructs shop-context email_request (including DummyRequest from pyramid.testing when no live request), calls mailer, and wraps sends in try/except with logging. Adds passive-monitoring email notifications for economically unviable refunds without changing state transitions.
Refund email content tweak
make_post_sell/lib/mail.py
In send_refund_email, when status is NOT_REFUNDED and crypto_payment.refund_reason contains “economically unviable”, changes subject to “Refund Too Small” and includes a message referencing received_amount; otherwise retains prior messaging and behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Worker as Passive Monitor / Worker
  participant CW as CryptoWatcher
  participant ShopCtx as create_shop_context_request
  participant Mail as Mailer (send_refund_email)
  participant Log as Logger

  Note over Worker,CW: Determine refund decision (duplicate, expired, underpayment)
  Worker->>CW: Evaluate crypto_payment
  alt Refund determined (economically unviable / NOT_REFUNDED)
    CW->>ShopCtx: Build shop-context email_request (may use DummyRequest)
    ShopCtx-->>CW: email_request
    CW->>Mail: send_refund_email(email_request, crypto_payment)
    alt Email send succeeds
      Mail-->>CW: OK
      CW->>Log: "refund email sent"
    else Email send fails
      Mail--xCW: Exception
      CW->>Log: "refund email failed" (non-blocking)
    end
  else No email needed
    CW->>Log: Continue processing
  end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I twitch my whiskers at coins too small,
A tiny refund, a polite recall.
I wrap a shop-context in a little note,
Send it off, then safely tote.
If mail trips up, I log and hop—onward we scuttle, not fall. 🐇✉️


📝 NOTE

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- This is an auto-generated comment: rate limited by coderabbit.ai --> > ⚠️ **WARNING** > ## Rate limit exceeded > > @russellballestrini has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait **2 minutes and 9 seconds** before requesting another review. > > <details> > <summary>⌛ How to resolve this issue?</summary> > > After the wait time has elapsed, a review can be triggered using the `@coderabbitai review` command as a PR comment. Alternatively, push new commits to this PR. > > We recommend that you space out your commits to avoid hitting the rate limit. > > </details> > > > <details> > <summary>🚦 How do rate limits work?</summary> > > CodeRabbit enforces hourly rate limits for each developer per organization. > > Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. > > Please see our [FAQ](https://docs.coderabbit.ai/faq) for further information. > > </details> > > <details> > <summary>📥 Commits</summary> > > Reviewing files that changed from the base of the PR and between 125d8726bb73330d9d00e6d934d6634a263fa0f5 and 7ff744e0df7b083296a17ec49882830add5a59ce. > > </details> > > <details> > <summary>📒 Files selected for processing (1)</summary> > > * `make_post_sell/lib/mail.py` (1 hunks) > > </details> <!-- end of auto-generated comment: rate limited by coderabbit.ai --> <!-- walkthrough_start --> ## Walkthrough Adds refund-related email notifications across crypto refund paths, builds shop-context email requests (using DummyRequest when needed), wraps email sends in try/except with logging, and updates NOT_REFUNDED email content to reflect “economically unviable” refunds with adjusted subject/message. ## Changes | Cohort / File(s) | Summary | | --- | --- | | **Crypto watcher refund email integration**<br>`make_post_sell/lib/crypto_watcher/__init__.py` | Inserts refund email dispatches across duplicate/expired/underpayment/refund paths. Constructs shop-context `email_request` (including `DummyRequest` from `pyramid.testing` when no live request), calls mailer, and wraps sends in try/except with logging. Adds passive-monitoring email notifications for economically unviable refunds without changing state transitions. | | **Refund email content tweak**<br>`make_post_sell/lib/mail.py` | In `send_refund_email`, when status is `NOT_REFUNDED` and `crypto_payment.refund_reason` contains “economically unviable”, changes subject to “Refund Too Small” and includes a message referencing `received_amount`; otherwise retains prior messaging and behavior. | ## Sequence Diagram(s) ```mermaid sequenceDiagram autonumber actor Worker as Passive Monitor / Worker participant CW as CryptoWatcher participant ShopCtx as create_shop_context_request participant Mail as Mailer (send_refund_email) participant Log as Logger Note over Worker,CW: Determine refund decision (duplicate, expired, underpayment) Worker->>CW: Evaluate crypto_payment alt Refund determined (economically unviable / NOT_REFUNDED) CW->>ShopCtx: Build shop-context email_request (may use DummyRequest) ShopCtx-->>CW: email_request CW->>Mail: send_refund_email(email_request, crypto_payment) alt Email send succeeds Mail-->>CW: OK CW->>Log: "refund email sent" else Email send fails Mail--xCW: Exception CW->>Log: "refund email failed" (non-blocking) end else No email needed CW->>Log: Continue processing end ``` ## Estimated code review effort 🎯 4 (Complex) | ⏱️ ~60 minutes ## Poem > I twitch my whiskers at coins too small, > A tiny refund, a polite recall. > I wrap a shop-context in a little note, > Send it off, then safely tote. > If mail trips up, I log and hop—onward we scuttle, not fall. 🐇✉️ <!-- walkthrough_end --> <!-- tips_start --> --- > 📝 **NOTE** > <details> > <summary>🎁 Summarized by CodeRabbit Free</summary> > > Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting <https://app.coderabbit.ai/login>. > > </details> <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end --> <!-- internal state start --> <!-- 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= --> <!-- internal state end -->
coderabbitai commented 2025-10-03 16:42:35 -04:00 (Migrated from git2.unturf.com)

changed the description

changed the description
russellballestrini (Migrated from git2.unturf.com) canceled auto merging this pull request when all checks succeed 2025-10-03 16:43:54 -04:00
russellballestrini commented 2025-10-03 16:44:53 -04:00 (Migrated from git2.unturf.com)

added 1 commit

  • 125d8726 - Remove support contact message from economically unviable refund emails

Compare with previous version

added 1 commit <ul><li>125d8726 - Remove support contact message from economically unviable refund emails</li></ul> [Compare with previous version](/engineering/make-post-sell/make_post_sell/-/merge_requests/52/diffs?diff_id=761&start_sha=59963a62cdb78c6e24bd34382d8f085535d4d2c6)
coderabbitai commented 2025-10-03 16:45:14 -04:00 (Migrated from git2.unturf.com)

changed the description

changed the description
russellballestrini commented 2025-10-03 16:46:17 -04:00 (Migrated from git2.unturf.com)

added 1 commit

  • 7ff744e0 - Remove all 'contact support' references from refund emails

Compare with previous version

added 1 commit <ul><li>7ff744e0 - Remove all &#39;contact support&#39; references from refund emails</li></ul> [Compare with previous version](/engineering/make-post-sell/make_post_sell/-/merge_requests/52/diffs?diff_id=763&start_sha=125d8726bb73330d9d00e6d934d6634a263fa0f5)
russellballestrini (Migrated from git2.unturf.com) scheduled this pull request to auto merge when all checks succeed 2025-10-03 16:47:15 -04:00
russellballestrini commented 2025-10-03 16:54:18 -04:00 (Migrated from git2.unturf.com)

mentioned in commit b0dc15b06a

mentioned in commit b0dc15b06a62a12ce63b56f0598a177ffd8ad1a6
russellballestrini (Migrated from git2.unturf.com) merged commit b0dc15b06a into master 2025-10-03 16:54:18 -04:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: engineering/make_post_sell#88
No description provided.