第一次做小程序的支付,网上有很多的资料,但是不全,得找很长时间才能找到真正有帮助的资料,本着能帮助刚刚做支付的朋友的原则,同时也记录下来,方便自己以后忘记的时候,能回来看看,写这篇博客
首先,你得有小程序
去注册小程序,然后,有得到你的代码载体,最起码,小程序端和后台得能实现选择商品,确定订单的步骤,然后,一个按钮,崩!啪!输入密码,你的钱没了,哈哈哈
到了这一步了,开始说明,之前的步骤就跳过了,这个都不是大问题,点击微信支付的时候,小程序端吗,需要把商品的价格就是那个0.01元还有用户的标识(用户id或者是能找出用户openid的参数)传过去,其他的都不是支付必要的,但是是你实现支付业务需要的参数和数据,也需要传递
上面显示的是已经成功之后的弹出页面,下面是pay函数所传递的参数
//不是完整函数,上面生成订单部分省略
if($insert){
//调取支付接口
// 获取支付金额
$wx_pay = new Pay;
//将钱数转化为分
$money = $true_money*100;
$result = $wx_pay->wechat_pay($openid,$result['outer_id'],$money);
}
下面是引用的函数
//微信支付
public function wechat_pay($openid,$trade_no,$money){
//②、统一下单
$input = new \WxPayUnifiedOrder();
$input->SetBody('某某团');
$input->SetOpenid($openid);
$input->SetAttach("MMT");
$input->SetOut_trade_no($trade_no);
$input->SetTotal_fee($money);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
// $input->SetGoods_tag("test");
$input->SetNotify_url("http://".$_SERVER['HTTP_HOST']."/Api/Notify/wx_notify");
$input->SetTrade_type("JSAPI");
$order = \WxAppPayApi::unifiedOrder($input);
// $order['timestamp'] = time();
// $order['package'] = "Sign=WXPay";
//判断返回结果
if($order['return_code'] == 'SUCCESS' && $order['result_code'] == 'SUCCESS')
{
$time = time();
$info = '';
$info = array(
'appId' => '',//你的appid
'timeStamp' => ''.$time.'',
'nonceStr' => $this->nonce_str(),
'package' => 'prepay_id='.$order['prepay_id'],
'signType' => 'MD5',
);
$info['paySign'] = $this->sign($info);
$return['code'] = 200;
$return['msg'] = 'success';
$return['list'] = $info;
}else{
$return['code'] = 300;
$return['msg'] = 'fail';
$return['list'] = $order;
}
return $return;
}
需要注意的是,上面的参数部分
如果有问题,就需要,一步一步的打印返回值,就是上面的$order,看order返回值来修改问题,之前,本人就是因为直接在别人的项目之上改的,appid忘记改了,导致,一直报错,最后,才发现是appid没改,哎,只怪自己才粗心。
微信支付的常量配置,找小程序所有人去要,他能进后台,可以进后台去找。
四个参数,缺一不可。
成功之后,进入小程序端
wx.requestPayment({
timeStamp: rel.timeStamp,
nonceStr: rel.nonceStr,
package: rel.package,
signType: rel.signType,
paySign: rel.paySign,
//如果用户支付了,将支付成功的订单id发动到后台,将后台的订单状态改为已支付,
success() {
let success = pay_success({
user_id:user_id,
order_id:result.order_id,
money:result.money,
coupon_id:result.coupon_id
});
uni.navigateTo({
url:'/pages/order/orderDetail/orderDetail?otm='+result.order_id,//打开首页关闭其他页面
success() {
uni.showToast({
title: '支付成功',
icon: 'success',
});
}
})
},
//如果用户最后关头取消了,将订单信息和用户信息传到后台
fail(){
let fail = pay_fail({
user_id:user_id,
order_id:result.order_id,
nonceStr:result.list.nonceStr,
package:result.list.package,
paySign:result.list.paySign,
signType:result.list.signType,
timeStamp:result.list.timeStamp
});
console.log(result.order_id)
uni.navigateTo({
url:'/pages/order/orderDetail/orderDetail?otm='+result.order_id,
success() {
uni.showToast({
title: '支付失败'
});
}
})
}
})
如果用户成功支付了,那将订单转台修改即可,改为已支付,走后面流程即可,如果是没支付,到了最后一步取消了,但是微信支付的框,确实是弹出来了,那就把传过来的信息传回到后台,专门写一个支付失败的函数,
//用户取消支付的函数
public function pay_fail()
{
$user_id = $_POST['user_id'];
$order_id = $_POST['order_id'];
$nonceStr = $_POST['nonceStr'];
$package = $_POST['package'];
$paySign = $_POST['paySign'];
$signType = $_POST['signType'];
$timeStamp = $_POST['timeStamp'];
//同时将返回的信息返回存入数据库
$order_refund['user_id'] = $user_id;
$order_refund['order_id'] = $order_id;
$order_refund['nonceStr'] = $nonceStr;
$order_refund['package'] = $package;
$order_refund['paySign'] = $paySign;
$order_refund['signType'] = $signType;
$order_refund['timeStamp'] = $timeStamp;
$order_refund['created_at'] = date('Y-m-d H:i:s');
$order_result = Db::name('order_refund')->insert($order_refund);
if($order_result){
$return['code'] = 200;
}else{
$return['code'] = 300;
}
$this->ajaxReturn($return);
}
腾讯默认设置的是两个小时的过期时间,我们在用户取消的时候,将数据存入数据库,当用户点击未支付的订单去支付的时候,直接去数据库通过order_id找此条数据,咱们给设置为1个小时的过期时间或者是30分钟也行,过期了,可以去请求腾讯的接口去去取消订单,或者直接不让用户点击去支付,过了两个小时自己就取消了。