版权声明:转发原创文章请复制文章链接地址 https://blog.csdn.net/weixin_42579642/article/details/84860716
首先还是老样子把流程图给大家发一下
商户系统和微信支付系统主要交互:
1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API】
2、商户server调用支付统一下单,api参见公共api【统一下单API】
3、商户server调用再次签名,api参见公共api【再次签名】
4、商户server接收支付通知,api参见公共api【支付结果通知API】
5、商户server查询支付结果,api参见公共api【查询订单API】
获取openid首先客户端要调用wx.login()方法,得到code传给服务器端,服务器接收code通过wx.code2Session()获取openid及其他参数,php代码如下:
public function login(Request $request){
$code = $request -> get('code');
$url = 'https://api.weixin.qq.com/sns/jscode2session';
$str = 'appid='.self::appid.'&secret='.self::secret.'&js_code='.$code.'&grant_type=authorization_code';
$new_url = $url.'?'.$str;
$res = $this -> curlRequest($new_url);
$res = json_decode($res,true);
if(empty($res['openid'])){
return json_encode(['status'=>1,'content'=>$res['errmsg']]);
}
$openid = $res['openid'];
$session_key = $res['session_key'];
$token = uniqid();
$arr = [
'openid' => $openid,
'session_key' => $session_key,
'token' => $token,
'money' => 0,
'status' => 1
];
$data = DB::table('mobai_token')->where('openid',$openid)->first();
if(empty($data)){
DB::table('mobai_token')->insert($arr);
return json_encode(['status'=>0,'content'=>$token]);
}
$token = $data->token;
return json_encode(['status'=>0,'content'=>$token]);
}
调用统一下单接口并返回wx.requestPayment()所需的参数(注意生成paySign的时候一定要按规则生成)
//调取统一下单接口
public function unpay(Request $request){
$order = $request->get('rtime');
$money = $request->get('money');
$data = DB::table('mobai_order')->where('rtime',$order)->first();
$openid = $data->openid;
$unurl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$params = [
'appid' => self::appid,
'mch_id' => self::mch_id,
'nonce_str' => uniqid(),
'body' => '摩拜单车',
'out_trade_no' => $order,
'total_fee' => $money,
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'notify_url' => 'https://mobai.xxxx.cn/notify',//此处写你的回调地址
'trade_type' => 'JSAPI',
'openid' => $openid,
];
$params['sign'] = $this -> getSign($params);
$xml = $this -> ArrToXml($params);
$res = $this -> curlRequest($unurl,$xml);
$arr = $this -> XmlToArr($res);
$params2 = [
'appId' => self::appid,
'timeStamp' => strval(time()), //建议把时间戳转变成字符串
'nonceStr' => uniqid(),
'package' => 'prepay_id='.$arr['prepay_id'],
'signType' => 'MD5'
];
$params2['paySign'] = $this -> getSign($params2);
$params2['prepay_id'] = $arr['prepay_id'];
$redis = new \Redis();
$redis -> connect('127.0.0.1',6379);
$redis -> set($order,$arr['prepay_id']); //保存prepay_id,调用模板消息的时候需要
return $params2;
}
异步回调
public function notify(){
$data = file_get_contents('php://input');
$arr = $this -> XmlToArr($data);
$sign = $this -> getSign($arr);
if($sign == $arr['sign']){
//判断返回状态
if($arr['return_code'] == 'SUCCESS' || $arr['result_code'] == 'SUCCESS'){
$data = DB::table('mobai_order')->where('rtime',$arr['out_trade_no'])->where('status',1)->first();
//判断订单金额
if($data->money == $arr['total_fee']){
//修改订单状态
$res = DB::table('mobai_order')->where('rtime',$arr['out_trade_no'])->where('status',1)->update(['status'=>2]);
if($res){
$redis = new \Redis();
$redis -> connect('127.0.0.1',6379);
$prepay_id = $redis -> get($arr['out_trade_no']); //prepay_id要在统一下单的时候做保存
$money = $arr['total_fee']/100;
$this -> sendTemplateMessage($prepay_id,$arr['out_trade_no'],$money,$arr['openid']); //发送模板消息
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';//给微信正常相应(如果没有正常相应微信会根据自己的机制多次请求)
}
}
}
}
}
getSign()、XmlToArr()、ArrToXml()方法可以在这个博客看:https://blog.csdn.net/weixin_42579642/article/details/84861502