初始化代码

This commit is contained in:
2025-08-11 10:22:05 +08:00
commit ebd8d85201
4206 changed files with 753018 additions and 0 deletions

View File

@@ -0,0 +1,244 @@
<?php
namespace app\api\wxapi;
header('Content-type:text/html; Charset=utf-8');
/*** 请填写以下配置信息 ***/
$appid = 'xxxxx'; //https://open.alipay.com 账户中心->密钥管理->开放平台密钥填写添加了电脑网站支付的应用的APPID
$notifyUrl = 'http://www.xxx.com/alipay/notify.php'; //付款成功后的异步回调地址
$outTradeNo = uniqid(); //你自己的商品订单号,不能重复
$payAmount = 0.01; //付款金额,单位:元
$orderName = '支付测试'; //订单标题
$signType = 'RSA2'; //签名算法类型支持RSA2和RSA推荐使用RSA2
//商户私钥
$rsaPrivateKey='';
/*** 配置结束 ***/
$aliPay = new AlipayService();
$aliPay->setAppid($appid);
$aliPay->setNotifyUrl($notifyUrl);
$aliPay->setRsaPrivateKey($rsaPrivateKey);
$aliPay->setTotalFee($payAmount);
$aliPay->setOutTradeNo($outTradeNo);
$aliPay->setOrderName($orderName);
$orderStr = $aliPay->getOrderStr();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<title>支付宝jsapi支付</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script>
<script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js"></script>
</head>
<body>
<div class="container">
<?php
if(!isInAlipayClient()):
?>
<h3>请使用支付宝扫码打开该网页:</h3>
<img src="http://qr.liantu.com/api.php?text=<?php echo getCurrentUrl()?>" />
<?php
else:
?>
<h3>点击以下按钮唤起支付宝支付</h3>
<a href="javascript:void(0)" class="btn btn-primary btns-lg orderstrPay orderstr">点击调起支付宝支付</a>
<div class="alert alert-success" role="alert" style="margin-top:30px;display: none">
</div>
<?php
endif;
?>
</div>
<script>
function ready(callback) {
// 如果jsbridge已经注入则直接调用
if (window.AlipayJSBridge) {
callback && callback();
} else {
// 如果没有注入则监听注入的事件
document.addEventListener('AlipayJSBridgeReady', callback, false);
}
}
ready(function(){
document.querySelector('.orderstr').addEventListener('click', function() {
AlipayJSBridge.call("tradePay", {
orderStr: "<?php echo $orderStr?>"
}, function(result) {
if(result.resultCode!=9000){
//支付失败
alert(result.resultCode+""+result.memo);
}else{
//支付成功
var info = eval('(' + result.result + ')');
$(".alert-success").html("<strong>支付成功!</strong> 订单号:"+info.alipay_trade_app_pay_response.out_trade_no+" 支付金额:¥"+info.alipay_trade_app_pay_response.total_amount);
$(".alert-success").show();
}
// alert(JSON.stringify(result));
});
});
});
</script>
</body>
</html>
<?php
class AlipayService
{
protected $appId;
protected $notifyUrl;
protected $charset;
//私钥值
protected $rsaPrivateKey;
protected $totalFee;
protected $outTradeNo;
protected $orderName;
public function __construct()
{
$this->charset = 'utf8';
}
public function setAppid($appid)
{
$this->appId = $appid;
}
public function setNotifyUrl($notifyUrl)
{
$this->notifyUrl = $notifyUrl;
}
public function setRsaPrivateKey($saPrivateKey)
{
$this->rsaPrivateKey = $saPrivateKey;
}
public function setTotalFee($payAmount)
{
$this->totalFee = $payAmount;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
}
public function setOrderName($orderName)
{
$this->orderName = $orderName;
}
/**
* 获取orderStr
* @return array
*/
public function getOrderStr()
{
//请求参数
$requestConfigs = array(
'out_trade_no'=>$this->outTradeNo,
'total_amount'=>$this->totalFee, //单位 元
'subject'=>$this->orderName, //订单标题
'product_code'=>'QUICK_MSECURITY_PAY', //销售产品码商家和支付宝签约的产品码为固定值QUICK_MSECURITY_PAY
'timeout_express'=>'2h', //该笔订单允许的最晚付款时间逾期将关闭交易。取值范围1m15d。m-分钟h-小时d-天1c-当天1c-当天的情况下无论交易何时创建都在0点关闭。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
// 'store_id'=>'', //商户门店编号。该参数用于请求参数中以区分各门店,非必传项。
// 'extend_params'=>array(
// 'sys_service_provider_id'=>'' //系统商编号该参数作为系统商返佣数据提取的依据请填写系统商签约协议的PID
// )
);
$commonConfigs = array(
//公共参数
'app_id' => $this->appId,
'method' => 'alipay.trade.app.pay', //接口名称
'format' => 'JSON',
'charset'=>$this->charset,
'sign_type'=>'RSA2',
'timestamp'=>date('Y-m-d H:i:s'),
'version'=>'1.0',
'notify_url' => $this->notifyUrl,
'biz_content'=>json_encode($requestConfigs),
);
$commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']);
$result = $this->buildOrderStr($commonConfigs);
return $result;
}
public function generateSign($params, $signType = "RSA") {
return $this->sign($this->getSignContent($params), $signType);
}
protected function sign($data, $signType = "RSA") {
$priKey=$this->rsaPrivateKey;
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($priKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
($res) or die('您使用的私钥格式错误请检查RSA私钥配置');
if ("RSA2" == $signType) {
openssl_sign($data, $sign, $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持
} else {
openssl_sign($data, $sign, $res);
}
$sign = base64_encode($sign);
return $sign;
}
/**
* 校验$value是否非空
* if not set ,return true;
* if is null , return true;
**/
protected function checkEmpty($value) {
if (!isset($value))
return true;
if ($value === null)
return true;
if (trim($value) === "")
return true;
return false;
}
public function getSignContent($params) {
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = $this->characet($v, $this->charset);
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
/**
* 转换字符集编码
* @param $data
* @param $targetCharset
* @return string
*/
function characet($data, $targetCharset) {
if (!empty($data)) {
$fileType = $this->charset;
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset, $fileType);
//$data = iconv($fileType, $targetCharset.'//IGNORE', $data);
}
}
return $data;
}
public function buildOrderStr($data)
{
return http_build_query($data);
}
}
// 是否支付宝客户端
function isInAlipayClient() {
if( strpos($_SERVER['HTTP_USER_AGENT'], 'AlipayClient') !== false ) {
return true;
}
return false;
}
function getCurrentUrl()
{
$scheme = $_SERVER['HTTPS']=='on' ? 'https://' : 'http://';
$uri = $_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING'];
if($_SERVER['REQUEST_URI']) $uri = $_SERVER['REQUEST_URI'];
$baseUrl = urlencode($scheme.$_SERVER['HTTP_HOST'].$uri);
return $baseUrl;
}

View File

@@ -0,0 +1,344 @@
<?php
namespace app\api\wxapi;
use app\api\wxapi\pay\WxPayConfig;
class AppPayWx {
public $appid = ''; /*微信开放平台上的应用id*/
public $mch_id = ''; /*微信申请成功之后邮件中的商户id*/
public $api_key = ''; /*在微信商户平台上自己设定的api密钥 32位*/
public $notify_url = ''; // 服务器异步通知页面路径(必填)
public $out_trade_no = ''; // 商户订单号(必填,商户网站订单系统中唯一订单号)
public $body = ''; // 商品描述(必填,不填则为商品名称)
public $total_fee = 0; // 付款金额(必填)
public $time_expire = ''; // 自定义超时(选填支持dhmc)
private $WxPayHelper;
public function __construct(){
$WxPayConfig = new WxPayConfig();
$this->appid=$WxPayConfig->GetAppId();
$this->mch_id=$WxPayConfig->GetMerchantId();
$this->api_key=$WxPayConfig->GetKey();
}
public function Weixinpayandroid($total_fee, $tade_no) {
$this->total_fee = intval ( $total_fee * 100 ); // 订单的金额 1元
$this->out_trade_no = $tade_no; // date('YmdHis') . substr(time(), - 5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));//订单号
$this->body = 'wx_pay_app'; // 支付描述信息
$this->time_expire = date ( 'YmdHis', time () + 86400 ); // 订单支付的过期时间(eg:一天过期)
$app_response = $this->doPay(); // 数据以JSON的形式返回给APP
if (isset ( $app_response ['return_code'] ) && $app_response ['return_code'] == 'FAIL') {
$errorCode = 100;
$errorMsg = $app_response ['return_msg'];
$this->echoResult ( $errorCode, $errorMsg );
} else {
$errorCode = 0;
$errorMsg = 'success';
$responseData = array (
'notify_url' => $this->notify_url,
'app_response' => $app_response
);
$this->echoResult ( $errorCode, $errorMsg, $responseData );
}
}
// 接口输出
function echoResult($errorCode = 0, $errorMsg = 'success', $responseData = array()) {
$arr = array (
'errorCode' => $errorCode,
'errorMsg' => $errorMsg,
'responseData' => $responseData
);
exit ( json_encode ( $arr ) ); // exit可以正常发送给APP json数据
// return json_encode($arr); //在TP5中return这个json数据APP接收到的是null,无法正常吊起微信支付
}
function getVerifySign($data, $key) {
$String = $this->formatParameters ( $data, false );
// 签名步骤二在string后加入KEY
$String = $String . "&key=" . $key;
// 签名步骤三MD5加密
$String = md5 ( $String );
// 签名步骤四:所有字符转为大写
$result = strtoupper ( $String );
return $result;
}
function formatParameters($paraMap, $urlencode) {
$buff = "";
ksort ( $paraMap );
foreach ( $paraMap as $k => $v ) {
if ($k == "sign") {
continue;
}
if ($urlencode) {
$v = urlencode ( $v );
}
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen ( $buff ) > 0) {
$reqPar = substr ( $buff, 0, strlen ( $buff ) - 1 );
}
return $reqPar;
}
/**
* 得到签名
*
* @param object $obj
* @param string $api_key
* @return string
*/
function getSign($obj, $api_key) {
foreach ( $obj as $k => $v ) {
$Parameters [strtolower ( $k )] = $v;
}
// 签名步骤一:按字典序排序参数
ksort ( $Parameters );
$String = $this->formatBizQueryParaMap ( $Parameters, false );
// 签名步骤二在string后加入KEY
$String = $String . "&key=" . $api_key;
// 签名步骤三MD5加密
$result = strtoupper ( md5 ( $String ) );
return $result;
}
/**
* 获取指定长度的随机字符串
*
* @param int $length
* @return Ambigous <NULL, string>
*/
function getRandChar($length) {
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen ( $strPol ) - 1;
for($i = 0; $i < $length; $i ++) {
$str .= $strPol [rand ( 0, $max )]; // rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
return $str;
}
/**
* 数组转xml
*
* @param array $arr
* @return string
*/
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;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml
* 需要post的xml数据
* @param string $url
* url
* @param bool $useCert
* 是否需要证书,默认不需要
* @param int $second
* url执行超时时间默认30s
* @throws WxPayException
*/
function postXmlCurl($xml, $url, $second = 30, $useCert = false, $sslcert_path = '', $sslkey_path = '') {
$ch = curl_init ();
// 设置超时
curl_setopt ( $ch, CURLOPT_TIMEOUT, $second );
curl_setopt ( $ch, CURLOPT_URL, $url );
// 设置header
curl_setopt ( $ch, CURLOPT_HEADER, FALSE );
// 要求结果为字符串且输出到屏幕上
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
if ($useCert == true) {
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, TRUE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); // 严格校验
// 设置证书
// 使用证书cert 与 key 分别属于两个.pem文件
curl_setopt ( $ch, CURLOPT_SSLCERTTYPE, 'PEM' );
curl_setopt ( $ch, CURLOPT_SSLCERT, $sslcert_path );
curl_setopt ( $ch, CURLOPT_SSLKEYTYPE, 'PEM' );
curl_setopt ( $ch, CURLOPT_SSLKEY, $sslkey_path );
}
// post提交方式
curl_setopt ( $ch, CURLOPT_POST, TRUE );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml );
// 运行curl
$data = curl_exec ( $ch );
// 返回结果
if ($data) {
curl_close ( $ch );
return $data;
} else {
$error = curl_errno ( $ch );
curl_close ( $ch );
return false;
}
}
/**
* 获取当前服务器的IP
*
* @return Ambigous <string, unknown>
*/
function get_client_ip() {
if (isset ( $_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 = "127.0.0.1";
}
return $cip;
}
/**
* 将数组转成uri字符串
*
* @param array $paraMap
* @param bool $urlencode
* @return string
*/
function formatBizQueryParaMap($paraMap, $urlencode) {
$buff = "";
ksort ( $paraMap );
foreach ( $paraMap as $k => $v ) {
if ($urlencode) {
$v = urlencode ( $v );
}
$buff .= strtolower ( $k ) . "=" . $v . "&";
}
$reqPar;
if (strlen ( $buff ) > 0) {
$reqPar = substr ( $buff, 0, strlen ( $buff ) - 1 );
}
return $reqPar;
}
/**
* XML转数组
*
* @param unknown $xml
* @return mixed
*/
function xmlToArray($xml) {
// 将XML转为array
$array_data = json_decode ( json_encode ( simplexml_load_string ( $xml, 'SimpleXMLElement', LIBXML_NOCDATA ) ), true );
return $array_data;
}
public function chkParam() {
// 用户网站订单号
if (empty ( $this->out_trade_no )) {
die ( 'out_trade_no error' );
}
// 商品描述
if (empty ( $this->body )) {
die ( 'body error' );
}
if (empty ( $this->time_expire )) {
die ( 'time_expire error' );
}
// 检测支付金额
if (empty ( $this->total_fee ) || ! is_numeric ( $this->total_fee )) {
die ( 'total_fee error' );
}
// 异步通知URL
if (empty ( $this->notify_url )) {
die ( 'notify_url error' );
}
if (! preg_match ( "#^http:\/\/#i", $this->notify_url )) {
$this->notify_url = "http://" . $_SERVER ['HTTP_HOST'] . $this->notify_url;
}
return true;
}
/**
* 生成支付(返回给APP)
*
* @return boolean|mixed
*/
public function doPay() {
// 检测构造参数
$this->chkParam ();
return $this->createAppPara ();
}
/**
* APP统一下单
*/
private function createAppPara() {
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$data ["appid"] = $this->appid; // 微信开放平台审核通过的应用APPID
$data ["body"] = $this->body; // 商品或支付单简要描述
$data ["mch_id"] = $this->mch_id; // 商户号
$data ["nonce_str"] = $this->getRandChar ( 32 ); // 随机字符串
$data ["notify_url"] = $this->notify_url; // 通知地址
$data ["out_trade_no"] = $this->out_trade_no; // 商户订单号
$data ["spbill_create_ip"] = $this->get_client_ip (); // 终端IP
$data ["total_fee"] = $this->total_fee; // 总金额
$data ["time_expire"] = $this->time_expire; // 交易结束时间
$data ["trade_type"] = "APP"; // 交易类型
$data ["sign"] = $this->getSign ( $data, $this->api_key); // 签名
$xml = $this->arrayToXml ( $data );
$response = $this->postXmlCurl ( $xml, $url );
// 将微信返回的结果xml转成数组
$responseArr = $this->xmlToArray ( $response );
if (isset ( $responseArr ["return_code"] ) && $responseArr ["return_code"] == 'SUCCESS') {
return $this->getOrder ( $responseArr ['prepay_id'] );
}
return $responseArr;
}
/**
* 执行第二次签名,才能返回给客户端使用
*
* @param int $prepayId:预支付交易会话标识
* @return array
*/
public function getOrder($prepayId) {
$data ["appid"] = $this->appid;
$data ["noncestr"] = $this->getRandChar ( 32 );
$data ["package"] = "Sign=WXPay";
$data ["partnerid"] = $this->mch_id;
$data ["prepayid"] = $prepayId;
$data ["timestamp"] = time ();
$data ["sign"] = $this->getSign ( $data, $this->api_key);
$data ["packagestr"] = "Sign=WXPay";
return $data;
}
/**
* 异步通知信息验证
*
* @return boolean|mixed
*/
public function verifyNotify() {
$xml = isset ( $GLOBALS ['HTTP_RAW_POST_DATA'] ) ? $GLOBALS ['HTTP_RAW_POST_DATA'] : '';
if (! $xml) {
return false;
}
$wx_back = $this->xmlToArray ( $xml );
if (empty ( $wx_back )) {
return false;
}
$checkSign = $this->getVerifySign ( $wx_back, $this->api_key);
if ($checkSign = $wx_back ['sign']) {
return $wx_back;
} else {
return false;
}
}
}
?>

View File

@@ -0,0 +1,44 @@
<?php
namespace app\api\wxapi;
class Base{
protected $OtherData=[];
public static function className()
{
return get_called_class();
}
public function __construct()
{
$this->init();
}
public function init()
{
}
public function __get($name){
$getter='get'.$name;
if(method_exists($this, $getter)){
return $this->$getter();
}else if(property_exists($this,$name)){
return $this->$name;
}else if(isset($this->OtherData[$name])){
return $this->OtherData[$name];
}
return '';
}
public function __set($name, $value){
$setter='set'.$name;
if(method_exists($this, $setter)){
$this->$setter($value);
}/* else if(property_exists($this,$name)){
$this->$name=$value;
} */else{
$this->OtherData[$name]=$value;
}
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace app\api\wxapi;
/* $codeImg = new codeImg();
$source = "./uploads/share.png"; //背景图
$codeurl = "./uploads/pic.png"; //合成图
$n_pic='./uploads/1.png';
$generateImg = $codeImg->generateImg($n_pic,$source, $codeurl, 80, 95, 590, 850); */
class CodeImg {
public function generateImgPng($filename='',$source, $codeurl, $pic_position_x=0, $pic_position_y=0, $pic_w=0, $pic_h=0)
{
$main = imagecreatefrompng($source); //imagecreatefromjpeg
$source_w=imagesx($main);
$source_h=imagesy($main);
$target = imagecreatetruecolor($source_w, $source_h);
$white = imagecolorallocate($target, 255, 255, 255);
imagefill($target, 0, 0, $white);
imagecopyresampled($target, $main, 0, 0, 0, 0, $source_w, $source_h, $source_w, $source_h);
$codepic = imagecreatefrompng($codeurl);
$codepic_w=imagesx($codepic);
$codepic_h=imagesy($codepic);
$pic_w=$pic_w?$pic_w:$codepic_w;
$pic_h=$pic_h?$pic_h:$codepic_h;
$position_x=$source_w/2-$codepic_w/2;
$position_y=$source_h-$codepic_h-$source_h*0.2;
$pic_position_x=$pic_position_x?$pic_position_x:$position_x;
$pic_position_y=$pic_position_y?$pic_position_y:$position_y;
imagecopyresampled($target, $codepic, $pic_position_x, $pic_position_y, 0, 0, $pic_w, $pic_h,$codepic_w,$codepic_h);
imagedestroy($codepic);
//$this->createImg();
@mkdir('./' . dirname($filename));
imagepng($target, $filename); //imagejpeg
imagedestroy($main);
imagedestroy($target);
return $filename;
}
public function PngToJpeg($source, $codeurl){
$tmp = imagecreatefrompng($source);
$w = imagesx($tmp);
$y = imagesy($tmp);
$simg = imagecreatetruecolor($w, $y);
$bg =imagecolorallocate($simg, 255, 255, 255);
imagefill($simg, 0, 0, $bg);
imagecopyresized($simg, $tmp, 0, 0, 0, 0,$w, $y, $w, $y);
imagejpeg($tmp, $codeurl);
imagedestroy($tmp);
}
public function generateImgJpg($filename='',$source, $codeurl, $pic_position_x=0, $pic_position_y=0, $pic_w=0, $pic_h=0)
{
$main = imagecreatefromjpeg($source); //imagecreatefromjpeg
$source_w=imagesx($main);
$source_h=imagesy($main);
$target = imagecreatetruecolor($source_w, $source_h);
$white = imagecolorallocate($target, 255, 255, 255);
imagefill($target, 0, 0, $white);
imagecopyresampled($target, $main, 0, 0, 0, 0, $source_w, $source_h, $source_w, $source_h);
$codepic = imagecreatefromjpeg($codeurl);
$codepic_w=imagesx($codepic);
$codepic_h=imagesy($codepic);
$pic_w=$pic_w?$pic_w:$codepic_w;
$pic_h=$pic_h?$pic_h:$codepic_h;
$position_x=$source_w/2-$codepic_w/2;
$position_y=$source_h-$codepic_h-$source_h*0.2;
$pic_position_x=$pic_position_x?$pic_position_x:$position_x;
$pic_position_y=$pic_position_y?$pic_position_y:$position_y;
imagecopyresampled($target, $codepic, $pic_position_x, $pic_position_y, 0, 0, $pic_w, $pic_h,$codepic_w,$codepic_h);
imagedestroy($codepic);
//$this->createImg();
@mkdir('./' . dirname($filename));
imagejpeg($target, $filename); //imagejpeg
imagedestroy($main);
imagedestroy($target);
return $filename;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
<?php
include "request/Object.class.php";
include "WxClient.class.php";
include "request/GetWechatCodeRequest.class.php";
include "request/AccessTokenCodeRequest.class.php";
include "request/UserInfoRequest.class.php";
session_start();
class Wxchatlogin extends Base{
public function getWxUserInfo(){
$WxClient =new WxClient();
$WxClient->appID='wxb5a15da3a637ba28';
$WxClient->appsecret='4253603410d62d7942ffbeab5fc7d05c';
if(!isset($_GET['code'])){
$req = new GetWechatCodeRequest();
$req->setAppId($WxClient->appID);
$req->setScope(GetWechatCodeRequest::SNSAPI_USERINFO);
$url=$req->run();
header('location:'.$url);
return ;
}else{
$req = new AccessTokenCodeRequest();
$req->setAppId($WxClient->appID);
$req->setSecret($WxClient->appsecret);
$req->setCode($_GET['code']);
$resp=$WxClient->execute($req);
}
if(isset($resp->errcode)){
$host=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'];
header('Location:'.$host);
exit;
}
$UserInfoRequest = new UserInfoRequest();
$UserInfoRequest->setOpenid($resp->openid);
$UserInfoRequest->setAccessToken($resp->access_token);
$UserInfo=$WxClient->execute($UserInfoRequest);
$wx_user_info['open_id'] =$_SESSION['open_id']= $UserInfo->openid;
$wx_user_info['headimgurl'] = $UserInfo->headimgurl;
$wx_user_info['sex'] = $UserInfo->sex;
$wx_user_info['nickname'] = $UserInfo->nickname;
//$wx_user_info['parentId'] = isset($_GET['uid'])?$_GET['uid']:0;
$host=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'];
//$_GET['openid']='ocNXe1QOCfC1d6rc7gcIDevCdVYa';
//$wechat=file_get_contents($host.'/index.php/user/getwechat?open_id='.$_GET['openid']);
//$wx_user_info='{"parentId":"10","open_id":"ocNXe1QOCfC1d6rc7gcIDevCdVYa","wechat_name":"\u5434\u6d0b","sex":"1","headimgurl":"http:\/\/wx.qlogo.cn\/mmopen\/Q68wBPJfsuicsKavRpWaluyNRZaGwfHIZtgp3ztK5Mt4pjVwt67p9EGobmwfxvMSR1aF46TFKAPCQOPTibcLGJjQM6cejLicwlz\/"}';
/*$wx_user_info['open_id'] =$_SESSION['open_id']='ocNXe1QOCfC1d6rc7gcIDevCdVYae';
$wx_user_info['headimgurl'] = 'http://www.baidu.com';
$wx_user_info['sex'] = '1';
$wx_user_info['nickname'] = 'eeeee';
$wx_user_info['parentId'] = 37;*/
$wechat=$this->post_curl($host.'/index.php/user/wechat',$wx_user_info);
$wechat=json_decode($wechat,true);
return $wechat;
}
public function post_curl($url, $postFields = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//https 请求
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
if (is_array($postFields) && 0 < count($postFields))
{
$postBodyString = "";
$postMultipart = false;
foreach ($postFields as $k => $v)
{
if("@" != substr($v, 0, 1))//判断是不是文件上传
{
$postBodyString .= "$k=" . urlencode($v) . "&";
}
else//文件上传用multipart/form-data否则用www-form-urlencoded
{
$postMultipart = true;
}
}
unset($k, $v);
curl_setopt($ch, CURLOPT_POST, true);
if ($postMultipart)
{
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
}
else
{
curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString,0,-1));
}
}else{
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
}
$reponse = curl_exec($ch);
if (curl_errno($ch))
{
throw new \Exception(curl_error($ch),0);
}
else
{
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode)
{
throw new \Exception($reponse,$httpStatusCode);
}
}
curl_close($ch);
return $reponse;
}
public function get_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //以文件流的形式返回,不要直接输出
//curl_setopt($ch, CURLOPT_FAILONERROR, false);
if ($this->readTimeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
}
if ($this->connectTimeout) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
}
//https 请求
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$reponse = curl_exec($ch);
if (curl_errno($ch))
{
throw new \Exception(curl_error($ch),0);
}
else
{
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode)
{
throw new \Exception($reponse,$httpStatusCode);
}
}
curl_close($ch);
return $reponse;
}
}
$url=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'];
$Wxchatlogin = new Wxchatlogin();
$act = isset($_GET['act'])?$_GET['act']:'default';
//$_SESSION['code']=10010;
//echo $_SESSION['code'];
if($act=='default'){
// $_SESSION['user']=65442;
//header('location:'.$url);
$wechat=$Wxchatlogin->getWxUserInfo();
if($wechat['phone']){
$user=file_get_contents($url.'/index.php/user/getusername?phone='.$wechat['phone']);
if($user){
$_SESSION['user']=$wechat['phone'];
header('location:'.$url);
return ;
}
}
if($wechat['parentId']){
$_GET['uid']=$wechat['parentId'];
}
}else{
$user_info=file_get_contents($url.'/index.php/user/getuid?uid='.$_GET['uid']);
if($user_info=='0'){
$arr['code']='111';
$arr['mess']='推荐人不存在';
echo json_encode($arr);
return ;
}
$wx_user_info['open_id'] =$_SESSION['open_id'];
$wx_user_info['parentId'] = $_GET['uid'];
$Wxchatlogin->post_curl($url.'/index.php/user/wechat',$wx_user_info);
$code=$_GET['QRcode'];
if($_SESSION['code']==$code){
//if(1){
$_SESSION['user']=$_GET['phone'];
$wechat=$Wxchatlogin->get_curl($url.'/index.php/user/re/?username='.$_SESSION['user'].'&open_id='.$_SESSION['open_id']);
//$wechat=json_decode($wechat,true);
echo $wechat;
exit;
//$user1=file_get_contents('http://yule.360sikao.cn/index.php/user/re/?username='.$_SESSION['user']);
}else{
$arr['code']='110';
echo json_encode($arr);
return ;
}
}
$_GET['uid']=$_GET['uid']?$_GET['uid']:'123456';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title></title>
<script src="../js/initparam.js" type="text/javascript"></script>
</head>
<body ng-app="myApp" class="light-bg" style="background:#fff">
<div class="login_content" style="padding-bottom: 30px;">
<!-- <div class="close_login_btn" ng-click="closeUserLogin('false')"></div> -->
<div class="login_logo">
<h3>请绑定您的手机号</h3>
</div>
<div class="login_body">
<div class="login_phone_input" style="display:<?php if($wechat['parentId']){echo 'none';}else{echo 'block';}?>;">
<input type="text" id="meUid" value="<?php echo isset($_GET['uid'])?$_GET['uid']:'123456';?>" style="float: left;clear: right;font-size: 2.5rem;border: none;padding: 0;margin: 0;" onfocus="if(placeholder=='请输入推荐人ID') {placeholder=''}" onblur="if (value==''&amp;&amp;placeholder=='') {placeholder='请输入推荐人ID'}" placeholder="请输入推荐人ID" required="" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
<div class="login_phone_input">
<input type="number" id="mePhoneNum" ng-model="input.phone" style="display: block;float: left;clear: right;font-size: 2.5rem;border: none;padding: 0;margin: 0;" onfocus="if(placeholder=='请输入您的手机号') {placeholder=''}" onblur="if (value==''&amp;&amp;placeholder=='') {placeholder='请输入您的手机号'}" placeholder="请输入您的手机号" required="" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
<div class="changgePhoneNum_header_second login_phone_input">
<div id="inputbox">
<input type="number" id="yzhm" ng-model="input.QRcode" style="display: block;float: left;clear: right;font-size: 2.5rem;border: none;padding: 0;margin: 0;" onfocus="if(placeholder=='请输入验证码') {placeholder=''}" onblur="if (value==''&amp;&amp;placeholder=='') {placeholder='请输入验证码'}" placeholder="请输入验证码" required="" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
<div ng-class="{true: 'changgePhoneNum_identify', false: 'changgePhoneNum_identify_gray'}[isActive]" id="yzm" ng-click="sendVerfiCode('userLogin')" class="ng-binding changgePhoneNum_identify">获取验证码</div>
</div>
<div class="lang" style="padding:0">
<div class="lang_btn lang_btn_bg_color_red lang_btn_color_white" id="userlogin" >
登录
</div>
</div>
</div>
</div>
</body>
<script src="../js/jquery.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$("#userlogin").click(function(){
var phone = document.getElementById("mePhoneNum").value;
var QRcode = document.getElementById("yzhm").value;
var meUid = document.getElementById("meUid").value;
if (meUid == "") {
alert("请输入推荐人ID");
return
}
if (phone == "") {
alert("请填写手机号码");
return
}
if (phone.length != 11) {
alert("手机号码必须为11位");
return
}
if (QRcode == "") {
alert("请输入验证码");
return
}
$.get('/wxapi/Wechatlogin.php?act=LoginReg&phone='+phone+"&uid="+meUid+"&QRcode="+QRcode,function(res){
//alert(res);
var ress=$.parseJSON(res);
if(ress.code=="110"){
alert("验证码不正确");
}else if(ress.code=="111"){
alert(ress.mess);
}else{
localStorage.setItem("phone",phone);
localStorage.setItem("sessionObj",'{"uflag":"Z0GG3x4qRW2bK1JhAk7ssg==","sessionId":"/wF9RsnXG1GL6BzaWDvLttbeIPrYmqSebZEH3DjpHsuIULvJ8vM6AcowLeAr5yUOiFC7yfLzOgHKMC3gK+clDg=="}');
window.location.href='<?php echo $url;?>';
}
});
return false;
});
});
</script>
<script src="../js/index.js"></script>
</html>

