How another team uses MorePaying
Point the widget at MorePaying. See the first weekly judgment on the playground before you pay.
Never send Stripe secret keys to MorePaying. Sync totals and customer ids only.
Step 1
Never send Stripe secrets
MorePaying is read-only on money. Keep sk_live / webhook secrets on your server. We store totals and customer ids only.
Step 2
Identify at the paywall
Call identify with user, channel/UTM, plan, signed-up-at, generations, first success, remaining credits, pricing dwell, and Stripe amount. Customers only pick a reason.
Step 3
Ask in the product, not by email
Email surveys die. After identify, track("pricing_exit") or track("paid") opens one in-app question. That is the box. Do not add an ESP.
Step 4
Count the funnel
track("pricing_view") when the pricing page opens. track("pricing_exit") or track("paid") asks the one question. That is how 327 / 84 / 31 is built.
Step 5
Sync paying from your Stripe account
On your server, list subscriptions or handle webhooks. POST /api/stripe/sync with currentAmountCents, currentCustomers, and { stripeCustomerId, amountCents, status, userId }. The scoreboard source becomes stripe.
Step 6
Ship, then watch more paid move
Agent pick → ready (git trailer MorePaying-Ready: <id>) → release --through <deployed SHA>. Release snapshots current paying and attributes blocked revenue so more paid this period moves. Later Stripe syncs fill 7 / 14 / 30 day windows.
Step 7
Open the weekly page
Every Monday open /report: reasons, channels, three merged failure patterns, the experiment to run, blocked revenue. CSV is there. Slack comes after a real customer. Do not email a survey.
How it works
- 1
Capture
After identify, track(pricing_exit) or track(paid) opens one in-app question. Do not email a survey.
- 2
Check
Choices roll into blocked revenue. The sentence is a hypothesis until usage agrees.
- 3
Agent picks up
MCP, CLI, or /morepaying pick. After ship, notify that person.
- 4
Ship
Public board: received → in progress → pending release → shipped. Score is more paid this period.
Why it matters
One question
Fixed choices at pay, don't-pay, first result, checkout, cancel. No founder fields on the customer.
Why they pay too
Paid success is a first-class moment, not an afterthought.
Blocked revenue
Reasons roll up to people × estimated dollars. Do this first, don't cut price.
Trust check
The sentence is a hypothesis. Leftover credits and free-enough exports get flagged.
MCP + CLI + Skills
list, pick, ready, release, notify, paying.
More paid scoreboard
Baseline vs tracked paying amount. Seats are the plan. Lift is the score.
Channel × money
Which source paid, which only blocked revenue. Ask in the product, not by email.
Attach to a live paywall
Start with a site that already has a real paywall. The widget is cross-origin. Do not put sk_live or emails in the browser.
MKSaaS credit sites (seedvr2 / plain / aiupscale / happyhorse)
<!-- layout: once -->
<script src="https://morepaying.charlie0simmon.workers.dev/widget.js"></script>
<script>
MorePaying.init({
projectKey: "mp_proj_YOUR_KEY",
apiBase: "https://morepaying.charlie0simmon.workers.dev"
})
</script>
// after session + credits load
MorePaying.identify({
userId: session.user.id, // hash if you do not want raw ids on the board
plan: session.user.plan,
creditsRemaining,
creditsLimit,
firstSuccess,
generations,
utmSource: url.searchParams.get("utm_source"),
channel: session.user.channel
})
// PricingPopup open
MorePaying.track("pricing_view")
// PricingPopup closes without a purchase
// seedvr2: replace PricingDismissFeedback with this one question
// plain / aiupscale / happyhorse: hook onOpenChange(false)
MorePaying.track("pricing_exit")
// first paid-looking result
MorePaying.track("first_result")
// webhook / server only — totals, never sk_live
POST https://morepaying.charlie0simmon.workers.dev/api/stripe/sync
X-Project-Key: mp_proj_YOUR_KEY
{ "currentAmountCents": 315000, "currentCustomers": 24, "customers": [] }ShipAny credit sites (hunyuan / longcat / lyria / trellis)
Empty credits currently toast and the user leaves. Attach by opening pricing and asking the question.
<!-- layout: once -->
<script src="https://morepaying.charlie0simmon.workers.dev/widget.js"></script>
<script>
MorePaying.init({
projectKey: "mp_proj_YOUR_KEY",
apiBase: "https://morepaying.charlie0simmon.workers.dev"
})
</script>
MorePaying.identify({
userId: user.id,
plan: user.plan || "free",
creditsRemaining: remainingCredits,
creditsLimit
})
// today: toast.error(insufficient_credits) and the user leaves
// change: open /pricing AND ask
if (!hasEnoughCredits) {
MorePaying.track("pricing_view")
MorePaying.track("pricing_exit")
router.push("/pricing")
return
}Install
Skills teach the workflow. MCP and CLI read and update signals. Release stays in the CLI so a deployed SHA can be verified.
$ npx -y --package github:CharlieLZ/morepaying -- morepaying
$ npx -y --package github:CharlieLZ/morepaying -- morepaying-mcp
# copy packages/skills/morepaying/SKILL.md into your agent skills folderMorePaying.init({
projectKey: "mp_proj_YOUR_KEY",
apiBase: "https://morepaying.com",
userTokenFn: async () => {
const res = await fetch("/api/identity-token", {
method: "POST",
headers: { "Content-Type": "application/json", "X-Project-Key": "mp_proj_YOUR_KEY" },
body: JSON.stringify({ userId: currentUser.id })
})
return (await res.json()).token
}
})
MorePaying.identify({
userId: currentUser.id,
plan: currentUser.plan,
usage: currentUser.usageLabel,
signedUpAt: currentUser.createdAt,
generations: currentUser.generations,
firstSuccess: currentUser.firstSuccess,
creditsRemaining: currentUser.creditsRemaining,
creditsLimit: currentUser.creditsLimit,
utmSource: url.searchParams.get("utm_source"),
channel: currentUser.channel,
pricingDwellMs: dwellMs,
stripeCustomerId: currentUser.stripeCustomerId,
stripeAmountCents: currentUser.amountCents,
stripeStatus: currentUser.stripeStatus
})
MorePaying.track("pricing_view")
// later
MorePaying.track("pricing_exit")
// on your server, never in the browser
POST /api/stripe/sync
X-Project-Key: mp_proj_YOUR_KEY
{
"currentAmountCents": 315000,
"currentCustomers": 24,
"customers": [
{ "stripeCustomerId": "cus_123", "amountCents": 2000, "status": "active", "userId": "usr_123" }
]
}Open the weekly judgment on a shareable page. No extra host required to start.