Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added examples/paymentbot.py
Empty file.
11 changes: 10 additions & 1 deletion telegram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
from .messageentity import MessageEntity
from .animation import Animation
from .game import Game
from .shippingaddress import ShippingAddress
from .orderinfo import OrderInfo
from .successfulpayment import SuccessfulPayment
from .invoice import Invoice
from .message import Message
from .inputmessagecontent import InputMessageContent
from .callbackquery import CallbackQuery
Expand Down Expand Up @@ -82,6 +86,10 @@
from .inputlocationmessagecontent import InputLocationMessageContent
from .inputvenuemessagecontent import InputVenueMessageContent
from .inputcontactmessagecontent import InputContactMessageContent
from .labeledprice import LabeledPrice
from .shippingoption import ShippingOption
from .precheckoutquery import PreCheckoutQuery
from .shippingquery import ShippingQuery
from .webhookinfo import WebhookInfo
from .gamehighscore import GameHighScore
from .videonote import VideoNote
Expand Down Expand Up @@ -114,5 +122,6 @@
'Video', 'Voice', 'MAX_MESSAGE_LENGTH', 'MAX_CAPTION_LENGTH', 'SUPPORTED_WEBHOOK_PORTS',
'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT',
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
'Game', 'GameHighScore', 'VideoNote'
'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption',
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery'
]
179 changes: 179 additions & 0 deletions telegram/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,182 @@ def get_game_high_scores(self,

return [GameHighScore.de_json(hs, self) for hs in result]

@log
@message
def send_invoice(self,
chat_id,
title,
description,
payload,
provider_token,
start_parameter,
currency,
prices,
photo_url=None,
photo_size=None,
photo_width=None,
photo_height=None,
need_name=None,
need_phone_number=None,
need_shipping_address=None,
is_flexible=None,
disable_notification=False,
reply_to_message_id=None,
reply_markup=None,
timeout=None,
**kwargs):
"""
Use this method to send invoices.

Args:
chat_id (int|str): Unique identifier for the target private chat
title (str): Product name
description (str): Product description
payload (str): Bot-defined invoice payload, 1-128 bytes. This will not be displayed
to the user, use for your internal processes.
provider_token (str): Payments provider token, obtained via Botfather
start_parameter (str): Unique deep-linking parameter that can be used to generate
this invoice when used as a start parameter
currency (str): Three-letter ISO 4217 currency code
prices (List[:class:`telegram.LabeledPrice`]): Price breakdown, a list of components
(e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
photo_url (Optional[str]): 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 (Optional[str]): Photo size
photo_width (Optional[int]): Photo width
photo_height (Optional[int]): Photo height
need_name (Optional[bool]): Pass True, if you require the user's full name to complete
the order
need_phone_number (Optional[bool]): Pass True, if you require the user's phone number
to complete the order
need_shipping_address (Optional[bool]): Pass True, if you require the user's shipping
address to complete the order
is_flexible (Optional[bool]): Pass True, if the final price depends on the shipping
method
disable_notification (Optional[bool]): Sends the message silently. iOS users will not
receive a notification, Android users will receive a notification with no sound.
reply_to_message_id (Optional[int]): If the message is a reply, ID of the original
message.
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options.
An inlinekeyboard. If empty, one 'Pay total price' button will be shown. If not
empty, the first button must be a Pay button.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout
from the server (instead of the one specified during creation of the connection
pool).
**kwargs (dict): Arbitrary keyword arguments.

Returns:
:class:`telegram.Message`: On success, instance representing the message posted.

Raises:
:class:`telegram.TelegramError`

"""
url = '{0}/sendInvoice'.format(self.base_url)

data = {
'chat_id': chat_id,
'title': title,
'description': description,
'payload': payload,
'provider_token': provider_token,
'start_parameter': start_parameter,
'currency': currency,
'prices': [p.to_dict() for p in prices]
}

if photo_url is not None:
data['photo_url'] = photo_url
if photo_size is not None:
data['photo_size'] = photo_size
if photo_width is not None:
data['photo_width'] = photo_width
if photo_height is not None:
data['photo_height'] = photo_height
if need_name is not None:
data['need_name'] = need_name
if need_phone_number is not None:
data['need_phone_number'] = need_phone_number
if need_shipping_address is not None:
data['need_shipping_address'] = need_shipping_address
if is_flexible is not None:
data['is_flexible'] = is_flexible

return url, data

def answer_shipping_query(self,
shipping_query_id,
ok,
shipping_options=None,
error_message=None):
"""
If you sent an invoice requesting a shipping address and the parameter is_flexible was
specified, the Bot API will send an Update with a shipping_query field to the bot. Use
this method to reply to shipping queries.

Args:
shipping_query_id (str): Unique identifier for the query to be answered
ok (bool): Specify True if delivery to the specified address is possible and False if
there are any problems (for example, if delivery to the specified address
is not possible)
shipping_options (Optional[List[:class:`telegram.ShippingOption`]]): Required if ok is
True. A list of available shipping options.
error_message (Optional[str]): Required if ok is False. Error message in human readable
form that explains why it is impossible to complete the order (e.g. "Sorry,
delivery to your desired address is unavailable'). Telegram will display this
message to the user.

Returns:
bool: On success, `True` is returned.

Raises:
:class:`telegram.TelegramError`

"""
url = '{0]/answerShippingQuery'.format(self.base_url)

data = {'shipping_query_id': shipping_query_id, 'ok': ok}

if shipping_options is not None:
data['shipping_options'] = shipping_options
if error_message is not None:
data['error_message'] = error_message

return url, data

def answer_pre_checkout_query(self, pre_checkout_query_id, ok, error_message=None):
"""
If you sent an invoice requesting a shipping address and the parameter is_flexible was
specified, the Bot API will send an Update with a shipping_query field to the bot.
Use this method to reply to shipping queries.

Args:
pre_checkout_query_id (str): Unique identifier for the query to be answered
ok (bool): 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_message (Optional[str]): 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: On success, `True` is returned.

Raises:
:class:`telegram.TelegramError`

"""
url = '{0]/answerPreCheckoutQuery'.format(self.base_url)

data = {'pre_checkout_query_id': pre_checkout_query_id, 'ok': ok}

if error_message is not None:
data['error_message'] = error_message

return url, data

@staticmethod
def de_json(data, bot):
data = super(Bot, Bot).de_json(data, bot)
Expand Down Expand Up @@ -1873,3 +2049,6 @@ def __reduce__(self):
getWebhookInfo = get_webhook_info
setGameScore = set_game_score
getGameHighScores = get_game_high_scores
sendInvoice = send_invoice
answerShippingQuery = answer_shipping_query
answerPreCheckoutQuery = answer_pre_checkout_query
14 changes: 14 additions & 0 deletions telegram/ext/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,20 @@ def filter(self, message):

group = _Group()

class _Invoice(BaseFilter):

def filter(self, message):
return bool(message.invoice)

invoice = _Invoice()

class _SuccessfulPayment(BaseFilter):

def filter(self, message):
return bool(message.successful_payment)

successful_payment = _SuccessfulPayment()

class language(BaseFilter):
"""
Filters messages to only allow those which are from users with a certain language code.
Expand Down
7 changes: 6 additions & 1 deletion telegram/inlinekeyboardbutton.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ class InlineKeyboardButton(TelegramObject):
the bot's username and the specified inline query in the current chat's input field.
Can be empty, in which case only the bot's username will be inserted.
callback_game (Optional[:class:`telegram.CallbackGame`]): Description of the game that will
be launched when the user presses the button.
be launched when the user presses the button. NOTE: This type of button must always be
the first button in the first row.
pay (Optional[bool]): Specify True, to send a Pay button. NOTE: This type of button must
always be the first button in the first row.
**kwargs (dict): Arbitrary keyword arguments.

"""
Expand All @@ -58,6 +61,7 @@ def __init__(self,
switch_inline_query=None,
switch_inline_query_current_chat=None,
callback_game=None,
pay=None,
**kwargs):
# Required
self.text = text
Expand All @@ -68,6 +72,7 @@ def __init__(self,
self.switch_inline_query = switch_inline_query
self.switch_inline_query_current_chat = switch_inline_query_current_chat
self.callback_game = callback_game
self.pay = pay

@staticmethod
def de_json(data, bot):
Expand Down
58 changes: 58 additions & 0 deletions telegram/invoice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# 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 Invoice."""

from telegram import TelegramObject


class Invoice(TelegramObject):
"""This object contains basic information about an invoice.

Attributes:
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)
**kwargs (dict): Arbitrary keyword arguments.

"""

def __init__(self, title, description, start_parameter, currency, total_amount, **kwargs):
self.title = title
self.description = description
self.start_parameter = start_parameter
self.currency = currency
self.total_amount = total_amount

@staticmethod
def de_json(data, bot):
"""
Args:
data (dict):
bot (telegram.Bot):

Returns:
telegram.Invoice:
"""
if not data:
return None

return Invoice(**data)
70 changes: 70 additions & 0 deletions telegram/labeledprice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# 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 LabeledPrice."""

from telegram import TelegramObject


class LabeledPrice(TelegramObject):
"""This object represents a portion of the price for goods or services.

Attributes:
label (str): Portion label
amount (int): Price of the product in the smallest units of the currency (integer)
**kwargs (dict): Arbitrary keyword arguments.
"""

def __init__(self, label, amount, **kwargs):
self.label = label
self.amount = amount

@staticmethod
def de_json(data, bot):
"""
Args:
data (dict):
bot (telegram.Bot):

Returns:
telegram.LabeledPrice:

"""
if not data:
return None

return LabeledPrice(**data)

@staticmethod
def de_list(data, bot):
"""
Args:
data (list):
bot (telegram.Bot):

Returns:
List<telegram.PhotoSize>:
"""
if not data:
return []

labeled_prices = list()
for labeled_price in data:
labeled_prices.append(LabeledPrice.de_json(labeled_price, bot))

return labeled_prices
Loading