View File

@@ -0,0 +1,63 @@
<?php
namespace app\api\wxapi;
use app\api\wxapi\Base;
use app\api\wxapi\WxClient;
use app\api\wxapi\request\GetWechatCodeRequest;
use app\api\wxapi\request\AccessTokenCodeRequest;
use app\api\wxapi\request\UserInfoRequest;
use app\api\wxapi\pay\WxPayConfig;
class Wx extends Base{
public function getWxUserInfo(){
$WxPayConfig = new WxPayConfig();
$WxClient =new WxClient();
$WxClient->appID=$WxPayConfig->GetAppId();
$WxClient->appsecret=$WxPayConfig->GetAppSecret();
if(!isset($_GET['code'])){
$req = new GetWechatCodeRequest();
$req->setAppId($WxClient->appID);
$req->setScope(GetWechatCodeRequest::SNSAPI_USERINFO); //SNSAPI_BASE SNSAPI_USERINFO
$url=$req->run();
header('location:'.$url);
return ;
}else{
$req = new AccessTokenCodeRequest();
$req->setAppId($WxClient->appID);
$req->setSecret($WxClient->appsecret);
$req->setCode($_GET['code']);
$resp=$WxClient->execute($req);
if(isset($resp->access_token)){
$UserInfoRequest = new UserInfoRequest();
$UserInfoRequest->setOpenid($resp->openid);
$UserInfoRequest->setAccessToken($resp->access_token);
$UserInfo=$WxClient->execute($UserInfoRequest);
$fileName='/Uploads/headimgurl/'.$UserInfo->openid.'.jpg';
$this->userIconSave($UserInfo->headimgurl, $_SERVER['DOCUMENT_ROOT'].$fileName);
$UserInfo->headimgurl=$fileName;
//error_log(json_encode($UserInfo), 3, 'openid.log');
return $UserInfo;
}
return false;
}
}
public function userIconSave($url,$path){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$file = curl_exec($ch);
curl_close($ch);
$resource = fopen($path ,'a');
fwrite($resource, $file);
fclose($resource);
}
}
?>

View File

