利用UniApp实现多平台付出集成:小程序、Apple IAP、App端微信与付出宝付出
uniapp各平台付出功能目录
https://i-blog.csdnimg.cn/direct/3c79c20ea4cc47a8ab5ce4e6c9075e20.png
APP端付出参考资料
[*]方式一(保举):https://uniapp.dcloud.net.cn/api/plugins/payment.html
[*]方式二(唤醒不了微信付出):https://ask.dcloud.net.cn/article/71
申请开通各平台APP付出
在利用付出前,需要向各付出平台申请开通付出功能【要有营业执照才可以开通】。
Apple应用内付出(IAP)
因为苹果应用内置流程与其他三方付出平台存在差异,需要单独参考ios平台利用Apple应用内付出文档。
留意事项:
[*]要成为Apple 开辟者人员,需要向Apple付出开辟人员年费。【 https://developer.apple.com】,【https://developer.apple.com/cn】
[*]iOS平台苹果审核规范要求,应用中虚拟物品交易必需利用Apple应用内付出,实物交易才能利用第三方付出(付出宝和微信付出)
HBuilder 里的调试基座默认不带IAP付出通道,假如需要调试IAP需要利用开辟证书生成一个自定义调试基座,用来实现IAP的开辟和调试。 自定义调试基座利用方法请参考文档。
付出宝付出
登录付出宝账号,创建应用接入付出宝APP付出如下步调【前提需要营业执照】付出宝官方文档App付出快速接入。
[*] 步调一、 创建应用,登录付出宝开放平台,创建应用并提交审核,审核通事后会生成应用唯一标识,APPID,并且可以申请开通开放产物利用权限,通过AppID应用才能调用开放产物的接口能力。
https://i-blog.csdnimg.cn/direct/0889e63b85154a71a4b2912c17fb3541.png
https://i-blog.csdnimg.cn/direct/6a088d15784344218fbb999d818c7360.png
https://i-blog.csdnimg.cn/direct/7183ecda1a7940658e02e4e082bccb4d.png
点击上面设置后,在加签管理,选择公钥证书,然后下载工具生csr文件
https://i-blog.csdnimg.cn/direct/a5ca2b964ed148fc8adf1dc15852d86f.png
https://i-blog.csdnimg.cn/direct/9b20975cc78e4aebafb7ec5c449c8752.png
https://i-blog.csdnimg.cn/direct/4d77dc67f20749d9b15fdb83a6d31342.png
https://i-blog.csdnimg.cn/direct/2982271810294df7ab661b0b5be39c33.png
https://i-blog.csdnimg.cn/direct/36a8474bd86e494784bc1ac16a0f9137.png
https://i-blog.csdnimg.cn/direct/aad34b8a2ae249a395867a29eabe5757.png
https://i-blog.csdnimg.cn/direct/3bee45c5fb304662b339342b3a30c9fb.png
https://i-blog.csdnimg.cn/direct/f9d1d30dcdab408fa1601fdb69e1d813.png
[*] 步调二、开通App付出功能,应用创建完成后,体系会主动跳转到应用详情页面。开辟者可以点击 添加能力 来添加 App 付出能力。添加功能后开辟者需要在商家中心中进行 签约,第三方应用开辟者可以 代商户签约。
https://i-blog.csdnimg.cn/direct/eba97dc60165415ca7d9dc6853ae63ec.png
得到沙箱测试账号
https://i-blog.csdnimg.cn/direct/f92cd4d9bbde4c7f84f2526f40b3d556.png
步调三、 设置密钥(获取公钥、私钥)
为了包管交易双方(商户和付出宝)的身份和数据安全,商户在调用接口前,需要设置双方密钥,对交易数据进行双方校验。密钥包含应用私钥APP_PRIVATE_KEY和应用公钥 APP_PUBLIC_KEY。生成密钥后,商户需要在开放平台控制台进行密钥配,设置完成后可以获取付出宝公钥 ALIPAY_PUBLIC_KEY,设置的详细步调请参考 设置应用环境。您还可以通过 生成密钥并上传 学习密钥的设置。密钥的设置旨在对交易数据进行双方校验。
微信付出【参考】
步调一、创建应用
[*]利用微信付出功能需到微信开放平台 申请移动应用并开通付出功能 微信APP
付出接入商户服务中心 申请应用后可以获取AppID和AppSecret值。
https://i-blog.csdnimg.cn/direct/3a6df55b579340d7b60c7aae30743d7d.png
步调二、开通
开通付出功能后可获取付出业务服务器设置数据(要先交300元开辟者认证费用,个人不可)。
PARTNER:财付通商户号
PARTNER_KEY:财付通密钥
PAYSIGNKEY:付出签名密钥
https://i-blog.csdnimg.cn/direct/d91076c0ac09415abdbbf563b0bd3efc.png
服务端生成付出订单接口
在App端调用付出功能时,需要先在调用服务器上生成预付出订单接口,再将预付出订单信息传递给付出接口。
付出宝业务流程图【官方参考】
客户端请求背景服务端获取签名后的订单信息,客户端带上订单信息(字符串)请求付出接口。
https://i-blog.csdnimg.cn/direct/ac0d43032d654eca971539008750c433.png
微信付出业务流程图【官方参考】
客户端请求背景服务端获代替签名的付出订单信息,然后客户端带上订单信息(Object范例)请求付出接口,此中订单信息请求请参考官网文档【APP调起付出API】
https://i-blog.csdnimg.cn/direct/48ef9f32d98c40b798b43c29992229e5.png
HBuilderX中设置利用付出功能
从微信开放平台申请获取设置参数后(Apple应用内付出和付出宝无需设置),需要再HBuilderX中设置并提交云端打包才能生效。
https://i-blog.csdnimg.cn/direct/779100c3ece34b24ad3c302694447dcb.png
勾选后会表现支持的付出模块,可根据应用需要进行选择设置
Apple应用内付出【仅支持IOS平台】
https://i-blog.csdnimg.cn/direct/09f645c1597047189dd40efb79454336.png
付出宝付出【支持Android及iOS平台】
https://i-blog.csdnimg.cn/direct/302f2ff3108b44a8834c3210b4b9f942.png
微信付出【参考】
获取appid填入,去微信开放平台申请应用的AppId值,UniversalLinks:iOS平台通用链接,必须与微信开放平台设置的同等,参考iOS平台微信SDK设置通用链接(UniversalLinks)
https://i-blog.csdnimg.cn/direct/26906cd90c2549afa6482a0c35106195.png
功能实现
https://i-blog.csdnimg.cn/direct/d472ee3aca5449f2ad6f1ab52d7daf21.png
APP端付出宝/微信付出实现
发送请求到背景服务端,背景服务端生成订单信息,相应预付出订单信息,通过预付出订单信息请求付出接口。
import api from '@/api/order.js'
export default {
methods: {
// 获取订单信息 (微信小程序支付需要openid)
getOrderInfo(openid) {
// 不要少了async
return new Promise( async (resolve, reject) => {
let res = null
let data = {} // 服务接口请求参数
if(this.provider === 'alipay') {
res = await api.getOrderInfoAlipay(data)
}else if(this.provider === 'wxpay') {
res = await api.getOrderInfoWxpay(data)
}
if (res && res.code === 20000) {
resolve(res.data)
} else {
reject(new Error('获取支付信息失败' + res.message))
}
})
},
// 微信、支付宝等支付
async payHandler() {
// 支付中
this.loading = true
// #ifdef APP-PLUS
// 1. 发送请求到服务端,服务端生成订单信息,响应预支付订单
let orderInfo = await this.getOrderInfo();
if (!orderInfo) {
uni.showModal({
content: '获取支付信息失败',
showCancel: false
})
return
}
// 2. 请求支付
uni.requestPayment({
provider: this.provider, // 支付渠道
orderInfo: orderInfo,
success: (e) => {
console.log("success", e);
uni.showToast({
title: "支付成功!"
})
},
fail: (e) => {
console.log("fail", e);
uni.showModal({
content: "支付失败!",
showCancel: false
})
},
complete: () => {
this.loading = false;
}
})
// #endif
},
}
https://i-blog.csdnimg.cn/direct/c1129d700573422c8d2a4cdf4490bb59.gif
微信小程序付出功能实现
微信小程序运行在微信内里,需要付出的话,起首要知道是谁的微信内里,就需要将当前微信进行登录获取获取code,再根据code获取openid的值。
步调一、先登录微信小程序获取用户code,再请求服务端获取openid,微信小程序登录参考:
https://i-blog.csdnimg.cn/direct/c2f00f07434242358ccba5e3cf0e94df.png
// 登录微信小程序
loginWeixinMp() {
return new Promise((resolve, reject) => {
// 1. 先使用微信登录小程序响应 code,
uni.login({
provider: 'weixin',
success: (res) => {
console.log('登录', res)
const code = res.code
// 2. 请求服务端通过code获取openid
let openid = 'xx'
uni.setStorageSync('openid', openid)
resolve(openid)
},
fail(err) {
reject(err)
}
})
})
},
步调二、通过openid再获取订单预付出信息,直接在getOrderInfo写死一个模拟预付出信息即可。
getOrderInfo(openid) {
return new Promise(async (resolve, reject) => {
if (openid) {
// 微信小程序获取订单信息,发送请求
// let orderInfo = await api.getOrderInfoWxpayMP(openid) 如果有真实接口替换即可
let orderInfo = {
"timeStamp": "1414561699",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"package": "prepay_id=wx201410272009395522657a690389285100", //预支付交易会话标识( prepay_id)
"signType": "RSA",
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ",
}
resolve(orderInfo)
return
}
let res = null
let data = {} // 服务接口请求参数
if (this.provider === 'alipay') {
res = await api.getOrderInfoAlipay(data)
} else if (this.provider === 'wxpay') {
res = await api.getOrderInfoWxpay(data)
}
if (res && res.code === 20000) {
resolve(res.data)
} else {
reject(new Error('获取支付信息失败' + res.message))
}
})
},
步调三、通过订单预付出信息,去调用付出接口
// 微信小程序支付
async wxPayHandler() {
this.loading = true
// 1. 先获取用户code, 再获取openid
let openid = uni.getStorageSync('openid')
if (!openid) {
try {
openid = await this.loginWeixinMp()
} catch (e) {
console.error(e)
}
if (!openid) {
uni.showModal({
content: '获取openid失败',
showCancel: false
})
this.loading = false
return
}
}
// 2. 通过 openid 再获取订单信息,
let orderInfo = await this.getOrderInfo(openid)
// 3. 通过订单预支付信息,去调用支付接口
uni.requestPayment({
...orderInfo,
success: (res) => {
uni.showToast({
title: "支付成功!"
})
},
fail: (res) => {
uni.showModal({
content: "支付失败,原因为: " + res.errMsg,
showCancel: false
})
},
complete: () => {
this.loading = false;
}
})
}
因为用的是模拟的假数据,会报权限不足问题,假如真实开辟中调用后端请求服务拿到商品信息,先登录微信小程序获取用户code,再请求服务端获取openid,通过openid再获取订单预付出信息,直接在getOrderInfo写死一个模拟预付出信息即可,通过订单预付出信息,去调用付出接口即可。
https://i-blog.csdnimg.cn/direct/d6e8f4144586419ea96d2279ed189262.gif
Apple应用内付出
苹果应用内置流程与别的三方付出平台存在差异,请单独参考iOS 平台利用Apple应用内付出文档,项目中参考付出文档最下面示例代码
流程:
https://i-blog.csdnimg.cn/direct/9f16f07c482646b08e508096aea5d2c3.png
在onLoad中先获取Apple付出渠道的实例。
onLoad: function(option) {
// 获取支付金额
if (option.params) {
const params = JSON.parse(option.params)
this.price = params.price
this.courseIds = params.courseIds
}
// 查询余额
this.loadData()
// 获取apple支付渠道实例
plus.payment.getChannels((channels) => {
console.log("获取到channel" + JSON.stringify(channels))
for (var i in channels) {
var channel = channels;
if (channel.id === 'appleiap') {
iapChannel = channel;
this.requestOrder();
}
}
if (!iapChannel) {
this.errorMsg()
}
}, (error) => {
this.errorMsg()
});
},
requestOrder环境检测方法
requestOrder() {
uni.showLoading({
title: '检测支付环境...'
})
//必须调用此方法向Appstore请求有效的商品详情,才能进行 iap 支付,
iapChannel.requestOrder(this.moneyList, (orderList) => {
this.disabled = false;
console.log('requestOrder success666: ' + JSON.stringify(orderList));
uni.hideLoading();
}, (e) => {
console.log('requestOrder failed: ' + JSON.stringify(e));
uni.hideLoading();
this.errorMsg()
});
},
弹窗提示判断,假如环境不支持apple付出则弹窗提示
errorMsg() {
uni.showModal({
content: "暂不支持苹果 iap 支付",
showCancel: false
})
},
假如当前环境可以付出,则利用uni.requestPayment进行apple支
// Apple应用内支付
iosPayHandler() {
this.loading = true;
uni.requestPayment({
provider: 'appleiap',
orderInfo: {
productid: this.applePrice // 商品金额
},
success: (e) => {
console.log("success", e);
uni.showToast({
title: "支付成功!"
})
// 再进行app内部扣款
},
fail: (e) => {
console.log("fail", e);
uni.showModal({
content: "支付失败,原因为: " + e.errMsg,
showCancel: false
})
},
complete: () => {
this.loading = false;
}
})
},
总体代码:
<template> <view> <view class="money column center"> <text>余额:</text> <text>{{parseFloat(balance).toFixed(2)}}币</text> </view> <view class="recharge"> <view>充值</view> <view class="list"> <view v-for="(item, index) in 6" :key="index" :class="{active: activeIndex===index}" @click="clickItem(index, item)"> <view>{{index+1}}00币</view> <view>¥{{index+1}}00</view> </view> </view> </view> <view class="desc"> <view>充值说明:</view> <view> 1.在IOS设备的APP要进行充值后,利用虚拟币消耗。<br> 2.充值后不能在非IOS设备利用,与安卓版和网站余额不通用。<br> 3.充值后没有利用期限,但不可提现、退换、转让和申请发票。<br> 4.如遇无法充值、充值失败等问题,可关注[梦学谷]公众号,接洽我们解决。<br> </view> </view> <view class="bottom center"> <button class="btn" :loading="loading" :disabled="disabled" @click="iosPayHandler">立即充值</button> </view> </view></template><script> import api from '@/api/order.js' let iapChannel = null // 苹果内部付出渠道 export default { data() { return { activeIndex: 0, loading: false, // 是否充值中 disabled: true, //要先查抄付出环境是否iap,不付出则点击立即付出无效 balance: 0, // 余额 moneyList: [], // 充值列表展示金额 price: 0, // 付出金额 courseIds: [], // 付出的课程ids applePrice: 30, // ios充值金额 } }, onLoad: function(option) { // 获取付出金额 if (option.params) { const params = JSON.parse(option.params) this.price = params.price this.courseIds = params.courseIds } // 查询余额 this.loadData() // 获取apple付出渠道实例 plus.payment.getChannels((channels) => { console.log("获取到channel" + JSON.stringify(channels)) for (var i in channels) { var channel = channels; if (channel.id === 'appleiap') { iapChannel = channel; this.requestOrder(); } } if (!iapChannel) { this.errorMsg() } }, (error) => { this.errorMsg() }); }, methods: {
requestOrder() {
uni.showLoading({
title: '检测支付环境...'
})
//必须调用此方法向Appstore请求有效的商品详情,才能进行 iap 支付,
iapChannel.requestOrder(this.moneyList, (orderList) => {
this.disabled = false;
console.log('requestOrder success666: ' + JSON.stringify(orderList));
uni.hideLoading();
}, (e) => {
console.log('requestOrder failed: ' + JSON.stringify(e));
uni.hideLoading();
this.errorMsg()
});
},
iosPayHandler() { this.loading = true; uni.requestPayment({ provider: 'appleiap', orderInfo: { productid: this.applePrice // 商品id }, success: (e) => { console.log("success", e); uni.showToast({ title: "付出成功!" }) // 调用接口,立即扣款购买商品 }, fail: (e) => { console.log("fail", e); uni.showModal({ content: "付出失败,原因为: " + e.errMsg, showCancel: false }) }, complete: () => { this.loading = false; } }) }, errorMsg() { uni.showModal({ content: "暂不支持苹果 iap 付出", showCancel: false }) }, clickItem(index, item) { this.activeIndex = index this.applePrice = item }, async loadData() { // 查询余额 const { data } = await api.getUserBalance() this.balance = data // 要进行付出,则计算还差多少金额, 则充值多少, if (this.price) { // ios充值多少 = 余额-付款金额 < 0 : 余额不够:充足 const applePrice=this.balance - this.price // console.log('applePrice', applePrice) // 取正数,向上取整 this.applePrice=Math.ceil(Math.abs(applePrice)) } // 充值列表展示金额 for(let i=0; i<6; i++) { // 6个元素,每个加30元 this.moneyList.push(this.applePrice + i * 30) } }, } }</script><style lang="scss"> .money { height: 288rpx; background-color: $mxg-color-primary; color: #FFFFFF; font-size: 88rpx; text:first-child { color: #e7e4e9; font-size: 30rpx; } } .recharge { margin: 20rpx 0 0 20rpx; color: #999; font-size: 30rpx; .list { margin-top: 20rpx; text-align: center; >view { float: left; width: 225rpx; margin-right: 10rpx; margin-bottom: 15rpx; background-color: #fff; border-radius: 10rpx; padding: 20rpx 0; border: 1px solid $mxg-color-grey; flex-wrap: wrap; view:first-child { color: $mxg-text-color-red; font-size: 36rpx; } } } } .active { box-shadow: 0 0 0 .5px $mxg-text-color-red; } .desc { // 扫除浮动 clear: both; margin: 0 20rpx; font-size: 30rpx; line-height: 45rpx; color: #6e6d70; view:first-child { padding-top: 50rpx; padding-bottom: 30rpx; font-weight: bold; } view:last-child { padding-bottom: 120rpx; } } /* 底部 */ .bottom { position: fixed; left: 0; right: 0; bottom: 0; height: 100rpx; background-color: #FFFFFF; border-top: 1px solid #F1F1F1; } .btn { width: 700rpx; background-color: $mxg-color-primary; color: #fff; border-radius: 50rpx; line-height: 80rpx; font-size: 30rpx; &::after { // 加载中时,隐藏边框 border: none; } }</style> 效果:由于我用的是mock数据,说一检测环境就会失败判断,到了生产环境就会弹出apple应用付出弹窗。
https://i-blog.csdnimg.cn/direct/be04a5b963074148ab9ef4b79fe78e4b.jpeg
Appstore审核报PGPay SDK不答应上架的问题
A:数字类产物(好比购买会员等不需要配送实物的商品),Apple规定必须利用苹果IAP应用内付出,给Apple分成30%。打包的时间不要勾选微信或付出宝等其他付出方式。假如你提交的包里包含了微信付出宝等付出的sdk,即使没利用,Appstore也会以为你有隐藏方式,以后会绕过IAP,不给Apple分成,因此拒绝你的App上线。云打包时,manifest里选上付出模块,但sdk设置里去掉微信付出和付出宝付出。很多开辟者的Android版是包含微信和付出宝付出的,此时留意分开判断。详见
H5沙箱付出功能实现实现
设置沙箱
https://i-blog.csdnimg.cn/direct/9d281768ca874d7aa3ac217d0be70251.png
沙箱支持产物
https://i-blog.csdnimg.cn/direct/8d3d526b9da4436792b462ef510633ea.png
沙箱测试账号
https://i-blog.csdnimg.cn/direct/9f31e683f0314d4b88da6268e15392ac.png
带着商品信息请求后端接口,获取paymentUrl然后通过window.location.href = res.paymentUrl进行跳转
https://i-blog.csdnimg.cn/direct/ef703010e62a492991e3803292a83d61.png
https://i-blog.csdnimg.cn/direct/80e641e9717345858ba79818b0fa8610.png
通过location.href跳转到如下页面即可利用沙箱测试账号进行登录。下图为付出宝登录页面,可能会违规。
留意: 沙箱测试付出功能一定要开启无痕浏览进行测试。
https://i-blog.csdnimg.cn/direct/b8e897cd289d40548b4cf7c5f4157011.jpeg
利用付出宝开放平台给的沙箱测试账号进行测试:如下找到https://i-blog.csdnimg.cn/direct/057ce5b8f27440779a5b7b354a9ec546.png
输入沙箱账号暗码
https://i-blog.csdnimg.cn/direct/f3723d9b53a54a43a6e0eac51b6cbbcc.png
https://i-blog.csdnimg.cn/direct/2112d2c80cd04410a2658812af97e492.png
付出成功
https://i-blog.csdnimg.cn/direct/b9affc9ec0b14b97bf4692119bf45a70.png
交易成功后,此页面会跳转到前端传递给后端的设置的跳转页面,付出成功后就会跳回到指定页面。
https://i-blog.csdnimg.cn/direct/f38677a2858f424ba17ad8f8a1c103e5.png
设置的付出成功后的跳转页面,在此页面调用后端接口,后端返回付出状态,根据付出状态再在此页面进行其他业务逻辑处理。
https://i-blog.csdnimg.cn/direct/ce84d82847fe410d97b73ffebeeeb291.png
https://i-blog.csdnimg.cn/direct/2882e150aabb45eeb383782b633e8a87.png
H5付出第二种方法
微信付出:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_0.shtml
付出宝:https://opendocs.alipay.com/open/204/105297
[*]普通浏览器平台的付出,仍然是常规web做法。uni-app未封装。
[*]在普通浏览器里也可以调起微信进行付出,这个在微信叫做H5付出,此功能未开放给普通开辟者,需向微信 单独申请,[详见]
[*]微信内嵌浏览器运行H5版时,可通过js sdk实现微信付出,需要引入一个单独的js, [详见]
完结~,如有不足,后继补充。。。。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]