From a2cea3a2be4b651462fd10d10d51795ba7e34e0a Mon Sep 17 00:00:00 2001 From: martbost Date: Wed, 16 Sep 2026 14:52:46 -0500 Subject: [PATCH] Anti-fraud refusals redirect to Qualified Start (the sanctioned way to hold extra positions); chatbot says the same Co-Authored-By: Claude Fable 5.1 --- chatbot.js | 2 +- fraud.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/chatbot.js b/chatbot.js index ca15348..dfb2f94 100644 --- a/chatbot.js +++ b/chatbot.js @@ -98,7 +98,7 @@ FACTS: - HOLDING TANK (Members > My line > Holding tank card): free members who joined with no sponsor wait there; a member who has switched on payouts AND bought their own $20+ package can Adopt one (first come, max 2 open adoptions, 7-day window; if the person never links a wallet or buys, they fall back into the tank; a person can be adopted twice at most). Adopting sets the sponsor, opens a chat and emails the member; their first purchase then binds to the adopter on-chain. Members can also "Release to tank" one of their own free referrals (pay it forward), but NOT someone they adopted less than 3 days ago: an adoption is a commitment, and a dropped adoption still counts toward that person's two-adoption lifetime limit. Releases are posted to the feed and Telegram like pickups. Admin sees the tank under Members. - DAILY CLAIM STREAK: finishing the daily ad set and claiming pays 5 credits on day 1, 7 on day 2, 10 from day 3, and 25 on every 7th consecutive day; miss a day and it restarts. After the set, verified visits (up to 20 a day, 1 credit each) keep earning, and the credits are meant to be spent on a campaign. - FOUR-MINUTE OVERVIEW VIDEO (2026-09-16): 'InstantAdPay in four minutes' is the first card on Members > Training (group 'Start here') and embedded on the home page at instantadpay.com/#overview-video (hero button 'Watch the 4-minute overview'). Send it to anyone asking what the platform is; the tab-by-tab walkthrough videos on Training go deeper. It is evergreen: no dates, no launch talk. -- ANTI-FRAUD CHECKS (2026-09-16): at sign-up the site records IP, browser type and a browser cookie id. A second account from a browser that already has one is refused, so is a burst of new accounts from one connection in a day, and so is a sign-up through an invite link whose owner used that same browser. A sign-up from the same IP as the sponsor is allowed but flagged (households are fine). Flagged accounts never count on the leaderboard and cannot adopt from the holding tank; a suspended account cannot sign in. If a member says they were refused at sign-up: one account per person, sign in to the existing one, or contact support if it is a shared computer at work or a library. +- ANTI-FRAUD CHECKS (2026-09-16): at sign-up the site records IP, browser type and a browser cookie id. A second account from a browser that already has one is refused, so is a burst of new accounts from one connection in a day, and so is a sign-up through an invite link whose owner used that same browser. A sign-up from the same IP as the sponsor is allowed but flagged (households are fine). Flagged accounts never count on the leaderboard and cannot adopt from the holding tank; a suspended account cannot sign in. If a member says they were refused at sign-up, or asks how to get a second account to qualify themselves: one account per person, sign in to the existing one, and use QUALIFIED START (Buy packages tab) to link extra wallets of their own as positions under that account; each linked wallet that buys $20+ counts as one of their qualifying buyers, credits pool, and half of each such purchase returns to their main wallet. Levels 2 and 3 open at 2 and 5 qualifying buyers whether those buyers are referrals or the member's own linked positions. Shared computer at work or a library: contact support. Never suggest a second account. - ONE ACCOUNT PER PERSON (Terms section 3, 2026-09-16): a person may hold exactly one account; second or duplicate accounts under any email, name or wallet, and self-referral through another account, are prohibited. The only sanctioned way to hold more than one position is Qualified Start (extra wallets linked inside the one account). Duplicates may be merged, suspended or closed and credits, prizes and contest rankings earned through them are forfeited; the contract's on-chain payments cannot be reversed. Family members join under the member's link with their own email. - BLOG (public, instantadpay.com/blog): Marty's coaching and teaching articles on building a line, advertising that pays, and daily habits; each article has its own page and can be shared; RSS at /blog/feed.xml. Members who want to write their own articles: not offered today. - ACHIEVEMENT BADGES ON TELEGRAM (2026-09-13): when a member unlocks Spark/Surge/Circuit/Nexus, their personalised badge image (username on the ribbon) is posted automatically to the team's Telegram payments topic and the main group, once per badge; members cannot trigger posts themselves (the 'Post to Telegram' button is admin-only); 'Share' opens a picker (X, Facebook, Telegram, WhatsApp, LinkedIn, Massifly (copies the post and opens the feed composer), the phone's own share menu, copy link, save image) that shares the member's public badge page instantadpay.com/b//, which shows the badge and their join link. diff --git a/fraud.js b/fraud.js index 7d1f007..329cd95 100644 --- a/fraud.js +++ b/fraud.js @@ -22,6 +22,7 @@ const FILE = () => path.join(DATA_DIR, 'account-signals.json'); const J = { db: null, load() { try { this.db = JSON.parse(fs.readFileSync(FILE(), 'utf8')); } catch (e) { this.db = {}; } }, save() { try { fs.writeFileSync(FILE(), JSON.stringify(this.db)); } catch (e) {} } }; let suspendedSet = new Set(); // refreshed on init and on every suspend/unsuspend let flaggedSet = new Set(); // accounts carrying a hard flag (excluded from leaderboard / adoption) +const QS = ' To hold more than one position, sign in to your account and use Qualified Start on the Buy packages tab: link another wallet of your own as a position under your account. Each linked wallet that buys a $20 or larger package counts as one of YOUR qualifying buyers, its credits pool with yours, and half of that purchase comes straight back to your main wallet. That is the built-in way to self-qualify.'; const HARD = new Set(['dup-device', 'ip-burst', 'sponsor-device', 'sponsor-ip', 'multi-account']); let seenAt = new Map(); // email -> ts of last recordSeen (throttle writes) @@ -91,18 +92,18 @@ async function checkSignup(req, sponsorAccount, cfg) { const blockDevice = !(cfg && String(cfg.fraudBlockSharedDevice) === 'off'); if (dev) { const same = rows.filter(r => r.deviceId === dev || r.lastDevice === dev); - if (same.length) { flags.push('dup-device'); if (blockDevice) block = 'This browser already has an InstantAdPay account (' + mask(same[0].email) + '). One account per person: sign in to that one instead. If this is a shared computer, contact support.'; } + if (same.length) { flags.push('dup-device'); if (blockDevice) block = 'This browser already has an InstantAdPay account (' + mask(same[0].email) + '), and it is one account per person.' + QS + ' Shared computer at work or a library? Contact support.'; } } if (ip) { const burst = rows.filter(r => r.signupIp === ip && now - (r.signupAt || 0) < 86400000); - if (burst.length >= maxPerDay) { flags.push('ip-burst'); block = block || 'Too many new accounts from this connection today. One account per person. Try again tomorrow or contact support.'; } + if (burst.length >= maxPerDay) { flags.push('ip-burst'); block = block || 'Too many new accounts from this connection today, and it is one account per person.' + QS + ' If these are different people on one connection, try again tomorrow or contact support.'; } const shared = rows.filter(r => (r.signupIp === ip || r.lastIp === ip) && now - Math.max(r.signupAt || 0, r.lastAt || 0) < 30 * 86400000); if (shared.length) flags.push('shared-ip'); } if (sponsorAccount && sponsorAccount.email) { const sp = await get(sponsorAccount.email); if (sp) { - if (dev && (sp.deviceId === dev || sp.lastDevice === dev)) { flags.push('sponsor-device'); if (blockDevice) block = block || 'The invite link you used belongs to an account on this same browser. One account per person, and you cannot refer yourself.'; } + if (dev && (sp.deviceId === dev || sp.lastDevice === dev)) { flags.push('sponsor-device'); if (blockDevice) block = block || 'The invite link you used belongs to an account on this same browser, so this would be a second account for the same person, which the Terms do not allow.' + QS; } if (ip && (sp.signupIp === ip || sp.lastIp === ip)) flags.push('sponsor-ip'); } }