近日开发一个顺风小巴的小程序,开发还是比较简单的,只是有些语法真是反人类,主要难点是微信支付,其他的调调接口渲染一下数据就ok了,下面就详细说一下整个流程及中间遇到的坑。
1、准备工作
a、小程序账号申请
像申请公众号一样,要求企业资质,另外交给企鹅300块钱。
b、微信支付商家平台申请
申请支付功能必不可少的部分,期间踩了一个坑,老板为了节省三百块钱,用一个老的商户平台id绑定到小程序上,结果调试的时候一直报错,提示appid与商家MCHID不匹配,然后小程序无法解绑商户号,只能重新申请小程序和商户号。既耽误了时间又多花了钱。
c、下载商家证书
在商家平台上下载证书,解压放到sdk文件存储证书对应位置
d、服务器https验证
小程序要求服务器必须是https的,并且不是所有https都可以,https://www.qcloud.com/product/ssl 这个地址可以进行测试,测试通过即可使用,否则可能出现真机测试无法获取数据的问题。
e、下载jsapi的SDK
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 SDK文档下载地址
之后修改SDK的配置文件WxPay.Config.php
const APPID = 'wx97fs3234d88desb';
const APPSECRET = 'ef103ba456be043244238f7b721e957';
const MCHID = '1444333112';
const KEY = 'Niskh5WfdsdfsdWYkr8lrddwsHyE78m2sE';
2、开发
a、微信登录
通过code到服务器获取用户openid,然后存储到小程序本地,用以后续与服务器交互
wx.login({
success: function (res1) {
var code = res1.code;
wx.request({
url: 'https://服务器/example/login.php',
method:'GET',
data: {
code: code
},
success: function (res) {
var uid = res.data;
console.log(uid)
wx.setStorage({
key: "uid",
data: uid
})
console.log('同步保存成功')
}
}),
wx.getUserInfo({
success: function (res) {
console.log(res.data)
that.globalData.userInfo = res.userInfo
typeof cb == "function" && cb(that.globalData.userInfo)
}
})
}
})
b、获取列表
wx.request({
url: 'https://接口地址',
method: 'GET',
success: function (res) {
var noStartList = res.data.noStartList;
that.setData({
noStartList: noStartList,
hiddenLoading: !that.data.hiddenLoading
});
}
})
c、微信支付
小程序端先调用服务器,让服务器创建订单,然后服务器去请求微信支付服务后台生成预支付交易单,返回正确的预支付交易后由小程序端调起支付。
wx.request({
url: 'https://调用服务器获取微信统一下单数据',
method: 'GET',
data: { uid: uid, id: id },
success: function (res) {
var nowTime = new Date()
var appId = res.data.appid
var timeStamp1 = Math.round((nowTime.getTime()) / 1000)
var timeStamp = timeStamp1.toString()
var nonceStr = res.data.nonce_str
var package = "prepay_id=" + res.data.prepay_id
var signType = "MD5"
var key = "Niskh5234234WYk4323HyE78m2sE"//商户平台的key
var sign = res.data.sign
var paySign = md5.hexMD5("appId=" + appId + "&nonceStr=" + nonceStr + "&package=" + package + "&signType=MD5&timeStamp=" + timeStamp + "&key=" + key)
wx.requestPayment({
timeStamp: timeStamp,
//随机字符串,长度为32个字符以下。
nonceStr: nonceStr,
//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
package: package,
//签名算法,暂支持 MD5
signType: 'MD5',
paySign: paySign,
success: function (res) {
},
fail: function (res) {
},
complete: function (res) {
}
})
}
})
服务器端逻辑
//①、获取传递参数
//②、生成订单
//3、统一向微信端下单
$input = new WxPayUnifiedOrder();
$input->SetBody("顺风小巴购票");
$input->SetAttach("顺风小巴购票");
$input->SetOut_trade_no($data['oId']);
$input->SetTotal_fee($data['price']*100);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetNotify_url("http://服务器/notify.php");
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openId);
$order = WxPayApi::unifiedOrder($input);
header("Content-Type: application/json");
echo json_encode($order);
exit;
这时候还需要在服务器端完善回调函数notify.php
//重写回调处理函数
public function NotifyProcess($data, &$msg)
{
Log::DEBUG("call back:" . json_encode($data));
$notfiyOutput = array();
if(!array_key_exists("transaction_id", $data)){
$msg = "输入参数不正确";
return false;
}
//查询订单,判断订单真实性
if(!$this->Queryorder($data["transaction_id"])){
$msg = "订单查询失败";
return false;
}
//根据 $data["out_trade_no"] 订单号 更新订单状态
//更新订单状态逻辑代码
return true;
}
整个支付过程就完成了,尤其注意的就是支付需要的参数及参数加密顺序,其他的调试一下基本就ok了。