From 1e1191fcfcfe4f47eb2a96937c2ee40ff8176346 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 22 Sep 2022 19:08:06 +0300 Subject: [PATCH] Move InputInvoice to InputInvoice.h. --- CMakeLists.txt | 3 + td/telegram/InlineQueriesManager.cpp | 2 +- td/telegram/InputInvoice.cpp | 398 +++++++++++++++++++++++++++ td/telegram/InputInvoice.h | 102 +++++++ td/telegram/InputInvoice.hpp | 191 +++++++++++++ td/telegram/MessageContent.cpp | 2 + td/telegram/Payments.cpp | 384 +------------------------- td/telegram/Payments.h | 88 +----- td/telegram/Payments.hpp | 176 ------------ 9 files changed, 703 insertions(+), 643 deletions(-) create mode 100644 td/telegram/InputInvoice.cpp create mode 100644 td/telegram/InputInvoice.h create mode 100644 td/telegram/InputInvoice.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4472445e3..bc1971495 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,6 +362,7 @@ set(TDLIB_SOURCE td/telegram/InlineQueriesManager.cpp td/telegram/InputDialogId.cpp td/telegram/InputGroupCallId.cpp + td/telegram/InputInvoice.cpp td/telegram/InputMessageText.cpp td/telegram/JsonValue.cpp td/telegram/LanguagePackManager.cpp @@ -586,6 +587,7 @@ set(TDLIB_SOURCE td/telegram/InlineQueriesManager.h td/telegram/InputDialogId.h td/telegram/InputGroupCallId.h + td/telegram/InputInvoice.h td/telegram/InputMessageText.h td/telegram/JsonValue.h td/telegram/LabeledPricePart.h @@ -730,6 +732,7 @@ set(TDLIB_SOURCE td/telegram/files/FileManager.hpp td/telegram/files/FileSourceId.hpp td/telegram/Game.hpp + td/telegram/InputInvoice.hpp td/telegram/InputMessageText.hpp td/telegram/MessageEntity.hpp td/telegram/MessageExtendedMedia.hpp diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index fd04b7991..c37db8f95 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -18,6 +18,7 @@ #include "td/telegram/files/FileType.h" #include "td/telegram/Game.h" #include "td/telegram/Global.h" +#include "td/telegram/InputInvoice.h" #include "td/telegram/InputMessageText.h" #include "td/telegram/Location.h" #include "td/telegram/MessageContent.h" @@ -26,7 +27,6 @@ #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" -#include "td/telegram/Payments.h" #include "td/telegram/Photo.h" #include "td/telegram/PhotoFormat.h" #include "td/telegram/PhotoSize.h" diff --git a/td/telegram/InputInvoice.cpp b/td/telegram/InputInvoice.cpp new file mode 100644 index 000000000..71fb2f82d --- /dev/null +++ b/td/telegram/InputInvoice.cpp @@ -0,0 +1,398 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/InputInvoice.h" + +#include "td/telegram/files/FileManager.h" +#include "td/telegram/misc.h" +#include "td/telegram/Payments.h" +#include "td/telegram/PhotoSize.h" +#include "td/telegram/Td.h" + +#include "td/utils/algorithm.h" +#include "td/utils/common.h" +#include "td/utils/HttpUrl.h" +#include "td/utils/logging.h" +#include "td/utils/MimeType.h" +#include "td/utils/PathView.h" + +namespace td { + +bool operator==(const Invoice &lhs, const Invoice &rhs) { + return lhs.is_test == rhs.is_test && lhs.need_name == rhs.need_name && + lhs.need_phone_number == rhs.need_phone_number && lhs.need_email_address == rhs.need_email_address && + lhs.need_shipping_address == rhs.need_shipping_address && + lhs.send_phone_number_to_provider == rhs.send_phone_number_to_provider && + lhs.send_email_address_to_provider == rhs.send_email_address_to_provider && + lhs.is_flexible == rhs.is_flexible && lhs.currency == rhs.currency && lhs.price_parts == rhs.price_parts && + lhs.max_tip_amount == rhs.max_tip_amount && lhs.suggested_tip_amounts == rhs.suggested_tip_amounts && + lhs.recurring_payment_terms_of_service_url == rhs.recurring_payment_terms_of_service_url; +} + +bool operator!=(const Invoice &lhs, const Invoice &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice) { + return string_builder << "[" << (invoice.is_flexible ? "Flexible" : "") << (invoice.is_test ? "Test" : "") + << "Invoice" << (invoice.need_name ? ", needs name" : "") + << (invoice.need_phone_number ? ", needs phone number" : "") + << (invoice.need_email_address ? ", needs email address" : "") + << (invoice.need_shipping_address ? ", needs shipping address" : "") + << (invoice.send_phone_number_to_provider ? ", sends phone number to provider" : "") + << (invoice.send_email_address_to_provider ? ", sends email address to provider" : "") + << (invoice.recurring_payment_terms_of_service_url.empty() + ? string() + : ", recurring payments terms of service at " + + invoice.recurring_payment_terms_of_service_url) + << " in " << invoice.currency << " with price parts " << format::as_array(invoice.price_parts) + << " and suggested tip amounts " << invoice.suggested_tip_amounts << " up to " + << invoice.max_tip_amount << "]"; +} + +bool operator==(const InputInvoice &lhs, const InputInvoice &rhs) { + return lhs.title == rhs.title && lhs.description == rhs.description && lhs.photo == rhs.photo && + lhs.start_parameter == rhs.start_parameter && lhs.invoice == rhs.invoice && + lhs.total_amount == rhs.total_amount && lhs.receipt_message_id == rhs.receipt_message_id && + lhs.payload == rhs.payload && lhs.provider_token == rhs.provider_token && + lhs.provider_data == rhs.provider_data && lhs.extended_media == rhs.extended_media; +} + +bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs) { + return !(lhs == rhs); +} + +InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, + DialogId owner_dialog_id, FormattedText &&message) { + InputInvoice result; + result.title = std::move(message_invoice->title_); + result.description = std::move(message_invoice->description_); + result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); + result.start_parameter = std::move(message_invoice->start_param_); + result.invoice.currency = std::move(message_invoice->currency_); + result.invoice.is_test = message_invoice->test_; + result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; + // result.payload = string(); + // result.provider_token = string(); + // result.provider_data = string(); + result.extended_media = + MessageExtendedMedia(td, std::move(message_invoice->extended_media_), std::move(message), owner_dialog_id); + if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { + LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; + message_invoice->total_amount_ = 0; + } + result.total_amount = message_invoice->total_amount_; + if ((message_invoice->flags_ & telegram_api::messageMediaInvoice::RECEIPT_MSG_ID_MASK) != 0) { + result.receipt_message_id = MessageId(ServerMessageId(message_invoice->receipt_msg_id_)); + if (!result.receipt_message_id.is_valid()) { + LOG(ERROR) << "Receive as receipt message " << result.receipt_message_id << " in " << owner_dialog_id; + result.receipt_message_id = MessageId(); + } + } + return result; +} + +InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, + DialogId owner_dialog_id) { + InputInvoice result; + result.title = std::move(message_invoice->title_); + result.description = std::move(message_invoice->description_); + result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); + // result.start_parameter = string(); + result.invoice.currency = std::move(message_invoice->currency_); + result.invoice.is_test = message_invoice->test_; + result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; + // result.payload = string(); + // result.provider_token = string(); + // result.provider_data = string(); + // result.extended_media = MessageExtendedMedia(); + if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { + LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; + message_invoice->total_amount_ = 0; + } + result.total_amount = message_invoice->total_amount_; + // result.receipt_message_id = MessageId(); + return result; +} + +Result process_input_message_invoice( + td_api::object_ptr &&input_message_content, Td *td) { + CHECK(input_message_content != nullptr); + CHECK(input_message_content->get_id() == td_api::inputMessageInvoice::ID); + auto input_invoice = move_tl_object_as(input_message_content); + if (input_invoice->invoice_ == nullptr) { + return Status::Error(400, "Invoice must be non-empty"); + } + + if (!clean_input_string(input_invoice->title_)) { + return Status::Error(400, "Invoice title must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->description_)) { + return Status::Error(400, "Invoice description must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->photo_url_)) { + return Status::Error(400, "Invoice photo URL must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->start_parameter_)) { + return Status::Error(400, "Invoice bot start parameter must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->provider_token_)) { + return Status::Error(400, "Invoice provider token must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->provider_data_)) { + return Status::Error(400, "Invoice provider data must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->invoice_->currency_)) { + return Status::Error(400, "Invoice currency must be encoded in UTF-8"); + } + + InputInvoice result; + result.title = std::move(input_invoice->title_); + result.description = std::move(input_invoice->description_); + + auto r_http_url = parse_url(input_invoice->photo_url_); + if (r_http_url.is_error()) { + if (!input_invoice->photo_url_.empty()) { + LOG(INFO) << "Can't register url " << input_invoice->photo_url_; + } + } else { + auto url = r_http_url.ok().get_url(); + auto r_invoice_file_id = td->file_manager_->from_persistent_id(url, FileType::Temp); + if (r_invoice_file_id.is_error()) { + LOG(INFO) << "Can't register url " << url; + } else { + auto invoice_file_id = r_invoice_file_id.move_as_ok(); + + PhotoSize s; + s.type = 'n'; + s.dimensions = get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, nullptr); + s.size = input_invoice->photo_size_; // TODO use invoice_file_id size + s.file_id = invoice_file_id; + + result.photo.id = 0; + result.photo.photos.push_back(s); + } + } + result.start_parameter = std::move(input_invoice->start_parameter_); + + result.invoice.currency = std::move(input_invoice->invoice_->currency_); + result.invoice.price_parts.reserve(input_invoice->invoice_->price_parts_.size()); + int64 total_amount = 0; + for (auto &price : input_invoice->invoice_->price_parts_) { + if (!clean_input_string(price->label_)) { + return Status::Error(400, "Invoice price label must be encoded in UTF-8"); + } + if (!check_currency_amount(price->amount_)) { + return Status::Error(400, "Too big amount of the currency specified"); + } + result.invoice.price_parts.emplace_back(std::move(price->label_), price->amount_); + total_amount += price->amount_; + } + if (total_amount <= 0) { + return Status::Error(400, "Total price must be positive"); + } + if (!check_currency_amount(total_amount)) { + return Status::Error(400, "Total price is too big"); + } + result.total_amount = total_amount; + + if (input_invoice->invoice_->max_tip_amount_ < 0 || + !check_currency_amount(input_invoice->invoice_->max_tip_amount_)) { + return Status::Error(400, "Invalid max_tip_amount of the currency specified"); + } + for (auto tip_amount : input_invoice->invoice_->suggested_tip_amounts_) { + if (tip_amount <= 0) { + return Status::Error(400, "Suggested tip amount must be positive"); + } + if (tip_amount > input_invoice->invoice_->max_tip_amount_) { + return Status::Error(400, "Suggested tip amount can't be bigger than max_tip_amount"); + } + } + if (input_invoice->invoice_->suggested_tip_amounts_.size() > 4) { + return Status::Error(400, "There can be at most 4 suggested tip amounts"); + } + + result.invoice.max_tip_amount = input_invoice->invoice_->max_tip_amount_; + result.invoice.suggested_tip_amounts = std::move(input_invoice->invoice_->suggested_tip_amounts_); + result.invoice.recurring_payment_terms_of_service_url = + std::move(input_invoice->invoice_->recurring_payment_terms_of_service_url_); + result.invoice.is_test = input_invoice->invoice_->is_test_; + result.invoice.need_name = input_invoice->invoice_->need_name_; + result.invoice.need_phone_number = input_invoice->invoice_->need_phone_number_; + result.invoice.need_email_address = input_invoice->invoice_->need_email_address_; + result.invoice.need_shipping_address = input_invoice->invoice_->need_shipping_address_; + result.invoice.send_phone_number_to_provider = input_invoice->invoice_->send_phone_number_to_provider_; + result.invoice.send_email_address_to_provider = input_invoice->invoice_->send_email_address_to_provider_; + result.invoice.is_flexible = input_invoice->invoice_->is_flexible_; + if (result.invoice.send_phone_number_to_provider) { + result.invoice.need_phone_number = true; + } + if (result.invoice.send_email_address_to_provider) { + result.invoice.need_email_address = true; + } + if (result.invoice.is_flexible) { + result.invoice.need_shipping_address = true; + } + + result.payload = std::move(input_invoice->payload_); + result.provider_token = std::move(input_invoice->provider_token_); + result.provider_data = std::move(input_invoice->provider_data_); + + // TRY_RESULT(extended_media, MessageExtendedMedia::get_message_extended_media(td, std::move(input_invoice->extended_media_))); + // result.extended_media = std::move(extended_media); + + return result; +} + +tl_object_ptr get_message_invoice_object(const InputInvoice &input_invoice, Td *td, + bool skip_bot_commands, int32 max_media_timestamp) { + return make_tl_object( + input_invoice.title, get_product_description_object(input_invoice.description), + get_photo_object(td->file_manager_.get(), input_invoice.photo), input_invoice.invoice.currency, + input_invoice.total_amount, input_invoice.start_parameter, input_invoice.invoice.is_test, + input_invoice.invoice.need_shipping_address, input_invoice.receipt_message_id.get(), + input_invoice.extended_media.get_message_extended_media_object(td, skip_bot_commands, max_media_timestamp)); +} + +static tl_object_ptr get_input_invoice(const Invoice &invoice) { + int32 flags = 0; + if (invoice.is_test) { + flags |= telegram_api::invoice::TEST_MASK; + } + if (invoice.need_name) { + flags |= telegram_api::invoice::NAME_REQUESTED_MASK; + } + if (invoice.need_phone_number) { + flags |= telegram_api::invoice::PHONE_REQUESTED_MASK; + } + if (invoice.need_email_address) { + flags |= telegram_api::invoice::EMAIL_REQUESTED_MASK; + } + if (invoice.need_shipping_address) { + flags |= telegram_api::invoice::SHIPPING_ADDRESS_REQUESTED_MASK; + } + if (invoice.send_phone_number_to_provider) { + flags |= telegram_api::invoice::PHONE_TO_PROVIDER_MASK; + } + if (invoice.send_email_address_to_provider) { + flags |= telegram_api::invoice::EMAIL_TO_PROVIDER_MASK; + } + if (invoice.is_flexible) { + flags |= telegram_api::invoice::FLEXIBLE_MASK; + } + if (invoice.max_tip_amount != 0) { + flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK; + } + if (!invoice.recurring_payment_terms_of_service_url.empty()) { + flags |= telegram_api::invoice::RECURRING_TERMS_URL_MASK; + } + + auto prices = transform(invoice.price_parts, [](const LabeledPricePart &price) { + return telegram_api::make_object(price.label, price.amount); + }); + return make_tl_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices), + invoice.max_tip_amount, vector(invoice.suggested_tip_amounts), + invoice.recurring_payment_terms_of_service_url); +} + +static tl_object_ptr get_input_web_document(const FileManager *file_manager, + const Photo &photo) { + if (photo.is_empty()) { + return nullptr; + } + + CHECK(photo.photos.size() == 1); + const PhotoSize &size = photo.photos[0]; + CHECK(size.file_id.is_valid()); + + vector> attributes; + if (size.dimensions.width != 0 && size.dimensions.height != 0) { + attributes.push_back( + make_tl_object(size.dimensions.width, size.dimensions.height)); + } + + auto file_view = file_manager->get_file_view(size.file_id); + CHECK(file_view.has_url()); + + auto file_name = get_url_file_name(file_view.url()); + return make_tl_object( + file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"), + std::move(attributes)); +} + +tl_object_ptr get_input_media_invoice(const InputInvoice &input_invoice, Td *td) { + int32 flags = 0; + if (!input_invoice.start_parameter.empty()) { + flags |= telegram_api::inputMediaInvoice::START_PARAM_MASK; + } + auto input_web_document = get_input_web_document(td->file_manager_.get(), input_invoice.photo); + if (input_web_document != nullptr) { + flags |= telegram_api::inputMediaInvoice::PHOTO_MASK; + } + + return make_tl_object( + flags, input_invoice.title, input_invoice.description, std::move(input_web_document), + get_input_invoice(input_invoice.invoice), BufferSlice(input_invoice.payload), input_invoice.provider_token, + telegram_api::make_object( + input_invoice.provider_data.empty() ? "null" : input_invoice.provider_data), + input_invoice.start_parameter, nullptr); +} + +tl_object_ptr get_input_bot_inline_message_media_invoice( + const InputInvoice &input_invoice, tl_object_ptr &&reply_markup, Td *td) { + int32 flags = 0; + if (reply_markup != nullptr) { + flags |= telegram_api::inputBotInlineMessageMediaInvoice::REPLY_MARKUP_MASK; + } + auto input_web_document = get_input_web_document(td->file_manager_.get(), input_invoice.photo); + if (input_web_document != nullptr) { + flags |= telegram_api::inputBotInlineMessageMediaInvoice::PHOTO_MASK; + } + return make_tl_object( + flags, input_invoice.title, input_invoice.description, std::move(input_web_document), + get_input_invoice(input_invoice.invoice), BufferSlice(input_invoice.payload), input_invoice.provider_token, + telegram_api::make_object( + input_invoice.provider_data.empty() ? "null" : input_invoice.provider_data), + std::move(reply_markup)); +} + +vector get_input_invoice_file_ids(const Td *td, const InputInvoice &input_invoice) { + auto file_ids = photo_get_file_ids(input_invoice.photo); + input_invoice.extended_media.append_file_ids(td, file_ids); + return file_ids; +} + +void input_invoice_delete_thumbnail(Td *td, InputInvoice &input_invoice) { + input_invoice.extended_media.delete_thumbnail(td); +} + +bool has_input_invoice_media_timestamp(const InputInvoice &input_invoice) { + return input_invoice.extended_media.has_media_timestamp(); +} + +const FormattedText *get_input_invoice_caption(const InputInvoice &input_invoice) { + return input_invoice.extended_media.get_caption(); +} + +int32 get_input_invoice_duration(const Td *td, const InputInvoice &input_invoice) { + return input_invoice.extended_media.get_duration(td); +} + +FileId get_input_invoice_upload_file_id(const InputInvoice &input_invoice) { + return input_invoice.extended_media.get_upload_file_id(); +} + +FileId get_input_invoice_any_file_id(const InputInvoice &input_invoice) { + return input_invoice.extended_media.get_any_file_id(); +} + +FileId get_input_invoice_thumbnail_file_id(const Td *td, const InputInvoice &input_invoice) { + return input_invoice.extended_media.get_thumbnail_file_id(td); +} + +} // namespace td diff --git a/td/telegram/InputInvoice.h b/td/telegram/InputInvoice.h new file mode 100644 index 000000000..251684497 --- /dev/null +++ b/td/telegram/InputInvoice.h @@ -0,0 +1,102 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/files/FileId.h" +#include "td/telegram/LabeledPricePart.h" +#include "td/telegram/MessageExtendedMedia.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/Photo.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Td; + +struct Invoice { + string currency; + vector price_parts; + int64 max_tip_amount = 0; + vector suggested_tip_amounts; + string recurring_payment_terms_of_service_url; + bool is_test = false; + bool need_name = false; + bool need_phone_number = false; + bool need_email_address = false; + bool need_shipping_address = false; + bool send_phone_number_to_provider = false; + bool send_email_address_to_provider = false; + bool is_flexible = false; + + Invoice() = default; + Invoice(string &¤cy, bool is_test, bool need_shipping_address) + : currency(std::move(currency)), is_test(is_test), need_shipping_address(need_shipping_address) { + } +}; + +struct InputInvoice { + string title; + string description; + Photo photo; + string start_parameter; + Invoice invoice; + string payload; + string provider_token; + string provider_data; + MessageExtendedMedia extended_media; + + int64 total_amount = 0; + MessageId receipt_message_id; +}; + +bool operator==(const Invoice &lhs, const Invoice &rhs); +bool operator!=(const Invoice &lhs, const Invoice &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice); + +bool operator==(const InputInvoice &lhs, const InputInvoice &rhs); +bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs); + +InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, + DialogId owner_dialog_id, FormattedText &&message); + +InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, + DialogId owner_dialog_id); + +Result process_input_message_invoice( + td_api::object_ptr &&input_message_content, Td *td); + +tl_object_ptr get_message_invoice_object(const InputInvoice &input_invoice, Td *td, + bool skip_bot_commands, int32 max_media_timestamp); + +tl_object_ptr get_input_media_invoice(const InputInvoice &input_invoice, Td *td); + +tl_object_ptr get_input_bot_inline_message_media_invoice( + const InputInvoice &input_invoice, tl_object_ptr &&reply_markup, Td *td); + +vector get_input_invoice_file_ids(const Td *td, const InputInvoice &input_invoice); + +void input_invoice_delete_thumbnail(Td *td, InputInvoice &input_invoice); + +bool has_input_invoice_media_timestamp(const InputInvoice &input_invoice); + +const FormattedText *get_input_invoice_caption(const InputInvoice &input_invoice); + +int32 get_input_invoice_duration(const Td *td, const InputInvoice &input_invoice); + +FileId get_input_invoice_upload_file_id(const InputInvoice &input_invoice); + +FileId get_input_invoice_any_file_id(const InputInvoice &input_invoice); + +FileId get_input_invoice_thumbnail_file_id(const Td *td, const InputInvoice &input_invoice); + +} // namespace td diff --git a/td/telegram/InputInvoice.hpp b/td/telegram/InputInvoice.hpp new file mode 100644 index 000000000..2e4ff7a81 --- /dev/null +++ b/td/telegram/InputInvoice.hpp @@ -0,0 +1,191 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/InputInvoice.h" + +#include "td/telegram/MessageExtendedMedia.hpp" +#include "td/telegram/Photo.hpp" +#include "td/telegram/Version.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void store(const Invoice &invoice, StorerT &storer) { + bool has_tip = invoice.max_tip_amount != 0; + bool is_recurring = !invoice.recurring_payment_terms_of_service_url.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(invoice.is_test); + STORE_FLAG(invoice.need_name); + STORE_FLAG(invoice.need_phone_number); + STORE_FLAG(invoice.need_email_address); + STORE_FLAG(invoice.need_shipping_address); + STORE_FLAG(invoice.is_flexible); + STORE_FLAG(invoice.send_phone_number_to_provider); + STORE_FLAG(invoice.send_email_address_to_provider); + STORE_FLAG(has_tip); + STORE_FLAG(is_recurring); + END_STORE_FLAGS(); + store(invoice.currency, storer); + store(invoice.price_parts, storer); + if (has_tip) { + store(invoice.max_tip_amount, storer); + store(invoice.suggested_tip_amounts, storer); + } + if (is_recurring) { + store(invoice.recurring_payment_terms_of_service_url, storer); + } +} + +template +void parse(Invoice &invoice, ParserT &parser) { + bool has_tip; + bool is_recurring; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(invoice.is_test); + PARSE_FLAG(invoice.need_name); + PARSE_FLAG(invoice.need_phone_number); + PARSE_FLAG(invoice.need_email_address); + PARSE_FLAG(invoice.need_shipping_address); + PARSE_FLAG(invoice.is_flexible); + PARSE_FLAG(invoice.send_phone_number_to_provider); + PARSE_FLAG(invoice.send_email_address_to_provider); + PARSE_FLAG(has_tip); + PARSE_FLAG(is_recurring); + END_PARSE_FLAGS(); + parse(invoice.currency, parser); + parse(invoice.price_parts, parser); + if (has_tip) { + parse(invoice.max_tip_amount, parser); + parse(invoice.suggested_tip_amounts, parser); + } + if (is_recurring) { + parse(invoice.recurring_payment_terms_of_service_url, parser); + } +} + +template +void store(const InputInvoice &input_invoice, StorerT &storer) { + bool has_description = !input_invoice.description.empty(); + bool has_photo = !input_invoice.photo.is_empty(); + bool has_start_parameter = !input_invoice.start_parameter.empty(); + bool has_payload = !input_invoice.payload.empty(); + bool has_provider_token = !input_invoice.provider_token.empty(); + bool has_provider_data = !input_invoice.provider_data.empty(); + bool has_total_amount = input_invoice.total_amount != 0; + bool has_receipt_message_id = input_invoice.receipt_message_id.is_valid(); + bool has_extended_media = input_invoice.extended_media.is_empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_description); + STORE_FLAG(has_photo); + STORE_FLAG(has_start_parameter); + STORE_FLAG(has_payload); + STORE_FLAG(has_provider_token); + STORE_FLAG(has_provider_data); + STORE_FLAG(has_total_amount); + STORE_FLAG(has_receipt_message_id); + STORE_FLAG(has_extended_media); + END_STORE_FLAGS(); + store(input_invoice.title, storer); + if (has_description) { + store(input_invoice.description, storer); + } + if (has_photo) { + store(input_invoice.photo, storer); + } + if (has_start_parameter) { + store(input_invoice.start_parameter, storer); + } + store(input_invoice.invoice, storer); + if (has_payload) { + store(input_invoice.payload, storer); + } + if (has_provider_token) { + store(input_invoice.provider_token, storer); + } + if (has_provider_data) { + store(input_invoice.provider_data, storer); + } + if (has_total_amount) { + store(input_invoice.total_amount, storer); + } + if (has_receipt_message_id) { + store(input_invoice.receipt_message_id, storer); + } + if (has_extended_media) { + store(input_invoice.extended_media, storer); + } +} + +template +void parse(InputInvoice &input_invoice, ParserT &parser) { + bool has_description; + bool has_photo; + bool has_start_parameter; + bool has_payload; + bool has_provider_token; + bool has_provider_data; + bool has_total_amount; + bool has_receipt_message_id; + bool has_extended_media; + if (parser.version() >= static_cast(Version::AddInputInvoiceFlags)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_description); + PARSE_FLAG(has_photo); + PARSE_FLAG(has_start_parameter); + PARSE_FLAG(has_payload); + PARSE_FLAG(has_provider_token); + PARSE_FLAG(has_provider_data); + PARSE_FLAG(has_total_amount); + PARSE_FLAG(has_receipt_message_id); + PARSE_FLAG(has_extended_media); + END_PARSE_FLAGS(); + } else { + has_description = true; + has_photo = true; + has_start_parameter = true; + has_payload = true; + has_provider_token = true; + has_provider_data = parser.version() >= static_cast(Version::AddMessageInvoiceProviderData); + has_total_amount = true; + has_receipt_message_id = true; + has_extended_media = false; + } + parse(input_invoice.title, parser); + if (has_description) { + parse(input_invoice.description, parser); + } + if (has_photo) { + parse(input_invoice.photo, parser); + } + if (has_start_parameter) { + parse(input_invoice.start_parameter, parser); + } + parse(input_invoice.invoice, parser); + if (has_payload) { + parse(input_invoice.payload, parser); + } + if (has_provider_token) { + parse(input_invoice.provider_token, parser); + } + if (has_provider_data) { + parse(input_invoice.provider_data, parser); + } + if (has_total_amount) { + parse(input_invoice.total_amount, parser); + } + if (has_receipt_message_id) { + parse(input_invoice.receipt_message_id, parser); + } + if (has_extended_media) { + parse(input_invoice.extended_media, parser); + } +} + +} // namespace td diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 10b325a60..6c434a9c8 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -34,6 +34,8 @@ #include "td/telegram/GroupCallManager.h" #include "td/telegram/HashtagHints.h" #include "td/telegram/InputGroupCallId.h" +#include "td/telegram/InputInvoice.h" +#include "td/telegram/InputInvoice.hpp" #include "td/telegram/InputMessageText.h" #include "td/telegram/Location.h" #include "td/telegram/MessageEntity.h" diff --git a/td/telegram/Payments.cpp b/td/telegram/Payments.cpp index d067afec9..f68074f2c 100644 --- a/td/telegram/Payments.cpp +++ b/td/telegram/Payments.cpp @@ -12,6 +12,7 @@ #include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileType.h" #include "td/telegram/Global.h" +#include "td/telegram/InputInvoice.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" @@ -26,24 +27,21 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/format.h" -#include "td/utils/HttpUrl.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" -#include "td/utils/MimeType.h" -#include "td/utils/PathView.h" #include "td/utils/Status.h" namespace td { -namespace { - -static tl_object_ptr get_product_description_object(const string &description) { +tl_object_ptr get_product_description_object(const string &description) { FormattedText result; result.text = description; result.entities = find_entities(result.text, true, true); return get_formatted_text_object(result, true, 0); } +namespace { + struct InputInvoiceInfo { DialogId dialog_id_; telegram_api::object_ptr input_invoice_; @@ -707,380 +705,6 @@ class GetBankCardInfoQuery final : public Td::ResultHandler { } }; -bool operator==(const Invoice &lhs, const Invoice &rhs) { - return lhs.is_test == rhs.is_test && lhs.need_name == rhs.need_name && - lhs.need_phone_number == rhs.need_phone_number && lhs.need_email_address == rhs.need_email_address && - lhs.need_shipping_address == rhs.need_shipping_address && - lhs.send_phone_number_to_provider == rhs.send_phone_number_to_provider && - lhs.send_email_address_to_provider == rhs.send_email_address_to_provider && - lhs.is_flexible == rhs.is_flexible && lhs.currency == rhs.currency && lhs.price_parts == rhs.price_parts && - lhs.max_tip_amount == rhs.max_tip_amount && lhs.suggested_tip_amounts == rhs.suggested_tip_amounts && - lhs.recurring_payment_terms_of_service_url == rhs.recurring_payment_terms_of_service_url; -} - -bool operator!=(const Invoice &lhs, const Invoice &rhs) { - return !(lhs == rhs); -} - -StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice) { - return string_builder << "[" << (invoice.is_flexible ? "Flexible" : "") << (invoice.is_test ? "Test" : "") - << "Invoice" << (invoice.need_name ? ", needs name" : "") - << (invoice.need_phone_number ? ", needs phone number" : "") - << (invoice.need_email_address ? ", needs email address" : "") - << (invoice.need_shipping_address ? ", needs shipping address" : "") - << (invoice.send_phone_number_to_provider ? ", sends phone number to provider" : "") - << (invoice.send_email_address_to_provider ? ", sends email address to provider" : "") - << (invoice.recurring_payment_terms_of_service_url.empty() - ? string() - : ", recurring payments terms of service at " + - invoice.recurring_payment_terms_of_service_url) - << " in " << invoice.currency << " with price parts " << format::as_array(invoice.price_parts) - << " and suggested tip amounts " << invoice.suggested_tip_amounts << " up to " - << invoice.max_tip_amount << "]"; -} - -bool operator==(const InputInvoice &lhs, const InputInvoice &rhs) { - return lhs.title == rhs.title && lhs.description == rhs.description && lhs.photo == rhs.photo && - lhs.start_parameter == rhs.start_parameter && lhs.invoice == rhs.invoice && - lhs.total_amount == rhs.total_amount && lhs.receipt_message_id == rhs.receipt_message_id && - lhs.payload == rhs.payload && lhs.provider_token == rhs.provider_token && - lhs.provider_data == rhs.provider_data && lhs.extended_media == rhs.extended_media; -} - -bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs) { - return !(lhs == rhs); -} - -InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, - DialogId owner_dialog_id, FormattedText &&message) { - InputInvoice result; - result.title = std::move(message_invoice->title_); - result.description = std::move(message_invoice->description_); - result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); - result.start_parameter = std::move(message_invoice->start_param_); - result.invoice.currency = std::move(message_invoice->currency_); - result.invoice.is_test = message_invoice->test_; - result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; - // result.payload = string(); - // result.provider_token = string(); - // result.provider_data = string(); - result.extended_media = - MessageExtendedMedia(td, std::move(message_invoice->extended_media_), std::move(message), owner_dialog_id); - if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { - LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; - message_invoice->total_amount_ = 0; - } - result.total_amount = message_invoice->total_amount_; - if ((message_invoice->flags_ & telegram_api::messageMediaInvoice::RECEIPT_MSG_ID_MASK) != 0) { - result.receipt_message_id = MessageId(ServerMessageId(message_invoice->receipt_msg_id_)); - if (!result.receipt_message_id.is_valid()) { - LOG(ERROR) << "Receive as receipt message " << result.receipt_message_id << " in " << owner_dialog_id; - result.receipt_message_id = MessageId(); - } - } - return result; -} - -InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, - DialogId owner_dialog_id) { - InputInvoice result; - result.title = std::move(message_invoice->title_); - result.description = std::move(message_invoice->description_); - result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); - // result.start_parameter = string(); - result.invoice.currency = std::move(message_invoice->currency_); - result.invoice.is_test = message_invoice->test_; - result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; - // result.payload = string(); - // result.provider_token = string(); - // result.provider_data = string(); - // result.extended_media = MessageExtendedMedia(); - if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { - LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; - message_invoice->total_amount_ = 0; - } - result.total_amount = message_invoice->total_amount_; - // result.receipt_message_id = MessageId(); - return result; -} - -Result process_input_message_invoice( - td_api::object_ptr &&input_message_content, Td *td) { - CHECK(input_message_content != nullptr); - CHECK(input_message_content->get_id() == td_api::inputMessageInvoice::ID); - auto input_invoice = move_tl_object_as(input_message_content); - if (input_invoice->invoice_ == nullptr) { - return Status::Error(400, "Invoice must be non-empty"); - } - - if (!clean_input_string(input_invoice->title_)) { - return Status::Error(400, "Invoice title must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->description_)) { - return Status::Error(400, "Invoice description must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->photo_url_)) { - return Status::Error(400, "Invoice photo URL must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->start_parameter_)) { - return Status::Error(400, "Invoice bot start parameter must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->provider_token_)) { - return Status::Error(400, "Invoice provider token must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->provider_data_)) { - return Status::Error(400, "Invoice provider data must be encoded in UTF-8"); - } - if (!clean_input_string(input_invoice->invoice_->currency_)) { - return Status::Error(400, "Invoice currency must be encoded in UTF-8"); - } - - InputInvoice result; - result.title = std::move(input_invoice->title_); - result.description = std::move(input_invoice->description_); - - auto r_http_url = parse_url(input_invoice->photo_url_); - if (r_http_url.is_error()) { - if (!input_invoice->photo_url_.empty()) { - LOG(INFO) << "Can't register url " << input_invoice->photo_url_; - } - } else { - auto url = r_http_url.ok().get_url(); - auto r_invoice_file_id = td->file_manager_->from_persistent_id(url, FileType::Temp); - if (r_invoice_file_id.is_error()) { - LOG(INFO) << "Can't register url " << url; - } else { - auto invoice_file_id = r_invoice_file_id.move_as_ok(); - - PhotoSize s; - s.type = 'n'; - s.dimensions = get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, nullptr); - s.size = input_invoice->photo_size_; // TODO use invoice_file_id size - s.file_id = invoice_file_id; - - result.photo.id = 0; - result.photo.photos.push_back(s); - } - } - result.start_parameter = std::move(input_invoice->start_parameter_); - - result.invoice.currency = std::move(input_invoice->invoice_->currency_); - result.invoice.price_parts.reserve(input_invoice->invoice_->price_parts_.size()); - int64 total_amount = 0; - for (auto &price : input_invoice->invoice_->price_parts_) { - if (!clean_input_string(price->label_)) { - return Status::Error(400, "Invoice price label must be encoded in UTF-8"); - } - if (!check_currency_amount(price->amount_)) { - return Status::Error(400, "Too big amount of the currency specified"); - } - result.invoice.price_parts.emplace_back(std::move(price->label_), price->amount_); - total_amount += price->amount_; - } - if (total_amount <= 0) { - return Status::Error(400, "Total price must be positive"); - } - if (!check_currency_amount(total_amount)) { - return Status::Error(400, "Total price is too big"); - } - result.total_amount = total_amount; - - if (input_invoice->invoice_->max_tip_amount_ < 0 || - !check_currency_amount(input_invoice->invoice_->max_tip_amount_)) { - return Status::Error(400, "Invalid max_tip_amount of the currency specified"); - } - for (auto tip_amount : input_invoice->invoice_->suggested_tip_amounts_) { - if (tip_amount <= 0) { - return Status::Error(400, "Suggested tip amount must be positive"); - } - if (tip_amount > input_invoice->invoice_->max_tip_amount_) { - return Status::Error(400, "Suggested tip amount can't be bigger than max_tip_amount"); - } - } - if (input_invoice->invoice_->suggested_tip_amounts_.size() > 4) { - return Status::Error(400, "There can be at most 4 suggested tip amounts"); - } - - result.invoice.max_tip_amount = input_invoice->invoice_->max_tip_amount_; - result.invoice.suggested_tip_amounts = std::move(input_invoice->invoice_->suggested_tip_amounts_); - result.invoice.recurring_payment_terms_of_service_url = - std::move(input_invoice->invoice_->recurring_payment_terms_of_service_url_); - result.invoice.is_test = input_invoice->invoice_->is_test_; - result.invoice.need_name = input_invoice->invoice_->need_name_; - result.invoice.need_phone_number = input_invoice->invoice_->need_phone_number_; - result.invoice.need_email_address = input_invoice->invoice_->need_email_address_; - result.invoice.need_shipping_address = input_invoice->invoice_->need_shipping_address_; - result.invoice.send_phone_number_to_provider = input_invoice->invoice_->send_phone_number_to_provider_; - result.invoice.send_email_address_to_provider = input_invoice->invoice_->send_email_address_to_provider_; - result.invoice.is_flexible = input_invoice->invoice_->is_flexible_; - if (result.invoice.send_phone_number_to_provider) { - result.invoice.need_phone_number = true; - } - if (result.invoice.send_email_address_to_provider) { - result.invoice.need_email_address = true; - } - if (result.invoice.is_flexible) { - result.invoice.need_shipping_address = true; - } - - result.payload = std::move(input_invoice->payload_); - result.provider_token = std::move(input_invoice->provider_token_); - result.provider_data = std::move(input_invoice->provider_data_); - - // TRY_RESULT(extended_media, MessageExtendedMedia::get_message_extended_media(td, std::move(input_invoice->extended_media_))); - // result.extended_media = std::move(extended_media); - - return result; -} - -tl_object_ptr get_message_invoice_object(const InputInvoice &input_invoice, Td *td, - bool skip_bot_commands, int32 max_media_timestamp) { - return make_tl_object( - input_invoice.title, get_product_description_object(input_invoice.description), - get_photo_object(td->file_manager_.get(), input_invoice.photo), input_invoice.invoice.currency, - input_invoice.total_amount, input_invoice.start_parameter, input_invoice.invoice.is_test, - input_invoice.invoice.need_shipping_address, input_invoice.receipt_message_id.get(), - input_invoice.extended_media.get_message_extended_media_object(td, skip_bot_commands, max_media_timestamp)); -} - -static tl_object_ptr get_input_invoice(const Invoice &invoice) { - int32 flags = 0; - if (invoice.is_test) { - flags |= telegram_api::invoice::TEST_MASK; - } - if (invoice.need_name) { - flags |= telegram_api::invoice::NAME_REQUESTED_MASK; - } - if (invoice.need_phone_number) { - flags |= telegram_api::invoice::PHONE_REQUESTED_MASK; - } - if (invoice.need_email_address) { - flags |= telegram_api::invoice::EMAIL_REQUESTED_MASK; - } - if (invoice.need_shipping_address) { - flags |= telegram_api::invoice::SHIPPING_ADDRESS_REQUESTED_MASK; - } - if (invoice.send_phone_number_to_provider) { - flags |= telegram_api::invoice::PHONE_TO_PROVIDER_MASK; - } - if (invoice.send_email_address_to_provider) { - flags |= telegram_api::invoice::EMAIL_TO_PROVIDER_MASK; - } - if (invoice.is_flexible) { - flags |= telegram_api::invoice::FLEXIBLE_MASK; - } - if (invoice.max_tip_amount != 0) { - flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK; - } - if (!invoice.recurring_payment_terms_of_service_url.empty()) { - flags |= telegram_api::invoice::RECURRING_TERMS_URL_MASK; - } - - auto prices = transform(invoice.price_parts, [](const LabeledPricePart &price) { - return telegram_api::make_object(price.label, price.amount); - }); - return make_tl_object( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices), - invoice.max_tip_amount, vector(invoice.suggested_tip_amounts), - invoice.recurring_payment_terms_of_service_url); -} - -static tl_object_ptr get_input_web_document(const FileManager *file_manager, - const Photo &photo) { - if (photo.is_empty()) { - return nullptr; - } - - CHECK(photo.photos.size() == 1); - const PhotoSize &size = photo.photos[0]; - CHECK(size.file_id.is_valid()); - - vector> attributes; - if (size.dimensions.width != 0 && size.dimensions.height != 0) { - attributes.push_back( - make_tl_object(size.dimensions.width, size.dimensions.height)); - } - - auto file_view = file_manager->get_file_view(size.file_id); - CHECK(file_view.has_url()); - - auto file_name = get_url_file_name(file_view.url()); - return make_tl_object( - file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"), - std::move(attributes)); -} - -tl_object_ptr get_input_media_invoice(const InputInvoice &input_invoice, Td *td) { - int32 flags = 0; - if (!input_invoice.start_parameter.empty()) { - flags |= telegram_api::inputMediaInvoice::START_PARAM_MASK; - } - auto input_web_document = get_input_web_document(td->file_manager_.get(), input_invoice.photo); - if (input_web_document != nullptr) { - flags |= telegram_api::inputMediaInvoice::PHOTO_MASK; - } - - return make_tl_object( - flags, input_invoice.title, input_invoice.description, std::move(input_web_document), - get_input_invoice(input_invoice.invoice), BufferSlice(input_invoice.payload), input_invoice.provider_token, - telegram_api::make_object( - input_invoice.provider_data.empty() ? "null" : input_invoice.provider_data), - input_invoice.start_parameter, nullptr); -} - -tl_object_ptr get_input_bot_inline_message_media_invoice( - const InputInvoice &input_invoice, tl_object_ptr &&reply_markup, Td *td) { - int32 flags = 0; - if (reply_markup != nullptr) { - flags |= telegram_api::inputBotInlineMessageMediaInvoice::REPLY_MARKUP_MASK; - } - auto input_web_document = get_input_web_document(td->file_manager_.get(), input_invoice.photo); - if (input_web_document != nullptr) { - flags |= telegram_api::inputBotInlineMessageMediaInvoice::PHOTO_MASK; - } - return make_tl_object( - flags, input_invoice.title, input_invoice.description, std::move(input_web_document), - get_input_invoice(input_invoice.invoice), BufferSlice(input_invoice.payload), input_invoice.provider_token, - telegram_api::make_object( - input_invoice.provider_data.empty() ? "null" : input_invoice.provider_data), - std::move(reply_markup)); -} - -vector get_input_invoice_file_ids(const Td *td, const InputInvoice &input_invoice) { - auto file_ids = photo_get_file_ids(input_invoice.photo); - input_invoice.extended_media.append_file_ids(td, file_ids); - return file_ids; -} - -void input_invoice_delete_thumbnail(Td *td, InputInvoice &input_invoice) { - input_invoice.extended_media.delete_thumbnail(td); -} - -bool has_input_invoice_media_timestamp(const InputInvoice &input_invoice) { - return input_invoice.extended_media.has_media_timestamp(); -} - -const FormattedText *get_input_invoice_caption(const InputInvoice &input_invoice) { - return input_invoice.extended_media.get_caption(); -} - -int32 get_input_invoice_duration(const Td *td, const InputInvoice &input_invoice) { - return input_invoice.extended_media.get_duration(td); -} - -FileId get_input_invoice_upload_file_id(const InputInvoice &input_invoice) { - return input_invoice.extended_media.get_upload_file_id(); -} - -FileId get_input_invoice_any_file_id(const InputInvoice &input_invoice) { - return input_invoice.extended_media.get_any_file_id(); -} - -FileId get_input_invoice_thumbnail_file_id(const Td *td, const InputInvoice &input_invoice) { - return input_invoice.extended_media.get_thumbnail_file_id(td); -} - bool operator==(const Address &lhs, const Address &rhs) { return lhs.country_code == rhs.country_code && lhs.state == rhs.state && lhs.city == rhs.city && lhs.street_line1 == rhs.street_line1 && lhs.street_line2 == rhs.street_line2 && diff --git a/td/telegram/Payments.h b/td/telegram/Payments.h index 2f673f102..bdb29444f 100644 --- a/td/telegram/Payments.h +++ b/td/telegram/Payments.h @@ -7,12 +7,8 @@ #pragma once #include "td/telegram/DialogId.h" -#include "td/telegram/files/FileId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/LabeledPricePart.h" -#include "td/telegram/MessageExtendedMedia.h" -#include "td/telegram/MessageId.h" -#include "td/telegram/Photo.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -26,42 +22,6 @@ namespace td { class Td; -struct Invoice { - string currency; - vector price_parts; - int64 max_tip_amount = 0; - vector suggested_tip_amounts; - string recurring_payment_terms_of_service_url; - bool is_test = false; - bool need_name = false; - bool need_phone_number = false; - bool need_email_address = false; - bool need_shipping_address = false; - bool send_phone_number_to_provider = false; - bool send_email_address_to_provider = false; - bool is_flexible = false; - - Invoice() = default; - Invoice(string &¤cy, bool is_test, bool need_shipping_address) - : currency(std::move(currency)), is_test(is_test), need_shipping_address(need_shipping_address) { - } -}; - -struct InputInvoice { - string title; - string description; - Photo photo; - string start_parameter; - Invoice invoice; - string payload; - string provider_token; - string provider_data; - MessageExtendedMedia extended_media; - - int64 total_amount = 0; - MessageId receipt_message_id; -}; - struct Address { string country_code; string state; @@ -103,52 +63,6 @@ struct ShippingOption { vector price_parts; }; -bool operator==(const LabeledPricePart &lhs, const LabeledPricePart &rhs); -bool operator!=(const LabeledPricePart &lhs, const LabeledPricePart &rhs); - -StringBuilder &operator<<(StringBuilder &string_builder, const LabeledPricePart &labeled_price_part); - -bool operator==(const Invoice &lhs, const Invoice &rhs); -bool operator!=(const Invoice &lhs, const Invoice &rhs); - -StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice); - -bool operator==(const InputInvoice &lhs, const InputInvoice &rhs); -bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs); - -InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, - DialogId owner_dialog_id, FormattedText &&message); - -InputInvoice get_input_invoice(tl_object_ptr &&message_invoice, Td *td, - DialogId owner_dialog_id); - -Result process_input_message_invoice( - td_api::object_ptr &&input_message_content, Td *td); - -tl_object_ptr get_message_invoice_object(const InputInvoice &input_invoice, Td *td, - bool skip_bot_commands, int32 max_media_timestamp); - -tl_object_ptr get_input_media_invoice(const InputInvoice &input_invoice, Td *td); - -tl_object_ptr get_input_bot_inline_message_media_invoice( - const InputInvoice &input_invoice, tl_object_ptr &&reply_markup, Td *td); - -vector get_input_invoice_file_ids(const Td *td, const InputInvoice &input_invoice); - -void input_invoice_delete_thumbnail(Td *td, InputInvoice &input_invoice); - -bool has_input_invoice_media_timestamp(const InputInvoice &input_invoice); - -const FormattedText *get_input_invoice_caption(const InputInvoice &input_invoice); - -int32 get_input_invoice_duration(const Td *td, const InputInvoice &input_invoice); - -FileId get_input_invoice_upload_file_id(const InputInvoice &input_invoice); - -FileId get_input_invoice_any_file_id(const InputInvoice &input_invoice); - -FileId get_input_invoice_thumbnail_file_id(const Td *td, const InputInvoice &input_invoice); - bool operator==(const Address &lhs, const Address &rhs); bool operator!=(const Address &lhs, const Address &rhs); @@ -184,6 +98,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ShippingOption &s bool check_currency_amount(int64 amount); +tl_object_ptr get_product_description_object(const string &description); + void answer_shipping_query(Td *td, int64 shipping_query_id, vector> &&shipping_options, const string &error_message, Promise &&promise); diff --git a/td/telegram/Payments.hpp b/td/telegram/Payments.hpp index 0dec2c03b..3938a8715 100644 --- a/td/telegram/Payments.hpp +++ b/td/telegram/Payments.hpp @@ -8,186 +8,10 @@ #include "td/telegram/Payments.h" -#include "td/telegram/MessageExtendedMedia.hpp" -#include "td/telegram/Photo.hpp" -#include "td/telegram/Version.h" - #include "td/utils/tl_helpers.h" namespace td { -template -void store(const Invoice &invoice, StorerT &storer) { - bool has_tip = invoice.max_tip_amount != 0; - bool is_recurring = !invoice.recurring_payment_terms_of_service_url.empty(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(invoice.is_test); - STORE_FLAG(invoice.need_name); - STORE_FLAG(invoice.need_phone_number); - STORE_FLAG(invoice.need_email_address); - STORE_FLAG(invoice.need_shipping_address); - STORE_FLAG(invoice.is_flexible); - STORE_FLAG(invoice.send_phone_number_to_provider); - STORE_FLAG(invoice.send_email_address_to_provider); - STORE_FLAG(has_tip); - STORE_FLAG(is_recurring); - END_STORE_FLAGS(); - store(invoice.currency, storer); - store(invoice.price_parts, storer); - if (has_tip) { - store(invoice.max_tip_amount, storer); - store(invoice.suggested_tip_amounts, storer); - } - if (is_recurring) { - store(invoice.recurring_payment_terms_of_service_url, storer); - } -} - -template -void parse(Invoice &invoice, ParserT &parser) { - bool has_tip; - bool is_recurring; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(invoice.is_test); - PARSE_FLAG(invoice.need_name); - PARSE_FLAG(invoice.need_phone_number); - PARSE_FLAG(invoice.need_email_address); - PARSE_FLAG(invoice.need_shipping_address); - PARSE_FLAG(invoice.is_flexible); - PARSE_FLAG(invoice.send_phone_number_to_provider); - PARSE_FLAG(invoice.send_email_address_to_provider); - PARSE_FLAG(has_tip); - PARSE_FLAG(is_recurring); - END_PARSE_FLAGS(); - parse(invoice.currency, parser); - parse(invoice.price_parts, parser); - if (has_tip) { - parse(invoice.max_tip_amount, parser); - parse(invoice.suggested_tip_amounts, parser); - } - if (is_recurring) { - parse(invoice.recurring_payment_terms_of_service_url, parser); - } -} - -template -void store(const InputInvoice &input_invoice, StorerT &storer) { - bool has_description = !input_invoice.description.empty(); - bool has_photo = !input_invoice.photo.is_empty(); - bool has_start_parameter = !input_invoice.start_parameter.empty(); - bool has_payload = !input_invoice.payload.empty(); - bool has_provider_token = !input_invoice.provider_token.empty(); - bool has_provider_data = !input_invoice.provider_data.empty(); - bool has_total_amount = input_invoice.total_amount != 0; - bool has_receipt_message_id = input_invoice.receipt_message_id.is_valid(); - bool has_extended_media = input_invoice.extended_media.is_empty(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(has_description); - STORE_FLAG(has_photo); - STORE_FLAG(has_start_parameter); - STORE_FLAG(has_payload); - STORE_FLAG(has_provider_token); - STORE_FLAG(has_provider_data); - STORE_FLAG(has_total_amount); - STORE_FLAG(has_receipt_message_id); - STORE_FLAG(has_extended_media); - END_STORE_FLAGS(); - store(input_invoice.title, storer); - if (has_description) { - store(input_invoice.description, storer); - } - if (has_photo) { - store(input_invoice.photo, storer); - } - if (has_start_parameter) { - store(input_invoice.start_parameter, storer); - } - store(input_invoice.invoice, storer); - if (has_payload) { - store(input_invoice.payload, storer); - } - if (has_provider_token) { - store(input_invoice.provider_token, storer); - } - if (has_provider_data) { - store(input_invoice.provider_data, storer); - } - if (has_total_amount) { - store(input_invoice.total_amount, storer); - } - if (has_receipt_message_id) { - store(input_invoice.receipt_message_id, storer); - } - if (has_extended_media) { - store(input_invoice.extended_media, storer); - } -} - -template -void parse(InputInvoice &input_invoice, ParserT &parser) { - bool has_description; - bool has_photo; - bool has_start_parameter; - bool has_payload; - bool has_provider_token; - bool has_provider_data; - bool has_total_amount; - bool has_receipt_message_id; - bool has_extended_media; - if (parser.version() >= static_cast(Version::AddInputInvoiceFlags)) { - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_description); - PARSE_FLAG(has_photo); - PARSE_FLAG(has_start_parameter); - PARSE_FLAG(has_payload); - PARSE_FLAG(has_provider_token); - PARSE_FLAG(has_provider_data); - PARSE_FLAG(has_total_amount); - PARSE_FLAG(has_receipt_message_id); - PARSE_FLAG(has_extended_media); - END_PARSE_FLAGS(); - } else { - has_description = true; - has_photo = true; - has_start_parameter = true; - has_payload = true; - has_provider_token = true; - has_provider_data = parser.version() >= static_cast(Version::AddMessageInvoiceProviderData); - has_total_amount = true; - has_receipt_message_id = true; - has_extended_media = false; - } - parse(input_invoice.title, parser); - if (has_description) { - parse(input_invoice.description, parser); - } - if (has_photo) { - parse(input_invoice.photo, parser); - } - if (has_start_parameter) { - parse(input_invoice.start_parameter, parser); - } - parse(input_invoice.invoice, parser); - if (has_payload) { - parse(input_invoice.payload, parser); - } - if (has_provider_token) { - parse(input_invoice.provider_token, parser); - } - if (has_provider_data) { - parse(input_invoice.provider_data, parser); - } - if (has_total_amount) { - parse(input_invoice.total_amount, parser); - } - if (has_receipt_message_id) { - parse(input_invoice.receipt_message_id, parser); - } - if (has_extended_media) { - parse(input_invoice.extended_media, parser); - } -} - template void store(const Address &address, StorerT &storer) { store(address.country_code, storer);