|
@@ -0,0 +1,828 @@
|
|
|
+<script setup>
|
|
|
+import { onMounted, ref, getCurrentInstance, nextTick, onUnmounted, computed, watch } from 'vue'
|
|
|
+import { country } from '../../../utils/country.js'
|
|
|
+import Arrow from '@/components/icon/left_arrow.vue'
|
|
|
+import Info from '@/components/icon/info.vue'
|
|
|
+import { get, postWithHeader } from '../../../utils/request'
|
|
|
+import { userStore } from '@/store/userInfo'
|
|
|
+const { proxy } = getCurrentInstance()
|
|
|
+
|
|
|
+const CountryOption = country()
|
|
|
+const baseUrl = import.meta.env.VITE_STORE_DOMIN
|
|
|
+const id = proxy.$route.params.id
|
|
|
+const codeMap = {
|
|
|
+ '0': {
|
|
|
+ title: "LynxPDF Editor (Enterprise)",
|
|
|
+ desc: "Cost-Effective PDF Solution Tailored to Your Business",
|
|
|
+ code: "com.brother.pdftecheditor"
|
|
|
+ },
|
|
|
+ '1': {
|
|
|
+ title: "PDF Reader Pro Cross-Platform",
|
|
|
+ desc: "Mac + Windows",
|
|
|
+ code: "com.brother.pdfreaderpro.cross.platform.product_3"
|
|
|
+ },
|
|
|
+ '2': {
|
|
|
+ title: "PDF Reader Pro Permanent for Mac",
|
|
|
+ desc: "All-in-One & Affordable PDF Solution",
|
|
|
+ code: "com.brother.pdfreaderpro.mac.product_3"
|
|
|
+ },
|
|
|
+ '3': {
|
|
|
+ title: "PDF Reader Pro Premium for Mac",
|
|
|
+ desc: "All-in-One & Affordable PDF Solution",
|
|
|
+ code: "com.brother.pdfreaderpro.mac.product_1"
|
|
|
+ },
|
|
|
+ '4': {
|
|
|
+ title: "PDF Reader Pro Permanent for Windows",
|
|
|
+ desc: "All-in-One & Affordable PDF Solution",
|
|
|
+ code: "com.brother.pdfreaderpro.windows.product_3"
|
|
|
+ },
|
|
|
+ '5': {
|
|
|
+ title: "PDF Reader Pro Premium for Windows",
|
|
|
+ desc: "All-in-One & Affordable PDF Solution",
|
|
|
+ code: "com.brother.pdfreaderpro.windows.product_1"
|
|
|
+ }
|
|
|
+}
|
|
|
+const product = codeMap[id]
|
|
|
+const productNum = ref(1)
|
|
|
+
|
|
|
+const payMethod = ref('paypal')
|
|
|
+const countryCode = ref('US')
|
|
|
+const postCode = ref('')
|
|
|
+const paypalLoading = ref(true)
|
|
|
+const paddleShow = ref(true)
|
|
|
+const paymentID = ref(null)
|
|
|
+
|
|
|
+// 回到上一级
|
|
|
+const goBack = () => {
|
|
|
+ if (!document.referrer) {
|
|
|
+ window.location.href = '/product'
|
|
|
+ return
|
|
|
+ }
|
|
|
+ window.history.back()
|
|
|
+}
|
|
|
+// 获取用户信息
|
|
|
+const useInfo = ref({})
|
|
|
+const updataUserInfo = () => {
|
|
|
+ get(
|
|
|
+ '/pdf-tech/vppMember/getMemberInfo'
|
|
|
+ ).then((res) => {
|
|
|
+ if (res.data.code === 200 && res.data.msg == 'success') {
|
|
|
+ useInfo.value = res.data.result
|
|
|
+ if (useInfo.value.role !== '1') {
|
|
|
+ window.location.href = '/non-admin-user'
|
|
|
+ }
|
|
|
+ getCommodityInfo()
|
|
|
+ } else {
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 获取订单信息
|
|
|
+const commodityInfo = ref({})
|
|
|
+const getCommodityInfo = () => {
|
|
|
+ get(
|
|
|
+ baseUrl + '/api/shopping-cart/accumulated-discount?vpp_member_id=' + useInfo.value.id + '&product_code=' + product.code + '&number=' + productNum.value
|
|
|
+ ).then((res) => {
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ commodityInfo.value = res.data.data
|
|
|
+ allNum.value = commodityInfo.value.purchase_quantity
|
|
|
+ } else {
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const allNum = ref(1)
|
|
|
+let useTeamDiscount = computed(() => {
|
|
|
+ if (allNum.value >= 2 && allNum.value <= 4) {
|
|
|
+ return '15%'
|
|
|
+ } else if (allNum.value >= 5 && allNum.value <= 9) {
|
|
|
+ return '25%'
|
|
|
+ } else if (allNum.value >= 10 && allNum.value <= 29) {
|
|
|
+ return '30%'
|
|
|
+ } else if (allNum.value >= 30 && allNum.value <= 99) {
|
|
|
+ return '35%'
|
|
|
+ } else if (allNum.value >= 100) {
|
|
|
+ return '45%'
|
|
|
+ } else {
|
|
|
+ return '100%'
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+watch(productNum, () => {
|
|
|
+ if (productNum.value > 100 && paddleShow.value) {
|
|
|
+ paddleShow.value = false
|
|
|
+ if (payMethod.value === 'paddle') {
|
|
|
+ payMethod.value = 'paypal'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (productNum.value <= 100 && !paddleShow.value) {
|
|
|
+ paddleShow.value = true
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// 查询支付状态
|
|
|
+const getState = (trade_no, payMethod) => {
|
|
|
+ get(
|
|
|
+ baseUrl + '/api/subscriptions/payed_callback?out_trade_no=' + trade_no
|
|
|
+ )
|
|
|
+ .then(function (res) {
|
|
|
+ if ((Object.keys(res.data.data).length !== 0) && res.data.data.subscription.status === 'actived') {
|
|
|
+ const url = '/product/pay??out_trade_no=' + trade_no
|
|
|
+ window.location.href = url
|
|
|
+ } else if (payMethod && payMethod === 'paddle') {
|
|
|
+ paddleTimer.value = setTimeout(getState, 1000, trade_no, 'paddle')
|
|
|
+ } else {
|
|
|
+ timer.value = setTimeout(getState, 4000, trade_no, payMethod)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(function (error) {
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ console.error('server error', error, payMethod, trade_no)
|
|
|
+ })
|
|
|
+}
|
|
|
+// 获取支付data
|
|
|
+const getRequestData = (payMethod) => {
|
|
|
+ let payment = null
|
|
|
+ switch (payMethod) {
|
|
|
+ case 'paypal':
|
|
|
+ payment = 0
|
|
|
+ break
|
|
|
+ case 'alipay':
|
|
|
+ payment = 1
|
|
|
+ break
|
|
|
+ case 'wxpay':
|
|
|
+ payment = 2
|
|
|
+ break
|
|
|
+ case 'paddle':
|
|
|
+ payment = 3
|
|
|
+ break
|
|
|
+ }
|
|
|
+ let data = {
|
|
|
+ vpp_member_id: useInfo.value.id,
|
|
|
+ type: 1,
|
|
|
+ product_code: product.code,
|
|
|
+ number: productNum.value,
|
|
|
+ customer_country: countryCode.value,
|
|
|
+ customer_postcode: postCode.value,
|
|
|
+ payment: payment
|
|
|
+ }
|
|
|
+ return { data }
|
|
|
+}
|
|
|
+// 绑定paypal按钮
|
|
|
+const bindPaypalBtn = async () => {
|
|
|
+ if (document.getElementById('paypal-button') !== undefined) {
|
|
|
+ //@ts-ignore
|
|
|
+ await paypal.Button.render({
|
|
|
+ locale: 'en_US',
|
|
|
+ env: import.meta.env.MODE === 'production' ? 'production' : 'sandbox',
|
|
|
+ commit: false, // Show a 'Pay Now' button
|
|
|
+ client: {
|
|
|
+ sandbox: import.meta.env.VITE_KEY_DATA,
|
|
|
+ production: import.meta.env.VITE_KEY_DATA
|
|
|
+ },
|
|
|
+
|
|
|
+ style: {
|
|
|
+ layout: 'horizontal',
|
|
|
+ label: 'buynow',
|
|
|
+ fundingicons: false, // optional
|
|
|
+ branding: true, // optional
|
|
|
+ size: 'responsive', // small | medium | large | responsive
|
|
|
+ shape: 'rect', // pill | rect
|
|
|
+ color: 'blue', // gold | blue | silve | black
|
|
|
+ tagline: false,
|
|
|
+ height: 46
|
|
|
+ },
|
|
|
+
|
|
|
+ // payment() is called when the button is clicked
|
|
|
+ async payment() {
|
|
|
+ const { data } = getRequestData('paypal')
|
|
|
+ return postWithHeader(baseUrl + '/api/order/create', data)
|
|
|
+ .then(function (res) {
|
|
|
+ console.log(res)
|
|
|
+ paymentID.value = res.data.data.third_order_no
|
|
|
+ return res.data.data.third_order_no
|
|
|
+ })
|
|
|
+ .catch(function (err) {
|
|
|
+ console.log('err', err)
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onAuthorize(data, actions) {
|
|
|
+ const EXECUTE_URL = baseUrl + '/api/subscriptions/payed_callback?payment_id=' + data.paymentID
|
|
|
+ console.info('approved', data, actions)
|
|
|
+
|
|
|
+ return actions.payment.execute().then(function (payment) {
|
|
|
+ // The payment is complete!
|
|
|
+ // You can now show a confirmation message to the customer
|
|
|
+ //@ts-ignore
|
|
|
+ paypal.request.get(EXECUTE_URL)
|
|
|
+ .then(function (res) {
|
|
|
+ if (res.data && res.data.state === 'pending') {
|
|
|
+ pendingShow.value = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (res.data && res.data.subscription) {
|
|
|
+ const url = '/product/pay?payment_id=' + data.paymentID
|
|
|
+ window.location.href = url
|
|
|
+ } else {
|
|
|
+ alert('Your purchase is failed!\nPlease let us known if you have payed.')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(function (err) {
|
|
|
+ console.log(err)
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onCancel(data, actions) {
|
|
|
+ /*
|
|
|
+ * Buyer cancelled the payment
|
|
|
+ */
|
|
|
+ console.info('cancelled', data, actions)
|
|
|
+ },
|
|
|
+ onError(err) {
|
|
|
+ console.info('err', err)
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ }
|
|
|
+ }, '#paypal-button')
|
|
|
+ paypalLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+// 动态加载paypal的js文件
|
|
|
+const initTimer = ref(null)
|
|
|
+const createPaypal = () => {
|
|
|
+ const scriptElement = document.createElement('script')
|
|
|
+ scriptElement.src = `https://www.paypalobjects.com/api/checkout.js`
|
|
|
+ scriptElement.defer = true
|
|
|
+ document.head.appendChild(scriptElement)
|
|
|
+
|
|
|
+ scriptElement.onload = () => {
|
|
|
+ initTimer.value = setInterval(() => {
|
|
|
+ if (paypal && paypal.Button) {
|
|
|
+ clearInterval(initTimer.value)
|
|
|
+ bindPaypalBtn()
|
|
|
+ }
|
|
|
+ }, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 初始化paddle
|
|
|
+const paddleTimer = ref(null)
|
|
|
+const timer = ref(null)
|
|
|
+const initPaddle = () => {
|
|
|
+ if (import.meta.env.MODE !== 'production') {
|
|
|
+ //@ts-ignore
|
|
|
+ Paddle.Environment.set('sandbox')
|
|
|
+ }
|
|
|
+ //@ts-ignore
|
|
|
+ Paddle.Setup({
|
|
|
+ vendor: Number(import.meta.env.VITE_VENDOR_DATA),
|
|
|
+ eventCallback(data) {
|
|
|
+ // The data.event will specify the event type
|
|
|
+ if (data.event === 'Checkout.Complete') {
|
|
|
+ proxy.$route.query.debug && console.log(data.eventData) // Data specifics on the event
|
|
|
+ // Get the state of the transaction
|
|
|
+ paddleTimer.value = setTimeout(getState, 1000, data.eventData.checkout.passthrough, 'paddle')
|
|
|
+ } else if (data.event === 'Checkout.Close') {
|
|
|
+ console.log('Cancel') // Data specifics on the event
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+const isLoading = ref(false)
|
|
|
+const loading = ref(true)
|
|
|
+const qrcode = ref('')
|
|
|
+const wxpayShow = ref(false)
|
|
|
+
|
|
|
+// 购买
|
|
|
+const payNow = () => {
|
|
|
+ if (isLoading.value) { return }
|
|
|
+ isLoading.value = true
|
|
|
+ if (payMethod.value === 'wxpay' || payMethod.value === 'alipay') {
|
|
|
+ wxpayShow.value = true
|
|
|
+ loading.value = true
|
|
|
+ }
|
|
|
+ const { data } = getRequestData(payMethod.value)
|
|
|
+ postWithHeader(baseUrl + '/api/order/create', data)
|
|
|
+ .then((res) => {
|
|
|
+ isLoading.value = false
|
|
|
+ if (timer.value) {
|
|
|
+ clearTimeout(timer.value)
|
|
|
+ }
|
|
|
+ if (payMethod.value === 'wxpay') {
|
|
|
+ console.log(res.data.data.page_pay_url)
|
|
|
+ loading.value = false
|
|
|
+ qrcode.value = res.data.data.page_pay_url
|
|
|
+ let trade_no = res.data.data.page_pay_url.split('/')
|
|
|
+ trade_no = trade_no[trade_no.length - 1].split('.')[0]
|
|
|
+ timer.value = setTimeout(getState, 4000, trade_no, payMethod.value)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (payMethod.value === 'alipay' && /.png$/.test(res.data.data.page_pay_url)) {
|
|
|
+ console.log('createPayment: ', res.data.data.page_pay_url)
|
|
|
+ loading.value = false
|
|
|
+ qrcode.value = res.data.data.page_pay_url
|
|
|
+ timer.value = setTimeout(getState, 4000, res.data.data.trade_no, payMethod.value)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (payMethod.value === 'paddle') {
|
|
|
+ Paddle.Checkout.open({
|
|
|
+ override: res.data.data.page_pay_url
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ console.log('createPayment: ', res.data.subscription.alipay_order.page_pay_url)
|
|
|
+ window.location.href = res.data.subscription.alipay_order.page_pay_url
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ window.location.href = '/product/pay'
|
|
|
+ isLoading.value = false
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+}
|
|
|
+// 支付弹窗
|
|
|
+const closeWXpayShow = () => {
|
|
|
+ wxpayShow.value = false
|
|
|
+ clearTimeout(timer.value)
|
|
|
+}
|
|
|
+
|
|
|
+updataUserInfo()
|
|
|
+onMounted(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ createPaypal()
|
|
|
+ })
|
|
|
+ initPaddle()
|
|
|
+})
|
|
|
+onUnmounted(() => {
|
|
|
+ if (initTimer.value) {
|
|
|
+ clearInterval(initTimer.value)
|
|
|
+ }
|
|
|
+ if (paddleTimer.value) {
|
|
|
+ clearInterval(paddleTimer.value)
|
|
|
+ }
|
|
|
+ if (timer.value) {
|
|
|
+ clearInterval(paddleTimer.value)
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="min-h-100vh bg-[#E7EAEE] py-48px px-120px">
|
|
|
+ <div class="font-700 text-28px leading-40px text-[#232A40]">Add Licenses</div>
|
|
|
+ <div @click="goBack"
|
|
|
+ class="mt-16px inline-flex items-center text-[#1460F3] cursor-pointer pb-16px border-b-1px border-[#0000001A]">
|
|
|
+ <Arrow class="mr-6px" />
|
|
|
+ Back
|
|
|
+ </div>
|
|
|
+ <div class="pt-32px flex justify-between border-t-1px border-[#0000001A]">
|
|
|
+ <div>
|
|
|
+ <div class="font-700 text-[#232A40] text-16px leading-20px">Review Your Order</div>
|
|
|
+ <table class="mt-24px">
|
|
|
+ <tr>
|
|
|
+ <td class="text-14px leading-20px font-700 text-[#232A40] pr-40px">Super Admin Email</td>
|
|
|
+ <td class="text-14px leading-20px text-[#232A40]">{{ useInfo.email }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="text-14px leading-20px font-700 text-[#232A40] pt-16px pr-40px">Organization Name</td>
|
|
|
+ <td class="text-14px leading-20px text-[#232A40] pt-17px">{{ useInfo.company }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="text-14px leading-20px font-700 text-[#232A40] pt-16px pr-40px">User Name</td>
|
|
|
+ <td class="text-14px leading-20px text-[#232A40] pt-17px">{{ useInfo.fullName }}</td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="font-700 text-16px leading-20px text-[#232A40]">You’re Adding</div>
|
|
|
+ <div class="card w-500px rounded-8px p-40px bg-[#fff] mt-12px">
|
|
|
+ <div class="flex">
|
|
|
+ <img v-if="id === '1'" src="@/assets/images/cross.png" alt="logo" class="h-48px">
|
|
|
+ <img v-else src="@/assets/images/logo.png" alt="logo" class="h-48px">
|
|
|
+ <div class="ml-20px">
|
|
|
+ <div class="font-700 leading-20px text-16px text-[#232A40]">{{ product.title }}</div>
|
|
|
+ <div class="leading-20px text-14px text-[#505258] mt-4px">{{ product.desc }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mt-32px font-700 text-14px leading-20px text-[#232A40]">
|
|
|
+ Authorized Devices
|
|
|
+ </div>
|
|
|
+ <div class="recommend-icon text-14px leading-20px text-[#808185] cursor-pointer">
|
|
|
+ <span v-show="commodityInfo.next_number">
|
|
|
+ Authorize another <span class="text-[#232A40]">{{ commodityInfo.next_number }}
|
|
|
+ <span v-if="commodityInfo.next_number !== 1">devices</span>
|
|
|
+ <span v-else>device</span></span> to upgrade to
|
|
|
+ <span class="text-[#232A40]">{{ commodityInfo.next_discount }} OFF</span>
|
|
|
+ </span>
|
|
|
+ <span v-show="!commodityInfo.next_number">
|
|
|
+ <a href="mailto:support@pdfreaderpro.com?subject=Feedback from Admin Console"
|
|
|
+ class="text-[#1460F3] hover:underline">Contact us</a> for a higher discount.
|
|
|
+ </span>
|
|
|
+ <Info class="ml-8px inline-block mb-4px" />
|
|
|
+ <div class="tip">
|
|
|
+ You have currently authorized {{ commodityInfo.purchase_quantity }} devices
|
|
|
+ <div>Authorize 2 devices cumulatively: 15% OFF</div>
|
|
|
+ <div>Authorize 5 devices cumulatively: 25% OFF</div>
|
|
|
+ <div>Authorize 10 devices cumulatively: 30% OFF</div>
|
|
|
+ <div>Authorize 30 devices cumulatively: 35% OFF</div>
|
|
|
+ <div>Authorize 100 devices cumulatively:: 45% OFF</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mt-16px pb-32px border-[#0000001A] border-b-1px">
|
|
|
+ <el-input-number v-model="productNum" :precision="0" @change="getCommodityInfo" controls-position="right"
|
|
|
+ :min="1"></el-input-number>
|
|
|
+ </div>
|
|
|
+ <div class="flex justify-between mt-32px">
|
|
|
+ <div class="text-14px font-700 leading-20px text-[#232A40]">Discount</div>
|
|
|
+ <div class="text-16px leading-20px font-700 text-[#FF5054]"><span
|
|
|
+ v-show="useTeamDiscount !== commodityInfo.discount">Upgrade to</span> {{ commodityInfo.discount }} OFF
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex justify-between mt-12px items-center">
|
|
|
+ <div class="text-14px font-700 leading-20px text-[#232A40]">Total Price</div>
|
|
|
+ <!-- 数据没回来之前不展示 -->
|
|
|
+ <template v-if="commodityInfo.discount_price">
|
|
|
+ <div v-show="payMethod === 'paypal' || payMethod === 'paddle'"
|
|
|
+ class="text-28px leading-40px font-700 text-[#232A40]">
|
|
|
+ <span class="text-16px font-400 text-[#808185] line-through">${{ commodityInfo.price }}</span>
|
|
|
+ ${{ commodityInfo.discount_price }}
|
|
|
+ </div>
|
|
|
+ <div v-show="payMethod === 'wxpay' || payMethod === 'alipay'"
|
|
|
+ class="text-28px leading-40px font-700 text-[#232A40]">
|
|
|
+ <span class="text-16px font-400 text-[#808185] line-through">¥{{ commodityInfo.cny_price }}</span>
|
|
|
+ ¥{{ commodityInfo.discount_cny_price }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div v-else class="h-40px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="method-container">
|
|
|
+ <div class="paypal-btn pay-btn" :class="{ active: payMethod === 'paypal' }" @click="payMethod = 'paypal'">
|
|
|
+ <img loading="lazy" src="@/assets/images/store/order_box.png" alt="select pic">
|
|
|
+ </div>
|
|
|
+ <div v-if="paddleShow" class="card-btn pay-btn" :class="{ active: payMethod === 'paddle' }"
|
|
|
+ @click="payMethod = 'paddle'">
|
|
|
+ <img loading="lazy" src="@/assets/images/store/order_box.png" alt="select pic">
|
|
|
+ </div>
|
|
|
+ <div class="wxpay-btn pay-btn pay-btn-cny" :class="{ active: payMethod === 'wxpay' }"
|
|
|
+ @click="payMethod = 'wxpay'">
|
|
|
+ <img loading="lazy" src="@/assets/images/store/order_box.png" alt="select pic">
|
|
|
+ </div>
|
|
|
+ <div class="ali-btn pay-btn pay-btn-cny" :class="{ active: payMethod === 'alipay' }"
|
|
|
+ @click="payMethod = 'alipay'">
|
|
|
+ <img loading="lazy" src="@/assets/images/store/order_box.png" alt="select pic">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="payMethod === 'paddle'" class="info-message flex justify-center items-center mt-16px">
|
|
|
+ <select v-model="countryCode" name="countryCode"
|
|
|
+ class="w-[60%] border-1 border-[#E2E3E5] leading-40px h-40px">
|
|
|
+ <option disabled value>Select a country</option>
|
|
|
+ <option v-for="(item, index) in CountryOption" :key="index" :value="item.code">{{ item.name }}
|
|
|
+ </option>
|
|
|
+ </select>
|
|
|
+ <input v-model.trim="postCode" type="text" name="Postcode" placeholder="Postcode"
|
|
|
+ class="border-1 border-[#E2E3E5] ml-12px rounded-4px leading-40px px-8px text-[#888C94]">
|
|
|
+ </div>
|
|
|
+ <div v-if="payMethod !== 'paypal'"
|
|
|
+ class="mt-24px cursor-pointer leading-48px text-center bg-[#0097ff] rounded-8px text-16px font-700 text-[#fff] hover:bg-[#1460F3]"
|
|
|
+ @click="payNow">Continue to Checkout</div>
|
|
|
+ <button v-show="!paypalLoading && payMethod === 'paypal'" id="paypal-button" class="w-[100%] mt-24px"></button>
|
|
|
+ <div v-if="paypalLoading && payMethod === 'paypal'" class="load-container">
|
|
|
+ <svg class="load" x="0px" y="0px" viewBox="0 0 150 150">
|
|
|
+ <circle id="loading-inner" cx="75" cy="75" r="50" />
|
|
|
+ </svg>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 支付弹窗 -->
|
|
|
+ <div v-show="wxpayShow" class="wxpay-container">
|
|
|
+ <div class="wxpay-content">
|
|
|
+ <span class="wx-close" @click="closeWXpayShow"></span>
|
|
|
+ <div class="title">{{ payMethod === 'wxpay' ? 'Wechat Pay' : 'Alipay' }}</div>
|
|
|
+ <span class="img-container">
|
|
|
+ <template v-if="loading">
|
|
|
+ <img loading="lazy" class="loading" src="@/assets/images/store/loading.gif" alt="loading icon">
|
|
|
+ <div class="loading">Loading ...</div>
|
|
|
+ </template>
|
|
|
+ <img v-else loading="lazy" class="qrcode" :src="qrcode" alt="QR code">
|
|
|
+ </span>
|
|
|
+ <p class="note">{{ payMethod === 'wxpay' ? 'Please scan QR Code with Wechat' : 'Please scan QR Code with Alipay'
|
|
|
+ }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.card {
|
|
|
+ box-shadow: 0px 0px 12px 0px #2361A90D;
|
|
|
+}
|
|
|
+
|
|
|
+.recommend-icon {
|
|
|
+ position: relative;
|
|
|
+ display: inline-block;
|
|
|
+
|
|
|
+ .tip {
|
|
|
+ display: none;
|
|
|
+ box-shadow: 0px 4px 16px 0px #8195C82E;
|
|
|
+ padding: 8px;
|
|
|
+ z-index: 101;
|
|
|
+ top: 0px;
|
|
|
+ right: 0px;
|
|
|
+ transform: translate(50%, -100%);
|
|
|
+ width: 320px;
|
|
|
+ position: absolute;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 20px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ text-align: left;
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ border-radius: 4px;
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ display: block;
|
|
|
+ background: #373A47;
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 6px);
|
|
|
+ z-index: -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ div {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ top: -7px;
|
|
|
+ right: 0%;
|
|
|
+ transform: translate(50%, 0);
|
|
|
+ position: absolute;
|
|
|
+ z-index: 2;
|
|
|
+ border: 6px solid transparent;
|
|
|
+ border-top-color: #373A47;
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+
|
|
|
+ &::before,
|
|
|
+ .tip {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-input-number {
|
|
|
+ width: 180px;
|
|
|
+ line-height: 40px;
|
|
|
+
|
|
|
+ .el-input-number__increase,
|
|
|
+ .el-input-number__decrease {
|
|
|
+ width: 20px;
|
|
|
+ height: 14px;
|
|
|
+ right: 4px;
|
|
|
+ border: none;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-input-number__increase {
|
|
|
+ top: 7px;
|
|
|
+ border-radius: 4px 4px 0 0;
|
|
|
+
|
|
|
+ i {
|
|
|
+ border-bottom: 1px solid #E2E3E5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-input-number__decrease {
|
|
|
+ bottom: 7px;
|
|
|
+ border-radius: 0 0 4px 4px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ border-top: 1px solid #E2E3E5;
|
|
|
+ vertical-align: top;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-input {
|
|
|
+ input {
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.method-container {
|
|
|
+ font-size: 0;
|
|
|
+ margin-top: 32px;
|
|
|
+
|
|
|
+ input {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pay-btn {
|
|
|
+ position: relative;
|
|
|
+ display: inline-block;
|
|
|
+ width: 20.5882%;
|
|
|
+ height: 30px;
|
|
|
+ border-radius: 3px;
|
|
|
+ border: 1px solid #cacaca;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ img {
|
|
|
+ display: none;
|
|
|
+ position: absolute;
|
|
|
+ bottom: -1px;
|
|
|
+ right: -1px;
|
|
|
+ width: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ border-color: #0097ff;
|
|
|
+
|
|
|
+ img {
|
|
|
+ display: inline;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .card-btn {
|
|
|
+ width: 29.4117%;
|
|
|
+ margin-right: 2.9412%;
|
|
|
+ background: url('@/assets/images/store/card.svg') center no-repeat;
|
|
|
+ background-size: 100px auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .paypal-btn {
|
|
|
+ width: 20.5882%;
|
|
|
+ margin-right: 2.9412%;
|
|
|
+ background: url('@/assets/images/store/paypal_icon.svg') center no-repeat;
|
|
|
+ background-size: 71.4286% auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pay-btn-cny {
|
|
|
+ width: 20.5882%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .wxpay-btn {
|
|
|
+ margin-right: 2.9412%;
|
|
|
+ background: url('@/assets/images/store/wechatpay.svg') center no-repeat;
|
|
|
+ background-size: 48px auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .ali-btn {
|
|
|
+ background: url('@/assets/images/store/alipay.svg') center no-repeat;
|
|
|
+ background-size: 48px auto;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.info-message {
|
|
|
+ select {
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ color: #101828;
|
|
|
+
|
|
|
+ option {
|
|
|
+ width: 60%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes loading-circle {
|
|
|
+ 0% {
|
|
|
+ stroke-dashoffset: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ 100% {
|
|
|
+ stroke-dashoffset: -600;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.load-container {
|
|
|
+ margin-top: 24px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .load {
|
|
|
+ width: 46px;
|
|
|
+ -webkit-animation: loading 3s linear infinite;
|
|
|
+ animation: loading 3s linear infinite;
|
|
|
+
|
|
|
+ #loading-inner {
|
|
|
+ stroke-dashoffset: 0;
|
|
|
+ stroke-dasharray: 300;
|
|
|
+ stroke-width: 6;
|
|
|
+ stroke-miterlimit: 10;
|
|
|
+ stroke-linecap: round;
|
|
|
+ -webkit-animation: loading-circle 2s linear infinite;
|
|
|
+ animation: loading-circle 2s linear infinite;
|
|
|
+ stroke: #0097ff;
|
|
|
+ fill: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// wechatpay
|
|
|
+.wxpay-container {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 1800;
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
+
|
|
|
+ .wxpay-content {
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ padding-bottom: 50px;
|
|
|
+ background-color: #fff;
|
|
|
+ width: 334px;
|
|
|
+ border-radius: 7px;
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ padding-top: 42px;
|
|
|
+ font-size: 18px;
|
|
|
+ color: rgba(51, 51, 51, 1);
|
|
|
+ line-height: 25px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .img-container {
|
|
|
+ display: inline-block;
|
|
|
+ width: 244px;
|
|
|
+ height: 244px;
|
|
|
+
|
|
|
+ img.loading {
|
|
|
+ margin: 0 auto;
|
|
|
+ margin-top: 110px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ div.loading {
|
|
|
+ font-size: 14px;
|
|
|
+ color: rgba(51, 51, 51, 1);
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode {
|
|
|
+ width: 244px;
|
|
|
+ height: 244px;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .note {
|
|
|
+ margin-bottom: 5px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: rgba(51, 51, 51, 1);
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mess {
|
|
|
+ font-size: 16px;
|
|
|
+ color: rgba(153, 153, 153, 1);
|
|
|
+ line-height: 22px;
|
|
|
+
|
|
|
+ a {
|
|
|
+ color: #3285E3;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .wx-close {
|
|
|
+ position: absolute;
|
|
|
+ top: 10px;
|
|
|
+ right: 10px;
|
|
|
+ display: inline-block;
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ background: url('@/assets/images/store/ic_close.png') no-repeat;
|
|
|
+ background-size: 14px 14px;
|
|
|
+ opacity: 0.5;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|