<?php

namespace Potting;


class WechatPay

{

private static $mchid='';

private static $appid='';

private static $key='';

//生成微信APP预支付信息

public static function createJsBizPackage($totalFee, $outTradeNo, $orderName, $notifyUrl.$timestamp){

$unified = array(

'appid' => self::$appid,

'attach' => '支付',

'body' => $orderName,

'mch_id' => self::$mchid,

'nonce_str' => self::createNonceStr(),

'notify_url' => $notifyUrl,

'out_trade_no' => $outTradeNo,

'spbill_create_ip' => '127.0.0.1',

'total_fee' => intval($totalFee * 100),

'trade_type' => 'APP',

);

$unified['sign'] = self::getSign($unified);

$responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified));

$unifiedOrder = (array)simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);

if ($unifiedOrder === false) {

die('parse xml error');

}

if ($unifiedOrder['return_code'] != 'SUCCESS') {

die($unifiedOrder['return_msg']);

}

if ($unifiedOrder['result_code'] != 'SUCCESS') {

die($unifiedOrder['err_code']);

}

$arr = array(

"appid" => self::$appid,

'partnerid'=>self::$mchid,

"timestamp" => $timestamp,

"noncestr" => $unifiedOrder['nonce_str'],

"package" => 'Sign=WXPay',

"prepayid"=>$unifiedOrder['prepay_id'],

);

$data['paySign'] = self::getSign($arr);

$data['appId']=self::$appid;

$data['timeStamp']=$timestamp;

$data['nonceStr']=$unifiedOrder['nonce_str'];

$data['prepay_id']=$unifiedOrder['prepay_id'];

$data['trade_type']=$unifiedOrder['trade_type'];

$data['mchid']=self::$mchid;

return $data;

}

//生成微信JSAPI预支付信息

public static function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp){

$unified = array(

'appid' => self::$appid,

'attach' => $orderName,

'body' => $orderName,

'mch_id' => self::$mchid,

'nonce_str' => self::createNonceStr(),

'notify_url' => $notifyUrl,

'openid' => $openid,

'out_trade_no' => $outTradeNo,

'spbill_create_ip' => '127.0.0.1',

'total_fee' => intval($totalFee * 100),

'trade_type' => 'JSAPI',

);

$unified['sign'] = self::getSign($unified, self::$key);

$responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified));

$unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);

if ($unifiedOrder === false) {

die('parse xml error');

}

if ($unifiedOrder->return_code != 'SUCCESS') {

die($unifiedOrder->return_msg);

}

if ($unifiedOrder->result_code != 'SUCCESS') {

die($unifiedOrder->err_code_des);

}

$arr = array(

"appId" => self::$appid,

"timeStamp" => $timestamp,

"nonceStr" => self::createNonceStr(),

"package" => "prepay_id=" . $unifiedOrder->prepay_id,

"signType" => 'MD5',

);

$arr['paySign'] = self::getSign($arr, self::$key);

return $arr;

}


//微信支付回调

public static function actionNotify($postStr){

$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

if ($postObj === false) {

die('parse xml error');

}

if ($postObj->return_code != 'SUCCESS') {

die($postObj->return_msg);

}

if ($postObj->result_code != 'SUCCESS') {

die($postObj->err_code);

}

//验证签名

$arr = (array)$postObj;

unset($arr['sign']);

if (self::getSign($arr,self::$key) != $postObj->sign) {

die("签名错误");

}


//支付处理正确-判断是否已处理过支付状态

//$orders = Order::find()->where(['uid'=>$postObj->openid, 'oid'=>$postObj->out_trade_no, 'status' => 0])->all();

// if(count($orders) > 0){

// //更新订单状态

// foreach ($orders as $order) {

// //更新订单

// $order['status'] = 1;

// $order->update();

// }

// return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';

// } else {

// //订单状态已更新,直接返回

// return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';

// }

}


public static function curlGet($url = '', $options = array()){

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

if (!empty($options)) {

curl_setopt_array($ch, $options);

}

//https请求 不验证证书和host

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$data = curl_exec($ch);

curl_close($ch);

return $data;

}



public static function curlPost($url = '', $postData = '', $options = array()){

if (is_array($postData)) {

$postData = http_build_query($postData);

}

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数

if (!empty($options)) {

curl_setopt_array($ch, $options);

}

//https请求 不验证证书和host

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$data = curl_exec($ch);

curl_close($ch);

return $data;

}


public static function createNonceStr($length = 16){

$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

$str = '';

for ($i = 0; $i<$length; $i++){

$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);

}

return $str;

}


public static function arrayToXml($arr){

$xml = "<xml>";

foreach ($arr as $key => $val){

if (is_numeric($val)) {

$xml .= "<" . $key . ">" . $val . "</" . $key . ">";

} else {

$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";

}

}

$xml .= "</xml>";

return $xml;

}


public static function getSign($params){

ksort($params, SORT_STRING);

$unSignParaString = self::formatQueryParaMap($params, false);

$signStr = strtoupper(md5($unSignParaString . "&key=" . self::$key));

return $signStr;

}


protected static function formatQueryParaMap($paraMap, $urlEncode = false){

$buff = "";

ksort($paraMap);

foreach ($paraMap as $k => $v){

if (null != $v && "null" != $v) {

if ($urlEncode) {

$v = urlencode($v);

}

$buff .= $k . "=" . $v . "&";

}

}

$reqPar = '';

if (strlen($buff)>0) {

$reqPar = substr($buff, 0, strlen($buff) - 1);

}

return $reqPar;

}


}