mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Request terms acceptance for recurring payments.
This commit is contained in:
parent
8e6825771e
commit
b7259615a7
11 changed files with 126 additions and 5 deletions
|
@ -2353,6 +2353,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_payments_precheckout_failed" = "The bot couldn't process your payment. Your card has not been billed.";
|
"lng_payments_precheckout_failed" = "The bot couldn't process your payment. Your card has not been billed.";
|
||||||
"lng_payments_already_paid" = "You have already paid for this item.";
|
"lng_payments_already_paid" = "You have already paid for this item.";
|
||||||
|
|
||||||
|
"lng_payments_terms_title" = "Terms of Service";
|
||||||
|
"lng_payments_terms_text" = "Subscribe and accept terms of service of {bot}?";
|
||||||
|
"lng_payments_terms_agree" = "I agree to {link}";
|
||||||
|
"lng_payments_terms_link" = "Terms of Service";
|
||||||
|
"lng_payments_terms_accept" = "Accept";
|
||||||
|
|
||||||
"lng_call_status_incoming" = "is calling you...";
|
"lng_call_status_incoming" = "is calling you...";
|
||||||
"lng_call_status_connecting" = "connecting...";
|
"lng_call_status_connecting" = "connecting...";
|
||||||
"lng_call_status_exchanging" = "exchanging encryption keys...";
|
"lng_call_status_exchanging" = "exchanging encryption keys...";
|
||||||
|
|
|
@ -173,8 +173,8 @@ messageActionChannelMigrateFrom#ea3948e9 title:string chat_id:long = MessageActi
|
||||||
messageActionPinMessage#94bd38ed = MessageAction;
|
messageActionPinMessage#94bd38ed = MessageAction;
|
||||||
messageActionHistoryClear#9fbab604 = MessageAction;
|
messageActionHistoryClear#9fbab604 = MessageAction;
|
||||||
messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
|
messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
|
||||||
messageActionPaymentSentMe#8f31b327 flags:# currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction;
|
messageActionPaymentSentMe#8f31b327 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction;
|
||||||
messageActionPaymentSent#96163f56 flags:# currency:string total_amount:long invoice_slug:flags.0?string = MessageAction;
|
messageActionPaymentSent#96163f56 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string = MessageAction;
|
||||||
messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||||
messageActionScreenshotTaken#4792929b = MessageAction;
|
messageActionScreenshotTaken#4792929b = MessageAction;
|
||||||
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||||
|
@ -826,7 +826,7 @@ dataJSON#7d748d04 data:string = DataJSON;
|
||||||
|
|
||||||
labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;
|
labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;
|
||||||
|
|
||||||
invoice#cd886e0 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> = Invoice;
|
invoice#3e85a91b flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector<LabeledPrice> max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector<long> recurring_terms_url:flags.9?string = Invoice;
|
||||||
|
|
||||||
paymentCharge#ea02c27e id:string provider_charge_id:string = PaymentCharge;
|
paymentCharge#ea02c27e id:string provider_charge_id:string = PaymentCharge;
|
||||||
|
|
||||||
|
@ -1345,7 +1345,7 @@ attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
|
||||||
|
|
||||||
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
|
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
|
||||||
|
|
||||||
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
||||||
|
|
||||||
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
|
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
|
||||||
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
|
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
|
||||||
|
@ -1386,6 +1386,8 @@ payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||||
|
|
||||||
messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio;
|
messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio;
|
||||||
|
|
||||||
|
help.premiumPromo#3f7ae6ee status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> = help.PremiumPromo;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
|
@ -1729,6 +1731,7 @@ help.getPromoData#c0977421 = help.PromoData;
|
||||||
help.hidePromoData#1e251c95 peer:InputPeer = Bool;
|
help.hidePromoData#1e251c95 peer:InputPeer = Bool;
|
||||||
help.dismissSuggestion#f50dbaa1 peer:InputPeer suggestion:string = Bool;
|
help.dismissSuggestion#f50dbaa1 peer:InputPeer suggestion:string = Bool;
|
||||||
help.getCountriesList#735787a8 lang_code:string hash:int = help.CountriesList;
|
help.getCountriesList#735787a8 lang_code:string hash:int = help.CountriesList;
|
||||||
|
help.getPremiumPromo#b81b93d4 = help.PremiumPromo;
|
||||||
|
|
||||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||||
|
@ -1792,6 +1795,7 @@ payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
|
||||||
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
|
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
|
||||||
payments.assignAppStoreTransaction#6299a12f transaction_id:string = Updates;
|
payments.assignAppStoreTransaction#6299a12f transaction_id:string = Updates;
|
||||||
payments.assignPlayMarketTransaction#4faa4aed purchase_token:string = Updates;
|
payments.assignPlayMarketTransaction#4faa4aed purchase_token:string = Updates;
|
||||||
|
payments.requestRecurringPayment#146e958d user_id:InputUser recurring_init_charge:string invoice_media:InputMedia = Updates;
|
||||||
|
|
||||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||||
|
|
|
@ -533,6 +533,10 @@ void CheckoutProcess::panelSubmit() {
|
||||||
_form->validateInformation(_form->information());
|
_form->validateInformation(_form->information());
|
||||||
} else if (!method.newCredentials && !method.savedCredentials) {
|
} else if (!method.newCredentials && !method.savedCredentials) {
|
||||||
editPaymentMethod();
|
editPaymentMethod();
|
||||||
|
} else if (invoice.isRecurring && !_form->details().termsAccepted) {
|
||||||
|
_panel->requestTermsAcceptance(
|
||||||
|
_form->details().termsBotUsername,
|
||||||
|
invoice.recurringTermsUrl);
|
||||||
} else {
|
} else {
|
||||||
RegisterPaymentStart(this, { _form->invoice().cover.title });
|
RegisterPaymentStart(this, { _form->invoice().cover.title });
|
||||||
_submitState = SubmitState::Finishing;
|
_submitState = SubmitState::Finishing;
|
||||||
|
@ -545,6 +549,11 @@ void CheckoutProcess::panelTrustAndSubmit() {
|
||||||
panelSubmit();
|
panelSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckoutProcess::panelAcceptTermsAndSubmit() {
|
||||||
|
_form->acceptTerms();
|
||||||
|
panelSubmit();
|
||||||
|
}
|
||||||
|
|
||||||
void CheckoutProcess::panelWebviewMessage(
|
void CheckoutProcess::panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) {
|
bool saveInformation) {
|
||||||
|
|
|
@ -123,6 +123,7 @@ private:
|
||||||
void panelCloseSure() override;
|
void panelCloseSure() override;
|
||||||
void panelSubmit() override;
|
void panelSubmit() override;
|
||||||
void panelTrustAndSubmit() override;
|
void panelTrustAndSubmit() override;
|
||||||
|
void panelAcceptTermsAndSubmit() override;
|
||||||
void panelWebviewMessage(
|
void panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) override;
|
bool saveInformation) override;
|
||||||
|
|
|
@ -368,9 +368,13 @@ void Form::processInvoice(const MTPDinvoice &data) {
|
||||||
.isPhoneRequested = data.is_phone_requested(),
|
.isPhoneRequested = data.is_phone_requested(),
|
||||||
.isEmailRequested = data.is_email_requested(),
|
.isEmailRequested = data.is_email_requested(),
|
||||||
.isShippingAddressRequested = data.is_shipping_address_requested(),
|
.isShippingAddressRequested = data.is_shipping_address_requested(),
|
||||||
|
.isRecurring = data.is_recurring(),
|
||||||
.isFlexible = data.is_flexible(),
|
.isFlexible = data.is_flexible(),
|
||||||
.isTest = data.is_test(),
|
.isTest = data.is_test(),
|
||||||
|
|
||||||
|
.recurringTermsUrl = qs(
|
||||||
|
data.vrecurring_terms_url().value_or_empty()),
|
||||||
|
|
||||||
.phoneSentToProvider = data.is_phone_to_provider(),
|
.phoneSentToProvider = data.is_phone_to_provider(),
|
||||||
.emailSentToProvider = data.is_email_to_provider(),
|
.emailSentToProvider = data.is_email_to_provider(),
|
||||||
};
|
};
|
||||||
|
@ -403,6 +407,7 @@ void Form::processDetails(const MTPDpayments_paymentForm &data) {
|
||||||
if (const auto botId = _details.botId) {
|
if (const auto botId = _details.botId) {
|
||||||
if (const auto bot = _session->data().userLoaded(botId)) {
|
if (const auto bot = _session->data().userLoaded(botId)) {
|
||||||
_invoice.cover.seller = bot->name;
|
_invoice.cover.seller = bot->name;
|
||||||
|
_details.termsBotUsername = bot->username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (const auto providerId = _details.providerId) {
|
if (const auto providerId = _details.providerId) {
|
||||||
|
@ -938,6 +943,10 @@ void Form::setTips(int64 value) {
|
||||||
_invoice.tipsSelected = std::min(value, _invoice.tipsMax);
|
_invoice.tipsSelected = std::min(value, _invoice.tipsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Form::acceptTerms() {
|
||||||
|
_details.termsAccepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Form::trustBot() {
|
void Form::trustBot() {
|
||||||
_session->local().markBotTrustedPayment(_details.botId);
|
_session->local().markBotTrustedPayment(_details.botId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,13 @@ struct FormDetails {
|
||||||
uint64 formId = 0;
|
uint64 formId = 0;
|
||||||
QString url;
|
QString url;
|
||||||
QString nativeProvider;
|
QString nativeProvider;
|
||||||
|
QString termsBotUsername;
|
||||||
QByteArray nativeParamsJson;
|
QByteArray nativeParamsJson;
|
||||||
UserId botId = 0;
|
UserId botId = 0;
|
||||||
UserId providerId = 0;
|
UserId providerId = 0;
|
||||||
bool canSaveCredentials = false;
|
bool canSaveCredentials = false;
|
||||||
bool passwordMissing = false;
|
bool passwordMissing = false;
|
||||||
|
bool termsAccepted = false;
|
||||||
|
|
||||||
[[nodiscard]] bool valid() const {
|
[[nodiscard]] bool valid() const {
|
||||||
return !url.isEmpty();
|
return !url.isEmpty();
|
||||||
|
@ -223,6 +225,7 @@ public:
|
||||||
void setHasPassword(bool has);
|
void setHasPassword(bool has);
|
||||||
void setShippingOption(const QString &id);
|
void setShippingOption(const QString &id);
|
||||||
void setTips(int64 value);
|
void setTips(int64 value);
|
||||||
|
void acceptTerms();
|
||||||
void trustBot();
|
void trustBot();
|
||||||
void submit();
|
void submit();
|
||||||
void submit(const Core::CloudPasswordResult &result);
|
void submit(const Core::CloudPasswordResult &result);
|
||||||
|
|
|
@ -644,6 +644,91 @@ void Panel::showWarning(const QString &bot, const QString &provider) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panel::requestTermsAcceptance(
|
||||||
|
const QString &username,
|
||||||
|
const QString &url) {
|
||||||
|
showBox(Box([=](not_null<GenericBox*> box) {
|
||||||
|
box->setTitle(tr::lng_payments_terms_title());
|
||||||
|
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||||
|
box.get(),
|
||||||
|
tr::lng_payments_terms_text(
|
||||||
|
lt_bot,
|
||||||
|
rpl::single(Ui::Text::Bold('@' + username)),
|
||||||
|
Ui::Text::WithEntities),
|
||||||
|
st::boxLabel));
|
||||||
|
const auto update = std::make_shared<Fn<void()>>();
|
||||||
|
auto checkView = std::make_unique<Ui::CheckView>(
|
||||||
|
st::defaultCheck,
|
||||||
|
false,
|
||||||
|
[=] { if (*update) { (*update)(); } });
|
||||||
|
const auto check = checkView.get();
|
||||||
|
const auto row = box->addRow(
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
box.get(),
|
||||||
|
tr::lng_payments_terms_agree(
|
||||||
|
lt_link,
|
||||||
|
rpl::single(Ui::Text::Link(
|
||||||
|
tr::lng_payments_terms_link(tr::now),
|
||||||
|
url)),
|
||||||
|
Ui::Text::WithEntities),
|
||||||
|
st::defaultBoxCheckbox,
|
||||||
|
std::move(checkView)),
|
||||||
|
{
|
||||||
|
st::boxRowPadding.left(),
|
||||||
|
st::boxRowPadding.left(),
|
||||||
|
st::boxRowPadding.right(),
|
||||||
|
st::defaultBoxCheckbox.margin.bottom(),
|
||||||
|
});
|
||||||
|
(*update) = [=] { row->update(); };
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
bool error = false;
|
||||||
|
Ui::Animations::Simple errorAnimation;
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<State>();
|
||||||
|
const auto showError = [=] {
|
||||||
|
const auto callback = [=] {
|
||||||
|
const auto error = state->errorAnimation.value(
|
||||||
|
state->error ? 1. : 0.);
|
||||||
|
if (error == 0.) {
|
||||||
|
check->setUntoggledOverride(std::nullopt);
|
||||||
|
} else {
|
||||||
|
const auto color = anim::color(
|
||||||
|
st::defaultCheck.untoggledFg,
|
||||||
|
st::boxTextFgError,
|
||||||
|
error);
|
||||||
|
check->setUntoggledOverride(color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
state->error = true;
|
||||||
|
state->errorAnimation.stop();
|
||||||
|
state->errorAnimation.start(
|
||||||
|
callback,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
st::defaultCheck.duration);
|
||||||
|
};
|
||||||
|
|
||||||
|
row->checkedChanges(
|
||||||
|
) | rpl::filter([=](bool checked) {
|
||||||
|
return checked;
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
state->error = false;
|
||||||
|
check->setUntoggledOverride(std::nullopt);
|
||||||
|
}, row->lifetime());
|
||||||
|
|
||||||
|
box->addButton(tr::lng_payments_terms_accept(), [=] {
|
||||||
|
if (check->checked()) {
|
||||||
|
_delegate->panelAcceptTermsAndSubmit();
|
||||||
|
box->closeBox();
|
||||||
|
} else {
|
||||||
|
showError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::showEditCard(
|
void Panel::showEditCard(
|
||||||
const NativeMethodDetails &native,
|
const NativeMethodDetails &native,
|
||||||
CardField field) {
|
CardField field) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
void askSetPassword();
|
void askSetPassword();
|
||||||
void showCloseConfirm();
|
void showCloseConfirm();
|
||||||
void showWarning(const QString &bot, const QString &provider);
|
void showWarning(const QString &bot, const QString &provider);
|
||||||
|
void requestTermsAcceptance(const QString &username, const QString &url);
|
||||||
|
|
||||||
bool showWebview(
|
bool showWebview(
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
|
|
@ -49,10 +49,12 @@ struct Invoice {
|
||||||
bool isPhoneRequested = false;
|
bool isPhoneRequested = false;
|
||||||
bool isEmailRequested = false;
|
bool isEmailRequested = false;
|
||||||
bool isShippingAddressRequested = false;
|
bool isShippingAddressRequested = false;
|
||||||
|
bool isRecurring = false;
|
||||||
bool isFlexible = false;
|
bool isFlexible = false;
|
||||||
bool isTest = false;
|
bool isTest = false;
|
||||||
|
|
||||||
QString provider;
|
QString provider;
|
||||||
|
QString recurringTermsUrl;
|
||||||
bool phoneSentToProvider = false;
|
bool phoneSentToProvider = false;
|
||||||
bool emailSentToProvider = false;
|
bool emailSentToProvider = false;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
virtual void panelCloseSure() = 0;
|
virtual void panelCloseSure() = 0;
|
||||||
virtual void panelSubmit() = 0;
|
virtual void panelSubmit() = 0;
|
||||||
virtual void panelTrustAndSubmit() = 0;
|
virtual void panelTrustAndSubmit() = 0;
|
||||||
|
virtual void panelAcceptTermsAndSubmit() = 0;
|
||||||
virtual void panelWebviewMessage(
|
virtual void panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) = 0;
|
bool saveInformation) = 0;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 676d8697c6c704c6c5494f03f0bc78d006052768
|
Subproject commit e1ec6a38beae8f90202b8bfa5a247e8f286b810f
|
Loading…
Add table
Reference in a new issue