index.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. <template>
  2. <div class="payment">
  3. <!-- 选择支付方式 -->
  4. <template v-if="step === 1">
  5. <div class="moneyInfo">
  6. <div class="tips">You Neet to Pay</div>
  7. <div class="money" v-if="salePlans">
  8. <FontZoom width="300" :unColor="true" v-if="salePlans && salePlans.price">
  9. <template v-if="salePlans && salePlans.currencyCode && salePlans.currencyCode !== 'USD'">
  10. <template v-if="salePlans.price.length + salePlans.currencyInfo.tokenSymbol.length >= 30">
  11. <div style="text-align:center">
  12. <div><img class="icon" :src="salePlans.currencyInfo.iconPath" /> {{ salePlans.price }}</div>
  13. <div>{{ salePlans.currencyInfo.tokenSymbol }} (${{salePlans.usdPrice}})</div>
  14. </div>
  15. </template>
  16. <template v-else>
  17. <img class="icon" :src="salePlans.currencyInfo.iconPath" /> {{ salePlans.price }} {{ salePlans.currencyInfo.tokenSymbol }} (${{salePlans.usdPrice}})
  18. </template>
  19. </template>
  20. <template v-else>
  21. <span class="info usd">${{salePlans.usdPrice}}</span>
  22. </template>
  23. </FontZoom>
  24. </div>
  25. </div>
  26. <div class="payList">
  27. <div class="detail" v-if="salePlans && salePlans.currencyCode && salePlans.currencyCode !== 'USD'">
  28. <div class="title">Crypto Wallet</div>
  29. <div class="item denet" @click="deNetPay">
  30. <div>
  31. <img src="../../static/payment/icon_wallet.png" />
  32. <span>DeNet Pay</span>
  33. </div>
  34. <div class="wallet">
  35. <FontZoom width="300" :unColor="true">
  36. Balance:{{currencyInfoData.balance}} {{currencyInfoData.tokenSymbol}}
  37. </FontZoom>
  38. </div>
  39. </div>
  40. <div class="item" @click="maskPay">
  41. <a class="maskLink" :href="maskUrlLink" v-if="Number(usdAmountData.rechargeAmountValue) > 0"></a>
  42. <img src="../../static/payment/icon_meta_mask.png" />
  43. <span>MetaMask</span>
  44. </div>
  45. </div>
  46. <div class="detail" v-if="salePlans && salePlans.currencyCode && salePlans.currencyCode === 'USD'">
  47. <div class="title">Credit/Debit Card</div>
  48. <div class="item denet" @click="deNetPay">
  49. <div>
  50. <img src="../../static/payment/icon_wallet.png" />
  51. <span>DeNet Pay</span>
  52. </div>
  53. <div class="wallet">
  54. Balance:{{currencyInfoData.balance}} {{currencyInfoData.tokenSymbol}}
  55. </div>
  56. </div>
  57. <div class="item" @click="achPay(true, Report.objectType.mastercardPayButton)">
  58. <img src="../../static/payment/icon_master_card.png" />
  59. <span>MasterCard</span>
  60. </div>
  61. <div class="item" @click="achPay(true, Report.objectType.visaPayButton)">
  62. <img src="../../static/payment/icon_visa.png" />
  63. <span>VISA</span>
  64. </div>
  65. </div>
  66. <div class="detail">
  67. <div class="title">Redemption Code</div>
  68. <div class="item" @click="showRedeem">
  69. <img src="../../static/payment/icon_enter_code.png" />
  70. <span>Enter Code</span>
  71. </div>
  72. </div>
  73. </div>
  74. </template>
  75. <!-- 余额足够 -->
  76. <template v-else-if="step === 2">
  77. <div class="balanceTop">
  78. <img class="balance" src="../../static/img/icon_balance.svg" />
  79. <div class="text">Balance</div>
  80. <div class="money">
  81. <FontZoom width="300" :unColor="true">
  82. <img class="icon" :src="currencyInfoData.iconPath" /> {{currencyInfoData.balance}} {{currencyInfoData.tokenSymbol}}
  83. </FontZoom>
  84. </div>
  85. <template v-if="waitRefresh">
  86. <div class="waitFont">It may take some time to credit the funds into your account.</div>
  87. <div
  88. @click="checkWaitInfo"
  89. class="waitBtn">
  90. <img :class="{ 'icon-refresh-rotate': refreshRotate }" src="../../static/img/icon_refresh.svg" />
  91. </div>
  92. </template>
  93. </div>
  94. <div class="balanceBot">
  95. <div class="l">
  96. <div class="neet">You Neet to Pay</div>
  97. <div class="money">
  98. <FontZoom width="190" :unColor="true">
  99. <span class="text">{{salePlans.price}} {{ salePlans.currencyInfo.tokenSymbol }}</span>
  100. </FontZoom>
  101. </div>
  102. </div>
  103. <div>
  104. <div
  105. class="btn"
  106. :class="{ disable: (Number(usdAmountData.rechargeAmountValue) > 0) || payDisabled }"
  107. @click="pay">
  108. Pay Now
  109. </div>
  110. </div>
  111. </div>
  112. </template>
  113. <!-- 余额不足 -->
  114. <template v-else-if="step === 3">
  115. <template v-if="salePlans && salePlans.currencyCode && salePlans.currencyCode !== 'USD'">
  116. <div class="balanceInfo">
  117. <div class="top">
  118. <div class="item title">
  119. <img src="../../static/img/icon_deposit.png" />
  120. <span>Deposit to Buy</span>
  121. </div>
  122. <div class="item column">
  123. <div class="l">Deposit</div>
  124. <div class="r">
  125. <FontZoom width="260" :unColor="true">
  126. <img :src="currencyInfoData.iconPath" />
  127. <span>{{ usdAmountData.rechargeAmountValue || 0 }} {{currencyInfoData.tokenSymbol}}</span>
  128. </FontZoom>
  129. </div>
  130. </div>
  131. <div class="item column">
  132. <div class="l">Network</div>
  133. <div class="r">
  134. <FontZoom width="260" :unColor="true">
  135. <img :src="currencyInfoData.chainInfo.iconPath" />
  136. <span>{{ currencyInfoData.chainInfo.chainName }}</span>
  137. </FontZoom>
  138. </div>
  139. </div>
  140. <div class="address">
  141. <div class="title">Address</div>
  142. <QrCode :tokenChain="currencyInfoData.tokenChain" :rechargeAddress="rechargeAddress" @copy="copyErCode"></QrCode>
  143. </div>
  144. <div class="notice">
  145. <div class="icon"><img src="../../static/img/icon_warning.svg" /></div>
  146. <div class="text">Make sure you also selected <Br/><strong>{{ currencyInfoData.chainInfo.chainName }}</strong> <br/>as the Network on the platform where you are withdrawing funds for this deposiit. Otherwise, you'll lose your assets.</div>
  147. </div>
  148. </div>
  149. <div class="line"></div>
  150. <div class="balance">
  151. <div class="icon">
  152. <img src="../../static/img/icon_balance_blue.svg" />
  153. </div>
  154. <div class="text">
  155. <FontZoom width="260" :unColor="true">
  156. <span>Balance: {{ currencyInfoData.balance }} {{ currencyInfoData.tokenSymbol }}</span>
  157. </FontZoom>
  158. </div>
  159. <div
  160. class="refresh"
  161. @click="checkCurrencyInfo">
  162. <img :class="{ 'icon-refresh-rotate': refreshRotate }" src="../../static/img/icon_refresh.svg" />
  163. </div>
  164. </div>
  165. </div>
  166. <div class="balanceBot">
  167. <div class="l">
  168. <div class="neet">You Neet to Pay</div>
  169. <div class="money">
  170. <FontZoomMobile width="260" :unColor="true">
  171. {{salePlans.price}} {{ salePlans.currencyInfo.tokenSymbol }}
  172. </FontZoomMobile>
  173. </div>
  174. </div>
  175. <div>
  176. <div
  177. class="btn"
  178. :class="{ disable: (Number(usdAmountData.rechargeAmountValue) > 0) || payDisabled }"
  179. @click="payToken">
  180. Pay Now
  181. </div>
  182. </div>
  183. </div>
  184. </template>
  185. <template v-if="salePlans && salePlans.currencyCode && salePlans.currencyCode === 'USD'">
  186. <div class="balanceInfo">
  187. <div class="top">
  188. <div class="item usd">
  189. <div class="l">Payment amount</div>
  190. <div class="r fontPayment">${{ usdAmountData.orderAmountValue }}</div>
  191. </div>
  192. <div class="item usd">
  193. <div class="l">Balance</div>
  194. <div class="r font">${{ usdAmountData.balance }}</div>
  195. </div>
  196. <div class="item usd" v-if="Number(usdAmountData.rechargeAmountValue) > 0">
  197. <div class="l">{{ usdAmountData.feeDesc }}</div>
  198. <div class="r font">${{ usdAmountData.feeAmountValue }}</div>
  199. </div>
  200. <div class="item usd" v-if="Number(usdAmountData.rechargeAmountValue) > 0">
  201. <div class="l">Deposit Amount</div>
  202. <div class="r fontDeposit">${{ usdAmountData.rechargeAmountValue }}</div>
  203. </div>
  204. <div class="deposit" @click="achPay(false, '')">Deposit</div>
  205. </div>
  206. <div class="line"></div>
  207. <div class="balance">
  208. <div class="icon">
  209. <img src="../../static/img/icon_balance_blue.svg" />
  210. </div>
  211. <div class="text">Balance: ${{currencyInfoData.balance}}</div>
  212. <div
  213. class="refresh"
  214. @click="checkUsdCurrencyInfo">
  215. <img :class="{ 'icon-refresh-rotate': refreshRotate }" src="../../static/img/icon_refresh.svg" />
  216. </div>
  217. </div>
  218. </div>
  219. <div class="balanceBot">
  220. <div class="l">
  221. <div class="neet">You Neet to Pay</div>
  222. <div class="money">
  223. <FontZoomMobile width="260" :unColor="true">
  224. {{ Number(usdAmountData.rechargeAmountValue) > 0 ? usdAmountData.rechargeAmountValue : usdAmountData.orderAmountValue }} {{ salePlans.currencyInfo.tokenSymbol }}
  225. </FontZoomMobile>
  226. </div>
  227. </div>
  228. <div>
  229. <div
  230. class="btn"
  231. :class="{ disable: (Number(usdAmountData.rechargeAmountValue) > 0) || payDisabled }"
  232. @click="payUSD">
  233. Pay Now
  234. </div>
  235. </div>
  236. </div>
  237. </template>
  238. </template>
  239. <!-- 成功支付 -->
  240. <template v-else-if="step === 4">
  241. <div class="payInfo">
  242. <div class="picShow" v-if="buyData">
  243. <div class="tip">Wow, NFT in the Mystery box is</div>
  244. <img class="pic" :src="buyData.imagePath" />
  245. <div class="name">{{buyData.nftItemName}}</div>
  246. </div>
  247. </div>
  248. <div class="payBtn">
  249. <button class="btn" @click="goNext">Done</button>
  250. </div>
  251. </template>
  252. <!-- loading -->
  253. <div class="loading" v-if="loading">
  254. <van-loading color="#1D9BF0"></van-loading>
  255. </div>
  256. <div class="loadingBg" v-if="loading"></div>
  257. <!-- redeem -->
  258. <van-popup
  259. round
  260. v-model="redeemLayer"
  261. position="bottom">
  262. <div class="redeem">
  263. <div class="tips">Enter Redemption Code</div>
  264. <div class="footer">
  265. <div class="input">
  266. <input
  267. type="text"
  268. ref="input"
  269. v-model="redeemStr"
  270. @input="textInput"
  271. @blur="textBlur"
  272. @focus="textFocus"
  273. @keydown.enter="redeemPayment" />
  274. </div>
  275. <button
  276. class="enter"
  277. :class="{ disable: !redeemNext }"
  278. @click="redeemPayment">
  279. Redeem
  280. </button>
  281. </div>
  282. </div>
  283. </van-popup>
  284. </div>
  285. </template>
  286. <script>
  287. import FontZoom from '../../components/FontZoom.vue';
  288. import FontZoomMobile from '../../components/FontZoomMobile.vue';
  289. import QrCode from '../../components/qrcode.vue';
  290. import { postRequest } from '../../http/index';
  291. import { maskUrl } from '../../utils/help';
  292. import { Dialog, Toast } from 'vant';
  293. import Api from '../../http/api';
  294. import Report from '../../log-center/log';
  295. export default {
  296. name: 'payment',
  297. data() {
  298. return {
  299. step: 1, // 1: 支付方式列表 2: 余额支付 3: 充值支付 4: 支付完成
  300. loading: true,
  301. salePlans: null,
  302. rechargeAddress: '',
  303. redeemStr: '',
  304. redeemNext: false,
  305. redeemLayer: false,
  306. buyData: {},
  307. payDisabled: false,
  308. waitRefresh: false,
  309. refreshRotate: false,
  310. currencyInfoData: {},
  311. currencyTimer: 0,
  312. achTimer: 0,
  313. maskUrlLink: ``,
  314. usdAmountData: {},
  315. Report: Report,
  316. }
  317. },
  318. head() {
  319. return {
  320. title: 'Buy NFT Mystery Box',
  321. }
  322. },
  323. components: {
  324. QrCode,
  325. FontZoom,
  326. FontZoomMobile,
  327. },
  328. mounted() {
  329. this.saleInfo()
  330. this.reportView(Report.pageSource.nftPaymentPage)
  331. },
  332. beforeDestroy() {
  333. clearTimeout(this.currencyTimer);
  334. },
  335. methods : {
  336. saleInfo () {
  337. postRequest(Api.getNftMysteryBoxSaleInfo, {
  338. params: {
  339. nftProjectId: this.$route.query.nftProjectId
  340. }
  341. }).then(res => {
  342. let { code, data } = res;
  343. if (code === 0) {
  344. this.salePlans = data.salePlans[0];
  345. this.getCurrencyInfoByCode();
  346. // 获取充值地址
  347. if (this.rechargeAddress === '') {
  348. this.getAddress()
  349. }
  350. }
  351. }).finally(() => {
  352. setTimeout(() => {
  353. this.loading = false;
  354. }, 600)
  355. })
  356. },
  357. getCurrencyInfoByCode() {
  358. postRequest(Api.getCurrencyInfoByCode, {
  359. params: {
  360. currencyCode: this.salePlans.currencyCode
  361. }
  362. }).then(res => {
  363. let { code, data } = res;
  364. if (code === 0) {
  365. this.currencyInfoData = data;
  366. }
  367. })
  368. // 计算金额
  369. postRequest(Api.calcRechargePayAmount, {
  370. params: {
  371. currencyCode: this.salePlans.currencyCode,
  372. orderAmountValue: this.salePlans.price,
  373. payChannel: 'ach'
  374. }
  375. }).then(res => {
  376. let { code, data } = res;
  377. if (code === 0) {
  378. this.usdAmountData = data;
  379. }
  380. })
  381. },
  382. getTokenRechargeRecord() {
  383. postRequest(Api.syncChainTokenRechargeRecord, {
  384. params: {
  385. currencyCode: this.salePlans.currencyCode
  386. }
  387. }).then(res => {
  388. let { code, data } = res;
  389. if (code === 0) {
  390. if (data.length > 0) {
  391. let currencyInfo = data[0];
  392. if (currencyInfo.currencyCode == this.currencyInfoData.currencyCode) {
  393. this.currencyInfoData.balance = currencyInfo.balance;
  394. }
  395. } else {
  396. this.currencyInfoData.balance = 0
  397. }
  398. }
  399. })
  400. },
  401. currencyInfoTimer() {
  402. clearTimeout(this.currencyTimer);
  403. this.currencyTimer = setTimeout(() => {
  404. this.currencyInfoTimer()
  405. this.getCurrencyInfoByCode()
  406. }, 10000);
  407. },
  408. checkUsdCurrencyInfo() {
  409. if (!this.refreshRotate) {
  410. this.refreshRotate = true;
  411. this.getCurrencyInfoByCode()
  412. setTimeout(() => {
  413. this.refreshRotate = false;
  414. }, 1000)
  415. // report
  416. this.reportDepositCashPageClick(Report.objectType.refreshBalanceButton)
  417. }
  418. },
  419. checkCurrencyInfo() {
  420. if (!this.refreshRotate) {
  421. this.refreshRotate = true;
  422. this.getTokenRechargeRecord()
  423. setTimeout(() => {
  424. this.refreshRotate = false;
  425. }, 1000)
  426. // report
  427. this.reportDepositTokenPageClick(Report.objectType.refreshBalanceButton)
  428. }
  429. },
  430. checkWaitInfo(isReport = true) {
  431. if (!this.refreshRotate) {
  432. this.refreshRotate = true;
  433. if (this.salePlans.currencyCode === 'USD') {
  434. this.getCurrencyInfoByCode()
  435. } else {
  436. this.getTokenRechargeRecord()
  437. }
  438. setTimeout(() => {
  439. this.refreshRotate = false;
  440. }, 1000)
  441. }
  442. if (isReport) {
  443. this.reportBalanceRefresh()
  444. }
  445. },
  446. showRedeem() {
  447. this.redeemStr = '';
  448. this.redeemNext = false;
  449. this.redeemLayer = true;
  450. this.$nextTick(() => {
  451. this.$refs.input.focus();
  452. })
  453. this.reportView(Report.pageSource.nftRedeemPage)
  454. this.reportPaymentBtnClick(Report.objectType.redeemButton)
  455. },
  456. textInput(e) {
  457. let len = 16
  458. let str = this.redeemStr.replace(/[^a-zA-Z0-9]/g, '')
  459. str = str.toUpperCase();
  460. str = str.slice(0, len);
  461. // set
  462. this.redeemStr = str;
  463. this.redeemNext = str !== '' && str.length === len;
  464. },
  465. textBlur(e) {
  466. let isiOS = !!window.navigator.userAgent.match(/\(i\[^;]+;( U;)? CPU.+Mac OS X/)
  467. if (isiOS) {
  468. setTimeout(() => {
  469. const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
  470. window.scrollTo(0, Math.max(scrollHeight - 1, 0))
  471. }, 100)
  472. }
  473. },
  474. textFocus(e) {
  475. let isiOS = !!window.navigator.userAgent.match(/\(i\[^;]+;( U;)? CPU.+Mac OS X/)
  476. if (isiOS) {
  477. setTimeout(() => {
  478. const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
  479. window.scrollTo(0, Math.max(scrollHeight - 1, 0))
  480. }, 100)
  481. }
  482. },
  483. redeemPayment() {
  484. if (!this.redeemNext) return;
  485. let params = {
  486. redeemCode: this.redeemStr,
  487. nftProjectId: this.$route.query.nftProjectId,
  488. }
  489. this.redeemNext = false;
  490. postRequest(Api.redeemNft, {
  491. params
  492. }).then(res => {
  493. let { code, data } = res;
  494. if (code === 0) {
  495. this.redeemLayer = false;
  496. if (data.length > 0) {
  497. this.buyData = data[0];
  498. }
  499. // 购买成功
  500. this.step = 4;
  501. } else {
  502. this.payError(code)
  503. }
  504. }).finally(() => {
  505. this.redeemNext = true;
  506. })
  507. this.reportRedeemBtnClick()
  508. },
  509. getAddress() {
  510. postRequest(Api.getTokenRechargeAddress, {
  511. params: {
  512. tokenChain: this.salePlans.currencyInfo?.tokenChain
  513. }
  514. }).then(res => {
  515. let { code, data } = res;
  516. if (code === 0) {
  517. this.rechargeAddress = data.rechargeAddress
  518. this.maskUrlToLink()
  519. }
  520. })
  521. },
  522. maskUrlToLink() {
  523. // MetaMask Link
  524. let url;
  525. let price = this.usdAmountData.rechargeAmountValue;
  526. if (this.salePlans.currencyInfo?.contractAddress) {
  527. // 代币
  528. url = maskUrl({
  529. target_address: this.salePlans.currencyInfo.contractAddress,
  530. parameters: {
  531. address: this.rechargeAddress,
  532. uint256: `${price}e${this.salePlans.currencyInfo?.decimalLength || 18}`
  533. }
  534. }, false)
  535. } else {
  536. // 主币
  537. url = maskUrl({
  538. target_address: this.rechargeAddress,
  539. parameters: {
  540. value: `${price}e${this.salePlans.currencyInfo?.decimalLength || 18}`
  541. }
  542. })
  543. }
  544. this.maskUrlLink = url;
  545. },
  546. goNext() {
  547. this.$router.push({
  548. path: `/nft/${this.$route.query.nftProjectId}/${this.$route.query.account}/show`,
  549. })
  550. },
  551. pay(isReport = true) {
  552. if (this.payDisabled || Number(this.usdAmountData.rechargeAmountValue) > 0) return;
  553. this.payDisabled = true;
  554. postRequest(Api.payNftMysteryBoxWithBalance, {
  555. params: {
  556. nftProjectId: this.$route.query.nftProjectId,
  557. salePlanId: this.salePlans.salePlanId,
  558. }
  559. }).then(res => {
  560. let { code, data } = res;
  561. if (code == 0) {
  562. if (data && data.buyItems.length > 0) {
  563. this.buyData = data.buyItems[0];
  564. }
  565. // 购买成功
  566. this.step = 4;
  567. } else {
  568. this.payError(code)
  569. }
  570. }).finally(() => {
  571. this.payDisabled = false;
  572. })
  573. // report
  574. if (isReport) {
  575. this.reportBalanceBuy()
  576. }
  577. },
  578. payUSD() {
  579. if (Number(this.usdAmountData.rechargeAmountValue) <= 0) {
  580. this.pay(false)
  581. this.reportDepositCashPageClick(Report.objectType.purchaseNftButton)
  582. }
  583. },
  584. payToken() {
  585. if (Number(this.currencyInfoData.balance) >= Number(this.salePlans.price)) {
  586. this.pay(false)
  587. this.reportDepositTokenPageClick(Report.objectType.purchaseNftButton)
  588. }
  589. },
  590. payError(code) {
  591. let msg;
  592. switch (code.toString()) {
  593. case '5001':
  594. msg = 'nft project not exist'
  595. break;
  596. case '5002':
  597. msg = 'nft project not available'
  598. break
  599. case '5101':
  600. msg = 'nft sale plan not exist'
  601. break
  602. case '5102':
  603. msg = 'nft sold out'
  604. break
  605. case '5103':
  606. msg = 'Purchase limit reached'
  607. break
  608. case '5104':
  609. case '5105':
  610. case '5106':
  611. msg = 'Invalid redemption code'
  612. break;
  613. default:
  614. msg = 'Invalid redemption code, please try again'
  615. break;
  616. }
  617. // Dialog
  618. Dialog({
  619. message: msg,
  620. confirmButtonText: 'OK',
  621. confirmButtonColor: '#1D9BF0',
  622. });
  623. },
  624. deNetPay() {
  625. if (!this.salePlans) return;
  626. let pageSource;
  627. if (this.salePlans.currencyCode === 'USD') {
  628. pageSource = Report.pageSource.nftDepositCashPage
  629. } else {
  630. pageSource = Report.pageSource.nftDepositTokenPage
  631. }
  632. if (Number(this.usdAmountData.rechargeAmountValue) > 0) {
  633. // 余额不够
  634. this.step = 3;
  635. this.currencyInfoTimer();
  636. // Report
  637. this.reportView(pageSource);
  638. } else {
  639. // 余额足够
  640. this.step = 2;
  641. this.reportView(Report.pageSource.nftBalancePage);
  642. }
  643. this.reportPaymentBtnClick(Report.objectType.denetPayButton)
  644. },
  645. maskPay() {
  646. if (Number(this.usdAmountData.rechargeAmountValue) > 0) {
  647. this.step = 2;
  648. this.waitRefresh = true;
  649. this.currencyInfoTimer();
  650. Dialog({
  651. message: `Was the pament successful?`,
  652. showCancelButton: true,
  653. confirmButtonText: 'YES',
  654. confirmButtonColor: '#1D9BF0',
  655. cancelButtonText: 'NO',
  656. cancelButtonColor: '#1D9BF0',
  657. }).then(() => {
  658. this.checkWaitInfo(false)
  659. }).catch(() => {
  660. this.checkWaitInfo(false)
  661. });
  662. this.reportView(Report.pageSource.nftPaymentBalancePage);
  663. } else {
  664. this.step = 2;
  665. this.reportView(Report.pageSource.nftBalancePage);
  666. }
  667. this.reportPaymentBtnClick(Report.objectType.metamaskPayButton)
  668. },
  669. achPay(modifyStep = true, objectType = '') {
  670. if (Number(this.usdAmountData.rechargeAmountValue) > 0) {
  671. if (modifyStep) {
  672. this.step = 2;
  673. this.reportView(Report.pageSource.nftPaymentBalancePage);
  674. }
  675. this.waitRefresh = true;
  676. this.currencyInfoTimer();
  677. Dialog({
  678. message: `Was the pament successful?`,
  679. showCancelButton: true,
  680. confirmButtonText: 'YES',
  681. confirmButtonColor: '#1D9BF0',
  682. cancelButtonText: 'NO',
  683. cancelButtonColor: '#1D9BF0',
  684. }).then(() => {
  685. this.checkWaitInfo(false)
  686. }).catch(() => {
  687. this.checkWaitInfo(false)
  688. });
  689. this.$nextTick(() => {
  690. let win = window.open();
  691. win.opener = null;
  692. win.location.href = `${location.protocol}//${location.host}/payment_ach/${this.usdAmountData.rechargeAmountValue}`;
  693. this.achTimer = setInterval(() => {
  694. console.log('pay')
  695. if (win && win.closed) {
  696. console.log('done')
  697. clearInterval(this.achTimer);
  698. }
  699. }, 500);
  700. })
  701. } else {
  702. if (modifyStep) {
  703. this.step = 2;
  704. this.reportView(Report.pageSource.nftBalancePage);
  705. }
  706. }
  707. if (objectType !== '') {
  708. this.reportPaymentBtnClick(objectType)
  709. } else {
  710. this.reportDepositCashPageClick(Report.objectType.depositButtion)
  711. }
  712. },
  713. copyErCode() {
  714. this.reportDepositTokenPageClick(Report.objectType.copyButtion)
  715. },
  716. reportView(pageSource) {
  717. Report.log({
  718. pageSource,
  719. params: {
  720. eventData: {
  721. businessType: Report.businessType.pageView,
  722. },
  723. extParams: {
  724. userAgent: window.navigator.userAgent,
  725. }
  726. }
  727. })
  728. },
  729. reportPaymentBtnClick(objectType) {
  730. Report.log({
  731. pageSource: Report.pageSource.nftPaymentPage,
  732. params: {
  733. eventData: {
  734. objectType,
  735. businessType: Report.businessType.buttonClick,
  736. },
  737. extParams: {
  738. userAgent: window.navigator.userAgent,
  739. }
  740. }
  741. })
  742. },
  743. reportRedeemBtnClick() {
  744. Report.log({
  745. pageSource: Report.pageSource.nftRedeemPage,
  746. params: {
  747. eventData: {
  748. objectType: Report.objectType.redeemButton,
  749. businessType: Report.businessType.buttonClick,
  750. },
  751. extParams: {
  752. userAgent: window.navigator.userAgent,
  753. }
  754. }
  755. })
  756. },
  757. reportDepositCashPageClick(objectType) {
  758. Report.log({
  759. pageSource: Report.pageSource.nftDepositCashPage,
  760. params: {
  761. eventData: {
  762. objectType,
  763. businessType: Report.businessType.buttonClick,
  764. },
  765. extParams: {
  766. userAgent: window.navigator.userAgent,
  767. }
  768. }
  769. })
  770. },
  771. reportDepositTokenPageClick(objectType) {
  772. Report.log({
  773. pageSource: Report.pageSource.nftDepositTokenPage,
  774. params: {
  775. eventData: {
  776. objectType,
  777. businessType: Report.businessType.buttonClick,
  778. },
  779. extParams: {
  780. userAgent: window.navigator.userAgent,
  781. }
  782. }
  783. })
  784. },
  785. reportBalanceRefresh() {
  786. let pageSource = this.waitRefresh ? Report.pageSource.nftPaymentBalancePage : Report.pageSource.nftBalancePage;
  787. Report.log({
  788. pageSource: pageSource,
  789. params: {
  790. eventData: {
  791. objectType: Report.objectType.refreshBalanceButton,
  792. businessType: Report.businessType.buttonClick,
  793. },
  794. extParams: {
  795. userAgent: window.navigator.userAgent,
  796. }
  797. }
  798. })
  799. },
  800. reportBalanceBuy() {
  801. let pageSource = this.waitRefresh ? Report.pageSource.nftPaymentBalancePage : Report.pageSource.nftBalancePage;
  802. Report.log({
  803. pageSource: pageSource,
  804. params: {
  805. eventData: {
  806. objectType: Report.objectType.purchaseNftButton,
  807. businessType: Report.businessType.buttonClick,
  808. },
  809. extParams: {
  810. userAgent: window.navigator.userAgent,
  811. }
  812. }
  813. })
  814. },
  815. }
  816. }
  817. </script>
  818. <style lang="scss">
  819. html,
  820. body,
  821. #__nuxt,
  822. #__layout {
  823. width: 100%;
  824. height: 100%;
  825. padding: 0;
  826. margin: 0;
  827. overflow: hidden;
  828. }
  829. .payment {
  830. width: 100%;
  831. height: 100%;
  832. }
  833. .moneyInfo {
  834. display: flex;
  835. align-items: center;
  836. justify-content: center;
  837. flex-direction: column;
  838. height: 90px;
  839. border-bottom: solid 8px rgba($color: #f5f5f5, $alpha: .6);
  840. .tips {
  841. font-size: 12px;
  842. font-weight: 500;
  843. }
  844. .money {
  845. display: flex;
  846. align-items: center;
  847. justify-content: center;
  848. margin-top: 10px;
  849. color: #000;
  850. font-size: 20px;
  851. font-weight: 700;
  852. .icon {
  853. overflow: hidden;
  854. width: 26px;
  855. height: 26px;
  856. border-radius: 50%;
  857. margin-right: 10px;
  858. vertical-align: middle;
  859. background-color: #f5f5f5;
  860. }
  861. .info {
  862. &.usd {
  863. margin-top: -5px;
  864. }
  865. }
  866. }
  867. }
  868. .payList {
  869. overflow-y: auto;
  870. height: calc(100% - 90px);
  871. .detail {
  872. padding: 18px 16px;
  873. .title {
  874. color: #ADADAD;
  875. height: 26px;
  876. font-size: 12px;
  877. font-weight: 500;
  878. }
  879. .item {
  880. position: relative;
  881. display: flex;
  882. align-items: center;
  883. justify-content: center;
  884. font-weight: 500;
  885. font-size: 16px;
  886. height: 50px;
  887. margin-bottom: 14px;
  888. border-radius: 100px;
  889. border: 1px solid #ECECEC;
  890. &:last-child {
  891. margin-bottom: 0;
  892. }
  893. img {
  894. width: 24px;
  895. height: 24px;
  896. margin-right: 4px;
  897. }
  898. &.denet {
  899. flex-direction: column;
  900. img {
  901. margin-top: -6px;
  902. }
  903. }
  904. .wallet {
  905. width: 100%;
  906. overflow: hidden;
  907. color: #ADADAD;
  908. font-size: 11px;
  909. text-align: center;
  910. margin-top: -2px;
  911. }
  912. .maskLink {
  913. position: absolute;
  914. z-index: 10;
  915. width: 100%;
  916. height: 100%;
  917. }
  918. }
  919. }
  920. }
  921. .loading {
  922. position: absolute;
  923. z-index: 3;
  924. display: flex;
  925. align-items: center;
  926. justify-content: center;
  927. top: 0;
  928. left: 0;
  929. width: 100%;
  930. height: 100%;
  931. }
  932. .loadingBg {
  933. position: absolute;
  934. z-index: 2;
  935. top: 0;
  936. left: 0;
  937. width: 100%;
  938. height: 100%;
  939. background-color: rgba($color: #000, $alpha: .1);
  940. }
  941. .redeem {
  942. padding: 18px 16px 38px;
  943. .tips {
  944. height: 31px;
  945. font-size: 15px;
  946. font-weight: 500;
  947. }
  948. .footer {
  949. display: flex;
  950. justify-content: space-between;
  951. .input {
  952. display: flex;
  953. align-items: center;
  954. justify-content: center;
  955. width: calc(100% - 93px);
  956. height: 45px;
  957. border-radius: 5px;
  958. border: 1px solid #E0E0E0;
  959. input {
  960. width: 94%;
  961. border: 0;
  962. outline: 0;
  963. }
  964. }
  965. .enter {
  966. width: 83px;
  967. height: 45px;
  968. border: 0;
  969. padding: 0;
  970. color: #ffffff;
  971. font-size: 17px;
  972. font-weight: 500;
  973. border-radius: 5px;
  974. background: #1D9BF0;
  975. &.disable {
  976. background: #DEDEDE;
  977. }
  978. }
  979. }
  980. }
  981. .payInfo {
  982. width: 100%;
  983. height: calc(100% - 88px);
  984. .picShow {
  985. padding: 54px 48px;
  986. .tip {
  987. height: 44px;
  988. font-size: 18px;
  989. font-weight: 600;
  990. text-align: center;
  991. }
  992. .pic {
  993. display: block;
  994. margin: auto;
  995. width: 280px;
  996. height: 280px;
  997. border-radius: 3px;
  998. margin-bottom: 20px;
  999. }
  1000. .name {
  1001. font-size: 18px;
  1002. font-weight: 600;
  1003. line-height: 21px;
  1004. text-align: center;
  1005. }
  1006. }
  1007. }
  1008. .payBtn {
  1009. padding: 0 16px 38px;
  1010. .btn {
  1011. width: 100%;
  1012. height: 50px;
  1013. color: #FFFFFF;
  1014. font-size: 18px;
  1015. font-weight: 700;
  1016. border-radius: 50px;
  1017. background: #1D9BF0;
  1018. }
  1019. }
  1020. .balanceTop {
  1021. display: flex;
  1022. align-items: center;
  1023. justify-content: center;
  1024. flex-direction: column;
  1025. height: calc(100% - 100px);
  1026. background-color: #f5f5f5;
  1027. .balance {
  1028. width: 66px;
  1029. height: 66px;
  1030. margin-bottom: 6px;
  1031. }
  1032. .text {
  1033. font-size: 15px;
  1034. font-weight: 500;
  1035. line-height: 18px;
  1036. color: #9D9D9D;
  1037. }
  1038. .money {
  1039. font-size: 22px;
  1040. font-weight: 700;
  1041. line-height: 26px;
  1042. margin-top: 6px;
  1043. .icon {
  1044. width: 22px;
  1045. height: 22px;
  1046. margin-right: 6px;
  1047. }
  1048. .font {
  1049. color: #000;
  1050. }
  1051. }
  1052. }
  1053. .balanceInfo {
  1054. overflow-y: auto;
  1055. height: calc(100% - 100px);
  1056. background-color: #f5f5f5;
  1057. .top {
  1058. padding: 0 16px 17px 16px;
  1059. background-color: #ffffff;
  1060. .item {
  1061. display: flex;
  1062. align-items: center;
  1063. height: 54px;
  1064. border-bottom: solid 1px #F2F2F2;
  1065. &.title {
  1066. font-size: 16px;
  1067. font-weight: 600;
  1068. line-height: 19px;
  1069. img {
  1070. width: 26px;
  1071. height: 26px;
  1072. margin-right: 6px;
  1073. }
  1074. }
  1075. &.column {
  1076. color: rgba($color: #5E5E5E, $alpha: .7);
  1077. font-size: 14px;
  1078. font-weight: 400;
  1079. .l {
  1080. width: 70px;
  1081. }
  1082. .r {
  1083. img {
  1084. width: 21px;
  1085. height: 21px;
  1086. margin-right: 4px;
  1087. }
  1088. span {
  1089. color: rgba($color: #5E5E5E, $alpha: .7);
  1090. }
  1091. }
  1092. }
  1093. &.usd {
  1094. font-size: 14px;
  1095. font-weight: 500;
  1096. justify-content: space-between;
  1097. .fontPayment {
  1098. font-size: 18px;
  1099. font-weight: 600;
  1100. }
  1101. .font {
  1102. color: #9A9A9A;
  1103. font-size: 16px;
  1104. font-weight: 500;
  1105. }
  1106. .fontDeposit {
  1107. color: #1D9BF0;
  1108. font-size: 18px;
  1109. font-weight: 600;
  1110. }
  1111. }
  1112. }
  1113. .deposit {
  1114. display: flex;
  1115. align-items: center;
  1116. justify-content: center;
  1117. height: 54px;
  1118. color: #ffffff;
  1119. font-weight: 600;
  1120. font-size: 18px;
  1121. margin-top: 16px;
  1122. border-radius: 54px;
  1123. background: #1D9BF0;
  1124. }
  1125. .address {
  1126. color: rgba($color: #5E5E5E, $alpha: .7);
  1127. .title {
  1128. height: 42px;
  1129. font-size: 14px;
  1130. font-weight: 400;
  1131. line-height: 42px;
  1132. }
  1133. }
  1134. .notice {
  1135. display: flex;
  1136. justify-content: space-between;
  1137. padding: 10px;
  1138. margin-top: 12px;
  1139. border-radius: 8px;
  1140. background: #F9F6EE;
  1141. .icon {
  1142. width: 20px;
  1143. margin-right: 10px;
  1144. img {
  1145. width: 20px;
  1146. height: 20px;
  1147. }
  1148. }
  1149. .text {
  1150. flex: 1;
  1151. color: rgba($color: #5E5E5E, $alpha: .7);
  1152. font-size: 14px;
  1153. font-weight: 400;
  1154. line-height: 19px;
  1155. word-break: break-all;
  1156. strong {
  1157. color: #FF0000;
  1158. font-weight: bold;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. .line {
  1164. height: 8px;
  1165. }
  1166. .balance {
  1167. display: flex;
  1168. align-items: center;
  1169. padding: 0 16px;
  1170. height: 54px;
  1171. background-color: #ffffff;
  1172. .icon {
  1173. width: 24px;
  1174. margin-right: 6px;
  1175. img {
  1176. width: 24px;
  1177. }
  1178. }
  1179. .text {
  1180. flex: 1;
  1181. font-size: 14px;
  1182. font-weight: 500;
  1183. line-height: 17px;
  1184. span {
  1185. color: #000;
  1186. margin-right: auto;
  1187. }
  1188. }
  1189. .refresh {
  1190. width: 24px;
  1191. height: 24px;
  1192. img {
  1193. width: 24px;
  1194. transform-origin: center center;
  1195. }
  1196. }
  1197. }
  1198. }
  1199. .balanceBot {
  1200. display: flex;
  1201. justify-content: space-between;
  1202. width: 100%;
  1203. padding: 17px 16px 38px;
  1204. border-top: solid 1px #ECECEC;
  1205. .l {
  1206. display: flex;
  1207. flex-direction: column;
  1208. justify-content: center;
  1209. }
  1210. .neet {
  1211. font-size: 12px;
  1212. font-weight: 500;
  1213. line-height: 14px;
  1214. }
  1215. .money {
  1216. height: 22px;
  1217. line-height: 22px;
  1218. font-size: 18px;
  1219. font-weight: 700;
  1220. margin-top: 4px;
  1221. .text {
  1222. margin-right: auto;
  1223. }
  1224. }
  1225. .btn {
  1226. display: flex;
  1227. align-items: center;
  1228. justify-content: center;
  1229. width: 110px;
  1230. height: 46px;
  1231. color: #ffffff;
  1232. font-size: 18px;
  1233. font-weight: 700;
  1234. line-height: 21px;
  1235. border-radius: 46px;
  1236. background: #1D9BF0;
  1237. &.disable {
  1238. background: #D2D2D2;
  1239. }
  1240. }
  1241. }
  1242. .waitFont {
  1243. margin-top: 16px;
  1244. padding: 0 20px;
  1245. font-size: 14px;
  1246. font-weight: 500;
  1247. line-height: 17px;
  1248. text-align: center;
  1249. }
  1250. .waitBtn {
  1251. display: flex;
  1252. align-items: center;
  1253. justify-content: center;
  1254. width: 50px;
  1255. height: 50px;
  1256. margin: 50px auto 0;
  1257. border-radius: 50%;
  1258. background-color: #ffffff;
  1259. img {
  1260. width: 24px;
  1261. height: 24px;
  1262. }
  1263. }
  1264. .icon-refresh-rotate {
  1265. transform: rotate(360deg);
  1266. transition-duration: 1s;
  1267. }
  1268. </style>