Криптовалюты в Telegram

Приветствую сообщество.

Бот Telegram @wallet недавно предоставил API для приема платежей в сторонних Telegram ботах. Из крипто валют поддерживаются BTC, TON, USDT.

Необходимо зарегистрироваться на сайте, предоставить сведения о подключаемом к API боте, пройти процедуру идентификации (биометрия для физических лиц), дождаться одобрения заявки и назначения размера комиссии для ваших платежей. У меня процедура заняла чуть более суток.

После одобрения заявки получаете доступ в личный кабинет, где нужно сгенерировать ключ для доступа к API WalletPay.

После этого можно приступать к продажам. Покупателю нужно предоставить ссылку для оплаты через WalletPay товаров/услуг вашего бота. Код для получения этой ссылки может быть таким.

import requests

def get_pay_link():
    headers = {
     'Wpay-Store-Api-Key': 'YOUR-API-KEY',
     'Content-Type': 'application/json',
     'Accept': 'application/json',
    }

    payload = {
      'amount': {
        'currencyCode': 'USD',  # выставляем счет в долларах США
        'amount': '1.00',
      },
      'description': 'Goods and service.',
      'externalId': 'XXX-YYY-ZZZ',  # ID счета на оплату в вашем боте
      'timeoutSeconds': 60 * 60 * 24,  # время действия счета в секундах
      'customerTelegramUserId': '999666999',  # ID аккаунта Telegram покупателя
      'returnUrl': 'https://t.me/mybot',  # после успешной оплаты направить покупателя в наш бот
      'failReturnUrl': 'https://t.me/wallet',  # при отсутствии оплаты оставить покупателя в @wallet
    }

    response = requests.post(
      "https://pay.wallet.tg/wpay/store-api/v1/order",
      json=payload, headers=headers, timeout=10
    )
    data = response.json()

    if (response.status_code != 200) or (data['status'] not in ["SUCCESS", "ALREADY"]):
        logging.warning("# code: %s json: %s", response.status_code, data)
        return ''

    return data['data']['payLink']

Счет можно выставлять в долларах США, евро или рублях. Пересчет в BTC, TON, USDT будет выполнен по курсу WalletPay.

Для подтверждения факта оплаты счета, WalletPay предоставляет две опции:

  • периодический опрос состояния счета с вашей стороны.

  • POST-запрос на указанный вами в личном кабинете https адрес (webhook в терминах WalletPay).

Я использовал второй вариант. Код обработчика вебхука может быть таким.

from flask import Flask, request

app = Flask(__name__)

@app.route('/tgwallet/ipn', methods=['POST'])
def ipn_tgwallet():
    for event in request.get_json():
        if event["type"] == "ORDER_PAID":
            data = event["payload"]
            print("Оплачен счет N {} на сумму {} {}. Оплата {} {}.".format(
              data["externalId"],  # ID счета в вашем боте, который мы указывали при создании ссылки для оплаты
              data["orderAmount"]["amount"],  # Сумма счета, указанная при создании ссылки для оплаты
              data["orderAmount"]["currencyCode"],  # Валюта счета
              data["selectedPaymentOption"]["amount"]["amount"],  # Сколько оплатил покупатель
              data["selectedPaymentOption"]["amount"]["currencyCode"]  # В какой криптовалюте
            ))

    # нужно всегда возвращать код 200, чтобы WalletPay не делал повторных вызовов вебхука
    return 'OK'

Прежде чем передавать оплаченный товар или услугу, нужно убедиться, что вызов вебхука пришел из WalletPay, а не от злоумышленников, жаждущих заполучить наш товар бесплатно.

Для этого WalletPay предлагает две опции:

  • проверка принадлежности IP вызова к пулу IP адресов WalletPay;

  • проверка хеша, вычисленного на основе данных вызова вебхука и вашего ключа API.

Список IP адресов WalletPay можно найти в документации, а для проверки хеша можно использовать следующий код.

import base64, hashlib, hmac

ENCODING = 'utf-8'

def is_valid(flask_request):
    text = '.'.join([
      flask_request.method,  # 'POST'
      flask_request.path,  # нужно использовать часть адреса без имени домена, '/tgwallet/ipn' в нашем случае
      flask_request.headers.get('WalletPay-Timestamp'),
      base64.b64encode(flask_request.get_data()).decode(ENCODING),
    ])
    signature = base64.b64encode(hmac.new(
      bytes('YOUR-API-KEY', ENCODING),
      msg=bytes(text, ENCODING),
      digestmod=hashlib.sha256
    ).digest())

    return flask_request.headers.get('Walletpay-Signature') == signature.decode(ENCODING)

