Add send_invoice and refund_star_payment method

Also fix some bugs and renamed some parameters of pre_checkout_query etc

Co-authored-by: Shrimadhav U K <SpEcHiDe@users.noreply.github.com>
This commit is contained in:
KurimuzonAkuma 2024-06-07 14:11:51 +03:00
parent 579a9e2b31
commit 92c0295095
14 changed files with 583 additions and 186 deletions

View File

@ -536,7 +536,7 @@ def pyrogram_api():
RequestChatInfo
RequestUserInfo
RequestPollInfo
PaymentInfo
OrderInfo
PreCheckoutQuery
ShippingAddress
""",

View File

@ -26,9 +26,11 @@ from .get_bot_default_privileges import GetBotDefaultPrivileges
from .get_chat_menu_button import GetChatMenuButton
from .get_game_high_scores import GetGameHighScores
from .get_inline_bot_results import GetInlineBotResults
from .refund_star_payment import RefundStarPayment
from .request_callback_answer import RequestCallbackAnswer
from .send_game import SendGame
from .send_inline_bot_result import SendInlineBotResult
from .send_invoice import SendInvoice
from .set_bot_commands import SetBotCommands
from .set_bot_default_privileges import SetBotDefaultPrivileges
from .set_chat_menu_button import SetChatMenuButton
@ -39,8 +41,10 @@ class Bots(
AnswerCallbackQuery,
AnswerInlineQuery,
GetInlineBotResults,
RefundStarPayment,
RequestCallbackAnswer,
SendInlineBotResult,
SendInvoice,
SendGame,
SetGameScore,
GetGameHighScores,

View File

@ -16,6 +16,8 @@
# 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 Optional
import pyrogram
from pyrogram import raw
@ -24,8 +26,8 @@ class AnswerPreCheckoutQuery:
async def answer_pre_checkout_query(
self: "pyrogram.Client",
pre_checkout_query_id: str,
success: bool = None,
error: str = None
ok: Optional[bool] = None,
error_message: Optional[str] = None
):
"""Send answers to pre-checkout queries.
@ -35,11 +37,11 @@ class AnswerPreCheckoutQuery:
pre_checkout_query_id (``str``):
Unique identifier for the query to be answered.
success (``bool``, *optional*):
ok (``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 (``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.
@ -50,15 +52,15 @@ class AnswerPreCheckoutQuery:
.. code-block:: python
# Proceed with the order
await app.answer_pre_checkout_query(query_id, success=True)
await app.answer_pre_checkout_query(query_id, ok=True)
# Answer with error message
await app.answer_pre_checkout_query(query_id, error=error)
await app.answer_pre_checkout_query(query_id, ok=False, error_message="Out of stock")
"""
return await self.invoke(
raw.functions.messages.SetBotPrecheckoutResults(
query_id=int(pre_checkout_query_id),
success=success or None,
error=error or None
success=ok,
error=error_message
)
)

View File

@ -0,0 +1,54 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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
import pyrogram
from pyrogram import raw
class RefundStarPayment:
async def refund_star_payment(
self: "pyrogram.Client",
user_id: Union[int, str],
telegram_payment_charge_id: str
) -> bool:
"""Refunds a successful payment in `Telegram Stars <https://t.me/BotNews/90>`_.
.. include:: /_includes/usable-by/bots.rst
Parameters:
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target user, whose payment will be refunded.
telegram_payment_charge_id (``str``):
Telegram payment identifier.
Returns:
``bool``: True on success
"""
r = await self.invoke(
raw.functions.payments.RefundStarsCharge(
user_id=await self.resolve_peer(user_id),
charge_id=telegram_payment_charge_id
)
)
return bool(r)

View File

@ -0,0 +1,237 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 logging
from typing import List, Optional, Union
import pyrogram
from pyrogram import enums, raw, utils, types
log = logging.getLogger(__name__)
class SendInvoice:
async def send_invoice(
self: "pyrogram.Client",
chat_id: Union[int, str],
title: str,
description: str,
payload: Union[str, bytes],
currency: str,
prices: List["types.LabeledPrice"],
message_thread_id: Optional[int] = None,
provider_token: Optional[str] = None,
max_tip_amount: Optional[int] = None,
suggested_tip_amounts: Optional[List[int]] = None,
start_parameter: Optional[str] = None,
provider_data: Optional[str] = None,
photo_url: Optional[str] = None,
photo_size: Optional[int] = None,
photo_width: Optional[int] = None,
photo_height: Optional[int] = None,
need_name: Optional[bool] = None,
need_phone_number: Optional[bool] = None,
need_email: Optional[bool] = None,
need_shipping_address: Optional[bool] = None,
send_phone_number_to_provider: Optional[bool] = None,
send_email_to_provider: Optional[bool] = None,
is_flexible: Optional[bool] = None,
disable_notification: Optional[bool] = None,
protect_content: Optional[bool] = None,
message_effect_id: Optional[int] = None,
reply_to_message_id: Optional[int] = None,
reply_markup: Optional[Union[
"types.InlineKeyboardMarkup",
"types.ReplyKeyboardMarkup",
"types.ReplyKeyboardRemove",
"types.ForceReply"
]] = None,
caption: str = "",
parse_mode: Optional["enums.ParseMode"] = None,
caption_entities: Optional[List["types.MessageEntity"]] = None
) -> "types.Message":
"""Use this method to send invoices.
.. include:: /_includes/usable-by/bots.rst
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
title (``str``):
Product name, 1-32 characters.
description (``str``):
Product description, 1-255 characters
payload (``str`` | ``bytes``):
Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes.
currency (``str``):
Three-letter ISO 4217 currency code, see `more on currencies <https://core.telegram.org/bots/payments#supported-currencies>`_. Pass ``XTR`` for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
prices (List of :obj:`~pyrogram.types.LabeledPrice`):
Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). Must contain exactly one item for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
message_thread_id (``int``, *optional*):
If the message is in a thread, ID of the original message.
reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message.
provider_token (``str``, *optional*):
Payment provider token, obtained via `@BotFather <https://t.me/botfather>`_. Pass an empty string for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
max_tip_amount (``int``, *optional*):
The maximum accepted amount for tips in the smallest units of the currency (integer, **not** float/double). For example, for a maximum tip of ``US$ 1.45`` pass ``max_tip_amount = 145``. See the exp parameter in `currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0. Not supported for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
suggested_tip_amounts (List of ``int``, *optional*):
An array of suggested amounts of tips in the smallest units of the currency (integer, **not** float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed ``max_tip_amount``.
start_parameter (``str``, *optional*):
Unique deep-linking parameter. If left empty, **forwarded copies** of the sent message will have a Pay button, allowing multiple users to pay directly from the forwarded message, using the same invoice. If non-empty, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button), with the value used as the start parameter.
provider_data (``str``, *optional*):
JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider.
photo_url (``str``, *optional*):
URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for.
photo_size (``int``, *optional*):
Photo size in bytes
photo_width (``int``, *optional*):
Photo width
photo_height (``int``, *optional*):
Photo height
need_name (``bool``, *optional*):
Pass True if you require the user's full name to complete the order. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
need_phone_number (``bool``, *optional*):
Pass True if you require the user's phone number to complete the order. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
need_email (``bool``, *optional*):
Pass True if you require the user's email address to complete the order. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
need_shipping_address (``bool``, *optional*):
Pass True if you require the user's shipping address to complete the order. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
send_phone_number_to_provider (``bool``, *optional*):
Pass True if the user's phone number should be sent to the provider. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
send_email_to_provider (``bool``, *optional*):
Pass True if the user's email address should be sent to the provider. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
is_flexible (``bool``, *optional*):
Pass True if the final price depends on the shipping method. Ignored for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
disable_notification (``bool``, *optional*):
Sends the message silently.
Users will receive a notification with no sound.
protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving.
message_effect_id (``int`` ``64-bit``, *optional*):
Unique identifier of the message effect to be added to the message; for private chats only.
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user.
caption (``str``, *optional*):
Document caption, 0-1024 characters.
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
By default, texts are parsed using both Markdown and HTML styles.
You can combine both syntaxes together.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of *parse_mode*.
Returns:
:obj:`~pyrogram.types.Message`: On success, the sent invoice message is returned.
"""
media = raw.types.InputMediaInvoice(
title=title,
description=description,
photo=raw.types.InputWebDocument(
url=photo_url,
mime_type="image/jpg",
size=photo_size,
attributes=[
raw.types.DocumentAttributeImageSize(
w=photo_width,
h=photo_height
)
]
) if photo_url else None,
invoice=raw.types.Invoice(
currency=currency,
prices=[i.write() for i in prices],
test=self.test_mode,
name_requested=need_name,
phone_requested=need_phone_number,
email_requested=need_email,
shipping_address_requested=need_shipping_address,
flexible=is_flexible,
phone_to_provider=send_phone_number_to_provider,
email_to_provider=send_email_to_provider,
max_tip_amount=max_tip_amount,
suggested_tip_amounts=suggested_tip_amounts
),
payload=payload.encode() if isinstance(payload, str) else payload,
provider=provider_token,
provider_data=raw.types.DataJSON(
data=provider_data if provider_data else "{}"
),
start_param=start_parameter
)
rpc = raw.functions.messages.SendMedia(
peer=await self.resolve_peer(chat_id),
media=media,
silent=disable_notification or None,
reply_to=utils.get_reply_to(
reply_to_message_id=reply_to_message_id,
message_thread_id=message_thread_id
),
random_id=self.rnd_id(),
noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None,
effect=message_effect_id,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
r = await self.invoke(rpc)
for i in r.updates:
if isinstance(i, (raw.types.UpdateNewMessage,
raw.types.UpdateNewChannelMessage,
raw.types.UpdateNewScheduledMessage,
raw.types.UpdateBotNewBusinessMessage)):
return await types.Message._parse(
self, i.message,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage),
business_connection_id=getattr(i, "connection_id", None)
)

View File

@ -32,23 +32,23 @@ from .game_high_score import GameHighScore
from .inline_keyboard_button import InlineKeyboardButton
from .inline_keyboard_markup import InlineKeyboardMarkup
from .keyboard_button import KeyboardButton
from .labeled_price import LabeledPrice
from .login_url import LoginUrl
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 .order_info import OrderInfo
from .pre_checkout_query import PreCheckoutQuery
from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove
from .request_channel_info import RequestChannelInfo
from .request_chat_info import RequestChatInfo
from .request_user_info import RequestUserInfo
from .request_poll_info import RequestPollInfo
from .request_user_info import RequestUserInfo
from .requested_chats import RequestedChats
from .sent_web_app_message import SentWebAppMessage
from .shipping_address import ShippingAddress
from .successful_payment import SuccessfulPayment
from .web_app_info import WebAppInfo
__all__ = [
@ -66,6 +66,7 @@ __all__ = [
"RequestUserInfo",
"RequestPollInfo",
"RequestedChats",
"LabeledPrice",
"LoginUrl",
"BotCommand",
"BotCommandScope",
@ -80,10 +81,9 @@ __all__ = [
"MenuButton",
"MenuButtonCommands",
"MenuButtonWebApp",
"OrderInfo",
"PreCheckoutQuery",
"MenuButtonDefault",
"SentWebAppMessage",
"ShippingAddress",
"PaymentInfo",
"PreCheckoutQuery",
"SuccessfulPayment"
"ShippingAddress"
]

View File

@ -0,0 +1,58 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 ..object import Object
class LabeledPrice(Object):
"""This object represents a portion of the price for goods or services.
Parameters:
label (``str``):
Portion label.
amount (``int``):
Price of the product 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 <https://core.telegram.org/bots/payments/currencies.json>`_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).
"""
def __init__(
self,
label: str,
amount: int
):
super().__init__()
self.label = label
self.amount = amount
@staticmethod
def _parse(labeled_price: "raw.types.LabeledPrice") -> "LabeledPrice":
if isinstance(labeled_price, raw.types.LabeledPrice):
return LabeledPrice(
label=labeled_price.label,
amount=labeled_price.amount
)
def write(self):
return raw.types.LabeledPrice(
label=self.label,
amount=self.amount
)

View File

@ -16,32 +16,38 @@
# 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 Optional
from pyrogram import types
from ..object import Object
class PaymentInfo(Object):
"""Contains information about a payment.
class OrderInfo(Object):
"""This object represents information about an order.
Parameters:
name (``str``, *optional*):
User's name.
User name.
phone_number (``str``, *optional*):
User's phone number.
email (``str``, *optional*):
User's email.
User email.
shipping_address (:obj:`~pyrogram.types.ShippingAddress`, *optional*):
User's shipping address.
User shipping address.
"""
def __init__(
self, *,
name: str = None,
phone_number: str = None,
email: str = None,
shipping_address: "types.ShippingAddress" = None
self,
*,
name: Optional[str] = None,
phone_number: Optional[str] = None,
email: Optional[str] = None,
shipping_address: Optional["types.ShippingAddress"] = None
):
super().__init__()

