|
- <?php
-
- namespace addons\nzf;
-
- use addons\unishop\model\Config;
-
- /**
- * Class WxPayService
- * 微信交易接口调用核心
- * @package Base\Tool
- */
- class WeChatPay
- {
- public $unifiedOrderUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//统一下单API
- /************************手机浏览器内web支付**************************************/
- /**
- *
- */
- public function H5Pay($params)
- {
- if (empty($params['notify_url'])) {
- $params['notify_url'] = Config::getByName('notify_url')['value'];
- }
- $data = array(
- 'name' => $params['name'],//名称
- 'order_id' => (string)$params['order_id'] . '_' . rand(1000, 9999),//支付ID
- 'total_fee' => (string)$params['total_fee'] * 100,//总金
- 'notify_url' => $params['notify_url'],//支付回调接口
- 'trade_type' => 'MWEB',//用户的OPENID
- 'scene_info' => [
- 'h5_info' => [
- 'type' => 'Wap',
- 'wap_url' => Config::getByName('name')['value'],
- 'wap_name' => Config::getByName('name')['value']
- ]
- ]
- );
- $getpay = $this->unifiedOrderForWeChat($data);//统一下单API
- if ($getpay['flag'] == false) {
- return $getpay;
- }
- if (empty($getpay['data']['mweb_url'])) {
- return Util::returnArrEr('预支付会话异常!');
- }
- return Util::returnArrSu('', ['pay_url' => $getpay['data']['mweb_url']]);
- }
- /************************微信浏览器内web支付**************************************/
- /**
- * Function Description:去微信下单并获取返回
- * Function Name: unifiedOrderByOrderId
- * @param $params array
- * $order_id string 订单表 订单ID
- * $name string 产品名称
- * $total_fee int 总金额 单位分
- * $openid string 用户opendid
- * @return array
- *
- * @author nzf
- */
- public function webPay($params)
- {
- if (empty($params['notify_url'])) {
- $params['notify_url'] = Config::getByName('notify_url')['value'];;
- }
- $data = array(
- 'name' => $params['name'],//名称
- 'order_id' => (string)$params['order_id'] . '_' . rand(1000, 9999),//支付ID
- 'total_fee' => (string)$params['total_fee'] * 100,//总金
- 'notify_url' => $params['notify_url'],//支付回调接口
- 'openid' => $params['openid']//用户的OPENID
- );
- $getPrepayId = $this->unifiedOrderForWeChat($data);//统一下单API
- if ($getPrepayId['flag'] == false) {
- return $getPrepayId;
- }
- //设置成功返回的结果数
- $return = array(
- 'appId' => Config::getByName('app_id')['value'],//微信�?放平台审核�?�过的应用APPID
- 'package' => 'prepay_id=' . $getPrepayId['data']['prepay_id'],//微信返回的支付交易会话ID
- 'nonceStr' => self::getNonceStr(),//随机字符�?
- 'signType' => 'MD5',
- 'timeStamp' => strval(time()),//当前时间�?
- );
- $return['paySign'] = self::getSign($return);
- return Util::returnArrSu('', array('payData' => $return, 'price' => $params['total_fee']));
- }
-
- /**
- * Function Description:统一下单API
- * Function Name: unifiedOrder
- * @param $params array
- * attach 附加数据,在查询API和支付知中原样返回,该字段主要用于商户携带订单的自定义数
- * line_name 线路名称
- * order_id 订单ID
- * total_fee 总金
- * notify_url 回调地址
- *
- * @return array
- *
- * @author nzf
- */
- public function unifiedOrderForWeChat($params)
- {
- $data = array(
- 'appid' => Config::getByName('app_id')['value'],//微信开放平台审核过的应用APPID
- 'attach' => empty($params['attach']) ? '' : $params['attach'],
- 'body' => $params['name'],//产品名称
- 'mch_id' => Config::getByName('mch_id')['value'],//商户微信支付分配的商户号
- 'nonce_str' => $this->getNonceStr(),//随机字符
- 'notify_url' => $params['notify_url'],//通知地址
- 'out_trade_no' => $params['order_id'],//商户订单ID加上当前时间
- 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],//用户端实际ip
- 'total_fee' => $params['total_fee'],//订单总金额,单位为分
- 'trade_type' => empty($params['trade_type']) ? 'JSAPI' : $params['trade_type'],//交易类型
- );
- if (empty($params['openid']) == false) {//存在openid
- $data['openid'] = $params['openid'];
- }
- if (isset($params['scene_info'])) {
- $data['scene_info'] = json_encode($params['scene_info']);
- }
- $data['sign'] = $this->getSign($data);//交易签名
- $curl = new CurlInterface($data, 2);//函数
- $curl->setBaseUrl($this->unifiedOrderUrl);
- $result = $curl->execute('', 'POST');
- if (empty($result['prepay_id'])) {
- return Util::returnArrEr('预支付交易会话异常!');
- }
- return Util::returnArrSu('', array('prepay_id' => $result['prepay_id'], 'mweb_url' => empty($result['mweb_url']) ? '' : $result['mweb_url']));
- }
- /************************扫描支付**************************************/
-
- /**
- * Function Description:去微信下单并获取返回
- * Function Name: unifiedOrderByOrderId
- * @param $par
- * @return array
- *
- * @author nzf
- */
- public function unifiedOrderByOrderIdForSao($par)
- {
- $notify_url = Config::getByName('notify_url')['value'];
- $data = array(
- 'name' => $par['name'],//线路名称
- 'order_id' => (string)$par['order_id'] . '_' . rand(100, 999),//订单ID
- 'total_fee' => $par['total_fee'] * 100,//总金
- 'notify_url' => $notify_url
- );
- $codUrl = $this->unifiedOrderForSao($data);//统一下单API
- if ($codUrl['flag'] == false) {
- return $codUrl;
- }
- //设置成功返回的结果数�?
- $url = '/fx/?r=weChat/we-chat/q-code&qCode=' . urlencode($codUrl['data']['code_url']) . '&_math=' . rand(100, 999);
- return Util::returnArrSu('', array('codUrl' => $url, 'price' => $par['total_fee']));
- }
-
- /**
- * Function Description:统一下单API
- * Function Name: unifiedOrder
- * @param $params array
- * attach 附加数据,在查询API和支付知中原样返回,该字段主要用于商户携带订单的自定义数
- * line_name 线路名称
- * order_id 订单ID
- * total_fee 总金
- * notify_url 回调地址
- *
- * @return array
- *
- * @author 倪宗�?
- */
- public function unifiedOrderForSao($params)
- {
- $data = array(
- 'appid' => Config::getByName('app_id')['value'],//微信�?放平台审核�?�过的应用APPID
- 'mch_id' => Config::getByName('mch_id')['value'],//商户�? 微信支付分配的商户号
- 'nonce_str' => $this->getNonceStr(),//随机字符�?
- 'body' => $params['name'],//线路名称 �? 上订单ID
- 'out_trade_no' => $params['order_id'],//商户订单ID加上当前时间
- 'total_fee' => $params['total_fee'],//订单总金额,单位为分
- 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],//用户端实际ip
- 'notify_url' => $params['notify_url'],//通知地址
- 'trade_type' => 'NATIVE',//交易类型
- );
- $data['sign'] = $this->getSign($data);//交易签名
- $curl = new CurlInterface($data, 2);//函数�?
- $curl->setBaseUrl($this->unifiedOrderUrl);
- $result = $curl->execute('', 'POST');
- if (empty($result['prepay_id'])) {
- return Util::returnArrEr('预支付交易会话异常!');
- }
- return Util::returnArrSu('', array('prepay_id' => $result['prepay_id'], 'code_url' => $result['code_url']));
- }
-
- /***************************************退款****************************************/
-
- /**
- * Des:微信退款接口
- * Name: cancelOrder
- * @param $params
- * @return array
- * @author 倪宗锋
- */
- public static function cancelOrder($params)
- {
- $arr = array(
- 'appid' => Config::getByName('app_id')['value'],
- 'mch_id' => Config::getByName('mch_id')['value'],
- 'nonce_str' => static::getNonceStr(),
- 'out_trade_no' => (string)$params['order_id'],//订单ID
- 'out_refund_no' => (string)date('YmdHis') . rand(100, 999),//退款ID
- 'total_fee' => (string)$params['total_fee'] * 100,//订单总金额 元
- 'refund_fee' => (string)$params['refund_fee'] * 100,//退款金额 元
- 'op_user_id' => Config::getByName('mch_id')['value']
- );
- $arr['sign'] = static::getSign($arr);
- $curl = new CurlInterface($arr, 2);//函数类
- $certArr = [
- "SSLCERT_PATH"=>ROOT_PATH.Config::getByName('cert_path')['value'],
- "SSLKEY_PATH"=>ROOT_PATH.Config::getByName('key_path')['value']
- ];
- $curl->setCert($certArr);
- $curl->setBaseUrl('https://api.mch.weixin.qq.com/secapi/pay/refund');
- $result = $curl->execute('', 'POST');
- if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
- return Util::returnArrSu();
- }
- $msg = $result['return_msg'];
- if ($msg == 'OK') {
- $msg = $result['err_code_des'];
- }
- return Util::returnArrEr('退款失败!' . $msg);
-
- }
-
- /*************************************通用方法**************************************/
- /**
- * Des:检测是否已经支付
- * Name: checkIsPay
- * @param $orderId
- * @return array
- * @author 倪宗锋
- */
- public static function checkIsPay($orderId)
- {
- $arr = array(
- 'appid' => Config::getByName('app_id')['value'],
- 'mch_id' => Config::getByName('mch_id')['value'],
- 'out_trade_no' => (string)$orderId,//订单ID
- 'nonce_str' => static::getNonceStr(),
- );
- $arr['sign'] = static::getSign($arr);
- $curl = new CurlInterface($arr, 2);//函数类
- $certArr = [
- "SSLCERT_PATH"=>ROOT_PATH.Config::getByName('cert_path')['value'],
- "SSLKEY_PATH"=>ROOT_PATH.Config::getByName('key_path')['value']
- ];
- $curl->setCert($certArr);
- $curl->setBaseUrl('https://api.mch.weixin.qq.com/pay/orderquery');
- $result = $curl->execute('', 'POST');
- if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
- return Util::returnArrSu('', $result);
- }
- $msg = $result['return_msg'];
- if ($msg == 'OK') {
- $msg = $result['err_code_des'];
- }
- return Util::returnArrEr('退款失败!' . $msg);
- }
-
- /**
- * Function Description:获取签名
- * Function Name: getSign
- * @param $params
- * @return string
- *
- * @author nzf
- */
- public static function getSign($params)
- {
- if (isset($params['sign'])) {
- unset($params['sign']);
- }
- //签名步骤按字典序排序参
- ksort($params);
- $string = self::ToUrlParams($params);
- //签名步骤二:在string后加入KEY
- $string = $string . "&key=" . Config::getByName('key')['value'];
- //签名步骤三:MD5加密
- $string = md5($string);
- //签名步骤四:有字符转为大
- $result = strtoupper($string);
- return $result;
-
- }
-
- /**
- * Function Description:格式化参�? 格式化成url参数
- * Function Name: ToUrlParams
- * @param $params
- *
- * @return string
- *
- * @author 倪宗�?
- */
- public static function ToUrlParams($params)
- {
- $buff = "";
- foreach ($params as $k => $v) {
- if ($k != "sign" && $v != "" && !is_array($v)) {
- $buff .= $k . "=" . $v . "&";
- }
- }
- $buff = trim($buff, "&");
- return $buff;
- }
-
- /**
- * Function Description:产生的随机字符串 不长
- * Function Name: getNonceStr
- * @param int $length
- *
- * @return string
- *
- * @author 倪宗�?
- */
- public static function getNonceStr($length = 32)
- {
- $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
- $str = "";
- for ($i = 0; $i < $length; $i++) {
- $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
- }
- return $str;
- }
- }
|