Затем использовать функцию is_valid для проверки в обработчике вебхука.

Спасибо за внимание.

Комментарии (6)


  1. domage
    02.08.2023 06:37
    +3

    С самого появления этого бота было очень интересно, а кто является его разработчиком и мэнтейнером? Найти эту информацию невозможно.

    Даже если мы найдём веб-сайт этого проекта (https://pay.wallet.tg/) и откроем условия использования (https://pay.wallet.tg/static/documents/terms_of_use.pdf) мы там не найдём даже названия организации, которая предоставляет этот сервис. Кстати, я даже не уверен, что это тот самый проект.

    Единственное, что хоть как-то связывает этого бота с "реальной жизнью", так это строчка "This Agreement is governed by the applicable laws of the Republic of Seychelles".

    Как говорится, "Если вы не отзовётесь мы напишем в Спортлото".


    1. vb64 Автор
      02.08.2023 06:37

      вопрос конечно интересный. при выводе средств из него в фиатную валюту в платежке будет указан источник платежа.

      конечно не факт, что это будет реальная контора, но конец цепочки можно будет увидеть.

      с другой стороны, использования для бота юзернейма, не оканчивающегося на 'bot', говорит о каком-то взаимодействии с командой Telegram.

      насколько я понимаю, такие юзернеймы выдают по запросу и далеко не всем.


      1. Aelliari
        02.08.2023 06:37

        насколько я понимаю, такие юзернеймы выдают по запросу и далеко не всем.

        Больше нет, теперь есть штатная возможность получить такой юзернейм для бота (но «галочки» к нему это не добавит), стоит применено 6000$ (5000 TON), ну и с оглядкой на «отказ от ответственности» со стороны fragment


      1. domage
        02.08.2023 06:37

        "Ах, опять эта проклятая неизвестность!"

        Я прекрасно понимаю почему так было сделано. Почему бы и нет? Если нет разработчиков, то и спросить не с кого.

        Вопрос у меня - к потенциальным пользователям этого бота. Вы действительно готовы доверить свои деньги (хоть и виртуальные) проекту, который прячет информацию о своих разработчиках и аффилированной организации?

        Что мешает этому боту завтра просто исчезнуть?

        Edit: Всем потенциальным пользователям. Учтите, что этот "кошелёк" на самом деле не на вашем устройстве. У вас нет ключей, которые позволили бы вам управлять вашими активами. Так называемый "кастодиальный" кошелёк означает, что вам просто рисуют циферки, которые отображают состояние реального кошелька, принадлежащего сторонней организации.


        1. aanovik42
          02.08.2023 06:37

          Как обычно, it depends. В 00-е весь рунет держался на разного рода вебманях, в 10-е пышным цветом цвели криптобиржи разной степени мутности. Если понимание рисков заложено в модель работы, то почему бы и нет.


          1. domage
            02.08.2023 06:37
            +1

            Действительно, такие механизмы были очень распространены. Однако, даже по сравнению с Webmoney, тут какой-то другой уровень безумства, на мой взгляд.

            1) У Webmoney указана организация, которая обеспечивает ее разработку и поддержку (https://www.webmoney.ru/rus/subjects/administrator.shtml) Если что-то идёт не так, вы можете к ним прийти ножками, либо подать на них в суд (Vytenio g. 4, LT-03113 Vilnius, Lithuania).

            2) По каждому типу кошельков Webmoney действуют отдельные гаранты, которые являются юридическими лицами, зарегистрированными в разных странах

            3) У Webmoney есть механизм Арбитража.

            И так далее, и тому подобное.

            В случае данного бота, нам сообщают, что если вы испытываете какую-то фрустрацию, вы можете испытывать ее дальше, т.к. никто никому ничего не должен.

            Предположим, что завтра вы приходите, а бота нет. Ну вот так случилось: телеграм есть, а бота нет. И что? А ничего, все свободны.

            Через неделю появится другой бот, и "На дворе кол, на колу висит мочало, начинай сначала". Никаких репутационных издержек никто не несёт.