对接银联和日照银行分开页面
This commit is contained in:
@@ -50,11 +50,16 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onUnmounted } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { getUnionPayTn } from '/pageSubPack/api/apiSub.js'
|
||||
import { getPushSingle } from '/pageSubPack/api/api.js'
|
||||
|
||||
// 支付宝和微信支付
|
||||
// 银联商务全民付为 App 原生 UTS 插件,不支持小程序/H5,必须条件编译引入,否则其他端构建失败
|
||||
// #ifdef APP-PLUS
|
||||
import { upPayWithChannel, upPayRegistry, setPayEnviroment } from '@/uni_modules/xh-uppay'
|
||||
// #endif
|
||||
|
||||
// 银联商务全民付收银台:微信 / 支付宝
|
||||
|
||||
const amount = ref('0.00')
|
||||
const countdownTime = ref('10:00')
|
||||
@@ -92,7 +97,6 @@
|
||||
}
|
||||
|
||||
const selectedType = ref('wx')
|
||||
const goBack = () => uni.navigateBack()
|
||||
|
||||
const selectPayType = (type) => {
|
||||
selectedType.value = type
|
||||
@@ -101,28 +105,69 @@
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 银联商务渠道号:01 微信原生支付 / 02 支付宝支付 / 03 支付宝小程序 / 11 支付宝2.0
|
||||
// 渠道号必须与后端下单的产品对应(响应里的 targetSys),对不上会静默失败:
|
||||
// 微信 targetSys = WXPay → 01
|
||||
// 支付宝 targetSys = Alipay 2.0 → 11(插件 Android 端 '11' 分支是空壳,未实现)
|
||||
// 支付宝 targetSys = 支付宝小程序 → 03(需后端改下这个小程序产品才会生效)
|
||||
const CHANNEL_MAP = { wx: '01', alipay: '03' }
|
||||
|
||||
// 传给后端的支付方式,沿用原有枚举 0=微信 / 1=支付宝
|
||||
const PAY_TYPE_MAP = { wx: '0', alipay: '1' }
|
||||
|
||||
// 银联环境:0 正式 / 1 测试。必须与后端下单时所用的银联环境一致,
|
||||
// 这是后端的配置项、不是前端构建环境;联调报「交易不存在/签名错误」多半是这里对不上。
|
||||
// 注意:这里只对 iOS 生效,Android 要改插件 utssdk/app-android/AndroidManifest.xml 的 CurrentEnvironment(PROD/TEST)。
|
||||
const UNIONPAY_ENV = process.env.NODE_ENV === 'development' ? 1 : 0
|
||||
|
||||
// 以下常量只在 iOS 生效(Android 的 upPayRegistry 是空实现),且每一项都必须与
|
||||
// xh-uppay/utssdk/app-ios/info.plist 里 CFBundleURLTypes 的取值完全一致,
|
||||
// 否则 iOS 上支付完成后回不到本应用。
|
||||
const WX_APPID = 'wx84b02b2ec80715f4' // 需同步改 info.plist 的 weixin scheme(现在是 demo 值)
|
||||
// 存疑:暂用项目里微信分享的 Universal Link,但银联商务支付链路可能要求用他们备案的域名,需与其确认
|
||||
const WX_UNIVERSAL_LINK = 'https://verification.ckdzkj.com/uni-universallinks/__UNI__29C3D60/'
|
||||
const SCHEME_CLOUD = 'unifyPayDemo' // info.plist 中 ucloud(云闪付回调,暂不用云闪付)
|
||||
const SCHEME_ALI_MINI = 'qmfpppay' // info.plist 中 aliminipay(支付宝小程序回调)
|
||||
const SCHEME_ALI = 'umsunifyalisafepay' // info.plist 中 alisafepay(支付宝回调)
|
||||
|
||||
const handlePayClick = () => {
|
||||
handlePay()
|
||||
}
|
||||
|
||||
// 账单明细 id:接口要求 string,多个账单逗号拼接,兼容单个 billId 的旧场景
|
||||
const toBillIds = (billIds, billId) => {
|
||||
if (Array.isArray(billIds) && billIds.length) {
|
||||
return billIds.filter(Boolean).join(',')
|
||||
}
|
||||
if (typeof billIds === 'string' && billIds) {
|
||||
return billIds
|
||||
}
|
||||
return billId ? String(billId) : ''
|
||||
}
|
||||
|
||||
const handlePay = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: '发起支付中' })
|
||||
const payTypeMap = { wx: '0', alipay: '1' }
|
||||
const backendPayType = payTypeMap[selectedType.value] || '1'
|
||||
|
||||
const res = await getUnionPayTn({
|
||||
amount: amount.value,
|
||||
const billIds = toBillIds(payData.value.billIds, payData.value.billId)
|
||||
if (!billIds) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '账单信息异常,请返回重新选择', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// deviceCode/deviceType 仅水电表充值传;无值即物业费/停车费/垃圾处理费
|
||||
const payload = {
|
||||
amount: Number(amount.value),
|
||||
orderDesc: (payData.value.type || '缴费') + '缴费',
|
||||
residentUserId: uni.getStorageSync('userId'),
|
||||
payType: backendPayType,
|
||||
deviceCode: payData.value.deviceCode || '',
|
||||
deviceType: '2',
|
||||
chargeTypeId: payData.value.chargeTypeId,
|
||||
chargeItemId: payData.value.chargeItemId,
|
||||
billId: payData.value.billId,
|
||||
houseId: payData.value.houseId
|
||||
})
|
||||
residentUserId: payData.value.residentUserId || uni.getStorageSync('userId'),
|
||||
payType: PAY_TYPE_MAP[selectedType.value],
|
||||
billIds
|
||||
}
|
||||
if (payData.value.deviceCode) payload.deviceCode = payData.value.deviceCode
|
||||
if (payData.value.deviceType) payload.deviceType = payData.value.deviceType
|
||||
|
||||
const res = await getUnionPayTn(payload)
|
||||
console.log('支付接口返回:', JSON.stringify(res.data))
|
||||
uni.hideLoading()
|
||||
|
||||
@@ -131,15 +176,20 @@
|
||||
return
|
||||
}
|
||||
|
||||
const payType = selectedType.value
|
||||
// 后端下发银联商务的 appPayRequest,整串 JSON 原样交给 SDK,不要拆开解析
|
||||
const data = res.data
|
||||
const payDataStr = typeof data === 'string'
|
||||
? data
|
||||
: (data.appPayRequest || data.appRequest || '')
|
||||
|
||||
if (payType === 'wx') {
|
||||
invokeWxPay(data.wx || data.wxPayInfo || data)
|
||||
} else if (payType === 'alipay') {
|
||||
invokeAlipay(data.alipay || data.aliPayInfo || data)
|
||||
if (!payDataStr || typeof payDataStr !== 'string' || !payDataStr.trim().startsWith('{')) {
|
||||
console.error('未获取到有效的 appPayRequest,后端返回:', JSON.stringify(data))
|
||||
uni.showToast({ title: '支付参数异常,请联系客服', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
invokeUnionPay(payDataStr, CHANNEL_MAP[selectedType.value])
|
||||
|
||||
} catch (err) {
|
||||
uni.hideLoading()
|
||||
console.log('支付异常', err)
|
||||
@@ -147,49 +197,96 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 微信支付
|
||||
const invokeWxPay = (data) => {
|
||||
const orderInfo = {
|
||||
appid: data.appId,
|
||||
partnerid: data.partnerId || data.partnerid || '',
|
||||
prepayid: data.prepayId || data.prepayid || (data.package || '').replace('prepay_id=', ''),
|
||||
package: 'Sign=WXPay',
|
||||
noncestr: data.nonceStr,
|
||||
timestamp: data.timeStamp,
|
||||
sign: data.paySign
|
||||
// 银联商务综合支付:拉起微信 / 支付宝完成付款
|
||||
const invokeUnionPay = (payData, channel) => {
|
||||
// #ifdef APP-PLUS
|
||||
ensureRegistered()
|
||||
paying = true
|
||||
upPayWithChannel({ payData, channel }, (code, info) => {
|
||||
handlePayResult(String(code), info)
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
uni.showToast({ title: '当前端暂不支持银联支付', icon: 'none' })
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 注册和支付环境设置都只对 iOS 生效;Android 调 setPayEnviroment 只会刷警告,
|
||||
// Android 的环境要改插件 utssdk/app-android/AndroidManifest.xml 里的 CurrentEnvironment。
|
||||
let registered = false
|
||||
const ensureRegistered = () => {
|
||||
if (registered) return
|
||||
registered = true
|
||||
// #ifdef APP-PLUS
|
||||
if (uni.getSystemInfoSync().platform === 'ios') {
|
||||
setPayEnviroment(UNIONPAY_ENV)
|
||||
upPayRegistry({
|
||||
appId: WX_APPID,
|
||||
link: WX_UNIVERSAL_LINK,
|
||||
cloudUrl: SCHEME_CLOUD,
|
||||
aliminipayUrl: SCHEME_ALI_MINI,
|
||||
aliUrl: SCHEME_ALI
|
||||
})
|
||||
}
|
||||
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
orderInfo: orderInfo,
|
||||
success: (res) => {
|
||||
console.log('微信支付成功', res)
|
||||
paySuccess()
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('微信支付失败或取消', err)
|
||||
uni.showToast({ title: '支付取消或失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 支付宝支付
|
||||
const invokeAlipay = (data) => {
|
||||
const orderInfo = data.orderInfo || data
|
||||
uni.requestPayment({
|
||||
provider: 'alipay',
|
||||
orderInfo: orderInfo,
|
||||
success: (res) => {
|
||||
console.log('支付宝支付成功', res)
|
||||
paySuccess()
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('支付宝支付失败或取消', err)
|
||||
uni.showToast({ title: '支付取消或失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
let paying = false // 支付请求是否已发出
|
||||
let payDone = false // 是否已给出结果提示,避免重复
|
||||
|
||||
// Android 端插件不触发回调,用户从微信/支付宝切回来时靠 onShow 兜底;
|
||||
// iOS 有回调,交给 handlePayResult 处理,这里不插手。
|
||||
onShow(() => {
|
||||
if (!paying) return
|
||||
if (uni.getSystemInfoSync().platform === 'android') {
|
||||
paying = false
|
||||
notifyPayPending()
|
||||
}
|
||||
})
|
||||
|
||||
// 结果码见 xh-uppay readme:0000 只表示「支付请求发送成功」,不代表付款成功,
|
||||
// 真实结果以银联商务异步通知到后端的结果为准。所以这里不做成功判定,
|
||||
// 统一引导用户回账单列表看实际状态。
|
||||
const handlePayResult = (code, info) => {
|
||||
console.log('银联支付回调', code, JSON.stringify(info))
|
||||
paying = false
|
||||
switch (code) {
|
||||
case '0000':
|
||||
case '2001': // 订单处理中,结果未知(有可能已支付成功)
|
||||
notifyPayPending()
|
||||
break
|
||||
case '1000':
|
||||
payDone = true
|
||||
uni.showToast({ title: '支付已取消', icon: 'none' })
|
||||
break
|
||||
case '1001':
|
||||
payDone = true
|
||||
uni.showToast({ title: '支付参数错误', icon: 'none' })
|
||||
break
|
||||
case '1002':
|
||||
payDone = true
|
||||
uni.showToast({ title: '网络异常,请重试', icon: 'none' })
|
||||
break
|
||||
case '1003':
|
||||
payDone = true
|
||||
uni.showToast({ title: '未安装对应的支付客户端', icon: 'none' })
|
||||
break
|
||||
default:
|
||||
payDone = true
|
||||
uni.showToast({ title: (info && info.resultMsg) || '支付失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
const notifyPayPending = () => {
|
||||
if (payDone) return
|
||||
payDone = true
|
||||
uni.showToast({ title: '支付结果确认中,请稍后在账单中查看', icon: 'none' })
|
||||
setTimeout(() => uni.navigateBack(), 2000)
|
||||
}
|
||||
|
||||
// 支付成功流转:等后端提供「订单查询」接口后,查单确认已支付时再调用这里。
|
||||
// 目前 SDK 的结果码不足以判定付款成功,所以暂时没有调用点。
|
||||
const paySuccess = () => {
|
||||
sendPaySuccessPush()
|
||||
uni.showToast({ title: '支付成功', icon: 'success' })
|
||||
|
||||
Reference in New Issue
Block a user