uniapp各平台付出功能
目录
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应用才能调用开放产物的接口能力。
点击上面设置后,在加签管理,选择公钥证书,然后下载工具生csr文件
- 步调二、开通App付出功能,应用创建完成后,体系会主动跳转到应用详情页面。开辟者可以点击 添加能力 来添加 App 付出能力。添加功能后开辟者需要在商家中心中进行 签约,第三方应用开辟者可以 代商户签约。
得到沙箱测试账号
步调三、 设置密钥(获取公钥、私钥)
为了包管交易双方(商户和付出宝)的身份和数据安全,商户在调用接口前,需要设置双方密钥,对交易数据进行双方校验。密钥包含应用私钥APP_PRIVATE_KEY和应用公钥 APP_PUBLIC_KEY。生成密钥后,商户需要在开放平台控制台进行密钥配,设置完成后可以获取付出宝公钥 ALIPAY_PUBLIC_KEY,设置的详细步调请参考 设置应用环境。您还可以通过 生成密钥并上传 学习密钥的设置。密钥的设置旨在对交易数据进行双方校验。
微信付出【参考】
步调一、创建应用
- 利用微信付出功能需到微信开放平台 申请移动应用并开通付出功能 微信APP
付出接入商户服务中心 申请应用后可以获取AppID和AppSecret值。
步调二、开通
开通付出功能后可获取付出业务服务器设置数据(要先交300元开辟者认证费用,个人不可)。
PARTNER:财付通商户号
PARTNER_KEY:财付通密钥
PAYSIGNKEY:付出签名密钥
服务端生成付出订单接口
在App端调用付出功能时,需要先在调用服务器上生成预付出订单接口,再将预付出订单信息传递给付出接口。
付出宝业务流程图【官方参考】
客户端请求背景服务端获取签名后的订单信息,客户端带上订单信息(字符串)请求付出接口。
微信付出业务流程图【官方参考】
客户端请求背景服务端获代替签名的付出订单信息,然后客户端带上订单信息(Object范例)请求付出接口,此中订单信息请求请参考官网文档【APP调起付出API】
HBuilderX中设置利用付出功能
从微信开放平台申请获取设置参数后(Apple应用内付出和付出宝无需设置),需要再HBuilderX中设置并提交云端打包才能生效。
勾选后会表现支持的付出模块,可根据应用需要进行选择设置
Apple应用内付出【仅支持IOS平台】
付出宝付出【支持Android及iOS平台】
微信付出【参考】
获取appid填入,去微信开放平台申请应用的AppId值,UniversalLinks:iOS平台通用链接,必须与微信开放平台设置的同等,参考iOS平台微信SDK设置通用链接(UniversalLinks)
功能实现
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
- },
- }
复制代码
微信小程序付出功能实现
微信小程序运行在微信内里,需要付出的话,起首要知道是谁的微信内里,就需要将当前微信进行登录获取获取code,再根据code获取openid的值。
步调一、先登录微信小程序获取用户code,再请求服务端获取openid,微信小程序登录参考:
- // 登录微信小程序
- 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写死一个模拟预付出信息即可,通过订单预付出信息,去调用付出接口即可。
Apple应用内付出
苹果应用内置流程与别的三方付出平台存在差异,请单独参考iOS 平台利用Apple应用内付出文档,项目中参考付出文档最下面示例代码
流程:
在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[i];
- 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[i]; 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应用付出弹窗。

Appstore审核报PGPay SDK不答应上架的问题
A:数字类产物(好比购买会员等不需要配送实物的商品),Apple规定必须利用苹果IAP应用内付出,给Apple分成30%。打包的时间不要勾选微信或付出宝等其他付出方式。假如你提交的包里包含了微信付出宝等付出的sdk,即使没利用,Appstore也会以为你有隐藏方式,以后会绕过IAP,不给Apple分成,因此拒绝你的App上线。云打包时,manifest里选上付出模块,但sdk设置里去掉微信付出和付出宝付出。很多开辟者的Android版是包含微信和付出宝付出的,此时留意分开判断。详见
H5沙箱付出功能实现实现
设置沙箱
沙箱支持产物
沙箱测试账号
带着商品信息请求后端接口,获取paymentUrl然后通过window.location.href = res.paymentUrl进行跳转
通过location.href跳转到如下页面即可利用沙箱测试账号进行登录。下图为付出宝登录页面,可能会违规。
留意: 沙箱测试付出功能一定要开启无痕浏览进行测试。
利用付出宝开放平台给的沙箱测试账号进行测试:如下找到
输入沙箱账号暗码
付出成功
交易成功后,此页面会跳转到前端传递给后端的设置的跳转页面,付出成功后就会跳回到指定页面。
设置的付出成功后的跳转页面,在此页面调用后端接口,后端返回付出状态,根据付出状态再在此页面进行其他业务逻辑处理。
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企服之家,中国第一个企服评测及商务社交产业平台。 |