You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中查看Telegram Bot API的sendInvoice原始HTTP请求?

捕获Telegram Bot sendInvoice接口的原始HTTP请求

问题背景

用Python开发Telegram机器人时,调用sendInvoice接口后,合作支付系统反馈provider_data字段内容异常,对方要求提供该接口的原始HTTP请求以排查问题。

代码示例

import json
from telegram import Bot, Update, LabeledPrice
from telegram.ext import ContextTypes


PAYMENT_SYSTEM_TOKEN = '000000000000000'
INVOICE_PAYLOAD = 'Payload-Testing'
MATERIAL_CODES = {"202409TESTPURCHASE": ["TEST Purchase",
                                         "Checking the functioning of the payment system.",
                                         100,
                                         "https://www.python.org",
                                         "https://www.python.org/static/img/python-logo.png",
                                         "python-logo.png",
                                         ],
                  }


async def catch_callback_codes(update: Update, context: ContextTypes.DEFAULT_TYPE):
    tguser, name, lastname, username = (update.effective_user.id,
                                        update.effective_user.first_name,
                                        update.effective_user.last_name,
                                        update.effective_user.username)
    code_m = str(context.user_data['user_code'])
    title = f'{MATERIAL_CODES[code_m][0]}'
    description = f'{MATERIAL_CODES[code_m][1]}'
    label = f'Material of {code_m.upper()}'  # Turn into uppercase for a pretty view.
    amount = int(MATERIAL_CODES[code_m][2])
    currency = 'USD'
    
    if context.user_data.get('phone'):  # String of exactly 11 numeric characters.
        payment_params = {"receipt": {"phone": context.user_data['phone'],  # In string format.
                                      "items": [{"description": label,  # Up to 128 characters max.
                                                 "quantity": "1.00",
                                                 "amount": {"value": f'{amount:.2f}',  # In string format.
                                                            "currency": currency,  # In string format.
                                                            },
                                                 "vat_code": 1,
                                                 },
                                                ],
                                      },
                          }
    else:
        payment_params = {"receipt": {"email": context.user_data['email'],  # In string format.
                                      "items": [{"description": label,  # Up to 128 characters max.
                                                 "quantity": "1.00",
                                                 "amount": {"value": f'{amount:.2f}',  # In string format.
                                                            "currency": currency,  # In string format.
                                                            },
                                                 "vat_code": 1,
                                                 },
                                                ],
                                      },
                          }

    provider_data = json.dumps(payment_params)
    # print(f'provider_data {type(provider_data)}: {provider_data}')  # DEBUGGING
    # https://core.telegram.org/bots/api#sendinvoice
    await context.bot.send_invoice(tguser,  # chat_id, required.
                                   title,  # title, required.
                                   description,  # description, required.
                                   INVOICE_PAYLOAD,  # payload, required.
                                   PAYMENT_SYSTEM_TOKEN,  # provider_token, optional.
                                   currency,  # currency, required.
                                   [LabeledPrice(label, amount * 100)],  # prices, required.
                                   need_name=False,  # Optional.
                                   need_phone_number=False,  # Optional.
                                   send_phone_number_to_provider=False,  # Optional.
                                   need_email=False,  # Optional.
                                   send_email_to_provider=False,  # Optional.
                                   provider_data=provider_data,  # Optional.
                                   need_shipping_address=False,  # Optional.
                                   reply_to_message_id=update.effective_message.id)

已尝试方法

使用logging模块设置DEBUG级别日志,仅能获取接口调用参数及httpcore的流程日志,无法得到完整的原始HTTP请求内容。

日志配置代码:

import logging

logging.basicConfig(filename='debugging.log',
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    encoding='utf-8',
                    level=logging.DEBUG,
                    )

日志内容示例:

2024-09-14 13:58:53,713 - telegram.ext.ExtBot - DEBUG - Calling Bot API endpoint `sendInvoice` with parameters `{'chat_id': 0000000, 'title': 'TEST Python The Language', 'description': 'Python is a high-level, general-purpose programming language.', 'payload': 'Payload-Testing', 'provider_token': '00000000000000', 'currency': 'USD', 'prices': [LabeledPrice(amount=11100, label='Testing of 19910220PYTHON')], 'provider_data': '{"amount": {"value": "111.00", "currency": "USD"}, "receipt": {"customer": {"email": "123@123"}, "items": [{"description": "Testing of 19910220PYTHON", "amount": {"value": "111.00", "currency": "USD"}, "vat_code": 1, "quantity": "1"}]}}', 'need_name': False, 'need_phone_number': False, 'need_email': False, 'need_shipping_address': False, 'send_phone_number_to_provider': False, 'send_email_to_provider': False, 'reply_parameters': ReplyParameters(message_id=4655)}`
2024-09-14 13:58:53,720 - httpcore.http11 - DEBUG - send_request_headers.started request=<Request [b'POST']>
2024-09-14 13:58:53,721 - httpcore.http11 - DEBUG - send_request_headers.complete
2024-09-14 13:58:53,721 - httpcore.http11 - DEBUG - send_request_body.started request=<Request [b'POST']>
2024-09-14 13:58:53,722 - httpcore.http11 - DEBUG - send_request_body.complete

当前计划

打算改用requests模块直接构造请求,获取sendInvoice的原始HTTP请求内容。

可行解决方案

方案1:调整日志级别,获取完整请求内容

python-telegram-bot底层依赖httpcore,将httpcore的日志级别设为TRACE,即可输出完整的请求头和请求体:

import logging

logging.basicConfig(
    filename='debugging.log',
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    encoding='utf-8',
    level=logging.DEBUG,
)
# 开启httpcore的TRACE级别日志
logging.getLogger("httpcore").setLevel(logging.TRACE)

修改后,日志中会包含完整的HTTP请求细节,包括请求体中的provider_data字段内容。

方案2:用requests手动构造请求

跳过python-telegram-bot的封装,直接用requests调用Telegram API,可直接打印或保存完整请求:

import json
import requests

TELEGRAM_BOT_TOKEN = "你的机器人Token"
CHAT_ID = 目标用户ID
PAYMENT_SYSTEM_TOKEN = '000000000000000'
INVOICE_PAYLOAD = 'Payload-Testing'

# 构造sendInvoice参数
request_payload = {
    "chat_id": CHAT_ID,
    "title": "TEST Purchase",
    "description": "Checking the functioning of the payment system.",
    "payload": INVOICE_PAYLOAD,
    "provider_token": PAYMENT_SYSTEM_TOKEN,
    "currency": "USD",
    "prices": [{"label": "Material of 202409TESTPURCHASE", "amount": 10000}],
    "provider_data": json.dumps({
        "receipt": {
            "email": "用户邮箱",
            "items": [
                {
                    "description": "Material of 202409TESTPURCHASE",
                    "quantity": "1.00",
                    "amount": {"value": "100.00", "currency": "USD"},
                    "vat_code": 1
                }
            ]
        }
    }),
    "need_name": False,
    "need_phone_number": False,
    "send_phone_number_to_provider": False,
    "need_email": False,
    "send_email_to_provider": False,
    "need_shipping_address": False
}

# 发送请求并打印原始请求信息
api_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendInvoice"
response = requests.post(api_url, json=request_payload)

# 输出完整请求内容
print("请求URL:", api_url)
print("请求头:", dict(response.request.headers))
print("请求体:", response.request.body.decode('utf-8'))

运行后即可得到完整的原始HTTP请求,直接提供给支付系统排查。

方案3:使用抓包工具

无需修改代码,用mitmproxy、Charles等抓包工具捕获机器人的HTTP请求流量,可直接查看sendInvoice接口的完整请求细节,包括provider_data字段的实际传输内容。


内容的提问来源于stack exchange,提问作者Serge-M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:14:58