@@ -0,0 +1,448 @@
<?php
namespace app\api\wxapi;
/* 发送curl请求
* $WxClient =new WxClient();
* $WxClient->appID='wx8efa24d0434873ae';
* $WxClient->appsecret='123ce1bd44bbdd6ce3339a69f24820e9';
* $WxClient->setTypeCurl(WxClient::TYPE_CURL_POST); //发送post请求时需要设置
* $QrcodeInfo=$WxClient->execute($QrcodeCreatePost);
* */
class WxClient
{
const TYPE_CURL_GET='GET';
const TYPE_CURL_POST='POST';
const TYPE_CURL_JSON='JSON';
public $serverUrl = "https://api.weixin.qq.com/";
public $accessToken;
public $connectTimeout = 0;
public $readTimeout = 0;
public $appID='';
public $appsecret='';
public $typeCurl; //get or post
public $IsReturn=false;
public function execute($request){
switch ($this->typeCurl){
case self::TYPE_CURL_POST;
$resq=$this->post_execute($request);
break;
case self::TYPE_CURL_JSON;
$resq=$this->json_execute($request);
break;
default :
$resq=$this->get_execute($request);
}
return $resq;
}
public function get_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //以文件流的形式返回,不要直接输出
//curl_setopt($ch, CURLOPT_FAILONERROR, false);
if ($this->readTimeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
}
if ($this->connectTimeout) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
}
//https 请求
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$reponse = curl_exec($ch);
if (curl_errno($ch))
{
throw new \Exception(curl_error($ch),0);
}
else
{
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode)
{
throw new \Exception($reponse,$httpStatusCode);
}
}
curl_close($ch);
return $reponse;
}
public function get_execute($request)
{
//获取业务参数
$apiParams = $request->getApiParas();
//系统参数放入GET请求串
$requestUrl = ((property_exists($request,'serverUrl'))?$request->serverUrl:$this->serverUrl) . $request->getApiMethodName() . "?";
foreach ($apiParams as $key => $value)
{
$requestUrl .= "$key=" . $value . "&";
}
$requestUrl=trim($requestUrl,"&");
//发起HTTP请求
try
{
$resp = $this->get_curl($requestUrl);
}
catch (\Exception $e)
{
$result->code = $e->getCode();
$result->msg = $e->getMessage();
return $result;
}
if($this->IsReturn){
return $resp;
}
$respObject = json_decode($resp);
if(isset($respObject->errcode)){
$respObject->errmsg=isset($this->errmsg[$respObject->errcode])?$this->errmsg[$respObject->errcode]:$respObject->errmsg;
}
return $respObject;
}
public function post_curl($url, $postFields = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($this->readTimeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);
}
if ($this->connectTimeout) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
}
//https 请求
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
if (is_array($postFields) && 0 < count($postFields))
{
$postBodyString = "";
$postMultipart = false;
foreach ($postFields as $k => $v)
{
if("@" != substr($v, 0, 1))//判断是不是文件上传
{
$postBodyString .= "$k=" . urlencode($v) . "&";
}
else//文件上传用multipart/form-data否则用www-form-urlencoded
{
$postMultipart = true;
}
}
unset($k, $v);
curl_setopt($ch, CURLOPT_POST, true);
if ($postMultipart)
{
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
}
else
{
curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString,0,-1));
}
}else{
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
}
$reponse = curl_exec($ch);
if (curl_errno($ch))
{
throw new \Exception(curl_error($ch),0);
}
else
{
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode)
{
throw new \Exception($reponse,$httpStatusCode);
}
}
curl_close($ch);
return $reponse;
}
public function post_execute($request)
{
//获取业务参数
$apiParams = $request->getApiParas();
//系统参数放入post请求串
$requestUrl = ((property_exists($request,'serverUrl'))?$request->serverUrl:$this->serverUrl) . $request->getApiMethodName() . "?";
$getParams = $request->getGetParas();
foreach ($getParams as $key => $value)
{
$requestUrl .= "$key=" . $value . "&";
}
$requestUrl=trim($requestUrl,"&");
//发起HTTP请求
try
{
$resp = $this->post_curl($requestUrl,$apiParams);
}
catch (\Exception $e)
{
$result->code = $e->getCode();
$result->msg = $e->getMessage();
return $result;
}
if($this->IsReturn){
return $resp;
}
$respObject = json_decode($resp);
if(isset($respObject->errcode)){
$respObject->errmsg=isset($this->errmsg[$respObject->errcode])?$this->errmsg[$respObject->errcode]:$respObject->errmsg;
}
return $respObject;
}
function post_curl_json($url, $postFields) {
$data_string=json_encode($postFields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8','Content-Length: ' . strlen($data_string)));
if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
ob_start();
curl_exec($ch);
$return_content = ob_get_contents();
ob_end_clean();
$return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
return $return_content;
}
public function json_execute($request)
{
//获取业务参数
$apiParams = $request->getApiParas();
//系统参数放入post请求串
$requestUrl = ((property_exists($request,'serverUrl'))?$request->serverUrl:$this->serverUrl) . $request->getApiMethodName() . "?";
$getParams = $request->getGetParas();
foreach ($getParams as $key => $value)
{
$requestUrl .= "$key=" . $value . "&";
}
$requestUrl=trim($requestUrl,"&");
//发起HTTP请求
try
{
$resp = $this->post_curl_json($requestUrl,$apiParams);
}
catch (\Exception $e)
{
$result->code = $e->getCode();
$result->msg = $e->getMessage();
return $result;
}
if($this->IsReturn){
return $resp;
}
$respObject = json_decode($resp);
if(isset($respObject->errcode)){
$respObject->errmsg=isset($this->errmsg[$respObject->errcode])?$this->errmsg[$respObject->errcode]:$respObject->errmsg;
}
return $respObject;
}
public function setTypeCurl($typeCurl){
$this->typeCurl=$typeCurl;
return $this;
}
public function setIsReturn($IsReturn=false){
$this->IsReturn=$IsReturn;
return $this;
}
public function getTypeCurl(){
return $this->typeCurl;
}
public function xmlToArray($xml)
{
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
public $errmsg=[
'-1'=>'系统繁忙,此时请开发者稍候再试',
'0'=>'请求成功',
'40001'=>'获取access_token时AppSecret错误或者access_token无效。请开发者认真比对AppSecret的正确性或查看是否正在为恰当的公众号调用接口',
'40002'=>'不合法的凭证类型',
'40003'=>'不合法的OpenID请开发者确认OpenID该用户是否已关注公众号或是否是其他公众号的OpenID',
'40004'=>'不合法的媒体文件类型',
'40005'=>'不合法的文件类型',
'40006'=>'不合法的文件大小',
'40007'=>'不合法的媒体文件id',
'40008'=>'不合法的消息类型',
'40009'=>'不合法的图片文件大小',
'40010'=>'不合法的语音文件大小',
'40011'=>'不合法的视频文件大小',
'40012'=>'不合法的缩略图文件大小',
'40013'=>'不合法的AppID请开发者检查AppID的正确性避免异常字符注意大小写',
'40014'=>'不合法的access_token请开发者认真比对access_token的有效性如是否过期或查看是否正在为恰当的公众号调用接口',
'40015'=>'不合法的菜单类型',
'40016'=>'不合法的按钮个数',
'40017'=>'不合法的按钮个数',
'40018'=>'不合法的按钮名字长度',
'40019'=>'不合法的按钮KEY长度',
'40020'=>'不合法的按钮URL长度',
'40021'=>'不合法的菜单版本号',
'40022'=>'不合法的子菜单级数',
'40023'=>'不合法的子菜单按钮个数',
'40024'=>'不合法的子菜单按钮类型',
'40025'=>'不合法的子菜单按钮名字长度',
'40026'=>'不合法的子菜单按钮KEY长度',
'40027'=>'不合法的子菜单按钮URL长度',
'40028'=>'不合法的自定义菜单使用用户',
'40029'=>'不合法的oauth_code',
'40030'=>'不合法的refresh_token',
'40031'=>'不合法的openid列表',
'40032'=>'不合法的openid列表长度',
'40033'=>'不合法的请求字符,不能包含\uxxxx格式的字符',
'40035'=>'不合法的参数',
'40038'=>'不合法的请求格式',
'40039'=>'不合法的URL长度',
'40050'=>'不合法的分组id',
'40051'=>'分组名字不合法',
'40117'=>'分组名字不合法',
'40118'=>'media_id大小不合法',
'40119'=>'button类型错误',
'40120'=>'button类型错误',
'40121'=>'不合法的media_id类型',
'40132'=>'微信号不合法',
'40137'=>'不支持的图片格式',
'40155'=>'请勿添加其他公众号的主页链接',
'41001'=>'缺少access_token参数',
'41002'=>'缺少appid参数',
'41003'=>'缺少refresh_token参数',
'41004'=>'缺少secret参数',
'41005'=>'缺少多媒体文件数据',
'41006'=>'缺少media_id参数',
'41007'=>'缺少子菜单数据',
'41008'=>'缺少oauth code',
'41009'=>'缺少openid',
'42001'=>'access_token超时请检查access_token的有效期请参考基础支持-获取access_token中对access_token的详细机制说明',
'42002'=>'refresh_token超时',
'42003'=>'oauth_code超时',
'42007'=>'用户修改微信密码accesstoken和refreshtoken失效需要重新授权',
'43001'=>'需要GET请求',
'43002'=>'需要POST请求',
'43003'=>'需要HTTPS请求',
'43004'=>'需要接收者关注',
'43005'=>'需要好友关系',
'43019'=>'需要将接收者从黑名单中移除',
'44001'=>'多媒体文件为空',
'44002'=>'POST的数据包为空',
'44003'=>'图文消息内容为空',
'44004'=>'文本消息内容为空',
'45001'=>'多媒体文件大小超过限制',
'45002'=>'消息内容超过限制',
'45003'=>'标题字段超过限制',
'45004'=>'描述字段超过限制',
'45005'=>'链接字段超过限制',
'45006'=>'图片链接字段超过限制',
'45007'=>'语音播放时间超过限制',
'45008'=>'图文消息超过限制',
'45009'=>'接口调用超过限制',
'45010'=>'创建菜单个数超过限制',
'45011'=>'API调用太频繁请稍候再试',
'45015'=>'回复时间超过限制',
'45016'=>'系统分组,不允许修改',
'45017'=>'分组名字过长',
'45018'=>'分组数量超过上限',
'45047'=>'客服接口下行条数超过上限',
'46001'=>'不存在媒体数据',
'46002'=>'不存在的菜单版本',
'46003'=>'不存在的菜单数据',
'46004'=>'不存在的用户',
'47001'=>'解析JSON/XML内容错误',
'48001'=>'api功能未授权请确认公众号已获得该接口可以在公众平台官网-开发者中心页中查看接口权限',
'48002'=>'粉丝拒收消息(粉丝在公众号选项中,关闭了“接收消息”)',
'48004'=>'api接口被封禁请登录mp.weixin.qq.com查看详情',
'48005'=>'api禁止删除被自动回复和自定义菜单引用的素材',
'48006'=>'api禁止清零调用次数因为清零次数达到上限',
'50001'=>'用户未授权该api',
'50002'=>'用户受限,可能是违规后接口被封禁',
'61451'=>'参数错误(invalid parameter)',
'61452'=>'无效客服账号(invalid kf_account)',
'61453'=>'客服帐号已存在(kf_account exsited)',
'61454'=>'客服帐号名长度超过限制(仅允许10个英文字符不包括@及@后的公众号的微信号)(invalid kf_acount length)',
'61455'=>'客服帐号名包含非法字符(仅允许英文+数字)(illegal character in kf_account)',
'61456'=>'客服帐号个数超过限制(10个客服账号)(kf_account count exceeded)',
'61457'=>'无效头像文件类型(invalid file type)',
'61450'=>'系统错误(system error)',
'61500'=>'日期格式错误',
'65301'=>'不存在此menuid对应的个性化菜单',
'65302'=>'没有相应的用户',
'65303'=>'没有默认菜单,不能创建个性化菜单',
'65304'=>'MatchRule信息为空',
'65305'=>'个性化菜单数量受限',
'65306'=>'不支持个性化菜单的帐号',
'65307'=>'个性化菜单信息为空',
'65308'=>'包含没有响应类型的button',
'65309'=>'个性化菜单开关处于关闭状态',
'65310'=>'填写了省份或城市信息,国家信息不能为空',
'65311'=>'填写了城市信息,省份信息不能为空',
'65312'=>'不合法的国家信息',
'65313'=>'不合法的省份信息',
'65314'=>'不合法的城市信息',
'65316'=>'该公众号的菜单设置了过多的域名外跳最多跳转到3个域名的链接',
'65317'=>'不合法的URL',
'9001001'=>'POST数据参数不合法',
'9001002'=>'远端服务不可用',
'9001003'=>'Ticket不合法',
'9001004'=>'获取摇周边用户信息失败',
'9001005'=>'获取商户信息失败',
'9001006'=>'获取OpenID失败',
'9001007'=>'上传文件缺失',
'9001008'=>'上传素材的文件类型不合法',
'9001009'=>'上传素材的文件尺寸不合法',
'9001010'=>'上传失败',
'9001020'=>'帐号不合法',
'9001021'=>'已有设备激活率低于50%,不能新增设备',
'9001022'=>'设备申请数不合法必须为大于0的数字',
'9001023'=>'已存在审核中的设备ID申请',
'9001024'=>'一次查询设备ID数量不能超过50',
'9001025'=>'设备ID不合法',
'9001026'=>'页面ID不合法',
'9001027'=>'页面参数不合法',
'9001028'=>'一次删除页面ID数量不能超过10',
'9001029'=>'页面已应用在设备中,请先解除应用关系再删除',
'9001030'=>'一次查询页面ID数量不能超过50',
'9001031'=>'时间区间不合法',
'9001032'=>'保存设备与页面的绑定关系参数错误',
'9001033'=>'门店ID不合法',
'9001034'=>'设备备注信息过长',
'9001035'=>'设备申请参数不合法',
'9001036'=>'查询起始值begin不合法'
];
}

View File

@@ -0,0 +1,54 @@
<?php
namespace app\api\wxapi;
use app\api\wxapi\pay\WxPayApi;
use app\api\wxapi\pay\JsApiPay;
use app\api\wxapi\pay\WxPayConfig;
use app\api\wxapi\pay\WxPayUnifiedOrder;
use app\api\wxapi\pay\Log;
class WxPay{
//打印输出数组信息
function printf_info($data)
{
foreach($data as $key=>$value){
echo "<font color='#00ff55;'>$key</font> : ".htmlspecialchars($value, ENT_QUOTES)." <br/>";
}
}
function unifiedorder(){
try{
$tools = new JsApiPay();
$openId = $tools->GetOpenid();
//②、统一下单
$input = new WxPayUnifiedOrder();
$input->SetBody("test");
$input->SetAttach("test");
$input->SetOut_trade_no("sdkphp".date("YmdHis"));
$input->SetTotal_fee("1");
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("test");
$input->SetNotify_url('http://'.$_SERVER['HTTP_HOST']."/index.php/Api/wxjsapi/notify");
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openId);
$config = new WxPayConfig();
$order = WxPayApi::unifiedOrder($config, $input);
//echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';
$this->printf_info($order);
$PayConf['jsApiParameters'] = $tools->GetJsApiParameters($order);
//获取共享收货地址js函数参数
$PayConf['editAddress'] = $tools->GetEditAddressParameters();
return $PayConf;
} catch(Exception $e) {
Log::ERROR(json_encode($e));
}
return false;
}
}
?>

View File

@@ -0,0 +1,49 @@
<?php
namespace app\api\wxapi;
use app\api\wxapi\Base;
use app\api\wxapi\WxClient;
use app\api\wxapi\pay\WxPayConfig;
use app\api\wxapi\request\AccessTokenRequest;
use app\api\wxapi\post\QrcodeCreatePost;
class Wxqr extends Base{
public function getQr($fileName='', $val=''){
if(file_exists(trim($fileName,'/'))){
return $fileName;
}
$WxPayConfig = new WxPayConfig();
$WxClient =new WxClient();
$WxClient->appID=$WxPayConfig->GetAppId();
$WxClient->appsecret=$WxPayConfig->GetAppSecret();
$AccessTokenRequest=new AccessTokenRequest();
$AccessTokenRequest->setAppId($WxClient->appID);
$AccessTokenRequest->setSecret($WxClient->appsecret);
$AccessTokenRequest=$WxClient->execute($AccessTokenRequest);
$QrcodeCreatePost=new QrcodeCreatePost();
$QrcodeCreatePost->setAccessToken($AccessTokenRequest->access_token);
$QrcodeCreatePost->setActionName(QrcodeCreatePost::ACTION_NAME_QR_LIMIT_STR_SCENE);
//$QrcodeCreatePost->setExpireSeconds(60*60); //临时时间戳
$QrcodeCreatePost->setSceneVal($val);
$QrcodeCreatePost->run();
$WxClient->setTypeCurl(WxClient::TYPE_CURL_POST);
$QrcodeInfo=$WxClient->execute($QrcodeCreatePost);
if($QrcodeInfo->url){
$url='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.$QrcodeInfo->ticket;
$current = file_get_contents($url);
file_put_contents($fileName, $current);
return $fileName;
}
return '';
}
}
?>

View File

@@ -0,0 +1,215 @@
<?php
namespace app\api\wxapi;
use app\api\wxapi\WxClient;
use app\api\wxapi\pay\WxPayConfig;
use app\api\wxapi\request\AccessTokenRequest;
use app\api\wxapi\request\TemplateSendRequest;
use think\Db;
class Wxtemp extends Base{
public $WxClient='';
public $error='';
public function getAccessToken(){
$access_token_config=DB::name('config')->where(['name'=>'access_token',])->find();
$access_token=$access_token_config['value'];
/* $appID=DB::name('config')->where('name', 'wx_appid')->value('value');
if(!strlen($appID)){
$this->error='appid不能为空';
return false;
}
$appsecret=DB::name('config')->where('name', 'wx_secret')->value('value');
if(!strlen($appsecret)){
$this->error='appsecret不能为空';
return false;
}
$WxClient =new WxClient();
$WxClient->appID=$appID;
$WxClient->appsecret=$appsecret;*/
$WxPayConfig = new WxPayConfig();
$WxClient =new WxClient();
$WxClient->appID=$WxPayConfig->GetAppId();
$WxClient->appsecret=$WxPayConfig->GetAppSecret();
$this->WxClient=$WxClient;
if(time()>$access_token_config['ctime']){
$AccessTokenRequest=new AccessTokenRequest();
$AccessTokenRequest->setAppId($WxClient->appID);
$AccessTokenRequest->setSecret($WxClient->appsecret);
$WxClient->setTypeCurl(WxClient::TYPE_CURL_GET);
$AccessTokenRequest=$WxClient->execute($AccessTokenRequest);
$access_token=$AccessTokenRequest->access_token;
DB::name('config')->where(['name'=>'access_token',])->update(['value'=>$access_token,'ctime'=>time()+7200,]);
}
if(!strlen($access_token)){
$this->error='access_token不能为空';
return false;
}
return $access_token;
}
public function sendTempMsg($info=[]){
$access_token=$this->getAccessToken();
if(!$access_token){
return false;
}
$WxClient=$this->WxClient;
$tempArray=[
'buy_order'=>'450UXsKV5qdrogsAwjb0zyr8hMwxzCKenx2S4UiXq2w',
];
if(!isset($info['temp_type']) || !$info['temp_type'] || !in_array($info['temp_type'], array_keys($tempArray))){
$this->error='temp_type消息模板配制异常';
return false;
}
$tempid=$tempArray[$info['temp_type']];
//$url=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'];
//$user_info=DB::name('users')->where(['id'=>,])->find();
if(!isset($info['touser']) || !$info['touser']){
$this->error='touser消息接收人不能为空';
return false;
}
if(is_string($info['touser'])){
$touser[]=$info['touser'];
}else{
$touser=$info['touser'];
}
$_TemplateSendRequest=new TemplateSendRequest();
foreach($touser as $u){
$TemplateSendRequest=clone $_TemplateSendRequest;
$TemplateSendRequest->setAccessToken($access_token);
$TemplateSendRequest->setToUser($u);
$TemplateSendRequest->setTemplateId($tempid);
//$TemplateSendRequest->setUrl($url);
$TemplateSendRequest->setTopColor('#FF0000');
switch($info['temp_type']){
case 'buy_order':
$data=$this->buy_order($info);
break;
/* case 'fans_temp':
$data=$this->fans_temp($info);
break;
case 'daili_temp':
$data=$this->daili_temp($info);
break;*/
}
if(empty($data)){
return false;
}
$TemplateSendRequest->setData($data);
$WxClient->setTypeCurl(WxClient::TYPE_CURL_JSON);
$req=$WxClient->execute($TemplateSendRequest);
/* print_r($touser);
print_r($req);
*/ }
return true;
}
public function buy_order($info=[]){
$title=isset($info['title'])?$info['title']:'';
$name=isset($info['name'])?$info['name']:'';
$ordersn=isset($info['ordersn'])?$info['ordersn']:'';
$content=isset($info['content'])?$info['content']:'';
$remark=isset($info['remark'])?$info['remark']:'';
/*您已预订成功请在24小时内完成支付。
产品名称20134-0815
订单编号A39393939331
通知内容:预订时间 2015-08-01 15:34
如有疑问,请拨打咨询热线*/
$data = [
'first' => [
'value' => $title,
'color' => '#173177'
],
'keyword1' => [
'value' => $content,
'color' => '#173177'
],
'keyword2' => [
'value' => $name.'-'.$ordersn,
'color' => '#173177'
],
'remark' => [
'value' => $remark,
'color' => '#173177'
],
];
return $data;
}
public function fans_temp($info=[]){
$nick_name=isset($info['nick_name'])?$info['nick_name']:'';
$title=isset($info['title'])?$info['title']:'';
$remark=isset($info['remark'])?$info['remark']:'';
$order_sn=isset($info['order_sn'])?$info['order_sn']:'';
$price=isset($info['price'])?$info['price']:'';
$pay_type=isset($info['pay_type'])?$info['pay_type']:'';
$data = [
'first' => [
'value' => '粉丝【' . $nick_name . '】成功的完成了一笔消费!',
'color' => '#173177'
],
'keyword1' => [
'value' => $price.'元',
'color' => '#173177'
],
'keyword2' => [
'value' => $pay_type,
'color' => '#173177'
],
'keyword3' => [
'value' => $title,
'color' => '#173177'
],
'keyword4' => [
'value' => $order_sn,
'color' => '#173177'
],
'keyword5' => [
'value' => $remark,
'color' => '#173177'
],
];
return $data;
}
public function daili_temp($info=[]){
$nick_name=isset($info['nick_name'])?$info['nick_name']:'';
$price=isset($info['price'])?$info['price']:'';
$data = [
'first' => [
'value' => '尊敬的会员【' . $nick_name . '】您好,您有一笔收益到帐提醒!',
'color' => '#173177'
],
'keyword1' => [
'value' => '粉丝收益',
'color' => '#173177'
],
'keyword2' => [
'value' => $price.'元',
'color' => '#173177'
],
];
return $data;
}
}
?>

View File

