pyrofork: Add high level support for pre-checkout queries and service messages for successful payments

* Add high level support for pre-checkout queries

* Add high level support for incoming payments

* Update and fix documentation

---------

Co-authored-by: KurimuzonAkuma <31959970+KurimuzonAkuma@users.noreply.github.com>
Signed-off-by: wulan17 <wulan17@nusantararom.org>
This commit is contained in:
coglione 2024-06-01 00:01:22 +02:00 committed by wulan17
parent 8b52f1f71d
commit 4cec859126
No known key found for this signature in database
GPG key ID: 318CD6CD3A6AC0A5
19 changed files with 626 additions and 7 deletions

View file

@ -357,6 +357,7 @@ def pyrogram_api():
set_chat_menu_button
get_chat_menu_button
answer_web_app_query
answer_pre_checkout_query
get_bot_info
set_bot_info
""",
@ -504,6 +505,7 @@ def pyrogram_api():
ReactionType
MessageReactionUpdated
MessageReactionCountUpdated
SuccessfulPayment
""",
stories="""
Stories
@ -546,6 +548,9 @@ def pyrogram_api():
MenuButtonWebApp
MenuButtonDefault
SentWebAppMessage
PaymentInfo
PreCheckoutQuery
ShippingAddress
""",
bot_commands="""
Bot commands
@ -592,6 +597,10 @@ def pyrogram_api():
InlineQueryResultVoice
ChosenInlineResult
""",
pre_checkout_query="""
PreCheckoutQuery
PreCheckoutQuery.answer
""",
input_message_content="""
InputMessageContent
InputMessageContent
@ -742,6 +751,10 @@ def pyrogram_api():
InlineQuery
InlineQuery.answer
""",
pre_checkout_query="""
PreCheckoutQuery
PreCheckoutQuery.answer
""",
chat_join_request="""
ChatJoinRequest
ChatJoinRequest.approve

View file

@ -101,6 +101,19 @@ InlineQuery
{inline_query_toctree}
PreCheckoutQuery
-----------
.. hlist::
:columns: 2
{pre_checkout_query_hlist}
.. toctree::
:hidden:
{pre_checkout_query_toctree}
ChatJoinRequest
---------------

View file

@ -39,6 +39,7 @@ from pyrogram.handlers import (
RawUpdateHandler,
InlineQueryHandler,
PollHandler,
PreCheckoutQueryHandler,
ConversationHandler,
ChosenInlineResultHandler,
ChatMemberUpdatedHandler,
@ -51,7 +52,7 @@ from pyrogram.raw.types import (
UpdateBotNewBusinessMessage, UpdateBotDeleteBusinessMessage, UpdateBotEditBusinessMessage,
UpdateEditMessage, UpdateEditChannelMessage,
UpdateDeleteMessages, UpdateDeleteChannelMessages,
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery,
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, UpdateBotPrecheckoutQuery,
UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll,
UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant, UpdateBotStopped,
UpdateBotChatInviteRequester, UpdateStory,
@ -80,6 +81,7 @@ class Dispatcher:
MESSAGE_BOT_NA_REACTION_UPDATES = (UpdateBotMessageReaction,)
MESSAGE_BOT_A_REACTION_UPDATES = (UpdateBotMessageReactions,)
BOT_BUSSINESS_CONNECT_UPDATES = (UpdateBotBusinessConnect,)
PRE_CHECKOUT_QUERY_UPDATES = (UpdateBotPrecheckoutQuery,)
def __init__(self, client: "pyrogram.Client"):
self.client = client
@ -191,6 +193,12 @@ class Dispatcher:
StoryHandler
)
async def pre_checkout_query_parser(update, users, chats):
return (
await pyrogram.types.PreCheckoutQuery._parse(self.client, update, users),
PreCheckoutQueryHandler
)
async def message_bot_na_reaction_parser(update, users, chats):
return (
pyrogram.types.MessageReactionUpdated._parse(self.client, update, users, chats),
@ -224,6 +232,7 @@ class Dispatcher:
Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser,
Dispatcher.CHAT_JOIN_REQUEST_UPDATES: chat_join_request_parser,
Dispatcher.NEW_STORY_UPDATES: story_parser,
Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser,
Dispatcher.MESSAGE_BOT_NA_REACTION_UPDATES: message_bot_na_reaction_parser,
Dispatcher.MESSAGE_BOT_A_REACTION_UPDATES: message_bot_a_reaction_parser,
Dispatcher.BOT_BUSSINESS_CONNECT_UPDATES: bot_business_connect_parser

View file

@ -111,3 +111,6 @@ class MessageServiceType(AutoName):
BOOST_APPLY = auto()
"Boost apply"
SUCCESSFUL_PAYMENT = auto()
"Successful payment"

View file

@ -28,6 +28,7 @@ from pyrogram.types import (
InlineKeyboardMarkup,
InlineQuery,
Message,
PreCheckoutQuery,
ReplyKeyboardMarkup,
Story,
Update,
@ -697,6 +698,17 @@ video_chat_members_invited = create(video_chat_members_invited_filter)
"""Filter messages for voice chat invited members"""
# endregion
# region successful_payment_filter
async def successful_payment_filter(_, __, m: Message):
return bool(m.successful_payment)
successful_payment = create(successful_payment_filter)
"""Filter messages for successful payments"""
# endregion
# region service_filter
@ -710,7 +722,7 @@ service = create(service_filter)
A service message contains any of the following fields set: *left_chat_member*,
*new_chat_title*, *new_chat_photo*, *delete_chat_photo*, *group_chat_created*, *supergroup_chat_created*,
*channel_chat_created*, *migrate_to_chat_id*, *migrate_from_chat_id*, *pinned_message*, *game_score*,
*video_chat_started*, *video_chat_ended*, *video_chat_members_invited*.
*video_chat_started*, *video_chat_ended*, *video_chat_members_invited*, *successful_payment*, *successful_payment*.
"""
@ -909,6 +921,7 @@ def regex(pattern: Union[str, Pattern], flags: int = 0):
- :obj:`~pyrogram.types.Message`: The filter will match ``text`` or ``caption``.
- :obj:`~pyrogram.types.CallbackQuery`: The filter will match ``data``.
- :obj:`~pyrogram.types.InlineQuery`: The filter will match ``query``.
- :obj:`~pyrogram.types.PreCheckoutQuery`: The filter will match ``payload``.
When a pattern matches, all the `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ are
stored in the ``matches`` field of the update object itself.
@ -928,6 +941,8 @@ def regex(pattern: Union[str, Pattern], flags: int = 0):
value = update.data
elif isinstance(update, InlineQuery):
value = update.query
elif isinstance(update, PreCheckoutQuery):
value = update.payload
else:
raise ValueError(f"Regex filter doesn't work with {type(update)}")

View file

@ -32,6 +32,7 @@ from .edited_bot_business_message_handler import EditedBotBusinessMessageHandler
from .inline_query_handler import InlineQueryHandler
from .message_handler import MessageHandler
from .poll_handler import PollHandler
from .pre_checkout_query_handler import PreCheckoutQueryHandler
from .raw_update_handler import RawUpdateHandler
from .user_status_handler import UserStatusHandler
from .story_handler import StoryHandler

View file

@ -0,0 +1,50 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Callable
from .handler import Handler
class PreCheckoutQueryHandler(Handler):
"""The PreCheckoutQueryHandler handler class. Used to handle pre-checkout queries coming from buy buttons.
It is intended to be used with :meth:`~pyrogram.Client.add_handler`
For a nicer way to register this handler, have a look at the
:meth:`~pyrogram.Client.on_pre_checkout_query` decorator.
Parameters:
callback (``Callable``):
Pass a function that will be called when a new PreCheckoutQuery arrives. It takes *(client, pre_checkout_query)*
as positional arguments (look at the section below for a detailed description).
filters (:obj:`Filters`):
Pass one or more filters to allow only a subset of callback queries to be passed
in your callback function.
Other parameters:
client (:obj:`~pyrogram.Client`):
The Client itself, useful when you want to call other API methods inside the message handler.
pre_checkout_query (:obj:`~pyrogram.types.PreCheckoutQuery`):
The received callback query.
"""
def __init__(self, callback: Callable, filters=None):
super().__init__(callback, filters)

View file

@ -19,6 +19,7 @@
from .answer_callback_query import AnswerCallbackQuery
from .answer_inline_query import AnswerInlineQuery
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .answer_web_app_query import AnswerWebAppQuery
from .delete_bot_commands import DeleteBotCommands
from .get_bot_commands import GetBotCommands
@ -55,6 +56,7 @@ class Bots(
GetBotInfo,
SetChatMenuButton,
GetChatMenuButton,
AnswerWebAppQuery
AnswerWebAppQuery,
AnswerPreCheckoutQuery
):
pass

View file

@ -0,0 +1,65 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
class AnswerPreCheckoutQuery:
async def answer_pre_checkout_query(
self: "pyrogram.Client",
pre_checkout_query_id: str,
success: bool = None,
error: str = None
):
"""Send answers to pre-checkout queries.
.. include:: /_includes/usable-by/bots.rst
Parameters:
pre_checkout_query_id (``str``):
Unique identifier for the query to be answered.
success (``bool``, *optional*):
Set this flag if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order.
Otherwise do not set it, and set the error field, instead.
error (``str``, *optional*):
Error message in human readable form that explains the reason for failure to proceed with the checkout.
Required if ``success`` isn't set.
Returns:
``bool``: True, on success.
Example:
.. code-block:: python
# Proceed with the order
await app.answer_pre_checkout_query(query_id, success=True)
# Answer with error message
await app.answer_pre_checkout_query(query_id, error=error)
"""
return await self.invoke(
raw.functions.messages.SetBotPrecheckoutResults(
query_id=int(pre_checkout_query_id),
success=success or None,
error=error or None
)
)

View file

@ -40,7 +40,7 @@ class GetChatMember:
Unique identifier (int) or username (str) of the target chat.
You can also use chat public link in form of *t.me/<username>* (str).
user_id (``int`` | ``str``)::
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target user.
For you yourself you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).

View file

@ -31,6 +31,7 @@ from .on_edited_bot_business_message import OnEditedBotBusinessMessage
from .on_inline_query import OnInlineQuery
from .on_message import OnMessage
from .on_poll import OnPoll
from .on_pre_checkout_query import OnPreCheckoutQuery
from .on_raw_update import OnRawUpdate
from .on_user_status import OnUserStatus
from .on_story import OnStory
@ -57,6 +58,7 @@ class Decorators(
OnChatJoinRequest,
OnStory,
OnMessageReactionUpdated,
OnMessageReactionCountUpdated
OnMessageReactionCountUpdated,
OnPreCheckoutQuery
):
pass

View file

@ -0,0 +1,62 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Callable, Optional, Union
import pyrogram
from pyrogram.filters import Filter
class OnPreCheckoutQuery:
def on_pre_checkout_query(
self: Union["OnPreCheckoutQuery", Filter, None] = None,
filters: Optional[Filter] = None,
group: int = 0,
) -> Callable:
"""Decorator for handling pre-checkout queries.
This does the same thing as :meth:`~pyrogram.Client.add_handler` using the
:obj:`~pyrogram.handlers.PreCheckoutQueryHandler`.
Parameters:
filters (:obj:`~pyrogram.filters`, *optional*):
Pass one or more filters to allow only a subset of callback queries to be passed
in your function.
group (``int``, *optional*):
The group identifier, defaults to 0.
"""
def decorator(func: Callable) -> Callable:
if isinstance(self, pyrogram.Client):
self.add_handler(pyrogram.handlers.PreCheckoutQueryHandler(func, filters), group)
elif isinstance(self, Filter) or self is None:
if not hasattr(func, "handlers"):
func.handlers = []
func.handlers.append(
(
pyrogram.handlers.PreCheckoutQueryHandler(func, self),
group if filters is None else filters
)
)
return func
return decorator

View file

@ -33,7 +33,7 @@ class UnblockUser:
.. include:: /_includes/usable-by/users.rst
Parameters:
user_id (``int`` | ``str``)::
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target user.
For you yourself you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).

View file

@ -40,12 +40,16 @@ from .menu_button import MenuButton
from .menu_button_commands import MenuButtonCommands
from .menu_button_default import MenuButtonDefault
from .menu_button_web_app import MenuButtonWebApp
from .payment_info import PaymentInfo
from .pre_checkout_query import PreCheckoutQuery
from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove
from .request_peer_type_channel import RequestPeerTypeChannel
from .request_peer_type_chat import RequestPeerTypeChat
from .request_peer_type_user import RequestPeerTypeUser
from .sent_web_app_message import SentWebAppMessage
from .shipping_address import ShippingAddress
from .successful_payment import SuccessfulPayment
from .web_app_info import WebAppInfo
__all__ = [
@ -78,5 +82,9 @@ __all__ = [
"MenuButtonCommands",
"MenuButtonWebApp",
"MenuButtonDefault",
"SentWebAppMessage"
"SentWebAppMessage",
"ShippingAddress",
"PaymentInfo",
"PreCheckoutQuery",
"SuccessfulPayment"
]

View file

@ -0,0 +1,52 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from ..object import Object
class PaymentInfo(Object):
"""Contains information about a payment.
Parameters:
name (``str``, *optional*):
User's name.
phone_number (``str``, *optional*):
User's phone number.
email (``str``, *optional*):
User's email.
shipping_address (:obj:`~pyrogram.types.ShippingAddress`, *optional*):
User's shipping address.
"""
def __init__(
self, *,
name: str = None,
phone_number: str = None,
email: str = None,
shipping_address: "types.ShippingAddress" = None
):
super().__init__()
self.name = name
self.phone_number = phone_number
self.email = email
self.shipping_address = shipping_address

View file

@ -0,0 +1,140 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, List, Match, Optional
import pyrogram
from pyrogram import raw, enums
from pyrogram import types
from ..object import Object
from ..update import Update
from ... import utils
class PreCheckoutQuery(Object, Update):
"""An incoming pre-checkout query from a buy button in an inline keyboard.
Parameters:
id (``str``):
Unique identifier for this query.
from_user (:obj:`~pyrogram.types.User`):
User who sent the query.
currency (``str``):
Three-letter ISO 4217 currency code.
total_amount (``int``):
Total price in the smallest units of the currency.
payload (``str``):
Bot specified invoice payload.
shipping_option_id (``str``, *optional*):
Identifier of the shipping option chosen by the user.
payment_info (:obj:`~pyrogram.types.PaymentInfo`, *optional*):
Payment information provided by the user.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
id: str,
from_user: "types.User",
currency: str,
total_amount: int,
payload: str,
shipping_option_id: str = None,
payment_info: "types.PaymentInfo" = None
):
super().__init__(client)
self.id = id
self.from_user = from_user
self.currency = currency
self.total_amount = total_amount
self.payload = payload
self.shipping_option_id = shipping_option_id
self.payment_info = payment_info
@staticmethod
async def _parse(client: "pyrogram.Client", pre_checkout_query, users) -> "PreCheckoutQuery":
# Try to decode pre-checkout query payload into string. If that fails, fallback to bytes instead of decoding by
# ignoring/replacing errors, this way, button clicks will still work.
try:
payload = pre_checkout_query.payload.decode()
except (UnicodeDecodeError, AttributeError):
payload = pre_checkout_query.payload
return PreCheckoutQuery(
id=str(pre_checkout_query.query_id),
from_user=types.User._parse(client, users[pre_checkout_query.user_id]),
currency=pre_checkout_query.currency,
total_amount=pre_checkout_query.total_amount,
payload=payload,
shipping_option_id=pre_checkout_query.shipping_option_id,
payment_info=types.PaymentInfo(
name=pre_checkout_query.info.name,
phone_number=pre_checkout_query.info.phone,
email=pre_checkout_query.info.email,
shipping_address=types.ShippingAddress(
street_line1=pre_checkout_query.info.shipping_address.street_line1,
street_line2=pre_checkout_query.info.shipping_address.street_line2,
city=pre_checkout_query.info.shipping_address.city,
state=pre_checkout_query.info.shipping_address.state,
post_code=pre_checkout_query.info.shipping_address.post_code,
country_code=pre_checkout_query.info.shipping_address.country_iso2
)
) if pre_checkout_query.info else None,
client=client
)
async def answer(self, success: bool = None, error: str = None):
"""Bound method *answer* of :obj:`~pyrogram.types.PreCheckoutQuery`.
Use this method as a shortcut for:
.. code-block:: python
await client.answer_pre_checkout_query(
pre_checkout_query.id,
success=True
)
Example:
.. code-block:: python
await pre_checkout_query.answer(success=True)
Parameters:
success (``bool`` *optional*):
If true, an alert will be shown by the client instead of a notification at the top of the chat screen.
Defaults to False.
error (``bool`` *optional*):
If true, an alert will be shown by the client instead of a notification at the top of the chat screen.
Defaults to False.
"""
return await self._client.answer_pre_checkout_query(
pre_checkout_query_id=self.id,
success=success,
error=error
)

View file

@ -0,0 +1,62 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from ..object import Object
class ShippingAddress(Object):
"""Contains information about a shipping address.
Parameters:
street_line1 (``str``):
First line for the address.
street_line1 (``str``):
Second line for the address.
city (``str``):
City for the address.
state (``str``):
State for the address, if applicable.
post_code (``str``):
Post code for the address.
country_code (``str``):
Two-letter ISO 3166-1 alpha-2 country code.
"""
def __init__(
self, *,
street_line1: str,
street_line2: str,
city: str,
state: str,
post_code: str,
country_code: str
):
super().__init__()
self.street_line1 = street_line1
self.street_line2 = street_line2
self.city = city
self.state = state
self.post_code = post_code
self.country_code = country_code

View file

@ -0,0 +1,112 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram import raw
from pyrogram import types
from ..object import Object
class SuccessfulPayment(Object):
"""Contains information about a successful payment.
Parameters:
currency (``str``):
Three-letter ISO 4217 currency code.
total_amount (``int``):
Total price in the smallest units of the currency.
payload (``str``, *optional*):
Bot specified invoice payload. Only available to the bot that received the payment.
telegram_payment_charge_id (``str``, *optional*):
Telegram payment identifier. Only available to the bot that received the payment.
provider_payment_charge_id (``str``, *optional*):
Provider payment identifier. Only available to the bot that received the payment.
shipping_option_id (``str``, *optional*):
Identifier of the shipping option chosen by the user. Only available to the bot that received the payment.
payment_info (:obj:`~pyrogram.types.PaymentInfo`, *optional*):
Payment information provided by the user. Only available to the bot that received the payment.
"""
def __init__(
self, *,
currency: str,
total_amount: str,
payload: str,
telegram_payment_charge_id: str,
provider_payment_charge_id: str,
shipping_option_id: str = None,
payment_info: "types.PaymentInfo" = None
):
super().__init__()
self.currency = currency
self.total_amount = total_amount
self.payload = payload
self.telegram_payment_charge_id = telegram_payment_charge_id
self.provider_payment_charge_id = provider_payment_charge_id
self.shipping_option_id = shipping_option_id
self.payment_info = payment_info
@staticmethod
def _parse(client: "pyrogram.Client", successful_payment) -> "SuccessfulPayment":
payload = None
telegram_payment_charge_id = None
provider_payment_charge_id = None
shipping_option_id = None
payment_info = None
if isinstance(successful_payment, raw.types.MessageActionPaymentSentMe):
# Try to decode invoice payload into string. If that fails, fallback to bytes instead of decoding by
# ignoring/replacing errors, this way, button clicks will still work.
try:
payload = successful_payment.payload.decode()
except (UnicodeDecodeError, AttributeError):
payload = successful_payment.payload
telegram_payment_charge_id = successful_payment.charge.id
provider_payment_charge_id = successful_payment.charge.provider_charge_id
shipping_option_id = successful_payment.shipping_option_id
payment_info = types.PaymentInfo(
name=successful_payment.info.name,
phone_number=successful_payment.info.phone,
email=successful_payment.info.email,
shipping_address=types.ShippingAddress(
street_line1=successful_payment.info.shipping_address.street_line1,
street_line2=successful_payment.info.shipping_address.street_line2,
city=successful_payment.info.shipping_address.city,
state=successful_payment.info.shipping_address.state,
post_code=successful_payment.info.shipping_address.post_code,
country_code=successful_payment.info.shipping_address.country_iso2
)
) if successful_payment.info else None
return SuccessfulPayment(
currency=successful_payment.currency,
total_amount=successful_payment.total_amount,
payload=payload,
telegram_payment_charge_id=telegram_payment_charge_id,
provider_payment_charge_id=shipping_option_id,
shipping_option_id=shipping_option_id,
payment_info=payment_info
)

View file

@ -379,6 +379,9 @@ class Message(Object, Update):
web_app_data (:obj:`~pyrogram.types.WebAppData`, *optional*):
Service message: web app data sent to the bot.
successful_payment (:obj:`~pyrogram.types.SuccessfulPayment`, *optional*):
Service message: successful payment.
boosts_applied (``int``, *optional*):
Service message: how many boosts were applied.
@ -509,6 +512,7 @@ class Message(Object, Update):
video_chat_ended: "types.VideoChatEnded" = None,
video_chat_members_invited: "types.VideoChatMembersInvited" = None,
web_app_data: "types.WebAppData" = None,
successful_payment: "types.SuccessfulPayment" = None,
reply_markup: Union[
"types.InlineKeyboardMarkup",
"types.ReplyKeyboardMarkup",
@ -616,6 +620,7 @@ class Message(Object, Update):
self.video_chat_ended = video_chat_ended
self.video_chat_members_invited = video_chat_members_invited
self.web_app_data = web_app_data
self.successful_payment = successful_payment
self.reactions = reactions
self.raw = raw
@ -721,6 +726,7 @@ class Message(Object, Update):
gifted_premium = None
giveaway_launched = None
giveaway_result = None
successful_payment = None
boosts_applied = None
service_type = None
@ -819,6 +825,9 @@ class Message(Object, Update):
elif isinstance(action, raw.types.MessageActionBoostApply):
boosts_applied = action.boosts
service_type = enums.MessageServiceType.BOOST_APPLY
elif isinstance(action, (raw.types.MessageActionPaymentSent, raw.types.MessageActionPaymentSentMe)):
successful_payment = types.SuccessfulPayment._parse(client, action)
service_type = enums.MessageServiceType.SUCCESSFUL_PAYMENT
from_user = types.User._parse(client, users.get(user_id, None))
sender_chat = types.Chat._parse(client, message, users, chats, is_chat=False) if not from_user else None
@ -858,6 +867,7 @@ class Message(Object, Update):
gifted_premium=gifted_premium,
giveaway_launched=giveaway_launched,
giveaway_result=giveaway_result,
successful_payment=successful_payment,
boosts_applied=boosts_applied,
raw=message,
client=client