Invoice

The Invoice class represents an invoice for payment in Telegram. It contains information about the payment, such as title, description, currency, and total amount.

Overview

The Invoice class is a Pydantic model that represents an invoice for payment in Telegram. It contains information about the payment, such as title, description, currency, and total amount.

from gpgram.types.payments import Invoice

# Access an invoice from a message
invoice = message.invoice

# Access invoice properties
title = invoice.title
description = invoice.description
currency = invoice.currency
total_amount = invoice.total_amount

Note

The Invoice class is a Pydantic model that validates and converts the raw JSON data from Telegram into a Python object with proper types.

Warning

To use payments in your bot, you need to enable payments with BotFather and set up a payment provider. See the Telegram Payments API for more information.

Properties

The Invoice class has the following properties:

  • title (str): Product name

  • description (str): Product description

  • start_parameter (str): Unique bot deep-linking parameter that can be used to generate this invoice

  • currency (str): Three-letter ISO 4217 currency code

  • total_amount (int): Total price in the smallest units of the currency (integer, not float/double). For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).

Methods

from_dict

@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'Invoice':
    """
    Create an Invoice from a dictionary.
    
    Args:
        data: Dictionary representation of the invoice
        
    Returns:
        An Invoice instance
    """

Creates an Invoice instance from a dictionary representation of an invoice.

Parameters:

  • data (Dict[str, Any]): Dictionary representation of the invoice

Returns:

  • Invoice: An Invoice instance

to_dict

def to_dict(self) -> Dict[str, Any]:
    """
    Convert the invoice to a dictionary.
    
    Returns:
        Dictionary representation of the invoice
    """

Converts the Invoice instance to a dictionary representation.

Returns:

  • Dict[str, Any]: Dictionary representation of the invoice

Creating and Sending Invoices

To create and send an invoice, you need to use the send_invoice method of the Bot class. Here’s an example:

@router.message(CommandFilter('buy'))
async def buy_command(message, bot):
    # Create labeled prices
    prices = [
        {
            "label": "Product",
            "amount": 1000  # $10.00
        },
        {
            "label": "Tax",
            "amount": 200   # $2.00
        }
    ]
    
    # Send an invoice
    await bot.send_invoice(
        chat_id=message.chat.id,
        title="Product Title",
        description="Product Description",
        payload="unique_payment_payload",
        provider_token="YOUR_PAYMENT_PROVIDER_TOKEN",
        currency="USD",
        prices=prices,
        # Optional parameters
        photo_url="https://example.com/product.jpg",
        photo_width=600,
        photo_height=400,
        need_name=True,
        need_phone_number=True,
        need_email=True,
        need_shipping_address=True,
        is_flexible=True,  # If you want to offer different shipping options
        disable_notification=False,
        reply_to_message_id=None,
        reply_markup=None
    )

Handling Payment Callbacks

When a user makes a payment, Telegram sends several updates to your bot. You need to handle these updates to complete the payment process:

# Handle pre-checkout queries
@router.pre_checkout_query()
async def pre_checkout_query_handler(pre_checkout_query, bot):
    # Here you can check if the order is still valid
    # If everything is okay, answer the pre-checkout query
    await bot.answer_pre_checkout_query(
        pre_checkout_query_id=pre_checkout_query.id,
        ok=True
    )
    
    # If there's a problem, you can reject the payment
    # await bot.answer_pre_checkout_query(
    #     pre_checkout_query_id=pre_checkout_query.id,
    #     ok=False,
    #     error_message="Payment cannot be completed at this time."
    # )

# Handle successful payments
@router.message(lambda message: message.successful_payment is not None)
async def successful_payment_handler(message, bot):
    # Payment was successful, you can now fulfill the order
    payment = message.successful_payment
    
    # Log the payment
    logging.info(f"Payment for {payment.total_amount / 100} {payment.currency} received from {message.from_user.id}")
    
    # Thank the user
    await bot.send_message(
        chat_id=message.chat.id,
        text=f"Thank you for your payment of {payment.total_amount / 100} {payment.currency}!\n"
             f"We've received your order and will process it shortly."
    )

Shipping Options

If you set is_flexible=True when sending an invoice, you need to handle shipping queries to provide shipping options:

# Handle shipping queries
@router.shipping_query()
async def shipping_query_handler(shipping_query, bot):
    # Provide shipping options based on the shipping address
    shipping_options = [
        {
            "id": "standard",
            "title": "Standard Shipping",
            "prices": [
                {
                    "label": "Standard Shipping",
                    "amount": 500  # $5.00
                }
            ]
        },
        {
            "id": "express",
            "title": "Express Shipping",
            "prices": [
                {
                    "label": "Express Shipping",
                    "amount": 1000  # $10.00
                }
            ]
        }
    ]
    
    # Answer the shipping query
    await bot.answer_shipping_query(
        shipping_query_id=shipping_query.id,
        ok=True,
        shipping_options=shipping_options
    )
    
    # If shipping to the specified address is not possible
    # await bot.answer_shipping_query(
    #     shipping_query_id=shipping_query.id,
    #     ok=False,
    #     error_message="Sorry, we can't ship to your address."
    # )

See Also