博客列表 >php+微信支付V3

php+微信支付V3

毅铭
毅铭原创
2022年08月07日 23:06:121236浏览

<?php

 

namespace app\index\controller;

use think\Controller;

use think\Request;

 

/**

 * 微信支付V3

 * Class Pay

 * @package app\index\controller

 */

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."\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: */*',

            '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);

//    }

}



声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议