一、主要逻辑
1.支付可能需要哪些东西
-
支付的方式【微信】【支付宝】
-
支付的金额
-
订单的标题
-
订单号
-
订单的有效期
-
支付完成跳转的链接
2.支付
2.1.点击立即购买的时候,想后端发送ajax请求,请求中携带信息 的完整流程
ajax({
url:'xxxx', =====》前端给后端传递的数据
data:{
用户id,
****订单的金额
****订单的商品系类
},
success:function(){ ===》后端给前端返回的数据
if(data.xxx){
data是一个对象,通常含有订单号
然后跳转到确认订单页面
}
}
})
2.2.确认订单页面===>点击提交订单===>选择支付方式(支付前也会发送请求)
2.2.1 再三确定用户选择的,和后端返回的方式是否一致
````
ajax({
data:{ ===>前端给后端传递数据
appid:'已经准备好的(通常是公司申请的id(用来收钱的)'
订单号
选择了那种支付方式
},
success:function(){
1.后端会返回true,代表可以支付了
2.还会返回一个标示(那种支付方式
if(后端给前端传递的哪种支付方式===用户点击的哪种支付方式){
//成立情况下,则开始发起支付的请求(这时候需要对接支付宝或微信支付官方了)
发起支付
}
}
})
````
2.2.2 对接官方支付
把得到的一些数据,传递给支付宝|微信支付官方
总结1:用户点击购买的时候不是立即调起支付的请求,而是向后端发送请求,然后后端返回订单号。返回订单号的意义就是当用户点击提交订单的时候,再将这个订单号传递给后端,可以知道该订单的状态,然后同时将用户选择 的支付方式告知后端,最后后端进行返回验证。最后根据后端返回的数据发送支付请求(对接官方)----这个支付请求一般是封装好的,你只需要传递一些数据即可
前端拿到订单号之后再向后端发送请求,
三、在uni-app中的使用:
前端的所要做的就是:
- 请求后端接口,获取到orderinfo(订单信息)根据官方的新这个订单信息是后端直接拼接的字符串,前端不需要其他操作
- 调用支付API:uni.requestPayMent
- 处理回调
注意问题:
- 订单的格式是后端返回来的,前端不需要进行任何处理,不管是哪种支付,订单的信息都是strng类习惯的
- uni-app里的mainfest.json里面的微信支付id,要添加在微信开发平台申请移动应用支付的appid,,因为可能会遇到好几个appid,因为这个原因弄了很长时间
- 在开放平台申请的移动用用支付时,应用包名可以自己起,应用签名需要按照微信的说明生成或者在线生成证书(证书可以是生成md5的签名),全部小写没有冒号----这一步类似于调用起高德地图中的配置
- 商户订单号 唯一 是针对整个项目,可能有多个交易记录表,订单号不能重复
//微信orderinfo格式
"{\"appid\":\"xxxxxxxx\",\"partnerid\":\"xxxxxxx\",\"prepayid\":\"xxxxxxxxxxxxxxxx\",\"timestamp\":\"1579779903\",\"noncestr\":\"xxxxxxx\",\"package\":\"Sign": "WXPay\",\"sign\":\"xxxxxxxxxxxxxxxxxxxx\"}"
//支付宝orderinfo格式
app_id=xxxxxxxxx&method=xxxxxxxxxx&format=JSON&charset=UTF-8&sign_type=RSA2&version=1.0&return_url=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx¬ify_url=xxxxx×tamp=xxxxxx&sign=xxxxxxx&biz_content=xxxxxxxxxx
主要代码:
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view style="background:#FFF; padding:50upx 0;">
<view class="uni-hello-text uni-center">支付金额</text></view>
<view class="uni-h1 uni-center uni-common-mt">
<text class="rmbLogo">¥</text>
<input class="price" type="digit" :value="price" maxlength="4" @input="priceChange" />
</view>
</view>
<view class="uni-btn-v uni-common-mt">
<!-- #ifdef APP-PLUS -->
<template v-if="providerList.length > 0">
<button v-for="(item,index) in providerList" :key="index" @click="requestPayment(item,index)"
:loading="item.loading">{
{item.name}}支付</button>
</template>
<!-- #endif -->
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'request-payment',
loading: false,
price: 1,
providerList: []
}
},
onLoad: function() {
// #ifdef APP-PLUS
uni.getProvider({
service: "payment",
success: (e) => {
console.log("payment success:" + JSON.stringify(e));
let providerList = [];
e.provider.map((value) => {
switch (value) {
case 'alipay':
providerList.push({
name: '支付宝',
id: value,
loading: false
});
break;
case 'wxpay':
providerList.push({
name: '微信',
id: value,
loading: false
});
break;
default:
break;
}
})
this.providerList = providerList;
},
fail: (e) => {
console.log("获取支付通道失败:", e);
}
});
// #endif
},
methods: {
async requestPayment(e, index) {
this.providerList[index].loading = true;
let orderInfo = await this.getOrderInfo(e.id);
console.log("得到订单信息", orderInfo);
if (orderInfo.statusCode !== 200) {
console.log("获得订单信息失败", orderInfo);
uni.showModal({
content: "获得订单信息失败",
showCancel: false
})
return;
}
uni.requestPayment({
provider: e.id,
orderInfo: orderInfo.data.data,
success: (e) => {
console.log("success", e);
uni.showToast({
title: "感谢您的赞助!"
})
},
fail: (e) => {
console.log("fail", e);
uni.showModal({
content: "支付失败,原因为: " + e.errMsg,
showCancel: false
})
},
complete: () => {
this.providerList[index].loading = false;
}
})
},
getOrderInfo(e) {
let appid = "";
// #ifdef APP-PLUS
appid = plus.runtime.appid;
// #endif
let url = 'http://10.10.60.200:8070/sc-admin/sales/wx/prepay/?brokerId=shba01';
return new Promise((res) => {
uni.request({
url: url,
success: (result) => {
res(result);
},
fail: (e) => {
res(e);
}
})
})
},
priceChange(e) {
console.log(e.detail.value)
this.price = e.detail.value;
}
}
}
</script>
<style>
.rmbLogo {
font-size: 40upx;
}
button {
background-color: #007aff;
color: #ffffff;
}
.uni-h1.uni-center {
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-end;
}
.price {
border-bottom: 1px solid #eee;
width: 200upx;
height: 80upx;
padding-bottom: 4upx;
}
.ipaPayBtn {
margin-top: 30upx;
}
</style>
简洁版的理解代码:
uni.requestPayment({
provider: 'alipay',
orderInfo: '后端返回的orderinfo字符串',
success: res => {
// 进入此回调说明支付成功
},
fail: err => {
const message = err.errMsg || '';
if (message.indexOf('[payment支付宝:62001]') !== -1) {
uni.showModal({
content: '您已取消支付。如有需要,您可在我的订单里重新付款。30分钟内有效。',
showCancel: false
});
} else {
uni.showModal({
content: '支付失败,原因为: ' + message,
showCancel: false
});
}
},
complete: () => {
this.submitting = false;
}
});