PHP tp5 微信支付

在php中实现微信支付,我们需要准备设置以下东西:

1、appid(微信开放平台上的应用id)

2、mch_id(微信申请成功之后邮件中的商户id)

3、notify_url(支付成功后的回调地址)

4、api_key(在微信商户平台上自己设定的api密钥 32位)

5、apiclient_cert.pem 和 apiclient_key.pem 证书

接下来直接上代码(可复制粘贴,修改以上的参数及可使用):

 "你的微信开放平台上的应用id",    /*微信开放平台上的应用id*/
        'mch_id' => "你的微信申请成功之后邮件中的商户id",   /*微信申请成功之后邮件中的商户id*/
        'api_key' => "你的在微信商户平台上自己设定的api密钥",    /*在微信商户平台上自己设定的api密钥 32位*/
        'notify_url' => '回调地址',
  
    );
 
    //微信支付下单
    public function wxpay($body,$orderid, $out_trade_no, $total_fee, $type){
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $data["appid"]            = $this->config["appid"];
        $data["body"]             = '艺商城-'.$body;
        $data["mch_id"]           = $this->config['mch_id'];
        $data["nonce_str"]        = $this->createNoncestr();
        $data["notify_url"]       = $this->config["notify_url"];
        $data['trade_type']       = 'APP';
        $data["total_fee"]        = "1";//"$total_fee"
        $data["out_trade_no"]     = $out_trade_no;
        $data["spbill_create_ip"] = $this->get_client_ip();
        $sign                     = $this->getSign($data);
        $data["sign"]             = $sign;

        $xml      = $this->arrayToXml($data);
        $response = $this->postXmlCurl($xml, $url);
        $response = $this->xmlToArray($response);
        $response = $this->two_sign($response, $data["nonce_str"]);
        //返回数据
        echo json_encode(['status'=>1,'indo'=>'success','orderid'=>$orderid,'data'=>$response]);
    }

    //微信支付回调地址--商品支付
    public function wxNotifyUrl(){
        $type = 3;
        $this->payCommom($type);
    }

  
    /**
     * [payCommom 充值公共方法]
     * @param  [type] $type []
     * @return [type]       [description]
     */
    public function payCommom($type){
        $xml_data = file_get_contents('php://input');
        $re = $this->wx_verification($xml_data);
        $flow_sn = $re['transaction_id'];//获取流水号
        if($re['code'] == 1){
            $data  = $this->xmlToArray($xml_data);
                // 启动事务
                Db::startTrans();
                try{

                  #你的订单业务逻辑....

                    // 提交事务
                    Db::commit(); 
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                }
            }
        }
        echo "";
    }

    /**
     * 微信支付退款
     * $pay_sn      支付单号
     * $total_fee   订单金额
     * $refund_fee  退款金额
     */
    public function wxrefundOrder($pay_sn, $total_fee, $refund_fee)
    {
        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
 
        $data["appid"]            = $this->config["appid"];
        $data["mch_id"]           = $this->config['mch_id'];
        $data["nonce_str"]        = $this->createNoncestr();
        $data['out_trade_no']     = $pay_sn;
        $data['out_refund_no']    = $pay_sn;
        $data["total_fee"]        = intval($total_fee * 100);
        $data["refund_fee"]       = intval($refund_fee * 100);
        $sign                     = $this->getSign($data);
        $data["sign"]             = $sign;

        $xml      = $this->arrayToXml($data);
        $response = $this->postXmlCurl($xml, $url);
        $response = $this->xmlToArray($response);  
        if ($response['return_code'] == 'SUCCESS' && $response['refund_id']) {
            return ['code'=>1,'refund_id'    => $response['refund_id']];
        }else{
            return ['code'=>0,'err_code_des' => $response['err_code_des']];
        }
    }

    /**
     * [order_record 订单记录]
     * @return [type] [description]
     */
    public function order_record($orderid, $unionid, $title, $price, $user_money){
        $record['orderid'] = $orderid; 
        $record['unionid'] = $unionid; 
        $record['title'] = $title; 
        $record['price'] = $price;
        $record['money'] = $user_money;
        $record['addtime'] = time();
        Db::name('order_record')->insert($record);
    }

    //微信支付二次签名
    public function two_sign( $response = NULL, $nonce_str){
        if( $response != NULL && $response['return_code'] != 'SUCCESS'){
            return [];
        }else{
            //接收微信返回的数据,传给APP!
            $arr =array(
                'appid'     => $this->config["appid"],
                'partnerid' => $this->config['mch_id'],
                'prepayid'  => $response['prepay_id'],
                'package'   => 'Sign=WXPay',
                'noncestr'  => $nonce_str,
                'timestamp' => time(),
            );
            //第二次生成签名
            $sign = $this->getSign($arr);
            $arr['sign'] = $sign;
            return $arr;
        }
    }
    //微信支付签名
    public function getSign($Obj){
        foreach ($Obj as $k => $v){
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        // echo '【string1】:'.$String.'
'; //签名步骤二:在string后加入KEY $String = $String."&key=".$this->config['api_key']; // echo "【string2】".$String."
"; //签名步骤三:MD5加密 $String = md5($String); // echo "【string3】 ".$String."
"; //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); // echo "【result】 ".$result_."
"; return $result_; } /** * 作用:产生随机字符串,不长于32位 */ public 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; } /* 获取当前服务器的IP */ public function get_client_ip(){ if ($_SERVER['REMOTE_ADDR']) { $cip = $_SERVER['REMOTE_ADDR']; } elseif (getenv("REMOTE_ADDR")) { $cip = getenv("REMOTE_ADDR"); } elseif (getenv("HTTP_CLIENT_IP")) { $cip = getenv("HTTP_CLIENT_IP"); } else { $cip = "unknown"; } return $cip; } //数组转xml public function arrayToXml($arr){ $xml = ""; foreach ($arr as $key=>$val){ if (is_numeric($val)){ $xml.="<".$key.">".$val.""; }else{ $xml.="<".$key.">"; } } $xml.=""; return $xml; } /** * 作用:将xml转为array */ public function xmlToArray($xml){ //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:以post方式提交xml到对应的接口url */ public function postXmlCurl($xml,$url,$second=30){ //初始化curl $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2); //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); //退款证书 curl_setopt($ch,CURLOPT_SSLCERT,PUBLIC_PATH.'/wx/apiclient_cert.pem'); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); //退款证书 curl_setopt($ch,CURLOPT_SSLKEY,PUBLIC_PATH.'/wx/apiclient_key.pem'); //运行curl $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; }else{ $error = curl_errno($ch); echo "curl出错,错误码:$error"."
"; curl_close($ch); return false; } } /** * 作用:格式化参数,签名过程需要使用 */ public function formatBizQueryParaMap($paraMap, $urlencode){ $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v){ if($urlencode){ $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0){ $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } //微信支付回调验证 public function wx_verification($xml_data){ $data = $this->xmlToArray($xml_data); $sign = $data['sign']; unset($data['sign']); if($sign == $this->getSign($data)){ if ($data['result_code'] == 'SUCCESS') { $arr=['code'=>1]; }else{ $arr=['code'=>0,'msg'=>$data['return_msg']]; } }else{ $arr=['code'=>0,'msg'=>'签名验证失败']; } return $arr; } }

 

你可能感兴趣的:(php)