Stripe + mock
Celý proces jde vyzkoušet i bez skutečné platby.

Web fiktivní posilovny zaměřený na tvorbu turniketového systému. Web je v robo tech stylu, kdo by nechtěl naprat sílu legendárního Tonnyho S.. Moderní styl není to jediné unikátní na tomto projektu. Další unikátností je vstup 24/7 díky terminálovému systému, stačí se na webu zadat email, zaplatiti poplatek a otevře se vám váš vlastní svět. Díky QR kódu který naleznete v emailu se dostanete přes stránku /terminál přímo do budovy.
Nejde jen o nákup. Po zaplacení musí vzniknout vstupenka, QR kód a e-mail, se kterým pak člověk projde turniketem.
Nákup je jen začátek. Po zaplacení se musí rozjet celý řetězec a na jeho konci stojí člověk před turniketem s QR kódem v mobilu.
Celý proces jde vyzkoušet i bez skutečné platby.
Vstupenka má vlastní platnost.
Turniket ověří, jestli je vstupenka platná.
Osobní údaje jsou zašifrované.
Platba, vstupenka, vstup a ochrana osobních údajů mají každé svůj úkol. V dalších kapitolách ukazuju, jak je to spojené.
async def _mock_checkout(pass_type: str, user: dict | None = None, guest_email: str | None = None) -> str:
"""
Skips Stripe entirely: records a "paid" payment, issues the ticket and
sends the real e-mail — so the whole flow (except the actual card payment)
is exercised. Controlled by the admin panel's "mock payments" toggle.
"""
now = datetime.now(timezone.utc)
payment_doc = {
"user_id": str(user["_id"]) if user else None,
"guest_email": guest_email,
"pass_type": pass_type,
"stripe_session_id": None,
"status": "paid",
"amount": 0,
"currency": "czk",
"mock": True,
"created_at": now,
}
result = await payments_col.insert_one(payment_doc)
await create_ticket_and_notify(
pass_type, str(result.inserted_id), user=user, guest_email=guest_email
)
async def create_ticket_and_notify(
pass_type: str, payment_id: str, user: dict | None = None, guest_email: str | None = None
) -> dict:
user_id = str(user["_id"]) if user else None
ticket_doc = build_ticket_document(user_id, pass_type, payment_id)
if guest_email:
ticket_doc["guest_email"] = guest_email
await tickets_col.insert_one(ticket_doc)
if user:
data_key = unwrap_data_key(user["data_key_wrapped"])
profile = decrypt_profile(data_key, user["encrypted_profile"])
to_email = user["email"]
name = profile.get("name", "")
else:
to_email = guest_email
name = "zákazníku"
qr_base64 = make_qr_png_base64(ticket_doc["token_id"])
send_ticket_email(to_email, name, ticket_doc["label"], qr_base64)
return ticket_doc
def generate_data_key() -> bytes:
"""A fresh symmetric key, unique per user."""
return Fernet.generate_key()
def wrap_data_key(data_key: bytes) -> str:
"""Encrypt a user's data key with the master key, for storage."""
return _master_fernet.encrypt(data_key).decode()
def unwrap_data_key(wrapped: str) -> bytes:
"""Decrypt a user's data key using the master key."""
return _master_fernet.decrypt(wrapped.encode())
def encrypt_profile(data_key: bytes, profile: dict) -> str:
f = Fernet(data_key)
payload = json.dumps(profile).encode()
return f.encrypt(payload).decode()
Turniket načte QR kód a zeptá se serveru, jestli je vstupenka platná. Pokud ano, pustí člověka dál. U jednorázové vstupenky se vstup odečte.
Vstupenka přijde e-mailem, QR kód je vidět přímo v textu i v příloze. Funguje s libovolným e-mailovým poskytovatelem.
Tady se potkává hodně služeb: platba, databáze, e-mail a QR kód. Kdyby po platbě selhal e-mail, měl by člověk zaplaceno bez vstupenky. Proto je vydání vstupenky oddělené a jde ho zopakovat.
Součástí je i administrace, správa účtu, pravidelný úklid dat a stránka o ochraně osobních údajů. Je to blíž malému skutečnému systému než ukázkovému nákupu.
Žádná technologie tu není jen pro parádu. Tady je rychlý přehled, kdo za co odpovídá.
Nejde mi jen o to, jak to vypadá. Baví mě hlavně to, co je pod tím: kudy data tečou, co se validuje, co může selhat a proč jsem to udělala právě takhle.
Napiš mi