diff --git a/src/api/pay.js b/src/api/pay.js index f9b8bc9..695d3a9 100644 --- a/src/api/pay.js +++ b/src/api/pay.js @@ -33,7 +33,6 @@ export const payPlaceAnOrderRecharge = async (data) => { return response; } catch (error) { console.error("Failed to fetch get pay application:", error); - onsole.error("error:" + error.response.errorMsg); throw error; } }; diff --git a/src/assets/icon/Vector.png b/src/assets/icon/Vector.png new file mode 100644 index 0000000..e90ee4a Binary files /dev/null and b/src/assets/icon/Vector.png differ diff --git a/src/assets/images/firstRechargeBonus.png b/src/assets/images/firstRechargeBonus.png new file mode 100644 index 0000000..b3378be Binary files /dev/null and b/src/assets/images/firstRechargeBonus.png differ diff --git a/src/router/index.js b/src/router/index.js index 9ebbcb1..1da9210 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -185,6 +185,12 @@ const router = createRouter({ component: () => import("../views/RechargeFreightAgent.vue"), meta: { requiresAuth: true }, }, + { + path: "/pay-result", + name: "pay-result", + component: () => import("../views/payResult.vue"), + meta: { requiresAuth: true }, + }, ], }); diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..f8ee4db --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,29 @@ +/** + * 合并对象. + */ +export function mergeObject(source, target) { + if (!source && !target) { + return {}; + } + + if (!source) { + return !!target && isObject(target) ? deepClone(target) : {}; + } + + if (!target) { + return !!source && isObject(source) ? deepClone(source) : {}; + } + + const resultObj = deepClone(source); + for (const key in target) { + const sourceObj = resultObj[key]; + const targetObj = target[key]; + + if (!isObject(sourceObj) || !isObject(targetObj)) { + resultObj[key] = deepClone(target[key]); + continue; + } + resultObj[key] = mergeObject(sourceObj, targetObj); + } + return resultObj; +} diff --git a/src/utils/payment.js b/src/utils/payment.js new file mode 100644 index 0000000..e3d1290 --- /dev/null +++ b/src/utils/payment.js @@ -0,0 +1,65 @@ +import { mergeObject } from "@/utils"; +import { loadAirwallex, redirectToCheckout } from "airwallex-payment-elements"; + +/** + * 空中云汇率,支付环境. + */ +export function getAirwallexEnv() { + const env = process.env.ENV; + if (env === "staging") { + return "staging"; + } + if (env === "production") { + return "prod"; + } + return "demo"; +} + +/** + * 发起支付. + * @param result 下单结果 + * @param callback 支付拉起加载回掉 + * @param props 空中云汇支付属性 + */ +export function goAirwallex({ result, props, callback }) { + const env = getAirwallexEnv(); + loadAirwallex({ env }) + .then(() => { + callback({ code: "INIT-LOAD", msg: "init load success." }); + const param = mergeObject( + { + env, + mode: "payment", + currency: result.currency, + intent_id: result.expand.id, + client_secret: result.expand["client_secret"], + methods: [result.factoryChannelCode], + // country_code: result.countryCode, + recurringOptions: { + card: { + next_triggered_by: "customer", + merchant_trigger_reason: "unscheduled", + currency: result.currency, + }, + }, + theme: { + // Must provide theme to display the checkout page properly + fonts: [ + // Customizes the font for the payment elements + { + src: "https://checkout.airwallex.com/fonts/CircularXXWeb/CircularXXWeb-Regular.woff2", + family: "AxLLCircular", + weight: 400, + }, + ], + }, + }, + props + ); + redirectToCheckout(param); + }) + .catch((er) => { + console.error(er); + callback({ code: "FAIL", msg: "init fail!!!" }); + }); +} diff --git a/src/utils/permissionManager.js b/src/utils/permissionManager.js index e0bc140..470030f 100644 --- a/src/utils/permissionManager.js +++ b/src/utils/permissionManager.js @@ -29,6 +29,7 @@ export const PAGES = { LOADING: "/loading", ADMIN_CENTER: "/admin-center", RECHARGE_STANDARD: "/recharge-standard", + PAY_RESULT: "/pay-result", }; // 🎯 核心改变:基于身份的权限配置 @@ -91,7 +92,7 @@ export const ROLE_PERMISSIONS = { // Admin(管理员) [USER_ROLES.ADMIN]: [ - PAGES.ADMIN_CENTER, //管理员的身份验证 + PAGES.ADMIN_CENTER, //管理员中心 "/item-distribution", //赠送商品页面 PAGES.RECHARGE_STANDARD, //普通转账功能 ], @@ -104,6 +105,9 @@ export const ROLE_PERMISSIONS = { // 公共页面(所有身份都可以访问) PUBLIC_PAGES: [ PAGES.NOT_APP, // 错误页面 + PAGES.PAY_RESULT, // 支付成功页面 + "/recharge", + "/recharge-freight-agent", ], // 加载页面 diff --git a/src/views/RechargeFreightAgent.vue b/src/views/RechargeFreightAgent.vue index f1cbc70..c9a441a 100644 --- a/src/views/RechargeFreightAgent.vue +++ b/src/views/RechargeFreightAgent.vue @@ -10,8 +10,9 @@ position: relative; color: rgba(187, 146, 255, 1) !important; " + @click="listBt" > -
English
+
{{ selectedLanguage.type }}
>
- {{ item }} + {{ item.type }}
@@ -45,13 +46,36 @@
-
Recharge ID:
- -
name:{{ userProfile.userNickname }}
+ + -
-
Select a country:
-
图标{{ selectedCountry.countryName }}
+
Recharge ID:
+ +
+ +
+
{{ userProfile.userNickname }}
+
ID:{{ userProfile.id }}
+
+
+ +
+
Select a country:
+
+ + {{ selectedCountry.countryName }} +
@@ -65,6 +89,7 @@ box-shadow: 0 0 4px 0 #00000050; align-items: center; " + @click="setChannelName(channelItem.channel.channelName)" >
{{ channelItem.channel.channelName }}
@@ -81,6 +106,7 @@ padding: 10px; margin-top: 1rem; " + v-if="selectedChannelName == channelItem.channel.channelName" >
{ + visibleList.value = !visibleList.value; +}; + const applicationId = ref("1963531459019739137"); const userProfile = ref({}); //用户信息 +const type = ref(""); //用户身份 const countryList = ref([]); //国家信息 const regionId = ref(""); //区域id -const selectedCountry = ref(""); +const selectedCountry = ref({}); //选中的国家 + +const channels = ref([]); //支付渠道 +const selectedChannelName = ref(""); //选中的支付渠道 const commodityList = ref([]); //商品列表 -const channels = ref([]); //支付渠道 - const selectedCommodity = ref({}); //选中的商品 const goPay = async (item, commodity) => { selectedCommodity.value = commodity; let payData = { applicationId: applicationId.value, - payCountryId: applicationId.value, + payCountryId: selectedCountry.value.id, goodsId: commodity.id, - userId: userProfile.id, + userId: userProfile.value.id, channelCode: item.channel.channelCode, }; + console.log("payData:", payData); - const payRes = await payPlaceAnOrderRecharge(data); + const payRes = await payPlaceAnOrderRecharge(payData); const body = payRes.body; if (!body) { console.log("Payment not available, please contact administrator!!!"); return; } if (body.factoryCode === "AIRWALLEX") { + goAirwallex({ + result: body, + props: { + logoUrl: that.sysOriginLog, + successUrl: `${location.origin}/#/pay-result?redirect=recharge&appType=${type.value}&appId=${applicationId.value}&appStatus=0`, + failUrl: `${location.origin}/#/pay-result?redirect=recharge&appType=${type.value}&appId=${applicationId.value}&appStatus=1`, + }, + callback: (response) => { + if (response.code === "FAIL") { + showWarning("init fail!!!"); + return; + } + }, + }); + } + if (body.requestUrl) { + location.href = decodeURIComponent(body.requestUrl); } }; +// 选中支付渠道 +const setChannelName = (channelName) => { + selectedChannelName.value = selectedChannelName.value != channelName ? channelName : ""; +}; + onMounted(async () => { + type.value = route.params.type || "GOLD"; + const PayAplication = await getPayAplication(applicationId.value); console.log("PayAplication:", PayAplication); if (PayAplication.body && PayAplication.body.appCode) { @@ -180,4 +248,28 @@ onMounted(async () => { }); - +