微信 app支付 php篇

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/12 0012
 * Time: 17:17
 */
namespace WeixinPay;

use Curl\Curl;
use think\Config;
use think\Log;

class WeixinPay
{
    /**
     * 统一下单
     * @param $pay_host 微信支付接口地址
     * @param array $data 请求参数
     * array(
        'body'=>'',//商品描述
        'out_trade_no'=>'',//商户订单号
        'total_fee'=>'',//总金额
        'product_id'=>'',//商品ID
      )
     * @param $pay_key pay_key为商户平台设置的密钥key
     * @return array|mixed
     */
    public function unifiedorder(array $params)
    {
        $timestamp = time();
        $spbill_create_ip = Config::get('wx_spbill_create_ip');
        if($spbill_create_ip == null || $spbill_create_ip == ""){
            $spbill_create_ip = $_SERVER["SERVER_ADDR"];
        }
        Log::write(array('ip'=>$spbill_create_ip));
        $data = [
            'appid'=>Config::get('wx_appid'),
            'mch_id'=>Config::get('wx_mch_id'),
            'nonce_str'=>$this->createNoncestr(),
            'body'=>$params["body"],
            'out_trade_no'=>$params["out_trade_no"],
            'total_fee'=>$params["total_fee"],//分
            'spbill_create_ip'=>$spbill_create_ip,
            'notify_url'=>Config::get('wx_notify_url'),
            'trade_type'=>Config::get('wx_trade_type'),
        ];
        ksort($data);
        $stringA = "";
        foreach ($data as $key=>$value)
        {
            $stringA .= $key."=".$value;
            $stringA .= "&";
        }
        $stringA = substr($stringA,0,strlen($stringA)-1);

        $stringSignTemp = $stringA."&key=".Config::get('wx_key');
        $sign = strtoupper(MD5($stringSignTemp));
//        $sign = strtoupper(hash_hmac('sha256',$stringSignTemp,Config::get('o2o.weixin_mch_key')));

        $xml = "<xml>";
        foreach ($data as $key=>$value)
        {
            $xml .= "<".$key.">".$value."</".$key.">";
        }
        $xml .= "<sign>".$sign."</sign>";
        $xml .= "</xml>";


        $http = new Curl();
        //https://api.mch.weixin.qq.com/pay/unifiedorder
        $body = $http->post('https://api.mch.weixin.qq.com/pay/unifiedorder',array($xml),true);
        $body = $this->xmlstring2array($body);

        if($body['return_code'] == 'FAIL'){
            return array('result_code'=>'FAIL','return_msg'=>$body['return_msg']);
        }
        if($body['return_code'] == "SUCCESS"){
            if($body['result_code'] == 'SUCCESS'){
                if(Config::get('wx_trade_type') == 'NATIVE'){
                    return array('prepay_id'=>$body['prepay_id'],'result_code'=>$body['result_code'],'code_url'=>$body['code_url']);
                }else{
//                    $_sign = $this->weixinSign($body['prepay_id']);
                    $data = array(
                        'appid' => Config::get('wx_appid'),
                        'noncestr' => $this->createNoncestr(),
                        'package' => 'Sign=WXPay',
                        'partnerid' => Config::get('wx_mch_id'),
                        'prepayid' => $body['prepay_id'],
                        'timestamp' => $timestamp,
                        'key' => Config::get('wx_key'),
                    );
                    $sign = '';
                    foreach ($data as $key=>$value)
                    {
                        $sign .=  $key."=".$value."&";
                    }
                    $sign = substr($sign, 0, -1);
                    $data['sign'] =  strtoupper(md5($sign));
                    return $data;
                }
            }
            return array('err_code'=>$body['err_code'],'err_code_des'=>$body['err_code_des'],'result_code'=>$body['result_code']);
        }
        return array('result_code'=>'FAIL','return_msg'=>'微信支付接口获取数据失败');
    }

