payments_form.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "payments/ui/payments_panel_data.h"
  9. #include "base/weak_ptr.h"
  10. #include "mtproto/sender.h"
  11. class Image;
  12. class QJsonObject;
  13. namespace Core {
  14. struct CloudPasswordResult;
  15. } // namespace Core
  16. namespace Stripe {
  17. class APIClient;
  18. } // namespace Stripe
  19. namespace SmartGlocal {
  20. class APIClient;
  21. } // namespace SmartGlocal
  22. namespace Main {
  23. class Session;
  24. } // namespace Main
  25. namespace Data {
  26. class PhotoMedia;
  27. } // namespace Data
  28. namespace Payments {
  29. enum class Mode;
  30. struct FormDetails {
  31. uint64 formId = 0;
  32. QString url;
  33. QString nativeProvider;
  34. QString termsBotUsername;
  35. QByteArray nativeParamsJson;
  36. UserId botId = 0;
  37. UserId providerId = 0;
  38. bool canSaveCredentials = false;
  39. bool passwordMissing = false;
  40. bool termsAccepted = false;
  41. [[nodiscard]] bool valid() const {
  42. return !url.isEmpty();
  43. }
  44. [[nodiscard]] explicit operator bool() const {
  45. return valid();
  46. }
  47. };
  48. struct ThumbnailLoadProcess {
  49. std::shared_ptr<Data::PhotoMedia> view;
  50. bool blurredSet = false;
  51. rpl::lifetime lifetime;
  52. };
  53. struct SavedCredentials {
  54. QString id;
  55. QString title;
  56. [[nodiscard]] bool valid() const {
  57. return !id.isEmpty();
  58. }
  59. [[nodiscard]] explicit operator bool() const {
  60. return valid();
  61. }
  62. };
  63. struct NewCredentials {
  64. QString title;
  65. QByteArray data;
  66. bool saveOnServer = false;
  67. [[nodiscard]] bool empty() const {
  68. return data.isEmpty();
  69. }
  70. [[nodiscard]] explicit operator bool() const {
  71. return !empty();
  72. }
  73. };
  74. struct StripePaymentMethod {
  75. QString publishableKey;
  76. };
  77. struct SmartGlocalPaymentMethod {
  78. QString publicToken;
  79. QString tokenizeUrl;
  80. };
  81. struct NativePaymentMethod {
  82. std::variant<
  83. v::null_t,
  84. StripePaymentMethod,
  85. SmartGlocalPaymentMethod> data;
  86. [[nodiscard]] bool valid() const {
  87. return !v::is_null(data);
  88. }
  89. [[nodiscard]] explicit operator bool() const {
  90. return valid();
  91. }
  92. };
  93. struct PaymentMethod {
  94. NativePaymentMethod native;
  95. std::vector<SavedCredentials> savedCredentials;
  96. int savedCredentialsIndex = 0;
  97. NewCredentials newCredentials;
  98. Ui::PaymentMethodDetails ui;
  99. };
  100. struct InvoiceMessage {
  101. not_null<PeerData*> peer;
  102. MsgId itemId = 0;
  103. };
  104. struct InvoiceSlug {
  105. not_null<Main::Session*> session;
  106. QString slug;
  107. };
  108. struct InvoicePremiumGiftCodeGiveaway {
  109. not_null<ChannelData*> boostPeer;
  110. std::vector<not_null<ChannelData*>> additionalChannels;
  111. std::vector<QString> countries;
  112. QString additionalPrize;
  113. TimeId untilDate = 0;
  114. bool onlyNewSubscribers = false;
  115. bool showWinners = false;
  116. };
  117. struct InvoicePremiumGiftCodeUsers {
  118. std::vector<not_null<UserData*>> users;
  119. ChannelData *boostPeer = nullptr;
  120. TextWithEntities message;
  121. };
  122. struct InvoicePremiumGiftCode {
  123. std::variant<
  124. InvoicePremiumGiftCodeUsers,
  125. InvoicePremiumGiftCodeGiveaway> purpose;
  126. QString currency;
  127. QString storeProduct;
  128. std::optional<uint64> giveawayCredits;
  129. uint64 randomId = 0;
  130. uint64 amount = 0;
  131. int storeQuantity = 0;
  132. int users = 0;
  133. int months = 0;
  134. };
  135. struct InvoiceCredits {
  136. not_null<Main::Session*> session;
  137. uint64 randomId = 0;
  138. uint64 credits = 0;
  139. QString product;
  140. QString currency;
  141. uint64 amount = 0;
  142. bool extended = false;
  143. PeerId giftPeerId = PeerId(0);
  144. int subscriptionPeriod = 0;
  145. };
  146. struct InvoiceStarGift {
  147. uint64 giftId = 0;
  148. uint64 randomId = 0;
  149. TextWithEntities message;
  150. not_null<PeerData*> recipient;
  151. int limitedCount = 0;
  152. bool anonymous = false;
  153. bool upgraded = false;
  154. };
  155. struct InvoiceId {
  156. std::variant<
  157. InvoiceMessage,
  158. InvoiceSlug,
  159. InvoicePremiumGiftCode,
  160. InvoiceCredits,
  161. InvoiceStarGift> value;
  162. };
  163. struct CreditsFormData {
  164. InvoiceId id;
  165. uint64 formId = 0;
  166. uint64 botId = 0;
  167. QString title;
  168. QString description;
  169. PhotoData *photo = nullptr;
  170. InvoiceCredits invoice;
  171. MTPInputInvoice inputInvoice;
  172. int starGiftLimitedCount = 0;
  173. bool starGiftForm = false;
  174. };
  175. struct CreditsReceiptData {
  176. QString id;
  177. QString title;
  178. QString description;
  179. PhotoData *photo = nullptr;
  180. PeerId peerId = PeerId(0);
  181. StarsAmount credits;
  182. TimeId date = 0;
  183. };
  184. struct ToggleProgress {
  185. bool shown = true;
  186. };
  187. struct FormReady {};
  188. struct ThumbnailUpdated {
  189. QImage thumbnail;
  190. };
  191. struct ValidateFinished {};
  192. struct PaymentMethodUpdate {
  193. bool requestNewPassword = false;
  194. };
  195. struct VerificationNeeded {
  196. QString url;
  197. };
  198. struct TmpPasswordRequired {};
  199. struct BotTrustRequired {
  200. not_null<UserData*> bot;
  201. not_null<UserData*> provider;
  202. };
  203. struct PaymentFinished {
  204. MTPUpdates updates;
  205. };
  206. struct CreditsPaymentStarted {
  207. CreditsFormData data;
  208. };
  209. struct CreditsReceiptReady {
  210. CreditsReceiptData data;
  211. };
  212. struct Error {
  213. enum class Type {
  214. None,
  215. Form,
  216. Validate,
  217. Stripe,
  218. SmartGlocal,
  219. TmpPassword,
  220. Send,
  221. };
  222. Type type = Type::None;
  223. QString id;
  224. [[nodiscard]] bool empty() const {
  225. return (type == Type::None);
  226. }
  227. [[nodiscard]] explicit operator bool() const {
  228. return !empty();
  229. }
  230. };
  231. struct FormUpdate : std::variant<
  232. ToggleProgress,
  233. FormReady,
  234. ThumbnailUpdated,
  235. ValidateFinished,
  236. PaymentMethodUpdate,
  237. VerificationNeeded,
  238. TmpPasswordRequired,
  239. BotTrustRequired,
  240. PaymentFinished,
  241. CreditsPaymentStarted,
  242. CreditsReceiptReady,
  243. Error> {
  244. using variant::variant;
  245. };
  246. [[nodiscard]] not_null<Main::Session*> SessionFromId(const InvoiceId &id);
  247. [[nodiscard]] MTPinputStorePaymentPurpose InvoicePremiumGiftCodeGiveawayToTL(
  248. const InvoicePremiumGiftCode &invoice);
  249. [[nodiscard]] MTPinputStorePaymentPurpose InvoiceCreditsGiveawayToTL(
  250. const InvoicePremiumGiftCode &invoice);
  251. [[nodiscard]] bool IsPremiumForStarsInvoice(const InvoiceId &id);
  252. class Form final : public base::has_weak_ptr {
  253. public:
  254. Form(InvoiceId id, bool receipt);
  255. ~Form();
  256. [[nodiscard]] const Ui::Invoice &invoice() const {
  257. return _invoice;
  258. }
  259. [[nodiscard]] const FormDetails &details() const {
  260. return _details;
  261. }
  262. [[nodiscard]] const Ui::RequestedInformation &information() const {
  263. return _information;
  264. }
  265. [[nodiscard]] const PaymentMethod &paymentMethod() const {
  266. return _paymentMethod;
  267. }
  268. [[nodiscard]] const Ui::ShippingOptions &shippingOptions() const {
  269. return _shippingOptions;
  270. }
  271. [[nodiscard]] bool hasChanges() const;
  272. [[nodiscard]] rpl::producer<FormUpdate> updates() const {
  273. return _updates.events();
  274. }
  275. [[nodiscard]] std::optional<QDate> overrideExpireDateThreshold() const;
  276. void validateInformation(const Ui::RequestedInformation &information);
  277. void validateCard(
  278. const Ui::UncheckedCardDetails &details,
  279. bool saveInformation);
  280. void setPaymentCredentials(const NewCredentials &credentials);
  281. void chooseSavedMethod(const QString &id);
  282. void setHasPassword(bool has);
  283. void setShippingOption(const QString &id);
  284. void setTips(int64 value);
  285. void acceptTerms();
  286. void trustBot();
  287. void submit();
  288. void submit(const Core::CloudPasswordResult &result);
  289. private:
  290. void fillInvoiceFromMessage();
  291. void showProgress();
  292. void hideProgress();
  293. [[nodiscard]] Data::FileOrigin thumbnailFileOrigin() const;
  294. void loadThumbnail(not_null<PhotoData*> photo);
  295. [[nodiscard]] QImage prepareGoodThumbnail(
  296. const std::shared_ptr<Data::PhotoMedia> &view) const;
  297. [[nodiscard]] QImage prepareBlurredThumbnail(
  298. const std::shared_ptr<Data::PhotoMedia> &view) const;
  299. [[nodiscard]] QImage prepareThumbnail(
  300. not_null<const Image*> image,
  301. bool blurred = false) const;
  302. [[nodiscard]] QImage prepareEmptyThumbnail() const;
  303. void requestForm();
  304. void requestReceipt();
  305. void processForm(const MTPDpayments_paymentForm &data);
  306. void processReceipt(const MTPDpayments_paymentReceipt &data);
  307. void processReceipt(const MTPDpayments_paymentReceiptStars &data);
  308. void processInvoice(const MTPDinvoice &data);
  309. void processDetails(const MTPDpayments_paymentForm &data);
  310. void processDetails(const MTPDpayments_paymentReceipt &data);
  311. void processDetails(const MTPDpayments_paymentReceiptStars &data);
  312. void processSavedInformation(const MTPDpaymentRequestedInfo &data);
  313. void processAdditionalPaymentMethods(
  314. const QVector<MTPPaymentFormMethod> &list);
  315. void processShippingOptions(const QVector<MTPShippingOption> &data);
  316. void fillPaymentMethodInformation();
  317. void fillStripeNativeMethod(QJsonObject object);
  318. void fillSmartGlocalNativeMethod(QJsonObject object);
  319. void refreshPaymentMethodDetails();
  320. void refreshSavedPaymentMethodDetails();
  321. [[nodiscard]] QString defaultPhone() const;
  322. [[nodiscard]] QString defaultCountry() const;
  323. [[nodiscard]] MTPInputInvoice inputInvoice() const;
  324. void validateCard(
  325. const StripePaymentMethod &method,
  326. const Ui::UncheckedCardDetails &details,
  327. bool saveInformation);
  328. void validateCard(
  329. const SmartGlocalPaymentMethod &method,
  330. const Ui::UncheckedCardDetails &details,
  331. bool saveInformation);
  332. bool validateInformationLocal(
  333. const Ui::RequestedInformation &information) const;
  334. [[nodiscard]] Error informationErrorLocal(
  335. const Ui::RequestedInformation &information) const;
  336. bool validateCardLocal(
  337. const Ui::UncheckedCardDetails &details,
  338. const std::optional<QDate> &overrideExpireDateThreshold) const;
  339. [[nodiscard]] Error cardErrorLocal(
  340. const Ui::UncheckedCardDetails &details,
  341. const std::optional<QDate> &overrideExpireDateThreshold) const;
  342. const InvoiceId _id;
  343. const not_null<Main::Session*> _session;
  344. MTP::Sender _api;
  345. bool _receiptMode = false;
  346. Ui::Invoice _invoice;
  347. std::unique_ptr<ThumbnailLoadProcess> _thumbnailLoadProcess;
  348. FormDetails _details;
  349. Ui::RequestedInformation _savedInformation;
  350. Ui::RequestedInformation _information;
  351. PaymentMethod _paymentMethod;
  352. Ui::RequestedInformation _validatedInformation;
  353. mtpRequestId _validateRequestId = 0;
  354. mtpRequestId _passwordRequestId = 0;
  355. std::unique_ptr<Stripe::APIClient> _stripe;
  356. std::unique_ptr<SmartGlocal::APIClient> _smartglocal;
  357. Ui::ShippingOptions _shippingOptions;
  358. QString _requestedInformationId;
  359. rpl::event_stream<FormUpdate> _updates;
  360. };
  361. } // namespace Payments