How to capture raw HTTP request data when using Python telegram-bot library for payment processing?

I’m working on a telegram bot that handles payments and I need to debug an issue with my payment provider. They’re saying the data they receive is malformed and want me to show them the exact HTTP request being sent.

My current code:

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

PROVIDER_TOKEN = '123456789012345'
PAYMENT_PAYLOAD = 'order-verification'
PRODUCT_CATALOG = {"SKU2024TEST": ["Demo Product",
                                   "Sample item for testing payments",
                                   250,
                                   "https://example.com",
                                   "https://example.com/logo.jpg",
                                   "logo.jpg"],
                   }

async def process_purchase_request(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    first_name = update.effective_user.first_name
    
    product_key = str(context.user_data['selected_item'])
    item_title = f'{PRODUCT_CATALOG[product_key][0]}'
    item_desc = f'{PRODUCT_CATALOG[product_key][1]}'
    price_label = f'Purchase of {product_key}'
    cost = int(PRODUCT_CATALOG[product_key][2])
    
    receipt_data = {
        "receipt": {
            "email": context.user_data['user_email'],
            "items": [{
                "description": price_label,
                "quantity": "1.00",
                "amount": {
                    "value": f'{cost:.2f}',
                    "currency": "USD"
                },
                "vat_code": 1
            }]
        }
    }
    
    provider_json = json.dumps(receipt_data)
    
    await context.bot.send_invoice(
        user_id,
        item_title,
        item_desc,
        PAYMENT_PAYLOAD,
        PROVIDER_TOKEN,
        "USD",
        [LabeledPrice(price_label, cost * 100)],
        provider_data=provider_json,
        need_name=True,
        need_email=True
    )

I tried using basic logging but it only shows the parameters, not the actual HTTP request body that gets sent to Telegram’s servers. The payment provider needs to see the raw request format to figure out why the provider_data field isn’t being parsed correctly on their end.

What’s the best way to intercept and log the complete HTTP request including headers and body before it gets sent to the Telegram Bot API?

You can use mitmproxy to capture the raw HTTP traffic without modifying your code. Install it with pip install mitmproxy then run mitmdump -s capture_script.py where capture_script.py filters for telegram API calls. Set your bot to use the proxy with something like bot = Bot(token=TOKEN, request=HTTPXRequest(proxy_url='http://localhost:8080')). This approach captures everything including headers and the exact request body that telegram receives. I’ve used this method before when debugging payment issues with different providers and it shows you exactly what’s being transmitted. Much cleaner than monkey patching the underlying HTTP library and you get a complete view of the request/response cycle.

check out the httpx or requests lib underneath - you can monkey patch the send method to intercept calls. something like wrapping bot._request.post with your own function that logs everything before calling original method. works pretty well for debugging telegram api issues