From 7166836c1a109663b6c1aecc3303771d6a3c8901 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 3 May 2022 18:50:29 +0300 Subject: [PATCH] Add td_api::InputInvoice. --- td/generate/scheme/td_api.tl | 23 +++++--- td/telegram/Payments.cpp | 109 ++++++++++++++++++++++------------- td/telegram/Payments.h | 15 +++-- td/telegram/Td.cpp | 14 ++--- td/telegram/Td.h | 2 +- td/telegram/cli.cpp | 56 ++++++++++++------ 6 files changed, 139 insertions(+), 80 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 299129b71..e92a32531 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1556,6 +1556,15 @@ paymentResult success:Bool verification_url:string = PaymentResult; paymentReceipt title:string description:string photo:photo date:int32 seller_bot_user_id:int53 payments_provider_user_id:int53 invoice:invoice order_info:orderInfo shipping_option:shippingOption credentials_title:string tip_amount:int53 = PaymentReceipt; +//@class InputInvoice @description Describe an invoice to process + +//@description An invoice from a message of the type messageInvoice @chat_id Chat identifier of the message @message_id Message identifier +inputInvoiceMessage chat_id:int53 message_id:int53 = InputInvoice; + +//@description An invoice from a link of the type internalLinkTypeInvoice @name Name of the invoice +inputInvoiceName name:string = InputInvoice; + + //@description File with the date it was uploaded @file The file @date Point in time (Unix timestamp) when the file was uploaded datedFile file:file date:int32 = DatedFile; @@ -5908,22 +5917,20 @@ getChatEventLog chat_id:int53 query:string from_event_id:int64 limit:int32 filte //@description Returns an invoice payment form. This method must be called when the user presses inlineKeyboardButtonBuy -//@chat_id Chat identifier of the Invoice message -//@message_id Message identifier +//@input_invoice The invoice //@theme Preferred payment form theme; pass null to use the default theme -getPaymentForm chat_id:int53 message_id:int53 theme:themeParameters = PaymentForm; +getPaymentForm input_invoice:InputInvoice theme:themeParameters = PaymentForm; //@description Validates the order information provided by a user and returns the available shipping options for a flexible invoice -//@chat_id Chat identifier of the Invoice message -//@message_id Message identifier +//@input_invoice The invoice //@order_info The order information, provided by the user; pass null if empty //@allow_save Pass true to save the order information -validateOrderInfo chat_id:int53 message_id:int53 order_info:orderInfo allow_save:Bool = ValidatedOrderInfo; +validateOrderInfo input_invoice:InputInvoice order_info:orderInfo allow_save:Bool = ValidatedOrderInfo; -//@description Sends a filled-out payment form to the bot for final verification @chat_id Chat identifier of the Invoice message @message_id Message identifier +//@description Sends a filled-out payment form to the bot for final verification @input_invoice The invoice //@payment_form_id Payment form identifier returned by getPaymentForm @order_info_id Identifier returned by validateOrderInfo, or an empty string @shipping_option_id Identifier of a chosen shipping option, if applicable //@credentials The credentials chosen by user for payment @tip_amount Chosen by the user amount of tip in the smallest units of the currency -sendPaymentForm chat_id:int53 message_id:int53 payment_form_id:int64 order_info_id:string shipping_option_id:string credentials:InputCredentials tip_amount:int53 = PaymentResult; +sendPaymentForm input_invoice:InputInvoice payment_form_id:int64 order_info_id:string shipping_option_id:string credentials:InputCredentials tip_amount:int53 = PaymentResult; //@description Returns information about a successful payment @chat_id Chat identifier of the PaymentSuccessful message @message_id Message identifier getPaymentReceipt chat_id:int53 message_id:int53 = PaymentReceipt; diff --git a/td/telegram/Payments.cpp b/td/telegram/Payments.cpp index c3028243f..6d018daa4 100644 --- a/td/telegram/Payments.cpp +++ b/td/telegram/Payments.cpp @@ -34,6 +34,49 @@ namespace td { +namespace { + +struct InputInvoiceInfo { + DialogId dialog_id_; + telegram_api::object_ptr input_invoice_; +}; + +Result get_input_invoice_info(Td *td, td_api::object_ptr &&input_invoice) { + if (input_invoice == nullptr) { + return Status::Error(400, "Input invoice must be non-empty"); + } + + InputInvoiceInfo result; + switch (input_invoice->get_id()) { + case td_api::inputInvoiceMessage::ID: { + auto invoice = td_api::move_object_as(input_invoice); + DialogId dialog_id(invoice->chat_id_); + MessageId message_id(invoice->message_id_); + TRY_RESULT(server_message_id, td->messages_manager_->get_invoice_message_id({dialog_id, message_id})); + + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return Status::Error(400, "Can't access the chat"); + } + + result.dialog_id_ = dialog_id; + result.input_invoice_ = + make_tl_object(std::move(input_peer), server_message_id.get()); + break; + } + case td_api::inputInvoiceName::ID: { + auto invoice = td_api::move_object_as(input_invoice); + result.input_invoice_ = make_tl_object(invoice->name_); + break; + } + default: + UNREACHABLE(); + } + return std::move(result); +} + +} // namespace + class SetBotShippingAnswerQuery final : public Td::ResultHandler { Promise promise_; @@ -270,21 +313,15 @@ class GetPaymentFormQuery final : public Td::ResultHandler { explicit GetPaymentFormQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, ServerMessageId server_message_id, - tl_object_ptr &&theme_parameters) { - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chat")); - } + void send(InputInvoiceInfo &&input_invoice_info, tl_object_ptr &&theme_parameters) { + dialog_id_ = input_invoice_info.dialog_id_; int32 flags = 0; if (theme_parameters != nullptr) { flags |= telegram_api::payments_getPaymentForm::THEME_PARAMS_MASK; } send_query(G()->net_query_creator().create(telegram_api::payments_getPaymentForm( - flags, make_tl_object(std::move(input_peer), server_message_id.get()), - std::move(theme_parameters)))); + flags, std::move(input_invoice_info.input_invoice_), std::move(theme_parameters)))); } void on_result(BufferSlice packet) final { @@ -334,13 +371,9 @@ class ValidateRequestedInfoQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, ServerMessageId server_message_id, - tl_object_ptr requested_info, bool allow_save) { - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chat")); - } + void send(InputInvoiceInfo &&input_invoice_info, tl_object_ptr requested_info, + bool allow_save) { + dialog_id_ = input_invoice_info.dialog_id_; int32 flags = 0; if (allow_save) { @@ -351,9 +384,7 @@ class ValidateRequestedInfoQuery final : public Td::ResultHandler { requested_info->flags_ = 0; } send_query(G()->net_query_creator().create(telegram_api::payments_validateRequestedInfo( - flags, false /*ignored*/, - make_tl_object(std::move(input_peer), server_message_id.get()), - std::move(requested_info)))); + flags, false /*ignored*/, std::move(input_invoice_info.input_invoice_), std::move(requested_info)))); } void on_result(BufferSlice packet) final { @@ -385,16 +416,12 @@ class SendPaymentFormQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, ServerMessageId server_message_id, int64 payment_form_id, const string &order_info_id, + void send(InputInvoiceInfo &&input_invoice_info, int64 payment_form_id, const string &order_info_id, const string &shipping_option_id, tl_object_ptr input_credentials, int64 tip_amount) { CHECK(input_credentials != nullptr); - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chat")); - } + dialog_id_ = input_invoice_info.dialog_id_; int32 flags = 0; if (!order_info_id.empty()) { @@ -407,9 +434,8 @@ class SendPaymentFormQuery final : public Td::ResultHandler { flags |= telegram_api::payments_sendPaymentForm::TIP_AMOUNT_MASK; } send_query(G()->net_query_creator().create(telegram_api::payments_sendPaymentForm( - flags, payment_form_id, - make_tl_object(std::move(input_peer), server_message_id.get()), - order_info_id, shipping_option_id, std::move(input_credentials), tip_amount))); + flags, payment_form_id, std::move(input_invoice_info.input_invoice_), order_info_id, shipping_option_id, + std::move(input_credentials), tip_amount))); } void on_result(BufferSlice packet) final { @@ -1151,9 +1177,10 @@ void answer_pre_checkout_query(Td *td, int64 pre_checkout_query_id, const string td->create_handler(std::move(promise))->send(pre_checkout_query_id, error_message); } -void get_payment_form(Td *td, FullMessageId full_message_id, const td_api::object_ptr &theme, +void get_payment_form(Td *td, td_api::object_ptr &&input_invoice, + const td_api::object_ptr &theme, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, server_message_id, td->messages_manager_->get_invoice_message_id(full_message_id)); + TRY_RESULT_PROMISE(promise, input_invoice_info, get_input_invoice_info(td, std::move(input_invoice))); tl_object_ptr theme_parameters; if (theme != nullptr) { @@ -1161,12 +1188,13 @@ void get_payment_form(Td *td, FullMessageId full_message_id, const td_api::objec theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme, false); } td->create_handler(std::move(promise)) - ->send(full_message_id.get_dialog_id(), server_message_id, std::move(theme_parameters)); + ->send(std::move(input_invoice_info), std::move(theme_parameters)); } -void validate_order_info(Td *td, FullMessageId full_message_id, tl_object_ptr order_info, - bool allow_save, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, server_message_id, td->messages_manager_->get_invoice_message_id(full_message_id)); +void validate_order_info(Td *td, td_api::object_ptr &&input_invoice, + td_api::object_ptr &&order_info, bool allow_save, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, input_invoice_info, get_input_invoice_info(td, std::move(input_invoice))); if (order_info != nullptr) { if (!clean_input_string(order_info->name_)) { @@ -1201,13 +1229,14 @@ void validate_order_info(Td *td, FullMessageId full_message_id, tl_object_ptrcreate_handler(std::move(promise)) - ->send(full_message_id.get_dialog_id(), server_message_id, convert_order_info(std::move(order_info)), allow_save); + ->send(std::move(input_invoice_info), convert_order_info(std::move(order_info)), allow_save); } -void send_payment_form(Td *td, FullMessageId full_message_id, int64 payment_form_id, const string &order_info_id, - const string &shipping_option_id, const tl_object_ptr &credentials, - int64 tip_amount, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, server_message_id, td->messages_manager_->get_invoice_message_id(full_message_id)); +void send_payment_form(Td *td, td_api::object_ptr &&input_invoice, int64 payment_form_id, + const string &order_info_id, const string &shipping_option_id, + const td_api::object_ptr &credentials, int64 tip_amount, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, input_invoice_info, get_input_invoice_info(td, std::move(input_invoice))); if (credentials == nullptr) { return promise.set_error(Status::Error(400, "Input payment credentials must be non-empty")); @@ -1258,7 +1287,7 @@ void send_payment_form(Td *td, FullMessageId full_message_id, int64 payment_form } td->create_handler(std::move(promise)) - ->send(full_message_id.get_dialog_id(), server_message_id, payment_form_id, order_info_id, shipping_option_id, + ->send(std::move(input_invoice_info), payment_form_id, order_info_id, shipping_option_id, std::move(input_credentials), tip_amount); } diff --git a/td/telegram/Payments.h b/td/telegram/Payments.h index 1deb56d81..4efd7878b 100644 --- a/td/telegram/Payments.h +++ b/td/telegram/Payments.h @@ -180,15 +180,18 @@ void answer_shipping_query(Td *td, int64 shipping_query_id, void answer_pre_checkout_query(Td *td, int64 pre_checkout_query_id, const string &error_message, Promise &&promise); -void get_payment_form(Td *td, FullMessageId full_message_id, const td_api::object_ptr &theme, +void get_payment_form(Td *td, td_api::object_ptr &&input_invoice, + const td_api::object_ptr &theme, Promise> &&promise); -void validate_order_info(Td *td, FullMessageId full_message_id, tl_object_ptr order_info, - bool allow_save, Promise> &&promise); +void validate_order_info(Td *td, td_api::object_ptr &&input_invoice, + td_api::object_ptr &&order_info, bool allow_save, + Promise> &&promise); -void send_payment_form(Td *td, FullMessageId full_message_id, int64 payment_form_id, const string &order_info_id, - const string &shipping_option_id, const tl_object_ptr &credentials, - int64 tip_amount, Promise> &&promise); +void send_payment_form(Td *td, td_api::object_ptr &&input_invoice, int64 payment_form_id, + const string &order_info_id, const string &shipping_option_id, + const td_api::object_ptr &credentials, int64 tip_amount, + Promise> &&promise); void get_payment_receipt(Td *td, FullMessageId full_message_id, Promise> &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 89ddf2e8e..dd3716755 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7493,18 +7493,17 @@ void Td::on_request(uint64 id, td_api::getBankCardInfo &request) { get_bank_card_info(this, request.bank_card_number_, std::move(promise)); } -void Td::on_request(uint64 id, const td_api::getPaymentForm &request) { +void Td::on_request(uint64 id, td_api::getPaymentForm &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); - get_payment_form(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.theme_, - std::move(promise)); + get_payment_form(this, std::move(request.input_invoice_), request.theme_, std::move(promise)); } void Td::on_request(uint64 id, td_api::validateOrderInfo &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); - validate_order_info(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.order_info_), request.allow_save_, std::move(promise)); + validate_order_info(this, std::move(request.input_invoice_), std::move(request.order_info_), request.allow_save_, + std::move(promise)); } void Td::on_request(uint64 id, td_api::sendPaymentForm &request) { @@ -7512,9 +7511,8 @@ void Td::on_request(uint64 id, td_api::sendPaymentForm &request) { CLEAN_INPUT_STRING(request.order_info_id_); CLEAN_INPUT_STRING(request.shipping_option_id_); CREATE_REQUEST_PROMISE(); - send_payment_form(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.payment_form_id_, - request.order_info_id_, request.shipping_option_id_, request.credentials_, request.tip_amount_, - std::move(promise)); + send_payment_form(this, std::move(request.input_invoice_), request.payment_form_id_, request.order_info_id_, + request.shipping_option_id_, request.credentials_, request.tip_amount_, std::move(promise)); } void Td::on_request(uint64 id, const td_api::getPaymentReceipt &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 7e2dd0b5c..38051fc47 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1206,7 +1206,7 @@ class Td final : public Actor { void on_request(uint64 id, td_api::getBankCardInfo &request); - void on_request(uint64 id, const td_api::getPaymentForm &request); + void on_request(uint64 id, td_api::getPaymentForm &request); void on_request(uint64 id, td_api::validateOrderInfo &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 3067e7edd..2de86d244 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -434,7 +434,7 @@ class CliClient final : public Actor { static char get_delimiter(Slice str) { FlatHashSet chars; for (auto c : trim(str)) { - if (!is_alnum(c) && c != '-' && c != '.' && c != '/' && c != '\0' && static_cast(c) <= 127) { + if (!is_alnum(c) && c != '-' && c != '@' && c != '.' && c != '/' && c != '\0' && static_cast(c) <= 127) { chars.insert(c); } } @@ -802,6 +802,32 @@ class CliClient final : public Actor { arg.file_id = as_file_id(args); } + struct InputInvoice { + int64 chat_id = 0; + int64 message_id = 0; + string invoice_name; + + operator td_api::object_ptr() const { + if (invoice_name.empty()) { + return td_api::make_object(chat_id, message_id); + } else { + return td_api::make_object(invoice_name); + } + } + }; + + void get_args(string &args, InputInvoice &arg) const { + if (args.size() > 1 && args[0] == '#') { + arg.invoice_name = args; + } else { + string chat_id; + string message_id; + std::tie(chat_id, message_id) = split(args, get_delimiter(args)); + arg.chat_id = as_chat_id(args); + arg.message_id = as_message_id(args); + } + } + template void get_args(string &args, FirstType &first_arg, SecondType &second_arg, Types &...other_args) const { string arg; @@ -1999,40 +2025,36 @@ class CliClient final : public Actor { } else if (op == "gbci") { send_request(td_api::make_object(args)); } else if (op == "gpf") { - ChatId chat_id; - MessageId message_id; - get_args(args, chat_id, message_id); - send_request(td_api::make_object(chat_id, message_id, get_theme_parameters())); + InputInvoice input_invoice; + get_args(args, input_invoice); + send_request(td_api::make_object(input_invoice, get_theme_parameters())); } else if (op == "voi") { - ChatId chat_id; - MessageId message_id; + InputInvoice input_invoice; bool allow_save; - get_args(args, chat_id, message_id, allow_save); - send_request(td_api::make_object(chat_id, message_id, nullptr, allow_save)); + get_args(args, input_invoice, allow_save); + send_request(td_api::make_object(input_invoice, nullptr, allow_save)); } else if (op == "spfs") { - ChatId chat_id; - MessageId message_id; + InputInvoice input_invoice; int64 tip_amount; int64 payment_form_id; string order_info_id; string shipping_option_id; string saved_credentials_id; - get_args(args, chat_id, message_id, tip_amount, payment_form_id, order_info_id, shipping_option_id, + get_args(args, input_invoice, tip_amount, payment_form_id, order_info_id, shipping_option_id, saved_credentials_id); send_request(td_api::make_object( - chat_id, message_id, payment_form_id, order_info_id, shipping_option_id, + input_invoice, payment_form_id, order_info_id, shipping_option_id, td_api::make_object(saved_credentials_id), tip_amount)); } else if (op == "spfn") { - ChatId chat_id; - MessageId message_id; + InputInvoice input_invoice; int64 tip_amount; int64 payment_form_id; string order_info_id; string shipping_option_id; string data; - get_args(args, chat_id, message_id, tip_amount, payment_form_id, order_info_id, shipping_option_id, data); + get_args(args, input_invoice, tip_amount, payment_form_id, order_info_id, shipping_option_id, data); send_request(td_api::make_object( - chat_id, message_id, payment_form_id, order_info_id, shipping_option_id, + input_invoice, payment_form_id, order_info_id, shipping_option_id, td_api::make_object(data, true), tip_amount)); } else if (op == "gpre") { ChatId chat_id;