@@ -0,0 +1,57 @@
<?php
namespace app\api\wxapi\media;
use app\api\wxapi\Base;
/*
* */
class GetPicTextList extends Base
{
private $apiParas = array();
private $getParas = array();
public function init(){
$this->setOffset();
$this->setCount();
}
public function getApiMethodName(){
return "cgi-bin/material/batchget_material";
}
public function getApiParas(){
return $this->apiParas;
}
public function getGetParas(){
return $this->getParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->getParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->getParas["access_token"];
}
public function setTypes($type){ //素材的类型图片image、视频video、语音 voice、图文news
$this->apiParas["type"] = $type;
}
public function setOffset($offset=0){
$this->apiParas["offset"] = $offset;
}
public function setCount($count=20){
$this->apiParas["count"] = $count;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace app\api\wxapi\menus;
use app\api\wxapi\Base;
/* 菜单创建接口
* */
class CreateMenus extends Base
{
private $apiParas = array();
private $GetParas = array(); //请求地址参数
public function init(){
}
public function getApiMethodName(){
return "cgi-bin/menu/create";
}
public function getApiParas(){
return json_encode($this->apiParas,JSON_UNESCAPED_UNICODE);
}
public function getGetParas(){
return $this->GetParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
}
public function setAccessToken($access_token){
$this->GetParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->GetParas["access_token"];
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace app\api\wxapi\menus;
use app\api\wxapi\Base;
/* 通过API调用设置的菜单
* */
class ListMenus extends Base
{
private $apiParas = array();
public function init(){
}
public function getApiMethodName(){
return "cgi-bin/get_current_selfmenu_info";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->apiParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->apiParas["access_token"];
}
}

View File

@@ -0,0 +1,233 @@
<?php
namespace app\api\wxapi\pay;
/**
*
* example目录下为简单的支付样例仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk在安全上面仅做了简单处理 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
*
**/
/**
*
* JSAPI支付实现类
* 该类实现了从微信公众平台获取code、通过code获取openid和access_token、
* 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数
*
* 该类是微信支付提供的样例程序商户可根据自己的需求修改或者使用lib中的api自行开发
*
* @author widy
*
*/
class JsApiPay
{
/**
*
* 网页授权接口微信服务器返回的数据,返回样例如下
* {
* "access_token":"ACCESS_TOKEN",
* "expires_in":7200,
* "refresh_token":"REFRESH_TOKEN",
* "openid":"OPENID",
* "scope":"SCOPE",
* "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
* }
* 其中access_token可用于获取共享收货地址
* openid是微信支付jsapi支付接口必须的参数
* @var array
*/
public $data = null;
/**
*
* 通过跳转获取用户的openid跳转流程如下
* 1、设置自己需要调回的url及其其他参数跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
* 2、微信服务处理完成之后会跳转回用户redirect_uri地址此时会带上一些参数code
*
* @return 用户的openid
*/
public function GetOpenid()
{
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
$url = $this->_CreateOauthUrlForCode($baseUrl);
Header("Location: $url");
exit();
} else {
//获取code码以获取openid
$code = $_GET['code'];
$openid = $this->getOpenidFromMp($code);
return $openid;
}
}
/**
*
* 获取jsapi支付的参数
* @param array $UnifiedOrderResult 统一支付接口返回的数据
* @throws WxPayException
*
* @return json数据可直接填入js函数作为参数
*/
public function GetJsApiParameters($UnifiedOrderResult)
{
if(!array_key_exists("appid", $UnifiedOrderResult)
|| !array_key_exists("prepay_id", $UnifiedOrderResult)
|| $UnifiedOrderResult['prepay_id'] == "")
{
throw new WxPayException("参数错误");
}
$jsapi = new WxPayJsApiPay();
$jsapi->SetAppid($UnifiedOrderResult["appid"]);
$timeStamp = time();
$jsapi->SetTimeStamp("$timeStamp");
$jsapi->SetNonceStr(WxPayApi::getNonceStr());
$jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
$config = new WxPayConfig();
$jsapi->SetPaySign($jsapi->MakeSign($config));
$parameters = json_encode($jsapi->GetValues());
return $parameters;
}
/**
*
* 通过code从工作平台获取openid机器access_token
* @param string $code 微信跳转回来带上的code
*
* @return openid
*/
public $curl_timeout=30;
public function GetOpenidFromMp($code)
{
$url = $this->__CreateOauthUrlForOpenid($code);
//初始化curl
$ch = curl_init();
$curlVersion = curl_version();
$config = new WxPayConfig();
$ua = "WXPaySDK/3.0.9 (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "
.$config->GetMerchantId();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$proxyHost = "0.0.0.0";
$proxyPort = 0;
$config->GetProxy($proxyHost, $proxyPort);
if($proxyHost != "0.0.0.0" && $proxyPort != 0){
curl_setopt($ch,CURLOPT_PROXY, $proxyHost);
curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);
}
//运行curl结果以jason形式返回
$res = curl_exec($ch);
curl_close($ch);
//取出openid
$data = json_decode($res,true);
// dump($data);exit;
$this->data = $data;
$openid = $data['openid'];
return $openid;
}
/**
*
* 拼接签名字符串
* @param array $urlObj
*
* @return 返回已经拼接好的字符串
*/
private function ToUrlParams($urlObj)
{
$buff = "";
foreach ($urlObj as $k => $v)
{
if($k != "sign"){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
*
* 获取地址js参数
*
* @return 获取共享收货地址js函数需要的参数json格式可以直接做参数使用
*/
public function GetEditAddressParameters()
{
$config = new WxPayConfig();
$getData = $this->data;
$data = array();
$data["appid"] = $config->GetAppId();
$data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$time = time();
$data["timestamp"] = "$time";
$data["noncestr"] = WxPayApi::getNonceStr();
$data["accesstoken"] = $getData["access_token"];
ksort($data);
$params = $this->ToUrlParams($data);
$addrSign = sha1($params);
$afterData = array(
"addrSign" => $addrSign,
"signType" => "sha1",
"scope" => "jsapi_address",
"appId" => $config->GetAppId(),
"timeStamp" => $data["timestamp"],
"nonceStr" => $data["noncestr"]
);
$parameters = json_encode($afterData);
return $parameters;
}
/**
*
* 构造获取code的url连接
* @param string $redirectUrl 微信服务器回跳的url需要url编码
*
* @return 返回构造好的url
*/
private function _CreateOauthUrlForCode($redirectUrl)
{
$config = new WxPayConfig();
$urlObj["appid"] = $config->GetAppId();
$urlObj["redirect_uri"] = "$redirectUrl";
$urlObj["response_type"] = "code";
$urlObj["scope"] = "snsapi_base";
$urlObj["state"] = "STATE"."#wechat_redirect";
$bizString = $this->ToUrlParams($urlObj);
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
}
/**
*
* 构造获取open和access_toke的url地址
* @param string $code微信跳转带回的code
*
* @return 请求的url
*/
private function __CreateOauthUrlForOpenid($code)
{
$config = new WxPayConfig();
$urlObj["appid"] = $config->GetAppId();
$urlObj["secret"] = $config->GetAppSecret();
$urlObj["code"] = $code;
$urlObj["grant_type"] = "authorization_code";
$bizString = $this->ToUrlParams($urlObj);
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
}
}

View File

@@ -0,0 +1,614 @@
<?php
namespace app\api\wxapi\pay;
/**
*
* 接口访问类包含所有微信支付API列表的封装类中方法为static方法
* 每个接口有默认超时时间除提交被扫支付为10s上报超时时间为1s外其他均为6s
* @author widyhu
*
*/
class WxPayApi
{
/**
* SDK版本号
* @var string
*/
public static $VERSION = "3.0.10";
/**
*
* 统一下单WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayUnifiedOrder $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function unifiedOrder($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//检测必填参数
if(!$inputObj->IsOut_trade_noSet()) {
throw new WxPayException("缺少统一支付接口必填参数out_trade_no");
}else if(!$inputObj->IsBodySet()){
throw new WxPayException("缺少统一支付接口必填参数body");
}else if(!$inputObj->IsTotal_feeSet()) {
throw new WxPayException("缺少统一支付接口必填参数total_fee");
}else if(!$inputObj->IsTrade_typeSet()) {
throw new WxPayException("缺少统一支付接口必填参数trade_type");
}
//关联参数
if($inputObj->GetTrade_type() == "JSAPI" && !$inputObj->IsOpenidSet()){
throw new WxPayException("统一支付接口中缺少必填参数openidtrade_type为JSAPI时openid为必填参数");
}
if($inputObj->GetTrade_type() == "NATIVE" && !$inputObj->IsProduct_idSet()){
throw new WxPayException("统一支付接口中缺少必填参数product_idtrade_type为JSAPI时product_id为必填参数");
}
//异步通知url未设置则使用配置文件中的url
if(!$inputObj->IsNotify_urlSet() && $config->GetNotifyUrl() != ""){
$inputObj->SetNotify_url($config->GetNotifyUrl());//异步通知url
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
//签名
$inputObj->SetSign($config);
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 查询订单WxPayOrderQuery中out_trade_no、transaction_id至少填一个
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayOrderQuery $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function orderQuery($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/orderquery";
//检测必填参数
if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
throw new WxPayException("订单查询接口中out_trade_no、transaction_id至少填一个");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 关闭订单WxPayCloseOrder中out_trade_no必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayCloseOrder $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function closeOrder($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/closeorder";
//检测必填参数
if(!$inputObj->IsOut_trade_noSet()) {
throw new WxPayException("订单查询接口中out_trade_no必填");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 申请退款WxPayRefund中out_trade_no、transaction_id至少填一个且
* out_refund_no、total_fee、refund_fee、op_user_id为必填参数
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayRefund $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function refund($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//检测必填参数
if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
throw new WxPayException("退款申请接口中out_trade_no、transaction_id至少填一个");
}else if(!$inputObj->IsOut_refund_noSet()){
throw new WxPayException("退款申请接口中缺少必填参数out_refund_no");
}else if(!$inputObj->IsTotal_feeSet()){
throw new WxPayException("退款申请接口中缺少必填参数total_fee");
}else if(!$inputObj->IsRefund_feeSet()){
throw new WxPayException("退款申请接口中缺少必填参数refund_fee");
}else if(!$inputObj->IsOp_user_idSet()){
throw new WxPayException("退款申请接口中缺少必填参数op_user_id");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, true, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 查询退款
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,
* 用零钱支付的退款20分钟内到账银行卡支付的退款3个工作日后重新查询退款状态。
* WxPayRefundQuery中out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayRefundQuery $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function refundQuery($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/refundquery";
//检测必填参数
if(!$inputObj->IsOut_refund_noSet() &&
!$inputObj->IsOut_trade_noSet() &&
!$inputObj->IsTransaction_idSet() &&
!$inputObj->IsRefund_idSet()) {
throw new WxPayException("退款查询接口中out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
* 下载对账单WxPayDownloadBill中bill_date为必填参数
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayDownloadBill $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function downloadBill($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/downloadbill";
//检测必填参数
if(!$inputObj->IsBill_dateSet()) {
throw new WxPayException("对账单接口中缺少必填参数bill_date");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
if(substr($response, 0 , 5) == "<xml>"){
return "";
}
return $response;
}
/**
* 提交被扫支付API
* 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,
* 由商户收银台或者商户后台调用该接口发起支付。
* WxPayWxPayMicroPay中body、out_trade_no、total_fee、auth_code参数必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayWxPayMicroPay $inputObj
* @param int $timeOut
*/
public static function micropay($config, $inputObj, $timeOut = 10)
{
$url = "https://api.mch.weixin.qq.com/pay/micropay";
//检测必填参数
if(!$inputObj->IsBodySet()) {
throw new WxPayException("提交被扫支付API接口中缺少必填参数body");
} else if(!$inputObj->IsOut_trade_noSet()) {
throw new WxPayException("提交被扫支付API接口中缺少必填参数out_trade_no");
} else if(!$inputObj->IsTotal_feeSet()) {
throw new WxPayException("提交被扫支付API接口中缺少必填参数total_fee");
} else if(!$inputObj->IsAuth_codeSet()) {
throw new WxPayException("提交被扫支付API接口中缺少必填参数auth_code");
}
$inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 撤销订单API接口WxPayReverse中参数out_trade_no和transaction_id必须填写一个
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayReverse $inputObj
* @param int $timeOut
* @throws WxPayException
*/
public static function reverse($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
//检测必填参数
if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
throw new WxPayException("撤销订单API接口中参数out_trade_no和transaction_id必须填写一个");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, true, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 测速上报该方法内部封装在report中使用时请注意异常流程
* WxPayReport中interface_url、return_code、result_code、user_ip、execute_time_必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayReport $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function report($config, $inputObj, $timeOut = 1)
{
$url = "https://api.mch.weixin.qq.com/payitil/report";
//检测必填参数
if(!$inputObj->IsInterface_urlSet()) {
throw new WxPayException("接口URL缺少必填参数interface_url");
} if(!$inputObj->IsReturn_codeSet()) {
throw new WxPayException("返回状态码缺少必填参数return_code");
} if(!$inputObj->IsResult_codeSet()) {
throw new WxPayException("业务结果缺少必填参数result_code");
} if(!$inputObj->IsUser_ipSet()) {
throw new WxPayException("访问接口IP缺少必填参数user_ip");
} if(!$inputObj->IsExecute_time_Set()) {
throw new WxPayException("接口耗时缺少必填参数execute_time_");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetUser_ip($_SERVER['REMOTE_ADDR']);//终端ip
$inputObj->SetTime(date("YmdHis"));//商户上报时间
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
return $response;
}
/**
*
* 生成二维码规则,模式一生成支付二维码
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayBizPayUrl $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function bizpayurl($config, $inputObj, $timeOut = 6)
{
if(!$inputObj->IsProduct_idSet()){
throw new WxPayException("生成二维码缺少必填参数product_id");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetTime_stamp(time());//时间戳
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
return $inputObj->GetValues();
}
/**
*
* 转换短链接
* 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX)
* 减小二维码数据量,提升扫描速度和精确度。
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayShortUrl $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
public static function shorturl($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/tools/shorturl";
//检测必填参数
if(!$inputObj->IsLong_urlSet()) {
throw new WxPayException("需要转换的URL签名用原串传输需URL encode");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
/**
*
* 支付结果通用通知
* @param function $callback
* 直接回调函数使用方法: notify(you_function);
* 回调类成员函数方法:notify(array($this, you_function));
* $callback 原型为function function_name($data){}
*/
public static function notify($config, $callback, &$msg)
{
//获取通知的数据
$xml = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
if (empty($xml)) {
# 如果没有数据,直接返回失败
return false;
}
//error_log($xml, 3, 'xml.log');
//如果返回成功则验证签名
try {
$result = WxPayNotifyResults::Init($config, $xml);
} catch (WxPayException $e){
$msg = $e->errorMessage();
return false;
}
return call_user_func($callback, $result);
}
/**
*
* 产生随机字符串不长于32位
* @param int $length
* @return 产生的随机字符串
*/
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;
}
/**
* 直接输出xml
* @param string $xml
*/
public static function replyNotify($xml)
{
echo $xml;
}
/**
*
* 上报数据, 上报的时候将屏蔽所有异常流程
* @param WxPayConfigInterface $config 配置对象
* @param string $usrl
* @param int $startTimeStamp
* @param array $data
*/
private static function reportCostTime($config, $url, $startTimeStamp, $data)
{
//如果不需要上报数据
$reportLevenl = $config->GetReportLevenl();
if($reportLevenl == 0){
return;
}
//如果仅失败上报
if($reportLevenl == 1 &&
array_key_exists("return_code", $data) &&
$data["return_code"] == "SUCCESS" &&
array_key_exists("result_code", $data) &&
$data["result_code"] == "SUCCESS")
{
return;
}
//上报逻辑
$endTimeStamp = self::getMillisecond();
$objInput = new WxPayReport();
$objInput->SetInterface_url($url);
$objInput->SetExecute_time_($endTimeStamp - $startTimeStamp);
//返回状态码
if(array_key_exists("return_code", $data)){
$objInput->SetReturn_code($data["return_code"]);
}
//返回信息
if(array_key_exists("return_msg", $data)){
$objInput->SetReturn_msg($data["return_msg"]);
}
//业务结果
if(array_key_exists("result_code", $data)){
$objInput->SetResult_code($data["result_code"]);
}
//错误代码
if(array_key_exists("err_code", $data)){
$objInput->SetErr_code($data["err_code"]);
}
//错误代码描述
if(array_key_exists("err_code_des", $data)){
$objInput->SetErr_code_des($data["err_code_des"]);
}
//商户订单号
if(array_key_exists("out_trade_no", $data)){
$objInput->SetOut_trade_no($data["out_trade_no"]);
}
//设备号
if(array_key_exists("device_info", $data)){
$objInput->SetDevice_info($data["device_info"]);
}
try{
self::report($config, $objInput);
} catch (WxPayException $e){
//不做任何处理
}
}
/**
* 以post方式提交xml到对应的接口url
*
* @param WxPayConfigInterface $config 配置对象
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间默认30s
* @throws WxPayException
*/
private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
$curlVersion = curl_version();
$ua = "WXPaySDK/".self::$VERSION." (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." ".$config->GetMerchantId();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
$proxyHost = "0.0.0.0";
$proxyPort = 0;
$config->GetProxy($proxyHost, $proxyPort);
//如果有配置代理这里就设置代理
if($proxyHost != "0.0.0.0" && $proxyPort != 0){
curl_setopt($ch,CURLOPT_PROXY, $proxyHost);
curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);
}
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
curl_setopt($ch,CURLOPT_USERAGENT, $ua);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if($useCert == true){
//设置证书
//使用证书cert 与 key 分别属于两个.pem文件
//证书文件请放入服务器的非web目录下
$sslCertPath = "";
$sslKeyPath = "";
$config->GetSSLCertPath($sslCertPath, $sslKeyPath);
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $sslKeyPath);
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错错误码:$error");
}
}
/**
* 获取毫秒级别的时间戳
*/
private static function getMillisecond()
{
//获取毫秒的时间戳
$time = explode ( " ", microtime () );
$time = $time[1] . ($time[0] * 1000);
$time2 = explode( ".", $time );
$time = $time2[0];
return $time;
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayConfigInterface;
/**
*
* example目录下为简单的支付样例仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk在安全上面仅做了简单处理 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
*
**/
/**
*
* 该类需要业务自己继承, 该类只是作为deamon使用
* 实际部署时,请务必保管自己的商户密钥,证书等
*
*/
class WxPayBajiaoConfig extends WxPayConfigInterface
{
//=======【基本信息设置】=====================================
/**
* TODO: 修改这里配置为您自己申请的商户信息
* 微信公众号信息配置
*
* APPID绑定支付的APPID必须配置开户邮件中可查看
*
* MCHID商户号必须配置开户邮件中可查看
*
*/
public function GetAppId()
{
return 'wxbad8cd9d897ef155'; //wx8af116e84f257e41
}
public function GetMerchantId()
{
return '1369789502'; //1556027731
}
//=======【支付相关配置:支付成功回调地址/签名方式】===================================
/**
* TODO:支付回调url
* 签名和验证签名方式, 支持md5和sha256方式
**/
public function GetNotifyUrl()
{
return "";
}
public function GetSignType()
{
return "HMAC-SHA256";
}
//=======【curl代理设置】===================================
/**
* TODO这里设置代理机器只有需要代理的时候才设置不需要代理请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法此处可修改代理服务器
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0此时不开启代理如有需要才设置
* @var unknown_type
*/
public function GetProxy(&$proxyHost, &$proxyPort)
{
$proxyHost = "0.0.0.0";
$proxyPort = 0;
}
//=======【上报信息配置】===================================
/**
* TODO接口调用上报等级默认紧错误上报注意上报超时间为【1s】上报无论成败【永不抛出异常】
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
public function GetReportLevenl()
{
return 1;
}
//=======【商户密钥信息-需要业务方继承】===================================
/*
* KEY商户支付密钥参考开户邮件设置必须配置登录商户平台自行设置, 请妥善保管, 避免密钥泄露
* 设置地址https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET公众帐号secert仅JSAPI支付的时候需要配置 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露
* 获取地址https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
public function GetKey()
{
return '3db14e5f4727656268adaec1ac49502g'; //3db14e5f4727656268adaec1ac49502g
}
public function GetAppSecret()
{
return 'b555b2ffbe47bdf18eb86aff39881603'; //028ada76aab35b20dc5aa474f605cf50
}
//=======【证书路径设置-需要业务方继承】=====================================
/**
* TODO设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址https://pay.weixin.qq.com/index.php/account/api_cert下载之前需要安装商户操作证书
* 注意:
* 1.证书文件不能放在web服务器虚拟目录应放在有访问权限控制的目录中防止被他人下载
* 2.建议将证书文件名改为复杂且不容易猜测的文件名;
* 3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
* @var path
*/
public function GetSSLCertPath(&$sslCertPath, &$sslKeyPath)
{
$sslCertPath = './apiclient_cert.pem';
$sslKeyPath = './apiclient_key.pem';
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBaseSignMd5;
/**
*
* 扫码支付模式一生成二维码参数
* @author widyhu
*
*/
class WxPayBizPayUrl extends WxPayDataBaseSignMd5
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置支付时间戳
* @param string $value
**/
public function SetTime_stamp($value)
{
$this->values['time_stamp'] = $value;
}
/**
* 获取支付时间戳的值
* @return 值
**/
public function GetTime_stamp()
{
return $this->values['time_stamp'];
}
/**
* 判断支付时间戳是否存在
* @return true 或 false
**/
public function IsTime_stampSet()
{
return array_key_exists('time_stamp', $this->values);
}
/**
* 设置随机字符串
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置商品ID
* @param string $value
**/
public function SetProduct_id($value)
{
$this->values['product_id'] = $value;
}
/**
* 获取商品ID的值
* @return 值
**/
public function GetProduct_id()
{
return $this->values['product_id'];
}
/**
* 判断商品ID是否存在
* @return true 或 false
**/
public function IsProduct_idSet()
{
return array_key_exists('product_id', $this->values);
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 关闭订单输入对象
* @author widyhu
*
*/
class WxPayCloseOrder extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置商户系统内部的订单号
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayConfigInterface;
/**
*
* example目录下为简单的支付样例仅能用于搭建快速体验微信支付使用
* 样例的作用仅限于指导如何使用sdk在安全上面仅做了简单处理 复制使用样例代码时请慎重
* 请勿直接直接使用样例对外提供服务
*
**/
/**
*
* 该类需要业务自己继承, 该类只是作为deamon使用
* 实际部署时,请务必保管自己的商户密钥,证书等
*
*/
class WxPayConfig extends WxPayConfigInterface
{
//=======【基本信息设置】=====================================
/**
* TODO: 修改这里配置为您自己申请的商户信息
* 微信公众号信息配置
*
* APPID绑定支付的APPID必须配置开户邮件中可查看
*
* MCHID商户号必须配置开户邮件中可查看
*
*/
public function GetAppId()
{
// return 'wx965a1d0925edc5c0';
return 'wx7b5c4e89e726a72c';
}
public function GetMerchantId()
{
// return '1669025060';
return '1724482647';
}
//=======【支付相关配置:支付成功回调地址/签名方式】===================================
/**
* TODO:支付回调url
* 签名和验证签名方式, 支持md5和sha256方式
**/
public function GetNotifyUrl()
{
return "";
}
public function GetSignType()
{
return "HMAC-SHA256";
}
//=======【curl代理设置】===================================
/**
* TODO这里设置代理机器只有需要代理的时候才设置不需要代理请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法此处可修改代理服务器
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0此时不开启代理如有需要才设置
* @var unknown_type
*/
public function GetProxy(&$proxyHost, &$proxyPort)
{
$proxyHost = "0.0.0.0";
$proxyPort = 0;
}
//=======【上报信息配置】===================================
/**
* TODO接口调用上报等级默认紧错误上报注意上报超时间为【1s】上报无论成败【永不抛出异常】
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
public function GetReportLevenl()
{
return 1;
}
//=======【商户密钥信息-需要业务方继承】===================================
/*
* KEY商户支付密钥参考开户邮件设置必须配置登录商户平台自行设置, 请妥善保管, 避免密钥泄露
* 设置地址https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET公众帐号secert仅JSAPI支付的时候需要配置 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露
* 获取地址https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
public function GetKey()
{
return 'B4WB6294x9VT5rP6s9CUzhVA3h1fAkbA';
}
public function GetAppSecret()
{
// return '562d3856021bfb89379f6b6f624fe315';
return 'afc9860f4c670ac19f9efb0ab94927a3';
}
//=======【证书路径设置-需要业务方继承】=====================================
/**
* TODO设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址https://pay.weixin.qq.com/index.php/account/api_cert下载之前需要安装商户操作证书
* 注意:
* 1.证书文件不能放在web服务器虚拟目录应放在有访问权限控制的目录中防止被他人下载
* 2.建议将证书文件名改为复杂且不容易猜测的文件名;
* 3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
* @var path
*/
public function GetSSLCertPath(&$sslCertPath, &$sslKeyPath)
{
$sslCertPath = './apiclient_cert.pem';
$sslKeyPath = './apiclient_key.pem';
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace app\api\wxapi\pay;
/**
* 配置账号信息
*/
abstract class WxPayConfigInterface
{
//=======【基本信息设置】=====================================
/**
* TODO: 修改这里配置为您自己申请的商户信息
* 微信公众号信息配置
*
* APPID绑定支付的APPID必须配置开户邮件中可查看
*
* MCHID商户号必须配置开户邮件中可查看
*
*/
public abstract function GetAppId();
public abstract function GetMerchantId();
//=======【支付相关配置:支付成功回调地址/签名方式】===================================
/**
* TODO:支付回调url
* 签名和验证签名方式, 支持md5和sha256方式
**/
public abstract function GetNotifyUrl();
public abstract function GetSignType();
//=======【curl代理设置】===================================
/**
* TODO这里设置代理机器只有需要代理的时候才设置不需要代理请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法此处可修改代理服务器
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0此时不开启代理如有需要才设置
* @var unknown_type
*/
public abstract function GetProxy(&$proxyHost, &$proxyPort);
//=======【上报信息配置】===================================
/**
* TODO接口调用上报等级默认紧错误上报注意上报超时间为【1s】上报无论成败【永不抛出异常】
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
public abstract function GetReportLevenl();
//=======【商户密钥信息-需要业务方继承】===================================
/*
* KEY商户支付密钥参考开户邮件设置必须配置登录商户平台自行设置, 请妥善保管, 避免密钥泄露
* 设置地址https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET公众帐号secert仅JSAPI支付的时候需要配置 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露
* 获取地址https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
public abstract function GetKey();
public abstract function GetAppSecret();
//=======【证书路径设置-需要业务方继承】=====================================
/**
* TODO设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址https://pay.weixin.qq.com/index.php/account/api_cert下载之前需要安装商户操作证书
* 注意:
* 1.证书文件不能放在web服务器虚拟目录应放在有访问权限控制的目录中防止被他人下载
* 2.建议将证书文件名改为复杂且不容易猜测的文件名;
* 3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
* @var path
*/
public abstract function GetSSLCertPath(&$sslCertPath, &$sslKeyPath);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
<?php
namespace app\api\wxapi\pay;
/**
* 2015-06-29 修复签名问题
**/
/**
*
* 数据对象基础类,该类中定义数据类最基本的行为,包括:
* 计算/设置/获取签名、输出xml格式的参数、从xml读取数据对象等
* @author widyhu
*
*/
class WxPayDataBase
{
protected $values = array();
/**
* 设置签名,详见签名生成算法类型
* @param string $value
**/
public function SetSignType($sign_type)
{
$this->values['sign_type'] = $sign_type;
return $sign_type;
}
/**
* 设置签名,详见签名生成算法
* @param string $value
**/
public function SetSign($config)
{
$sign = $this->MakeSign($config);
$this->values['sign'] = $sign;
return $sign;
}
/**
* 获取签名,详见签名生成算法的值
* @return 值
**/
public function GetSign()
{
return $this->values['sign'];
}
/**
* 判断签名,详见签名生成算法是否存在
* @return true 或 false
**/
public function IsSignSet()
{
return array_key_exists('sign', $this->values);
}
/**
* 输出xml字符
* @throws WxPayException
**/
public function ToXml()
{
if(!is_array($this->values) || count($this->values) <= 0)
{
throw new WxPayException("数组数据异常!");
}
$xml = "<xml>";
foreach ($this->values as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* 将xml转为array
* @param string $xml
* @throws WxPayException
*/
public function FromXml($xml)
{
if(!$xml){
throw new WxPayException("xml数据异常");
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
}
/**
* 格式化参数格式化成url参数
*/
public function ToUrlParams()
{
$buff = "";
foreach ($this->values as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 生成签名
* @param WxPayConfigInterface $config 配置对象
* @param bool $needSignType 是否需要补signtype
* @return 签名本函数不覆盖sign成员变量如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign($config, $needSignType = true)
{
if($needSignType) {
$this->SetSignType($config->GetSignType());
}
//签名步骤一:按字典序排序参数
ksort($this->values);
$string = $this->ToUrlParams();
//签名步骤二在string后加入KEY
$string = $string . "&key=".$config->GetKey();
//签名步骤三MD5加密或者HMAC-SHA256
if($config->GetSignType() == "MD5"){
$string = md5($string);
} else if($config->GetSignType() == "HMAC-SHA256") {
$string = hash_hmac("sha256",$string ,$config->GetKey());
} else {
throw new WxPayException("签名类型不支持!");
}
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 获取设置的值
*/
public function GetValues()
{
return $this->values;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 只使用md5算法进行签名 不管配置的是什么签名方式都只支持md5签名方式
*
**/
class WxPayDataBaseSignMd5 extends WxPayDataBase
{
/**
* 生成签名 - 重写该方法
* @param WxPayConfigInterface $config 配置对象
* @param bool $needSignType 是否需要补signtype
* @return 签名本函数不覆盖sign成员变量如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign($config, $needSignType = false)
{
if($needSignType) {
$this->SetSignType($config->GetSignType());
}
//签名步骤一:按字典序排序参数
ksort($this->values);
$string = $this->ToUrlParams();
//签名步骤二在string后加入KEY
$string = $string . "&key=".$config->GetKey();
//签名步骤三MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
}

View File

@@ -0,0 +1,168 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 下载对账单输入对象
* @author widyhu
*
*/
class WxPayDownloadBill extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置下载对账单的日期格式20140603
* @param string $value
**/
public function SetBill_date($value)
{
$this->values['bill_date'] = $value;
}
/**
* 获取下载对账单的日期格式20140603的值
* @return 值
**/
public function GetBill_date()
{
return $this->values['bill_date'];
}
/**
* 判断下载对账单的日期格式20140603是否存在
* @return true 或 false
**/
public function IsBill_dateSet()
{
return array_key_exists('bill_date', $this->values);
}
/**
* 设置ALL返回当日所有订单信息默认值SUCCESS返回当日成功支付的订单REFUND返回当日退款订单REVOKED已撤销的订单
* @param string $value
**/
public function SetBill_type($value)
{
$this->values['bill_type'] = $value;
}
/**
* 获取ALL返回当日所有订单信息默认值SUCCESS返回当日成功支付的订单REFUND返回当日退款订单REVOKED已撤销的订单的值
* @return 值
**/
public function GetBill_type()
{
return $this->values['bill_type'];
}
/**
* 判断ALL返回当日所有订单信息默认值SUCCESS返回当日成功支付的订单REFUND返回当日退款订单REVOKED已撤销的订单是否存在
* @return true 或 false
**/
public function IsBill_typeSet()
{
return array_key_exists('bill_type', $this->values);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace app\api\wxapi\pay;
/**
*
* 微信支付API异常类
* @author widyhu
*
*/
class WxPayException extends \Exception {
public function errorMessage()
{
return $this->getMessage();
}
}

View File

@@ -0,0 +1,166 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 提交JSAPI输入对象
* @author widyhu
*
*/
class WxPayJsApiPay extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appId'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appId'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appId', $this->values);
}
/**
* 设置支付时间戳
* @param string $value
**/
public function SetTimeStamp($value)
{
$this->values['timeStamp'] = $value;
}
/**
* 获取支付时间戳的值
* @return 值
**/
public function GetTimeStamp()
{
return $this->values['timeStamp'];
}
/**
* 判断支付时间戳是否存在
* @return true 或 false
**/
public function IsTimeStampSet()
{
return array_key_exists('timeStamp', $this->values);
}
/**
* 随机字符串
* @param string $value
**/
public function SetNonceStr($value)
{
$this->values['nonceStr'] = $value;
}
/**
* 获取notify随机字符串值
* @return 值
**/
public function GetReturn_code()
{
return $this->values['nonceStr'];
}
/**
* 判断随机字符串是否存在
* @return true 或 false
**/
public function IsReturn_codeSet()
{
return array_key_exists('nonceStr', $this->values);
}
/**
* 设置订单详情扩展字符串
* @param string $value
**/
public function SetPackage($value)
{
$this->values['package'] = $value;
}
/**
* 获取订单详情扩展字符串的值
* @return 值
**/
public function GetPackage()
{
return $this->values['package'];
}
/**
* 判断订单详情扩展字符串是否存在
* @return true 或 false
**/
public function IsPackageSet()
{
return array_key_exists('package', $this->values);
}
/**
* 设置签名方式
* @param string $value
**/
public function SetSignType($value)
{
$this->values['signType'] = $value;
}
/**
* 获取签名方式
* @return 值
**/
public function GetSignType()
{
return $this->values['signType'];
}
/**
* 判断签名方式是否存在
* @return true 或 false
**/
public function IsSignTypeSet()
{
return array_key_exists('signType', $this->values);
}
/**
* 设置签名方式
* @param string $value
**/
public function SetPaySign($value)
{
$this->values['paySign'] = $value;
}
/**
* 获取签名方式
* @return 值
**/
public function GetPaySign()
{
return $this->values['paySign'];
}
/**
* 判断签名方式是否存在
* @return true 或 false
**/
public function IsPaySignSet()
{
return array_key_exists('paySign', $this->values);
}
}

View File

@@ -0,0 +1,401 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 提交被扫输入对象
* @author widyhu
*
*/
class WxPayMicroPay extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置终端设备号(商户自定义,如门店编号)
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取终端设备号(商户自定义,如门店编号)的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断终端设备号(商户自定义,如门店编号)是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置商品或支付单简要描述
* @param string $value
**/
public function SetBody($value)
{
$this->values['body'] = $value;
}
/**
* 获取商品或支付单简要描述的值
* @return 值
**/
public function GetBody()
{
return $this->values['body'];
}
/**
* 判断商品或支付单简要描述是否存在
* @return true 或 false
**/
public function IsBodySet()
{
return array_key_exists('body', $this->values);
}
/**
* 设置商品名称明细列表
* @param string $value
**/
public function SetDetail($value)
{
$this->values['detail'] = $value;
}
/**
* 获取商品名称明细列表的值
* @return 值
**/
public function GetDetail()
{
return $this->values['detail'];
}
/**
* 判断商品名称明细列表是否存在
* @return true 或 false
**/
public function IsDetailSet()
{
return array_key_exists('detail', $this->values);
}
/**
* 设置附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据
* @param string $value
**/
public function SetAttach($value)
{
$this->values['attach'] = $value;
}
/**
* 获取附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据的值
* @return 值
**/
public function GetAttach()
{
return $this->values['attach'];
}
/**
* 判断附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据是否存在
* @return true 或 false
**/
public function IsAttachSet()
{
return array_key_exists('attach', $this->values);
}
/**
* 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置订单总金额,单位为分,只能为整数,详见支付金额
* @param string $value
**/
public function SetTotal_fee($value)
{
$this->values['total_fee'] = $value;
}
/**
* 获取订单总金额,单位为分,只能为整数,详见支付金额的值
* @return 值
**/
public function GetTotal_fee()
{
return $this->values['total_fee'];
}
/**
* 判断订单总金额,单位为分,只能为整数,详见支付金额是否存在
* @return true 或 false
**/
public function IsTotal_feeSet()
{
return array_key_exists('total_fee', $this->values);
}
/**
* 设置符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
* @param string $value
**/
public function SetFee_type($value)
{
$this->values['fee_type'] = $value;
}
/**
* 获取符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型的值
* @return 值
**/
public function GetFee_type()
{
return $this->values['fee_type'];
}
/**
* 判断符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型是否存在
* @return true 或 false
**/
public function IsFee_typeSet()
{
return array_key_exists('fee_type', $this->values);
}
/**
* 设置调用微信支付API的机器IP
* @param string $value
**/
public function SetSpbill_create_ip($value)
{
$this->values['spbill_create_ip'] = $value;
}
/**
* 获取调用微信支付API的机器IP 的值
* @return 值
**/
public function GetSpbill_create_ip()
{
return $this->values['spbill_create_ip'];
}
/**
* 判断调用微信支付API的机器IP 是否存在
* @return true 或 false
**/
public function IsSpbill_create_ipSet()
{
return array_key_exists('spbill_create_ip', $this->values);
}
/**
* 设置订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则
* @param string $value
**/
public function SetTime_start($value)
{
$this->values['time_start'] = $value;
}
/**
* 获取订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则的值
* @return 值
**/
public function GetTime_start()
{
return $this->values['time_start'];
}
/**
* 判断订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则是否存在
* @return true 或 false
**/
public function IsTime_startSet()
{
return array_key_exists('time_start', $this->values);
}
/**
* 设置订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则
* @param string $value
**/
public function SetTime_expire($value)
{
$this->values['time_expire'] = $value;
}
/**
* 获取订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则的值
* @return 值
**/
public function GetTime_expire()
{
return $this->values['time_expire'];
}
/**
* 判断订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则是否存在
* @return true 或 false
**/
public function IsTime_expireSet()
{
return array_key_exists('time_expire', $this->values);
}
/**
* 设置商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
* @param string $value
**/
public function SetGoods_tag($value)
{
$this->values['goods_tag'] = $value;
}
/**
* 获取商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠的值
* @return 值
**/
public function GetGoods_tag()
{
return $this->values['goods_tag'];
}
/**
* 判断商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠是否存在
* @return true 或 false
**/
public function IsGoods_tagSet()
{
return array_key_exists('goods_tag', $this->values);
}
/**
* 设置扫码支付授权码,设备读取用户微信中的条码或者二维码信息
* @param string $value
**/
public function SetAuth_code($value)
{
$this->values['auth_code'] = $value;
}
/**
* 获取扫码支付授权码,设备读取用户微信中的条码或者二维码信息的值
* @return 值
**/
public function GetAuth_code()
{
return $this->values['auth_code'];
}
/**
* 判断扫码支付授权码,设备读取用户微信中的条码或者二维码信息是否存在
* @return true 或 false
**/
public function IsAuth_codeSet()
{
return array_key_exists('auth_code', $this->values);
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace app\api\wxapi\pay;
/**
*
* 回调基础类
* @author widyhu
*
*/
class WxPayNotify extends WxPayNotifyReply
{
private $config = null;
/**
*
* 回调入口
* @param bool $needSign 是否需要签名返回
*/
final public function Handle($config, $needSign = true)
{
$this->config = $config;
$msg = "OK";
//当返回false的时候表示notify中调用NotifyCallBack回调失败获取签名校验失败此时直接回复失败
$result = WxPayApi::notify($config, array($this, 'NotifyCallBack'), $msg);
if($result == false){
$this->SetReturn_code("FAIL");
$this->SetReturn_msg($msg);
$this->ReplyNotify(false);
return;
} else {
//该分支在成功回调到NotifyCallBack方法处理完成之后流程
$this->SetReturn_code("SUCCESS");
$this->SetReturn_msg("OK");
}
$this->ReplyNotify($needSign);
}
/**
*
* 回调方法入口,子类可重写该方法
//TODO 1、进行参数校验
//TODO 2、进行签名验证
//TODO 3、处理业务逻辑
* 注意:
* 1、微信回调超时时间为2s建议用户使用异步处理流程确认成功之后立刻回复微信服务器
* 2、微信服务器在调用失败或者接到回包为非确认包的时候会发起重试需确保你的回调是可以重入
* @param WxPayNotifyResults $objData 回调解释出的参数
* @param WxPayConfigInterface $config
* @param string $msg 如果回调处理失败,可以将错误信息输出到该方法
* @return true回调出来完成不需要继续回调false回调处理未完成需要继续回调
*/
public function NotifyProcess($objData, $config, &$msg)
{
//TODO 用户基础该类之后需要重写该方法成功的时候返回true失败返回false
return false;
}
/**
*
* 业务可以继承该方法打印XML方便定位.
* @param string $xmlData 返回的xml参数
*
**/
public function LogAfterProcess($xmlData)
{
return;
}
/**
*
* notify回调方法该方法中需要赋值需要输出的参数,不可重写
* @param array $data
* @return true回调出来完成不需要继续回调false回调处理未完成需要继续回调
*/
final public function NotifyCallBack($data)
{
$msg = "OK";
$result = $this->NotifyProcess($data, $this->config, $msg);
if($result == true){
$this->SetReturn_code("SUCCESS");
$this->SetReturn_msg("OK");
} else {
$this->SetReturn_code("FAIL");
$this->SetReturn_msg($msg);
}
return $result;
}
/**
*
* 回复通知
* @param bool $needSign 是否需要签名输出
*/
final private function ReplyNotify($needSign = true)
{
//如果需要签名
if($needSign == true &&
$this->GetReturn_code() == "SUCCESS")
{
$this->SetSign($this->config);
}
$xml = $this->ToXml();
$this->LogAfterProcess($xml);
WxPayApi::replyNotify($xml);
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBaseSignMd5;
/**
*
* 回调基础类
* @author widyhu
*
*/
class WxPayNotifyReply extends WxPayDataBaseSignMd5
{
/**
*
* 设置错误码 FAIL 或者 SUCCESS
* @param string
*/
public function SetReturn_code($return_code)
{
$this->values['return_code'] = $return_code;
}
/**
*
* 获取错误码 FAIL 或者 SUCCESS
* @return string $return_code
*/
public function GetReturn_code()
{
return $this->values['return_code'];
}
/**
*
* 设置错误信息
* @param string $return_code
*/
public function SetReturn_msg($return_msg)
{
$this->values['return_msg'] = $return_msg;
}
/**
*
* 获取错误信息
* @return string
*/
public function GetReturn_msg()
{
return $this->values['return_msg'];
}
/**
*
* 设置返回参数
* @param string $key
* @param string $value
*/
public function SetData($key, $value)
{
$this->values[$key] = $value;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayResults;
/**
*
* 回调回包数据基类
*
**/
class WxPayNotifyResults extends WxPayResults
{
/**
* 将xml转为array
* @param WxPayConfigInterface $config
* @param string $xml
* @return WxPayNotifyResults
* @throws WxPayException
*/
public static function Init($config, $xml)
{
$obj = new self();
$obj->FromXml($xml);
//失败则直接返回失败
$obj->CheckSign($config);
return $obj;
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 订单查询输入对象
* @author widyhu
*
*/
class WxPayOrderQuery extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信的订单号,优先使用
* @param string $value
**/
public function SetTransaction_id($value)
{
$this->values['transaction_id'] = $value;
}
/**
* 获取微信的订单号,优先使用的值
* @return 值
**/
public function GetTransaction_id()
{
return $this->values['transaction_id'];
}
/**
* 判断微信的订单号,优先使用是否存在
* @return true 或 false
**/
public function IsTransaction_idSet()
{
return array_key_exists('transaction_id', $this->values);
}
/**
* 设置商户系统内部的订单号当没提供transaction_id时需要传这个。
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号当没提供transaction_id时需要传这个。的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号当没提供transaction_id时需要传这个。是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
}

View File

@@ -0,0 +1,298 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 提交退款输入对象
* @author widyhu
*
*/
class WxPayRefund extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信支付分配的终端设备号,与下单一致
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取微信支付分配的终端设备号,与下单一致的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断微信支付分配的终端设备号,与下单一致是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置微信订单号
* @param string $value
**/
public function SetTransaction_id($value)
{
$this->values['transaction_id'] = $value;
}
/**
* 获取微信订单号的值
* @return 值
**/
public function GetTransaction_id()
{
return $this->values['transaction_id'];
}
/**
* 判断微信订单号是否存在
* @return true 或 false
**/
public function IsTransaction_idSet()
{
return array_key_exists('transaction_id', $this->values);
}
/**
* 设置商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
* @param string $value
**/
public function SetOut_refund_no($value)
{
$this->values['out_refund_no'] = $value;
}
/**
* 获取商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔的值
* @return 值
**/
public function GetOut_refund_no()
{
return $this->values['out_refund_no'];
}
/**
* 判断商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔是否存在
* @return true 或 false
**/
public function IsOut_refund_noSet()
{
return array_key_exists('out_refund_no', $this->values);
}
/**
* 设置订单总金额,单位为分,只能为整数,详见支付金额
* @param string $value
**/
public function SetTotal_fee($value)
{
$this->values['total_fee'] = $value;
}
/**
* 获取订单总金额,单位为分,只能为整数,详见支付金额的值
* @return 值
**/
public function GetTotal_fee()
{
return $this->values['total_fee'];
}
/**
* 判断订单总金额,单位为分,只能为整数,详见支付金额是否存在
* @return true 或 false
**/
public function IsTotal_feeSet()
{
return array_key_exists('total_fee', $this->values);
}
/**
* 设置退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
* @param string $value
**/
public function SetRefund_fee($value)
{
$this->values['refund_fee'] = $value;
}
/**
* 获取退款总金额,订单总金额,单位为分,只能为整数,详见支付金额的值
* @return 值
**/
public function GetRefund_fee()
{
return $this->values['refund_fee'];
}
/**
* 判断退款总金额,订单总金额,单位为分,只能为整数,详见支付金额是否存在
* @return true 或 false
**/
public function IsRefund_feeSet()
{
return array_key_exists('refund_fee', $this->values);
}
/**
* 设置货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
* @param string $value
**/
public function SetRefund_fee_type($value)
{
$this->values['refund_fee_type'] = $value;
}
/**
* 获取货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型的值
* @return 值
**/
public function GetRefund_fee_type()
{
return $this->values['refund_fee_type'];
}
/**
* 判断货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型是否存在
* @return true 或 false
**/
public function IsRefund_fee_typeSet()
{
return array_key_exists('refund_fee_type', $this->values);
}
/**
* 设置操作员帐号, 默认为商户号
* @param string $value
**/
public function SetOp_user_id($value)
{
$this->values['op_user_id'] = $value;
}
/**
* 获取操作员帐号, 默认为商户号的值
* @return 值
**/
public function GetOp_user_id()
{
return $this->values['op_user_id'];
}
/**
* 判断操作员帐号, 默认为商户号是否存在
* @return true 或 false
**/
public function IsOp_user_idSet()
{
return array_key_exists('op_user_id', $this->values);
}
}

View File

@@ -0,0 +1,220 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 退款查询输入对象
* @author widyhu
*
*/
class WxPayRefundQuery extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信支付分配的终端设备号
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取微信支付分配的终端设备号的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断微信支付分配的终端设备号是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置微信订单号
* @param string $value
**/
public function SetTransaction_id($value)
{
$this->values['transaction_id'] = $value;
}
/**
* 获取微信订单号的值
* @return 值
**/
public function GetTransaction_id()
{
return $this->values['transaction_id'];
}
/**
* 判断微信订单号是否存在
* @return true 或 false
**/
public function IsTransaction_idSet()
{
return array_key_exists('transaction_id', $this->values);
}
/**
* 设置商户系统内部的订单号
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置商户退款单号
* @param string $value
**/
public function SetOut_refund_no($value)
{
$this->values['out_refund_no'] = $value;
}
/**
* 获取商户退款单号的值
* @return 值
**/
public function GetOut_refund_no()
{
return $this->values['out_refund_no'];
}
/**
* 判断商户退款单号是否存在
* @return true 或 false
**/
public function IsOut_refund_noSet()
{
return array_key_exists('out_refund_no', $this->values);
}
/**
* 设置微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个如果同时存在优先级为refund_id>out_refund_no>transaction_id>out_trade_no
* @param string $value
**/
public function SetRefund_id($value)
{
$this->values['refund_id'] = $value;
}
/**
* 获取微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个如果同时存在优先级为refund_id>out_refund_no>transaction_id>out_trade_no的值
* @return 值
**/
public function GetRefund_id()
{
return $this->values['refund_id'];
}
/**
* 判断微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个如果同时存在优先级为refund_id>out_refund_no>transaction_id>out_trade_no是否存在
* @return true 或 false
**/
public function IsRefund_idSet()
{
return array_key_exists('refund_id', $this->values);
}
}

View File

@@ -0,0 +1,377 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 测速上报输入对象
* @author widyhu
*
*/
class WxPayReport extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信支付分配的终端设备号,商户自定义
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取微信支付分配的终端设备号,商户自定义的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断微信支付分配的终端设备号,商户自定义是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置上报对应的接口的完整URL类似https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付为更好的和商户共同分析一次业务行为的整体耗时情况对于两种接入模式请都在门店侧对一次被扫行为进行一次单独的整体上报上报URL指定为https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节被扫支付商户接入模式其它接口调用仍然按照调用一次上报一次来进行。
* @param string $value
**/
public function SetInterface_url($value)
{
$this->values['interface_url'] = $value;
}
/**
* 获取上报对应的接口的完整URL类似https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付为更好的和商户共同分析一次业务行为的整体耗时情况对于两种接入模式请都在门店侧对一次被扫行为进行一次单独的整体上报上报URL指定为https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节被扫支付商户接入模式其它接口调用仍然按照调用一次上报一次来进行。的值
* @return 值
**/
public function GetInterface_url()
{
return $this->values['interface_url'];
}
/**
* 判断上报对应的接口的完整URL类似https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付为更好的和商户共同分析一次业务行为的整体耗时情况对于两种接入模式请都在门店侧对一次被扫行为进行一次单独的整体上报上报URL指定为https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节被扫支付商户接入模式其它接口调用仍然按照调用一次上报一次来进行。是否存在
* @return true 或 false
**/
public function IsInterface_urlSet()
{
return array_key_exists('interface_url', $this->values);
}
/**
* 设置接口耗时情况,单位为毫秒
* @param string $value
**/
public function SetExecute_time_($value)
{
$this->values['execute_time_'] = $value;
}
/**
* 获取接口耗时情况,单位为毫秒的值
* @return 值
**/
public function GetExecute_time_()
{
return $this->values['execute_time_'];
}
/**
* 判断接口耗时情况,单位为毫秒是否存在
* @return true 或 false
**/
public function IsExecute_time_Set()
{
return array_key_exists('execute_time_', $this->values);
}
/**
* 设置SUCCESS/FAIL此字段是通信标识非交易标识交易是否成功需要查看trade_state来判断
* @param string $value
**/
public function SetReturn_code($value)
{
$this->values['return_code'] = $value;
}
/**
* 获取SUCCESS/FAIL此字段是通信标识非交易标识交易是否成功需要查看trade_state来判断的值
* @return 值
**/
public function GetReturn_code()
{
return $this->values['return_code'];
}
/**
* 判断SUCCESS/FAIL此字段是通信标识非交易标识交易是否成功需要查看trade_state来判断是否存在
* @return true 或 false
**/
public function IsReturn_codeSet()
{
return array_key_exists('return_code', $this->values);
}
/**
* 设置返回信息,如非空,为错误原因签名失败参数格式校验错误
* @param string $value
**/
public function SetReturn_msg($value)
{
$this->values['return_msg'] = $value;
}
/**
* 获取返回信息,如非空,为错误原因签名失败参数格式校验错误的值
* @return 值
**/
public function GetReturn_msg()
{
return $this->values['return_msg'];
}
/**
* 判断返回信息,如非空,为错误原因签名失败参数格式校验错误是否存在
* @return true 或 false
**/
public function IsReturn_msgSet()
{
return array_key_exists('return_msg', $this->values);
}
/**
* 设置SUCCESS/FAIL
* @param string $value
**/
public function SetResult_code($value)
{
$this->values['result_code'] = $value;
}
/**
* 获取SUCCESS/FAIL的值
* @return 值
**/
public function GetResult_code()
{
return $this->values['result_code'];
}
/**
* 判断SUCCESS/FAIL是否存在
* @return true 或 false
**/
public function IsResult_codeSet()
{
return array_key_exists('result_code', $this->values);
}
/**
* 设置ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误
* @param string $value
**/
public function SetErr_code($value)
{
$this->values['err_code'] = $value;
}
/**
* 获取ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误的值
* @return 值
**/
public function GetErr_code()
{
return $this->values['err_code'];
}
/**
* 判断ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误是否存在
* @return true 或 false
**/
public function IsErr_codeSet()
{
return array_key_exists('err_code', $this->values);
}
/**
* 设置结果信息描述
* @param string $value
**/
public function SetErr_code_des($value)
{
$this->values['err_code_des'] = $value;
}
/**
* 获取结果信息描述的值
* @return 值
**/
public function GetErr_code_des()
{
return $this->values['err_code_des'];
}
/**
* 判断结果信息描述是否存在
* @return true 或 false
**/
public function IsErr_code_desSet()
{
return array_key_exists('err_code_des', $this->values);
}
/**
* 设置商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。 的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。 是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置发起接口调用时的机器IP
* @param string $value
**/
public function SetUser_ip($value)
{
$this->values['user_ip'] = $value;
}
/**
* 获取发起接口调用时的机器IP 的值
* @return 值
**/
public function GetUser_ip()
{
return $this->values['user_ip'];
}
/**
* 判断发起接口调用时的机器IP 是否存在
* @return true 或 false
**/
public function IsUser_ipSet()
{
return array_key_exists('user_ip', $this->values);
}
/**
* 设置系统时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
* @param string $value
**/
public function SetTime($value)
{
$this->values['time'] = $value;
}
/**
* 获取系统时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则的值
* @return 值
**/
public function GetTime()
{
return $this->values['time'];
}
/**
* 判断系统时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则是否存在
* @return true 或 false
**/
public function IsTimeSet()
{
return array_key_exists('time', $this->values);
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 接口调用结果类
* @author widyhu
*
*/
class WxPayResults extends WxPayDataBase
{
/**
* 生成签名 - 重写该方法
* @param WxPayConfigInterface $config 配置对象
* @param bool $needSignType 是否需要补signtype
* @return 签名本函数不覆盖sign成员变量如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign($config, $needSignType = false)
{
//签名步骤一:按字典序排序参数
ksort($this->values);
$string = $this->ToUrlParams();
//签名步骤二在string后加入KEY
$string = $string . "&key=".$config->GetKey();
//签名步骤三MD5加密或者HMAC-SHA256
if(strlen($this->GetSign()) <= 32){
//如果签名小于等于32个,则使用md5验证
$string = md5($string);
} else {
//是用sha256校验
$string = hash_hmac("sha256",$string ,$config->GetKey());
}
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* @param WxPayConfigInterface $config 配置对象
* 检测签名
*/
public function CheckSign($config)
{
if(!$this->IsSignSet()){
throw new WxPayException("签名错误!");
}
$sign = $this->MakeSign($config, false);
if($this->GetSign() == $sign){
//签名正确
return true;
}
throw new WxPayException("签名错误!");
}
/**
*
* 使用数组初始化
* @param array $array
*/
public function FromArray($array)
{
$this->values = $array;
}
/**
*
* 使用数组初始化对象
* @param array $array
* @param 是否检测签名 $noCheckSign
*/
public static function InitFromArray($config, $array, $noCheckSign = false)
{
$obj = new self();
$obj->FromArray($array);
if($noCheckSign == false){
$obj->CheckSign($config);
}
return $obj;
}
/**
*
* 设置参数
* @param string $key
* @param string $value
*/
public function SetData($key, $value)
{
$this->values[$key] = $value;
}
/**
* 将xml转为array
* @param WxPayConfigInterface $config 配置对象
* @param string $xml
* @throws WxPayException
*/
public static function Init($config, $xml)
{
$obj = new self();
$obj->FromXml($xml);
//失败则直接返回失败
if($obj->values['return_code'] != 'SUCCESS') {
foreach ($obj->values as $key => $value) {
#除了return_code和return_msg之外其他的参数存在则报错
if($key != "return_code" && $key != "return_msg"){
throw new WxPayException("输入数据存在异常!");
return false;
}
}
return $obj->GetValues();
}
$obj->CheckSign($config);
return $obj->GetValues();
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 撤销输入对象
* @author widyhu
*
*/
class WxPayReverse extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信的订单号,优先使用
* @param string $value
**/
public function SetTransaction_id($value)
{
$this->values['transaction_id'] = $value;
}
/**
* 获取微信的订单号,优先使用的值
* @return 值
**/
public function GetTransaction_id()
{
return $this->values['transaction_id'];
}
/**
* 判断微信的订单号,优先使用是否存在
* @return true 或 false
**/
public function IsTransaction_idSet()
{
return array_key_exists('transaction_id', $this->values);
}
/**
* 设置商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号,transaction_id、out_trade_no二选一如果同时存在优先级transaction_id> out_trade_no是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 短链转换输入对象
* @author widyhu
*
*/
class WxPayShortUrl extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置需要转换的URL签名用原串传输需URL encode
* @param string $value
**/
public function SetLong_url($value)
{
$this->values['long_url'] = $value;
}
/**
* 获取需要转换的URL签名用原串传输需URL encode的值
* @return 值
**/
public function GetLong_url()
{
return $this->values['long_url'];
}
/**
* 判断需要转换的URL签名用原串传输需URL encode是否存在
* @return true 或 false
**/
public function IsLong_urlSet()
{
return array_key_exists('long_url', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
}

View File

@@ -0,0 +1,480 @@
<?php
namespace app\api\wxapi\pay;
use app\api\wxapi\pay\WxPayDataBase;
/**
*
* 统一下单输入对象
* @author widyhu
*
*/
class WxPayUnifiedOrder extends WxPayDataBase
{
/**
* 设置微信分配的公众账号ID
* @param string $value
**/
public function SetAppid($value)
{
$this->values['appid'] = $value;
}
/**
* 获取微信分配的公众账号ID的值
* @return 值
**/
public function GetAppid()
{
return $this->values['appid'];
}
/**
* 判断微信分配的公众账号ID是否存在
* @return true 或 false
**/
public function IsAppidSet()
{
return array_key_exists('appid', $this->values);
}
/**
* 设置微信支付分配的商户号
* @param string $value
**/
public function SetMch_id($value)
{
$this->values['mch_id'] = $value;
}
/**
* 获取微信支付分配的商户号的值
* @return 值
**/
public function GetMch_id()
{
return $this->values['mch_id'];
}
/**
* 判断微信支付分配的商户号是否存在
* @return true 或 false
**/
public function IsMch_idSet()
{
return array_key_exists('mch_id', $this->values);
}
/**
* 设置微信支付分配的终端设备号,商户自定义
* @param string $value
**/
public function SetDevice_info($value)
{
$this->values['device_info'] = $value;
}
/**
* 获取微信支付分配的终端设备号,商户自定义的值
* @return 值
**/
public function GetDevice_info()
{
return $this->values['device_info'];
}
/**
* 判断微信支付分配的终端设备号,商户自定义是否存在
* @return true 或 false
**/
public function IsDevice_infoSet()
{
return array_key_exists('device_info', $this->values);
}
/**
* 设置随机字符串不长于32位。推荐随机数生成算法
* @param string $value
**/
public function SetNonce_str($value)
{
$this->values['nonce_str'] = $value;
}
/**
* 获取随机字符串不长于32位。推荐随机数生成算法的值
* @return 值
**/
public function GetNonce_str()
{
return $this->values['nonce_str'];
}
/**
* 判断随机字符串不长于32位。推荐随机数生成算法是否存在
* @return true 或 false
**/
public function IsNonce_strSet()
{
return array_key_exists('nonce_str', $this->values);
}
/**
* 设置商品或支付单简要描述
* @param string $value
**/
public function SetBody($value)
{
$this->values['body'] = $value;
}
/**
* 获取商品或支付单简要描述的值
* @return 值
**/
public function GetBody()
{
return $this->values['body'];
}
/**
* 判断商品或支付单简要描述是否存在
* @return true 或 false
**/
public function IsBodySet()
{
return array_key_exists('body', $this->values);
}
/**
* 设置商品名称明细列表
* @param string $value
**/
public function SetDetail($value)
{
$this->values['detail'] = $value;
}
/**
* 获取商品名称明细列表的值
* @return 值
**/
public function GetDetail()
{
return $this->values['detail'];
}
/**
* 判断商品名称明细列表是否存在
* @return true 或 false
**/
public function IsDetailSet()
{
return array_key_exists('detail', $this->values);
}
/**
* 设置附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据
* @param string $value
**/
public function SetAttach($value)
{
$this->values['attach'] = $value;
}
/**
* 获取附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据的值
* @return 值
**/
public function GetAttach()
{
return $this->values['attach'];
}
/**
* 判断附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据是否存在
* @return true 或 false
**/
public function IsAttachSet()
{
return array_key_exists('attach', $this->values);
}
/**
* 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
* @param string $value
**/
public function SetOut_trade_no($value)
{
$this->values['out_trade_no'] = $value;
}
/**
* 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
* @return 值
**/
public function GetOut_trade_no()
{
return $this->values['out_trade_no'];
}
/**
* 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
* @return true 或 false
**/
public function IsOut_trade_noSet()
{
return array_key_exists('out_trade_no', $this->values);
}
/**
* 设置符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
* @param string $value
**/
public function SetFee_type($value)
{
$this->values['fee_type'] = $value;
}
/**
* 获取符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型的值
* @return 值
**/
public function GetFee_type()
{
return $this->values['fee_type'];
}
/**
* 判断符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型是否存在
* @return true 或 false
**/
public function IsFee_typeSet()
{
return array_key_exists('fee_type', $this->values);
}
/**
* 设置订单总金额,只能为整数,详见支付金额
* @param string $value
**/
public function SetTotal_fee($value)
{
$this->values['total_fee'] = $value;
}
/**
* 获取订单总金额,只能为整数,详见支付金额的值
* @return 值
**/
public function GetTotal_fee()
{
return $this->values['total_fee'];
}
/**
* 判断订单总金额,只能为整数,详见支付金额是否存在
* @return true 或 false
**/
public function IsTotal_feeSet()
{
return array_key_exists('total_fee', $this->values);
}
/**
* 设置APP和网页支付提交用户端ipNative支付填调用微信支付API的机器IP。
* @param string $value
**/
public function SetSpbill_create_ip($value)
{
$this->values['spbill_create_ip'] = $value;
}
/**
* 获取APP和网页支付提交用户端ipNative支付填调用微信支付API的机器IP。的值
* @return 值
**/
public function GetSpbill_create_ip()
{
return $this->values['spbill_create_ip'];
}
/**
* 判断APP和网页支付提交用户端ipNative支付填调用微信支付API的机器IP。是否存在
* @return true 或 false
**/
public function IsSpbill_create_ipSet()
{
return array_key_exists('spbill_create_ip', $this->values);
}
/**
* 设置订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
* @param string $value
**/
public function SetTime_start($value)
{
$this->values['time_start'] = $value;
}
/**
* 获取订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则的值
* @return 值
**/
public function GetTime_start()
{
return $this->values['time_start'];
}
/**
* 判断订单生成时间格式为yyyyMMddHHmmss如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则是否存在
* @return true 或 false
**/
public function IsTime_startSet()
{
return array_key_exists('time_start', $this->values);
}
/**
* 设置订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
* @param string $value
**/
public function SetTime_expire($value)
{
$this->values['time_expire'] = $value;
}
/**
* 获取订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则的值
* @return 值
**/
public function GetTime_expire()
{
return $this->values['time_expire'];
}
/**
* 判断订单失效时间格式为yyyyMMddHHmmss如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则是否存在
* @return true 或 false
**/
public function IsTime_expireSet()
{
return array_key_exists('time_expire', $this->values);
}
/**
* 设置商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
* @param string $value
**/
public function SetGoods_tag($value)
{
$this->values['goods_tag'] = $value;
}
/**
* 获取商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠的值
* @return 值
**/
public function GetGoods_tag()
{
return $this->values['goods_tag'];
}
/**
* 判断商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠是否存在
* @return true 或 false
**/
public function IsGoods_tagSet()
{
return array_key_exists('goods_tag', $this->values);
}
/**
* 设置接收微信支付异步通知回调地址
* @param string $value
**/
public function SetNotify_url($value)
{
$this->values['notify_url'] = $value;
}
/**
* 获取接收微信支付异步通知回调地址的值
* @return 值
**/
public function GetNotify_url()
{
return $this->values['notify_url'];
}
/**
* 判断接收微信支付异步通知回调地址是否存在
* @return true 或 false
**/
public function IsNotify_urlSet()
{
return array_key_exists('notify_url', $this->values);
}
/**
* 设置取值如下JSAPINATIVEAPP详细说明见参数规定
* @param string $value
**/
public function SetTrade_type($value)
{
$this->values['trade_type'] = $value;
}
/**
* 获取取值如下JSAPINATIVEAPP详细说明见参数规定的值
* @return 值
**/
public function GetTrade_type()
{
return $this->values['trade_type'];
}
/**
* 判断取值如下JSAPINATIVEAPP详细说明见参数规定是否存在
* @return true 或 false
**/
public function IsTrade_typeSet()
{
return array_key_exists('trade_type', $this->values);
}
/**
* 设置trade_type=NATIVE此参数必传。此id为二维码中包含的商品ID商户自行定义。
* @param string $value
**/
public function SetProduct_id($value)
{
$this->values['product_id'] = $value;
}
/**
* 获取trade_type=NATIVE此参数必传。此id为二维码中包含的商品ID商户自行定义。的值
* @return 值
**/
public function GetProduct_id()
{
return $this->values['product_id'];
}
/**
* 判断trade_type=NATIVE此参数必传。此id为二维码中包含的商品ID商户自行定义。是否存在
* @return true 或 false
**/
public function IsProduct_idSet()
{
return array_key_exists('product_id', $this->values);
}
/**
* 设置trade_type=JSAPI此参数必传用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。
* @param string $value
**/
public function SetOpenid($value)
{
$this->values['openid'] = $value;
}
/**
* 获取trade_type=JSAPI此参数必传用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 的值
* @return 值
**/
public function GetOpenid()
{
return $this->values['openid'];
}
/**
* 判断trade_type=JSAPI此参数必传用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 是否存在
* @return true 或 false
**/
public function IsOpenidSet()
{
return array_key_exists('openid', $this->values);
}
}

View File

@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIUSENKOxec1p5btJo5KfLwiQw/mBgwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMTkxMTA3MDYwOTMxWhcNMjQxMTA1MDYwOTMxWjCBgTETMBEGA1UEAwwK
MTM2OTc4OTUwMjEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL
DCTpg5Hlt57lhavop5Lkv6Hmga/mioDmnK/mnInpmZDlhazlj7gxCzAJBgNVBAYM
AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKJNUi/934sT4mk8RONHl+3aqLD3I6tvMjAbKMtQn5F3lssZ94GU9aEb
dtz9U92T6mx3v/d6bGQ6uRE4paf6BoitjmmYGaqDYtCYH3pt1jD86UJ0kl8t5eXd
FJNOp61p4YZHmG7Jph961tTy+jBaDTPrlEoyRkctp5o3EgNQhZ0FHyQ+cnVfRpM6
h85nfhR73u4OiM6bAuQ2X76dnr3nUULCpJSkp6OS7+CJqKJPu9UpxDhFLqkj0fJh
QLlA8Gmb3+KvV8VyrVx2h3AbZLT3yC+rD43cz2pLZMp+QAfYwmFuwpiLC75zMhnh
0iEbvmNRVuyPsjj8mbgUhOlC3Iwt3IMCAwEAAaOBgTB/MAkGA1UdEwQCMAAwCwYD
VR0PBAQDAgTwMGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0cnVzLmNv
bS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1
NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEAtyyUCHglHO0xOsaa
5UbZ7PE7ggZy/Dv6Q7lvSIxcXRimc9GrOHswb3s3/3yM5Zsi3O/Kr0PktmdPC3J6
UV3WPDlCYqsDTbFWn6U6lIf9kkRtV+4FA+Iz6MSPKWb7X9GuH3WM2o1LKrUW7dVj
HiJK1n3Qpfr7W/6tVhj42OiRNeKMYnnYkysiqFi8+B58NHZ2Gplq/HJ3O6qTmPSi
zzzoEs1tgaQfIHY4hqt2RZRTHtIv1fUfiRRL6emehqGy7jUfuE1LsDtVduVTl+gY
EjzEVHJS/r1NX95RWxX7oJk3uyFsPB9QurtgWRdZKWW6akmRXLFiSpPTYR35PLA1
rpd+8A==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCiTVIv/d+LE+Jp
PETjR5ft2qiw9yOrbzIwGyjLUJ+Rd5bLGfeBlPWhG3bc/VPdk+psd7/3emxkOrkR
OKWn+gaIrY5pmBmqg2LQmB96bdYw/OlCdJJfLeXl3RSTTqetaeGGR5huyaYfetbU
8vowWg0z65RKMkZHLaeaNxIDUIWdBR8kPnJ1X0aTOofOZ34Ue97uDojOmwLkNl++
nZ6951FCwqSUpKejku/giaiiT7vVKcQ4RS6pI9HyYUC5QPBpm9/ir1fFcq1cdodw
G2S098gvqw+N3M9qS2TKfkAH2MJhbsKYiwu+czIZ4dIhG75jUVbsj7I4/Jm4FITp
QtyMLdyDAgMBAAECggEAfpYF8y50KvowTdnW9NmDEt3HUnb/WBebMlAMij7wpbl7
YB95npS625QbKhNfVOOoJD9l9zSB087FRzxCX/gvHm0XNR6PbiGZcY4khw2h0IWB
vPZEr32R4K2E/buMJkH9xwiSSF54dfcOFfsIzat+vq8P8qqxi5R9M1eecf1cqPD2
twVuuulJELJ8tOsCthxvA8tM1fWq1OXTO2/251+ZRROL/CCwKY1ZuDtklq1qqFg/
HVxVcuN4tgfsk8bxG0tUQwZBg5UioUeFo6hZaFV6CscAbyo5DHvMkQtuowH0TdEo
y4J4ZgK0XJVoxTB0ApImkUJiB2g0w4bBQJHdOgR3uQKBgQDNLUzPpg90Edn8mXWG
9hc4NRSiYD8MP+6Ge/zjH6OLZtSD3MNkGNiTxVPL0tZR5i/B10ct9whYU6pUdf3Q
GvSLa7x8nBfIbvPylB29oLUt9GNDaPfl/GHu1s1r434ti1uwxcNbjYBbmZNHFHk+
ThuyNrRyPb8jHq5o22Z8I+DFjwKBgQDKgTuUeWtMSutAhVM1ZsmiHmhyC+xdPT3G
u7Kn6zhQznBPAbqrFm1lSeMn+El4+DuBd4Hgqpw7F/pJZNNJPng2xMFXWTilddh9
UHlprH0MMIHh/+O0KZG615GttgSIL7YDFy6o3yRrGLDhMHpoY224hrajQJQ7Qc0E
O6QqDstHzQKBgQDH5tbriTONNsdX4HwtXh8JWE4eVf+Xg8J1rN+aufyxmSJ8xt5n
6/03HA6ki2rcqJTnG0PyeLjctcdCOyNrWpfgLruZ/Mr/MXrkYYMIekeL2ovL5b2B
igAwn3/NGfyZiyludX/890ST+nEP09a86YT6gWoV1CshoIb1Cq4zTRF16QKBgHx7
IILOeJS3YRGSY2nqO3w6sP2aMrvGD5mAe/wY7c9Od185suPEr46Z8tb5G0EPZpTZ
P685cTwqKyK+pdraWc9g93CYWefsHx45P8kjzOKXVt/0CqcO/pQaO2TLBNIqcfpI
X9hTAvIKhYCH6lcM9798n/yOkBA1DK/TccCgw3jpAoGACZtTgpIS7LZ54YjsBFLE
A2Gp18IhxxZcHC29FU+huK0fkru0MfA4gtjMyRD+nfSdyWddZfvVKmDEL4bEEcQd
4PPKxP4u/ZYh+LTA//0rh2tD4rLXmhfQF28nXITZTHVSesZ8UhRSBSLDDN33dNkP
P0klmm9ka7IhM+RUk1A/2o0=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,126 @@
<?php
namespace app\api\wxapi\pay;
//以下为日志
interface ILogHandler
{
public function write($msg);
}
class CLogFileHandler implements ILogHandler
{
private $handle = null;
public function __construct($file = '')
{
$this->handle = fopen($file,'a');
}
public function write($msg)
{
fwrite($this->handle, $msg, 4096);
}
public function __destruct()
{
fclose($this->handle);
}
}
class Log
{
private $handler = null;
private $level = 15;
private static $instance = null;
private function __construct(){}
private function __clone(){}
public static function Init($handler = null,$level = 15)
{
if(!self::$instance instanceof self)
{
self::$instance = new self();
self::$instance->__setHandle($handler);
self::$instance->__setLevel($level);
}
return self::$instance;
}
private function __setHandle($handler){
$this->handler = $handler;
}
private function __setLevel($level)
{
$this->level = $level;
}
public static function DEBUG($msg)
{
self::$instance->write(1, $msg);
}
public static function WARN($msg)
{
self::$instance->write(4, $msg);
}
public static function ERROR($msg)
{
$debugInfo = debug_backtrace();
$stack = "[";
foreach($debugInfo as $key => $val){
if(array_key_exists("file", $val)){
$stack .= ",file:" . $val["file"];
}
if(array_key_exists("line", $val)){
$stack .= ",line:" . $val["line"];
}
if(array_key_exists("function", $val)){
$stack .= ",function:" . $val["function"];
}
}
$stack .= "]";
self::$instance->write(8, $stack . $msg);
}
public static function INFO($msg)
{
self::$instance->write(2, $msg);
}
private function getLevelStr($level)
{
switch ($level)
{
case 1:
return 'debug';
break;
case 2:
return 'info';
break;
case 4:
return 'warn';
break;
case 8:
return 'error';
break;
default:
}
}
protected function write($level,$msg)
{
if(($level & $this->level) == $level )
{
$msg = '['.date('Y-m-d H:i:s').']['.$this->getLevelStr($level).'] '.$msg."\n";
$this->handler->write($msg);
}
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace app\api\wxapi\post;
use app\api\wxapi\Base;
/* 生成带参数的二维码
* $QrcodeCreatePost=new QrcodeCreatePost();
* $QrcodeCreatePost->setAccessToken($AccessTokenRequest->access_token);
* $QrcodeCreatePost->setActionName(QrcodeCreatePost::ACTION_NAME_QR_SCENE);
* $QrcodeCreatePost->setExpireSeconds(60*60); //临时时间戳
* $QrcodeCreatePost->setSceneVal('123');
* $QrcodeCreatePost->run();
* $WxClient->setTypeCurl(WxClient::TYPE_CURL_POST);
* $QrcodeInfo=$WxClient->execute($QrcodeCreatePost);
* */
class QrcodeCreatePost extends Base
{
const ACTION_NAME_QR_SCENE='QR_SCENE'; //临时32位非0整型
const ACTION_NAME_QR_LIMIT_SCENE='QR_LIMIT_SCENE'; //永久最大值为1--100000
const ACTION_NAME_QR_LIMIT_STR_SCENE='QR_LIMIT_STR_SCENE'; //永久字符串长度限制为1到64
private $PostParas = array(); //post参数
private $GetParas = array(); //请求地址参数
private $access_token;
private $expire_seconds; //该二维码有效时间,以秒为单位。 最大不超过2592000即30天此字段如果不填则默认有效期为30秒。临时二维码参数
private $action_name; //ACTION_NAME_QR_SCENE(临时) ACTION_NAME_QR_LIMIT_SCENE(永久) ACTION_NAME_QR_LIMIT_STR_SCENE(永久字符串)
private $scene_val; //场景值
public function init(){
}
public function run(){
switch ($this->action_name) {
case self::ACTION_NAME_QR_LIMIT_STR_SCENE;
$this->PostParas["action_info"]['scene']['scene_str'] = $this->getSceneVal();
break;
default :
$this->PostParas["action_info"]['scene']['scene_id'] = $this->getSceneVal();
}
}
public function getApiMethodName(){
return "cgi-bin/qrcode/create";
}
public function getApiParas(){
return json_encode($this->PostParas);
}
public function getGetParas(){
return $this->GetParas;
}
public function putOtherTextParam($key, $value){
$this->PostParas[$key] = $value;
$this->$key = $value;
}
public function setExpireSeconds($expire_seconds){
$this->expire_seconds = $expire_seconds;
$this->PostParas["expire_seconds"] = $expire_seconds;
}
public function getExpireSeconds(){
return $this->expire_seconds;
}
public function setActionName($action_name){
$this->action_name = $action_name;
$this->PostParas["action_name"] = $action_name;
}
public function getActionName(){
return $this->action_name;
}
public function setSceneVal($scene_val){
$this->scene_val = $scene_val;
}
public function getSceneVal(){
return $this->scene_val;
}
public function setAccessToken($access_token){
$this->access_token = $access_token;
$this->GetParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->access_token;
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/*
* */
class AccessTokenCodeRequest extends Base
{
private $apiParas = array();
private $appid;
private $secret;
private $code;
public function init(){
$this->setAppId('');
$this->setSecret('');
$this->setCode('');
$this->apiParas['grant_type'] = 'authorization_code';
}
public function getApiMethodName(){
return "sns/oauth2/access_token";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAppId($appid){
$this->appid = $appid;
$this->apiParas["appid"] = $appid;
}
public function getAppId(){
return $this->appid;
}
public function setSecret($secret){
$this->secret = $secret;
$this->apiParas["secret"] = $secret;
}
public function getSecret(){
return $this->secret;
}
public function setCode($code){
$this->code = $code;
$this->apiParas["code"] = $code;
}
public function getCode(){
return $this->code;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 获取常规access_token
* $AccessTokenRequest=new AccessTokenRequest();
* $AccessTokenRequest->setAppId($WxClient->appID);
* $AccessTokenRequest->setSecret($WxClient->appsecret);
* $AccessTokenRequest=$WxClient->execute($AccessTokenRequest);
* */
class AccessTokenRequest extends Base
{
private $apiParas = array();
private $appid;
private $secret;
private $code;
public function init(){
$this->apiParas['grant_type'] = 'client_credential';
$this->setAppId('');
$this->setSecret('');
}
public function getApiMethodName(){
return "cgi-bin/token";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAppId($appid){
$this->appid = $appid;
$this->apiParas["appid"] = $appid;
}
public function getAppId(){
return $this->appid;
}
public function setSecret($secret){
$this->secret = $secret;
$this->apiParas["secret"] = $secret;
}
public function getSecret(){
return $this->secret;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 检验授权凭证access_token是否有效
* $AuthAccessTokenRequest = new AuthAccessTokenRequest();
* $AuthAccessTokenRequest->setAccessToken($resp->access_token);
* $AuthAccessTokenRequest->setOpenid($resp->openid);
* $AuthAccessTokenRequest=$WxClient->execute($AuthAccessTokenRequest);
* */
class AuthAccessTokenRequest extends Base
{
private $apiParas = array();
private $access_token;
private $openid;
public function init(){
$this->setAccessToken('');
$this->setOpenid('');
}
public function getApiMethodName(){
return "sns/auth";
}
public function getApiParas(){
return $this->apiParas;
}
public function setOpenid($openid){
$this->openid = $openid;
$this->apiParas["openid"] = $openid;
}
public function getOpenid(){
return $this->openid;
}
public function setAccessToken($access_token){
$this->access_token = $access_token;
$this->apiParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->access_token;
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* $req = new CodeRequest();
* $req->setAppId($WxClient->appID);
* $req->setServerUrl($WxClient->serverUrl);
* $req->setScope(self::STATE_SNSAPI_BASE);
* $url=$req->run();
* return $this->redirect($url);
* */
class CodeRequest extends Base
{
const STATE_SNSAPI_BASE='snsapi_base'; //不弹出授权页面直接跳转只能获取用户openid
const STATE_SNSAPI_USERINFO='snsapi_userinfo'; //弹出授权页面可通过openid拿到昵称、性别、所在地。并且即使在未关注的情况下只要用户授权也能获取其信息
private $serverUrl='https://open.weixin.qq.com/';
private $redirect_uri;
private $apiParas = array();
private $appid;
private $scope;
private $state;
public function init(){
$callback=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$this->setAppId('');
$this->setRredirectUri($callback);
$this->apiParas['response_type'] = 'code';
$this->setScope(self::STATE_SNSAPI_BASE);
$this->apiParas['state'] = time();
$this->apiParas['#'] = 'wechat_redirect';
}
public function run()
{
//获取业务参数
$apiParams = $this->getApiParas();
//系统参数放入GET请求串
$requestUrl = $this->serverUrl . $this->getApiMethodName() . "?";
foreach ($apiParams as $key => $value)
{
$requestUrl .= "$key=" . $value . "&";
}
return trim($requestUrl,"&");
}
public function getApiMethodName(){
return "connect/oauth2/authorize";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAppId($appid){
$this->appid = $appid;
$this->apiParas["appid"] = $appid;
}
public function getAppId(){
return $this->appid;
}
public function setRredirectUri($redirect_uri){
$redirect_uri = urlencode($redirect_uri);
$this->redirect_uri = $redirect_uri;
$this->apiParas["redirect_uri"] = $redirect_uri;
}
public function getRredirectUri(){
return $this->redirect_uri;
}
public function setScope($scope){
$this->scope = $scope;
$this->apiParas["scope"] = $scope;
}
public function getScope(){
return $this->scope;
}
public function setServerUrl($serverUrl){
$this->serverUrl = $serverUrl;
}
public function getServerUrl(){
return $this->serverUrl;
}
public function setState($state){
$this->state = $state;
$this->apiParas["state"] = $state;
}
public function getState(){
return $this->state;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/*
* */
class GetWechatCodeRequest extends Base
{
const SNSAPI_BASE="snsapi_base";
const SNSAPI_USERINFO="snsapi_userinfo";
private $apiParas = array();
private $appid;
private $redirect_uri;
private $scope;
private $state;
public function init(){
$this->setResponseType();
$this->setRedirectUri();
//$this->apiParas['#'] = 'wechat_redirect';
}
public function run(){
//获取业务参数
$apiParams = $this->getApiParas();
$arr['appid']=$apiParams['appid'];
$arr['redirect_uri']=$apiParams['redirect_uri'];
$arr['response_type']=$apiParams['response_type'];
$arr['scope']=$apiParams['scope'];
//系统参数放入GET请求串
$requestUrl =$this->getApiMethodName() . "?";
$str='';
foreach ($arr as $key=>$val){
$str.=$key.'='.$val.'&';
}
$str=rtrim($str,'&').'#wechat_redirect';
return $requestUrl.$str;
}
public function getApiMethodName(){
return "https://open.weixin.qq.com/connect/oauth2/authorize";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAppId($appid){
$this->appid = $appid;
$this->apiParas["appid"] = $appid;
}
public function getAppId(){
return $this->appid;
}
public function setRedirectUri(){
$this->redirect_uri=urlEncode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']);
$this->apiParas["redirect_uri"] = $this->redirect_uri;
}
public function setResponseType(){
$this->apiParas["response_type"] = 'code';
}
public function setScope($scope){
$this->scope = $scope;
$this->apiParas["scope"] = $scope;
}
public function getScope(){
return $this->scope;
}
public function setState($state){
$this->state = $state;
$this->apiParas["state"] = $state;
}
public function getState(){
return $this->state;
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 获取小程序码
* $GetWxAcodeUnLimitRequest=new GetWxAcodeUnLimitRequest();
* $GetWxAcodeUnLimitRequest->setAccessToken($AccessTokenRequest->access_token);
* $GetWxAcodeUnLimitRequest=$WxClient->execute($GetWxAcodeUnLimitRequest);
* */
class GetWxAcodeUnLimitRequest extends Base
{
private $apiParas = array();
private $access_token;
public function init(){
$this->setPage();
$this->setWidth();
$this->setAutoColor();
}
public function getApiMethodName(){
return "wxa/getwxacodeunlimit";
}
public function getApiParas(){
return $this->apiParas;
}
public function getGetParas(){
return $this->OtherData;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setScene($scene){
$this->apiParas["scene"] = $scene;
}
public function setPage($page=''){
$this->apiParas["page"] = $page;
}
public function setWidth($width=500){
$this->apiParas["width"] = $width;
}
public function setAutoColor($AutoColor=false){
$this->apiParas["auto_color"] = $AutoColor;
}
/* auto_color为false时生效{"r":0,"g":0,"b":0}
* */
public function setLineColor($LineColor=[]){
$this->apiParas["line_color"] = $LineColor;
}
/* 底色是否透明
* */
public function setIsHyaline($IsHyaline=false){
$this->apiParas["is_hyaline"] = $IsHyaline;
}
public function setAccessToken($access_token){
$this->access_token = $access_token;
$this->OtherData["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->access_token;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 获取小程序码
* $GetWxaCodeRequest=new GetWxaCodeRequest();
* $GetWxaCodeRequest->setAccessToken($AccessTokenRequest->access_token);
* $GetWxaCodeRequest=$WxClient->execute($GetWxaCodeRequest);
* */
class GetWxaCodeRequest extends Base
{
private $apiParas = array();
private $access_token;
public function init(){
$this->setWidth();
}
public function getApiMethodName(){
return "wxa/getwxacode";
}
public function getApiParas(){
return $this->apiParas;
}
public function getGetParas(){
return $this->OtherData;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setPath($path=''){
$this->apiParas["path"] = $path;
}
public function setWidth($width=430){
$this->apiParas["width"] = $width;
}
public function setAccessToken($access_token){
$this->access_token = $access_token;
$this->OtherData["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->access_token;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 刷新access_token如果需要
* $RefreshTokenRequest=new RefreshTokenRequest();
* $RefreshTokenRequest->setAppid($WxClient->appID);
* $RefreshTokenRequest->setRefreshToken($resp->refresh_token);
* $resp=$WxClient->execute($RefreshTokenRequest);
* */
class RefreshTokenRequest extends Base
{
private $apiParas = array();
private $refresh_token;
private $appid;
public function init(){
$this->setAppid('');
$this->apiParas["grant_type"] = 'refresh_token';
$this->setRefreshToken('');
}
public function getApiMethodName(){
return "sns/oauth2/refresh_token";
}
public function getApiParas(){
return $this->apiParas;
}
public function setAppid($appid){
$this->appid = $appid;
$this->apiParas["appid"] = $appid;
}
public function getAppid(){
return $this->appid;
}
public function setRefreshToken($refresh_token){
$this->refresh_token = $refresh_token;
$this->apiParas["refresh_token"] = $refresh_token;
}
public function getRefreshToken(){
return $this->refresh_token;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/*
* */
class TemplateSendRequest extends Base
{
private $apiParas = array();
private $getParas=[];
public function getApiMethodName(){
return "cgi-bin/message/template/send";
}
public function getApiParas(){
return $this->apiParas;
}
public function getGetParas(){
return $this->getParas;
}
public function setAccessToken($access_token){
$this->getParas["access_token"] = $access_token;
}
public function getAccessToken(){
return $this->getParas["access_token"];
}
public function setToUser($touser){
$this->apiParas["touser"] = $touser;
}
public function setTopColor($topcolor){
$this->apiParas["topcolor"] = $topcolor;
}
public function setTemplateId($template_id){
$this->apiParas["template_id"] = $template_id;
}
public function setUrl($url){
$this->apiParas["url"] = $url;
}
public function setData($data=[]){
$this->apiParas["data"] = $data;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 获取UnionID
* $UnionIDRequest=new UnionIDRequest();
* $UnionIDRequest->setAccessToken($WxClient->appID);
* $UnionIDRequest->setOpenid($WxClient->appsecret);
* $UnionIDRequestResult=$WxClient->execute($UnionIDRequest);
* */
class UnionIDRequest extends Base
{
private $apiParas = array();
public function init(){
$this->setAccessToken('');
$this->setOpenid('');
$this->setLang('');
}
public function getApiMethodName(){
return "cgi-bin/user/info";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->apiParas["access_token"] = $access_token;
}
public function setOpenid($openid){
$this->apiParas["openid"] = $openid;
}
public function setLang($lang='zh_CN'){
$this->apiParas["lang"] = $lang;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
class UserInfoQqAppRequest extends Base
{
private $apiParas = array();
public function init(){
$this->setFormat('json');
}
public function getApiMethodName(){
return "user/get_user_info";
}
public function getGetParas(){
return [];
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->apiParas["access_token"] = $access_token;
}
public function setOpenid($openid){
$this->apiParas["openid"] = $openid;
}
public function setAppid($appid){
$this->apiParas["oauth_consumer_key"] = $appid;
}
public function setFormat($format){
$this->apiParas["format"] = $format;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
/* 通过code取的AccessToken用来取用户openid和信息
* */
class UserInfoRequest extends Base
{
private $apiParas = array();
public function init(){
$this->setLang("zh_CN");
}
public function getApiMethodName(){
return "sns/userinfo";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->apiParas["access_token"] = $access_token;
}
public function setOpenid($openid){
$this->apiParas["openid"] = $openid;
}
public function setLang($lang){
$this->apiParas["lang"] = $lang;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace app\api\wxapi\request;
use app\api\wxapi\Base;
class UserInfoWeiboAppRequest extends Base
{
private $apiParas = array();
public function init(){
}
public function getApiMethodName(){
return "2/users/show.json";
}
public function getApiParas(){
return $this->apiParas;
}
public function putOtherTextParam($key, $value){
$this->apiParas[$key] = $value;
$this->$key = $value;
}
public function setAccessToken($access_token){
$this->apiParas["access_token"] = $access_token;
}
public function setUid($uid){
$this->apiParas["uid"] = $uid;
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace app\api\wxapi\wxmsg;
class Base
{
protected $OtherData=[];
public static function className()
{
return get_called_class();
}
public function __construct()
{
$this->init();
}
public function init()
{
}
public function __get($name){
$getter='get'.$name;
if(method_exists($this, $getter)){
return $this->$getter();
}else if(isset($this->OtherData[$name])){
return $this->OtherData[$name];
}
return '';
}
public function __set($name, $value){
$setter='set'.$name;
if(method_exists($this, $setter)){
$this->$setter($value);
}else{
$this->OtherData[$name]=$value;
}
}
protected function nonceStr($len)
{
$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
$arr=[];
for($i=0;$i<strlen($chars);$i++){
$arr[]=$chars{$i};
}
shuffle($arr);
$arr=array_chunk($arr,$len);
$arr=array_shift($arr);
$arr=strtoupper(implode("",$arr));
return $arr;
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
use think\Db;
class BaseObject extends Base{
public $token; //响应接收消息URL Token
public function run(){
$resq=$this->xmlToArray(file_get_contents("php://input"));
/*$xml='<xml><ToUserName><![CDATA[gh_9f61b83af9e8]]></ToUserName>
<FromUserName><![CDATA[oDXoW66sZbQwyYA2Rzpqd_ZA7cyI]]></FromUserName>
<CreateTime>1605773759</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[]]></EventKey>
</xml>';
$resq=json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);*/
foreach($resq as $key=>$val){
$this->$key=$val;
}
/*$TempDataLog=[];
$TempDataLog['event'] = $resq['Event'];
$TempDataLog['contents'] = json_encode($resq);
$TempDataLog['addtime'] = time();
Db::name('wx_temp_log')->insertGetId($TempDataLog);*/
//error_log(json_encode($resq), 3, 'sub.log');
return true;
}
public function CheckSignature(){
$sign=$_GET;
$arr['token']=$this->token;
$arr['timestamp']=$sign['timestamp'];
$arr['nonce']=$sign['nonce'];
asort($arr);
$sha1=sha1(implode('',$arr));
if($sha1==$sign['signature']){
return true;
}
return false;
}
public function xmlToArray($xml)
{
//error_log($xml, 3, 'xml.log');
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
public function ArrayToXml($arr){
$xml='<?xml version="1.0" encoding="UTF-8"?>';
$xml='<xml>';
$this->ToXml($arr,$xml);
$xml.='</xml>';
return $xml;
}
public function ToXml($data,&$xml){
foreach($data as $k=>$v){
if(is_array($v)){
$xml.=' <'.$k.'>';
$this->ToXml($v, $xml);
$xml.=' </'.$k.'>';
}else{
if(is_int($v)){
$xml.=' <'.$k.'>'.$v.'</'.$k.'>';
}else{
$xml.=' <'.$k.'><![CDATA['.$v.']]></'.$k.'>';
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\wxmsg\BaseObject;
use app\api\wxapi\wxmsg\Event;
use app\api\wxapi\wxmsg\ReceiveText;
class Client{
public $BaseObject;
public function run(){
switch($this->BaseObject->MsgType){
case 'event':
$Event=new Event();
$Event->BaseObject=$this->BaseObject;
$Event->run();
break;
default:
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\wxmsg\EventClick;
use think\Db;
/* 扫描带参数二维码事件
* */
class Event{
public $BaseObject;
public function run(){
switch($this->BaseObject->Event){
case 'CLICK': //点击菜单拉取消息时的事件推送
$EventClick=new EventClick();
$EventClick->BaseObject=$this->BaseObject;
$EventClick->run();
break;
case 'subscribe':
$Subscribe=new Subscribe();
$Subscribe->BaseObject=$this->BaseObject;
$Subscribe->run();
case 'SCAN':
$Subscribe=new Subscribe();
$Subscribe->BaseObject=$this->BaseObject;
$Subscribe->run();
default :
$TempDataLog=[];
$TempDataLog['event'] = $this->BaseObject->Event;
$TempDataLog['from_user_name'] = $this->BaseObject->FromUserName;
$content=json_decode(json_encode(simplexml_load_string(file_get_contents("php://input"), 'SimpleXMLElement', LIBXML_NOCDATA)), true);
$TempDataLog['contents'] = json_encode($content);
$TempDataLog['addtime'] = time();
Db::name('wx_temp_log')->insertGetId($TempDataLog);
}
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
use app\api\wxapi\wxmsg\Reply;
/* 点击菜单拉取消息时的事件推送
* */
class EventClick extends Base{
public $BaseObject;
public function run(){
$this->send();
}
//回复消息
public function send(){
$Reply=new Reply();
$Reply->BaseObject=$this->BaseObject;
$Reply->run();
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
use app\api\wxapi\wxmsg\Reply;
/* 接收text消息
* */
class ReceiveText extends Base{
public $BaseObject;
public function run(){
$this->send();
}
//回复消息
public function send(){
$Reply=new Reply();
$Reply->BaseObject=$this->BaseObject;
$Reply->run();
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
use app\api\wxapi\wxmsg\ReplyText;
/* 回复消息
* */
class Reply extends Base{
public $BaseObject;
public function run(){
$EventKey=$this->BaseObject->EventKey;
$data['ToUserName']=$this->BaseObject->FromUserName;
$data['FromUserName']=$this->BaseObject->ToUserName;
$data['CreateTime']=time();
switch($EventKey){
case 'click_tel': //回复文本消息
$data['MsgType']='text';
$data['Content']='4000500510';
break;
case 'click_down':
$data['MsgType']='text';
$data['Content']='即将上线';
break;
case 'click_pic':
$data['MsgType']='image';
$data['Image']=[
'MediaId'=>'',
];
break;
default :
exit('');
}
echo $this->BaseObject->ArrayToXml($data);
exit;
/*查SQL*/
/* $MsgType='';
if($ReplyTextCout=M("wx_reply_text")->where(['EventKey'=>$this->BaseObject->EventKey,])->count()){
$MsgType='text';
} */
/*查SQL*/
/* switch($MsgType){
case 'text': //回复文本消息
$ReplyText=new ReplyText();
$ReplyText->BaseObject=$this->BaseObject;
$ReplyText->send();
break;
default :
exit('');
} */
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
/* 回复文本消息
* */
class ReplyText extends Base{
public $BaseObject;
public function send(){
$EventKey=$this->BaseObject->EventKey; //事件KEY值与自定义菜单接口中KEY值对应
$ReplyTextModel=M("wx_reply_text")->where(['EventKey'=>$EventKey,])->order("id asc")->find();
$data['ToUserName']=$this->BaseObject->FromUserName;
$data['FromUserName']=$this->BaseObject->ToUserName;
$data['CreateTime']=time();
$data['MsgType']='text';
$str=$ReplyTextModel['Content'];
//$str="<a href='http://www.baidu.com/Wap/Shop/index.html?t={time()+60}'>登录入口,点击后失效</a><br>有效期至{date('Y-m-d H:i:s',time()+60)}";
preg_match_all("/{(.*)}/Ums",$str,$rel);
$rs=[];
foreach($rel[1] as $k=>$v){
$strs = '<?php return '.$v.'; ?>';
$rs[$k]=eval('?>'.$strs.'<?php;');
}
$Content=str_replace($rel[0],$rs,$str);
$Content=htmlspecialchars_decode($Content);
$Content=str_replace("<br>","\n",$Content);
$data['Content']=$Content;
echo $this->BaseObject->ArrayToXml($data);
}
}

View File

@@ -0,0 +1,154 @@
<?php
namespace app\api\wxapi\wxmsg;
use app\api\wxapi\Base;
use app\api\wxapi\request\UnionIDRequest;
use app\api\wxapi\WxClient;
use app\api\wxapi\pay\WxPayConfig;
use app\api\wxapi\request\AccessTokenRequest;
use think\Db;
use app\common\library\Auth;
/* 扫二维码
* */
class Subscribe extends Base{
public $BaseObject;
protected $auth = null;
public function run(){
/*查SQL*/
$FromUserNameOpenID=$this->BaseObject->FromUserName;
if($this->BaseObject->Event=='subscribe'){
$access_token_config=DB::name('config')->where(['name'=>'access_token',])->find();
$access_token=$access_token_config['value'];
$WxPayConfig = new WxPayConfig();
$WxClient =new WxClient();
$WxClient->appID=$WxPayConfig->GetAppId();
$WxClient->appsecret=$WxPayConfig->GetAppSecret();
if(time()>$access_token_config['ctime']){
$AccessTokenRequest=new AccessTokenRequest();
$AccessTokenRequest->setAppId($WxClient->appID);
$AccessTokenRequest->setSecret($WxClient->appsecret);
$WxClient->setTypeCurl(WxClient::TYPE_CURL_GET);
$AccessTokenRequest=$WxClient->execute($AccessTokenRequest);
$access_token=$AccessTokenRequest->access_token;
DB::name('config')->where(['name'=>'access_token',])->update(['value'=>$access_token,'ctime'=>time()+7200,]);
}
$UnionIDRequest=new UnionIDRequest();
$UnionIDRequest->setAccessToken($access_token);
$UnionIDRequest->setOpenid($FromUserNameOpenID);
$UnionIDRequestResult=$WxClient->execute($UnionIDRequest);
//echo $FromUserNameOpenID;
//print_r($UnionIDRequestResult);
$openid = $UnionIDRequestResult->openid;
$pass = '123456abc';
$nickname = $UnionIDRequestResult->nickname;
$sex = $UnionIDRequestResult->sex;
$headimgurl = $UnionIDRequestResult->headimgurl;
$wx_unionId=$UnionIDRequestResult->unionid;
$phone = time();
$birthday = date('Y-m-d',time());
$system = 'wx'; //系统,android或ios
$channel = 'wx'; //渠道
$this->auth = Auth::instance();
$user = DB::name('users')->field('id,wx_openid,wx_unionId,temp_wx_openid')->where('wx_unionId',$wx_unionId)->find();
if(isset($user['id'])){
if(!strlen($user['temp_wx_openid'])){
$up=[];
$up['temp_wx_openid']=$openid;
DB::name('users')->where('id',$user['id'])->update($up);
}
}else{
$ret = $this->auth->register($pass,$phone,$nickname,$sex,$headimgurl,$birthday,$system,$channel);
if ($ret){
$getUserinfo = $this->auth->getUserinfo();
$up=[];
$tag_id=0;
$users_tags=[];
if($sex==1){
$tag_id=1;
}
if($sex==2){
$tag_id=3;
}
if($tag_id){
$tagsInfo=DB::name('users_tags')->field('id,tag_name,tag_color,bg_color')->where(['id'=>$tag_id,])->find();
if(isset($tagsInfo['id'])){
$users_tags[]=$tagsInfo;
$users_tags=array_values($users_tags);
}
}
$up['users_tags']=json_encode($users_tags);
$up['wx_unionId']=$wx_unionId;
$up['phone']=$getUserinfo['id'];
DB::name('users')->where('id',$getUserinfo['id'])->update($up);
$img = $this->auth->setFilePath($headimgurl);
$res = $this->ryHand(1,$getUserinfo['id'],$getUserinfo['id'],$img);
if($res['code'] == 200){
DB::name('users')->where('id',$getUserinfo['id'])->update(['ry_uid'=>$res['userId'],'ry_token'=>$res['token'], ]);
}
}
}
}
}
protected function getConfig($name = null)
{
if (!$name) {
return '';
}
$val = DB::name('config')->where('name', $name)->where('status', 1)->value('value');
return $val;
}
//融云
protected function ryHand($type,$ry_uid,$nickname='',$headimg=''){
import('RongCloud/RongCloud', VENDOR_PATH);
$AppKey = $this->getConfig('ry_app_key');
$AppSecret = $this->getConfig('ry_app_secret');
$RongSDK = new \RongCloud\RongCloud($AppKey,$AppSecret);
$user = [
'id'=> $ry_uid,
'name'=> $nickname,//用户名称
'portrait'=> $headimg //用户头像
];
if($type == 1){
$res = $RongSDK->getUser()->register($user);
}elseif($type == 2){
$res = $RongSDK->getUser()->register($user);
}else{
return ['code'=>0,'info'=>'not found type'];
}
// $update = $RongSDK->getUser()->update($user);
// $res = $RongSDK->getUser()->MuteGroups()->getList(['test1']);
return $res;
}
}