1. 地图导航
注意: (支付宝内部调用高德地图API, 微信内容调用腾讯地图API)
1.1 支付宝
点击导航会引导用户打开高德地图;若未安装高德地图,会引导用户下载高德地图.
- 代码:
my.openLocation({
longitude: 121.47061,
latitude: 31.26460,
name: '申航大厦',
address: '上海市静安区中山北路198号(西藏北路地铁站2号口步行250米)',
success: res => {
console.log(res);
},
fail: res => {
console.log(res);
},
});
- 参数说明
- 注意:支付宝调用API的经纬度可以自己给上,微信调用API不可以,只能通过
wx.getLocation方法返回来精确的经纬度 - 支付宝文档:点我进入文档
1.2 微信
微信小程序和支付宝小程序大致相同,工作中没有直接使用到微信的地图导航,这里只做文档的说明
- 代码
wx.getLocation({
type: 'gcj02', //返回可以用于wx.openLocation的经纬度 (固定写法)
success (res) {
const latitude = res.latitude
const longitude = res.longitude
wx.openLocation({
latitude,
longitude,
scale: 18
})
}
})
- 阅读示例代码发现 和支付宝相比在外层多调用了一次
wx.getLocation方法, 这个方法是为了获取精确的经纬度. - 微信文档点我进入文档
2. 微信&支付宝支付
2.1 支付宝支付
- 支付宝支付是绝对的重头戏。支付宝有两种支付方式,一是直接支付(需要支付押金),二是签署连续包月服务(不需要支付押金)。
- 先说签署协议
// 代码实现
// 一般会用一个变量来判断是哪种支付方式
if (this.confirmImage) {
// 公司内部封装的发请求的轮子 可以忽略写法
const [err, res] = await rentBatteryRequest({
path: '/alipay/agreement/sign/nofreeze',
method: 'POST',
data: {
setmealId: this.setmealId
}
}, 1)
console.log('连续包月回调', err, res);
if (err) return
await this.aliSesamePay(res.data.signStr) // 返回的res里有调用连续包月需要的 signStr
return
}
//连续包月 方法
async aliSesamePay(signStr) {
my.paySignCenter({ //调起支付宝连续包月页面让用户点击 (下列主要对各种情况进行处理)
signStr,
success: async (result) => {
console.log('连续包月回调', result);
if (result.resultStatus == 7000) {
uni.showToast({
title: '已完成支付',
icon: 'none'
})
uni.showLoading({
title: '跳转中'
})
setTimeout(async (restimeout) => {
uni.hideLoading()
this.$request.to('../devController/devController', 'r')
}, 2500)
return
}
if (result.resultStatus == 6001) {
uni.showModal({
content: '中途取消',
showCancel: false
})
return
}
if (result.resultStatus == 7002) {
uni.showModal({
content: '协议签约失败',
showCancel: false
})
return
}
},
fail: (err) => {
console.log('连续包月回调', err);
uni.showToast({
title: '支付失败,请继续完成支付',
icon: 'none'
})
},
});
},
- 直接支付
- 看着代码比较长,逻辑大概是这样:
- 判断用户是否缴纳了押金. 如果是,那么去支付租金;如果否,调用峰云免押接口,如果成功,则冻结押金,如果失败,调用支付押金接口
//支付押金
async goPayCash() {
//判断是否缴纳押金
if (this.isPayCash) {
//已缴纳押金需要支付租金
await this.goPayCRent(); // 支付租金方法
return;
}
//免押金
if (this.showView) {
//调用峰云免押
const option = {
path: "/fengyun/preFreeze",
method: "POST",
data: {
setmeal_id: this.setmealId,
},
};
const [err, res] = await myRequest(option, 1);
if (err) {
console.log(err, "失败");
return;
}
this.rentOrderId = res.data.rent_order_id;
my.tradePay({
orderStr: res.data.orderStr, // 完整的支付参数拼接成的字符串,从服务端获取
success: async (tradeRes) => {
if (tradeRes.resultCode == 9000) {
//押金已经缴纳更改状态
this.isPayCash = true;
uni.showModal({
content:"已缴纳押金,请点击下方支付租金。支付完成后在“我的设备”绑定电池即可使用。",
showCancel: false,
success: async () => {
await this.goPayCRent();
},
});
return;
}
if (tradeRes.resultCode == 6001) {
uni.showToast({
title: "已取消支付",
icon: "none",
});
return;
}
this.showView = false;
},
fail: (res) => {
console.log(res, "失败");
uni.alert({
content: JSON.stringify(res),
});
},
});
}
//免押失败的情况,支付押金
if (!this.showView) {
const [error, success] = await myRequest({
path: "/alipay/preFreeze",
method: "POST",
data: {setmeal_id: this.setmealId,},
},1)
this.rentOrderId = success.data.rent_order_id;
my.tradePay({
orderStr: success.data.orderStr, // 完整的支付参数拼接成的字符串,从服务端获取
success: async (payRes) => {
console.log(payRes, "调起支付宝支付接口后");
if (payRes.resultCode == 9000) {
//押金已经缴纳更改状态
this.isPayCash = true;
uni.showModal({
content:"已缴纳押金,请支付租金。支付完成后在“我的设备”绑定电池即可使用。",
showCancel: false,
success: async () => {
await this.goPayCRent(); // 支付租金方法
},
});
}
},
});
}
},
//支付租金
async goPayCRent() {
...
await this.affirmPay();
},
//直接购买 支付租金
async affirmPay() {
//发起支付
const [rentErr, rentRes] = await rentBatteryRequest({
path: "/alipay/rentalPreCreate",
method: "POST",
data: {
rent_order_id: this.rentOrderId,
months: `${this.productCount}`,
coupons: this.confirmList,
discount_id: this.discount_id,
},
},1);
// 这个是调用支付内部的支付接口 我们后端会返回需要的orderInfo参数
uni.requestPayment({
provider: "alipay",
orderInfo: rentRes.data.trade_no,
success: async (payRes) => {
if (payRes.resultCode == 9000) {
uni.showToast({
title: "已完成支付",
});
setTimeout(() => {
uni.redirectTo({
url: "../devController/devController",
});
}, 1000);
return;
}
if (payRes.resultCode == 6001) {
uni.showModal({
content: "支付未完成,请在'我的设备'继续对此订单完成支付",
showCancel: false,
success: (res) => {
uni.redirectTo({
url: "../devController/devController",
});
},
});
}
},
});
},
2.2 微信支付
- 微信只有一种支付方式
// 微信端支付 点击确定
async rentConfirm(){
const option = {
path:'/weixin/createOrder',
method:'POST',
data: {
setmeal_id:this.setmealId,
setmeal_num:`${this.productCount}`,
isNeedPremium:false,
coupons:this.confirmList,
discount_id: this.discount_id
}
}
const [err,res] = await rentBatteryRequest(option,1)
const result = mypay(res.data).then(result => {
//处理result,提示,然后跳转
if(!result) {
return
}
this.$request.to('../devController/devController','r')
}).catch(err=>{
//处理err
console.error(err.errMsg,'错误')
})//前提:外部方法是async的
await mypay(res.data).then((res)=>{
console.log('支付成功',res)
uni.showToast({
title: '已完成支付,正在跳转',
icon: 'none'
})
setTimeout(()=>{
this.$request.to('../devController/devController','r')
},3000)
}).catch(()=>{
console.log('支付失败')
})
},
// 封装的轮子 支付方法(微信支付宝都兼容)
export async function mypay(data) {
const { timeStamp, nonceStr, signType, paySign, provider, trade_no } = data
return await new Promise(async (resolve, reject) => {
console.log('执行支付内部 ,支付宝需要的trade_no = ', trade_no);
console.log('执行支付内部,微信支付需要的', timeStamp, nonceStr, data.package, signType, paySign);
await uni.requestPayment({
// #ifdef MP-ALIPAY
provider: 'alipay',
orderInfo: trade_no,
// #endif
// #ifdef MP-WEIXIN
provider: 'wxpay',
timeStamp,
nonceStr,
package: data.package,
signType,
paySign,
// #endif
success: (res) => {
console.log('支付成功', res);
// #ifdef MP-ALIPAY
if (res.resultCode == 9000) {
console.log('支付成功');
uni.showToast({
title: '支付成功',
icon: 'none'
})
resolve(true)
return
}
uni.showModal({
content: res.memo ? res.memo : '支付未完成',
showCancel: false
})
reject(false)
// #endif
// #ifdef MP-WEIXIN
uni.showToast({
title: '支付成功',
icon: 'none'
})
resolve(true)
// #endif
},
fail: err => {
console.log('失败', err);
uni.showModal({
content: '支付未完成',
showCancel: false
})
reject(false)
}
})
console.log('支付方法 已经走完');
})
}