    //xml字符串转数组
    private function xmlstring2array($string)
    {
        $xml = simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);
        $array = json_decode(json_encode($xml), TRUE);
        return $array;
    }

    /**
     * 订单查询
     * @param $pay_host 微信支付接口地址
     * @param array $data 接口参数
       array(
        'out_trade_no'=>'',//商户订单号
       )

     * @param $pay_key pay_key为商户平台设置的密钥key
     * @return array|mixed
     */
    public function orderquery(array $data)
    {
        $data['appid'] = Config::get('wx_appid');
        $data['mch_id'] = Config::get('wx_mch_id');
        $data['nonce_str'] = $this->createNoncestr();
        ksort($data);
        $stringA = "";
        foreach ($data as $key=>$value)
        {
            $stringA .= $key."=".$value;
            $stringA .= "&";
        }
        $stringA = substr($stringA,0,strlen($stringA)-1);
        $stringSignTemp = $stringA."&key=".Config::get('wx_key');
        $sign = strtoupper(MD5($stringSignTemp));

        $xml = "<xml>";
        foreach ($data as $key=>$value)
        {
            $xml .= "<".$key.">".$value."</".$key.">";
        }
        $xml .= "<sign>".$sign."</sign>";
        $xml .= "</xml>";
        $http = new Curl();
        $body = $http->post(Config::get('wx_pay_orderquery_host'),array($xml),true);
        $body = $this->xmlstring2array($body);

        Log::write("微信订单查询接口(post)-url:".Config::get('wx_pay_orderquery_host')."-data:".json_encode($data,JSON_UNESCAPED_UNICODE).'-result:'.json_encode($body,JSON_UNESCAPED_UNICODE),"notice");

        if($body['return_code'] == 'FAIL'){
            return $body;
        }
        //响应成功
        if($body['return_code'] == "SUCCESS"){
            //订单数据结果
            if($body['result_code'] == 'SUCCESS'){
                //判断支付成功,返回的数据
                if($body['trade_state'] == 'SUCCESS'){
                    return array(
                        'trade_type'=>$body['trade_type'],
                        'trade_state'=>$body['trade_state'],
                        'bank_type'=>$body['bank_type'],
                        'total_fee'=>$body['total_fee'],
                        'cash_fee'=>$body['cash_fee'],
                        'transaction_id'=>$body['transaction_id'],
                        'out_trade_no'=>$body['out_trade_no'],
                        'time_end'=>$body['time_end'],
                        'trade_state_desc'=>$body['trade_state_desc'],
                        'sign'=>$body['sign']
                    );
                }
            }
//            return array('err_code'=>$body['err_code'],'err_code_des'=>$body['err_code_des'],'result_code'=>$body['result_code']);
        }
        return array('result_code'=>'FAIL','return_msg'=>'微信支付接口获取数据失败');
    }

    //创建随机数
    private function createNoncestr( $length = 32 )
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }

//    //微信签名
//    public function weixinSign(array $data){
//        ksort($data);
//        $stringA = "";
//        foreach ($data as $key=>$value)
//        {
//            $stringA .= $key."=".$value;
//            $stringA .= "&";
//        }
//        $stringA = substr($stringA,0,strlen($stringA)-1);
//        $stringSignTemp = $stringA."&key=".Config::get('wx_key');
//        $sign = strtoupper(MD5($stringSignTemp));
//        return $sign;
//    }

    private function weixinSign($prepayid)
    {
        $timestamp = time();
        $data = [
            'appid'=>Config::get('wx_appid'),
            'partnerid'=>Config::get('wx_mch_id'),
            'prepayid'=>$prepayid,
            'package'=>'Sign=WXPay',
            'noncestr'=>$this->createNoncestr(),
            'timestamp'=>$timestamp
        ];
        ksort($data);
        $stringA = "";
        foreach ($data as $key=>$value)
        {
            $stringA .= $key."=".$value;
            $stringA .= "&";
        }
        $stringA = substr($stringA,0,strlen($stringA)-1);

        $stringSignTemp = $stringA."&key=".Config::get('wx_key');
        $sign = strtoupper(MD5($stringSignTemp));
//        $sign = strtoupper(hash_hmac('sha256',$stringSignTemp,Config::get('o2o.weixin_mch_key')));

//        $xml = "<xml>";
//        foreach ($data as $key=>$value)
//        {
//            $xml .= "<".$key.">".$value."</".$key.">";
//        }
//        $xml .= "<sign>".$sign."</sign>";
//        $xml .= "</xml>";

        return $sign;
    }
}

猜你喜欢

转载自blog.csdn.net/u010412629/article/details/86596686