zoukankan      html  css  js  c++  java
  • php+微信支付V3

    微信支付V3

    <?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2021/9/13
     * Time: 16:26
     */
    
    namespace appindexcontroller;
    
    
    use thinkController;
    use thinkRequest;
    
    /**
     * 微信支付V3
     * Class Pay
     * @package appindexcontroller
     */
    class Pay extends Controller
    {
        protected $payApi = [
            'app' => 'https://api.mch.weixin.qq.com/v3/pay/transactions/app',//APP支付
            'h5'  => 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5',//H5支付
        ];//支付接口列表
        protected $queryApi = 'https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id}';//查询订单接口
        protected $refundApi = 'https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';//退单接口
        protected $refundNotify = '******';//退单回调自定义
    
        public function _initialize()
        {
    
        }
    
        /**
         * 配置
         */
        public function config(){
            return [
                'appid' => '******',
                'mchid' => '******',//商户号
                'serial_no' => '******',//证书序列号
                'description' => '******',//应用名称
                'notify' => '******',//支付回调
            ];
        }
    
        /**
         * 设置支付url
         * @param string $type  支付平台
         * @return mixed
         */
        public function getPayUrl($type = 'app'){
            return $this->payApi[$type];
        }
    
        /**
         * H5支付
         * @param $total  int  支付金额
         * @return mixed
         */
        public function h5Pay($total){
            //请求参数(报文主体)
            $config = $this->config();
            $body = [
                'appid' => $config['appid'],
                'mchid' => $config['mchid'],
                'description' => $config['description'],
                'out_trade_no' => $this->getOrderNo(),
                'notify_url' => $config['notify'],
                'amount' => [
                    'total' => $total,
                    'currency' => 'CNY'
                ],
                'scene_info' => [
                    'payer_client_ip' => Request::instance()->ip(),
                    'h5_info' => [
                        'type' => 'Wap',
                    ],
                ],
            ];
            $headers = $this->sign('POST',$this->getPayUrl('h5'),json_encode($body));
            return $this->curl_post($this->getPayUrl('h5'),json_encode($body),$headers);
        }
    
        /**
         * APP支付
         * @param $total  int  支付金额
         * @return mixed
         */
        public function appPay($total){
            //请求参数(报文主体)
            $config = $this->config();
            $body = [
                'appid' => $config['appid'],
                'mchid' => $config['mchid'],
                'description' => $config['description'],
                'out_trade_no' => $this->getOrderNo(),
                'notify_url' => $config['notify'],
                'amount' => [
                    'total' => $total,
                    'currency' => 'CNY'
                ],
            ];
            $headers = $this->sign('POST',$this->getPayUrl(),json_encode($body));
            return $this->curl_post($this->getPayUrl(),json_encode($body),$headers);
        }
    
        /**
         * 预下单
         */
        public function preOrder(){
            $res = $this->h5Pay(1);
            print_r($res);die;
        }
    
        /**
         * 支付回调
         */
        public function notify(){
    
        }
    
        /**
         * 退款
         * @param string $transaction_id  平台订单号
         * @return mixed
         */
        public function refund($transaction_id = ''){
            $body = [
                'transaction_id' => $transaction_id,//平台订单号
                'out_refund_no' => $this->getOrderNo(),//系统退款单号
                'reason' => '退款',//退款原因
                'notify_url' => '',//退款回调
                'amount' => [
                    'refund' => 1,//退款金额
                    'total' => 1,//原订单金额
                    'currency' => 'CNY',
                ],
            ];
            $headers = $this->sign('POST',$this->refundApi,json_encode($body));
            return $this->curl_post($this->refundApi,json_encode($body),$headers);
        }
    
    	/**
         * 退款回调
         */
        public function refundNotify(){
    
        }
        
        /**
         * 签名
         * @param string $http_method    请求方式GET|POST
         * @param string $url            url
         * @param string $body           报文主体
         * @return array
         */
        public function sign($http_method = 'POST',$url = '',$body = ''){
            $mch_private_key = $this->getMchKey();//私钥
            $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."
    ".
                $canonical_url."
    ".
                $timestamp."
    ".
                $nonce."
    ".
                $body."
    ";//报文主体
            //计算签名值
            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: */*',
                'Content-Type: application/json; charset=utf-8',
                'Authorization: '.$token,
            ];
            return $headers;
        }
    
        //私钥
        public function getMchKey(){
            //path->私钥文件存放路径
            return openssl_get_privatekey(file_get_contents('path'));
        }
    
        //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;
        }
    
        /**
         * 获得随机字符串
         * @param $len      integer       需要的长度
         * @param $special  bool      是否需要特殊符号
         * @return string       返回随机字符串
         */
        public function getRandomStr($len, $special=false){
            $chars = array(
                "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
                "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
                "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
                "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
                "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
                "3", "4", "5", "6", "7", "8", "9"
            );
    
            if($special){
                $chars = array_merge($chars, array(
                    "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
                    "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
                    "}", "<", ">", "~", "+", "=", ",", "."
                ));
            }
    
            $charsLen = count($chars) - 1;
            shuffle($chars);                            //打乱数组顺序
            $str = '';
            for($i=0; $i<$len; $i++){
                $str .= $chars[mt_rand(0, $charsLen)];    //随机取出一位
            }
            return $str;
        }
    
        /**
         * 生成订单号
         */
        public function getOrderNo(){
            return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        }
    
        //H5测试支付
    //    public function pay(){
    //        $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5';
    //        $body = [
    //            'appid' => '******',
    //            'mchid' => '******',
    //            'description' => '******',
    //            'out_trade_no' => date('YmdHis').rand(1000,9999),
    //            'notify_url' => "******",
    //            'amount' => [
    //                'total' => 100,
    //                'currency' => 'CNY'
    //            ],
    //            'scene_info' => [
    //                'payer_client_ip' => Request::instance()->ip(),
    //                'h5_info' => [
    //                    'type' => 'Wap',
    //                ],
    //            ],
    //        ];
    //        $headers = $this->sign('POST',$url,json_encode($body));
    //        $res = $this->curl_post($url,$body,$headers);
    //        print_r($res);
    //    }
    }
    

    简单的写了个支付类,没有接通业务,其余的请自行补充

  • 相关阅读:
    进程 触发器
    关于 if条件 光标 循环的综合应用
    3-15记录
    day3.python 学习之列表
    day2: python3.5学习——逻辑判断
    day1: python3.5学习
    OpenGL_曲线函数
    OpenGL_赛平斯基垫片
    【quick-cocos2d-x 游戏开发之一】开发工具sublime text及其强力插件QuickXDev
    Python正则表达式指南
  • 原文地址:https://www.cnblogs.com/ljkltt/p/15269083.html
Copyright © 2011-2022 走看看