Skip to content

CoinPay hosted checkout sessions (any coin or PayPal); open /crawl through the invite gate - #295

Merged
ralyodio merged 1 commit into
masterfrom
feat/coinpay-checkout-sessions
Oct 21, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/coinpay-checkout-sessions

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Checkout

Premium subscription (/api/payments), IPTV subscription and IPTV extension now open a CoinPay hosted checkout session (POST /api/checkout/sessions, coinpayportal #494): the buyer picks any coin bittorrented's business takes, or PayPal. Body: amount, currency:'USD', description, customer_email (user email), account_id (user id), property: bittorrented.com, metadata, success_url, cancel_url, expires_in_minutes: 60.

  • The local row (payment_history / iptv_payment_history) is keyed by the session id. The first money-moving webhook (detected/confirmed/forwarded) carrying checkout_session_id re-keys it to the payment id (src/lib/coinpayportal/session-payments.ts); the existing payment-id handlers then run unchanged, so in-flight one-coin payments keep settling. An abandoned attempt inside an open session (expired/failed) is acknowledged without claiming the row.
  • CoinPay delivers every event to the business webhook URL (/api/webhooks/coinpayportal), so IPTV payments never reached /api/iptv/subscription/webhook. The main route now hands IPTV rows to a shared handler (src/lib/argontv/webhook.ts). The IPTV route now requires the X-CoinPay-Signature (it trusted any POST before), and fulfilment runs once per payment (confirmed then forwarded no longer extends the ArgonTV line twice).
  • UI: the coin pickers on /pricing and the IPTV account section are gone; one button goes to CoinPay's page. Accounts without an email get a 400 asking for one.
  • @profullstack/live-translate ^0.3.0: translated-audio passes use sessions too (email + account id), settled from the webhook event.
  • The CoinPay business now has the house PayPal app connected (done in the coinpay DB, not in this PR).

/crawl

/crawl and /crawl/* (the x402 sales page, its checkout and return pages) were a 307 to /invite-only. They are now open under both the invite-only gate and legal mode; the crawl gateway answers them itself.

Tests

session-payments.test.ts (session body, CoinPay-origin URL check, re-key, abandoned attempt, IPTV once-only fulfilment, unsigned IPTV webhook refused), updated payments/IPTV/webhook route tests, /crawl gate test. Full suite: 3094 passed.

🤖 Generated with Claude Code

… the invite gate

Premium subscriptions, IPTV subscriptions and IPTV extensions now open a
CoinPay hosted checkout session (POST /api/checkout/sessions): the buyer
picks any coin the business takes, or PayPal, and the sale is filed under
property bittorrented.com with account_id (user id) and customer_email.
The order row is keyed by the session id; the first money-moving webhook
that carries checkout_session_id re-keys it to the payment id, and the
existing payment-id handlers run unchanged, so in-flight one-coin
payments keep settling.

CoinPay sends every event to the business webhook URL, so IPTV payments
are now settled from /api/webhooks/coinpayportal too (they never reached
/api/iptv/subscription/webhook). That route now requires the signature,
and IPTV fulfilment runs once per payment (confirmed then forwarded no
longer extends the line twice).

@profullstack/live-translate 0.3.0: translated-audio passes use sessions
too (email + account id from the signed-in user).

/crawl and /crawl/* (x402 sales page, checkout, return) are open while
the site is invite only and in legal mode; it was a 307 to /invite-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​profullstack/​live-translate@​0.2.1 ⏵ 0.3.082 +710098 +693 +3100

View full report

@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

97 finding(s)

HIGH/CRITICAL: 11 | MEDIUM: 30 | LOW: 56

Severity Rule Location
HIGH secret-private-key src/app/settings/seedbox-section.tsx:412
HIGH secret-generic-api-key docs/incidents/2026-05-okshanaby-supply-chain.md:18
HIGH tls-verification-disabled src/app/api/iptv-proxy/route.ts:39
HIGH tls-verification-disabled src/app/api/iptv/channels/route.ts:35
HIGH tls-verification-disabled src/app/api/iptv/playlists/[id]/route.ts:73
HIGH tls-verification-disabled src/app/api/iptv/playlists/route.ts:64
HIGH js-cors-origin-reflected src/app/api/public/shares/[slug]/checkout/route.ts:40
HIGH js-cors-origin-reflected src/app/api/public/vod/[slug]/checkout/route.ts:34
HIGH tls-verification-disabled src/lib/iptv/shares/upstream.ts:37
HIGH tls-verification-disabled workers/iptv-cache/epg-fetcher.ts:25
HIGH tls-verification-disabled workers/iptv-cache/playlist-fetcher.ts:62
MEDIUM secret-jwt .github/workflows/ci.yml:120
MEDIUM secret-jwt .github/workflows/ci.yml:121
MEDIUM secret-jwt .github/workflows/ci.yml:123
MEDIUM secret-jwt .github/workflows/ci.yml:162
MEDIUM secret-jwt .github/workflows/ci.yml:164
MEDIUM secret-jwt docs/tunein (2).py:9
MEDIUM secret-jwt docs/tunein.py:9
MEDIUM sh-remote-script-execution scripts/setup-server.sh:182
MEDIUM sh-remote-script-execution scripts/setup-server.sh:419
MEDIUM sh-remote-script-execution scripts/setup-server.sh:428
MEDIUM sh-unquoted-expansion-destructive scripts/setup-server.sh:1096
MEDIUM sh-unquoted-expansion-destructive scripts/setup-server.sh:1106
MEDIUM js-unescaped-html-sink src/app/api/player/route.ts:127
MEDIUM js-unescaped-html-sink src/app/api/player/route.ts:281
MEDIUM js-unescaped-html-sink src/app/blog/[slug]/page.tsx:40
MEDIUM js-unescaped-html-sink src/app/blog/[slug]/page.tsx:66
MEDIUM js-unescaped-html-sink src/app/email/email-content.tsx:566
MEDIUM js-open-redirect src/app/login/page.tsx:68
MEDIUM js-open-redirect src/app/pricing/page.tsx:148
MEDIUM js-open-redirect src/app/rent/[slug]/rent-client.tsx:170
MEDIUM js-unescaped-html-sink src/app/rss/rss-content.tsx:615
MEDIUM js-open-redirect src/app/vod/[slug]/vod-client.tsx:138
MEDIUM js-open-redirect src/app/watch/[slug]/watch-client.tsx:131
MEDIUM js-unescaped-html-sink src/app/youtube/youtube-content.tsx:546
MEDIUM js-open-redirect src/components/account/iptv-subscription-section.tsx:121
MEDIUM js-open-redirect src/components/account/iptv-subscription-section.tsx:151
MEDIUM js-unescaped-html-sink src/components/layout/pit-footer.tsx:25
MEDIUM js-unescaped-html-sink src/components/news/news-section.tsx:358
MEDIUM js-unescaped-html-sink src/components/news/news-section.tsx:731
MEDIUM redos-nested-quantifier src/lib/metadata-enrichment/metadata-enrichment.ts:317
LOW tls-verification-disabled docs/tunein (2).py:34
LOW tls-verification-disabled docs/tunein (2).py:37
LOW tls-verification-disabled docs/tunein (2).py:47
LOW tls-verification-disabled docs/tunein.py:34
LOW tls-verification-disabled docs/tunein.py:37
LOW tls-verification-disabled docs/tunein.py:47
LOW tls-verification-disabled src/app/api/iptv-proxy/route.test.ts:457
LOW secret-generic-credential src/app/api/iptv/subscription/route.test.ts:66
LOW secret-generic-credential src/lib/argontv/client.test.ts:54

…and 47 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit d0373a3 into master Oct 21, 2026
9 checks passed
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