こんにちは、dev.toの皆さん、
これは少し奇妙な話ですが、共有したいと思いました。ついて来てください、決済処理の部分は本当に面白いです。
私は15歳で、ロシアに住んでおり、過去の3週間の激しい個人でのコーディング中に、Dodayを構築しました — Webアプリとして動作するタスク管理アプリで、Telegramのミニアプリとボットとしても利用可能で、すべて同じバックエンドを共有しています。基本的にはTodoistの代替品で、ポモドーロタイマー、カンバンボード、学校ポータル同期(ロシアの学生向け——これは実際には大きな壁ですよ)、チームのコラボレーションが組み込まれています。
こちらで試すことができます:getdoday.ru · コード:github.com/SwairIt/doday · ボット:Telegram上のDodayTaskBot
モノエコ化の部分について話したいと思います。他の製品を売り出そうとしている未成年者にとって役立つかもしれないからです.
問題点
私は5月2日からDodayを開発していました。有料プランを追加しようとしたとき、アプリにはすでに小さなユーザーグループがいました(主に友人や学校の人に加えて、いくつかのランダムな人々)。私はBETA_FREE_FOR_ALL=true 環境フラグで、みんながPro機能を無料で使えるように設定しました。これはリリース期間には持続可能でしたが、実際に人々がそのサービスを支払うかどうかを検証したいと思いました。
計画は単純でした:ロシアの決済プロセッサ(YooKassa、以前はYandex Kassa——ローカルのStripeとほぼ同等)を登録し、そのチェックアウト機能を実装すれば完了です。
私は「自営業」(ロシアの税制で14歳以上で親の同意があると利用可能なsamozanyetyy)として登録されているので、税番号と本物の銀行口座があります。これで十分だと判断しました.
2日間で3回の拒否
YooKassa — グオーシュリュウ(私たちのe-gov/政府サービスの単一サインオンに相当するもの)を通じてログインします。すぐに拒否されました:"Госуслугиの子供向けアカウントをお持ちの方はサインインできません。"私のГосуслугиアカウントは完全に検証されています—税金を払い、大人と同じことをします。しかしYooKassaは生年月日を確認し、18歳未満であれば控訴できません。硬い壁です.
はい、手動入力は開きます—彼らはスキャンしたカラー版のパスポートをアップロードしたいです。彼らのOCRは生年月日を読み取り、それを拒否します。戦略的にぼかした日付で試みました—1時間後に「身分証明を確認できません」と表示されました。同じ壁です.
OK、T-Bankが取得中です(別の主要なロシア製プロセッサー)。サインアップの流れは「登録されたIP(個人事業主)またはLLCである必要があります」となります。自営業は許可されますが、18歳以上からのみ可能です。IPとして登録するには、18歳である必要があります(親の同意と公証書がある場合16歳可ですが、銀行はこれを受け入れません)。
OK、親の名前で登録します は今法律上彼らのものです。もし顧客とのトラブルがあれば、私の親はそれを議論しなければなりません。税務署はその収入を彼らのものと考えています。もし彼らが明日関与したくないと決めたら、私は一晩で全ての支払いインフラを失います。そんなことは起こりません.
OK、18歳になるまで待ってくださいそれはさらに三年です。いくらかもっと時間をその製品に投資するのに、いくらかの財政的検証を見ることができないと、それを正当化できません
正直に言って、収益化をあきらめていたところでした。それから、Telegram Starsの存在を思い出しました
Telegram Stars (XTR)
知らないなら — Telegramは、自社のアプリ内通貨としてStars(通貨コードXTR は彼らのボットAPIで利用可能です。ユーザーはTelegramクライアント(Apple/Googleアプリ内購入)を通じてこれらを購入します。ボットはStarを通じて受け取ることができ、createInvoiceLink で受け取れます。開発者はStarの価値の約70%を受け取り、TON暗号通貨またはFragmentを通じて引き出すことができます。
重要な点:BotFather(Telegramのボット管理ボット)は13歳以上から利用可能です。 ドキュメントはありません。税IDはありません。銀行もありません。あなたの契約はテレグラムと銀行ではありません。
15歳の私にとって、これは唯一の合法的な支払い経路です。
私は座ってそれを書きました。
私が作ったもの(技術的)
-
スキーマ移行 (
alembic 0039):users.pro_until(タイムスタンプ)、star_paymentsテーブルにUNIQUE(telegram_payment_charge_id)に対する idempotency -
商品カタログ (
app/billing/products.py) —価格の真実の一元ソース。Pro 1ヶ月 = 250⭐、Pro 12ヶ月 = 2500⭐、Pro ライフタイム = 12500⭐。このファイルを編集するだけです. -
HMAC署名された請求書ペイロード —
v1:{product}:{user_id_hex}:{nonce}:{sig}この場合、誰でも請求書URLを傍受して支払い前に製品コードを "pro_forever" に置き換えることができます。それがあると、署名が無効になり Bot API が拒否します。ペイロードは80バイト以下(Telegramの制限は128バイトです)。 -
一意性のある支払いアプリケーション — Telegramは失敗時にwebhookを再試行します。私は
star_paymentsにUNIQUEをチャージIDで挿入し、2回目の挿入はエラーを引き起こします。IntegrityError→ 既存の行をキャッチして返す。ダブルクレジットは絶対にない。 -
effective_tier()はpro_untilを認証する — 有効期限切れのpro_untilを持つ有料ユーザーは自動的に無料に戻り、cronジョブはゼロになる。毎回のリクエストで惰性評価を行う。ライフタイム購入はpro_untilを2099年とするセンチネルとして設定される。 -
更新は既存のものを延長する
pro_until— プロをまだ10日残っているのに1ヶ月購入した場合、30日にならない。current_pro_until + 30 daysに延長される。(Todoistはこれを間違えている、つまり。) -
返金フロー — 管理者エンドポイントが
refundStarPaymentボットAPIを呼び出し、pro_untilをロールバックする。Telegramは21日以内に返金を許可する。 -
ボットハンドラ —
PreCheckoutQueryHandler(10秒以内に回答する必要があり、署名と金額を検証する)、MessageHandler(filters.SUCCESSFUL_PAYMENT)(適用成功支払いを呼び出す)。
テスト:署名、改ざん拒否、金額不一致、一貫性、更新計算、ライフタイムセンチネル、有効期限切れ→無料フォールバックをカバーする24のユニットテスト。
ミニアプリUIは、アプリ内支払いのためにTelegram.WebApp.openInvoice(url, callback)を使用する。ウェブUIはデスクトップ用のフォールバックとして新しいタブで請求書URLを開く。
セキュリティ上の脆弱性も閉じました—POST /api/billing/change-tierは以前、認証されたユーザーが{"tier": "pro"}をPOSTすることで無料でProにアップグレードできるように許可していました。当日に閉じました:アップグレードは現在402 Payment Requiredを必要とし、無料にダウングレードのみがセルフサービスです.
今回のモノエコ化に関する重要な注意点
Starsをリリースしたばかりですがサービスは現在ベータ版で、Pro機能は誰でも無料で利用できます。まだ誰も支払っていませんし、私は強く推しません。ベータ版を終了したら、有料モードに切り替え、既存のユーザー(その変更前までに登録された人)は既に作成したものに関わらず無料で利用し続けられます。ミニアプリには、創業者スタイルの「Pro Forever」オファー(12500 ⭐)があります。 — Proを有料モードが戻る前にロックインしたい人向け。必須ではありません。買わなければ、切り替わった後は無料になります.
つまり、収益化は設計上オプション付きで組み込まれています。製品が安定し始めて成長を遂げる時点で正式に公開されます.
スタック(関心がある場合)
- FastAPI 0.115 + async SQLAlchemy 2.0 + Pydantic v2
- PostgreSQL 16 (asyncpg)
- Jinja2 + HTMX + Alpine.js + Tailwind via CDN — Reactなし、ビルドステップなし
- ボットワーカー用のpython-telegram-bot v21
-
mypy --strictコミットごとにpre-commitで強制 - ~20k行のPython、850以上のpytestテスト、39件のAlembicマイグレーション
- 一線でのデプロイ:
git push→ プロダクションVPSで毎分cron-pollが実行され、マイグレーションを適用し、uvicornを再起動。~60秒で稼働。
クロードコードの使用について
クロードコード(アンソプティックのAIコーディングアシスタント)とペアプログラミングでDodayを書きました。私が隠していないように、アーキテクチャの決定は私のものですが、クロードはコードベースの記憶力が良くて早打ちだったので、クロードが助けをしました。プッシュする前に、各コミットはレビューされました。理解できなかった行は、声に出して説明できるまで再書きされました。
コードベースがAIの汚い作業の匂いをしない理由は、レールだからですmypy --strict は型エラーでビルドに失敗します。すべての挙動の変更にはテストが付属し、Jinjaのリンターはクロードが生成する悪いAlpineパターンを捉えます。それらのガイドラインがあると、AIアシスタントはただ速いペアプログラマーです。
「本物の」コーディングかどうかはあなたの定義によるものです。私はそう思います。3週間でこれだけ多くリリースしたとは思わないが、構造の好みとレビューなしにはうまくリリースすることもできなかったでしょう。
誠実な統計
- 初回コミット:2026年5月2日
- 総コミット数:511
- テスト:850
- ~20k行のPythonコード
- 活発なユーザー数:少なく、主に私の学校や友人の友人から。マーケティングを本気で試したことなんてまだない——このRedditの投稿は最初の試みの一つです。
- 有料ユーザー:0 — ベータモード、Proは誰でも無料、ライフタイムオファーは任意
- これまでの収益:$0
- ロードマップ:Familyレベルの親ダッシュボード、公開APIトークン、CapacitorでラップされたミニアプリによるネイティブiOS
要求していること
もし興味を持たれたら、ライブデモはgetdoday.ruにあります — UIはロシア語ですが、英語読者はブラウザの翻訳でナビゲートできます。github.com/SwairIt/dodayのコードベースは、すべての部品がどのように組み合わさっているかを見たい場合はより興味深いです(ミニアプリ認証、Star決済フロー、チーム共有、オプトイン機能フラグ)。
アーキテクチャや決済フローに関するフィードバックがある場合、または「未成年者でSaaSを発送しようとしている問題」にも取り組んでいる場合——意見を聞かせていただければと思います。
お客様が独自のStars統合をリリース済みの場合、一つ不確かな点があります:現在、provider_payment_charge_idをnull許容としていますが、Telegramが実際にどのタイミングで値を設定するか分かりません。分かっている方いますか?
そして、リポジトリをスターログインするなら—本当に役立つよ。私は楽しいだけでなく、結局はそれから生活を立て直したいんだ.
ロシアの15歳からお礼を言う.
編集: ロシアのティーンエージャーがRedditに投稿している理由について疑問に感じているなら — DodayはオープンソースのMITプロジェクトであり、私はロシアのユーザーだけではなく、より多くのユーザーに成長させたいです。コードベースは英語(ドキュメント文字列、変数名、コミットメッセージを除く — それらはロシア語の過去形)なので、貢献は歓迎されます。特にTelegram Starsの統合は汎用的です — Telegramを使って何かを売っている誰にでも動作します。












