#!/usr/bin/env python # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2025 # Leandro Toledo de Souza # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser Public License for more details. # # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains an object that represents a Telegram SuccessfulPayment.""" import datetime as dtm from typing import TYPE_CHECKING, Optional from telegram._payment.orderinfo import OrderInfo from telegram._telegramobject import TelegramObject from telegram._utils.argumentparsing import de_json_optional from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp from telegram._utils.types import JSONDict if TYPE_CHECKING: from telegram import Bot class SuccessfulPayment(TelegramObject): """This object contains basic information about a successful payment. Note that if the buyer initiates a chargeback with the relevant payment provider following this transaction, the funds may be debited from your balance. This is outside of Telegram's control. Objects of this class are comparable in terms of equality. Two objects of this class are considered equal, if their :attr:`telegram_payment_charge_id` and :attr:`provider_payment_charge_id` are equal. Args: currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in |tg_stars|. total_amount (:obj:`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). invoice_payload (:obj:`str`): Bot-specified invoice payload. subscription_expiration_date (:class:`datetime.datetime`, optional): Expiration date of the subscription; for recurring payments only. .. versionadded:: 21.8 is_recurring (:obj:`bool`, optional): True, if the payment is for a subscription. .. versionadded:: 21.8 is_first_recurring (:obj:`bool`, optional): True, if the payment is the first payment of a subscription. .. versionadded:: 21.8 shipping_option_id (:obj:`str`, optional): Identifier of the shipping option chosen by the user. order_info (:class:`telegram.OrderInfo`, optional): Order info provided by the user. telegram_payment_charge_id (:obj:`str`): Telegram payment identifier. provider_payment_charge_id (:obj:`str`): Provider payment identifier. Attributes: currency (:obj:`str`): Three-letter ISO 4217 currency code, or ``XTR`` for payments in |tg_stars|. total_amount (:obj:`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). invoice_payload (:obj:`str`): Bot-specified invoice payload. subscription_expiration_date (:class:`datetime.datetime`): Optional. Expiration date of the subscription; for recurring payments only. .. versionadded:: 21.8 is_recurring (:obj:`bool`): Optional. True, if the payment is for a subscription. .. versionadded:: 21.8 is_first_recurring (:obj:`bool`): Optional. True, if the payment is the first payment of a subscription. .. versionadded:: 21.8 shipping_option_id (:obj:`str`): Optional. Identifier of the shipping option chosen by the user. order_info (:class:`telegram.OrderInfo`): Optional. Order info provided by the user. telegram_payment_charge_id (:obj:`str`): Telegram payment identifier. provider_payment_charge_id (:obj:`str`): Provider payment identifier. """ __slots__ = ( "currency", "invoice_payload", "is_first_recurring", "is_recurring", "order_info", "provider_payment_charge_id", "shipping_option_id", "subscription_expiration_date", "telegram_payment_charge_id", "total_amount", ) def __init__( self, currency: str, total_amount: int, invoice_payload: str, telegram_payment_charge_id: str, provider_payment_charge_id: str, shipping_option_id: Optional[str] = None, order_info: Optional[OrderInfo] = None, subscription_expiration_date: Optional[dtm.datetime] = None, is_recurring: Optional[bool] = None, is_first_recurring: Optional[bool] = None, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(api_kwargs=api_kwargs) self.currency: str = currency self.total_amount: int = total_amount self.invoice_payload: str = invoice_payload self.shipping_option_id: Optional[str] = shipping_option_id self.order_info: Optional[OrderInfo] = order_info self.telegram_payment_charge_id: str = telegram_payment_charge_id self.provider_payment_charge_id: str = provider_payment_charge_id self.subscription_expiration_date: Optional[dtm.datetime] = subscription_expiration_date self.is_recurring: Optional[bool] = is_recurring self.is_first_recurring: Optional[bool] = is_first_recurring self._id_attrs = (self.telegram_payment_charge_id, self.provider_payment_charge_id) self._freeze() @classmethod def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "SuccessfulPayment": """See :meth:`telegram.TelegramObject.de_json`.""" data = cls._parse_data(data) data["order_info"] = de_json_optional(data.get("order_info"), OrderInfo, bot) # Get the local timezone from the bot if it has defaults loc_tzinfo = extract_tzinfo_from_defaults(bot) data["subscription_expiration_date"] = from_timestamp( data.get("subscription_expiration_date"), tzinfo=loc_tzinfo ) return super().de_json(data=data, bot=bot)