KMPurchaseEmbeddedWindowController.swift 81 KB

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