Előfizetéses hozzáférés és számlázás automatizálása
Valaki fizet, és abban a pillanatban megvan a számla meg a belépő. Lejáratkor a rendszer szépen kilépteti.
- A helyzet
- Előfizetéses tartalmat vagy szolgáltatást árulsz. A hozzáférés egy zárt csoportban van. És minden egyes vásárlónál te küldöd a meghívót, te írod a számlát, és te tartod fejben, mikor jár le.
- A megoldás
- A vásárló fizet bankkártyával, és rögtön megkapja a számlát meg az egyszer használatos belépőt. A rendszer jegyzi a lejáratot, megújításkor új számlát ír, lejáratkor pedig kilépteti az embert.
- Az eredmény
- Fizetés, számla, hozzáférés, megújítás, lejárat — ehhez senki nem nyúl kézzel. Az üzemeltető azzal foglalkozik, amiért fizetnek neki, nem az adminisztrációval.
A rendszer számokban
| Külső rendszer, amivel összeköttetésben áll | 3 — Stripe, Telegram, Számlázz.hu |
|---|---|
| Telegram-csatorna | 3 — kettő fizetős, egy ingyenes |
| Éles indulás | 2026 tavasza |
| Folyamatos együttműködés | 2025 augusztusa óta |
- Projekt
- sportelemzői információs szolgáltatás
- Szerep
- Egyedüli fejlesztő — architektúra, integrációk, üzemeltetés
- Együttműködés
- Havidíjas karbantartás, folyamatos fejlesztéssel
- 01 Vásárló bankkártyás fizetés
- 02 Stripe Checkout előfizetés, megújítás
- 03 A rendszer egyedi PHP, saját adatréteg
- 04 Telegram-belépő egyszer használatos
- 05 Magyar számla Számlázz.hu
- 06 Értesítő e-mail a teljes életciklusra
esemény · webhook
Miért nem működik az előfizetés-kezelés kézzel
Az ügyfélnek volt egy ingyenes Telegram-csatornája, és nem volt semmi, amivel pénzt lehetett volna kérni érte. Ha kézzel csinálja, akkor minden vásárlónál küldeni kell egy meghívót. Írni kell egy számlát, fel kell jegyezni valahová, hogy mikor jár le, és a lejárat napján ki kell léptetni azt az embert.
Néhány tucat vásárlóig ez megy, néhány száznál nem megy, és a hibák pont ott jönnek elő, ahol a legtöbbe kerülnek. Valaki fizet, és nem kap belépőt. Vagy valakinek lejárt az előfizetése, és bent marad. Az első egy mérges embert csinál meg egy visszatérítést, a második egyszerűen pénz, ami nem jön be.
Mit jelent ez, ha hasonló a helyzeted
Egy ilyen rendszer nem a kód mennyiségétől nehéz. Attól nehéz, hogy pénz van a végén, meg egy ajtó, ami vagy kinyílik, vagy nem. Egy rosszul betöltött oldalt a látogató újratölt, egy elmaradt belépőt viszont nem lehet újratölteni — azt kezelni kell.
Ezért az idő nagyobb része nem a jó eset megírásával megy el, hanem a rossz esetekkel: mi van, ha a fizetés csak harmadszorra sikerül, ha a szolgáltató kétszer szól ugyanarról, ha a tárhely épp nem enged ki hívást, vagy ha valaki lemond, aztán két hét múlva meggondolja magát.
Ez a rendszer 2026 tavaszán indult élesben, és azóta folyamatosan nő. Új csomagok, promóciós kampányok, számlázási finomítások. Az együttműködés 2025 augusztusa óta tart, havidíjas karbantartással.
Ha ismerős a helyzet — előfizetés, zárt hozzáférés, kézzel írt számla vagy kézzel küldött belépő —, írj pár mondatot arról, hogyan megy ez most nálad. Egy levélváltásból általában kiderül, hogy automatizálható-e, és nagyjából mekkora munka.
kristof@kristofkarner.comInnentől a megvalósítás részletei következnek: a meghozott döntések háttere, és azok a buktatók, amikbe menet közben belefutottunk. Ha csak az érdekelt, hogy mit lehet elérni, fentebb minden megvan — ez a rész a döntések indoklását mutatja.
| Kezelt fizetési eseménytípus | 11 |
|---|---|
| Egyedi kód | 82 függvény, 6 400+ sor PHP |
| Saját adatréteg | külön MySQL-táblák az állapotokhoz |
A döntések
Miért Stripe, és nem hazai fizetési kapu
A fizetést Stripe Subscriptions alapon építettem, nem SimplePay vagy Revolut integrációval. Ezt írtam az ügyfélnek az árajánlatban, még mielőtt bármihez hozzáfogtam volna:
„A fizetési megoldást Stripe rendszerrel építem ki, nem pedig SimplePay vagy Revolut integrációval. Ennek az az előnye, hogy a Stripe kifejezetten előfizetéses rendszerekre és automatizált folyamatokra van kitalálva, így összeköthető a számlázással és a Telegram beléptetéssel.” Karner Kristóf árajánlata, 2025. augusztus
Az ismétlődő terhelés, a lemondás, az újrapróbálkozás sikertelen fizetés után, a lejárat — ez mind benne van a Stripe előfizetés-kezelőjében. Egy egyszeri fizetésre kitalált kapu olcsóbb lett volna, de akkor ezt mind nekünk kellett volna megírni — és minden saját megoldás egy újabb hely, ahol pénz tud elveszni. A kedvezménykampányokat ugyanezért a Stripe Promotion Codes viszi, felhasználási korláttal és lejárati dátummal, nem a mi kódunk.
Miért a fizetési szolgáltató szól, és nem mi kérdezünk
Ebben a rendszerben minden állapotváltozást a Stripe felől érkező webhook indít, nem a mi lekérdezésünk. Ezt azért így csináltam, mert a tárhely időnként blokkolta a kimenő Stripe-hívásokat. Egy elméletben tisztább megoldás, ami kifelé hívogat, ezen a környezeten kiszámíthatatlanul elhasalt volna.
A rendszer tizenegyféle fizetési eseményt kezel. Ezek a sikeres vásárlástól a számla véglegesítésén és a meghiúsult fizetésen át az előfizetés szüneteltetéséig és megszűnéséig terjednek. Ahol muszáj kifelé hívni, ott van egy tartalék út: megy egy értesítés, hogy a műveletet kézzel is el lehessen végezni.
$ grep -oE "'[a-z_]+\.[a-z_.]+'" functions.php | sort -u
'charge.dispute.created'
'checkout.session.completed'
'customer.subscription.created'
'customer.subscription.deleted'
'customer.subscription.paused'
'customer.subscription.resumed'
'customer.subscription.updated'
'invoice.created'
'invoice.finalized'
'invoice.payment_failed'
'invoice.payment_succeeded'
Hogyan készül magyar számla automatikusan
A magyar fiskális számlákat a Számlázz.hu Agent API állítja ki, XML-alapú kéréssel, az első vásárlásnál és minden megújításnál. Erre azért van szükség, mert amit a Stripe kiállít, az nem magyar számla.
A magyar adójogszabályok pontosan előírják, mi állhat egy számlán. A tételek szövegét és formáját ezért az ügyfél könyvelőjével együtt raktuk össze, és azóta nem nyúltunk hozzá. Számlázási mezőhöz azóta sem nyúlok egyeztetés nélkül, mert egy elrontott számlatételt utólag nehéz helyrehozni.
Hogyan működik a hozzáférés-kezelés a Telegramban
Sikeres fizetés után a rendszer a Telegram Bot API-n keresztül csinál egy meghívót, ami egyszer használható és lejár. A link nem adható tovább, és nem is használható újra. Lemondáskor vagy végleges fizetési hiba után ugyanez a bot lépteti ki az embert.
Három csatorna van: kettő fizetős, egy ingyenes. Az ingyenes nem melléktermék — az a hely, ahol az érdeklődők először bejönnek.
Miért lett saját adatréteg és üzemeltetői felület
A rendszer saját MySQL-táblákat hoz létre és tart karban az előfizetések és a kiküldött meghívók állapotához. Ezt nem lehetett a WordPress alapstruktúrájára bízni, mert a felhasználói metaadat nem tranzakciós állapot tárolására való — nincs rajta megbízható egyediség-garancia.
Mellé került egy üzemeltetői felület. Hibanapló, teszt-fizetés, teszt-számlázás, promóciókezelő, és egy saját naplózó réteg minden művelethez. Ahol éles pénz mozog, ott két dolog sokat számít: látni, mi történt, és tesztelni tudni úgy, hogy közben egyetlen valódi ügyfél se vegye észre. A napló maszkolva tárolja az azonosítókat, hogy a hibakereséshez ne kelljen fölöslegesen személyes adatot bogarászni.
Ami nem nyilvánvaló
A következő négy dolog nincs benne a dokumentációkban, ezek élesben derülnek ki, és mindegyikbe elég könnyű belefutni.
Ugyanaz a fizetési esemény kétszer is megérkezhet
A Stripe újraküldi az értesítést, ha nem kap időben választ. Ez helyes viselkedés a szolgáltató részéről, de azt jelenti, hogy minden művelet lefuthat kétszer. A meghívó-küldés ezért fel van jegyezve az adatbázisban, így ugyanaz a vásárló nem kap két belépőt ugyanahhoz a csatornához. Enélkül duplikált meghívók keletkeztek volna, amiket tovább lehet adni.
A Telegramban a kiléptetés alapértelmezés szerint örökre szól
A Telegram Bot API-jában a kiléptetés
(banChatMember)
egyben tiltás is, és a tiltott ember nem tud újra belépni. A rendszer ezért a
kitiltás után rögtön
fel is oldja a tiltást.
A lejárt előfizető kikerül a csatornából, de bármikor visszajöhet fizető
ügyfélként.
$ban = wp_remote_post('https://api.telegram.org/bot'.$token.'/banChatMember', [
'body' => ['chat_id'=>$chat_id, 'user_id'=>$user_id, 'until_date'=>time()+60],
'timeout' => 15
]);
// …hibakezelés…
$unban = wp_remote_post('https://api.telegram.org/bot'.$token.'/unbanChatMember', [
'body' => ['chat_id'=>$chat_id, 'user_id'=>$user_id],
'timeout' => 15
]);
- 01 Lejárat vagy lemondás
- 02 banChatMember kilépteti — és kitiltja
- 03 unbanChatMember feloldja a tiltást
- 04 Kint van, de bármikor visszajöhet újra vásárolhat, nincs akadály
azonnal · a második hívás nélkül itt megállna
Egy alapértelmezés, amit nem vesz észre az ember, itt bezárta volna az ajtót minden visszatérő vásárló előtt. És ezt hónapokig senki nem vette volna észre — csak a pénzt, ami nem jön.
Az aláírás-ellenőrzésnek meg kell előznie a naplózást is
A beérkező webhook hitelességét a rendszer HMAC-aláírással ellenőrzi, mielőtt bármit kezdene a tartalmával — még a naplózás előtt is. Ha az ellenőrzés a naplózás után futna, akkor bárki, aki ismeri a végpont címét, tetszőleges adatot írathatna a naplóba. A hamis előfizetés-aktiváláson túl ez magában is támadási felület.
Egy elgépelés az egész webhelyet leviszi
Az üzleti logika egyetlen, több ezer soros PHP-fájlban él, amit az éles rendszer minden kérésnél betölt. Egy szintaktikai hiba itt nem hibaüzenetet ad, hanem fehér képernyőt az egész webhelyen, a fizetési folyamattal együtt. Ezért minden módosítás előtt készül egy pillanatkép a fájl éles változatáról, és minden élesítés után végigmegy egy teljes vásárlás — valódi fizetéssel, valódi számlával, valódi belépővel. Egy másik projekten ugyanez a gondolat külön élesítő szkriptekké nőtt — ott írtam róla.
Kérdések erről a munkáról
Lehet-e egy zárt Telegram-csoport hozzáférését előfizetéshez kötni?
Lehet. A Telegram Bot API-ban a bot tud olyan meghívólinket csinálni, ami egyszer használható és lejár, és ki is tud léptetni valakit. Ha ezt rákötjük a fizetési szolgáltató előfizetés-eseményeire, akkor a fizetés magától ad hozzáférést, a lemondás meg magától elveszi. Ebben a rendszerben 2026 tavasza óta így megy.
Kell-e külön magyar számlázás a Stripe mellé?
Kell, mert amit a Stripe kiállít, az nem magyar számla. Magyar vevőnek magyar fiskális számla jár, és ezt nem lehet megkerülni. Ebben a rendszerben a Számlázz.hu Agent API csinálja, XML-ben, az első vásárlásnál és minden megújításnál. A számlatételek szövegét az ügyfél könyvelőjével együtt raktuk össze, és azóta se nyúltunk hozzá.
Mi történik, ha valaki lemondja az előfizetést, majd később visszatér?
Vissza tud jönni, ha a rendszert erre megírták. A Telegram Bot API-ban a kiléptetés alapból tiltás is, és a tiltott ember nem tud újra belépni, ezért ez a rendszer a kitiltás után rögtön fel is oldja a tiltást. A lejárt előfizető kikerül a csatornából, de bármikor vehet újra. Enélkül minden visszatérő vásárló előtt becsukódna az ajtó.
Mi van, ha a tárhely blokkolja a fizetési szolgáltató felé menő hívásokat?
Akkor meg kell fordítani az irányt. Ahelyett, hogy a webhely kérdezné a fizetési szolgáltatót, a szolgáltató szól a webhelynek minden változásról. Ezt hívják webhook-alapú működésnek. Ezt a rendszert azért terveztem így, mert a tárhely időnként blokkolta a kimenő Stripe-hívásokat. Ahol muszáj kifelé hívni, ott értesítés megy, hogy a műveletet kézzel is el lehessen végezni.
Mennyi idő alatt épül meg egy ilyen rendszer?
A fejlesztés hetek kérdése, a teljes átfutás viszont hosszabb. Ennél az ügyfélnél az árajánlattól az éles indulásig több hónap telt el, mert közben ki kellett találni a csomagszerkezetet, elkészültek a jogi dokumentumok, egyeztettük a számlatételeket a könyvelővel, és az ügyfélnek is fel kellett készülnie. A fejlesztő munkája ennek csak egy darabja.
Összefoglaló
Egy sportelemzői információs szolgáltatás zárt Telegram-csatornáihoz 2025 augusztusa és 2026 tavasza között előfizetéses rendszer épült: a fizetést a Stripe Subscriptions kezeli, a magyar fiskális számlát a Számlázz.hu Agent API állítja ki XML-kéréssel, a hozzáférést a Telegram Bot API egyszer használatos meghívói adják és veszik el. Minden állapotváltozást a Stripe webhookja indít, mert a tárhely a kimenő hívásokat időnként blokkolta; a rendszer tizenegy eseménytípust kezel, HMAC-aláírást ellenőriz a naplózás előtt, és az ismételten kézbesített eseményeket az adatbázisban jegyzett meghívók alapján szűri. A kiléptetés két hívás: a banChatMember után azonnal unbanChatMember, hogy a visszatérő vásárló előtt ne záruljon be az ajtó. Az üzemeltető felülete hibanaplót, teszt-fizetést és promóciókezelőt ad. A rendszer 2026 tavasza óta él, havidíjas karbantartással.