2025-06-24 11:36:21
来源:新华网
- 方式一(推荐):https://uniapp.dcloud.net.cn/api/plugins/payment.html
- 方式二(唤醒不了微信支付):https://ask.dcloud.net.cn/article/71
在使用支付前,需要向各支付平台申请开通支付功能【要有营业执照才可以开通】。
因为苹果应用内置流程与其他三方支付平台存在差异,需要单独参考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
,配置的详细步骤请参考 配置应用环境。您还可以通过 生成密钥并上传 学习密钥的配置。密钥的配置旨在对交易数据进行双方校验。
步骤一、创建应用
PARTNER
:财付通商户号PARTNER_KEY
:财付通密钥PAYSIGNKEY
:支付签名密钥在App端调用支付功能时,需要先在调用服务器上生成预支付订单接口,再将预支付订单信息传递给支付接口。
客户端请求后台服务端获取签名后的订单信息,客户端带上订单信息(字符串)请求支付接口。
客户端请求后台服务端获取代签名的支付订单信息,然后客户端带上订单信息(Object类型)请求支付接口,其中订单信息请求请参考官网文档【APP调起支付API】
从微信开放平台申请获取配置参数后(Apple应用内支付和支付宝无需配置),需要再HBuilderX中配置并提交云端打包才能生效。
勾选后会显示支持的支付模块,可根据应用需要进行选择配置
获取appid填入,去微信开放平台申请应用的AppId值,UniversalLinks:iOS平台通用链接,必须与微信开放平台配置的一致,参考iOS平台微信SDK配置通用链接(UniversalLinks)
发送请求到后台服务端,后台服务端生成订单信息,相应预支付订单信息,通过预支付订单信息请求支付接口。
importapi from'@/api/order.js'exportdefault{methods:{// 获取订单信息 (微信小程序支付需要openid)getOrderInfo(openid){// 不要少了asyncreturnnewPromise(async(resolve,reject)=>{letres =nullletdata ={}// 服务接口请求参数if(this.provider ==='alipay'){res =awaitapi.getOrderInfoAlipay(data)}elseif(this.provider ==='wxpay'){res =awaitapi.getOrderInfoWxpay(data)}if(res &&res.code ===20000){resolve(res.data)}else{reject(newError('获取支付信息失败'+res.message))}})},// 微信、支付宝等支付asyncpayHandler(){// 支付中this.loading =true// #ifdef APP-PLUS// 1. 发送请求到服务端,服务端生成订单信息,响应预支付订单letorderInfo =awaitthis.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(){returnnewPromise((resolve,reject)=>{// 1. 先使用微信登录小程序响应 code,uni.login({provider:'weixin',success:(res)=>{console.log('登录',res)constcode =res.code // 2. 请求服务端通过code获取openidletopenid ='xx'uni.setStorageSync('openid',openid)resolve(openid)},fail(err){reject(err)}})})},
步骤二、通过openid
再获取订单预支付信息,直接在getOrderInfo
写死一个模拟预支付信息即可。
getOrderInfo(openid){returnnewPromise(async(resolve,reject)=>{if(openid){// 微信小程序获取订单信息,发送请求 // let orderInfo = await api.getOrderInfoWxpayMP(openid) 如果有真实接口替换即可letorderInfo ={"timeStamp":"1414561699","nonceStr":"5K8264ILTKCH16CQ2502SI8ZNMTM67VS","package":"prepay_id=wx201410272009395522657a690389285100",//预支付交易会话标识( prepay_id) "signType":"RSA","paySign":"oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ",}resolve(orderInfo)return}letres =nullletdata ={}// 服务接口请求参数if(this.provider ==='alipay'){res =awaitapi.getOrderInfoAlipay(data)}elseif(this.provider ==='wxpay'){res =awaitapi.getOrderInfoWxpay(data)}if(res &&res.code ===20000){resolve(res.data)}else{reject(newError('获取支付信息失败'+res.message))}})},
步骤三、通过订单预支付信息,去调用支付接口
// 微信小程序支付asyncwxPayHandler(){this.loading =true// 1. 先获取用户code, 再获取openidletopenid =uni.getStorageSync('openid')if(!openid){try{openid =awaitthis.loginWeixinMp()}catch(e){console.error(e)}if(!openid){uni.showModal({content:'获取openid失败',showCancel:false})this.loading =falsereturn}}// 2. 通过 openid 再获取订单信息,letorderInfo =awaitthis.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
写死一个模拟预支付信息即可,通过订单预支付信息,去调用支付接口即可。
苹果应用内置流程与其它三方支付平台存在差异,请单独参考iOS 平台使用Apple应用内支付文档,项目中参考支付文档最下面示例代码
流程:
在onLoad中先获取Apple支付渠道的实例。
onLoad:function(option){// 获取支付金额if(option.params){constparams =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(vari inchannels){varchannel =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>importapi from'@/api/order.js'letiapChannel =null// 苹果内部支付渠道exportdefault{data(){return{activeIndex:0,loading:false,// 是否充值中disabled:true,//要先检查支付环境是否iap,不支付则点击立即支付无效balance:0,// 余额moneyList:[],// 充值列表展示金额price:0,// 支付金额courseIds:[],// 支付的课程idsapplePrice:30,// ios充值金额}},onLoad:function(option){// 获取支付金额if(option.params){constparams =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(vari inchannels){varchannel =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 },asyncloadData(){// 查询余额const{data }=awaitapi.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 0020rpx;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:000.5px $mxg-text-color-red;}.desc {// 清除浮动clear:both;margin:020rpx;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
版是包含微信和支付宝支付的,此时注意分开判断。详见
配置沙箱
沙箱支持产品
沙箱测试账号
带着商品信息请求后端接口,获取paymentUrl
然后通过window.location.href = res.paymentUrl
进行跳转
通过location.href
跳转到如下页面即可使用沙箱测试账号进行登录。下图为支付宝登录页面,可能会违规。
注意:沙箱测试支付功能一定要开启无痕浏览进行测试。
使用支付宝开放平台给的沙箱测试账号进行测试:如下找到
输入沙箱账号密码
支付成功
交易成功后,此页面会跳转到前端传递给后端的配置的跳转页面,支付成功后就会跳回到指定页面。
配置的支付成功后的跳转页面,在此页面调用后端接口,后端返回支付状态,根据支付状态再在此页面进行其他业务逻辑处理。
微信支付: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, [详见]
完结~,如有不足,后继补充。。。。