$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; } }