KMPurchaseEmbeddedWindowController.swift 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818
  1. //
  2. // KMPurchaseEmbeddedWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2024/8/29.
  6. //
  7. import Cocoa
  8. #if VERSION_DMG
  9. // paypal alipay wxpay paddle
  10. @objc enum KMPaymentType: UInt32 {
  11. case paypal = 0
  12. case paddle
  13. case wxpay
  14. case alipay
  15. }
  16. @objc enum KMDMGProductType: UInt32 {
  17. case advanced_annual_subscription_trail = 0 // 全平台高级版年订阅 99.9 美金,带免费试用
  18. case advanced_annual_subscription // 全平台高级版年订阅 99.9 美金
  19. case advanced_annual_subscription_blackFive // 全平台高级版年订阅 99.9 美金,黑五订单,优惠价格不为空
  20. case standard_annual_subscription // 全平台标准版年订阅 79.9 美金
  21. case advanced_permanent // Mac & Win 双平台高级永久 119.99 美金
  22. case advanced_permanent_blackFive // Mac & Win 双平台高级永久 119.99 美金,黑五订单,优惠价格不为空
  23. case ai_subscription_year_trail // AI 年订阅 125.99 美金,带免费试用
  24. case ai_subscription_month // AI 月订阅 14.99 美金
  25. }
  26. let kKMNewUserGiftDiscountCodeId = "B89EF-166C-4AD"
  27. let kKMAdvancedYearSubscribeDiscountCodeId = "B89EF-166C-4AD"
  28. class KMPurchaseEmbeddedWindowController: NSWindowController {
  29. @IBOutlet weak var mainBox: NSBox!
  30. @IBOutlet weak var yourOrderLabel: NSTextField!
  31. @IBOutlet weak var pdfReaderProLabel: NSTextField!
  32. @IBOutlet weak var prmiumLabel: NSTextField!
  33. @IBOutlet weak var oneLicenseLabel: NSTextField!
  34. @IBOutlet weak var removeButton1: NSButton! // 减少按钮1
  35. @IBOutlet weak var addButton1: NSButton! // 增加按钮1
  36. @IBOutlet weak var amountTextField1: NSTextField! // 数目1
  37. @IBOutlet weak var originalPriceLabel1: NSTextField! // 原价
  38. @IBOutlet weak var discountPriceLabel1: NSTextField! // 折扣
  39. @IBOutlet weak var usualAddonView: NSView!
  40. @IBOutlet weak var firmLabel: NSTextField!
  41. @IBOutlet weak var addbox: NSBox!
  42. @IBOutlet weak var textbox: NSBox!
  43. @IBOutlet weak var removebox: NSBox!
  44. @IBOutlet weak var linebox: NSBox!
  45. @IBOutlet weak var prodocumentView: NSView!
  46. @IBOutlet weak var couponView: NSView!
  47. @IBOutlet private weak var couponButton: NSButton!
  48. @IBOutlet weak var couponBox: NSBox!
  49. @IBOutlet weak var coupomTextField: NSTextField!
  50. @IBOutlet weak var couponClearButton: NSButton!
  51. @IBOutlet weak var applyBox: NSBox!
  52. @IBOutlet weak var applyButton: NSButton!
  53. @IBOutlet weak var coupomErrorLabel: NSTextField!
  54. @IBOutlet weak var coupomErrorTopLayout: NSLayoutConstraint!
  55. @IBOutlet weak var lastPriceLabel: NSTextField!
  56. @IBOutlet weak var lastPriceLabel1: NSTextField!
  57. @IBOutlet weak var discountView: NSView!
  58. @IBOutlet weak var discountLabel: NSTextField!
  59. @IBOutlet weak var discountLabel1: NSTextField!
  60. @IBOutlet weak var paySumLabel: NSTextField!
  61. @IBOutlet weak var paySumLabel1: NSTextField!
  62. @IBOutlet weak var discountLayoutConstraint: NSLayoutConstraint!
  63. @IBOutlet weak var privacyLabel: NSTextField!
  64. @IBOutlet weak var billInformationLabel: NSTextField!
  65. @IBOutlet weak var emailLabel: NSTextField!
  66. @IBOutlet weak var emailTextField: NSTextField!
  67. @IBOutlet weak var emailBox: NSBox!
  68. @IBOutlet weak var errorView: NSView!
  69. @IBOutlet weak var errorLabel: NSTextField!
  70. @IBOutlet weak var errorLabelTopLayout: NSLayoutConstraint!
  71. @IBOutlet weak var paymentMethodLabel: NSTextField!
  72. @IBOutlet weak var paypalButton: NSButton!
  73. @IBOutlet weak var cardButton: NSButton!
  74. @IBOutlet weak var wechatPayButton: NSButton!
  75. @IBOutlet weak var alipayButton: NSButton!
  76. @IBOutlet weak var wechatPayButton2: NSButton!
  77. @IBOutlet weak var payBox: NSBox!
  78. @IBOutlet weak var payBoxHeight: NSLayoutConstraint!
  79. @IBOutlet weak var payExplainLabel: NSTextField!
  80. @IBOutlet var paypalView: NSView!
  81. @IBOutlet weak var paypalBox: NSBox!
  82. @IBOutlet weak var paypalBuyNowLabel: NSTextField!
  83. @IBOutlet var cardView: NSView!
  84. @IBOutlet var paddleView: NSView!
  85. @IBOutlet weak var paddleButton: NSButton!
  86. @IBOutlet weak var paddlePopUpButton: KMPopUpButton!
  87. @IBOutlet weak var paddleBox: NSBox!
  88. @IBOutlet weak var paddleTextField: NSTextField!
  89. @IBOutlet var weChatPayView: NSView!
  90. @IBOutlet weak var weChatBox: NSBox!
  91. @IBOutlet weak var weChatButton: NSButton!
  92. @IBOutlet var payResult: NSView!
  93. @IBOutlet weak var scanLabel: NSTextField!
  94. @IBOutlet weak var qrCodeImageView: NSImageView!
  95. @IBOutlet weak var payTypeImageView: NSImageView!
  96. @IBOutlet weak var successfullyView: NSView!
  97. @IBOutlet weak var purchasedLabel: NSTextField!
  98. @IBOutlet weak var successfullyLabel: NSTextField!
  99. @IBOutlet weak var imageBottomLayout: NSLayoutConstraint!
  100. @IBOutlet weak var image2BottomLayout: NSLayoutConstraint!
  101. @IBOutlet weak var cardButtonWidthConst: NSLayoutConstraint!
  102. private var _product_code : String = ""
  103. private var _product_Info: KMListingProductsModel = KMListingProductsModel(id: "23", productName: "PDF Reader Pro Advanced - Annual Plan", price: "99.99", maxDeviceNum: 4, displayPrice: "0.0", levels: "3", platforms: "Windows,Android,Mac,iOS", productLineId: 1, paymentModel: 1, cycle: 4, cnyPrice: "0.0", displayCnyPrice: "0.0", upgradePrice: "0.0", code: "advanced-annual-subscription-trail")
  104. private var pdfCount: Int = 1
  105. private var _paymentMethod: KMPaymentType = .paypal
  106. private var _productType: ProductType = .ipaConvert
  107. private var couponCode: String = "" //优惠卷
  108. private var discountAmount: String = "" // 优惠金额
  109. private var discountScale: String = "" // 优惠比例
  110. private var orderID: String = "" // 订单ID
  111. private var timer: Timer?
  112. private var pollCount = 0
  113. private let maxPolls = 36
  114. private let interval: TimeInterval = 5.0
  115. private var _activityAlertViewController: KMActivityALertViewController?
  116. private let countryKeys = [
  117. "Afghanistan", "Aland Islands", "Albania", "Algeria", "American Samoa",
  118. "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina",
  119. "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas",
  120. "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize",
  121. "Benin", "Bermuda", "Bhutan", "Bolivia", "Bonaire, Sint Eustatius and Saba",
  122. "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
  123. "Brit. Indian Ocean", "British Virgin Islands", "Brunei Darussalam", "Bulgaria",
  124. "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde",
  125. "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
  126. "Christmas Island", "Cocos Islands", "Colombia", "Comoros", "Congo",
  127. "Cook Islands", "Costa Rica", "Cote D'Ivoire", "Croatia", "Curaçao", "Cyprus",
  128. "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
  129. "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia",
  130. "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France",
  131. "French Guiana", "French Polynesia", "French Southern Terr.", "Gabon", "Gambia",
  132. "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada",
  133. "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea-Bissau",
  134. "Guyana", "Haiti", "Heard/ Mcdonald Islands", "Holy See/ Vatican City", "Honduras",
  135. "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iraq", "Ireland",
  136. "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan",
  137. "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Lao People's DR",
  138. "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein",
  139. "Lithuania", "Luxembourg", "Macao", "Macedonia", "Madagascar", "Malawi",
  140. "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique",
  141. "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
  142. "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique",
  143. "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles",
  144. "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue",
  145. "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan",
  146. "Palau", "Palestinian Territory", "Panama", "Papua New Guinea", "Paraguay",
  147. "Peru", "Philippines", "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar",
  148. "Republic of Serbia", "Reunion", "Romania", "Russian Federation", "Rwanda",
  149. "S. Georgia/ Sandwich Islands", "Saint Helena", "Saint Kitts and Nevis",
  150. "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent/ Grenadines",
  151. "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal",
  152. "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
  153. "Somalia", "South Africa", "South Korea", "Spain", "Sri Lanka", "Sudan",
  154. "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Taiwan",
  155. "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tokelau", "Tonga",
  156. "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands",
  157. "Tuvalu", "U.S. Virgin Islands", "Uganda", "Ukraine", "United Arab Emirates",
  158. "United Kingdom", "United States", "United States (M.O.I.)", "Uruguay", "Uzbekistan",
  159. "Vanuatu", "Venezuela", "Viet Nam", "Wallis and Futuna", "Western Sahara", "Yemen",
  160. "Zambia", "Zimbabwe"
  161. ]
  162. private let countryAbbreviationValues = [
  163. "AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB",
  164. "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "VG", "BN", "BG", "BF", "BI", "KH",
  165. "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CK", "CR", "CI", "HR", "CW", "CY",
  166. "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF",
  167. "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM",
  168. "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI",
  169. "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT",
  170. "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL",
  171. "AN", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH",
  172. "PN", "PL", "PT", "PR", "QA", "RS", "RE", "RO", "RU", "RW", "GS", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM",
  173. "ST", "SA", "SN", "SC", "SL", "SG", "SK", "SI", "SB", "SO", "ZA", "KR", "ES", "LK", "SD", "SR", "SJ", "SZ", "SE",
  174. "CH", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "VI", "UG", "UA", "AE",
  175. "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "WF", "EH", "YE", "ZM", "ZW"
  176. ]
  177. private var handler: ((Int) -> Void)!
  178. static var currentWindowController: KMPurchaseEmbeddedWindowController!
  179. private var embeddedPaymentPopWC: KMEmbeddedPaymentPopWC?
  180. private var successfulPaymentsNumber = 0
  181. private var license1 = ""
  182. private var licenseAI1 = ""
  183. private var isApplyCoupon: Bool = false
  184. private var isWindowDidLoad: Bool = false
  185. private var isBatchProductPriceGetFinsed: Bool = false
  186. private var discountType_: KMDiscountType = .none
  187. public var isAIPurchase = false
  188. var discountCodeId: String? {
  189. didSet { }
  190. }
  191. @objc static func currentWC(_ productInfo: KMListingProductsModel) -> KMPurchaseEmbeddedWindowController {
  192. if currentWindowController != nil {
  193. currentWindowController.product_Info = productInfo
  194. currentWindowController.discountCodeId = nil
  195. return currentWindowController
  196. } else {
  197. let configWC: KMPurchaseEmbeddedWindowController = KMPurchaseEmbeddedWindowController.init(windowNibName: "KMPurchaseEmbeddedWindowController")
  198. currentWindowController = configWC;
  199. currentWindowController.product_Info = productInfo
  200. currentWindowController.discountCodeId = nil
  201. return currentWindowController
  202. }
  203. }
  204. @objc static func currentCode(_ productCode: String) -> KMPurchaseEmbeddedWindowController {
  205. if currentWindowController != nil {
  206. currentWindowController.product_code = productCode
  207. return currentWindowController
  208. } else {
  209. let configWC: KMPurchaseEmbeddedWindowController = KMPurchaseEmbeddedWindowController.init(windowNibName: "KMPurchaseEmbeddedWindowController")
  210. currentWindowController = configWC;
  211. _ = configWC.window
  212. currentWindowController.product_code = productCode
  213. return currentWindowController
  214. }
  215. }
  216. override func windowDidLoad() {
  217. super.windowDidLoad()
  218. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
  219. window?.title = ""
  220. window?.makeFirstResponder(nil)
  221. xibInitialization()
  222. paymentMethod = .paypal
  223. priceRefresh(productsModel: product_Info)
  224. self.window?.delegate = self;
  225. isWindowDidLoad = true
  226. _configFirmLabel()
  227. firmLabel.isHidden = true
  228. couponView.isHidden = false
  229. couponButton.isHidden = false
  230. couponBox.isHidden = true
  231. applyBox.isHidden = true
  232. DistributedNotificationCenter.default.addObserver(self, selector: #selector(themeChanged(_:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
  233. }
  234. @objc func themeChanged(_ notification: Notification) {
  235. DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
  236. self._updateViewColor()
  237. }
  238. }
  239. override func close() {
  240. super.close()
  241. self.clearEventData()
  242. }
  243. override func showWindow(_ sender: Any?) {
  244. super.showWindow(sender)
  245. self.window?.center()
  246. discountType_ = .none
  247. isAIPurchase = false
  248. if let data = discountCodeId, _canUseDiscountCode() {
  249. self._applyDiscount(data) { [weak self] success, result in
  250. if(success == true) {
  251. guard let productResult = result else {
  252. return
  253. }
  254. guard let couponModel = productResult.checkCoupon else {
  255. return
  256. }
  257. let priceString = couponModel.priceString
  258. self?.product_Info.priceString = priceString
  259. let cnyPriceString = couponModel.cnyPriceString
  260. self?.product_Info.cnyPriceString = cnyPriceString //批量时将总价赋给priceString,只显示priceString价格了,其他的置空
  261. self?.product_Info.upgradePriceString = couponModel.upgradePriceString
  262. self?.product_Info.cnyUpgradePriceString = couponModel.upgradecnyPriceString
  263. self?.product_Info.displayPriceString = couponModel.displayPriceString
  264. self?.product_Info.displayCnyPriceString = couponModel.displayCnyPriceString
  265. self?.product_Info.individualPriceString = couponModel.priceString
  266. self?.product_Info.individualCnyPriceString = couponModel.cnyPriceString
  267. self?.product_Info.verifyofferCode = data
  268. if self?._paymentMethod == .alipay || self?._paymentMethod == .wxpay {
  269. self?.updatePrice()
  270. }
  271. self?.couponButton.isHidden = true
  272. self?.priceRefresh(productsModel: self?._product_Info ?? KMListingProductsModel())
  273. }else {
  274. KMPrint("The coupon code is invalid. Please try again.")
  275. }
  276. }
  277. }
  278. }
  279. public func openWindow(discountType: KMDiscountType) {
  280. self.showWindow(nil)
  281. discountType_ = discountType
  282. }
  283. // MARK: DMG Action
  284. func isOneTimePurchase(_ productinfo: KMListingProductsModel) -> Bool {
  285. //买断版本才能一次购买多个,并且购买多个时,不会自动绑定,需要在后台给自己绑定才能有会员权益
  286. if productinfo.paymentModel == 2 {
  287. return true
  288. }
  289. return false
  290. }
  291. func updateProduct_Info() -> Void { //重新获取产品接口
  292. if KMMemberInfo.shared.isLogin {
  293. let model = KMProductModel.shared
  294. if(pdfCount > 1) {
  295. model.getDMGBatchProductPriceInfosForMember(productId: _product_Info.id, num: pdfCount) { [weak self] success, result in
  296. guard let pricesArrays : KMMemberProductResult = result else {
  297. return
  298. }
  299. guard let batchProductPrice : KMBatchProductPriceModel = pricesArrays.batchProductPrice else {
  300. return
  301. }
  302. //原价更新
  303. let priceString = batchProductPrice.totalPrice
  304. self?.product_Info.priceString = priceString
  305. let cnyPriceString = batchProductPrice.cnyTotalPrice
  306. self?.product_Info.cnyPriceString = cnyPriceString //批量时将总价赋给priceString,只显示priceString价格了,其他的置空
  307. self?.product_Info.upgradePriceString = nil
  308. self?.product_Info.displayPriceString = nil
  309. self?.product_Info.displayCnyPriceString = nil
  310. self?.product_Info.individualPriceString = batchProductPrice.price
  311. self?.product_Info.individualCnyPriceString = batchProductPrice.cnyPrice
  312. self?.product_Info.verifyofferCode = ""
  313. if self?._paymentMethod == .alipay || self?._paymentMethod == .wxpay {
  314. self?.updatePrice()
  315. }
  316. self?.priceRefresh(productsModel: self?.product_Info ?? KMListingProductsModel())
  317. }
  318. } else {
  319. if _canUseDiscountCode() {
  320. self._applyDiscount(discountCodeId ?? "") { [weak self] success, result in
  321. if(success == true) {
  322. guard let productResult = result else {
  323. return
  324. }
  325. guard let couponModel = productResult.checkCoupon else {
  326. return
  327. }
  328. let priceString = couponModel.priceString
  329. self?.product_Info.priceString = priceString
  330. let cnyPriceString = couponModel.cnyPriceString
  331. self?.product_Info.cnyPriceString = cnyPriceString //批量时将总价赋给priceString,只显示priceString价格了,其他的置空
  332. self?.product_Info.upgradePriceString = couponModel.upgradePriceString
  333. self?.product_Info.cnyUpgradePriceString = couponModel.upgradecnyPriceString
  334. self?.product_Info.displayPriceString = couponModel.displayPriceString
  335. self?.product_Info.displayCnyPriceString = couponModel.displayCnyPriceString
  336. self?.product_Info.individualPriceString = couponModel.priceString
  337. self?.product_Info.individualCnyPriceString = couponModel.cnyPriceString
  338. self?.product_Info.verifyofferCode = self?.discountCodeId ?? ""
  339. if self?._paymentMethod == .alipay || self?._paymentMethod == .wxpay {
  340. self?.updatePrice()
  341. }
  342. self?.couponButton.isHidden = true
  343. self?.priceRefresh(productsModel: self?._product_Info ?? KMListingProductsModel())
  344. }else {
  345. KMPrint("The coupon code is invalid. Please try again.")
  346. }
  347. }
  348. } else {
  349. model.getDMGProductPriceInfosForMember(productId: product_Info.id, isEducation: 0) { [weak self] success, result in
  350. if success {
  351. guard let productResults : KMMemberProductResult = result else {
  352. return
  353. }
  354. guard let products : [KMListingProductsModel] = productResults.listingProducts else {
  355. return
  356. }
  357. guard let product : KMListingProductsModel = products.first else {
  358. return
  359. }
  360. if self?._canUseDiscountCode() == true {
  361. return
  362. }
  363. self?.product_Info = product;
  364. for tProduct in products {
  365. if tProduct.id == self?.product_Info.id {
  366. self?.product_Info = product;
  367. }
  368. }
  369. }
  370. }
  371. }
  372. }
  373. }
  374. }
  375. // MARK: UI
  376. private func xibInitialization() -> Void {
  377. prodocumentView.wantsLayer = true
  378. prodocumentView.layer?.cornerRadius = 5.0
  379. prodocumentView.layer?.borderWidth = 1.0
  380. _showOrHideCardButton(show: true)
  381. if pdfCount <= 1 {
  382. addbox.fillColor = NSColor(hex: "#F1F1F2")
  383. } else {
  384. addbox.fillColor = NSColor(named: "0E1114 1") ?? .white
  385. }
  386. removebox.fillColor = NSColor(named: "0E1114 1") ?? .white
  387. _updateViewColor()
  388. textbox.fillColor = NSColor(named: "0E1114 2") ?? .white
  389. yourOrderLabel.stringValue = KMLocalizedString("Your Order", comment: "")
  390. yourOrderLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  391. yourOrderLabel.font = NSFont.SFProTextBoldFont(20.0)
  392. pdfReaderProLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  393. pdfReaderProLabel.font = NSFont.SFProTextRegularFont(14.0)
  394. prmiumLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  395. prmiumLabel.font = NSFont.SFProTextRegularFont(12.0)
  396. oneLicenseLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  397. oneLicenseLabel.font = NSFont.SFProTextRegularFont(12.0)
  398. originalPriceLabel1.textColor = NSColor(named: "KMPurchaseTitleColor")
  399. originalPriceLabel1.font = NSFont.SFProTextRegularFont(16.0)
  400. discountPriceLabel1.textColor = NSColor(named: "KMPurchaseDiscountColor")
  401. discountPriceLabel1.font = NSFont.SFProTextRegularFont(9.0)
  402. refreshLicenseCodeView(isReveal: false)
  403. oneLicenseLabel.stringValue = KMLocalizedString("and more offline. It's one time purchase.", comment: "")
  404. oneLicenseLabel.isHidden = true
  405. refreshLicenseCodeView(isReveal: true)
  406. refreshLicenseCodeErrorView(isReveal: false)
  407. if pdfCount > 1 {
  408. removeButton1.isEnabled = true
  409. } else {
  410. removeButton1.isEnabled = false
  411. }
  412. amountTextField1.delegate = self
  413. couponButton.title = KMLocalizedString("I have a coupon?", comment: "")
  414. couponButton.setTitleColor(color: NSColor(named: "KMPurchaseCouponColor")!, font: NSFont.SFProTextRegularFont(14))
  415. coupomTextField.placeholderString = KMLocalizedString("Please enter a coupon code.", comment: "")
  416. applyButton.title = KMLocalizedString("Apply", comment: "")
  417. applyButton.setTitleColor(color: NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black, font: NSFont.SFProTextRegularFont(13))
  418. couponBox.borderColor = NSColor(named: "KMPurchaseCouponBoxColor") ?? NSColor.gray
  419. couponBox.fillColor = NSColor(named: "KMPurchaseCouponBoxFillColor") ?? NSColor.gray
  420. applyBox.borderColor = NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black
  421. coupomErrorLabel.textColor = NSColor(named: "KMPurchaseErrorColor")
  422. coupomErrorLabel.font = NSFont.SFProTextRegularFont(11.0)
  423. refreshCouponError(isReveal: false)
  424. lastPriceLabel.stringValue = KMLocalizedString("List Price", comment: "")
  425. lastPriceLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  426. lastPriceLabel.font = NSFont.SFProTextRegularFont(16.0)
  427. discountLabel.stringValue = KMLocalizedString("Discount", comment: "")
  428. discountLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  429. discountLabel.font = NSFont.SFProTextRegularFont(16.0)
  430. paySumLabel.stringValue = KMLocalizedString("Pay sum", comment: "")
  431. paySumLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  432. paySumLabel.font = NSFont.SFProTextBoldFont(24.0)
  433. paySumLabel1.textColor = NSColor(named: "KMPurchaseCouponColor")
  434. paySumLabel1.font = NSFont.SFProTextBoldFont(24.0)
  435. privacyLabel.isEditable = false
  436. privacyLabel.isSelectable = true
  437. privacyLabel.allowsEditingTextAttributes = true
  438. privacyLabel.textColor = NSColor.black
  439. privacyLabel.font = NSFont.SFProTextRegularFont(16.0)
  440. let tipsString = KMLocalizedString("Are you a student or a professor? %@ / Want a volume purchase? Please %@.", comment: "")
  441. let specialOffer = KMLocalizedString("Get Special Offer", comment: "")
  442. let contactsUs = KMLocalizedString("Contact Us", comment: "")
  443. let fullString = String(format: tipsString, specialOffer, contactsUs)
  444. let attributedString = NSMutableAttributedString(string: fullString)
  445. // 定义链接的范围
  446. let specialOfferRange = (fullString as NSString).range(of: specialOffer)
  447. let contactsUsRange = (fullString as NSString).range(of: contactsUs)
  448. let linkColor = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  449. let font = NSFont.SFProTextRegularFont(16.0) // 与普通文本相同的字体
  450. attributedString.addAttributes([
  451. .foregroundColor: NSColor(named: "KMPurchase_99A6B2") as Any,
  452. .font: font
  453. ], range: (fullString as NSString).range(of: fullString))
  454. attributedString.addAttributes([
  455. .foregroundColor: linkColor,
  456. .link: KMLocalizedString("https://www.pdfreaderpro.com/store?mode=edu", comment: ""),
  457. .font: font
  458. ], range: specialOfferRange)
  459. attributedString.addAttributes([
  460. .foregroundColor: linkColor,
  461. .link: KMLocalizedString("https://www.pdfreaderpro.com/vpp-purchase-program", comment: ""),
  462. .font: font
  463. ], range: contactsUsRange)
  464. privacyLabel.attributedStringValue = attributedString
  465. billInformationLabel.stringValue = KMLocalizedString("Billing Information", comment: "")
  466. billInformationLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  467. billInformationLabel.font = NSFont.SFProTextRegularFont(14.0)
  468. emailLabel.stringValue = KMLocalizedString("You can purchase with the account linked to this email. If the email is not registered, an account will be automatically created for you upon successful purchase.", tableName: "MemberCenterLocalizable", comment: "")
  469. emailLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  470. emailLabel.font = NSFont.SFProTextRegularFont(14.0)
  471. emailTextField.placeholderString = KMLocalizedString("Email to receive license code", comment: "")
  472. emailBox.borderColor = NSColor(named: "KMPurchase_DADBDE")!
  473. // emailBox.fillColor = NSColor(named: "KMPurchase_FFFFFF")!
  474. errorLabel.stringValue = KMLocalizedString("Please enter your email for license receiving.", comment: "")
  475. emailTextField.stringValue = KMMemberInfo.shared.userEmail
  476. emailTextField.delegate = self
  477. errorLabel.textColor = NSColor(named: "KMPurchaseErrorColor")
  478. errorLabel.font = NSFont.SFProTextRegularFont(11.0)
  479. paymentMethodLabel.stringValue = KMLocalizedString("Payment Method", comment: "")
  480. paymentMethodLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  481. paymentMethodLabel.font = NSFont.SFProTextRegularFont(14.0)
  482. wechatPayButton2.isHidden = true
  483. payExplainLabel.isEditable = false
  484. payExplainLabel.isSelectable = true
  485. payExplainLabel.allowsEditingTextAttributes = true
  486. payExplainLabel.textColor = NSColor.black
  487. payExplainLabel.font = NSFont.SFProTextRegularFont(11.0)
  488. discountPriceLabel1.isHidden = true
  489. let localizedString = KMLocalizedString("By submitting this order, I agree to the %@ and %@ for subscription products", comment: "")
  490. let privacyPolicy = KMLocalizedString("Privacy Policy", comment: "")
  491. let termsOfService = KMLocalizedString("Terms of Service", comment: "")
  492. let fullString1 = String(format: localizedString, privacyPolicy, termsOfService)
  493. let attributedString1 = NSMutableAttributedString(string: fullString1)
  494. let privacyPolicyRange = (fullString1 as NSString).range(of: privacyPolicy)
  495. let termsOfServiceRange = (fullString1 as NSString).range(of: termsOfService)
  496. let linkColor1 = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  497. let font1 = NSFont.SFProTextRegularFont(11.0) // 与普通文本相同的字体
  498. attributedString1.addAttributes([
  499. .foregroundColor: NSColor(named: "KMPurchase_99A6B2") as Any,
  500. .font: font1
  501. ], range: (fullString1 as NSString).range(of: fullString1))
  502. attributedString1.addAttributes([
  503. .foregroundColor: linkColor1,
  504. .link: KMLocalizedString("https://www.pdfreaderpro.com/privacy-policy", comment: ""),
  505. .font: font1
  506. ], range: privacyPolicyRange)
  507. attributedString1.addAttributes([
  508. .foregroundColor: linkColor1,
  509. .link: KMLocalizedString("https://www.pdfreaderpro.com/terms_of_service", comment: ""),
  510. .font: font1
  511. ], range: termsOfServiceRange)
  512. payExplainLabel.attributedStringValue = attributedString1
  513. paypalBuyNowLabel.stringValue = KMLocalizedString("Buy Now", comment: "")
  514. paypalBuyNowLabel.textColor = NSColor.white
  515. paypalBuyNowLabel.font = NSFont.SFProTextBoldFont(16.0)
  516. paddleButton.title = KMLocalizedString("Continue to Pay", comment: "")
  517. paddleButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  518. paddlePopUpButton.type = .arrowDown
  519. paddlePopUpButton.removeAllItems()
  520. paddlePopUpButton.addItems(withTitles: countryKeys)
  521. let preferredLanguage = Locale.preferredLanguages.first ?? "en"
  522. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  523. paddlePopUpButton.selectItem(at: 45)
  524. } else {
  525. paddlePopUpButton.selectItem(at: 229)
  526. }
  527. paddleBox.fillColor = NSColor(named: "KMPurchase_FFFFFF") ?? NSColor.white
  528. paddleBox.borderColor = NSColor(named: "KMPurchase_DADBDE") ?? NSColor.gray
  529. paddleTextField.placeholderString = KMLocalizedString("Postcode", comment: "")
  530. paddleTextField.delegate = self
  531. weChatButton.title = KMLocalizedString("Continue to Pay", comment: "")
  532. weChatButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  533. qrCodeImageView.imageScaling = .scaleProportionallyUpOrDown
  534. scanLabel.textColor = NSColor(named: "KMPurchase_000000")
  535. scanLabel.font = NSFont.SFProTextRegularFont(12)
  536. successfullyView.isHidden = true
  537. purchasedLabel.stringValue = KMLocalizedString("Purchased", comment: "")
  538. purchasedLabel.textColor = NSColor(named: "KMPurchase_002143")
  539. purchasedLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  540. successfullyLabel.stringValue = KMLocalizedString("Successfully", comment: "")
  541. successfullyLabel.textColor = NSColor(named: "KMPurchase_002143")
  542. successfullyLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  543. emailErrorLabel(isReveal: false)
  544. }
  545. private func _updateViewColor() {
  546. paddlePopUpButton.wantsLayer = true
  547. if KMAppearance.isDarkMode() {
  548. prodocumentView.layer?.borderColor = NSColor(hex: "#E2E3E5").cgColor
  549. paddlePopUpButton.layer?.backgroundColor = NSColor(hex: "#393C3E").cgColor
  550. } else {
  551. prodocumentView.layer?.borderColor = NSColor(hex: "#E2E3E5").cgColor
  552. paddlePopUpButton.layer?.backgroundColor = NSColor(hex: "#FFFFFF").cgColor
  553. }
  554. }
  555. private func priceRefresh(productsModel: KMListingProductsModel) -> Void {
  556. if productsModel.code == "" {
  557. return
  558. }
  559. var listPrice: Float = 0.0
  560. var discount: Float = 0.0
  561. var paySum: Float = 0.0
  562. var discount1: Float = 0.0
  563. var original1: Float = 0.0
  564. var abbreviation = "USD"
  565. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  566. abbreviation = "CNY"
  567. }
  568. let insting = Float(showSinglePriceString())
  569. listPrice = Float(String(format: "%.2f", Float((insting ?? 0) * Float(pdfCount)))) ?? 0 //单价*购买个数
  570. if _product_code == KMAdvancedAnnualSubscriptionTrailCodeKey_DMG {
  571. var tipsString = KMLocalizedString("7-day free trial, then auto-renew at %@/year", tableName: "MemberCenterLocalizable", comment: "")
  572. let value = String(format: "%@ %.2f", abbreviation, insting ?? 0)
  573. let fullString = String(format: tipsString, value)
  574. prmiumLabel.stringValue = fullString
  575. original1 = Float(showOrgPriceString()) ?? 0
  576. discount1 = Float(showOrgShowPriceString()) ?? 0
  577. paySum = discount1
  578. discount = listPrice - paySum
  579. } else if _product_code == "advanced-annual-subscription-blackFive" ||
  580. _product_code == "advanced-permanent-blackFive" ||
  581. _product_code == KMAISubscriptionYearTrailCodeKey_DMG {
  582. // 全平台高级版年订阅 99.9 美金,带免费试用
  583. // 全平台高级版年订阅 99.9 美金,黑五订单
  584. // Mac & Win 双平台高级永久 119.99 美金,黑五订单
  585. // AI 年订阅 125.99 美金,带免费试用
  586. var tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  587. if product_Info.cycle == 4 {
  588. tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable",comment: "")
  589. }
  590. if product_Info.cycle == 3 {
  591. tipsString = KMLocalizedString("%.2f/half a year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  592. }
  593. if product_Info.cycle == 2 {
  594. tipsString = KMLocalizedString("%.2f/quarter, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  595. }
  596. if product_Info.cycle == 1 {
  597. tipsString = KMLocalizedString("%.2f/monthly, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  598. }
  599. if product_Info.cycle == 0 {
  600. tipsString = KMLocalizedString("%.2f/Permanent Plan", tableName: "MemberCenterLocalizable", comment: "")
  601. }
  602. let fullString = String(format: tipsString, insting ?? 0)
  603. prmiumLabel.stringValue = String(format: "%@ %@", abbreviation, fullString)
  604. original1 = Float(showOrgPriceString()) ?? 0
  605. discount1 = Float(showOrgShowPriceString()) ?? 0
  606. paySum = discount1
  607. discount = listPrice - paySum
  608. }
  609. if _product_code == "advanced-annual-subscription" ||
  610. _product_code == "standard-annual-subscription" ||
  611. _product_code == "ai-subscription-month" {
  612. // 全平台高级版年订阅 99.9 美金,无试用
  613. // 全平台标准版年订阅 79.9 美金
  614. // Mac & Win 双平台高级永久 119.99 美金
  615. // AI 月订阅 14.99 美金
  616. var tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  617. if product_Info.cycle == 4 {
  618. tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  619. }
  620. if product_Info.cycle == 3 {
  621. tipsString = KMLocalizedString("%.2f/half a year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  622. }
  623. if product_Info.cycle == 2 {
  624. tipsString = KMLocalizedString("%.2f/quarter, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  625. }
  626. if product_Info.cycle == 1 {
  627. tipsString = KMLocalizedString("%.2f/monthly, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  628. }
  629. if product_Info.cycle == 0 {
  630. tipsString = KMLocalizedString("%.2f/Permanent Plan", tableName: "MemberCenterLocalizable", comment: "")
  631. }
  632. var fullString = String(format: tipsString, insting ?? 0)
  633. let originalStr = showOrgPriceString()
  634. let discountStr = showOrgShowPriceString()
  635. if originalStr == discountStr {
  636. } else {
  637. if discountStr.isEmpty == false && discountStr != "0" {
  638. let data = Float(discountStr) ?? 0
  639. fullString = String(format: tipsString, data)
  640. }
  641. }
  642. prmiumLabel.stringValue = String(format: "%@ %@", abbreviation, fullString)
  643. original1 = Float(showOrgPriceString()) ?? 0
  644. discount1 = Float(showOrgShowPriceString()) ?? 0
  645. paySum = discount1
  646. discount = listPrice - paySum
  647. }
  648. if _product_code == "advanced-permanent" {
  649. // Mac & Win 双平台高级永久 119.99 美金
  650. var tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  651. if product_Info.cycle == 4 {
  652. tipsString = KMLocalizedString("%.2f/year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  653. }
  654. if product_Info.cycle == 3 {
  655. tipsString = KMLocalizedString("%.2f/half a year, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  656. }
  657. if product_Info.cycle == 2 {
  658. tipsString = KMLocalizedString("%.2f/quarter, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  659. }
  660. if product_Info.cycle == 1 {
  661. tipsString = KMLocalizedString("%.2f/monthly, auto-renewal", tableName: "MemberCenterLocalizable", comment: "")
  662. }
  663. if product_Info.cycle == 0 {
  664. tipsString = KMLocalizedString("%.2f/Permanent Plan", tableName: "MemberCenterLocalizable", comment: "")
  665. }
  666. let fullString = String(format: tipsString, insting ?? 0)
  667. prmiumLabel.stringValue = String(format: "%@ %@", abbreviation, fullString)
  668. original1 = Float(showOrgPriceString()) ?? 0
  669. discount1 = Float(showOrgShowPriceString()) ?? 0
  670. paySum = discount1
  671. discount = listPrice - paySum
  672. }
  673. originalPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", insting ?? 0))
  674. lastPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", listPrice))
  675. discountLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount))
  676. paySumLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", paySum))
  677. discountLayoutConstraint.constant = discountView.isHidden ? -CGRectGetHeight(discountView.bounds) : 8
  678. }
  679. // MARK: Active
  680. @IBAction func amountButtonAction(_ sender: NSButton) {
  681. if sender.tag == 0 || sender.tag == 1 {
  682. if sender.tag == 0 {
  683. if pdfCount > 1 {
  684. pdfCount -= 1
  685. }
  686. }
  687. if sender.tag == 1 {
  688. if pdfCount < 9999 {
  689. pdfCount += 1
  690. }
  691. }
  692. if pdfCount > 1 {
  693. removeButton1.isEnabled = true
  694. } else {
  695. removeButton1.isEnabled = false
  696. }
  697. if pdfCount > 100 {
  698. wechatPayButton2.isHidden = false
  699. cardButton.isHidden = true
  700. wechatPayButton.isHidden = true
  701. if _paymentMethod == .paddle {
  702. paymentMethod = .paypal
  703. }
  704. } else {
  705. wechatPayButton2.isHidden = true
  706. // cardButton.isHidden = false
  707. wechatPayButton.isHidden = false
  708. }
  709. amountTextField1.stringValue = String(pdfCount)
  710. let viewHidden = pdfCount <= 1
  711. firmLabel.isHidden = viewHidden
  712. if viewHidden {
  713. addbox.fillColor = NSColor(hex: "#F1F1F2")
  714. } else {
  715. addbox.fillColor = NSColor(named: "0E1114 1") ?? .white
  716. }
  717. couponView.isHidden = !viewHidden
  718. }
  719. // 价格刷新
  720. priceRefresh(productsModel: _product_Info)
  721. let model = KMProductModel.shared
  722. isBatchProductPriceGetFinsed = false
  723. updateProduct_Info()
  724. }
  725. @IBAction func payButtonAction(_ sender: NSButton) {
  726. emailErrorLabel(isReveal: false)
  727. paymentMethod = KMPaymentType(rawValue: uint32(sender.tag)) ?? .paypal
  728. // 价格刷新
  729. priceRefresh(productsModel: _product_Info)
  730. }
  731. @IBAction func couponButtonAction(_ sender: NSButton) {
  732. couponButton.isHidden = true
  733. couponBox.isHidden = false
  734. applyBox.isHidden = false
  735. }
  736. @IBAction func applyButtonAction(_ sender: NSButton) {
  737. if coupomTextField.stringValue == "" {
  738. let alert = NSAlert()
  739. alert.alertStyle = .critical
  740. alert.messageText = KMLocalizedString("Error Information", comment: "")
  741. alert.informativeText = KMLocalizedString("Please enter a coupon code.", comment: "")
  742. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  743. alert.runModal()
  744. return
  745. }
  746. if(Int(amountTextField1.stringValue) ?? 0 > 1) { //购买多个不支持优惠卷
  747. return
  748. }
  749. if KMMemberCenterManager.manager.isConnectionAvailable() == false {
  750. let alert = NSAlert()
  751. alert.alertStyle = .critical
  752. alert.messageText = KMLocalizedString("Error Information", comment: "")
  753. alert.informativeText = KMLocalizedString("Please make sure your internet connection is available.", comment: "")
  754. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  755. alert.runModal()
  756. return
  757. }
  758. self.refreshCouponError(isReveal: false)
  759. applyButton.isEnabled = false
  760. coupomTextField.isEnabled = false
  761. window?.showWaitingView()
  762. KMMemberCenterManager.manager.checkCoupon(productId: product_Info.id, userId: KMMemberInfo.shared.userID, code: coupomTextField.stringValue) {[weak self] success, result in
  763. self?.window?.hideWaitingView()
  764. KMMainThreadExecute {
  765. if(success == true) {
  766. let alert = NSAlert()
  767. alert.alertStyle = .critical
  768. alert.messageText = KMLocalizedString("Successfully", comment: "")
  769. _ = alert.runModal()
  770. guard let productResult : KMMemberProductResult = result else {
  771. return
  772. }
  773. guard let couponModel : KMCheckCouponModel = productResult.checkCoupon else {
  774. return
  775. }
  776. let priceString = couponModel.priceString
  777. self?.product_Info.priceString = priceString
  778. let cnyPriceString = couponModel.cnyPriceString
  779. self?.product_Info.cnyPriceString = cnyPriceString //批量时将总价赋给priceString,只显示priceString价格了,其他的置空
  780. self?.product_Info.upgradePriceString = couponModel.upgradePriceString
  781. self?.product_Info.cnyUpgradePriceString = couponModel.upgradecnyPriceString
  782. self?.product_Info.displayPriceString = couponModel.displayPriceString
  783. self?.product_Info.displayCnyPriceString = couponModel.displayCnyPriceString
  784. self?.product_Info.individualPriceString = couponModel.priceString
  785. self?.product_Info.individualCnyPriceString = couponModel.cnyPriceString
  786. self?.product_Info.verifyofferCode = self?.coupomTextField.stringValue ?? ""
  787. if self?._paymentMethod == .alipay || self?._paymentMethod == .wxpay {
  788. self?.updatePrice()
  789. }
  790. self?.priceRefresh(productsModel: self?._product_Info ?? KMListingProductsModel())
  791. }else {
  792. let alert = NSAlert()
  793. alert.alertStyle = .critical
  794. alert.messageText = KMLocalizedString("Error Information", comment: "")
  795. alert.informativeText = KMLocalizedString("The coupon code is invalid. Please try again.", comment: "")
  796. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  797. let result = alert.runModal()
  798. if (result == .alertFirstButtonReturn) {
  799. }
  800. }
  801. }
  802. }
  803. }
  804. @IBAction func paddlePopUpAction(_ sender: NSPopUpButton) {
  805. }
  806. @IBAction func couponClearButton(_ sender: NSButton) {
  807. coupomTextField.stringValue = ""
  808. couponClearButton.isHidden = true
  809. applyButton.isEnabled = true
  810. coupomTextField.isEnabled = true
  811. refreshCouponError(isReveal: false)
  812. }
  813. @IBAction func buyAction(_ sender: NSButton) {
  814. if emailTextField.stringValue == "" {
  815. emailErrorLabel(isReveal: true)
  816. return
  817. }
  818. if paymentMethod == .paddle {
  819. if !isNumeric(paddleTextField.stringValue) && paddleTextField.stringValue != "" {
  820. let alert = NSAlert()
  821. alert.alertStyle = .critical
  822. alert.messageText = KMLocalizedString("Error Information", comment: "")
  823. alert.informativeText = KMLocalizedString("Please enter the correct postcode.", comment: "")
  824. alert.addButton(withTitle: KMLocalizedString("OK", comment: ""))
  825. alert.runModal()
  826. return
  827. }
  828. }
  829. if paymentMethod == .paypal {
  830. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  831. } else if paymentMethod == .paddle {
  832. paddleView.wantsLayer = true
  833. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor1")?.cgColor ?? NSColor.blue.cgColor
  834. } else if paymentMethod == .wxpay {
  835. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  836. } else if paymentMethod == .alipay {
  837. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  838. }
  839. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
  840. guard let strongSelf = self else { return }
  841. if strongSelf.paymentMethod == .paypal {
  842. strongSelf.paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  843. } else if strongSelf.paymentMethod == .paddle {
  844. strongSelf.paddleView.wantsLayer = true
  845. strongSelf.paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  846. } else if strongSelf.paymentMethod == .wxpay {
  847. strongSelf.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  848. } else if strongSelf.paymentMethod == .alipay {
  849. strongSelf.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  850. }
  851. }
  852. var couponCode = ""
  853. if product_Info.verifyofferCode.isEmpty == false {
  854. couponCode = product_Info.verifyofferCode
  855. }
  856. let model = KMProductModel.shared
  857. if isOneTimePurchase(_product_Info) {
  858. let price = showPayPriceString()
  859. model.creatOrder(productId: _product_Info.id,
  860. paymentMethod: getPurchasePaymentMethod(),
  861. price: price,
  862. discountFlag: getOneTimePurchaseDiscountFlag(),
  863. couponCode: couponCode,
  864. num: pdfCount) { success, result in
  865. if success {
  866. if let dataInfo = result {
  867. self.orderID = result?.createOrder?.orderId ?? ""
  868. let page_pay_url = result?.createOrder?.payHref ?? ""
  869. let qrCode = result?.createOrder?.qrCode ?? ""
  870. if self.paymentMethod == .paddle || self.paymentMethod == .paypal {
  871. if self.orderID == "" || page_pay_url == "" {
  872. DispatchQueue.main.async {
  873. let alert = NSAlert()
  874. alert.alertStyle = .critical
  875. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  876. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  877. alert.runModal()
  878. }
  879. } else {
  880. self.openWebView(page_pay_url)
  881. }
  882. } else if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  883. if self.orderID == "" || qrCode == "" {
  884. DispatchQueue.main.async {
  885. let alert = NSAlert()
  886. alert.alertStyle = .critical
  887. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  888. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  889. alert.runModal()
  890. }
  891. } else {
  892. self.scanCode(qrCode)
  893. }
  894. }
  895. } else {
  896. DispatchQueue.main.async {
  897. let alert = NSAlert()
  898. alert.alertStyle = .critical
  899. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  900. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  901. alert.runModal()
  902. }
  903. }
  904. } else {
  905. DispatchQueue.main.async {
  906. let alert = NSAlert()
  907. alert.alertStyle = .critical
  908. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  909. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  910. alert.runModal()
  911. }
  912. }
  913. }
  914. } else {
  915. var priceString = showPayPriceString()
  916. model.createSubscriber(productId: _product_Info.id,
  917. paymentMethod: getPurchasePaymentMethod(),
  918. price: priceString,
  919. discountFlag: getOneTimePurchaseDiscountFlag(),
  920. couponCode: couponCode,
  921. num: pdfCount) { success, result in
  922. if success {
  923. if let dataInfo = result {
  924. self.orderID = result?.createOrder?.orderId ?? ""
  925. let page_pay_url = result?.createOrder?.payHref ?? ""
  926. if self.orderID == "" || page_pay_url == "" {
  927. DispatchQueue.main.async {
  928. let alert = NSAlert()
  929. alert.alertStyle = .critical
  930. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  931. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  932. alert.runModal()
  933. }
  934. } else {
  935. if self.paymentMethod == .paddle || self.paymentMethod == .paypal {
  936. self.openWebView(page_pay_url)
  937. }
  938. }
  939. } else {
  940. DispatchQueue.main.async {
  941. let alert = NSAlert()
  942. alert.alertStyle = .critical
  943. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  944. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  945. alert.runModal()
  946. }
  947. }
  948. } else {
  949. DispatchQueue.main.async {
  950. let alert = NSAlert()
  951. alert.alertStyle = .critical
  952. alert.messageText = KMLocalizedString("Please check if the information is wrong or the network is error.", comment: "")
  953. alert.addButton(withTitle: KMLocalizedString("Yes", comment: ""))
  954. alert.runModal()
  955. }
  956. }
  957. }
  958. }
  959. }
  960. func getPurchasePaymentMethod() -> Int {
  961. switch self.paymentMethod {
  962. case .paypal:
  963. return 0;
  964. case .alipay:
  965. return 1;
  966. case .wxpay:
  967. return 2;
  968. case .paddle:
  969. return 3;
  970. default:
  971. return 1;
  972. }
  973. }
  974. func getOneTimePurchaseDiscountFlag() -> Int {
  975. if pdfCount > 1 { //批量购买
  976. return 4
  977. } else {
  978. var couponCode = ""
  979. if _product_Info.verifyofferCode.isEmpty == false {
  980. couponCode = _product_Info.verifyofferCode
  981. }
  982. if(couponCode.isEmpty == false) {//判断是否有使用优惠卷
  983. if _product_code == "advanced-annual-subscription-blackFive" ||
  984. _product_code == "advanced-permanent-blackFive" {
  985. return 11
  986. } else {
  987. return 1
  988. }
  989. } else {
  990. if _product_code == "advanced-annual-subscription-blackFive"{ //黑五订阅
  991. if(_product_Info.upgradePriceString?.isEmpty == false) { //升级
  992. return 2
  993. } else {
  994. return 5
  995. }
  996. } else if _product_code == "advanced-permanent-blackFive" {//黑五买断
  997. return 5
  998. } else if _product_code == "advanced-annual-subscription" { //高级订阅
  999. if(_product_Info.upgradePriceString?.isEmpty == false) { //升级
  1000. return 2
  1001. } else {
  1002. return 0
  1003. }
  1004. } else if _product_code == "advanced-annual-subscription-trail" ||
  1005. _product_code == "ai-subscription-year-trail" { //试用
  1006. return 5
  1007. } else {
  1008. return 0
  1009. }
  1010. }
  1011. }
  1012. }
  1013. func getPurchaseDiscountFlag() -> Int {
  1014. var couponCode = ""
  1015. if coupomErrorLabel.isHidden {
  1016. couponCode = coupomTextField.stringValue
  1017. }
  1018. if couponCode == "" {
  1019. if _product_code == "advanced-annual-subscription-blackFive" ||
  1020. _product_code == "advanced-permanent-blackFive" {
  1021. return 5
  1022. }
  1023. if _product_code == "advanced-annual-subscription-trail" ||
  1024. _product_code == "ai-subscription-year-trail" {
  1025. return 5
  1026. }
  1027. return 0
  1028. } else {
  1029. if _product_code == "advanced-annual-subscription-blackFive" ||
  1030. _product_code == "advanced-permanent-blackFive" {
  1031. return 11
  1032. }
  1033. return 1
  1034. }
  1035. }
  1036. // MARK: get & set
  1037. var product_code : String { //设置code
  1038. get {
  1039. return _product_code
  1040. }
  1041. set {
  1042. _product_code = newValue
  1043. if(isSubscribeCode() == true) {
  1044. addButton1.isEnabled = false
  1045. wechatPayButton.isHidden = true
  1046. alipayButton.isHidden = true
  1047. prodocumentView.isHidden = true
  1048. } else {
  1049. addButton1.isEnabled = true
  1050. wechatPayButton.isHidden = false
  1051. alipayButton.isHidden = false
  1052. prodocumentView.isHidden = false
  1053. }
  1054. if pdfCount > 1 {
  1055. removeButton1.isEnabled = true
  1056. } else {
  1057. removeButton1.isEnabled = false
  1058. }
  1059. if(newValue == "advanced-annual-subscription-trail" ||
  1060. newValue == "ai-subscription-year-trail") {
  1061. couponView.isHidden = true
  1062. }
  1063. let model = KMProductModel.shared
  1064. let products : [KMListingProductsModel] = model.dmgProductDatas?.listingProducts ?? []
  1065. if products.count > 0 {
  1066. for product in products {
  1067. if product.code == _product_code {
  1068. self.product_Info = product;
  1069. self.updateProduct_Info()
  1070. break
  1071. }
  1072. }
  1073. } else {
  1074. model.getDMGProductDatas(discountCode: self.discountCodeId ?? "") { [weak self] success, result in
  1075. let products : [KMListingProductsModel] = model.dmgProductDatas?.listingProducts ?? []
  1076. if products.count > 0 {
  1077. for product in products {
  1078. if product.code == self?.product_code {
  1079. self?.product_Info = product;
  1080. //更新价格
  1081. self?.updateProduct_Info()
  1082. break
  1083. }
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089. }
  1090. var product_Info: KMListingProductsModel { //刷新产品ui+价格
  1091. get {
  1092. return _product_Info
  1093. }
  1094. set {
  1095. _product_Info = newValue
  1096. if isWindowDidLoad {
  1097. xibInitialization()
  1098. priceRefresh(productsModel: _product_Info)
  1099. func isSubscribeCode()-> Bool {//是否是订阅
  1100. if(product_code == "standard-annual-subscription" ||
  1101. product_code == "advanced-annual-subscription-blackFive" ||
  1102. product_code == "advanced-annual-subscription-trail" ||
  1103. product_code == "advanced-annual-subscription" ||
  1104. product_code == "ai-subscription-year-trail" ||
  1105. product_code == "ai-subscription-month") {
  1106. return true
  1107. }
  1108. return false
  1109. }
  1110. func isOneTimePurchaseCode()-> Bool { //是否是一次性购买
  1111. if(product_code == "advanced-permanent-blackFive" ||
  1112. product_code == "advanced-permanent") {
  1113. return true
  1114. }
  1115. return false
  1116. }
  1117. if(_product_code == "standard-annual-subscription") {
  1118. pdfReaderProLabel.stringValue = KMLocalizedString("PDF Reader Pro Standard - Annual Plan", tableName: "MemberCenterLocalizable", comment: "")
  1119. } else if (_product_code == "advanced-annual-subscription-blackFive" ||
  1120. _product_code == "advanced-annual-subscription-trail" ||
  1121. _product_code == "advanced-annual-subscription") {
  1122. pdfReaderProLabel.stringValue = KMLocalizedString("PDF Reader Pro Advanced - Annual Plan", tableName: "MemberCenterLocalizable", comment: "")
  1123. } else if (_product_code == "ai-subscription-year-trail") {
  1124. pdfReaderProLabel.stringValue = KMLocalizedString("PDF Reader Pro Al - Annual Plan", tableName: "MemberCenterLocalizable", comment: "")
  1125. } else if (_product_code == "ai-subscription-month") {
  1126. pdfReaderProLabel.stringValue = KMLocalizedString("PDF Reader Pro Al - Monthly Plan", tableName: "MemberCenterLocalizable", comment: "")
  1127. } else if (_product_code == "advanced-permanent-blackFive" ||
  1128. _product_code == "advanced-permanent") {
  1129. pdfReaderProLabel.stringValue = KMLocalizedString("PDF Reader Pro Permanent", tableName: "MemberCenterLocalizable", comment: "")
  1130. } else {
  1131. pdfReaderProLabel.stringValue = product_Info.productName //待区分多语
  1132. }
  1133. }
  1134. }
  1135. }
  1136. private var paymentMethod : KMPaymentType {
  1137. get {
  1138. return _paymentMethod
  1139. }
  1140. set {
  1141. _paymentMethod = newValue
  1142. paypalButton.image = NSImage(named: "EmbeddedPayment19")
  1143. cardButton.image = NSImage(named: "EmbeddedPayment21")
  1144. wechatPayButton.image = NSImage(named: "EmbeddedPayment23")
  1145. wechatPayButton2.image = NSImage(named: "EmbeddedPayment23")
  1146. alipayButton.image = NSImage(named: "EmbeddedPayment25")
  1147. if _paymentMethod == .paypal {
  1148. paypalButton.image = NSImage(named: "EmbeddedPayment18")
  1149. payBox.contentView = paypalView
  1150. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  1151. payBoxHeight.constant = 60.0
  1152. } else if _paymentMethod == .paddle {
  1153. cardButton.image = NSImage(named: "EmbeddedPayment20")
  1154. payBox.contentView = cardView
  1155. paddleView.wantsLayer = true
  1156. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  1157. payBoxHeight.constant = 150.0
  1158. } else if _paymentMethod == .wxpay {
  1159. wechatPayButton.image = NSImage(named: "EmbeddedPayment22")
  1160. wechatPayButton2.image = NSImage(named: "EmbeddedPayment22")
  1161. payBox.contentView = weChatPayView
  1162. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  1163. payBoxHeight.constant = 92.0
  1164. } else if _paymentMethod == .alipay {
  1165. alipayButton.image = NSImage(named: "EmbeddedPayment24")
  1166. payBox.contentView = weChatPayView
  1167. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  1168. payBoxHeight.constant = 92.0
  1169. }
  1170. }
  1171. }
  1172. private func updatePrice() {
  1173. if _paymentMethod == .wxpay {
  1174. wechatPayButton.image = NSImage(named: "EmbeddedPayment22")
  1175. wechatPayButton2.image = NSImage(named: "EmbeddedPayment22")
  1176. payBox.contentView = weChatPayView
  1177. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  1178. payBoxHeight.constant = 92.0
  1179. } else if _paymentMethod == .alipay {
  1180. alipayButton.image = NSImage(named: "EmbeddedPayment24")
  1181. payBox.contentView = weChatPayView
  1182. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  1183. payBoxHeight.constant = 92.0
  1184. }
  1185. }
  1186. func isSubscribeCode()-> Bool {//是否是订阅
  1187. if(product_code == "standard-annual-subscription" ||
  1188. product_code == "advanced-annual-subscription-blackFive" ||
  1189. product_code == "advanced-annual-subscription-trail" ||
  1190. product_code == "advanced-annual-subscription" ||
  1191. product_code == "ai-subscription-year-trail" ||
  1192. product_code == "ai-subscription-month") {
  1193. return true
  1194. }
  1195. return false
  1196. }
  1197. func isOneTimePurchaseCode()-> Bool { //是否是一次性购买
  1198. if(product_code == "advanced-permanent-blackFive" ||
  1199. product_code == "advanced-permanent") {
  1200. return true
  1201. }
  1202. return false
  1203. }
  1204. func isBlackFiveCode()-> Bool { //是否是黑五
  1205. if(product_code == "advanced-permanent-blackFive" ||
  1206. product_code == "advanced-annual-subscription-blackFive") {
  1207. return true
  1208. }
  1209. return false
  1210. }
  1211. func isHaveAvailableCoupon()-> Bool { //是否有优惠卷
  1212. return false
  1213. }
  1214. func showPriceString()->String {
  1215. let preferredLanguage = Locale.preferredLanguages.first ?? "en"
  1216. var priceString = product_Info.priceString ?? ""
  1217. if(product_Info.upgradePriceString?.isEmpty == false) {
  1218. priceString = product_Info.upgradePriceString ?? ""
  1219. } else if(product_Info.displayPriceString?.isEmpty == false) {
  1220. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1221. priceString = product_Info.displayCnyPriceString ?? ""
  1222. } else {
  1223. priceString = product_Info.displayPriceString ?? ""
  1224. }
  1225. } else if(product_Info.priceString?.isEmpty == false) {
  1226. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1227. priceString = product_Info.cnyPriceString ?? ""
  1228. } else {
  1229. priceString = product_Info.priceString ?? ""
  1230. }
  1231. }
  1232. return priceString
  1233. }
  1234. func showOrgPriceString()->String { //原价
  1235. let preferredLanguage = Locale.preferredLanguages.first ?? "en"
  1236. var priceString = product_Info.priceString ?? ""
  1237. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1238. priceString = product_Info.cnyPriceString ?? ""
  1239. } else {
  1240. priceString = product_Info.priceString ?? ""
  1241. }
  1242. return priceString
  1243. }
  1244. func showOrgShowPriceString()->String { //实际购买显示的价格
  1245. let preferredLanguage = Locale.preferredLanguages.first ?? "en"
  1246. var priceString = product_Info.priceString ?? ""
  1247. if(product_Info.upgradePriceString?.isEmpty == false) {
  1248. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1249. priceString = product_Info.cnyUpgradePriceString ?? ""
  1250. } else {
  1251. priceString = product_Info.upgradePriceString ?? ""
  1252. }
  1253. } else if(product_Info.displayPriceString?.isEmpty == false) {
  1254. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1255. priceString = product_Info.displayCnyPriceString ?? ""
  1256. } else {
  1257. priceString = product_Info.displayPriceString ?? ""
  1258. }
  1259. } else if(product_Info.priceString?.isEmpty == false) {
  1260. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1261. priceString = product_Info.cnyPriceString ?? ""
  1262. } else {
  1263. priceString = product_Info.priceString ?? ""
  1264. }
  1265. }
  1266. return priceString
  1267. }
  1268. func showSinglePriceString()->String { //单价
  1269. var priceString = product_Info.individualPriceString ?? ""
  1270. if KMLocalizedString("USD", tableName: "MemberCenterLocalizable", comment: "") == "CN" {
  1271. priceString = product_Info.individualCnyPriceString ?? ""
  1272. } else {
  1273. priceString = product_Info.individualPriceString ?? ""
  1274. }
  1275. return priceString
  1276. }
  1277. func showPayPriceString()->String { //实际支付的价格
  1278. let iswechatOrAlipayPay = (self.paymentMethod == .wxpay || self.paymentMethod == .alipay)
  1279. var priceString = product_Info.priceString ?? ""
  1280. if(product_Info.upgradePriceString?.isEmpty == false) {
  1281. priceString = product_Info.upgradePriceString ?? ""
  1282. } else if(product_Info.displayPriceString?.isEmpty == false) {
  1283. if(iswechatOrAlipayPay) {
  1284. priceString = product_Info.displayCnyPriceString ?? ""
  1285. } else {
  1286. priceString = product_Info.displayPriceString ?? ""
  1287. }
  1288. } else if(product_Info.priceString?.isEmpty == false) {
  1289. if(iswechatOrAlipayPay) {
  1290. priceString = product_Info.cnyPriceString ?? ""
  1291. } else {
  1292. priceString = product_Info.priceString ?? ""
  1293. }
  1294. }
  1295. return priceString
  1296. }
  1297. // MARK: Private
  1298. private func _showOrHideCardButton(show: Bool) {
  1299. KMMainThreadExecute { [weak self] in
  1300. self?.cardButton.isHidden = !show
  1301. self?.cardButtonWidthConst.constant = !show ? 0 : 78
  1302. }
  1303. }
  1304. private func _configFirmLabel() {
  1305. firmLabel.isEditable = false
  1306. firmLabel.isSelectable = true
  1307. firmLabel.allowsEditingTextAttributes = true
  1308. firmLabel.textColor = NSColor.black
  1309. firmLabel.font = NSFont.SFProTextRegularFont(14.0)
  1310. let firmString = KMLocalizedString("If you need to manage seats in PDF Reader Pro, please purchase the %@.", tableName: "MemberCenterLocalizable", comment: "")
  1311. let enterpriseStr = KMLocalizedString("enterprise version", tableName: "MemberCenterLocalizable", comment: "")
  1312. let fireFullString = String(format: firmString, enterpriseStr)
  1313. let firmLinkColor = NSColor(named: "4982E6") ?? NSColor.blue
  1314. let paragraphStyle = NSMutableParagraphStyle()
  1315. paragraphStyle.alignment = .right // 设置为右对齐
  1316. let attri = NSMutableAttributedString(string: fireFullString, attributes: [.foregroundColor : firmLinkColor, .font : NSFont.SFProTextRegularFont(14.0),.paragraphStyle:paragraphStyle,])
  1317. // 定义链接的范围
  1318. let enterpriseRange = (fireFullString as NSString).range(of: enterpriseStr)
  1319. let firmFont = NSFont.SFProTextRegularFont(14.0) // 与普通文本相同的字体
  1320. attri.addAttributes([
  1321. .foregroundColor: NSColor(named: "0E1114") ?? NSColor.black as Any,
  1322. .underlineStyle: NSUnderlineStyle.single.rawValue,
  1323. .font: firmFont
  1324. ], range: (fireFullString as NSString).range(of: enterpriseStr))
  1325. attri.addAttributes([
  1326. .foregroundColor: firmLinkColor,
  1327. .link: kLynxpdfeditorUrl,
  1328. .font: firmFont
  1329. ], range: enterpriseRange)
  1330. firmLabel.attributedStringValue = attri
  1331. }
  1332. private func uuid() -> String {
  1333. return GetHardwareUUID()!
  1334. }
  1335. private func _trackEvent_paid() {
  1336. self.trackEvent_dmg(eventName: self.kEventName, params: self.kEventParams, platform: .AppCenter)
  1337. }
  1338. private func _trackPurchaseCampaignEvent() {
  1339. if self.discountType_ == .newUserGift {
  1340. self.trackEvent(eventName: "Purchase_Campaign", params: ["Campaign_NewUser":"Tbr_Coupon"], platform: .firebase)
  1341. } else if self.discountType_ == .freeTrail {
  1342. self.trackEvent(eventName: "Purchase_Campaign", params: ["Campaign_NewUser":"Tbr_FreeTrial"], platform: .firebase)
  1343. } else if self.discountType_ == .advancedYearSubscribeTrialingCancel {
  1344. self.trackEvent(eventName: self.kEventName, params: self.kEventParams, platform: .firebase)
  1345. }
  1346. if (isAIPurchase) {
  1347. self.trackEvent(eventName: self.kEventName, params: self.kEventParams, platform: .firebase)
  1348. }
  1349. }
  1350. private func _canUseDiscountCode() -> Bool {
  1351. guard let data = discountCodeId else {
  1352. return false
  1353. }
  1354. if data == kKMNewUserGiftDiscountCodeId || data == kKMAdvancedYearSubscribeDiscountCodeId {
  1355. if product_code != KMStandardAnnualSubscriptionCodeKey_DMG && product_code != KMAdvancedAnnualSubscriptionCodeKey_DMG && product_code != KMAdvancedPermanentCodeKey_DMG {
  1356. return false
  1357. }
  1358. }
  1359. return true
  1360. }
  1361. private func getProductID() -> String {
  1362. return GetHardwareUUID()!
  1363. }
  1364. private func isNumeric(_ text: String) -> Bool {
  1365. return !text.isEmpty && text.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
  1366. }
  1367. private func openWebView(_ urlPath: String) -> Void {
  1368. DispatchQueue.main.async { [weak self] in
  1369. guard let self = self else { return }
  1370. self.pollCount = 0
  1371. self.startPolling()
  1372. self.embeddedPaymentPopWC = KMEmbeddedPaymentPopWC.currentFirstTrialWC(urlPath)
  1373. if self.paymentMethod == .paddle {
  1374. self.embeddedPaymentPopWC?.isPaddle = true
  1375. self.embeddedPaymentPopWC?.countryCode = self.countryAbbreviationValues[self.paddlePopUpButton.indexOfSelectedItem]
  1376. self.embeddedPaymentPopWC?.postCode = self.paddleTextField.stringValue
  1377. }
  1378. self.embeddedPaymentPopWC?.showWindow(nil)
  1379. self.embeddedPaymentPopWC?.callback = { isClose in
  1380. }
  1381. }
  1382. }
  1383. private func convertBase64StringToNSImage(base64String: String) -> NSImage? {
  1384. let sepS = "data:image/png;base64,"
  1385. guard let baseStr = base64String.components(separatedBy: sepS).last else {
  1386. return nil
  1387. }
  1388. if let data = Data(base64Encoded: baseStr) {
  1389. return NSImage(data: data)
  1390. }
  1391. return nil
  1392. }
  1393. private func scanCode(_ urlPath: String) -> Void {
  1394. DispatchQueue.main.async { [weak self] in
  1395. guard let self = self else { return }
  1396. self.payBox.contentView = self.payResult
  1397. self.payBoxHeight.constant = 262
  1398. if self.paymentMethod == .wxpay {
  1399. self.scanLabel.stringValue = KMLocalizedString("Scan QR Code with WeChat", comment: "")
  1400. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment27")
  1401. } else if self.paymentMethod == .alipay {
  1402. self.scanLabel.stringValue = KMLocalizedString("Scan QR Code with Alipay", comment: "")
  1403. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment28")
  1404. }
  1405. let img = self.convertBase64StringToNSImage(base64String: urlPath)
  1406. self.qrCodeImageView.image = img
  1407. self.pollCount = 0
  1408. self.startPolling()
  1409. }
  1410. }
  1411. private func pollingResultNew() -> Void { //刷新订单状态
  1412. DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
  1413. guard let self = self else { return }
  1414. if self.orderID == "" { return }
  1415. KMMemberCenterManager.manager.getStateByOrderId(orderId: self.orderID) { success, info in
  1416. self.startPolling()
  1417. if (success) {
  1418. let dic: NSDictionary = info ?? [:]
  1419. let requestDic: NSDictionary = dic["result"] as? NSDictionary ?? [:]
  1420. let status:String = requestDic["status"] as? String ?? ""
  1421. if(status.uppercased() == "COMPLETED") {
  1422. KMUserInfoVCModel().refreshUserInfo { success, msg,dic in
  1423. DispatchQueue.main.async {
  1424. #if VERSION_DMG
  1425. #else
  1426. KMCheckInManager.default.checkIn(refreshData: true, callback: nil)
  1427. #endif
  1428. NotificationCenter.default.post(name: NSNotification.Name.KMMemberInfoChange, object: self)
  1429. KMCancelSubscribeSuccessWindowController.shared.saveRecord()
  1430. self._trackPurchaseCampaignEvent()
  1431. }
  1432. }
  1433. KMMemberCenterManager.judgeTrailCancel { success, resultModel, error in
  1434. if success {
  1435. KMCheckInManager.default.trailCancel = resultModel?.result ?? false
  1436. }
  1437. }
  1438. self.stopPolling()
  1439. self.close()
  1440. DispatchQueue.main.async {
  1441. KMPurchaseSuccessWindowController.shared.showWindow(nil)
  1442. KMPurchaseSuccessWindowController.shared.closeCallback = { [weak self] (isClose: Bool) -> Void in
  1443. // guard let self = self else { return }
  1444. #if VERSION_DMG
  1445. KMCheckInManager.default.checkIn(refreshData: true, callback: nil)
  1446. #else
  1447. #endif
  1448. }
  1449. }
  1450. }
  1451. }
  1452. }
  1453. }
  1454. }
  1455. private func startPolling() {
  1456. timer = Timer(timeInterval: interval, repeats: false) { [weak self] _ in
  1457. guard let self = self else { return }
  1458. self.performTask()
  1459. }
  1460. RunLoop.main.add(timer!, forMode: .common)
  1461. }
  1462. @objc private func performTask() {
  1463. guard pollCount < maxPolls else {
  1464. timer?.invalidate()
  1465. timer = nil
  1466. return
  1467. }
  1468. // 执行你的轮询任务
  1469. print("Performing polling task \(pollCount + 1)/\(maxPolls)")
  1470. pollCount += 1
  1471. pollingResultNew()
  1472. }
  1473. private func stopPolling() {
  1474. timer?.invalidate()
  1475. timer = nil
  1476. pollCount = 0
  1477. }
  1478. private func emailErrorLabel(isReveal: Bool) {
  1479. errorView.isHidden = !isReveal
  1480. errorLabelTopLayout.constant = errorView.isHidden ? -CGRectGetHeight(errorView.bounds) : 4
  1481. }
  1482. private func refreshApplyButton(isReveal: Bool) {
  1483. self.applyButton.isEnabled = isReveal
  1484. }
  1485. private func refreshLicenseCodeView(isReveal: Bool) {
  1486. }
  1487. private func refreshLicenseCodeErrorView(isReveal: Bool) {
  1488. }
  1489. private func refreshCouponError(isReveal: Bool) {
  1490. coupomErrorLabel.isHidden = !isReveal
  1491. coupomErrorTopLayout.constant = coupomErrorLabel.isHidden ? -CGRectGetHeight(coupomErrorLabel.bounds) : 8.0
  1492. }
  1493. private func _applyDiscount(_ codeId: String, callback:((_ success: Bool, _ result: KMMemberProductResult?)->Void)?) {
  1494. if codeId == "" {
  1495. callback?(false, nil)
  1496. return
  1497. }
  1498. if KMMemberCenterManager.manager.isConnectionAvailable() == false {
  1499. callback?(false, nil)
  1500. return
  1501. }
  1502. self.refreshCouponError(isReveal: false)
  1503. applyButton.isEnabled = false
  1504. coupomTextField.isEnabled = false
  1505. window?.showWaitingView()
  1506. KMMemberCenterManager.manager.checkCoupon(productId: product_Info.id, userId: KMMemberInfo.shared.userID, code: codeId) {[weak self] success, result in
  1507. self?.window?.hideWaitingView()
  1508. KMMainThreadExecute {
  1509. callback?(success, result)
  1510. }
  1511. }
  1512. }
  1513. var activityAlertViewController: KMActivityALertViewController? {
  1514. if _activityAlertViewController == nil {
  1515. let blockSelf = self
  1516. _activityAlertViewController = KMActivityALertViewController()
  1517. _activityAlertViewController?.callback = {
  1518. blockSelf.close()
  1519. }
  1520. }
  1521. return _activityAlertViewController
  1522. }
  1523. }
  1524. extension KMPurchaseEmbeddedWindowController: NSTextFieldDelegate {
  1525. func controlTextDidEndEditing(_ obj: Notification) {
  1526. let textField = obj.object as? NSTextField
  1527. if textField == amountTextField1 {
  1528. if !isNumeric(textField!.stringValue) {
  1529. if textField == amountTextField1 { textField?.stringValue = String(pdfCount) }
  1530. } else {
  1531. if textField == amountTextField1 {
  1532. pdfCount = Int(textField!.stringValue) ?? 1
  1533. if Int(textField!.stringValue)! > 9999 {
  1534. pdfCount = 9999
  1535. textField?.stringValue = String(pdfCount)
  1536. } else if Int(textField!.stringValue)! < 1 {
  1537. pdfCount = 1
  1538. textField?.stringValue = String(pdfCount)
  1539. }
  1540. }
  1541. if pdfCount > 100 {
  1542. wechatPayButton2.isHidden = false
  1543. cardButton.isHidden = true
  1544. wechatPayButton.isHidden = true
  1545. if _paymentMethod == .paddle {
  1546. paymentMethod = .paypal
  1547. }
  1548. } else {
  1549. wechatPayButton2.isHidden = true
  1550. // cardButton.isHidden = false
  1551. wechatPayButton.isHidden = false
  1552. }
  1553. }
  1554. } else if textField == emailTextField {
  1555. emailErrorLabel(isReveal: false)
  1556. } else if textField == paddleTextField {
  1557. }
  1558. }
  1559. func controlTextDidChange(_ obj: Notification) {
  1560. let textField = obj.object as? NSTextField
  1561. if textField == amountTextField1 {
  1562. if !isNumeric(textField!.stringValue) {
  1563. if textField == amountTextField1 { textField?.stringValue = String(pdfCount) }
  1564. } else {
  1565. if Int(textField!.stringValue)! > 9999 {
  1566. textField?.stringValue = String(pdfCount)
  1567. } else if Int(textField!.stringValue)! < 1 {
  1568. textField?.stringValue = String(pdfCount)
  1569. }
  1570. }
  1571. }
  1572. }
  1573. }
  1574. extension KMPurchaseEmbeddedWindowController: NSWindowDelegate {
  1575. func windowWillClose(_ notification: Notification) {
  1576. if let data = self.window?.isEqual(to: notification.object), data {
  1577. // 窗口关闭,关闭轮询
  1578. stopPolling()
  1579. }
  1580. if self.embeddedPaymentPopWC != nil {
  1581. self.embeddedPaymentPopWC?.close()
  1582. self.embeddedPaymentPopWC = nil
  1583. }
  1584. KMPurchaseEmbeddedWindowController.currentWindowController = nil
  1585. }
  1586. }
  1587. #endif