Support tip amount in Invoice.

This commit is contained in:
levlam 2021-03-30 18:05:20 +03:00
parent 17e8860855
commit c3ff8539db
5 changed files with 56 additions and 20 deletions

View File

@ -552,7 +552,7 @@ supergroupMembersFilterBots = SupergroupMembersFilter;
//@date Point in time (Unix timestamp) when the link was created
//@edit_date Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown
//@expire_date Point in time (Unix timestamp) when the link will expire; 0 if never
//@member_limit Maximum number of members, which can join the chat using the link simultaneously; 0 if not limited
//@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited
//@member_count Number of chat members, which joined the chat using the link
//@is_primary True, if the link is primary. Primary invite link can't have expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time
//@is_revoked True, if the link was revoked
@ -1306,14 +1306,17 @@ bankCardInfo title:string actions:vector<bankCardActionOpenUrl> = BankCardInfo;
address country_code:string state:string city:string street_line1:string street_line2:string postal_code:string = Address;
//@description Portion of the price of a product (e.g., "delivery cost", "tax amount") @label Label for this portion of the product price @amount Currency amount in minimal quantity of the currency
//@description Portion of the price of a product (e.g., "delivery cost", "tax amount") @label Label for this portion of the product price @amount Currency amount in the smallest units of the currency
labeledPricePart label:string amount:int53 = LabeledPricePart;
//@description Product invoice @currency ISO 4217 currency code @price_parts A list of objects used to calculate the total price of the product @is_test True, if the payment is a test payment
//@description Product invoice @currency ISO 4217 currency code @price_parts A list of objects used to calculate the total price of the product
//@max_tip_amount The maximum allowed amount of tip in the smallest units of the currency
//@suggested_tip_amounts Suggested amounts of tip in the smallest units of the currency
//@is_test True, if the payment is a test payment
//@need_name True, if the user's name is needed for payment @need_phone_number True, if the user's phone number is needed for payment @need_email_address True, if the user's email address is needed for payment
//@need_shipping_address True, if the user's shipping address is needed for payment @send_phone_number_to_provider True, if the user's phone number will be sent to the provider
//@send_email_address_to_provider True, if the user's email address will be sent to the provider @is_flexible True, if the total price depends on the shipping method
invoice currency:string price_parts:vector<labeledPricePart> is_test:Bool need_name:Bool need_phone_number:Bool need_email_address:Bool need_shipping_address:Bool send_phone_number_to_provider:Bool send_email_address_to_provider:Bool is_flexible:Bool = Invoice;
invoice currency:string price_parts:vector<labeledPricePart> max_tip_amount:int53 suggested_tip_amounts:vector<int53> is_test:Bool need_name:Bool need_phone_number:Bool need_email_address:Bool need_shipping_address:Bool send_phone_number_to_provider:Bool send_email_address_to_provider:Bool is_flexible:Bool = Invoice;
//@description Order information @name Name of the user @phone_number Phone number of the user @email_address Email address of the user @shipping_address Shipping address for this order; may be null
orderInfo name:string phone_number:string email_address:string shipping_address:address = OrderInfo;
@ -1667,7 +1670,7 @@ messageGame game:game = MessageContent;
//@description A message with a poll @poll The poll description
messagePoll poll:poll = MessageContent;
//@description A message with an invoice from a bot @title Product title @param_description Product description @photo Product photo; may be null @currency Currency for the product price @total_amount Product total price in the minimal quantity of the currency
//@description A message with an invoice from a bot @title Product title @param_description Product description @photo Product photo; may be null @currency Currency for the product price @total_amount Product total price in the smallest units of the currency
//@start_parameter Unique invoice bot start_parameter. To share an invoice use the URL https://t.me/{bot_username}?start={start_parameter} @is_test True, if the invoice is a test invoice
//@need_shipping_address True, if the shipping address should be specified @receipt_message_id The identifier of the message with the receipt, after the product has been purchased
messageInvoice title:string description:string photo:photo currency:string total_amount:int53 start_parameter:string is_test:Bool need_shipping_address:Bool receipt_message_id:int53 = MessageContent;
@ -1729,11 +1732,11 @@ messageCustomServiceAction text:string = MessageContent;
//@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game; may be different from the games presented in the message with the game @score New score
messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageContent;
//@description A payment has been completed @invoice_message_id Identifier of the message with the corresponding invoice; can be an identifier of a deleted message @currency Currency for the price of the product @total_amount Total price for the product, in the minimal quantity of the currency
//@description A payment has been completed @invoice_message_id Identifier of the message with the corresponding invoice; can be an identifier of a deleted message @currency Currency for the price of the product @total_amount Total price for the product, in the smallest units of the currency
messagePaymentSuccessful invoice_message_id:int53 currency:string total_amount:int53 = MessageContent;
//@description A payment has been completed; for bots only @invoice_message_id Identifier of the message with the corresponding invoice; can be an identifier of a deleted message @currency Currency for price of the product
//@total_amount Total price for the product, in the minimal quantity of the currency @invoice_payload Invoice payload @shipping_option_id Identifier of the shipping option chosen by the user; may be empty if not applicable @order_info Information about the order; may be null
//@total_amount Total price for the product, in the smallest units of the currency @invoice_payload Invoice payload @shipping_option_id Identifier of the shipping option chosen by the user; may be empty if not applicable @order_info Information about the order; may be null
//@telegram_payment_charge_id Telegram payment identifier @provider_payment_charge_id Provider payment identifier
messagePaymentSuccessfulBot invoice_message_id:int53 currency:string total_amount:int53 invoice_payload:bytes shipping_option_id:string order_info:orderInfo telegram_payment_charge_id:string provider_payment_charge_id:string = MessageContent;
@ -3606,7 +3609,7 @@ updateNewInlineCallbackQuery id:int64 sender_user_id:int32 inline_message_id:str
//@description A new incoming shipping query; for bots only. Only for invoices with flexible price @id Unique query identifier @sender_user_id Identifier of the user who sent the query @invoice_payload Invoice payload @shipping_address User shipping address
updateNewShippingQuery id:int64 sender_user_id:int32 invoice_payload:string shipping_address:address = Update;
//@description A new incoming pre-checkout query; for bots only. Contains full information about a checkout @id Unique query identifier @sender_user_id Identifier of the user who sent the query @currency Currency for the product price @total_amount Total price for the product, in the minimal quantity of the currency
//@description A new incoming pre-checkout query; for bots only. Contains full information about a checkout @id Unique query identifier @sender_user_id Identifier of the user who sent the query @currency Currency for the product price @total_amount Total price for the product, in the smallest units of the currency
//@invoice_payload Invoice payload @shipping_option_id Identifier of a shipping option chosen by the user; may be empty if not applicable @order_info Information about the order; may be null
updateNewPreCheckoutQuery id:int64 sender_user_id:int32 currency:string total_amount:int53 invoice_payload:bytes shipping_option_id:string order_info:orderInfo = Update;
@ -4495,14 +4498,14 @@ replacePrimaryChatInviteLink chat_id:int53 = ChatInviteLink;
//@description Creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat
//@chat_id Chat identifier
//@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never
//@member_limit Maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited
//@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited
createChatInviteLink chat_id:int53 expire_date:int32 member_limit:int32 = ChatInviteLink;
//@description Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links
//@chat_id Chat identifier
//@invite_link Invite link to be edited
//@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never
//@member_limit Maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited
//@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited
editChatInviteLink chat_id:int53 invite_link:string expire_date:int32 member_limit:int32 = ChatInviteLink;
//@description Returns information about an invite link. Requires administrator privileges and can_invite_users right in the chat to get own links and owner privileges to get other links
@ -4519,11 +4522,11 @@ getChatInviteLinkCounts chat_id:int53 = ChatInviteLinkCounts;
//@is_revoked Pass true if revoked links needs to be returned instead of active or expired
//@offset_date Creation date of an invite link starting after which to return invite links; use 0 to get results from the beginning
//@offset_invite_link Invite link starting after which to return invite links; use empty string to get results from the beginning
//@limit Maximum number of invite links to return
//@limit The maximum number of invite links to return
getChatInviteLinks chat_id:int53 creator_user_id:int32 is_revoked:Bool offset_date:int32 offset_invite_link:string limit:int32 = ChatInviteLinks;
//@description Returns chat members joined a chat by an invite link. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links @chat_id Chat identifier @invite_link Invite link for which to return chat members
//@offset_member A chat member from which to return next chat members; use null to get results from the beginning @limit Maximum number of chat members to return
//@offset_member A chat member from which to return next chat members; use null to get results from the beginning @limit The maximum number of chat members to return
getChatInviteLinkMembers chat_id:int53 invite_link:string offset_member:chatInviteLinkMember limit:int32 = ChatInviteLinkMembers;
//@description Revokes invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links.
@ -4629,7 +4632,7 @@ toggleGroupCallParticipantIsHandRaised group_call_id:int32 participant:MessageSe
//@description Loads more group call participants. The loaded participants will be received through updates. Use the field groupCall.loaded_all_participants to check whether all participants has already been loaded
//@group_call_id Group call identifier. The group call must be previously received through getGroupCall and must be joined or being joined
//@limit Maximum number of participants to load
//@limit The maximum number of participants to load
loadGroupCallParticipants group_call_id:int32 limit:int32 = Ok;
//@description Leaves a group call @group_call_id Group call identifier

