v5pay
This commit is contained in:
parent
00cdea1a49
commit
82f430c83d
@ -1055,10 +1055,12 @@
|
||||
<script src="../common/toast.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var PENDING_MIFAPAY_ORDER_KEY =
|
||||
var PENDING_EXTERNAL_ORDER_KEY =
|
||||
'hyapp_recharge_pending_external_order';
|
||||
var LEGACY_PENDING_MIFAPAY_ORDER_KEY =
|
||||
'hyapp_recharge_pending_mifapay_order';
|
||||
var RETURN_MIFAPAY_ORDER_QUERY_KEY = 'hyapp_order_id';
|
||||
var PENDING_MIFAPAY_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
||||
var PENDING_EXTERNAL_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
||||
var state = {
|
||||
context: null,
|
||||
options: null,
|
||||
@ -1069,8 +1071,8 @@
|
||||
pollingTimer: 0,
|
||||
loading: false,
|
||||
orderNoticeKey: '',
|
||||
confirmingMifaPay: false,
|
||||
lastMifaPayResumeAtMS: 0,
|
||||
confirmingExternalPayment: false,
|
||||
lastExternalResumeAtMS: 0,
|
||||
};
|
||||
|
||||
var nodes = {};
|
||||
@ -1141,7 +1143,7 @@
|
||||
? window.HyAppParams.parse()
|
||||
: { raw: currentRawParams() };
|
||||
var raw = current.raw || currentRawParams();
|
||||
var pendingOrder = readPendingMifaPayOrder();
|
||||
var pendingOrder = readPendingExternalOrder();
|
||||
var displayUserID =
|
||||
raw.get('display_user_id') ||
|
||||
(pendingOrder && pendingOrder.display_user_id) ||
|
||||
@ -1181,11 +1183,11 @@
|
||||
nodes.copyAddress.addEventListener('click', copyAddress);
|
||||
nodes.copyOrderID.addEventListener('click', copyOrderID);
|
||||
nodes.txForm.addEventListener('submit', submitTx);
|
||||
window.addEventListener('pageshow', resumeMifaPayOrder);
|
||||
window.addEventListener('focus', resumeMifaPayOrder);
|
||||
window.addEventListener('pageshow', resumeExternalOrder);
|
||||
window.addEventListener('focus', resumeExternalOrder);
|
||||
document.addEventListener(
|
||||
'visibilitychange',
|
||||
resumeVisibleMifaPayOrder
|
||||
resumeVisibleExternalOrder
|
||||
);
|
||||
window.addEventListener('hyapp:i18n-ready', function () {
|
||||
document.title = t(
|
||||
@ -1228,7 +1230,7 @@
|
||||
state.order = null;
|
||||
state.orderModalOpen = false;
|
||||
render();
|
||||
restorePendingMifaPayOrder();
|
||||
restorePendingExternalOrder();
|
||||
})
|
||||
.catch(function (error) {
|
||||
toast(
|
||||
@ -1366,7 +1368,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 支付方式展示由当前商品驱动:USDT 用订单美元金额,MiFaPay 用后台汇率换算本币金额。
|
||||
// 支付方式展示由当前商品驱动:USDT 用订单美元金额,三方本地支付用后台汇率换算本币金额。
|
||||
function renderMethods() {
|
||||
var methods = availableMethods();
|
||||
var hasProduct = !!selectedProduct();
|
||||
@ -1455,9 +1457,7 @@
|
||||
nodes.usdtPanel.classList.toggle('hidden', !isUSDT);
|
||||
nodes.mifapayPanel.classList.toggle(
|
||||
'hidden',
|
||||
order.provider_code !== 'mifapay' ||
|
||||
!order.pay_url ||
|
||||
isTerminalOrder(order)
|
||||
!isRedirectPaymentOrder(order)
|
||||
);
|
||||
if (order.provider_code === 'usdt_trc20') {
|
||||
nodes.receiveAddress.textContent =
|
||||
@ -1477,10 +1477,10 @@
|
||||
order.failure_reason ||
|
||||
t('recharge.orderFailed', 'Order failed')
|
||||
);
|
||||
} else if (order.provider_code === 'mifapay') {
|
||||
} else if (isRedirectPaymentProvider(order.provider_code)) {
|
||||
setStatus(
|
||||
nodes.orderMessage,
|
||||
state.confirmingMifaPay
|
||||
state.confirmingExternalPayment
|
||||
? t(
|
||||
'recharge.confirmingPayment',
|
||||
'Confirming payment status...'
|
||||
@ -1496,7 +1496,7 @@
|
||||
}
|
||||
|
||||
// 可用支付方式只在选中商品后生成,避免用户先选支付方式再切商品造成金额不一致。
|
||||
// MiFaPay 方式必须是 active;USDT 必须同时有开关和收款地址,缺地址时不展示。
|
||||
// 三方本地支付方式必须是 active;USDT 必须同时有开关和收款地址,缺地址时不展示。
|
||||
function availableMethods() {
|
||||
var product = selectedProduct();
|
||||
if (!product) return [];
|
||||
@ -1517,7 +1517,7 @@
|
||||
}
|
||||
((state.options && state.options.payment_methods) || [])
|
||||
.filter(function (method) {
|
||||
// GLOBAL 是 MiFaPay 跨国兜底方式,当前充值页只展示用户所在国家的具体支付方式。
|
||||
// GLOBAL 是跨国兜底方式,当前充值页只展示用户所在国家的具体支付方式。
|
||||
return (
|
||||
method.status === 'active' &&
|
||||
String(
|
||||
@ -1527,7 +1527,10 @@
|
||||
})
|
||||
.forEach(function (method) {
|
||||
methods.push({
|
||||
key: 'mifapay:' + method.method_id,
|
||||
key:
|
||||
(method.provider_code || 'mifapay') +
|
||||
':' +
|
||||
method.method_id,
|
||||
icon: method.currency_code || 'PAY',
|
||||
name:
|
||||
method.method_name ||
|
||||
@ -1537,7 +1540,6 @@
|
||||
'Local payment'
|
||||
),
|
||||
meta: [
|
||||
method.provider_name,
|
||||
method.country_name || method.country_code,
|
||||
method.pay_type,
|
||||
]
|
||||
@ -1545,7 +1547,8 @@
|
||||
.join(' · '),
|
||||
logoURL: method.logo_url || '',
|
||||
amount: convertedAmount(product, method),
|
||||
providerCode: 'mifapay',
|
||||
providerCode:
|
||||
method.provider_code || 'mifapay',
|
||||
methodID: method.method_id,
|
||||
});
|
||||
});
|
||||
@ -1565,7 +1568,7 @@
|
||||
}
|
||||
|
||||
// 创建订单时只提交 product_id、provider 和 method_id;金额、金币、币商/普通钱包都由服务端订单快照决定。
|
||||
// MiFaPay 创建成功后必须立刻跳三方收银台;本页保存 order_id,支付完成 return 回来后继续轮询状态。
|
||||
// 三方支付创建成功后必须立刻跳收银台;本页保存 order_id,支付完成 return 回来后继续轮询状态。
|
||||
function createOrder() {
|
||||
var product = selectedProduct();
|
||||
var method = selectedMethod();
|
||||
@ -1582,7 +1585,7 @@
|
||||
provider_code: method.providerCode,
|
||||
payment_method_id: method.methodID || 0,
|
||||
command_id: commandID(product, method),
|
||||
return_url: mifaPayReturnURL(),
|
||||
return_url: externalPayReturnURL(),
|
||||
})
|
||||
.then(function (payload) {
|
||||
state.order = payload.order || payload;
|
||||
@ -1594,10 +1597,9 @@
|
||||
}
|
||||
startPolling();
|
||||
if (
|
||||
state.order.provider_code === 'mifapay' &&
|
||||
state.order.pay_url
|
||||
isRedirectPaymentOrder(state.order)
|
||||
) {
|
||||
savePendingMifaPayOrder(state.order);
|
||||
savePendingExternalOrder(state.order);
|
||||
window.location.href = state.order.pay_url;
|
||||
}
|
||||
})
|
||||
@ -1688,8 +1690,8 @@
|
||||
applyOrderTerminalSideEffects(state.order);
|
||||
return Promise.resolve(state.order);
|
||||
}
|
||||
if (state.order.provider_code === 'mifapay') {
|
||||
state.confirmingMifaPay = true;
|
||||
if (isRedirectPaymentProvider(state.order.provider_code)) {
|
||||
state.confirmingExternalPayment = true;
|
||||
state.orderModalOpen = true;
|
||||
renderOrder();
|
||||
}
|
||||
@ -1704,8 +1706,8 @@
|
||||
.catch(function () {});
|
||||
}
|
||||
|
||||
function restorePendingMifaPayOrder() {
|
||||
var pending = readPendingMifaPayOrder();
|
||||
function restorePendingExternalOrder() {
|
||||
var pending = readPendingExternalOrder();
|
||||
if (!pending) return;
|
||||
if (
|
||||
state.order &&
|
||||
@ -1726,13 +1728,13 @@
|
||||
state.order &&
|
||||
state.order.order_id === pending.order_id
|
||||
) {
|
||||
state.confirmingMifaPay = true;
|
||||
state.confirmingExternalPayment = true;
|
||||
state.orderModalOpen = true;
|
||||
renderOrder();
|
||||
startPolling();
|
||||
return;
|
||||
}
|
||||
state.confirmingMifaPay = true;
|
||||
state.confirmingExternalPayment = true;
|
||||
window.HyAppAPI.recharge
|
||||
.getOrder(
|
||||
pending.order_id,
|
||||
@ -1748,46 +1750,46 @@
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
clearPendingMifaPayOrder(pending.order_id);
|
||||
clearPendingExternalOrder(pending.order_id);
|
||||
});
|
||||
}
|
||||
|
||||
function resumeVisibleMifaPayOrder() {
|
||||
function resumeVisibleExternalOrder() {
|
||||
if (
|
||||
document.visibilityState &&
|
||||
document.visibilityState !== 'visible'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
resumeMifaPayOrder();
|
||||
resumeExternalOrder();
|
||||
}
|
||||
|
||||
function resumeMifaPayOrder() {
|
||||
function resumeExternalOrder() {
|
||||
if (!state.context) return;
|
||||
if (Date.now() - state.lastMifaPayResumeAtMS < 800) {
|
||||
if (Date.now() - state.lastExternalResumeAtMS < 800) {
|
||||
return;
|
||||
}
|
||||
state.lastMifaPayResumeAtMS = Date.now();
|
||||
state.lastExternalResumeAtMS = Date.now();
|
||||
if (
|
||||
state.order &&
|
||||
state.order.provider_code === 'mifapay' &&
|
||||
isRedirectPaymentProvider(state.order.provider_code) &&
|
||||
!isTerminalOrder(state.order)
|
||||
) {
|
||||
state.confirmingMifaPay = true;
|
||||
state.confirmingExternalPayment = true;
|
||||
state.orderModalOpen = true;
|
||||
renderOrder();
|
||||
startPolling();
|
||||
return;
|
||||
}
|
||||
restorePendingMifaPayOrder();
|
||||
restorePendingExternalOrder();
|
||||
}
|
||||
|
||||
function applyOrderTerminalSideEffects(order) {
|
||||
if (!isTerminalOrder(order)) {
|
||||
return;
|
||||
}
|
||||
state.confirmingMifaPay = false;
|
||||
clearPendingMifaPayOrder(order.order_id);
|
||||
state.confirmingExternalPayment = false;
|
||||
clearPendingExternalOrder(order.order_id);
|
||||
clearReturnedMifaPayOrderQuery();
|
||||
window.clearInterval(state.pollingTimer);
|
||||
if (order.status === 'credited') {
|
||||
@ -1807,37 +1809,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
function savePendingMifaPayOrder(order) {
|
||||
function savePendingExternalOrder(order) {
|
||||
if (!order || !order.order_id) return;
|
||||
storageSet(
|
||||
PENDING_MIFAPAY_ORDER_KEY,
|
||||
PENDING_EXTERNAL_ORDER_KEY,
|
||||
JSON.stringify({
|
||||
order_id: order.order_id,
|
||||
display_user_id: currentAccountDisplayUserID(),
|
||||
created_at_ms: Date.now(),
|
||||
})
|
||||
);
|
||||
storageRemove(LEGACY_PENDING_MIFAPAY_ORDER_KEY);
|
||||
}
|
||||
|
||||
function readPendingMifaPayOrder() {
|
||||
function readPendingExternalOrder() {
|
||||
var returned = readReturnedMifaPayOrder();
|
||||
if (returned) return returned;
|
||||
try {
|
||||
var raw = storageGet(PENDING_MIFAPAY_ORDER_KEY);
|
||||
var raw =
|
||||
storageGet(PENDING_EXTERNAL_ORDER_KEY) ||
|
||||
storageGet(LEGACY_PENDING_MIFAPAY_ORDER_KEY);
|
||||
if (!raw) return null;
|
||||
var parsed = JSON.parse(raw);
|
||||
if (!parsed || !parsed.order_id) return null;
|
||||
if (
|
||||
Number(parsed.created_at_ms || 0) > 0 &&
|
||||
Date.now() - Number(parsed.created_at_ms) >
|
||||
PENDING_MIFAPAY_MAX_AGE_MS
|
||||
PENDING_EXTERNAL_MAX_AGE_MS
|
||||
) {
|
||||
clearPendingMifaPayOrder(parsed.order_id);
|
||||
clearPendingExternalOrder(parsed.order_id);
|
||||
return null;
|
||||
}
|
||||
return parsed;
|
||||
} catch (error) {
|
||||
clearPendingMifaPayOrder('');
|
||||
clearPendingExternalOrder('');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1857,11 +1862,13 @@
|
||||
};
|
||||
}
|
||||
|
||||
function clearPendingMifaPayOrder(orderID) {
|
||||
function clearPendingExternalOrder(orderID) {
|
||||
var pending = null;
|
||||
try {
|
||||
pending = JSON.parse(
|
||||
storageGet(PENDING_MIFAPAY_ORDER_KEY) || 'null'
|
||||
storageGet(PENDING_EXTERNAL_ORDER_KEY) ||
|
||||
storageGet(LEGACY_PENDING_MIFAPAY_ORDER_KEY) ||
|
||||
'null'
|
||||
);
|
||||
} catch (error) {
|
||||
pending = null;
|
||||
@ -1872,7 +1879,8 @@
|
||||
!pending.order_id ||
|
||||
pending.order_id === orderID
|
||||
) {
|
||||
storageRemove(PENDING_MIFAPAY_ORDER_KEY);
|
||||
storageRemove(PENDING_EXTERNAL_ORDER_KEY);
|
||||
storageRemove(LEGACY_PENDING_MIFAPAY_ORDER_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2076,7 +2084,21 @@
|
||||
);
|
||||
}
|
||||
|
||||
function mifaPayReturnURL() {
|
||||
function isRedirectPaymentProvider(providerCode) {
|
||||
var normalized = String(providerCode || '').toLowerCase();
|
||||
return !!normalized && normalized !== 'usdt_trc20';
|
||||
}
|
||||
|
||||
function isRedirectPaymentOrder(order) {
|
||||
return (
|
||||
!!order &&
|
||||
isRedirectPaymentProvider(order.provider_code) &&
|
||||
!!order.pay_url &&
|
||||
!isTerminalOrder(order)
|
||||
);
|
||||
}
|
||||
|
||||
function externalPayReturnURL() {
|
||||
try {
|
||||
var url = new URL(window.location.href);
|
||||
var displayUserID =
|
||||
@ -2170,7 +2192,7 @@
|
||||
return Math.random().toString(36).slice(2, 14);
|
||||
}
|
||||
|
||||
// MiFaPay 国家方式按后台 USD->本币汇率展示;无有效汇率时回退 USD 展示但后端仍会拒绝不可用配置。
|
||||
// 本地三方支付按后台 USD->本币汇率展示;无有效汇率时回退 USD 展示但后端仍会拒绝不可用配置。
|
||||
function convertedAmount(product, method) {
|
||||
var usd = productUSD(product);
|
||||
var rate = Number(method.usd_to_currency_rate || 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user