Partner-code credits arrive as a drip; unclaimed installments expire

Marty (2026-09-19): partner codes keep working with no monthly cap, but the credits stop
being a dump. A fifth is paid the day the code is redeemed, then a fifth on each day the
member finishes their daily ad set, five days in all, and whatever is unclaimed 30 days after
redemption is never paid. Same headline number for the partner to promote; paid only to
people who show up. 49 of the 52 PARTNER redemptions were still sitting on 500+ unspent.

Every redemption now records the site the ?promo= link was opened from (iap.promoref cookie
set from the Referer at link-open), so a code's traffic can be attributed to the partner page
it was supposed to come from. Member-funded codes charge the funder one installment at a
time; a short funder leaves the installment due, not lost.

Pre-drip redemptions were paid in full up front and are marked paid=credits at start-up, so
nothing is paid twice. Covered by a module test (13 checks: per-day cadence, gaps, rounding,
expiry, pre-drip rows, declined payer) and an end-to-end HTTP test on a local copy (9 checks).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-19 06:24:14 -05:00
parent 5ebe890760
commit 415a5f3848
5 changed files with 69 additions and 13 deletions
+3 -1
View File
@@ -2822,7 +2822,9 @@
try {
const r = await (await fetch('/api/my/promo/redeem', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code }) })).json();
if (r.error) { say(r.error, false); return; }
say('Added ' + Number(r.credits).toLocaleString() + ' credits' + (r.partner ? ' from ' + r.partner : '') + '. They are in your balance now.', true);
say(r.step
? Number(r.now || 0).toLocaleString() + ' credits added now' + (r.partner ? ' from ' + r.partner : '') + '. The rest of the ' + Number(r.credits).toLocaleString() + ' arrive ' + r.step + ' at a time, one for each day you finish your daily ads, for the next 30 days.'
: 'Added ' + Number(r.credits).toLocaleString() + ' credits' + (r.partner ? ' from ' + r.partner : '') + '. They are in your balance now.', true);
inp.value = ''; if (typeof loadDashboard === 'function') loadDashboard();
} catch (e) { say('Could not apply that code. Try again.', false); }
finally { btn.disabled = false; }
+1 -1
View File
@@ -1037,7 +1037,7 @@
<script src="/assets/common.js?v=20260916a"></script>
<script src="/assets/wallet.js?v=20260911a"></script>
<script src="/assets/promo.js?v=20260911a"></script>
<script src="/assets/my.js?v=20260919a"></script>
<script src="/assets/my.js?v=20260919b"></script>
<script src="/assets/chat.js?v=20260907l"></script>
</body>
</html>