View File

@ -1875,7 +1875,7 @@ static Result<InputMessageContent> create_input_message_content(
}
message_invoice->invoice.price_parts.emplace_back(std::move(price->label_), price->amount_);
if (price->amount_ < -MAX_AMOUNT || price->amount_ > MAX_AMOUNT) {
return Status::Error(400, "Too big amount of currency specified");
return Status::Error(400, "Too big amount of the currency specified");
}
total_amount += price->amount_;
}
@ -1887,6 +1887,17 @@ static Result<InputMessageContent> create_input_message_content(
}
message_invoice->total_amount = total_amount;
if (input_invoice->invoice_->max_tip_amount_ < 0 || input_invoice->invoice_->max_tip_amount_ > MAX_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 || tip_amount > input_invoice->invoice_->max_tip_amount_) {
return Status::Error(400, "Invalid suggested tip amount of the currency specified");
}
}
message_invoice->invoice.max_tip_amount = input_invoice->invoice_->max_tip_amount_;
message_invoice->invoice.suggested_tip_amounts = std::move(input_invoice->invoice_->suggested_tip_amounts_);
message_invoice->invoice.is_test = input_invoice->invoice_->is_test_;
message_invoice->invoice.need_name = input_invoice->invoice_->need_name_;
message_invoice->invoice.need_phone_number = input_invoice->invoice_->need_phone_number_;
@ -2295,13 +2306,17 @@ static tl_object_ptr<telegram_api::invoice> get_input_invoice(const Invoice &inv
if (invoice.is_flexible) {
flags |= telegram_api::invoice::FLEXIBLE_MASK;
}
if (invoice.max_tip_amount != 0) {
flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK;
}
auto prices = transform(invoice.price_parts, [](const LabeledPricePart &price) {
return telegram_api::make_object<telegram_api::labeledPrice>(price.label, price.amount);
});
return make_tl_object<telegram_api::invoice>(
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices), 0, vector<int64>());
false /*ignored*/, false /*ignored*/, false /*ignored*/, invoice.currency, std::move(prices),
invoice.max_tip_amount, vector<int64>(invoice.suggested_tip_amounts));
}
static tl_object_ptr<telegram_api::inputWebDocument> get_input_web_document(const FileManager *file_manager,

View File

@ -129,9 +129,10 @@ static tl_object_ptr<td_api::invoice> convert_invoice(tl_object_ptr<telegram_api
need_shipping_address = true;
}
return make_tl_object<td_api::invoice>(std::move(invoice->currency_), std::move(labeled_prices), is_test, need_name,
need_phone_number, need_email_address, need_shipping_address,
send_phone_number_to_provider, send_email_address_to_provider, is_flexible);
return make_tl_object<td_api::invoice>(
std::move(invoice->currency_), std::move(labeled_prices), invoice->max_tip_amount_,
vector<int64>(invoice->suggested_tip_amounts_), is_test, need_name, need_phone_number, need_email_address,
need_shipping_address, send_phone_number_to_provider, send_email_address_to_provider, is_flexible);
}
static tl_object_ptr<td_api::paymentsProviderStripe> convert_payment_provider(
@ -574,7 +575,8 @@ bool operator==(const Invoice &lhs, const Invoice &rhs) {
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.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;
}
bool operator!=(const Invoice &lhs, const Invoice &rhs) {
@ -589,7 +591,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Invoice &invoice)
<< (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" : "") << " in "
<< invoice.currency << " with price parts " << format::as_array(invoice.price_parts) << "]";
<< 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 Address &lhs, const Address &rhs) {

View File

@ -34,6 +34,8 @@ struct LabeledPricePart {
struct Invoice {
string currency;
vector<LabeledPricePart> price_parts;
int64 max_tip_amount = 0;
vector<int64> suggested_tip_amounts;
bool is_test = false;
bool need_name = false;
bool need_phone_number = false;

View File

@ -28,6 +28,7 @@ void parse(LabeledPricePart &labeled_price_part, ParserT &parser) {
template <class StorerT>
void store(const Invoice &invoice, StorerT &storer) {
bool has_tip = invoice.max_tip_amount != 0;
BEGIN_STORE_FLAGS();
STORE_FLAG(invoice.is_test);
STORE_FLAG(invoice.need_name);
@ -37,13 +38,19 @@ void store(const Invoice &invoice, StorerT &storer) {
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);
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);
}
}
template <class ParserT>
void parse(Invoice &invoice, ParserT &parser) {
bool has_tip;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(invoice.is_test);
PARSE_FLAG(invoice.need_name);
@ -53,9 +60,14 @@ void parse(Invoice &invoice, ParserT &parser) {
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);
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);
}
}
template <class StorerT>