# Przepis: bot w Telegramie

> Sprzedawaj komendy bota, rolę lub prywatną grupę. Każdy użytkownik dostaje własną fakturę; podpisany webhook otwiera dostęp.

Bot nie widzi pieniędzy. Na `/buy` wysyła użytkownikowi jego własny link do faktury; Twój serwer słyszy `invoice.fulfilled` i otwiera dostęp. Każda płatna komenda pyta Perly Pay, więc po restarcie nic nie ginie. Discord — tak samo, przez rolę.

> **Uwaga:** Z asystentem: ten przepis realizuje w Twoim projekcie skill `sell-bot-access` wtyczki Perly Pay. Działający przykład to `examples/telegram-bot` (MIT) w repozytorium wtyczki.

## Jak to działa

1. **Produkt i cena** — Jednorazowa lub dożywotnia — „na zawsze”, okresowa — dla przepustek, subskrypcja — dla członkostwa z odnowieniem fakturą.
2. **Klient dla każdego użytkownika czatu** — `external_id: "tg:<user id>"`. O e-mail pytaj tylko przy subskrypcjach: tam idą odnowienia.
3. **/buy** — Faktura z identyfikatorem czatu w `metadata`, wysłana przyciskiem. Jedna faktura na użytkownika na dzień — dzięki kluczowi idempotencji.
4. **Otwórz dostęp** — Na `invoice.fulfilled` weź identyfikator czatu z `metadata` i odpowiedz: wiadomość, jednorazowe zaproszenie, rola.
5. **Płatne komendy** — `entitlements.check({ customer_external_id: "tg:<id>", product })`.

**/buy**

```js
const invoice = await pay.invoices.create(
  { line_items: [{ price: PRICE }], customer: customer.id, metadata: { chat_id: String(chatId) } },
  { idempotencyKey: `buy-${userId}-${today}` },
);
await tg("sendMessage", { chat_id: chatId, text: "Pay:", reply_markup: { inline_keyboard: [[{ text: "Pay", url: invoice.url }]] } });
```

## Uruchom przykład

1. **Zainstaluj** — `npm install` w `examples/telegram-bot` (Node 20.12+).
2. **Klucz** — Skopiuj `.env.example` do `.env` i wpisz klucz testowy (`sk_test_…`) w `PERLY_PAY_SECRET_KEY`.
3. **Przygotuj** — `npm run setup` tworzy produkt i cenę Twoim kluczem i drukuje ich identyfikatory do `.env`.
4. **Uruchom** — `npm start` (lub `npm run dev`), jak mówi jego README.
5. **Zapłać bez portfela** — Napisz do bota `/buy`, otwórz Pay i kliknij **Simulate payment**: bot napisze „Payment confirmed”, a `/secret` odpowie.

## Pułapki

- Jeden wspólny link do płatności dla wszystkich: nie widać, kto zapłacił. Faktura dla każdego, z identyfikatorem czatu.
- Otwieranie dostępu, gdy użytkownik kliknął „Zapłaciłem”. Otwiera tylko webhook albo `entitlements.check`.
- Dostęp w pamięci bota. Po restarcie go nie ma; pytaj Perly Pay.
