咱们在作小程序支付相关的开发时,总会遇到这些难题。小程序调用微信支付时,必需要有本身的服务器,有本身的备案域名,有本身的后台开发。这就致使咱们作小程序支付时的成本很大。本节就来教你们如何使用小程序云开发实现小程序支付功能的开发。不用搭建本身的服务器,不用有本身的备案域名。只须要简简单单的使用小程序云开发。html
老规矩先看效果图: node
1,云开发的部署和使用 2,支付相关的云函数开发 3,商品列表 4,订单列表 5,微信支付与支付成功回调数据库
支付成功给用户发送推送消息的功能会在后面讲解。小程序
1,小程序appid 2,云开发环境id 3,微信商户号 4,商户密匙微信小程序
1,已经申请小程序,获取小程序 AppID 和 Secret 在小程序管理后台中,【设置】 →【开发设置】 下能够获取微信小程序 AppID 和 Secret。 安全
3,微信开发者 IDE developers.weixin.qq.com/miniprogram… 4,开通小程序云开发功能:edu.csdn.net/course/play…bash
效果图以下,因为本节重点是支付的实现,因此这里只简单贴出关键代码。 服务器
<view class="container">
<view class="good-item" wx:for="{{goods}}" wx:key="*this" ontap="getDetail" data-goodid="{{item._id}}">
<view class="good-image">
<image src="{{pic}}"></image>
</view>
<view class="good-detail">
<view class="title">商品: {{item.name}}</view>
<view class="content">价格: {{item.price / 100}} 元 </view>
<button
class="button"
type="primary"
bindtap="makeOrder"
data-goodid="{{item._id}}"
>下单</button>
</view>
</view>
</view>
复制代码
咱们所须要作的就是借助云开发获取云数据库里的商品信息,而后展现到商品列表,关于云开发获取商品列表并展现本节不作讲解(感兴趣的同窗能够翻看个人历史博客,有写过的) 微信
首先看下咱们支付云函数都包含那些内容 微信开发
1,配置config下的index.js, 这一步所须要作的就是把小程序appid,云开发环境ID,商户id,商户密匙。填进去。
const cloud = require('wx-server-sdk')
cloud.init()
const app = require('tcb-admin-node');
const pay = require('./lib/pay');
const {
mpAppId,
KEY
} = require('./config/index');
const {
WXPayConstants,
WXPayUtil
} = require('wx-js-utils');
const Res = require('./lib/res');
const ip = require('ip');
/**
*
* @param {obj} event
* @param {string} event.type 功能类型
* @param {} userInfo.openId 用户的openid
*/
exports.main = async function(event, context) {
const {
type,
data,
userInfo
} = event;
const wxContext = cloud.getWXContext()
const openid = userInfo.openId;
app.init();
const db = app.database();
const goodCollection = db.collection('goods');
const orderCollection = db.collection('order');
// 订单文档的status 0 未支付 1 已支付 2 已关闭
switch (type) {
// [在此处放置 unifiedorder 的相关代码]
case 'unifiedorder':
{
// 查询该商品 ID 是否存在于数据库中,并将数据提取出来
const goodId = data.goodId
let goods = await goodCollection.doc(goodId).get();
if (!goods.data.length) {
return new Res({
code: 1,
message: '找不到商品'
});
}
// 在云函数中提取数据,包括名称、价格才更合理安全,
// 由于从端里传过来的商品数据都是不可靠的
let good = goods.data[0];
// 拼凑微信支付统一下单的参数
const curTime = Date.now();
const tradeNo = `${goodId}-${curTime}`;
const body = good.name;
const spbill_create_ip = ip.address() || '127.0.0.1';
// 云函数暂不支付 http 触发器,所以这里回调 notify_url 能够先随便填。
const notify_url = 'http://www.qq.com'; //'127.0.0.1';
const total_fee = good.price;
const time_stamp = '' + Math.ceil(Date.now() / 1000);
const out_trade_no = `${tradeNo}`;
const sign_type = WXPayConstants.SIGN_TYPE_MD5;
let orderParam = {
body,
spbill_create_ip,
notify_url,
out_trade_no,
total_fee,
openid,
trade_type: 'JSAPI',
timeStamp: time_stamp,
};
// 调用 wx-js-utils 中的统一下单方法
const {
return_code,
...restData
} = await pay.unifiedOrder(orderParam);
let order_id = null;
if (return_code === 'SUCCESS' && restData.result_code === 'SUCCESS') {
const {
prepay_id,
nonce_str
} = restData;
// 微信小程序支付要单独进地签名,并返回给小程序端
const sign = WXPayUtil.generateSignature({
appId: mpAppId,
nonceStr: nonce_str,
package: `prepay_id=${prepay_id}`,
signType: 'MD5',
timeStamp: time_stamp
}, KEY);
let orderData = {
out_trade_no,
time_stamp,
nonce_str,
sign,
sign_type,
body,
total_fee,
prepay_id,
sign,
status: 0, // 订单文档的status 0 未支付 1 已支付 2 已关闭
_openid: openid,
};
let order = await orderCollection.add(orderData);
order_id = order.id;
}
return new Res({
code: return_code === 'SUCCESS' ? 0 : 1,
data: {
out_trade_no,
time_stamp,
order_id,
...restData
}
});
}
// [在此处放置 payorder 的相关代码]
case 'payorder':
{
// 从端里出来相关的订单相信
const {
out_trade_no,
prepay_id,
body,
total_fee
} = data;
// 到微信支付侧查询是否存在该订单,并查询订单状态,看看是否已经支付成功了。
const {
return_code,
...restData
} = await pay.orderQuery({
out_trade_no
});
// 若订单存在并支付成功,则开始处理支付
if (restData.trade_state === 'SUCCESS') {
let result = await orderCollection
.where({
out_trade_no
})
.update({
status: 1,
trade_state: restData.trade_state,
trade_state_desc: restData.trade_state_desc
});
let curDate = new Date();
let time = `${curDate.getFullYear()}-${curDate.getMonth() +
1}-${curDate.getDate()} ${curDate.getHours()}:${curDate.getMinutes()}:${curDate.getSeconds()}`;
}
return new Res({
code: return_code === 'SUCCESS' ? 0 : 1,
data: restData
});
}
case 'orderquery':
{
const {
transaction_id,
out_trade_no
} = data;
// 查询订单
const {
data: dbData
} = await orderCollection
.where({
out_trade_no
})
.get();
const {
return_code,
...restData
} = await pay.orderQuery({
transaction_id,
out_trade_no
});
return new Res({
code: return_code === 'SUCCESS' ? 0 : 1,
data: { ...restData,
...dbData[0]
}
});
}
case 'closeorder':
{
// 关闭订单
const {
out_trade_no
} = data;
const {
return_code,
...restData
} = await pay.closeOrder({
out_trade_no
});
if (return_code === 'SUCCESS' &&
restData.result_code === 'SUCCESS') {
await orderCollection
.where({
out_trade_no
})
.update({
status: 2,
trade_state: 'CLOSED',
trade_state_desc: '订单已关闭'
});
}
return new Res({
code: return_code === 'SUCCESS' ? 0 : 1,
data: restData
});
}
}
}
复制代码
其实咱们支付的关键功能都在上面这些代码里面了。
再来看下,支付的相关流程截图
上图就涉及到了咱们的订单列表,支付状态,支付成功后的回调。 今天就先讲到这里,后面会继续给你们讲解支付的其余功能。好比支付成功后的消息推送,也是能够借助云开发实现的。
因为源码里涉及到一些私密信息,这里就不单独贴出源码下载连接了,你们感兴趣的话,能够私信我,或者在底部留言。单独找我要源码也行(微信2501902696)