View File

@ -16,18 +16,16 @@
# 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
from typing import Union, Optional
import pyrogram
from pyrogram import raw, enums
from pyrogram import types
from pyrogram import types, raw
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.
"""This object contains information about an incoming pre-checkout query.
Parameters:
id (``str``):
@ -37,18 +35,18 @@ class PreCheckoutQuery(Object, Update):
User who sent the query.
currency (``str``):
Three-letter ISO 4217 currency code.
Three-letter ISO 4217 `currency <https://core.telegram.org/bots/payments#supported-currencies>`_ code, or ``XTR`` for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
total_amount (``int``):
Total price in the smallest units of the currency.
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 <https://core.telegram.org/bots/payments/currencies.json>`_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).
payload (``str``):
invoice_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*):
order_info (:obj:`~pyrogram.types.OrderInfo`, *optional*):
Payment information provided by the user.
"""
@ -60,9 +58,9 @@ class PreCheckoutQuery(Object, Update):
from_user: "types.User",
currency: str,
total_amount: int,
payload: str,
shipping_option_id: str = None,
payment_info: "types.PaymentInfo" = None
invoice_payload: str,
shipping_option_id: Optional[str] = None,
order_info: Optional["types.OrderInfo"] = None
):
super().__init__(client)
@ -70,27 +68,31 @@ class PreCheckoutQuery(Object, Update):
self.from_user = from_user
self.currency = currency
self.total_amount = total_amount
self.payload = payload
self.invoice_payload = invoice_payload
self.shipping_option_id = shipping_option_id
self.payment_info = payment_info
self.order_info = order_info
@staticmethod
async def _parse(client: "pyrogram.Client", pre_checkout_query, users) -> "PreCheckoutQuery":
async def _parse(
client: "pyrogram.Client",
pre_checkout_query: "raw.types.UpdateBotPrecheckoutQuery",
users: dict
) -> "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()
invoice_payload = pre_checkout_query.payload.decode()
except (UnicodeDecodeError, AttributeError):
payload = pre_checkout_query.payload
invoice_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,
invoice_payload=invoice_payload,
shipping_option_id=pre_checkout_query.shipping_option_id,
payment_info=types.PaymentInfo(
order_info=types.OrderInfo(
name=pre_checkout_query.info.name,
phone_number=pre_checkout_query.info.phone,
email=pre_checkout_query.info.email,
@ -106,7 +108,7 @@ class PreCheckoutQuery(Object, Update):
client=client
)
async def answer(self, success: bool = None, error: str = None):
async def answer(self, ok: bool = None, error_message: str = None):
"""Bound method *answer* of :obj:`~pyrogram.types.PreCheckoutQuery`.
Use this method as a shortcut for:
@ -115,25 +117,26 @@ class PreCheckoutQuery(Object, Update):
await client.answer_pre_checkout_query(
pre_checkout_query.id,
success=True
ok=True
)
Example:
.. code-block:: python
await pre_checkout_query.answer(success=True)
await pre_checkout_query.answer(ok=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.
ok (``bool`` *optional*):
Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems.
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.
error_message (``str`` *optional*):
Required if ok is False. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user.
Returns:
``bool``: True, on success.
"""
return await self._client.answer_pre_checkout_query(
pre_checkout_query_id=self.id,
success=success,
error=error
ok=ok,
error_message=error_message
)

View File

@ -23,39 +23,41 @@ class ShippingAddress(Object):
"""Contains information about a shipping address.
Parameters:
country_code (``str``):
Two-letter `ISO 3166-1 alpha-2 <https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2>`_ country code.
state (``str``):
State, if applicable.
city (``str``):
City.
street_line1 (``str``):
First line for the address.
street_line1 (``str``):
street_line2 (``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.
Address post code.
country_code (``str``):
Two-letter ISO 3166-1 alpha-2 country code.
"""
def __init__(
self, *,
self,
*,
country_code: str,
state: str,
city: str,
street_line1: str,
street_line2: str,
city: str,
state: str,
post_code: str,
country_code: str
post_code: str
):
super().__init__()
self.country_code = country_code
self.state = state
self.city = city
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

@ -1,111 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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

@ -49,6 +49,7 @@ from .reaction import Reaction
from .sticker import Sticker
from .story import Story
from .stripped_thumbnail import StrippedThumbnail
from .successful_payment import SuccessfulPayment
from .thumbnail import Thumbnail
from .venue import Venue
from .video import Video
@ -91,6 +92,7 @@ __all__ = [
"Sticker",
"Story",
"StrippedThumbnail",
"SuccessfulPayment",
"Thumbnail",
"Venue",
"Video",

View File

@ -405,7 +405,7 @@ class Message(Object, Update):
Generate a link to this message, only for groups and channels.
"""
# TODO: Add game missing field. Also successful_payment, connected_website
# TODO: Add game missing field, connected_website
def __init__(
self,

View File

@ -0,0 +1,140 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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, Optional
from pyrogram import raw
from pyrogram import types
from ..object import Object
class SuccessfulPayment(Object):
"""A service message about a new successful payment.
Parameters:
currency (``str``):
Three-letter ISO 4217 `currency <https://core.telegram.org/bots/payments#supported-currencies>`_ code, or ``XTR`` for payments in `Telegram Stars <https://t.me/BotNews/90>`_.
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 <https://core.telegram.org/bots/payments/currencies.json>`_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).
invoice_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.
is_recurring (``bool``, *optional*):
True, if this is a recurring payment.
is_first_recurring (``bool``, *optional*):
True, if this is the first recurring payment.
invoice_slug (``str``, *optional*):
Name of the invoice.
"""
def __init__(
self, *,
currency: str,
total_amount: str,
invoice_payload: str,
telegram_payment_charge_id: str,
provider_payment_charge_id: str,
shipping_option_id: Optional[str] = None,
order_info: Optional["types.OrderInfo"] = None,
is_recurring: Optional[bool] = None,
is_first_recurring: Optional[bool] = None,
invoice_slug: Optional[str] = None
):
super().__init__()
self.currency = currency
self.total_amount = total_amount
self.invoice_payload = invoice_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.order_info = order_info
self.is_recurring = is_recurring
self.is_first_recurring = is_first_recurring
self.invoice_slug = invoice_slug
@staticmethod
def _parse(
client: "pyrogram.Client",
successful_payment: Union[
"raw.types.MessageActionPaymentSent",
"raw.types.MessageActionPaymentSentMe"
]) -> "SuccessfulPayment":
invoice_payload = None
telegram_payment_charge_id = None
provider_payment_charge_id = None
shipping_option_id = None
order_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:
invoice_payload = successful_payment.payload.decode()
except (UnicodeDecodeError, AttributeError):
invoice_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 = getattr(successful_payment, "shipping_option_id")
if successful_payment.info:
payment_info = successful_payment.info
order_info = types.OrderInfo(
name=getattr(payment_info, "name", None),
phone_number=getattr(payment_info, "phone", None),
email=getattr(payment_info, "email", None),
shipping_address=types.ShippingAddress(
country_code=successful_payment.info.shipping_address.country_iso2,
state=successful_payment.info.shipping_address.state,
city=successful_payment.info.shipping_address.city,
street_line1=successful_payment.info.shipping_address.street_line1,
street_line2=successful_payment.info.shipping_address.street_line2,
post_code=successful_payment.info.shipping_address.post_code
)
)
return SuccessfulPayment(
currency=successful_payment.currency,
total_amount=successful_payment.total_amount,
invoice_payload=invoice_payload,
telegram_payment_charge_id=telegram_payment_charge_id,
provider_payment_charge_id=provider_payment_charge_id,
shipping_option_id=shipping_option_id,
order_info=order_info,
is_recurring=getattr(successful_payment, "recurring_used", None),
is_first_recurring=getattr(successful_payment, "recurring_init", None),
invoice_slug=getattr(successful_payment, "invoice_slug", None),
)