广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP实现微信支付流程(Native支付)
  • 522
分享到

PHP实现微信支付流程(Native支付)

php微信Poweredby金山文档 2023-08-31 19:08:20 522人浏览 薄情痞子
摘要

最近项目需要做微信支付的功能,想着把流程以及遇到的坑记录下来 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文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作