From bb251627a9d713e27302a2fab8faed7db8c5ec6c Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 19 Jul 2022 14:28:23 +0300 Subject: [PATCH] Support additional payment methods. --- .../SourceFiles/payments/payments_form.cpp | 15 +++++++ Telegram/SourceFiles/payments/payments_form.h | 2 + .../payments/ui/payments_panel.cpp | 45 +++++++++++++++++-- .../SourceFiles/payments/ui/payments_panel.h | 4 ++ .../payments/ui/payments_panel_data.h | 6 +++ 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/payments/payments_form.cpp b/Telegram/SourceFiles/payments/payments_form.cpp index 3b2411fdd..0f1f518c8 100644 --- a/Telegram/SourceFiles/payments/payments_form.cpp +++ b/Telegram/SourceFiles/payments/payments_form.cpp @@ -318,6 +318,9 @@ void Form::processForm(const MTPDpayments_paymentForm &data) { processSavedCredentials(data); }); } + if (const auto additional = data.vadditional_methods()) { + processAdditionalPaymentMethods(additional->v); + } fillPaymentMethodInformation(); _updates.fire(FormReady{}); } @@ -470,6 +473,18 @@ void Form::processSavedCredentials( refreshPaymentMethodDetails(); } +void Form::processAdditionalPaymentMethods( + const QVector &list) { + _paymentMethod.ui.additionalMethods = ranges::views::all( + list + ) | ranges::views::transform([](const MTPPaymentFormMethod &method) { + return Ui::PaymentMethodAdditional{ + .title = qs(method.data().vtitle()), + .url = qs(method.data().vurl()), + }; + }) | ranges::to_vector; +} + void Form::refreshPaymentMethodDetails() { const auto &saved = _paymentMethod.savedCredentials; const auto &entered = _paymentMethod.newCredentials; diff --git a/Telegram/SourceFiles/payments/payments_form.h b/Telegram/SourceFiles/payments/payments_form.h index c1de78030..e34a55c9a 100644 --- a/Telegram/SourceFiles/payments/payments_form.h +++ b/Telegram/SourceFiles/payments/payments_form.h @@ -256,6 +256,8 @@ private: void processSavedInformation(const MTPDpaymentRequestedInfo &data); void processSavedCredentials( const MTPDpaymentSavedCredentialsCard &data); + void processAdditionalPaymentMethods( + const QVector &list); void processShippingOptions(const QVector &data); void fillPaymentMethodInformation(); void fillStripeNativeMethod(QJsonObject object); diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp index 18e5a7cdc..ca774d4cf 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_panel.cpp @@ -443,6 +443,26 @@ void Panel::showEditPaymentMethod(const PaymentMethodDetails &method) { } } +void Panel::showAdditionalMethod( + const QString &provider, + const PaymentMethodAdditional &method) { + auto bottomText = tr::lng_payments_processed_by( + lt_provider, + rpl::single(provider)); + setTitle(rpl::single(method.title)); + if (!showWebview(method.url, true, std::move(bottomText))) { + const auto available = Webview::Availability(); + if (available.error != Webview::Available::Error::None) { + showWebviewError( + tr::lng_payments_webview_no_use(tr::now), + available); + } else { + showCriticalError({ "Error: Could not initialize WebView." }); + } + _widget->setBackAllowed(true); + } +} + void Panel::showWebviewProgress() { if (_webviewProgress && _progress && _progress->shown) { return; @@ -572,20 +592,37 @@ postEvent: function(eventType, eventData) { } void Panel::choosePaymentMethod(const PaymentMethodDetails &method) { - if (!method.ready) { + const auto hasSaved = method.ready; + if (!hasSaved && method.additionalMethods.empty()) { showEditPaymentMethod(method); return; } showBox(Box([=](not_null box) { const auto save = [=](int option) { - if (option) { + const auto basic = hasSaved ? 1 : 0; + if (option > basic) { + const auto index = option - basic - 1; + Assert(index < method.additionalMethods.size()); + showAdditionalMethod( + method.provider, + method.additionalMethods[index]); + } else if (!option) { showEditPaymentMethod(method); } }; + auto options = std::vector{ + tr::lng_payments_new_card(tr::now), + }; + if (hasSaved) { + options.push_back(method.title); + } + for (const auto &additional : method.additionalMethods) { + options.push_back(additional.title); + } SingleChoiceBox(box, { .title = tr::lng_payments_payment_method(), - .options = { method.title, tr::lng_payments_new_card(tr::now) }, - .initialSelection = 0, + .options = std::move(options), + .initialSelection = hasSaved ? 1 : -1, .callback = save, }); })); diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.h b/Telegram/SourceFiles/payments/ui/payments_panel.h index d44351c84..6875a334a 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel.h +++ b/Telegram/SourceFiles/payments/ui/payments_panel.h @@ -36,6 +36,7 @@ class FormSummary; class EditInformation; class EditCard; struct PaymentMethodDetails; +struct PaymentMethodAdditional; struct NativeMethodDetails; class Panel final { @@ -61,6 +62,9 @@ public: const RequestedInformation ¤t, InformationField field); void showEditPaymentMethod(const PaymentMethodDetails &method); + void showAdditionalMethod( + const QString &provider, + const PaymentMethodAdditional &method); void showEditCard( const NativeMethodDetails &native, CardField field); diff --git a/Telegram/SourceFiles/payments/ui/payments_panel_data.h b/Telegram/SourceFiles/payments/ui/payments_panel_data.h index 4fc37321b..3ad6eacc4 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel_data.h +++ b/Telegram/SourceFiles/payments/ui/payments_panel_data.h @@ -160,9 +160,15 @@ struct NativeMethodDetails { bool canSaveInformation = false; }; +struct PaymentMethodAdditional { + QString title; + QString url; +}; + struct PaymentMethodDetails { QString title; NativeMethodDetails native; + std::vector additionalMethods; QString url; QString provider; bool ready = false;