KMPurchaseEmbeddedWindowController.swift 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603
  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. class KMPurchaseEmbeddedWindowController: NSWindowController {
  17. @IBOutlet weak var yourOrderLabel: NSTextField!
  18. @IBOutlet weak var pdfReaderProLabel: NSTextField!
  19. @IBOutlet weak var prmiumLabel: NSTextField!
  20. @IBOutlet weak var oneLicenseLabel: NSTextField!
  21. @IBOutlet weak var removeButton1: NSButton! // 减少按钮1
  22. @IBOutlet weak var addButton1: NSButton! // 增加按钮1
  23. @IBOutlet weak var amountTextField1: NSTextField! // 数目1
  24. @IBOutlet weak var originalPriceLabel1: NSTextField! // 原价
  25. @IBOutlet weak var discountPriceLabel1: NSTextField! // 折扣
  26. @IBOutlet weak var aiAddOnView: NSView!
  27. @IBOutlet weak var aiAddOnButton: NSButton!
  28. @IBOutlet weak var aiAddOnLabel: NSTextField!
  29. @IBOutlet weak var IndividualLabel: NSTextField!
  30. @IBOutlet weak var removeButton2: NSButton! // 减少按钮2
  31. @IBOutlet weak var addButton2: NSButton! // 增加按钮2
  32. @IBOutlet weak var amountTextField2: NSTextField! // 数目2
  33. @IBOutlet weak var amountView2: NSView!
  34. @IBOutlet weak var originalPriceLabel2: NSTextField! // 原价
  35. @IBOutlet weak var discountPriceLabel2: NSTextField! // 折扣
  36. @IBOutlet weak var aiAddOnButton1: NSButton!
  37. @IBOutlet weak var extendedView: NSView!
  38. @IBOutlet weak var extendedButton: NSButton!
  39. @IBOutlet weak var extendedLabel: NSTextField!
  40. @IBOutlet weak var extendedImageView: NSImageView!
  41. @IBOutlet weak var accessLabel: NSTextField!
  42. @IBOutlet weak var removeButton3: NSButton! // 减少按钮3
  43. @IBOutlet weak var addButton3: NSButton! // 增加按钮3
  44. @IBOutlet weak var amountTextField3: NSTextField! // 数目3
  45. @IBOutlet weak var amountView3: NSView!
  46. @IBOutlet weak var originalPriceLabel3: NSTextField! // 原价
  47. @IBOutlet weak var discountPriceLabel3: NSTextField! // 折扣
  48. @IBOutlet weak var extendedButton1: NSButton!
  49. @IBOutlet weak var couponButton: NSButton!
  50. @IBOutlet weak var couponBox: NSBox!
  51. @IBOutlet weak var coupomTextField: NSTextField!
  52. @IBOutlet weak var applyBox: NSBox!
  53. @IBOutlet weak var applyButton: NSButton!
  54. @IBOutlet weak var lastPriceLabel: NSTextField!
  55. @IBOutlet weak var lastPriceLabel1: NSTextField!
  56. @IBOutlet weak var discountView: NSView!
  57. @IBOutlet weak var discountLabel: NSTextField!
  58. @IBOutlet weak var discountLabel1: NSTextField!
  59. @IBOutlet weak var paySumLabel: NSTextField!
  60. @IBOutlet weak var paySumLabel1: NSTextField!
  61. @IBOutlet weak var discountLayoutConstraint: NSLayoutConstraint!
  62. @IBOutlet weak var privacyLabel: NSTextField!
  63. @IBOutlet weak var billInformationLabel: NSTextField!
  64. @IBOutlet weak var emailLabel: NSTextField!
  65. @IBOutlet weak var emailTextField: NSTextField!
  66. @IBOutlet weak var errorView: NSView!
  67. @IBOutlet weak var errorLabel: NSTextField!
  68. @IBOutlet weak var errorLabelTopLayout: NSLayoutConstraint!
  69. @IBOutlet weak var paymentMethodLabel: NSTextField!
  70. @IBOutlet weak var paypalButton: NSButton!
  71. @IBOutlet weak var cardButton: NSButton!
  72. @IBOutlet weak var wechatPayButton: NSButton!
  73. @IBOutlet weak var alipayButton: NSButton!
  74. @IBOutlet weak var wechatPayButton2: NSButton!
  75. @IBOutlet weak var payBox: NSBox!
  76. @IBOutlet weak var payBoxHeight: NSLayoutConstraint!
  77. @IBOutlet weak var payExplainLabel: NSTextField!
  78. @IBOutlet var paypalView: NSView!
  79. @IBOutlet weak var paypalBox: NSBox!
  80. @IBOutlet weak var paypalBuyNowLabel: NSTextField!
  81. @IBOutlet var cardView: NSView!
  82. @IBOutlet var paddleView: NSView!
  83. @IBOutlet weak var paddleButton: NSButton!
  84. @IBOutlet weak var paddlePopUpButton: KMPopUpButton!
  85. @IBOutlet weak var paddleBox: NSBox!
  86. @IBOutlet weak var paddleTextField: NSTextField!
  87. @IBOutlet var weChatPayView: NSView!
  88. @IBOutlet weak var weChatBox: NSBox!
  89. @IBOutlet weak var weChatButton: NSButton!
  90. @IBOutlet var payResult: NSView!
  91. @IBOutlet weak var scanLabel: NSTextField!
  92. @IBOutlet weak var qrCodeImageView: NSImageView!
  93. @IBOutlet weak var payTypeImageView: NSImageView!
  94. @IBOutlet weak var successfullyView: NSView!
  95. @IBOutlet weak var purchasedLabel: NSTextField!
  96. @IBOutlet weak var successfullyLabel: NSTextField!
  97. private var pdfCount: Int = 1
  98. private var _paymentMethod: KMPaymentType = .paypal
  99. private var _productType: ProductType = .ipaConvert
  100. private var productID: String = "com.brother.pdfreaderpro.mac.product_2"
  101. private var originalProductID: String = "com.brother.pdfreaderpro.mac.product_1"
  102. var couponCode: String = "" //优惠卷
  103. private var discountAmount: String = "" // 优惠金额
  104. private var discountScale: String = "" // 优惠比例
  105. private var orderID: String = "" // 订单ID
  106. private var timer: Timer?
  107. private var pollCount = 0
  108. private let maxPolls = 18
  109. private let interval: TimeInterval = 5
  110. private let countryKeys = [
  111. "Afghanistan", "Aland Islands", "Albania", "Algeria", "American Samoa",
  112. "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina",
  113. "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas",
  114. "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize",
  115. "Benin", "Bermuda", "Bhutan", "Bolivia", "Bonaire, Sint Eustatius and Saba",
  116. "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
  117. "Brit. Indian Ocean", "British Virgin Islands", "Brunei Darussalam", "Bulgaria",
  118. "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde",
  119. "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
  120. "Christmas Island", "Cocos Islands", "Colombia", "Comoros", "Congo",
  121. "Cook Islands", "Costa Rica", "Cote D'Ivoire", "Croatia", "Curaçao", "Cyprus",
  122. "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
  123. "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia",
  124. "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France",
  125. "French Guiana", "French Polynesia", "French Southern Terr.", "Gabon", "Gambia",
  126. "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada",
  127. "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea-Bissau",
  128. "Guyana", "Haiti", "Heard/ Mcdonald Islands", "Holy See/ Vatican City", "Honduras",
  129. "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iraq", "Ireland",
  130. "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan",
  131. "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Lao People's DR",
  132. "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein",
  133. "Lithuania", "Luxembourg", "Macao", "Macedonia", "Madagascar", "Malawi",
  134. "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique",
  135. "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
  136. "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique",
  137. "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles",
  138. "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue",
  139. "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan",
  140. "Palau", "Palestinian Territory", "Panama", "Papua New Guinea", "Paraguay",
  141. "Peru", "Philippines", "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar",
  142. "Republic of Serbia", "Reunion", "Romania", "Russian Federation", "Rwanda",
  143. "S. Georgia/ Sandwich Islands", "Saint Helena", "Saint Kitts and Nevis",
  144. "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent/ Grenadines",
  145. "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal",
  146. "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
  147. "Somalia", "South Africa", "South Korea", "Spain", "Sri Lanka", "Sudan",
  148. "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Taiwan",
  149. "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tokelau", "Tonga",
  150. "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands",
  151. "Tuvalu", "U.S. Virgin Islands", "Uganda", "Ukraine", "United Arab Emirates",
  152. "United Kingdom", "United States", "United States (M.O.I.)", "Uruguay", "Uzbekistan",
  153. "Vanuatu", "Venezuela", "Viet Nam", "Wallis and Futuna", "Western Sahara", "Yemen",
  154. "Zambia", "Zimbabwe"
  155. ]
  156. private let countryAbbreviationValues = [
  157. "AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB",
  158. "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "VG", "BN", "BG", "BF", "BI", "KH",
  159. "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CK", "CR", "CI", "HR", "CW", "CY",
  160. "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF",
  161. "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM",
  162. "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI",
  163. "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT",
  164. "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL",
  165. "AN", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH",
  166. "PN", "PL", "PT", "PR", "QA", "RS", "RE", "RO", "RU", "RW", "GS", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM",
  167. "ST", "SA", "SN", "SC", "SL", "SG", "SK", "SI", "SB", "SO", "ZA", "KR", "ES", "LK", "SD", "SR", "SJ", "SZ", "SE",
  168. "CH", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "VI", "UG", "UA", "AE",
  169. "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "WF", "EH", "YE", "ZM", "ZW"
  170. ]
  171. private var handler: ((Int) -> Void)!
  172. static var currentWindowController: KMPurchaseEmbeddedWindowController!
  173. private var embeddedPaymentPopWC: KMEmbeddedPaymentPopWC?
  174. @objc static func currentFirstTrialWC(_ productId: String) -> KMPurchaseEmbeddedWindowController {
  175. if currentWindowController != nil {
  176. currentWindowController.productID = productId
  177. return currentWindowController
  178. } else {
  179. let configWC: KMPurchaseEmbeddedWindowController = KMPurchaseEmbeddedWindowController.init(windowNibName: "KMPurchaseEmbeddedWindowController")
  180. currentWindowController = configWC;
  181. currentWindowController.productID = productId
  182. return currentWindowController
  183. }
  184. }
  185. override func windowDidLoad() {
  186. super.windowDidLoad()
  187. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
  188. productType = self.productToType(productID)
  189. originalProductID = productID
  190. if couponCode.count > 0 {
  191. coupomTextField.stringValue = couponCode
  192. }
  193. xibInitialization()
  194. paymentMethod = .paypal
  195. priceRefresh()
  196. confirmPayment(isConfirm: false)
  197. self.window?.delegate = self;
  198. }
  199. override func close() {
  200. super.close()
  201. self.clearEventData()
  202. }
  203. // MARK: UI
  204. private func xibInitialization() -> Void {
  205. yourOrderLabel.stringValue = NSLocalizedString("Your Order", comment: "")
  206. yourOrderLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  207. yourOrderLabel.font = NSFont.SFProTextBoldFont(20.0)
  208. pdfReaderProLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  209. pdfReaderProLabel.font = NSFont.SFProTextRegularFont(14.0)
  210. prmiumLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  211. prmiumLabel.font = NSFont.SFProTextRegularFont(12.0)
  212. oneLicenseLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  213. oneLicenseLabel.font = NSFont.SFProTextRegularFont(12.0)
  214. originalPriceLabel1.textColor = NSColor(named: "KMPurchaseTitleColor")
  215. originalPriceLabel1.font = NSFont.SFProTextRegularFont(16.0)
  216. discountPriceLabel1.textColor = NSColor(named: "KMPurchaseDiscountColor")
  217. discountPriceLabel1.font = NSFont.SFProTextRegularFont(9.0)
  218. if productType == .ipaConvert || productType == .ipaAI {
  219. aiAddOnView.isHidden = true
  220. extendedView.isHidden = true
  221. if productType == .ipaConvert {
  222. pdfReaderProLabel.stringValue = NSLocalizedString("PDF to Office", comment: "")
  223. prmiumLabel.stringValue = NSLocalizedString("Export PDF to Word(.docx), Excel (.xlsx), PowerPoint(.pptx) and more offline. It's one time purchase.", comment: "")
  224. oneLicenseLabel.isHidden = true
  225. } else if productType == .ipaAI {
  226. pdfReaderProLabel.stringValue = NSLocalizedString("PDF Reader Pro AI Tools", comment: "")
  227. prmiumLabel.stringValue = NSLocalizedString("50 credits for 30 days", comment: "")
  228. oneLicenseLabel.stringValue = NSLocalizedString("Manually renew at USD 14.99", comment: "")
  229. }
  230. } else {
  231. pdfReaderProLabel.stringValue = NSLocalizedString("PDF Reader Pro for Mac", comment: "")
  232. prmiumLabel.stringValue = NSLocalizedString("Premium and PDF to Office Converter", comment: "")
  233. oneLicenseLabel.stringValue = NSLocalizedString("One License for One Mac. One Time Purchase.", comment: "")
  234. aiAddOnButton.image = NSImage(named: "EmbeddedPayment06")
  235. aiAddOnLabel.stringValue = NSLocalizedString("AI Add-on", comment: "")
  236. aiAddOnLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  237. aiAddOnLabel.font = NSFont.SFProTextRegularFont(14.0)
  238. IndividualLabel.stringValue = NSLocalizedString("Individual monthly plan. Manually renew.", comment: "")
  239. IndividualLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  240. IndividualLabel.font = NSFont.SFProTextRegularFont(12.0)
  241. originalPriceLabel2.textColor = NSColor(named: "KMPurchaseTitleColor")
  242. originalPriceLabel2.font = NSFont.SFProTextRegularFont(16.0)
  243. discountPriceLabel2.textColor = NSColor(named: "KMPurchaseDiscountColor")
  244. discountPriceLabel2.font = NSFont.SFProTextRegularFont(9.0)
  245. if originalProductID == "com.brother.pdfreaderpro.mac.product_3" {
  246. extendedLabel.stringValue = NSLocalizedString("Extended Device Access", comment: "")
  247. accessLabel.stringValue = NSLocalizedString("Get access to your plan on up to 2 devices. (Mac or Windows)", comment: "")
  248. extendedImageView.isHidden = false
  249. } else {
  250. extendedLabel.stringValue = NSLocalizedString("PDF to Office Pack", comment: "")
  251. accessLabel.stringValue = NSLocalizedString("One time purchase", comment: "")
  252. extendedImageView.isHidden = true
  253. }
  254. extendedButton.image = NSImage(named: "EmbeddedPayment06")
  255. extendedLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  256. extendedLabel.font = NSFont.SFProTextRegularFont(14.0)
  257. accessLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  258. accessLabel.font = NSFont.SFProTextRegularFont(12.0)
  259. originalPriceLabel3.textColor = NSColor(named: "KMPurchaseTitleColor")
  260. originalPriceLabel3.font = NSFont.SFProTextRegularFont(16.0)
  261. discountPriceLabel3.textColor = NSColor(named: "KMPurchaseDiscountColor")
  262. discountPriceLabel3.font = NSFont.SFProTextRegularFont(9.0)
  263. }
  264. removeButton1.isEnabled = false
  265. amountTextField1.delegate = self
  266. amountTextField2.isEditable = false
  267. amountTextField3.isEditable = false
  268. amountView2.isHidden = true
  269. amountView3.isHidden = true
  270. couponButton.title = NSLocalizedString("I have a coupon?", comment: "")
  271. couponButton.setTitleColor(color: NSColor(named: "KMPurchaseCouponColor")!, font: NSFont.SFProTextRegularFont(14))
  272. coupomTextField.placeholderString = NSLocalizedString("Enter your coupon code and Apply it", comment: "")
  273. applyButton.title = NSLocalizedString("Apply", comment: "")
  274. applyButton.setTitleColor(color: NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black, font: NSFont.SFProTextRegularFont(13))
  275. couponBox.isHidden = true
  276. couponBox.borderColor = NSColor(named: "KMPurchaseCouponBoxColor") ?? NSColor.gray
  277. couponBox.fillColor = NSColor(named: "KMPurchaseCouponBoxFillColor") ?? NSColor.gray
  278. applyBox.isHidden = true
  279. applyBox.borderColor = NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black
  280. lastPriceLabel.stringValue = NSLocalizedString("List Price", comment: "")
  281. lastPriceLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  282. lastPriceLabel.font = NSFont.SFProTextRegularFont(16.0)
  283. discountLabel.stringValue = NSLocalizedString("Discount", comment: "")
  284. discountLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  285. discountLabel.font = NSFont.SFProTextRegularFont(16.0)
  286. paySumLabel.stringValue = NSLocalizedString("Pay sum", comment: "")
  287. paySumLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  288. paySumLabel.font = NSFont.SFProTextBoldFont(24.0)
  289. paySumLabel1.textColor = NSColor(named: "KMPurchaseCouponColor")
  290. paySumLabel1.font = NSFont.SFProTextBoldFont(24.0)
  291. privacyLabel.isEditable = false
  292. privacyLabel.isSelectable = true
  293. privacyLabel.allowsEditingTextAttributes = true
  294. privacyLabel.textColor = NSColor.black
  295. privacyLabel.font = NSFont.SFProTextRegularFont(16.0)
  296. let tipsString = NSLocalizedString("Are you a student or a professor? %@ / Want a volume purchase? Please %@.", comment: "")
  297. let specialOffer = NSLocalizedString("Get Special Offer", comment: "")
  298. let contactsUs = NSLocalizedString("Contact Us", comment: "")
  299. let fullString = String(format: tipsString, specialOffer, contactsUs)
  300. let attributedString = NSMutableAttributedString(string: fullString)
  301. // 定义链接的范围
  302. let specialOfferRange = (fullString as NSString).range(of: specialOffer)
  303. let contactsUsRange = (fullString as NSString).range(of: contactsUs)
  304. let linkColor = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  305. let font = NSFont.SFProTextRegularFont(16.0) // 与普通文本相同的字体
  306. attributedString.addAttributes([
  307. .foregroundColor: linkColor,
  308. .link: NSLocalizedString("https://www.pdfreaderpro.com/store?mode=edu", comment: ""),
  309. .font: font
  310. ], range: specialOfferRange)
  311. attributedString.addAttributes([
  312. .foregroundColor: linkColor,
  313. .link: NSLocalizedString("https://www.pdfreaderpro.com/vpp-purchase-program", comment: ""),
  314. .font: font
  315. ], range: contactsUsRange)
  316. attributedString.addAttribute(.font, value: font, range: (fullString as NSString).range(of: fullString))
  317. privacyLabel.attributedStringValue = attributedString
  318. billInformationLabel.stringValue = NSLocalizedString("Bill Information", comment: "")
  319. billInformationLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  320. billInformationLabel.font = NSFont.SFProTextRegularFont(14.0)
  321. emailLabel.stringValue = NSLocalizedString("Email", comment: "")
  322. emailLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  323. emailLabel.font = NSFont.SFProTextRegularFont(14.0)
  324. emailTextField.placeholderString = NSLocalizedString("Email to receive license code", comment: "")
  325. errorLabel.stringValue = NSLocalizedString("Please enter the email address number to receive the sequence code", comment: "")
  326. if VerificationManager.default().email != nil {
  327. emailTextField.stringValue = VerificationManager.default().email
  328. }
  329. errorLabel.textColor = NSColor(named: "KMPurchaseErrorColor")
  330. errorLabel.font = NSFont.SFProTextRegularFont(11.0)
  331. emailErrorLabel(isReveal: false)
  332. paymentMethodLabel.stringValue = NSLocalizedString("Payment Method", comment: "")
  333. paymentMethodLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  334. paymentMethodLabel.font = NSFont.SFProTextRegularFont(14.0)
  335. wechatPayButton2.isHidden = true
  336. payExplainLabel.isEditable = false
  337. payExplainLabel.isSelectable = true
  338. payExplainLabel.allowsEditingTextAttributes = true
  339. payExplainLabel.textColor = NSColor.black
  340. payExplainLabel.font = NSFont.SFProTextRegularFont(11.0)
  341. let localizedString = NSLocalizedString("By submitting this order, I agree to the %@ and %@ for subscription products", comment: "")
  342. let privacyPolicy = NSLocalizedString("Privacy Policy", comment: "")
  343. let termsOfService = NSLocalizedString("Terms of Service", comment: "")
  344. let fullString1 = String(format: localizedString, privacyPolicy, termsOfService)
  345. let attributedString1 = NSMutableAttributedString(string: fullString1)
  346. let privacyPolicyRange = (fullString1 as NSString).range(of: privacyPolicy)
  347. let termsOfServiceRange = (fullString1 as NSString).range(of: termsOfService)
  348. let linkColor1 = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  349. let font1 = NSFont.SFProTextRegularFont(11.0) // 与普通文本相同的字体
  350. attributedString1.addAttributes([
  351. .foregroundColor: linkColor1,
  352. .link: NSLocalizedString("https://www.pdfreaderpro.com/privacy-policy", comment: ""),
  353. .font: font1
  354. ], range: privacyPolicyRange)
  355. attributedString1.addAttributes([
  356. .foregroundColor: linkColor1,
  357. .link: NSLocalizedString("https://www.pdfreaderpro.com/terms_of_service", comment: ""),
  358. .font: font1
  359. ], range: termsOfServiceRange)
  360. attributedString1.addAttribute(.font, value: font1, range: (fullString1 as NSString).range(of: fullString1))
  361. payExplainLabel.attributedStringValue = attributedString1
  362. paypalBuyNowLabel.stringValue = NSLocalizedString("Buy Now", comment: "")
  363. paypalBuyNowLabel.textColor = NSColor.white
  364. paypalBuyNowLabel.font = NSFont.SFProTextBoldFont(16.0)
  365. paddleButton.title = NSLocalizedString("Continue to Pay", comment: "")
  366. paddleButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  367. paddlePopUpButton.type = .arrowDown
  368. paddlePopUpButton.removeAllItems()
  369. paddlePopUpButton.addItems(withTitles: countryKeys)
  370. let preferredLanguage = Locale.preferredLanguages.first ?? "en"
  371. if preferredLanguage.hasPrefix("zh-Hans") || preferredLanguage.hasPrefix("zh-Hant") {
  372. paddlePopUpButton.selectItem(at: 45)
  373. } else {
  374. paddlePopUpButton.selectItem(at: 229)
  375. }
  376. paddlePopUpButton.wantsLayer = true
  377. paddlePopUpButton.layer?.backgroundColor = NSColor(named: "KMPurchase_FFFFFF")?.cgColor
  378. paddlePopUpButton.layer?.borderColor = NSColor(named: "KMPurchase_DADBDE")?.cgColor
  379. paddleBox.fillColor = NSColor(named: "KMPurchase_FFFFFF") ?? NSColor.white
  380. paddleBox.borderColor = NSColor(named: "KMPurchase_DADBDE") ?? NSColor.gray
  381. paddleTextField.delegate = self
  382. weChatButton.title = NSLocalizedString("Continue to Pay", comment: "")
  383. weChatButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  384. qrCodeImageView.imageScaling = .scaleProportionallyUpOrDown
  385. scanLabel.textColor = NSColor(named: "KMPurchase_000000")
  386. scanLabel.font = NSFont.SFProTextRegularFont(12)
  387. successfullyView.isHidden = true
  388. purchasedLabel.stringValue = NSLocalizedString("Purchased", comment: "")
  389. purchasedLabel.textColor = NSColor(named: "KMPurchase_002143")
  390. purchasedLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  391. successfullyLabel.stringValue = NSLocalizedString("Successfully", comment: "")
  392. successfullyLabel.textColor = NSColor(named: "KMPurchase_002143")
  393. successfullyLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  394. }
  395. private func priceRefresh() -> Void {
  396. if KMDMGProductsManager.shareInstance.productDatas == nil {
  397. let alert = NSAlert()
  398. alert.alertStyle = .critical
  399. alert.messageText = NSLocalizedString("Connection Error", comment: "")
  400. alert.informativeText = NSLocalizedString("Please make sure your internet connection is available.", comment: "")
  401. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  402. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  403. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  404. } else {
  405. alert.runModal()
  406. }
  407. return
  408. }
  409. var abbreviation = "USD"
  410. if NSLocalizedString("USD", comment: "") == "CNY" {
  411. abbreviation = "CNY"
  412. }
  413. var discount1: Float = 0.0
  414. var original1: Float = 0.0
  415. var discount2: Float = 0.0
  416. var original2: Float = 0.0
  417. var discount3: Float = 0.0
  418. var original3: Float = 0.0
  419. var listPrice: Float = 0.0
  420. var discount: Float = 0.0
  421. var paySum: Float = 0.0
  422. let originalType: ProductType = productToType(originalProductID)
  423. if originalType == .ipaConvert || originalType == .ipaAI {
  424. if originalType == .ipaConvert {
  425. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2")) ?? 19.99
  426. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2")) ?? 19.99
  427. } else {
  428. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  429. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  430. }
  431. listPrice = original1 * Float(amountTextField1.stringValue)!
  432. paySum = discount1 * Float(amountTextField1.stringValue)!
  433. discount = listPrice - paySum
  434. originalPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount1))
  435. if String(format: "%.2f", original1) == String(format: "%.2f", discount1) {
  436. discountPriceLabel1.isHidden = true
  437. } else {
  438. discountPriceLabel1.isHidden = false
  439. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original1))
  440. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  441. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  442. discountPriceLabel1.attributedStringValue = attributedString
  443. }
  444. } else {
  445. if productType == .ipaPremium {
  446. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  447. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  448. discount2 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  449. original2 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  450. discount1 = aiBinding_discount - discount2
  451. original1 = aiBinding_original - original2
  452. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  453. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  454. listPrice = (original1 * Float(amountTextField1.stringValue)!)
  455. paySum = (discount1 * Float(amountTextField1.stringValue)!)
  456. discount = listPrice - paySum
  457. } else if productType == .ipaPermanent {
  458. if originalType == .ipaPremium {
  459. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  460. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  461. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  462. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  463. discount1 = paySum - discount3
  464. original1 = listPrice - original3
  465. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  466. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  467. let advanced_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  468. let advanced_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  469. discount2 = aiBinding_discount - advanced_discount
  470. original2 = aiBinding_original - advanced_original
  471. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  472. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  473. discount = listPrice - paySum
  474. } else if originalType == .ipaPermanent {
  475. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  476. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  477. discount1 = paySum
  478. original1 = listPrice
  479. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  480. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  481. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  482. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  483. discount2 = aiBinding_discount - discount1
  484. original2 = aiBinding_original - original1
  485. discount3 = cross_discount - discount1
  486. original3 = cross_original - original1
  487. listPrice = (original1 * Float(amountTextField1.stringValue)!)
  488. paySum = (discount1 * Float(amountTextField1.stringValue)!)
  489. discount = listPrice - paySum
  490. }
  491. } else if productType == .ipaPremiumCrossPlatform {
  492. } else if productType == .ipaPermanentCrossPlatform {
  493. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  494. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  495. discount1 = paySum
  496. original1 = listPrice
  497. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  498. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  499. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  500. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  501. discount2 = aiBinding_discount - discount1
  502. original2 = aiBinding_original - original1
  503. discount3 = cross_discount - discount1
  504. original3 = cross_original - original1
  505. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  506. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  507. discount = listPrice - paySum
  508. } else if productType == .ipaPremiumAI {
  509. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  510. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  511. discount2 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  512. original2 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  513. discount1 = aiBinding_discount - discount2
  514. original1 = aiBinding_original - original2
  515. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  516. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  517. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!)
  518. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!)
  519. discount = listPrice - paySum
  520. } else if productType == .ipaPermanentAI {
  521. if originalType == .ipaPremium {
  522. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  523. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  524. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  525. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  526. discount1 = paySum - discount3
  527. original1 = listPrice - original3
  528. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  529. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  530. let advanced_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  531. let advanced_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  532. discount2 = aiBinding_discount - advanced_discount
  533. original2 = aiBinding_original - advanced_original
  534. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  535. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  536. discount = listPrice - paySum
  537. } else if originalType == .ipaPermanent {
  538. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  539. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  540. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  541. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  542. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  543. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  544. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  545. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  546. discount2 = aiBinding_discount - discount1
  547. original2 = aiBinding_original - original1
  548. discount3 = cross_discount - discount1
  549. original3 = cross_original - original1
  550. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!)
  551. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!)
  552. discount = listPrice - paySum
  553. }
  554. } else if productType == .ipaPermanentCrossPlatformAI {
  555. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 149.96
  556. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 149.96
  557. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  558. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  559. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  560. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  561. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  562. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  563. discount2 = aiBinding_discount - discount1
  564. original2 = aiBinding_original - original1
  565. discount3 = cross_discount - discount1
  566. original3 = cross_original - original1
  567. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  568. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  569. discount = listPrice - paySum
  570. }
  571. originalPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount1))
  572. if String(format: "%.2f", original1) == String(format: "%.2f", discount1) {
  573. discountPriceLabel1.isHidden = true
  574. } else {
  575. discountPriceLabel1.isHidden = false
  576. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original1))
  577. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  578. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  579. discountPriceLabel1.attributedStringValue = attributedString
  580. }
  581. originalPriceLabel2.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount2))
  582. if String(format: "%.2f", original2) == String(format: "%.2f", discount2) {
  583. discountPriceLabel2.isHidden = true
  584. } else {
  585. discountPriceLabel2.isHidden = false
  586. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original2))
  587. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  588. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  589. discountPriceLabel2.attributedStringValue = attributedString
  590. }
  591. originalPriceLabel3.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount3))
  592. if String(format: "%.2f", original3) == String(format: "%.2f", discount3) {
  593. discountPriceLabel3.isHidden = true
  594. } else {
  595. discountPriceLabel3.isHidden = false
  596. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original3))
  597. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  598. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  599. discountPriceLabel3.attributedStringValue = attributedString
  600. }
  601. }
  602. if self.discountScale != "" || self.discountAmount != "" {
  603. if self.discountScale != "" {
  604. paySum = paySum * Float(self.discountScale)!
  605. discount = listPrice - paySum
  606. } else {
  607. var discountAmountF = Float(self.discountAmount)
  608. if NSLocalizedString("USD", comment: "") == "CNY" {
  609. discountAmountF = discountAmountF! * 6.5
  610. }
  611. paySum = paySum - discountAmountF!
  612. discount = listPrice - paySum
  613. }
  614. }
  615. lastPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", listPrice))
  616. discountLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount))
  617. paySumLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", paySum))
  618. if discount == 0 {
  619. discountView.isHidden = true
  620. discountLayoutConstraint.constant = discountView.isHidden ? -CGRectGetHeight(discountView.bounds) : 8
  621. }
  622. }
  623. // MARK: Active
  624. @IBAction func amountButtonAction(_ sender: NSButton) {
  625. if sender.tag == 0 || sender.tag == 1 {
  626. if sender.tag == 0 {
  627. if pdfCount > 1 {
  628. pdfCount -= 1
  629. }
  630. }
  631. if sender.tag == 1 {
  632. if pdfCount < 9999 {
  633. pdfCount += 1
  634. }
  635. }
  636. if pdfCount > 1 {
  637. removeButton1.isEnabled = true
  638. } else {
  639. removeButton1.isEnabled = false
  640. }
  641. if pdfCount > 100 {
  642. wechatPayButton2.isHidden = false
  643. cardButton.isHidden = true
  644. wechatPayButton.isHidden = true
  645. if _paymentMethod == .paddle {
  646. paymentMethod = .paypal
  647. }
  648. } else {
  649. wechatPayButton2.isHidden = true
  650. cardButton.isHidden = false
  651. wechatPayButton.isHidden = false
  652. }
  653. amountTextField1.stringValue = String(pdfCount)
  654. if extendedButton.state == .on {
  655. amountTextField2.stringValue = String(pdfCount * 2)
  656. } else {
  657. amountTextField2.stringValue = String(pdfCount * 1)
  658. }
  659. amountTextField3.stringValue = String(pdfCount)
  660. }
  661. // 价格刷新
  662. priceRefresh()
  663. }
  664. @IBAction func aiAddOnButtonAction(_ sender: NSButton) {
  665. let type: ProductType = productToType(originalProductID)
  666. aiAddOnButton.state = sender.state
  667. if sender.state == .on {
  668. amountView2.isHidden = false
  669. aiAddOnButton.image = NSImage(named: "EmbeddedPayment07")
  670. if extendedButton.state == .on {
  671. if type == .ipaPremium {
  672. productType = .ipaPermanentAI
  673. } else if type == .ipaPermanent {
  674. productType = .ipaPermanentCrossPlatformAI
  675. }
  676. } else {
  677. if type == .ipaPremium {
  678. productType = .ipaPremiumAI
  679. } else if type == .ipaPermanent {
  680. productType = .ipaPermanentAI
  681. }
  682. }
  683. } else {
  684. amountView2.isHidden = true
  685. aiAddOnButton.image = NSImage(named: "EmbeddedPayment06")
  686. if extendedButton.state == .on {
  687. if type == .ipaPremium {
  688. productType = .ipaPermanent
  689. } else if type == .ipaPermanent {
  690. productType = .ipaPermanentCrossPlatform
  691. }
  692. } else {
  693. if type == .ipaPremium {
  694. productType = .ipaPremium
  695. } else if type == .ipaPermanent {
  696. productType = .ipaPermanent
  697. }
  698. }
  699. }
  700. // 价格刷新
  701. priceRefresh()
  702. }
  703. @IBAction func extendedButtonAction(_ sender: NSButton) {
  704. let type: ProductType = productToType(originalProductID)
  705. extendedButton.state = sender.state
  706. if sender.state == .on {
  707. amountView3.isHidden = false
  708. if type == .ipaPremium {
  709. amountTextField2.stringValue = String(pdfCount)
  710. } else {
  711. amountTextField2.stringValue = String(pdfCount * 2)
  712. }
  713. extendedButton.image = NSImage(named: "EmbeddedPayment07")
  714. if aiAddOnButton.state == .on {
  715. if type == .ipaPremium {
  716. productType = .ipaPermanentAI
  717. } else if type == .ipaPermanent {
  718. productType = .ipaPermanentCrossPlatformAI
  719. }
  720. } else {
  721. if type == .ipaPremium {
  722. productType = .ipaPermanent
  723. } else if type == .ipaPermanent {
  724. productType = .ipaPermanentCrossPlatform
  725. }
  726. }
  727. } else {
  728. amountView3.isHidden = true
  729. amountTextField2.stringValue = String(pdfCount)
  730. extendedButton.image = NSImage(named: "EmbeddedPayment06")
  731. if aiAddOnButton.state == .on {
  732. if type == .ipaPremium {
  733. productType = .ipaPremiumAI
  734. } else if type == .ipaPermanent {
  735. productType = .ipaPermanentAI
  736. }
  737. } else {
  738. if type == .ipaPremium {
  739. productType = .ipaPremium
  740. } else if type == .ipaPermanent {
  741. productType = .ipaPermanent
  742. }
  743. }
  744. }
  745. // 价格刷新
  746. priceRefresh()
  747. }
  748. @IBAction func payButtonAction(_ sender: NSButton) {
  749. confirmPayment(isConfirm: false)
  750. paymentMethod = KMPaymentType(rawValue: uint32(sender.tag)) ?? .paypal
  751. }
  752. @IBAction func couponButtonAction(_ sender: NSButton) {
  753. couponButton.isHidden = true
  754. couponBox.isHidden = false
  755. applyBox.isHidden = false
  756. }
  757. @IBAction func applyButtonAction(_ sender: NSButton) {
  758. if coupomTextField.stringValue == "" {
  759. let alert = NSAlert()
  760. alert.alertStyle = .critical
  761. alert.messageText = NSLocalizedString("Coupon Error", comment: "")
  762. alert.informativeText = NSLocalizedString("Please enter the coupon.", comment: "")
  763. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  764. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  765. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  766. } else {
  767. alert.runModal()
  768. }
  769. return
  770. }
  771. self._getDiscount(productId: productID, discountId: coupomTextField.stringValue) { [weak self] info, err in
  772. guard let self = self else { return }
  773. if let dataInfo = info {
  774. if dataInfo.keys.contains("status") {
  775. let status = dataInfo["status"] as? String ?? ""
  776. if status == "" {
  777. let alert = NSAlert()
  778. alert.alertStyle = .critical
  779. alert.messageText = NSLocalizedString("Connection error", comment: "")
  780. alert.informativeText = NSLocalizedString("Promotional volume exception please try again.", comment: "")
  781. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  782. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  783. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  784. } else {
  785. alert.runModal()
  786. }
  787. return
  788. }
  789. if status == "unused" {
  790. if dataInfo["discount"] is NSNull && dataInfo["price"] is NSNull {
  791. let alert = NSAlert()
  792. alert.alertStyle = .critical
  793. alert.messageText = NSLocalizedString("Connection error", comment: "")
  794. alert.informativeText = NSLocalizedString("Non-concessionary amount.", comment: "")
  795. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  796. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  797. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  798. } else {
  799. alert.runModal()
  800. }
  801. return
  802. } else {
  803. if dataInfo["discount"] is NSNull {
  804. if dataInfo["price"] is NSNull {
  805. } else {
  806. if let price1 = dataInfo["price"] {
  807. self.discountAmount = String(format: "%@", price1 as! CVarArg)
  808. }
  809. }
  810. } else {
  811. if let discount1 = dataInfo["discount"] {
  812. self.discountScale = String(format: "%@", discount1 as! CVarArg)
  813. }
  814. }
  815. }
  816. }
  817. } else {
  818. if dataInfo["discount"] is NSNull && dataInfo["price"] is NSNull {
  819. let alert = NSAlert()
  820. alert.alertStyle = .critical
  821. alert.messageText = NSLocalizedString("Connection error", comment: "")
  822. alert.informativeText = NSLocalizedString("Non-concessionary amount.", comment: "")
  823. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  824. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  825. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  826. } else {
  827. alert.runModal()
  828. }
  829. return
  830. } else {
  831. if dataInfo["discount"] is NSNull {
  832. if dataInfo["price"] is NSNull {
  833. } else {
  834. if let price1 = dataInfo["price"] {
  835. self.discountAmount = String(format: "%@", price1 as! CVarArg)
  836. }
  837. }
  838. } else {
  839. if let discount1 = dataInfo["discount"] {
  840. self.discountScale = String(format: "%@", discount1 as! CVarArg)
  841. }
  842. }
  843. }
  844. }
  845. }
  846. self.priceRefresh()
  847. }
  848. }
  849. @IBAction func paddlePopUpAction(_ sender: NSPopUpButton) {
  850. buyAction(sender)
  851. }
  852. @IBAction func buyAction(_ sender: NSButton) {
  853. if emailTextField.stringValue == "" {
  854. // let alert = NSAlert()
  855. // alert.alertStyle = .critical
  856. // alert.messageText = NSLocalizedString("Connection Error", comment: "")
  857. // alert.informativeText = NSLocalizedString("The email address is empty.", comment: "")
  858. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  859. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  860. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  861. // } else {
  862. // alert.runModal()
  863. // }
  864. emailErrorLabel(isReveal: true)
  865. return
  866. }
  867. if paymentMethod == .paddle {
  868. if !isNumeric(paddleTextField.stringValue) && paddleTextField.stringValue != "" {
  869. let alert = NSAlert()
  870. alert.alertStyle = .critical
  871. alert.messageText = NSLocalizedString("Connection Error", comment: "")
  872. alert.informativeText = NSLocalizedString("Please enter the correct postcode.", comment: "")
  873. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  874. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  875. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  876. } else {
  877. alert.runModal()
  878. }
  879. return
  880. }
  881. }
  882. confirmPayment(isConfirm: true)
  883. if paymentMethod == .paypal {
  884. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  885. } else if paymentMethod == .paddle {
  886. paddleView.wantsLayer = true
  887. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor1")?.cgColor ?? NSColor.blue.cgColor
  888. } else if paymentMethod == .wxpay {
  889. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  890. } else if paymentMethod == .alipay {
  891. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  892. }
  893. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
  894. guard let self = self else { return }
  895. if self.paymentMethod == .paypal {
  896. self.paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  897. } else if _paymentMethod == .paddle {
  898. self.paddleView.wantsLayer = true
  899. self.paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  900. } else if _paymentMethod == .wxpay {
  901. self.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  902. } else if _paymentMethod == .alipay {
  903. self.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  904. }
  905. }
  906. var licenseCode = ""
  907. if let license = VerificationManager.default().originLicenseCode, license.count > 0 {
  908. licenseCode = license
  909. }
  910. self._buyProduct(productID, count: pdfCount, discountId: coupomTextField.stringValue, payment: paymentMethod, license: licenseCode, email: emailTextField.stringValue) { [weak self] info, err in
  911. guard let self = self else { return }
  912. if err != nil {return}
  913. if let dataInfo = info {
  914. self.orderID = dataInfo["trade_no"] as! String
  915. let page_pay_url = dataInfo["page_pay_url"] as! String
  916. if self.paymentMethod == .paddle || self.paymentMethod == .paypal {
  917. if page_pay_url != "" {
  918. self.openWebView(page_pay_url)
  919. }
  920. } else if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  921. if page_pay_url != "" {
  922. self.scanCode(page_pay_url)
  923. }
  924. }
  925. } else {
  926. // 数据错误
  927. }
  928. }
  929. }
  930. // MARK: get & set
  931. private var paymentMethod : KMPaymentType {
  932. get {
  933. return _paymentMethod
  934. }
  935. set {
  936. _paymentMethod = newValue
  937. paypalButton.image = NSImage(named: "EmbeddedPayment19")
  938. cardButton.image = NSImage(named: "EmbeddedPayment21")
  939. wechatPayButton.image = NSImage(named: "EmbeddedPayment23")
  940. wechatPayButton2.image = NSImage(named: "EmbeddedPayment23")
  941. alipayButton.image = NSImage(named: "EmbeddedPayment25")
  942. if _paymentMethod == .paypal {
  943. paypalButton.image = NSImage(named: "EmbeddedPayment18")
  944. payBox.contentView = paypalView
  945. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  946. payBoxHeight.constant = 60.0
  947. } else if _paymentMethod == .paddle {
  948. cardButton.image = NSImage(named: "EmbeddedPayment20")
  949. payBox.contentView = cardView
  950. paddleView.wantsLayer = true
  951. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  952. payBoxHeight.constant = 150.0
  953. } else if _paymentMethod == .wxpay {
  954. wechatPayButton.image = NSImage(named: "EmbeddedPayment22")
  955. wechatPayButton2.image = NSImage(named: "EmbeddedPayment22")
  956. payBox.contentView = weChatPayView
  957. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  958. payBoxHeight.constant = 92.0
  959. } else if _paymentMethod == .alipay {
  960. alipayButton.image = NSImage(named: "EmbeddedPayment24")
  961. payBox.contentView = weChatPayView
  962. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  963. payBoxHeight.constant = 92.0
  964. }
  965. }
  966. }
  967. var productType: ProductType {
  968. get {
  969. return _productType
  970. }
  971. set {
  972. _productType = newValue
  973. if _productType == .ipaConvert {
  974. productID = "com.brother.pdfreaderpro.mac.product_2"
  975. } else if _productType == .ipaConvert_checkout {
  976. productID = "com.brother.pdfreaderpro.mac.product_2.checkout"
  977. } else if _productType == .ipaPremium {
  978. productID = "com.brother.pdfreaderpro.mac.product_1"
  979. } else if _productType == .ipaPermanent {
  980. productID = "com.brother.pdfreaderpro.mac.product_3"
  981. } else if _productType == .ipaPremiumCrossPlatform {
  982. productID = "com.brother.pdfreaderpro.cross.platform.product_1"
  983. } else if _productType == .ipaPermanentCrossPlatform {
  984. productID = "com.brother.pdfreaderpro.cross.platform.product_3"
  985. } else if _productType == .ipaAI {
  986. productID = "com.brother.pdfreaderpro.ai.product_1"
  987. } else if _productType == .ipaPremiumAI {
  988. productID = "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1"
  989. } else if _productType == .ipaPermanentAI {
  990. productID = "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1"
  991. } else if _productType == .ipaPermanentCrossPlatformAI {
  992. productID = "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1"
  993. }
  994. }
  995. }
  996. // MARK: ——
  997. // 获取价格
  998. private func _getProductDatas(callback: @escaping (([String:Any]?, Any?)->Void)) {
  999. // func getPriceUrl() {
  1000. let urlString = kVerificationServer + "/api/product/get-price/v2"
  1001. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: nil) { task, responseObject, error in
  1002. if (error == nil && responseObject != nil) {
  1003. let array = responseObject?["data"] as? NSDictionary
  1004. if array != nil {
  1005. //解析数据
  1006. let productsDict = array?.object(forKey: "data") as? NSDictionary
  1007. callback(productsDict as? [String : Any], nil)
  1008. } else {
  1009. callback([:], error.debugDescription)
  1010. }
  1011. } else {
  1012. callback(nil, error.debugDescription)
  1013. }
  1014. }
  1015. }
  1016. // 获取优惠卷
  1017. private func _getDiscount(productId: String, discountId: String, callback: @escaping (([String : Any]?, Any?)->Void)) {
  1018. let urlString = kVerificationServer + "/api/coupons/retrieval"
  1019. let app_code = MainBundle.km_infoDictionary()?["CFBundleIdentifier"] ?? ""
  1020. let params = [
  1021. // 优惠卷id
  1022. "code" : discountId,
  1023. "app_code" : app_code,
  1024. "product_code" : productId]
  1025. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { task, responseObject, error in
  1026. if (error == nil && responseObject != nil) {
  1027. if let dataDict = responseObject?["data"] as? NSDictionary {
  1028. if let swiftDict = dataDict as? [String: Any] {
  1029. if swiftDict.keys.contains("price") || swiftDict.keys.contains("discount") {
  1030. callback(dataDict as? [String : Any], nil)
  1031. } else if swiftDict.keys.contains("coupon_provider") {
  1032. if let couponDict = swiftDict["coupon_provider"] as? [String: Any] {
  1033. callback(couponDict, nil)
  1034. }
  1035. }
  1036. }
  1037. } else if let coupon_provider = responseObject?["coupon_provider"] as? NSDictionary {
  1038. callback(coupon_provider as? [String : Any], nil)
  1039. } else {
  1040. callback([:], error.debugDescription)
  1041. }
  1042. } else {
  1043. callback(nil, error.debugDescription)
  1044. }
  1045. }
  1046. }
  1047. // 获取订单状态
  1048. private func _getOrderStatus(tradeNo: String, callback: @escaping (([String:Any]?, Any?)->Void)) {
  1049. let urlString = kVerificationServer + "/api/orders/getOrderStatus"
  1050. var jsonStr: String = ""
  1051. if let jsonData = try?JSONSerialization.data(withJSONObject: ["trade_no" : tradeNo], options:[]),
  1052. let data = String(data: jsonData, encoding: .utf8) {
  1053. jsonStr = data
  1054. }
  1055. let rsa = KMVerificationRSA()
  1056. let publicKey = rsa.loadPublicKey()
  1057. let encryptedData = rsa.encrypt(plainText: jsonStr, publicKey: publicKey!)
  1058. let tokenStr = encryptedData?.base64EncodedString()
  1059. var postData = try!JSONSerialization.data(withJSONObject: ["token" : tokenStr])
  1060. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  1061. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  1062. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  1063. request.httpMethod = "POST"
  1064. request.httpBody = postData
  1065. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  1066. guard let data = data else {
  1067. callback(nil, String(describing: error))
  1068. return
  1069. }
  1070. if let jsonDict = try?JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:] {
  1071. let dataStr = jsonDict["data"] as? String
  1072. let rsa = KMVerificationRSA()
  1073. if let deData = (rsa.decrypt(source: dataStr as? NSString ?? "") as? String)?.data(using: .utf8) {
  1074. if let dict = try?JSONSerialization.jsonObject(with: deData, options: []) as? NSDictionary ?? [:] {
  1075. return callback(dict as? [String : Any], nil)
  1076. }
  1077. }
  1078. callback([:], String(describing: error))
  1079. } else {
  1080. // 数据错误
  1081. callback([:], String(describing: error))
  1082. }
  1083. }
  1084. task.resume()
  1085. }
  1086. private func _buyProduct(_ productId: String, count: Int, discountId: String = "", payment: KMPaymentType, license: String = "", email: String, username: String = "", callback: @escaping (([String:Any]?, Any?)->Void)) {
  1087. let urlString = kVerificationServer + "/api/subscriptions"
  1088. let app_code = MainBundle.km_infoDictionary()?["CFBundleIdentifier"] ?? ""
  1089. let paymentStr = self._paymentTypeString(type: payment)
  1090. let country = countryAbbreviationValues[paddlePopUpButton.indexOfSelectedItem]
  1091. let postcode = paddleTextField.stringValue
  1092. let paraDict = ["data" :
  1093. ["product_code": productId,
  1094. "app_code": app_code,
  1095. // 购买数量
  1096. "amount": "\(count)",
  1097. // 优惠卷id
  1098. "coupon_code": discountId,
  1099. // 支付类型 paypal alipay wxpay paddle
  1100. "payment": paymentStr,
  1101. // 地区
  1102. "customer_country": country,
  1103. // 邮编码
  1104. "customer_postcode" : postcode,
  1105. "unique_sn" : uuid(),
  1106. // 序列码 标准包 升级 高级包 需要
  1107. "upgrade_cdkey" : license,
  1108. "email" : email,
  1109. // 用户名
  1110. "contact_name" : username,
  1111. "platform" : "DMG"]]
  1112. var postData = try! JSONSerialization.data(withJSONObject: paraDict)
  1113. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  1114. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  1115. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  1116. request.httpMethod = "POST"
  1117. request.httpBody = postData
  1118. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  1119. guard let theData = data else {
  1120. callback(nil, String(describing: error))
  1121. return
  1122. }
  1123. if let jsonDict = try? JSONSerialization.jsonObject(with: theData, options: []) as? NSDictionary ?? [:] {
  1124. let data1: NSDictionary = jsonDict["data"] as? NSDictionary ?? [:]
  1125. let subscriptionInfo = data1.object(forKey: "subscription") as? NSDictionary
  1126. let orderKey = self._paymentTypeString(type: payment) + "_order"
  1127. let order_info = subscriptionInfo?.object(forKey: orderKey) as? NSDictionary
  1128. if let dataInfo = order_info, dataInfo.count > 0 {
  1129. callback(dataInfo as? [String : Any], nil)
  1130. } else {
  1131. // 数据错误
  1132. callback([:], String(describing: error))
  1133. }
  1134. } else {
  1135. // 数据错误
  1136. callback([:], String(describing: error))
  1137. }
  1138. }
  1139. task.resume()
  1140. }
  1141. // MARK: Private
  1142. private func uuid() -> String {
  1143. return GetHardwareUUID()!
  1144. }
  1145. private func _paymentTypeString(type: KMPaymentType) -> String {
  1146. if type == .paddle {
  1147. return "paddle"
  1148. } else if type == .alipay {
  1149. return "alipay"
  1150. } else if type == .wxpay {
  1151. return "wxpay"
  1152. } else if type == .paypal {
  1153. return "paypal"
  1154. }
  1155. return ""
  1156. }
  1157. private func _trackEvent_paid() {
  1158. self.trackEvent_dmg(eventName: self.kEventName, params: self.kEventParams, platform: .firebase)
  1159. }
  1160. private let tabDict: [ProductType: String] = [
  1161. .ipaConvert: "com.brother.pdfreaderpro.mac.product_2",
  1162. .ipaConvert_checkout: "com.brother.pdfreaderpro.mac.product_2.checkout",
  1163. .ipaPremium: "com.brother.pdfreaderpro.mac.product_1",
  1164. .ipaPermanent: "com.brother.pdfreaderpro.mac.product_3",
  1165. .ipaPremiumCrossPlatform: "com.brother.pdfreaderpro.cross.platform.product_1",
  1166. .ipaPermanentCrossPlatform: "com.brother.pdfreaderpro.cross.platform.product_3",
  1167. .ipaAI: "com.brother.pdfreaderpro.ai.product_1",
  1168. .ipaPremiumAI: "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1",
  1169. .ipaPermanentAI: "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1",
  1170. .ipaPermanentCrossPlatformAI: "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1"
  1171. ]
  1172. private func getProductID() -> String {
  1173. return GetHardwareUUID()!
  1174. }
  1175. private func productToType(_ productId: String) -> ProductType {
  1176. if productId == "com.brother.pdfreaderpro.mac.product_2" {
  1177. return .ipaConvert
  1178. } else if productId == "com.brother.pdfreaderpro.mac.product_2.checkout" {
  1179. return .ipaConvert_checkout
  1180. } else if productId == "com.brother.pdfreaderpro.mac.product_1" {
  1181. return .ipaPremium
  1182. } else if productId == "com.brother.pdfreaderpro.mac.product_3" {
  1183. return .ipaPermanent
  1184. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_1" {
  1185. return .ipaPremiumCrossPlatform
  1186. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_3" {
  1187. return .ipaPermanentCrossPlatform
  1188. } else if productId == "com.brother.pdfreaderpro.ai.product_1" {
  1189. return .ipaAI
  1190. } else if productId == "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1" {
  1191. return .ipaPremiumAI
  1192. } else if productId == "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1" {
  1193. return .ipaPermanentAI
  1194. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1" {
  1195. return .ipaPermanentCrossPlatformAI
  1196. }
  1197. return .ipaConvert
  1198. }
  1199. private func isNumeric(_ text: String) -> Bool {
  1200. return !text.isEmpty && text.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
  1201. }
  1202. private func openWebView(_ urlPath: String) -> Void {
  1203. DispatchQueue.main.async { [weak self] in
  1204. guard let self = self else { return }
  1205. // let wc = KMEmbeddedPaymentPopWC.init(windowNibName: "KMEmbeddedPaymentPopWC")
  1206. self.embeddedPaymentPopWC = KMEmbeddedPaymentPopWC.currentFirstTrialWC(urlPath)
  1207. self.embeddedPaymentPopWC?.showWindow(nil)
  1208. self.embeddedPaymentPopWC?.callback = { isClose in
  1209. // let alert = NSAlert()
  1210. // alert.alertStyle = .critical
  1211. // alert.messageText = NSLocalizedString("Checking payment status", comment: "")
  1212. //// alert.informativeText = NSLocalizedString("Get License Code is empty.", comment: "")
  1213. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1214. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  1215. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  1216. // } else {
  1217. // alert.runModal()
  1218. // }
  1219. }
  1220. }
  1221. startPolling()
  1222. }
  1223. private func scanCode(_ urlPath: String) -> Void {
  1224. DispatchQueue.main.async { [weak self] in
  1225. guard let self = self else { return }
  1226. self.payBox.contentView = self.payResult
  1227. self.payBoxHeight.constant = 262
  1228. if self.paymentMethod == .wxpay {
  1229. self.scanLabel.stringValue = NSLocalizedString("Scan QR Code with WeChat", comment: "")
  1230. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment27")
  1231. } else if self.paymentMethod == .alipay {
  1232. self.scanLabel.stringValue = NSLocalizedString("Scan QR Code with AliPay", comment: "")
  1233. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment28")
  1234. }
  1235. if let url = URL(string: urlPath) {
  1236. URLSession.shared.dataTask(with: url) { data, response, error in
  1237. if let data = data, let image = NSImage(data: data) {
  1238. DispatchQueue.main.async {
  1239. self.qrCodeImageView.image = image
  1240. self.startPolling()
  1241. }
  1242. } else {
  1243. print("Failed to load image or there was an error: \(error?.localizedDescription ?? "Unknown error")")
  1244. }
  1245. }.resume()
  1246. } else {
  1247. print("Invalid URL.")
  1248. }
  1249. }
  1250. }
  1251. private func pollingResult() -> Void {
  1252. DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
  1253. guard let self = self else { return }
  1254. if self.orderID == "" { return }
  1255. self._getOrderStatus(tradeNo: self.orderID, callback: { info, err in
  1256. if let dataInfo = info {
  1257. if dataInfo.keys.contains("status") {
  1258. let status = dataInfo["status"] as? Int
  1259. if status == 2 {
  1260. self.orderID = ""
  1261. self.stopPolling()
  1262. if dataInfo.keys.contains("license") {
  1263. let license = dataInfo["license"] as? [String]
  1264. if license!.count > 0 {
  1265. self.verificationActivate(license: license![0])
  1266. self.embeddedPaymentPopWC?.close()
  1267. self.embeddedPaymentPopWC = nil
  1268. }
  1269. // else {
  1270. // let alert = NSAlert()
  1271. // alert.alertStyle = .critical
  1272. // alert.messageText = NSLocalizedString("Connection Error", comment: "")
  1273. // alert.informativeText = NSLocalizedString("Get License Code is empty.", comment: "")
  1274. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1275. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  1276. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  1277. // } else {
  1278. // alert.runModal()
  1279. // }
  1280. // return
  1281. // }
  1282. }
  1283. if dataInfo.keys.contains("ai_license") {
  1284. let ai_license = dataInfo["ai_license"] as? [String]
  1285. if ai_license!.count > 0 {
  1286. self.verificationActivateAIInfo(license: ai_license![0])
  1287. self.embeddedPaymentPopWC?.close()
  1288. self.embeddedPaymentPopWC = nil
  1289. }
  1290. // else {
  1291. // let alert = NSAlert()
  1292. // alert.alertStyle = .critical
  1293. // alert.messageText = NSLocalizedString("Connection Error", comment: "")
  1294. // alert.informativeText = NSLocalizedString("Get AI License Code is empty.", comment: "")
  1295. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1296. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  1297. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  1298. // } else {
  1299. // alert.runModal()
  1300. // }
  1301. // return
  1302. // }
  1303. }
  1304. } else {
  1305. self.startPolling()
  1306. }
  1307. }
  1308. }
  1309. })
  1310. }
  1311. }
  1312. private func startPolling() {
  1313. timer = Timer(timeInterval: interval, repeats: false) { [weak self] _ in
  1314. guard let self = self else { return }
  1315. self.performTask()
  1316. }
  1317. RunLoop.main.add(timer!, forMode: .common)
  1318. timer!.fire()
  1319. }
  1320. @objc private func performTask() {
  1321. guard pollCount < maxPolls else {
  1322. stopPolling()
  1323. return
  1324. }
  1325. // 执行你的轮询任务
  1326. print("Performing polling task \(pollCount + 1)/\(maxPolls)")
  1327. pollCount += 1
  1328. pollingResult()
  1329. }
  1330. private func stopPolling() {
  1331. timer?.invalidate()
  1332. timer = nil
  1333. print("Polling task completed.")
  1334. if self.embeddedPaymentPopWC != nil {
  1335. DispatchQueue.main.async { [weak self] in
  1336. guard let self = self else { return }
  1337. self.embeddedPaymentPopWC?.close()
  1338. self.embeddedPaymentPopWC = nil
  1339. }
  1340. }
  1341. pollCount = 0
  1342. }
  1343. private func verificationActivateAIInfo(license: String) {
  1344. guard !license.isEmpty else {
  1345. return
  1346. }
  1347. let infoDic = ["cdkey": license]
  1348. AIInfoManager.default().activateAI(withInfo: infoDic) { info, error in
  1349. if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  1350. self.qrCodeImageView.isHidden = true
  1351. self.successfullyView.isHidden = false
  1352. }
  1353. if info.isEmpty == false {
  1354. self._trackEvent_paid()
  1355. }
  1356. }
  1357. }
  1358. private func verificationActivate(license: String) {
  1359. guard !license.isEmpty else {
  1360. return
  1361. }
  1362. let infoDic = ["cdkey": license]
  1363. VerificationManager.default().activateDevice(withInfo: infoDic) { status, info, error in
  1364. if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  1365. self.qrCodeImageView.isHidden = true
  1366. self.successfullyView.isHidden = false
  1367. }
  1368. if let data = info, data.isEmpty == false {
  1369. self._trackEvent_paid()
  1370. }
  1371. }
  1372. }
  1373. private func confirmPayment(isConfirm: Bool) {
  1374. if isConfirm {
  1375. removeButton1.isEnabled = false
  1376. addButton1.isEnabled = false
  1377. aiAddOnButton1.isEnabled = false
  1378. extendedButton1.isEnabled = false
  1379. couponButton.isEnabled = false
  1380. coupomTextField.isEnabled = false
  1381. applyButton.isEnabled = false
  1382. } else {
  1383. removeButton1.isEnabled = true
  1384. addButton1.isEnabled = true
  1385. aiAddOnButton1.isEnabled = true
  1386. extendedButton1.isEnabled = true
  1387. couponButton.isEnabled = true
  1388. coupomTextField.isEnabled = true
  1389. applyButton.isEnabled = true
  1390. }
  1391. }
  1392. private func emailErrorLabel(isReveal: Bool) {
  1393. if isReveal {
  1394. errorLabel.isHidden = false
  1395. } else {
  1396. errorLabel.isHidden = true
  1397. }
  1398. errorLabelTopLayout.constant = errorLabel.isHidden ? -CGRectGetHeight(errorView.bounds) : 4
  1399. }
  1400. // MARK: Show Methods
  1401. // @IBAction private func dismissSheet(_ sender: NSButton) {
  1402. // NSApp.endSheet(window!)
  1403. // window!.orderOut(self)
  1404. // }
  1405. //
  1406. //
  1407. // @objc private func didEndSheet(_ sheet: NSWindow?, returnCode: Int, contextInfo: UnsafeMutableRawPointer?) {
  1408. // if contextInfo != nil && self.handler != nil {
  1409. // self.handler!(returnCode)
  1410. // }
  1411. // }
  1412. //
  1413. // @objc func beginSheetModal(for window: NSWindow?, completionHandler handler: ((Int) -> Void)?) {
  1414. // if window != nil {
  1415. // window!.beginSheet(self.window!) { ModalResponse in
  1416. // self.handler?(ModalResponse.rawValue)
  1417. // }
  1418. // }
  1419. // self.handler = handler
  1420. // }
  1421. }
  1422. extension KMPurchaseEmbeddedWindowController: NSTextFieldDelegate {
  1423. func controlTextDidEndEditing(_ obj: Notification) {
  1424. let textField = obj.object as? NSTextField
  1425. if textField == amountTextField1 {
  1426. if !isNumeric(textField!.stringValue) {
  1427. if textField == amountTextField1 { textField?.stringValue = String(pdfCount) }
  1428. } else {
  1429. if textField == amountTextField1 {
  1430. pdfCount = Int(textField!.stringValue) ?? 1
  1431. if Int(textField!.stringValue)! > 9999 {
  1432. pdfCount = 9999
  1433. textField?.stringValue = String(pdfCount)
  1434. }
  1435. }
  1436. if pdfCount > 100 {
  1437. wechatPayButton2.isHidden = false
  1438. cardButton.isHidden = true
  1439. wechatPayButton.isHidden = true
  1440. if _paymentMethod == .paddle {
  1441. paymentMethod = .paypal
  1442. }
  1443. } else {
  1444. wechatPayButton2.isHidden = true
  1445. cardButton.isHidden = false
  1446. wechatPayButton.isHidden = false
  1447. }
  1448. }
  1449. } else if textField == emailTextField {
  1450. emailErrorLabel(isReveal: false)
  1451. } else if textField == paddleTextField {
  1452. }
  1453. }
  1454. }
  1455. extension KMPurchaseEmbeddedWindowController: NSWindowDelegate {
  1456. func windowWillClose(_ notification: Notification) {
  1457. if orderID != "" {
  1458. pollingResult()
  1459. }
  1460. if self.embeddedPaymentPopWC != nil {
  1461. self.embeddedPaymentPopWC?.close()
  1462. self.embeddedPaymentPopWC = nil
  1463. }
  1464. KMPurchaseEmbeddedWindowController.currentWindowController = nil
  1465. }
  1466. }
  1467. #endif