KMPurchaseEmbeddedWindowController.swift 89 KB

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