Skip to content

Keep bounty payout payment details in-app#252

Open
BogdanMaryniuk wants to merge 2 commits into
profullstack:masterfrom
BogdanMaryniuk:fix/bounty-inapp-payment-details-clean
Open

Keep bounty payout payment details in-app#252
BogdanMaryniuk wants to merge 2 commits into
profullstack:masterfrom
BogdanMaryniuk:fix/bounty-inapp-payment-details-clean

Conversation

@BogdanMaryniuk
Copy link
Copy Markdown

Summary

  • keeps bounty CoinPay payment details in-app instead of opening hosted checkout URLs
  • persists payment address/amount/currency/expires metadata and keeps pay_url null for new bounty payments
  • lets pre-migration invoiced rows without in-app address details create a fresh in-app payment request instead of getting stuck

QA

  • Route Vitest: exit 0
  • TypeScript: exit 0
  • Targeted ESLint: exit 0

Notes

This supersedes the earlier conflicting PRs (#241/#244). Branch is based before the new workflow commit to avoid the contributor token workflow-scope push restriction; local merge test against current origin/master was clean.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 24, 2026

Greptile Summary

This PR switches bounty payouts from a hosted-checkout redirect flow to an in-app payment detail display, stores the payment address/amount/currency/expiry in metadata, and keeps pay_url null going forward. It also adds a terminal guard for already-paid submissions and a fall-through path that lets pre-migration rows without in-app address metadata generate a fresh payment request.

  • route.ts: Adds payout_status === "paid" guard (prevents downgrading completed payouts), narrows the cached-invoice early-return to require metadata.payment_address, persists checkout_url in DB metadata, and sets pay_url: null everywhere.
  • ReviewPanel.tsx: Pay button now also renders for invoiced rows missing an in-app address (old hosted-checkout rows), with an updated label; checkout_url is sourced from json.data.checkout_url first, fixing the always-null state issue from the previous review.
  • route.test.ts: Adds coverage for both new code paths (fresh payment for old row, 400 for already-paid row) and updates existing assertions to match pay_url: null.

Confidence Score: 5/5

Safe to merge — all changed logic paths are covered by tests, and no regressions were found in the three modified files.

Both previously flagged issues (always-null checkout_url in client state, and no guard against re-invoicing paid submissions) are properly fixed. The fall-through migration path for old hosted-checkout rows is correctly scoped to rows missing metadata.payment_address, the UI button condition and label are consistent with the new server logic, and new tests cover the two added code paths end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
src/app/api/bounties/[id]/submissions/[sid]/pay/route.ts Adds a terminal guard for payout_status === paid, narrows the early-return for existing invoices to require both coinpay_invoice_id and metadata.payment_address, stores checkout_url in DB metadata, and sets pay_url: null throughout — all logically correct.
src/app/api/bounties/[id]/submissions/[sid]/pay/route.test.ts Updates existing test assertions to match pay_url: null, adds a test for old hosted-checkout rows falling through to a fresh payment, and adds a test verifying the already paid guard returns 400 — good coverage of the new paths.
src/app/bounties/[id]/ReviewPanel.tsx Expands the Pay button condition to cover old invoiced rows without an in-app address, adjusts button label accordingly, and correctly falls back through checkout_url → pay_url → null for display in CryptoPaymentBox.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[POST /pay] --> B{payout_status is paid?}
    B -- Yes --> C[400 Already Paid]
    B -- No --> D{coinpay_invoice_id AND metadata.payment_address present?}
    D -- Yes --> E[Return cached in-app details]
    D -- No --> G[Call createPayment via CoinPay API]
    G --> I{payment_id AND address returned?}
    I -- No --> J[502 No usable payment]
    I -- Yes --> K[Update DB: payout_status=invoiced, pay_url=null, store address in metadata]
    K --> L[200 Return in-app payment details]

    style C fill:#f87171
    style J fill:#f87171
    style E fill:#86efac
    style L fill:#86efac
Loading

Reviews (2): Last reviewed commit: "fix(bounties): preserve completed payout..." | Re-trigger Greptile

Comment thread src/app/api/bounties/[id]/submissions/[sid]/pay/route.ts Outdated
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.

1 participant