最近项目需要做微信支付的功能,想着把流程以及遇到的坑记录下来 1.到微信商户平台中去开通Native支付(产品中心-Native支付-申请开通) 2.微信商户平台中下载证书以及设置api密钥(账户中心-api安全),查看指引中很详细的说
最近项目需要做微信支付的功能,想着把流程以及遇到的坑记录下来
1.到微信商户平台中去开通Native支付(产品中心-Native支付-申请开通)
2.微信商户平台中下载证书以及设置api密钥(账户中心-api安全),查看指引中很详细的说明了下载证书以及设置密钥的步骤。
3.微信商户平台中设置网页授权支付和支付回调url(产品中心-Native支付-开发配置)
4.微信公众平台中设置网页授权域名(公众号设置-功能设置-网页授权域名),这个微信里面也有详细的说明,照着做就行了。
到这里前期准备工作就做完了,现在可以进行开发了
1.下载好的证书放到项目中,我放的是extend/utils/wechart目录下
2.设置微信相关配置
3.调用Native支付接口,获取二维码链接,扫码付款后微信将信息回调到设置好的接口中,获取之后该干啥干啥。
class wxp extends Common{ protected $payApi = [ 'native' => 'https://api.mch.weixin.qq.com/v3/pay/transactions/native', //native支付 ]; public function nativePay($total) { $order_code = 'WX' . $this->getOrderNo(); //生成订单 $order_data['order_code'] = $order_code; $order_data['goods_money'] = $total; $order_data['totalmoney'] = $total; $order_data['person_id'] = $_REQUEST['person_id']; $order_data['order_type'] = $_REQUEST['order_type']; $order_data['pay_type'] = 1; $order_data['create_time'] = time(); $order_data['status'] = 0; $order_id = db('order')->insertGetId($order_data); $detail_data['order_id'] = $order_id; if ($_REQUEST['order_type'] == 1) { if ($_REQUEST['goods_id'] && $total) { $goods = db('goods')->where('goods_id', $_REQUEST['goods_id'])->find(); $detail_data['goods_num'] = $_REQUEST['goods_num']; $detail_data['goods_price'] = $_REQUEST['goods_price']; $detail_data['goods_id'] = $_REQUEST['goods_id']; $detail_data['person_id'] = $goods['person_id']; $detail_data['goods_name'] = $goods['goods_name']; $detail_data['goods_pic'] = $goods['goods_pic']; db('order_detail')->save($detail_data); } else { return json(['status' => 201, 'msg' => '参数错误']); } } //请求参数(报文主体) $config = $this->config(); $body = [ 'appid' => config('my.official_accounts.appid'), 'mchid' => config('my.wechart_pay.mchid'), 'description' => config('my.wechart_pay.description'), 'out_trade_no' => $order_code, 'notify_url' => config('my.wechart_pay.notify_url'), 'attach' => $_REQUEST['person_id'], 'amount' => [ 'total' => $total * 100, 'currency' => 'CNY' ], 'scene_info' => [ 'payer_client_ip' => $_SERVER['REMOTE_ADDR'], ], ]; $headers = $this->sign('POST', $this->getPayUrl('native'), json_encode($body)); //return $this->generateQRfromGoogle($this->curl_post($this->getPayUrl('native'),json_encode($body),$headers)['code_url']); return json(['status' => 200, 'msg' => json_decode($this->curl_post($this->getPayUrl('native'), json_encode($body), $headers)), 'order_code' => $order_code]); } public function sign($http_method = 'POST', $url = '', $body = '') { $mch_private_key = openssl_get_privatekey(file_get_contents(config('my.wechart_pay.key_path'))); //私钥 $timestamp = time(); //时间戳 $nonce = $this->getRandomStr(32); //随机串 $url_parts = parse_url($url); $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?{$url_parts['query']}" : "")); //构造签名串 $message = $http_method . "\n" . $canonical_url . "\n" . $timestamp . "\n" . $nonce . "\n" . $body . "\n"; //报文主体 //计算签名值 openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); //设置HTTP头 $config = $this->config(); $token = sprintf( 'WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $config['mchid'], $nonce, $timestamp, $config['serial_no'], $sign ); $headers = [ 'Accept: application/json', 'User-Agent: * public function notify() { $xml = file_get_contents('php://input'); //7.0以上 $arr = get_object_vars(json_decode(json_decode(json_encode($xml),true))); $arr = get_object_vars(json_decode(json_decode(json_encode((new AesUtil('708fabe717dfaedcabd7a48932ec71c9'))->decryptToString(get_object_vars($arr['resource'])['associated_data'], get_object_vars($arr['resource'])['nonce'], get_object_vars($arr['resource'])['ciphertext'])),true))); if ($arr['trade_state'] == 'SUCCESS') { //到这里说明已经付款成功了 // 判断是否已完成订单 如何已完成通知微信 if(db('order')->where('order_code', $arr['out_trade_no'])->value('status') == 4){ $mes = array( 'code' => 'SUCCESS', 'message' => '成功' ); return xml($mes); } //修改订单状态 db('order')->where('order_code', $arr['out_trade_no'])->update(['status' => 4]); //查询订单 $order = db('order')->where('order_code', $arr['out_trade_no'])->find(); //充值成功 加余额 $yue = db('person')->where('person_id',$order['person_id'])->value('balance'); if ($order['order_type'] == '2') { $balance = 0; $balance = intval($arr['amount']->total) / 10000; switch ($balance) { case 1: $balance = intval($yue) + 105; break; case 2: $balance = intval($yue) + 210; break; case 3: $balance = intval($yue) + 345; break; case 4: $balance = intval($yue) + 480; break; } db('person')->where('person_id',$order['person_id'])->update(['balance'=>$balance]); } else { $order_detail = db('order_detail')->where('order_id', $order['order_id'])->select()->toArray(); foreach ($order_detail as $value) { //增加销量 $xiaoliang = db('goods')->where('goods_id', $value['goods_id'])->find()['xiaoliang']; $xl_data['xiaoliang'] = $xiaoliang + $value['goods_num']; db('goods')->where('goods_id', $value['goods_id'])->update($xl_data); } } // $data['orderremarks'] = $arr; // db('order')->save($arr); //支付成功 支付类型 //告诉微信,已经处理了,否则微信那边会重复发送数据过来 $mes = array( 'code' => 'SUCCESS', 'message' => '成功' ); return xml($mes); } } //post请求 public function curl_post($url, $data, $headers = array()) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //设置header头 curl_setopt($ch, CURLOPT_HttpHEADER, $headers); // POST数据 curl_setopt($ch, CURLOPT_POST, 1); // 把post的变量加上 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $output = curl_exec($ch); curl_close($ch); return $output; } //get请求 public function curl_get($url, $headers = array()) { $info = curl_init(); curl_setopt($info, CURLOPT_RETURNTRANSFER, true); curl_setopt($info, CURLOPT_HEADER, 0); curl_setopt($info, CURLOPT_NOBODY, 0); curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($info, CURLOPT_SSL_VERIFYHOST, false); //设置header头 curl_setopt($info, CURLOPT_HTTPHEADER, $headers); curl_setopt($info, CURLOPT_URL, $url); $output = curl_exec($info); curl_close($info); return $output; }}
前面获取二维码链接都很容易,就是支付成功之后获取的内容拿不到,很是烦
其实都获取到了,但是取得时候方法不太对,就一直获取不到想要的数据,微信不知道已经成功,就一直回调,正常$arr['amount']['total']就可以获取到数据,但是微信返回的数据要$arr['amount']->total这样才可以获取到,真的是很坑诶。
还有一个就是查询订单的时候,因为是get方式获取,报文主体为空,但是构造签名的时候又不能少,要用“/n”去结尾,之前因为没有加,所以签名一直错误
希望大家以及自己在开发过程中少走一些弯路。
来源地址:https://blog.csdn.net/Edith_C/article/details/129421753
--结束END--
本文标题: PHP实现微信支付流程(Native支付)
本文链接: https://www.lsjlt.com/news/386790.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0