KMPurchaseEmbeddedWindowController.swift 84 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568
  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. // private var discountId: 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. xibInitialization()
  191. paymentMethod = .paypal
  192. priceRefresh()
  193. confirmPayment(isConfirm: false)
  194. self.window?.delegate = self;
  195. }
  196. override func close() {
  197. super.close()
  198. self.clearEventData()
  199. }
  200. // MARK: UI
  201. private func xibInitialization() -> Void {
  202. yourOrderLabel.stringValue = NSLocalizedString("Your Order", comment: "")
  203. yourOrderLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  204. yourOrderLabel.font = NSFont.SFProTextBoldFont(20.0)
  205. pdfReaderProLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  206. pdfReaderProLabel.font = NSFont.SFProTextRegularFont(14.0)
  207. prmiumLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  208. prmiumLabel.font = NSFont.SFProTextRegularFont(12.0)
  209. oneLicenseLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  210. oneLicenseLabel.font = NSFont.SFProTextRegularFont(12.0)
  211. originalPriceLabel1.textColor = NSColor(named: "KMPurchaseTitleColor")
  212. originalPriceLabel1.font = NSFont.SFProTextRegularFont(16.0)
  213. discountPriceLabel1.textColor = NSColor(named: "KMPurchaseDiscountColor")
  214. discountPriceLabel1.font = NSFont.SFProTextRegularFont(9.0)
  215. if productType == .ipaConvert || productType == .ipaAI {
  216. aiAddOnView.isHidden = true
  217. extendedView.isHidden = true
  218. if productType == .ipaConvert {
  219. pdfReaderProLabel.stringValue = NSLocalizedString("PDF to Office", comment: "")
  220. prmiumLabel.stringValue = NSLocalizedString("Export PDF to Word(.docx), Excel (.xlsx), PowerPoint(.pptx) and more offline. It's one time purchase.", comment: "")
  221. oneLicenseLabel.isHidden = true
  222. } else if productType == .ipaAI {
  223. pdfReaderProLabel.stringValue = NSLocalizedString("PDF Reader Pro AI Tools", comment: "")
  224. prmiumLabel.stringValue = NSLocalizedString("50 credits for 30 days", comment: "")
  225. oneLicenseLabel.stringValue = NSLocalizedString("Manually renew at USD 14.99", comment: "")
  226. }
  227. } else {
  228. pdfReaderProLabel.stringValue = NSLocalizedString("I have a coupon ?", comment: "")
  229. prmiumLabel.stringValue = NSLocalizedString("Premium and PDF to Office Converter", comment: "")
  230. oneLicenseLabel.stringValue = NSLocalizedString("One License for One Mac. One Time Purchase.", comment: "")
  231. aiAddOnButton.image = NSImage(named: "EmbeddedPayment06")
  232. aiAddOnLabel.stringValue = NSLocalizedString("AI Add-on", comment: "")
  233. aiAddOnLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  234. aiAddOnLabel.font = NSFont.SFProTextRegularFont(14.0)
  235. IndividualLabel.stringValue = NSLocalizedString("Individual monthly plan. Manually renew.", comment: "")
  236. IndividualLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  237. IndividualLabel.font = NSFont.SFProTextRegularFont(12.0)
  238. originalPriceLabel2.textColor = NSColor(named: "KMPurchaseTitleColor")
  239. originalPriceLabel2.font = NSFont.SFProTextRegularFont(16.0)
  240. discountPriceLabel2.textColor = NSColor(named: "KMPurchaseDiscountColor")
  241. discountPriceLabel2.font = NSFont.SFProTextRegularFont(9.0)
  242. if originalProductID == "com.brother.pdfreaderpro.mac.product_3" {
  243. extendedLabel.stringValue = NSLocalizedString("Extended Device Access", comment: "")
  244. accessLabel.stringValue = NSLocalizedString("Get access to your plan on up to 2 devices. (Mac or Windows)", comment: "")
  245. extendedImageView.isHidden = false
  246. } else {
  247. extendedLabel.stringValue = NSLocalizedString("PDF to Office Pack", comment: "")
  248. accessLabel.stringValue = NSLocalizedString("One time purchase", comment: "")
  249. extendedImageView.isHidden = true
  250. }
  251. extendedButton.image = NSImage(named: "EmbeddedPayment06")
  252. extendedLabel.textColor = NSColor(named: "KMPurchaseTitleColor")
  253. extendedLabel.font = NSFont.SFProTextRegularFont(14.0)
  254. accessLabel.textColor = NSColor(named: "KMPurchaseSubTitleColor")
  255. accessLabel.font = NSFont.SFProTextRegularFont(12.0)
  256. originalPriceLabel3.textColor = NSColor(named: "KMPurchaseTitleColor")
  257. originalPriceLabel3.font = NSFont.SFProTextRegularFont(16.0)
  258. discountPriceLabel3.textColor = NSColor(named: "KMPurchaseDiscountColor")
  259. discountPriceLabel3.font = NSFont.SFProTextRegularFont(9.0)
  260. }
  261. removeButton1.isEnabled = false
  262. amountTextField1.delegate = self
  263. amountTextField2.isEditable = false
  264. amountTextField3.isEditable = false
  265. amountView2.isHidden = true
  266. amountView3.isHidden = true
  267. couponButton.title = NSLocalizedString("PDF Reader Pro for Mac", comment: "")
  268. couponButton.setTitleColor(color: NSColor(named: "KMPurchaseCouponColor")!, font: NSFont.SFProTextRegularFont(14))
  269. coupomTextField.placeholderString = NSLocalizedString("Enter your coupon code and Apply it", comment: "")
  270. applyButton.title = NSLocalizedString("Apply", comment: "")
  271. applyButton.setTitleColor(color: NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black, font: NSFont.SFProTextRegularFont(13))
  272. couponBox.isHidden = true
  273. couponBox.borderColor = NSColor(named: "KMPurchaseCouponBoxColor") ?? NSColor.gray
  274. couponBox.fillColor = NSColor(named: "KMPurchaseCouponBoxFillColor") ?? NSColor.gray
  275. applyBox.isHidden = true
  276. applyBox.borderColor = NSColor(named: "KMPurchaseApplyColor") ?? NSColor.black
  277. lastPriceLabel.stringValue = NSLocalizedString("List Price", comment: "")
  278. lastPriceLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  279. lastPriceLabel.font = NSFont.SFProTextRegularFont(16.0)
  280. discountLabel.stringValue = NSLocalizedString("Discount", comment: "")
  281. discountLabel.textColor = NSColor(named: "KMPurchaseListPriceColor")
  282. discountLabel.font = NSFont.SFProTextRegularFont(16.0)
  283. paySumLabel.stringValue = NSLocalizedString("Pay sum", comment: "")
  284. paySumLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  285. paySumLabel.font = NSFont.SFProTextBoldFont(24.0)
  286. paySumLabel1.textColor = NSColor(named: "KMPurchaseCouponColor")
  287. paySumLabel1.font = NSFont.SFProTextBoldFont(24.0)
  288. privacyLabel.isEditable = false
  289. privacyLabel.isSelectable = true
  290. privacyLabel.allowsEditingTextAttributes = true
  291. privacyLabel.textColor = NSColor.black
  292. privacyLabel.font = NSFont.SFProTextRegularFont(16.0)
  293. let tipsString = NSLocalizedString("Are you a student or a professor? %@ / Want a volume purchase? Please %@.", comment: "")
  294. let specialOffer = NSLocalizedString("Get Special Offer", comment: "")
  295. let contactsUs = NSLocalizedString("Contact Us", comment: "")
  296. let fullString = String(format: tipsString, specialOffer, contactsUs)
  297. let attributedString = NSMutableAttributedString(string: fullString)
  298. // 定义链接的范围
  299. let specialOfferRange = (fullString as NSString).range(of: specialOffer)
  300. let contactsUsRange = (fullString as NSString).range(of: contactsUs)
  301. let linkColor = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  302. let font = NSFont.SFProTextRegularFont(16.0) // 与普通文本相同的字体
  303. attributedString.addAttributes([
  304. .foregroundColor: linkColor,
  305. .link: NSLocalizedString("https://www.pdfreaderpro.com/store?mode=edu", comment: ""),
  306. .font: font
  307. ], range: specialOfferRange)
  308. attributedString.addAttributes([
  309. .foregroundColor: linkColor,
  310. .link: NSLocalizedString("https://www.pdfreaderpro.com/vpp-purchase-program", comment: ""),
  311. .font: font
  312. ], range: contactsUsRange)
  313. attributedString.addAttribute(.font, value: font, range: (fullString as NSString).range(of: fullString))
  314. privacyLabel.attributedStringValue = attributedString
  315. billInformationLabel.stringValue = NSLocalizedString("Bill Information", comment: "")
  316. billInformationLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  317. billInformationLabel.font = NSFont.SFProTextRegularFont(14.0)
  318. emailLabel.stringValue = NSLocalizedString("Email", comment: "")
  319. emailLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  320. emailLabel.font = NSFont.SFProTextRegularFont(14.0)
  321. emailTextField.placeholderString = NSLocalizedString("Email to receive license code", comment: "")
  322. errorLabel.stringValue = NSLocalizedString("Please enter the email address number to receive the sequence code", comment: "")
  323. if VerificationManager.default().email != nil {
  324. emailTextField.stringValue = VerificationManager.default().email
  325. }
  326. errorLabel.textColor = NSColor(named: "KMPurchaseErrorColor")
  327. errorLabel.font = NSFont.SFProTextRegularFont(11.0)
  328. errorLabel.isHidden = true
  329. errorLabelTopLayout.constant = -CGRectGetHeight(errorView.bounds)
  330. paymentMethodLabel.stringValue = NSLocalizedString("Payment Method", comment: "")
  331. paymentMethodLabel.textColor = NSColor(named: "KMPurchaseTitleColor1")
  332. paymentMethodLabel.font = NSFont.SFProTextRegularFont(14.0)
  333. wechatPayButton2.isHidden = true
  334. payExplainLabel.isEditable = false
  335. payExplainLabel.isSelectable = true
  336. payExplainLabel.allowsEditingTextAttributes = true
  337. payExplainLabel.textColor = NSColor.black
  338. payExplainLabel.font = NSFont.SFProTextRegularFont(11.0)
  339. let localizedString = NSLocalizedString("By submitting this order, I agree to the %@ and %@ for subscription products", comment: "")
  340. let privacyPolicy = NSLocalizedString("Privacy Policy", comment: "")
  341. let termsOfService = NSLocalizedString("Terms of Service", comment: "")
  342. let fullString1 = String(format: localizedString, privacyPolicy, termsOfService)
  343. let attributedString1 = NSMutableAttributedString(string: fullString1)
  344. let privacyPolicyRange = (fullString1 as NSString).range(of: privacyPolicy)
  345. let termsOfServiceRange = (fullString1 as NSString).range(of: termsOfService)
  346. let linkColor1 = NSColor(red: 73/255.0, green: 130/255.0, blue: 230/255.0, alpha: 1.0)
  347. let font1 = NSFont.SFProTextRegularFont(11.0) // 与普通文本相同的字体
  348. attributedString1.addAttributes([
  349. .foregroundColor: linkColor1,
  350. .link: NSLocalizedString("https://www.pdfreaderpro.com/privacy-policy", comment: ""),
  351. .font: font1
  352. ], range: privacyPolicyRange)
  353. attributedString1.addAttributes([
  354. .foregroundColor: linkColor1,
  355. .link: NSLocalizedString("https://www.pdfreaderpro.com/terms_of_service", comment: ""),
  356. .font: font1
  357. ], range: termsOfServiceRange)
  358. attributedString1.addAttribute(.font, value: font1, range: (fullString1 as NSString).range(of: fullString1))
  359. payExplainLabel.attributedStringValue = attributedString1
  360. paypalBuyNowLabel.stringValue = NSLocalizedString("Buy Now", comment: "")
  361. paypalBuyNowLabel.textColor = NSColor.white
  362. paypalBuyNowLabel.font = NSFont.SFProTextBoldFont(16.0)
  363. paddleButton.title = NSLocalizedString("Continue to Pay", comment: "")
  364. paddleButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  365. paddlePopUpButton.type = .arrowDown
  366. paddlePopUpButton.removeAllItems()
  367. paddlePopUpButton.addItems(withTitles: countryKeys)
  368. paddlePopUpButton.selectItem(at: 229)
  369. paddlePopUpButton.wantsLayer = true
  370. paddlePopUpButton.layer?.backgroundColor = NSColor(named: "KMPurchase_FFFFFF")?.cgColor
  371. paddlePopUpButton.layer?.borderColor = NSColor(named: "KMPurchase_DADBDE")?.cgColor
  372. paddleBox.fillColor = NSColor(named: "KMPurchase_FFFFFF") ?? NSColor.white
  373. paddleBox.borderColor = NSColor(named: "KMPurchase_DADBDE") ?? NSColor.gray
  374. paddleTextField.delegate = self
  375. weChatButton.title = NSLocalizedString("Continue to Pay", comment: "")
  376. weChatButton.setTitleColor(color: NSColor.white, font: NSFont.SFProTextBoldFont(16))
  377. qrCodeImageView.imageScaling = .scaleProportionallyUpOrDown
  378. scanLabel.textColor = NSColor(named: "KMPurchase_000000")
  379. scanLabel.font = NSFont.SFProTextRegularFont(12)
  380. successfullyView.isHidden = true
  381. purchasedLabel.stringValue = NSLocalizedString("Purchased", comment: "")
  382. purchasedLabel.textColor = NSColor(named: "KMPurchase_002143")
  383. purchasedLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  384. successfullyLabel.stringValue = NSLocalizedString("Successfully", comment: "")
  385. successfullyLabel.textColor = NSColor(named: "KMPurchase_002143")
  386. successfullyLabel.font = NSFont(name: "Segoe UI", size: 18.0)
  387. }
  388. private func priceRefresh() -> Void {
  389. if KMDMGProductsManager.shareInstance.productDatas == nil {
  390. let alert = NSAlert()
  391. alert.alertStyle = .critical
  392. alert.messageText = NSLocalizedString("Connection Error", comment: "")
  393. alert.informativeText = NSLocalizedString("Please make sure your internet connection is available.", comment: "")
  394. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  395. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  396. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  397. } else {
  398. alert.runModal()
  399. }
  400. return
  401. }
  402. var abbreviation = "USD"
  403. if NSLocalizedString("USD", comment: "") == "CNY" {
  404. abbreviation = "CNY"
  405. }
  406. var discount1: Float = 0.0
  407. var original1: Float = 0.0
  408. var discount2: Float = 0.0
  409. var original2: Float = 0.0
  410. var discount3: Float = 0.0
  411. var original3: Float = 0.0
  412. var listPrice: Float = 0.0
  413. var discount: Float = 0.0
  414. var paySum: Float = 0.0
  415. let originalType: ProductType = productToType(originalProductID)
  416. if originalType == .ipaConvert || originalType == .ipaAI {
  417. if originalType == .ipaConvert {
  418. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2")) ?? 19.99
  419. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2")) ?? 19.99
  420. } else {
  421. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  422. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  423. }
  424. listPrice = original1 * Float(amountTextField1.stringValue)!
  425. paySum = discount1 * Float(amountTextField1.stringValue)!
  426. discount = listPrice - paySum
  427. originalPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount1))
  428. if String(format: "%.2f", original1) == String(format: "%.2f", discount1) {
  429. discountPriceLabel1.isHidden = true
  430. } else {
  431. discountPriceLabel1.isHidden = false
  432. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original1))
  433. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  434. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  435. discountPriceLabel1.attributedStringValue = attributedString
  436. }
  437. } else {
  438. if productType == .ipaPremium {
  439. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  440. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  441. discount2 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  442. original2 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  443. discount1 = aiBinding_discount - discount2
  444. original1 = aiBinding_original - original2
  445. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  446. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  447. listPrice = (original1 * Float(amountTextField1.stringValue)!)
  448. paySum = (discount1 * Float(amountTextField1.stringValue)!)
  449. discount = listPrice - paySum
  450. } else if productType == .ipaPermanent {
  451. if originalType == .ipaPremium {
  452. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  453. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  454. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  455. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  456. discount1 = paySum - discount3
  457. original1 = listPrice - original3
  458. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  459. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  460. let advanced_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  461. let advanced_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  462. discount2 = aiBinding_discount - advanced_discount
  463. original2 = aiBinding_original - advanced_original
  464. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  465. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  466. discount = listPrice - paySum
  467. } else if originalType == .ipaPermanent {
  468. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  469. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  470. discount1 = paySum
  471. original1 = listPrice
  472. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  473. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  474. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  475. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  476. discount2 = aiBinding_discount - discount1
  477. original2 = aiBinding_original - original1
  478. discount3 = cross_discount - discount1
  479. original3 = cross_original - original1
  480. listPrice = (original1 * Float(amountTextField1.stringValue)!)
  481. paySum = (discount1 * Float(amountTextField1.stringValue)!)
  482. discount = listPrice - paySum
  483. }
  484. } else if productType == .ipaPremiumCrossPlatform {
  485. } else if productType == .ipaPermanentCrossPlatform {
  486. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  487. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  488. discount1 = paySum
  489. original1 = listPrice
  490. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  491. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  492. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  493. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  494. discount2 = aiBinding_discount - discount1
  495. original2 = aiBinding_original - original1
  496. discount3 = cross_discount - discount1
  497. original3 = cross_original - original1
  498. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  499. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  500. discount = listPrice - paySum
  501. } else if productType == .ipaPremiumAI {
  502. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  503. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1")) ?? 74.98
  504. discount2 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  505. original2 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.ai.product_1")) ?? 14.99
  506. discount1 = aiBinding_discount - discount2
  507. original1 = aiBinding_original - original2
  508. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  509. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  510. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!)
  511. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!)
  512. discount = listPrice - paySum
  513. } else if productType == .ipaPermanentAI {
  514. if originalType == .ipaPremium {
  515. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  516. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  517. discount3 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  518. original3 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_2.checkout")) ?? 20.00
  519. discount1 = paySum - discount3
  520. original1 = listPrice - original3
  521. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  522. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  523. let advanced_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  524. let advanced_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  525. discount2 = aiBinding_discount - advanced_discount
  526. original2 = aiBinding_original - advanced_original
  527. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  528. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  529. discount = listPrice - paySum
  530. } else if originalType == .ipaPermanent {
  531. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  532. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  533. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  534. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  535. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  536. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  537. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  538. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  539. discount2 = aiBinding_discount - discount1
  540. original2 = aiBinding_original - original1
  541. discount3 = cross_discount - discount1
  542. original3 = cross_original - original1
  543. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!)
  544. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!)
  545. discount = listPrice - paySum
  546. }
  547. } else if productType == .ipaPermanentCrossPlatformAI {
  548. listPrice = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 149.96
  549. paySum = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 149.96
  550. discount1 = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  551. original1 = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3")) ?? 79.99
  552. let aiBinding_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  553. let aiBinding_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1")) ?? 94.98
  554. let cross_discount = Float(KMDMGProductsManager.shareInstance.getActivityPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  555. let cross_original = Float(KMDMGProductsManager.shareInstance.getPrice("com.brother.pdfreaderpro.cross.platform.product_3")) ?? 119.98
  556. discount2 = aiBinding_discount - discount1
  557. original2 = aiBinding_original - original1
  558. discount3 = cross_discount - discount1
  559. original3 = cross_original - original1
  560. listPrice = (original1 * Float(amountTextField1.stringValue)!) + (original2 * Float(amountTextField2.stringValue)!) + (original3 * Float(amountTextField3.stringValue)!)
  561. paySum = (discount1 * Float(amountTextField1.stringValue)!) + (discount2 * Float(amountTextField2.stringValue)!) + (discount3 * Float(amountTextField3.stringValue)!)
  562. discount = listPrice - paySum
  563. }
  564. originalPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount1))
  565. if String(format: "%.2f", original1) == String(format: "%.2f", discount1) {
  566. discountPriceLabel1.isHidden = true
  567. } else {
  568. discountPriceLabel1.isHidden = false
  569. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original1))
  570. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  571. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  572. discountPriceLabel1.attributedStringValue = attributedString
  573. }
  574. originalPriceLabel2.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount2))
  575. if String(format: "%.2f", original2) == String(format: "%.2f", discount2) {
  576. discountPriceLabel2.isHidden = true
  577. } else {
  578. discountPriceLabel2.isHidden = false
  579. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original2))
  580. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  581. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  582. discountPriceLabel2.attributedStringValue = attributedString
  583. }
  584. originalPriceLabel3.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount3))
  585. if String(format: "%.2f", original3) == String(format: "%.2f", discount3) {
  586. discountPriceLabel3.isHidden = true
  587. } else {
  588. discountPriceLabel3.isHidden = false
  589. let attributedString = NSMutableAttributedString(string: String(format: "%.2f", original3))
  590. attributedString.addAttribute(.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.single.rawValue), range: NSMakeRange(0, attributedString.length))
  591. attributedString.addAttribute(.strikethroughColor, value: NSColor(named: "KMPurchaseDiscountColor") as Any, range: NSMakeRange(0, attributedString.length))
  592. discountPriceLabel3.attributedStringValue = attributedString
  593. }
  594. }
  595. if self.discountScale != "" || self.discountAmount != "" {
  596. if self.discountScale != "" {
  597. paySum = paySum * Float(self.discountScale)!
  598. discount = listPrice - paySum
  599. } else {
  600. var discountAmountF = Float(self.discountAmount)
  601. if NSLocalizedString("USD", comment: "") == "CNY" {
  602. discountAmountF = discountAmountF! * 6.5
  603. }
  604. paySum = paySum - discountAmountF!
  605. discount = listPrice - paySum
  606. }
  607. }
  608. lastPriceLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", listPrice))
  609. discountLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", discount))
  610. paySumLabel1.stringValue = String(format: "%@ %@", abbreviation, String(format: "%.2f", paySum))
  611. if discount == 0 {
  612. discountView.isHidden = true
  613. discountLayoutConstraint.constant = discountView.isHidden ? -CGRectGetHeight(discountView.bounds) : 8
  614. }
  615. }
  616. // MARK: Active
  617. @IBAction func amountButtonAction(_ sender: NSButton) {
  618. if sender.tag == 0 || sender.tag == 1 {
  619. if sender.tag == 0 {
  620. if pdfCount > 1 {
  621. pdfCount -= 1
  622. }
  623. }
  624. if sender.tag == 1 {
  625. if pdfCount < 9999 {
  626. pdfCount += 1
  627. }
  628. }
  629. if pdfCount > 1 {
  630. removeButton1.isEnabled = true
  631. } else {
  632. removeButton1.isEnabled = false
  633. }
  634. if pdfCount > 100 {
  635. wechatPayButton2.isHidden = false
  636. cardButton.isHidden = true
  637. wechatPayButton.isHidden = true
  638. if _paymentMethod == .paddle {
  639. paymentMethod = .paypal
  640. }
  641. } else {
  642. wechatPayButton2.isHidden = true
  643. cardButton.isHidden = false
  644. wechatPayButton.isHidden = false
  645. }
  646. amountTextField1.stringValue = String(pdfCount)
  647. if extendedButton.state == .on {
  648. amountTextField2.stringValue = String(pdfCount * 2)
  649. } else {
  650. amountTextField2.stringValue = String(pdfCount * 1)
  651. }
  652. amountTextField3.stringValue = String(pdfCount)
  653. }
  654. // 价格刷新
  655. priceRefresh()
  656. }
  657. @IBAction func aiAddOnButtonAction(_ sender: NSButton) {
  658. let type: ProductType = productToType(originalProductID)
  659. aiAddOnButton.state = sender.state
  660. if sender.state == .on {
  661. amountView2.isHidden = false
  662. aiAddOnButton.image = NSImage(named: "EmbeddedPayment07")
  663. if extendedButton.state == .on {
  664. if type == .ipaPremium {
  665. productType = .ipaPermanentAI
  666. } else if type == .ipaPermanent {
  667. productType = .ipaPermanentCrossPlatformAI
  668. }
  669. } else {
  670. if type == .ipaPremium {
  671. productType = .ipaPremiumAI
  672. } else if type == .ipaPermanent {
  673. productType = .ipaPermanentAI
  674. }
  675. }
  676. } else {
  677. amountView2.isHidden = true
  678. aiAddOnButton.image = NSImage(named: "EmbeddedPayment06")
  679. if extendedButton.state == .on {
  680. if type == .ipaPremium {
  681. productType = .ipaPermanent
  682. } else if type == .ipaPermanent {
  683. productType = .ipaPermanentCrossPlatform
  684. }
  685. } else {
  686. if type == .ipaPremium {
  687. productType = .ipaPremium
  688. } else if type == .ipaPermanent {
  689. productType = .ipaPermanent
  690. }
  691. }
  692. }
  693. // 价格刷新
  694. priceRefresh()
  695. }
  696. @IBAction func extendedButtonAction(_ sender: NSButton) {
  697. let type: ProductType = productToType(originalProductID)
  698. extendedButton.state = sender.state
  699. if sender.state == .on {
  700. amountView3.isHidden = false
  701. if type == .ipaPremium {
  702. amountTextField2.stringValue = String(pdfCount)
  703. } else {
  704. amountTextField2.stringValue = String(pdfCount * 2)
  705. }
  706. extendedButton.image = NSImage(named: "EmbeddedPayment07")
  707. if aiAddOnButton.state == .on {
  708. if type == .ipaPremium {
  709. productType = .ipaPermanentAI
  710. } else if type == .ipaPermanent {
  711. productType = .ipaPermanentCrossPlatformAI
  712. }
  713. } else {
  714. if type == .ipaPremium {
  715. productType = .ipaPermanent
  716. } else if type == .ipaPermanent {
  717. productType = .ipaPermanentCrossPlatform
  718. }
  719. }
  720. } else {
  721. amountView3.isHidden = true
  722. amountTextField2.stringValue = String(pdfCount)
  723. extendedButton.image = NSImage(named: "EmbeddedPayment06")
  724. if aiAddOnButton.state == .on {
  725. if type == .ipaPremium {
  726. productType = .ipaPremiumAI
  727. } else if type == .ipaPermanent {
  728. productType = .ipaPermanentAI
  729. }
  730. } else {
  731. if type == .ipaPremium {
  732. productType = .ipaPremium
  733. } else if type == .ipaPermanent {
  734. productType = .ipaPermanent
  735. }
  736. }
  737. }
  738. // 价格刷新
  739. priceRefresh()
  740. }
  741. @IBAction func payButtonAction(_ sender: NSButton) {
  742. confirmPayment(isConfirm: false)
  743. paymentMethod = KMPaymentType(rawValue: uint32(sender.tag)) ?? .paypal
  744. }
  745. @IBAction func couponButtonAction(_ sender: NSButton) {
  746. couponButton.isHidden = true
  747. couponBox.isHidden = false
  748. applyBox.isHidden = false
  749. }
  750. @IBAction func applyButtonAction(_ sender: NSButton) {
  751. if coupomTextField.stringValue == "" {
  752. let alert = NSAlert()
  753. alert.alertStyle = .critical
  754. alert.messageText = NSLocalizedString("Coupon Error", comment: "")
  755. alert.informativeText = NSLocalizedString("Please enter the coupon.", comment: "")
  756. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  757. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  758. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  759. } else {
  760. alert.runModal()
  761. }
  762. return
  763. }
  764. self._getDiscount(productId: productID, discountId: coupomTextField.stringValue) { [weak self] info, err in
  765. guard let self = self else { return }
  766. if let dataInfo = info {
  767. if dataInfo.keys.contains("status") {
  768. let status = dataInfo["status"] as? String ?? ""
  769. if status == "" {
  770. let alert = NSAlert()
  771. alert.alertStyle = .critical
  772. alert.messageText = NSLocalizedString("Connection error", comment: "")
  773. alert.informativeText = NSLocalizedString("Promotional volume exception please try again.", comment: "")
  774. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  775. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  776. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  777. } else {
  778. alert.runModal()
  779. }
  780. return
  781. }
  782. if status == "unused" {
  783. if dataInfo["discount"] is NSNull && dataInfo["price"] is NSNull {
  784. let alert = NSAlert()
  785. alert.alertStyle = .critical
  786. alert.messageText = NSLocalizedString("Connection error", comment: "")
  787. alert.informativeText = NSLocalizedString("Non-concessionary amount.", comment: "")
  788. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  789. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  790. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  791. } else {
  792. alert.runModal()
  793. }
  794. return
  795. } else {
  796. if dataInfo["discount"] is NSNull {
  797. if dataInfo["price"] is NSNull {
  798. } else {
  799. if let price1 = dataInfo["price"] {
  800. self.discountAmount = String(format: "%@", price1 as! CVarArg)
  801. }
  802. }
  803. } else {
  804. if let discount1 = dataInfo["discount"] {
  805. self.discountScale = String(format: "%@", discount1 as! CVarArg)
  806. }
  807. }
  808. }
  809. }
  810. } else {
  811. if dataInfo["discount"] is NSNull && dataInfo["price"] is NSNull {
  812. let alert = NSAlert()
  813. alert.alertStyle = .critical
  814. alert.messageText = NSLocalizedString("Connection error", comment: "")
  815. alert.informativeText = NSLocalizedString("Non-concessionary amount.", comment: "")
  816. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  817. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  818. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  819. } else {
  820. alert.runModal()
  821. }
  822. return
  823. } else {
  824. if dataInfo["discount"] is NSNull {
  825. if dataInfo["price"] is NSNull {
  826. } else {
  827. if let price1 = dataInfo["price"] {
  828. self.discountAmount = String(format: "%@", price1 as! CVarArg)
  829. }
  830. }
  831. } else {
  832. if let discount1 = dataInfo["discount"] {
  833. self.discountScale = String(format: "%@", discount1 as! CVarArg)
  834. }
  835. }
  836. }
  837. }
  838. }
  839. self.priceRefresh()
  840. }
  841. }
  842. @IBAction func paddlePopUpAction(_ sender: NSPopUpButton) {
  843. buyAction(sender)
  844. }
  845. @IBAction func buyAction(_ sender: NSButton) {
  846. if emailTextField.stringValue == "" {
  847. let alert = NSAlert()
  848. alert.alertStyle = .critical
  849. alert.messageText = NSLocalizedString("Connection Error", comment: "")
  850. alert.informativeText = NSLocalizedString("The email address is empty.", comment: "")
  851. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  852. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  853. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  854. } else {
  855. alert.runModal()
  856. }
  857. return
  858. }
  859. if paymentMethod == .paddle {
  860. if !isNumeric(paddleTextField.stringValue) && paddleTextField.stringValue != "" {
  861. let alert = NSAlert()
  862. alert.alertStyle = .critical
  863. alert.messageText = NSLocalizedString("Connection Error", comment: "")
  864. alert.informativeText = NSLocalizedString("Please enter the correct postcode.", comment: "")
  865. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  866. if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  867. alert.beginSheetModal(for: self.window!, completionHandler: nil)
  868. } else {
  869. alert.runModal()
  870. }
  871. return
  872. }
  873. }
  874. confirmPayment(isConfirm: true)
  875. if paymentMethod == .paypal {
  876. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  877. } else if paymentMethod == .paddle {
  878. paddleView.wantsLayer = true
  879. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor1")?.cgColor ?? NSColor.blue.cgColor
  880. } else if paymentMethod == .wxpay {
  881. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  882. } else if paymentMethod == .alipay {
  883. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor1") ?? NSColor.blue
  884. }
  885. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
  886. guard let self = self else { return }
  887. if self.paymentMethod == .paypal {
  888. self.paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  889. } else if _paymentMethod == .paddle {
  890. self.paddleView.wantsLayer = true
  891. self.paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  892. } else if _paymentMethod == .wxpay {
  893. self.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  894. } else if _paymentMethod == .alipay {
  895. self.weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  896. }
  897. }
  898. var licenseCode = ""
  899. if let license = VerificationManager.default().originLicenseCode, license.count > 0 {
  900. licenseCode = license
  901. }
  902. self._buyProduct(productID, count: pdfCount, discountId: coupomTextField.stringValue, payment: paymentMethod, license: licenseCode, email: emailTextField.stringValue) { [weak self] info, err in
  903. guard let self = self else { return }
  904. if err != nil {return}
  905. if let dataInfo = info {
  906. self.orderID = dataInfo["trade_no"] as! String
  907. let page_pay_url = dataInfo["page_pay_url"] as! String
  908. if self.paymentMethod == .paddle || self.paymentMethod == .paypal {
  909. if page_pay_url != "" {
  910. self.openWebView(page_pay_url)
  911. }
  912. } else if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  913. if page_pay_url != "" {
  914. self.scanCode(page_pay_url)
  915. }
  916. }
  917. } else {
  918. // 数据错误
  919. }
  920. }
  921. }
  922. // MARK: get & set
  923. private var paymentMethod : KMPaymentType {
  924. get {
  925. return _paymentMethod
  926. }
  927. set {
  928. _paymentMethod = newValue
  929. paypalButton.image = NSImage(named: "EmbeddedPayment19")
  930. cardButton.image = NSImage(named: "EmbeddedPayment21")
  931. wechatPayButton.image = NSImage(named: "EmbeddedPayment23")
  932. wechatPayButton2.image = NSImage(named: "EmbeddedPayment23")
  933. alipayButton.image = NSImage(named: "EmbeddedPayment25")
  934. if _paymentMethod == .paypal {
  935. paypalButton.image = NSImage(named: "EmbeddedPayment18")
  936. payBox.contentView = paypalView
  937. paypalBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  938. payBoxHeight.constant = 60.0
  939. } else if _paymentMethod == .paddle {
  940. cardButton.image = NSImage(named: "EmbeddedPayment20")
  941. payBox.contentView = cardView
  942. paddleView.wantsLayer = true
  943. paddleView.layer?.backgroundColor = NSColor(named: "KMPurchaseBoxColor")?.cgColor ?? NSColor.blue.cgColor
  944. payBoxHeight.constant = 150.0
  945. } else if _paymentMethod == .wxpay {
  946. wechatPayButton.image = NSImage(named: "EmbeddedPayment22")
  947. wechatPayButton2.image = NSImage(named: "EmbeddedPayment22")
  948. payBox.contentView = weChatPayView
  949. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  950. payBoxHeight.constant = 92.0
  951. } else if _paymentMethod == .alipay {
  952. alipayButton.image = NSImage(named: "EmbeddedPayment24")
  953. payBox.contentView = weChatPayView
  954. weChatBox.fillColor = NSColor(named: "KMPurchaseBoxColor") ?? NSColor.blue
  955. payBoxHeight.constant = 92.0
  956. }
  957. }
  958. }
  959. var productType: ProductType {
  960. get {
  961. return _productType
  962. }
  963. set {
  964. _productType = newValue
  965. if _productType == .ipaConvert {
  966. productID = "com.brother.pdfreaderpro.mac.product_2"
  967. } else if _productType == .ipaConvert_checkout {
  968. productID = "com.brother.pdfreaderpro.mac.product_2.checkout"
  969. } else if _productType == .ipaPremium {
  970. productID = "com.brother.pdfreaderpro.mac.product_1"
  971. } else if _productType == .ipaPermanent {
  972. productID = "com.brother.pdfreaderpro.mac.product_3"
  973. } else if _productType == .ipaPremiumCrossPlatform {
  974. productID = "com.brother.pdfreaderpro.cross.platform.product_1"
  975. } else if _productType == .ipaPermanentCrossPlatform {
  976. productID = "com.brother.pdfreaderpro.cross.platform.product_3"
  977. } else if _productType == .ipaAI {
  978. productID = "com.brother.pdfreaderpro.ai.product_1"
  979. } else if _productType == .ipaPremiumAI {
  980. productID = "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1"
  981. } else if _productType == .ipaPermanentAI {
  982. productID = "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1"
  983. } else if _productType == .ipaPermanentCrossPlatformAI {
  984. productID = "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1"
  985. }
  986. }
  987. }
  988. // MARK: ——
  989. // 获取价格
  990. private func _getProductDatas(callback: @escaping (([String:Any]?, Any?)->Void)) {
  991. // func getPriceUrl() {
  992. let urlString = kVerificationServer + "/api/product/get-price/v2"
  993. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: nil) { task, responseObject, error in
  994. if (error == nil && responseObject != nil) {
  995. let array = responseObject?["data"] as? NSDictionary
  996. if array != nil {
  997. //解析数据
  998. let productsDict = array?.object(forKey: "data") as? NSDictionary
  999. callback(productsDict as? [String : Any], nil)
  1000. } else {
  1001. callback([:], error.debugDescription)
  1002. }
  1003. } else {
  1004. callback(nil, error.debugDescription)
  1005. }
  1006. }
  1007. }
  1008. // 获取优惠卷
  1009. private func _getDiscount(productId: String, discountId: String, callback: @escaping (([String : Any]?, Any?)->Void)) {
  1010. let urlString = kVerificationServer + "/api/coupons/retrieval"
  1011. let app_code = MainBundle.km_infoDictionary()?["CFBundleIdentifier"] ?? ""
  1012. let params = [
  1013. // 优惠卷id
  1014. "code" : discountId,
  1015. "app_code" : app_code,
  1016. "product_code" : productId]
  1017. KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { task, responseObject, error in
  1018. if (error == nil && responseObject != nil) {
  1019. if let dataDict = responseObject?["data"] as? NSDictionary {
  1020. if let swiftDict = dataDict as? [String: Any] {
  1021. if swiftDict.keys.contains("price") || swiftDict.keys.contains("discount") {
  1022. callback(dataDict as? [String : Any], nil)
  1023. } else if swiftDict.keys.contains("coupon_provider") {
  1024. if let couponDict = swiftDict["coupon_provider"] as? [String: Any] {
  1025. callback(couponDict, nil)
  1026. }
  1027. }
  1028. }
  1029. } else if let coupon_provider = responseObject?["coupon_provider"] as? NSDictionary {
  1030. callback(coupon_provider as? [String : Any], nil)
  1031. } else {
  1032. callback([:], error.debugDescription)
  1033. }
  1034. } else {
  1035. callback(nil, error.debugDescription)
  1036. }
  1037. }
  1038. }
  1039. // 获取订单状态
  1040. private func _getOrderStatus(tradeNo: String, callback: @escaping (([String:Any]?, Any?)->Void)) {
  1041. let urlString = kVerificationServer + "/api/orders/getOrderStatus"
  1042. var jsonStr: String = ""
  1043. if let jsonData = try?JSONSerialization.data(withJSONObject: ["trade_no" : tradeNo], options:[]),
  1044. let data = String(data: jsonData, encoding: .utf8) {
  1045. jsonStr = data
  1046. }
  1047. let rsa = KMVerificationRSA()
  1048. let publicKey = rsa.loadPublicKey()
  1049. let encryptedData = rsa.encrypt(plainText: jsonStr, publicKey: publicKey!)
  1050. let tokenStr = encryptedData?.base64EncodedString()
  1051. var postData = try!JSONSerialization.data(withJSONObject: ["token" : tokenStr])
  1052. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  1053. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  1054. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  1055. request.httpMethod = "POST"
  1056. request.httpBody = postData
  1057. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  1058. guard let data = data else {
  1059. callback(nil, String(describing: error))
  1060. return
  1061. }
  1062. if let jsonDict = try?JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary ?? [:] {
  1063. let dataStr = jsonDict["data"] as? String
  1064. let rsa = KMVerificationRSA()
  1065. if let deData = (rsa.decrypt(source: dataStr as? NSString ?? "") as? String)?.data(using: .utf8) {
  1066. if let dict = try?JSONSerialization.jsonObject(with: deData, options: []) as? NSDictionary ?? [:] {
  1067. return callback(dict as? [String : Any], nil)
  1068. }
  1069. }
  1070. callback([:], String(describing: error))
  1071. } else {
  1072. // 数据错误
  1073. callback([:], String(describing: error))
  1074. }
  1075. }
  1076. task.resume()
  1077. }
  1078. private func _buyProduct(_ productId: String, count: Int, discountId: String = "", payment: KMPaymentType, license: String = "", email: String, username: String = "", callback: @escaping (([String:Any]?, Any?)->Void)) {
  1079. let urlString = kVerificationServer + "/api/subscriptions"
  1080. let app_code = MainBundle.km_infoDictionary()?["CFBundleIdentifier"] ?? ""
  1081. let paymentStr = self._paymentTypeString(type: payment)
  1082. let country = countryAbbreviationValues[paddlePopUpButton.indexOfSelectedItem]
  1083. let postcode = paddleTextField.stringValue ?? ""
  1084. let paraDict = ["data" :
  1085. ["product_code": productId,
  1086. "app_code": app_code,
  1087. // 购买数量
  1088. "amount": "\(count)",
  1089. // 优惠卷id
  1090. "coupon_code": discountId,
  1091. // 支付类型 paypal alipay wxpay paddle
  1092. "payment": paymentStr,
  1093. // 地区
  1094. "customer_country": country,
  1095. // 邮编码
  1096. "customer_postcode" : postcode,
  1097. "unique_sn" : uuid(),
  1098. // 序列码 标准包 升级 高级包 需要
  1099. "upgrade_cdkey" : license,
  1100. "email" : email,
  1101. // 用户名
  1102. "contact_name" : username]]
  1103. var postData = try! JSONSerialization.data(withJSONObject: paraDict)
  1104. var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
  1105. request.addValue("Apifox/1.0.0 (https://www.apifox.cn)", forHTTPHeaderField: "User-Agent")
  1106. request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  1107. request.httpMethod = "POST"
  1108. request.httpBody = postData
  1109. let task = URLSession.shared.dataTask(with: request) { data, response, error in
  1110. guard let theData = data else {
  1111. callback(nil, String(describing: error))
  1112. return
  1113. }
  1114. if let jsonDict = try? JSONSerialization.jsonObject(with: theData, options: []) as? NSDictionary ?? [:] {
  1115. let data1: NSDictionary = jsonDict["data"] as? NSDictionary ?? [:]
  1116. let subscriptionInfo = data1.object(forKey: "subscription") as? NSDictionary
  1117. let orderKey = self._paymentTypeString(type: payment) + "_order"
  1118. let order_info = subscriptionInfo?.object(forKey: orderKey) as? NSDictionary
  1119. if let dataInfo = order_info, dataInfo.count > 0 {
  1120. callback(dataInfo as? [String : Any], nil)
  1121. } else {
  1122. // 数据错误
  1123. callback([:], String(describing: error))
  1124. }
  1125. } else {
  1126. // 数据错误
  1127. callback([:], String(describing: error))
  1128. }
  1129. }
  1130. task.resume()
  1131. }
  1132. // MARK: Private
  1133. private func uuid() -> String {
  1134. return GetHardwareUUID()!
  1135. }
  1136. private func _paymentTypeString(type: KMPaymentType) -> String {
  1137. if type == .paddle {
  1138. return "paddle"
  1139. } else if type == .alipay {
  1140. return "alipay"
  1141. } else if type == .wxpay {
  1142. return "wxpay"
  1143. } else if type == .paypal {
  1144. return "paypal"
  1145. }
  1146. return ""
  1147. }
  1148. private func _trackEvent_paid() {
  1149. self.trackEvent_dmg(eventName: self.kEventName, params: self.kEventParams, platform: .firebase)
  1150. }
  1151. private let tabDict: [ProductType: String] = [
  1152. .ipaConvert: "com.brother.pdfreaderpro.mac.product_2",
  1153. .ipaConvert_checkout: "com.brother.pdfreaderpro.mac.product_2.checkout",
  1154. .ipaPremium: "com.brother.pdfreaderpro.mac.product_1",
  1155. .ipaPermanent: "com.brother.pdfreaderpro.mac.product_3",
  1156. .ipaPremiumCrossPlatform: "com.brother.pdfreaderpro.cross.platform.product_1",
  1157. .ipaPermanentCrossPlatform: "com.brother.pdfreaderpro.cross.platform.product_3",
  1158. .ipaAI: "com.brother.pdfreaderpro.ai.product_1",
  1159. .ipaPremiumAI: "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1",
  1160. .ipaPermanentAI: "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1",
  1161. .ipaPermanentCrossPlatformAI: "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1"
  1162. ]
  1163. private func getProductID() -> String {
  1164. return GetHardwareUUID()!
  1165. }
  1166. private func productToType(_ productId: String) -> ProductType {
  1167. if productId == "com.brother.pdfreaderpro.mac.product_2" {
  1168. return .ipaConvert
  1169. } else if productId == "com.brother.pdfreaderpro.mac.product_2.checkout" {
  1170. return .ipaConvert_checkout
  1171. } else if productId == "com.brother.pdfreaderpro.mac.product_1" {
  1172. return .ipaPremium
  1173. } else if productId == "com.brother.pdfreaderpro.mac.product_3" {
  1174. return .ipaPermanent
  1175. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_1" {
  1176. return .ipaPremiumCrossPlatform
  1177. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_3" {
  1178. return .ipaPermanentCrossPlatform
  1179. } else if productId == "com.brother.pdfreaderpro.ai.product_1" {
  1180. return .ipaAI
  1181. } else if productId == "com.brother.pdfreaderpro.mac.product_1+com.brother.pdfreaderpro.ai.product_1" {
  1182. return .ipaPremiumAI
  1183. } else if productId == "com.brother.pdfreaderpro.mac.product_3+com.brother.pdfreaderpro.ai.product_1" {
  1184. return .ipaPermanentAI
  1185. } else if productId == "com.brother.pdfreaderpro.cross.platform.product_3+com.brother.pdfreaderpro.ai.product_1" {
  1186. return .ipaPermanentCrossPlatformAI
  1187. }
  1188. return .ipaConvert
  1189. }
  1190. private func isNumeric(_ text: String) -> Bool {
  1191. return !text.isEmpty && text.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
  1192. }
  1193. private func openWebView(_ urlPath: String) -> Void {
  1194. DispatchQueue.main.async { [weak self] in
  1195. guard let self = self else { return }
  1196. // let wc = KMEmbeddedPaymentPopWC.init(windowNibName: "KMEmbeddedPaymentPopWC")
  1197. self.embeddedPaymentPopWC = KMEmbeddedPaymentPopWC.currentFirstTrialWC(urlPath)
  1198. self.embeddedPaymentPopWC?.showWindow(nil)
  1199. }
  1200. startPolling()
  1201. }
  1202. private func scanCode(_ urlPath: String) -> Void {
  1203. DispatchQueue.main.async { [weak self] in
  1204. guard let self = self else { return }
  1205. self.payBox.contentView = self.payResult
  1206. self.payBoxHeight.constant = 262
  1207. if self.paymentMethod == .wxpay {
  1208. self.scanLabel.stringValue = NSLocalizedString("Scan QR Code with WeChat", comment: "")
  1209. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment27")
  1210. } else if self.paymentMethod == .alipay {
  1211. self.scanLabel.stringValue = NSLocalizedString("Scan QR Code with AliPay", comment: "")
  1212. self.payTypeImageView.image = NSImage(named: "EmbeddedPayment28")
  1213. }
  1214. if let url = URL(string: urlPath) {
  1215. URLSession.shared.dataTask(with: url) { data, response, error in
  1216. if let data = data, let image = NSImage(data: data) {
  1217. DispatchQueue.main.async {
  1218. self.qrCodeImageView.image = image
  1219. self.startPolling()
  1220. }
  1221. } else {
  1222. print("Failed to load image or there was an error: \(error?.localizedDescription ?? "Unknown error")")
  1223. }
  1224. }.resume()
  1225. } else {
  1226. print("Invalid URL.")
  1227. }
  1228. }
  1229. }
  1230. private func pollingResult() -> Void {
  1231. DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
  1232. guard let self = self else { return }
  1233. if self.orderID == "" { return }
  1234. self._getOrderStatus(tradeNo: self.orderID, callback: { info, err in
  1235. if let dataInfo = info {
  1236. if dataInfo.keys.contains("status") {
  1237. let status = dataInfo["status"] as? Int
  1238. if status == 2 {
  1239. self.stopPolling()
  1240. if dataInfo.keys.contains("license") {
  1241. let license = dataInfo["license"] as? [String]
  1242. if license!.count > 0 {
  1243. self.verificationActivate(license: license![0])
  1244. }
  1245. // else {
  1246. // let alert = NSAlert()
  1247. // alert.alertStyle = .critical
  1248. // alert.messageText = NSLocalizedString("Connection Error", comment: "")
  1249. // alert.informativeText = NSLocalizedString("Get License Code is empty.", comment: "")
  1250. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1251. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  1252. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  1253. // } else {
  1254. // alert.runModal()
  1255. // }
  1256. // return
  1257. // }
  1258. }
  1259. if dataInfo.keys.contains("ai_license") {
  1260. let ai_license = dataInfo["ai_license"] as? [String]
  1261. if ai_license!.count > 0 {
  1262. self.verificationActivateAIInfo(license: ai_license![0])
  1263. }
  1264. // else {
  1265. // let alert = NSAlert()
  1266. // alert.alertStyle = .critical
  1267. // alert.messageText = NSLocalizedString("Connection Error", comment: "")
  1268. // alert.informativeText = NSLocalizedString("Get AI License Code is empty.", comment: "")
  1269. // alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  1270. // if alert.responds(to: #selector(alert.beginSheetModal(for:completionHandler:))) {
  1271. // alert.beginSheetModal(for: self.window!, completionHandler: nil)
  1272. // } else {
  1273. // alert.runModal()
  1274. // }
  1275. // return
  1276. // }
  1277. }
  1278. } else {
  1279. self.startPolling()
  1280. }
  1281. }
  1282. }
  1283. })
  1284. }
  1285. }
  1286. private func startPolling() {
  1287. timer = Timer(timeInterval: interval, repeats: false) { [weak self] _ in
  1288. guard let self = self else { return }
  1289. self.performTask()
  1290. }
  1291. RunLoop.main.add(timer!, forMode: .common)
  1292. timer!.fire()
  1293. }
  1294. @objc private func performTask() {
  1295. guard pollCount < maxPolls else {
  1296. stopPolling()
  1297. return
  1298. }
  1299. // 执行你的轮询任务
  1300. print("Performing polling task \(pollCount + 1)/\(maxPolls)")
  1301. pollCount += 1
  1302. pollingResult()
  1303. }
  1304. private func stopPolling() {
  1305. timer?.invalidate()
  1306. timer = nil
  1307. print("Polling task completed.")
  1308. if self.embeddedPaymentPopWC != nil {
  1309. DispatchQueue.main.async { [weak self] in
  1310. guard let self = self else { return }
  1311. self.embeddedPaymentPopWC?.close()
  1312. self.embeddedPaymentPopWC = nil
  1313. }
  1314. }
  1315. pollCount = 0
  1316. }
  1317. private func verificationActivateAIInfo(license: String) {
  1318. guard !license.isEmpty else {
  1319. return
  1320. }
  1321. let infoDic = ["cdkey": license]
  1322. AIInfoManager.default().activateAI(withInfo: infoDic) { info, error in
  1323. if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  1324. self.qrCodeImageView.isHidden = true
  1325. self.successfullyView.isHidden = false
  1326. }
  1327. if info.isEmpty == false {
  1328. self._trackEvent_paid()
  1329. }
  1330. }
  1331. }
  1332. private func verificationActivate(license: String) {
  1333. guard !license.isEmpty else {
  1334. return
  1335. }
  1336. let infoDic = ["cdkey": license]
  1337. VerificationManager.default().activateDevice(withInfo: infoDic) { status, info, error in
  1338. if self.paymentMethod == .wxpay || self.paymentMethod == .alipay {
  1339. self.qrCodeImageView.isHidden = true
  1340. self.successfullyView.isHidden = false
  1341. }
  1342. if let data = info, data.isEmpty == false {
  1343. self._trackEvent_paid()
  1344. }
  1345. }
  1346. }
  1347. private func confirmPayment(isConfirm: Bool) {
  1348. if isConfirm {
  1349. removeButton1.isEnabled = false
  1350. addButton1.isEnabled = false
  1351. aiAddOnButton1.isEnabled = false
  1352. extendedButton1.isEnabled = false
  1353. couponButton.isEnabled = false
  1354. coupomTextField.isEnabled = false
  1355. applyButton.isEnabled = false
  1356. } else {
  1357. removeButton1.isEnabled = true
  1358. addButton1.isEnabled = true
  1359. aiAddOnButton1.isEnabled = true
  1360. extendedButton1.isEnabled = true
  1361. couponButton.isEnabled = true
  1362. coupomTextField.isEnabled = true
  1363. applyButton.isEnabled = true
  1364. }
  1365. }
  1366. // MARK: Show Methods
  1367. // @IBAction private func dismissSheet(_ sender: NSButton) {
  1368. // NSApp.endSheet(window!)
  1369. // window!.orderOut(self)
  1370. // }
  1371. //
  1372. //
  1373. // @objc private func didEndSheet(_ sheet: NSWindow?, returnCode: Int, contextInfo: UnsafeMutableRawPointer?) {
  1374. // if contextInfo != nil && self.handler != nil {
  1375. // self.handler!(returnCode)
  1376. // }
  1377. // }
  1378. //
  1379. // @objc func beginSheetModal(for window: NSWindow?, completionHandler handler: ((Int) -> Void)?) {
  1380. // if window != nil {
  1381. // window!.beginSheet(self.window!) { ModalResponse in
  1382. // self.handler?(ModalResponse.rawValue)
  1383. // }
  1384. // }
  1385. // self.handler = handler
  1386. // }
  1387. }
  1388. extension KMPurchaseEmbeddedWindowController: NSTextFieldDelegate {
  1389. func controlTextDidEndEditing(_ obj: Notification) {
  1390. let textField = obj.object as? NSTextField
  1391. if textField == amountTextField1 {
  1392. if !isNumeric(textField!.stringValue) {
  1393. if textField == amountTextField1 { textField?.stringValue = String(pdfCount) }
  1394. } else {
  1395. if textField == amountTextField1 {
  1396. pdfCount = Int(textField!.stringValue) ?? 1
  1397. if Int(textField!.stringValue)! > 9999 {
  1398. pdfCount = 9999
  1399. textField?.stringValue = String(pdfCount)
  1400. }
  1401. }
  1402. if pdfCount > 100 {
  1403. wechatPayButton2.isHidden = false
  1404. cardButton.isHidden = true
  1405. wechatPayButton.isHidden = true
  1406. if _paymentMethod == .paddle {
  1407. paymentMethod = .paypal
  1408. }
  1409. } else {
  1410. wechatPayButton2.isHidden = true
  1411. cardButton.isHidden = false
  1412. wechatPayButton.isHidden = false
  1413. }
  1414. }
  1415. } else if textField == emailTextField {
  1416. } else if textField == paddleTextField {
  1417. }
  1418. }
  1419. }
  1420. extension KMPurchaseEmbeddedWindowController: NSWindowDelegate {
  1421. func windowWillClose(_ notification: Notification) {
  1422. if orderID != "" {
  1423. pollingResult()
  1424. }
  1425. if self.embeddedPaymentPopWC != nil {
  1426. self.embeddedPaymentPopWC?.close()
  1427. self.embeddedPaymentPopWC = nil
  1428. }
  1429. KMPurchaseEmbeddedWindowController.currentWindowController = nil
  1430. }
  1431. }
  1432. #endif