添加后台代理代码

This commit is contained in:
2026-03-15 01:27:05 +08:00
parent 11f9ac4dc1
commit ea08c9366a
5254 changed files with 721042 additions and 0 deletions

View File

@@ -0,0 +1,494 @@
<?php
/**
* Created by PhpStorm.
* User: abcdefg
* Date: 2017/10/10
* Time: 11:00
*/
require_once dirname(dirname(__DIR__)) . '/common/ErrorType.php';
require_once dirname(dirname(__DIR__)) . '/common/common.inc.php';
require_once dirname(dirname(__DIR__)) . '/common/BaseMethodHelper.php';
///require_once dirname(dirname(__DIR__)) . '/third/wxpay/lib/wxpay.data.php';
/**
* 数据对象基础类,该类中定义数据类最基本的行为,包括:
* 计算/设置/获取签名、输出xml格式的参数、从xml读取数据对象等
*/
class WechatBaseData
{
protected $Values = array();
protected $SignKey = '';
/**
* 设置签名,详见签名生成算法
* @param mixed $Parameters
* @return string
**/
public function SetSign($Parameters = null)
{
if (is_null($Parameters))
$Parameters = $this->Values;
$Sign = $this->MakeSign($Parameters);
$this->Values['sign'] = $Sign;
return $Sign;
}
/**
* 获取签名,详见签名生成算法的值
* @return mixed
**/
public function GetSign()
{
return $this->Values['sign'];
}
/**
* 判断签名,详见签名生成算法是否存在
* @return bool
**/
public function IsSignSet()
{
return array_key_exists('sign', $this->Values);
}
/**
* 输出xml字符
* @param mixed $Parameters
* @return string
**/
public function ToXml($Parameters = null)
{
if (is_null($Parameters))
$Parameters = $this->Values;
if (is_object($Parameters))
$Parameters = (array)$Parameters;
elseif (!is_array($Parameters))
return '<xml></xml>';
$Result = '';
foreach ($Parameters as $Key => $Value)
{
if (is_numeric($Value))
$Result .= "<{$Key}>{$Value}</{$Key}>";
elseif (is_object($Value) || is_array($Value))
$Result .= "<{$Key}>" . $this->ToXml($Value) . "</{$Key}>";
else
$Result .= "<{$Key}><![CDATA[{$Value}]]></{$Key}>";
}
return "<xml>{$Result}</xml>";
}
/**
* 将xml转为array
* @param string $Parameters
* @return mixed
*/
public function FromXml($Parameters)
{
if (!$Parameters)
return null;
/// 将XML转为array
/// 禁止引用外部xml实体
libxml_disable_entity_loader(true);
$this->Values = json_decode(json_encode(simplexml_load_string($Parameters, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->Values;
}
/**
* 格式化参数格式化成url参数
* @param mixed $Parameters
* @return string;
*/
public function ToUrlParams($Parameters = null)
{
if (is_null($Parameters))
$Parameters = $this->Values;
if (empty($Parameters))
return '';
if (is_object($Parameters))
$Parameters = (array)$Parameters;
elseif (!is_array($Parameters))
return $Parameters;
$Result = '';
foreach ($Parameters as $Key => $Value)
{
if (is_object($Value) || is_array($Value))
$Result .= $Key . '=' . $this->ToUrlParams($Value) . '&';
elseif (strcasecmp($Key, 'sign') != 0 && strcasecmp($Value, '') != 0)
$Result .= "{$Key}={$Value}&";
}
return trim($Result, '&');
}
/**
* 生成签名
* @param mixed $Parameters
* @return string 签名本函数不覆盖sign成员变量如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign($Parameters = null)
{
if (is_null($Parameters))
$Parameters = $this->Values;
if (is_object($Parameters))
$Parameters = (array)$Parameters;
elseif (!is_array($Parameters))
return strtoupper(md5("{$Parameters}&key={$this->SignKey}"));
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->ToUrlParams($Parameters);
//签名步骤二在string后加入KEY
$String = "{$String}&key={$this->SignKey}";
//签名步骤三MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$Result = strtoupper($String);
return $Result;
}
/**
* 获取设置的值
*/
public function GetValues()
{
return $this->Values;
}
public function GetSignKey()
{
return $this->SignKey;
}
public function SetSignKey($SignKey)
{
$this->SignKey = $SignKey;
}
}
/// 红包数据对象
class RedPackData extends WechatBaseData
{
public $RequestUrl = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'; /// 请求URL
/*
nonce_str随机字符串不长于32位
sign签名详见签名生成算法
mch_billno商户订单号每个订单号必须唯一。取值范围0~9a~zA~Z接口根据商户订单号支持重入如出现超时可再调用。
mch_id微信支付分配的商户号
wxappid微信分配的公众账号ID企业号corpid即为此appId。接口传入的所有appid应该为公众号的appid在mp.weixin.qq.com申请的不能为APP的appid在open.weixin.qq.com申请的
send_name红包发送者名称
re_openid接受红包的用户用户在wxappid下的openid
total_amount付款金额单位分
total_num红包发放总人数
wishing红包祝福语
client_ip调用接口的机器Ip地址
act_name活动名称
remark备注信息
scene_id场景id发放红包使用场景红包金额大于200时必传PRODUCT_1:商品促销、PRODUCT_2:抽奖、PRODUCT_3:虚拟物品兑奖、PRODUCT_4:企业内部福利、PRODUCT_5:渠道分润、PRODUCT_6:保险回馈、PRODUCT_7:彩票派奖、PRODUCT_8:税务刮奖)
risk_info活动信息posttime:用户操作的时间戳mobile:业务系统账号的手机号,国家代码-手机号。不需要+号deviceid :mac 地址或者设备唯一标识clientversion :用户操作的客户端版本把值为非空的信息用key=value进行拼接再进行urlencodeurlencode(posttime=xx& mobile =xx&deviceid=xx)
consume_mch_id资金授权商户号服务商替特约商户发放时使用
*/
protected function SetValue($Key, $Value)
{
$this->Values[$Key] = $Value;
}
/// 微信分配的公众账号ID企业号corpid即为此appId。接口传入的所有appid应该为公众号的appid在mp.weixin.qq.com申请的不能为APP的appid在open.weixin.qq.com申请的
public function SetAppId($app_id)
{
$this->SetValue('wxappid', $app_id);
}
/// 微信支付分配的商户号
public function SetMchId($mch_id)
{
$this->SetValue('mch_id', $mch_id);
}
/// 商户订单号每个订单号必须唯一。取值范围0~9a~zA~Z接口根据商户订单号支持重入如出现超时可再调用。
public function SetMchBillNo($mch_billno)
{
$this->SetValue('mch_billno', $mch_billno);
}
/// 红包发送者名称
public function SetSendName($send_name)
{
$this->SetValue('send_name', $send_name);
}
/// 接受红包的用户用户在wxappid下的openid
public function SetOpenId($open_id)
{
$this->SetValue('re_openid', $open_id);
}
/// 付款金额,单位分
public function SetAmount($amount)
{
$this->SetValue('total_amount', $amount);
}
/// 红包发放总人数
public function SetNumber($number)
{
$this->SetValue('total_num', $number);
}
/// 红包祝福语
public function SetWishing($wishing)
{
$this->SetValue('wishing', $wishing);
}
/// 调用接口的机器Ip地址
public function SetClientIp($client_ip)
{
$this->SetValue('client_ip', $client_ip);
}
/// 活动名称
public function SetActiveName($act_name)
{
$this->SetValue('act_name', $act_name);
}
/// 备注信息
public function SetRemark($remark)
{
$this->SetValue('remark', $remark);
}
/// 场景id发放红包使用场景红包金额大于200时必传PRODUCT_1:商品促销、PRODUCT_2:抽奖、PRODUCT_3:虚拟物品兑奖、PRODUCT_4:企业内部福利、PRODUCT_5:渠道分润、PRODUCT_6:保险回馈、PRODUCT_7:彩票派奖、PRODUCT_8:税务刮奖)
public function SetSceneId($scene_id)
{
$this->SetValue('scene_id', $scene_id);
}
/// 活动信息posttime:用户操作的时间戳mobile:业务系统账号的手机号,国家代码-手机号。不需要+号deviceid :mac 地址或者设备唯一标识clientversion :用户操作的客户端版本把值为非空的信息用key=value进行拼接再进行urlencodeurlencode(posttime=xx& mobile =xx&deviceid=xx)
public function SetRiskInfo($risk_info)
{
if (is_object($risk_info))
$risk_info = (array)$risk_info;
elseif(!is_array($risk_info))
$this->SetValue('risk_info', $risk_info);
$risk_info = urlencode("posttime={$risk_info['posttime']}&mobile={$risk_info['mobile']}&deviceid={$risk_info['deviceid']}&clientversion={$risk_info['clientversion']}");
$this->SetValue('risk_info', $risk_info);
}
/// 资金授权商户号,服务商替特约商户发放时使用
public function SetConsumeMchId($consume_mch_id)
{
$this->SetValue('consume_mch_id', $consume_mch_id);
}
/// 随机字符串不长于32位
public function SetNonceString($nonce_str)
{
$this->SetValue('nonce_str', $nonce_str);
}
}
class wechat extends BaseMethod
{
/**
* @var RedPackData
*/
private $RedPackData;
/**
* @var int
*/
private $RequestErrorCode;
/**
* 公钥
*/
private $PublicKey = '/cert/0000000000/apiclient_cert.pem';
/**
* 私钥
*/
private $PrivateKey = '/cert/0000000000/apiclient_key.pem';
/**
* ca证书
*/
private $RootCA = '/cert/0000000000/rootca.pem';
/**
* wechat constructor.
*/
public function __construct()
{
/// todo:
parent::__construct();
$this->PublicKey = __DIR__ . '/cert/1399351902/apiclient_cert.pem';
$this->PrivateKey = __DIR__ . '/cert/1399351902/apiclient_key.pem';
$this->RootCA = __DIR__ . '/cert/1399351902/rootca.pem';
$this->RedPackData = new RedPackData();
/// 初始化红包设置信息
//$this->RedPackData->SetSignKey('0t3xm3w1foyhcmhlux31mwrmybqh4cgd'); /// 支付key
//$this->RedPackData->SetAppId('wxb534983dcd6d77c6'); /// 公众账号appid
//$this->RedPackData->SetMchId('1345625501'); /// 商户号
$this->RedPackData->SetSignKey('YSWDSJ20160620201606202016062020'); /// 支付key
$this->RedPackData->SetAppId('wxfd77eb9fb989e822'); /// 公众账号appid
$this->RedPackData->SetMchId('1399351902'); /// 商户号
$this->RedPackData->SetMchBillNo(''); /// 商户订单号
$this->RedPackData->SetActiveName('test'); /// 活动名称
$this->RedPackData->SetSendName('友乐互动游戏'); /// 商户名称
$this->RedPackData->SetOpenId(''); /// 接受红包的用户用户在wxappid下的openid
$this->RedPackData->SetAmount(100); /// 付款金额,单位分
$this->RedPackData->SetNumber(1); /// 发送红包总人数
$this->RedPackData->SetWishing('test'); /// 红包祝福语
$this->RedPackData->SetRemark('test'); /// 备注信息
$this->RedPackData->SetNonceString($this->create_nonce_str(32)); /// 随机字符串不长于32位
$this->RedPackData->SetClientIp($_SERVER['SERVER_ADDR']); /// 客户端ip
}
/**
* 产生随机字符串不长于32位
* @param int $length
* @return string 产生的随机字符串
*/
public static function create_nonce_str($length = 32)
{
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$str = '';
for ($i = 0; $i < $length; $i++)
{
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* @param string $Url 连接地址
* @param string $Data 发送的数据
* @param int $Second
* @param array $Header
* @return bool|mixed
*/
private function curl_post_ssl($Url, $Data, $Second = 30, $Header = array())
{
$ch = curl_init();
/// 超时时间
curl_setopt($ch, CURLOPT_TIMEOUT, $Second);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
/// 这里设置代理,如果有的话
/// curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
/// curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
/// 以下两种方式需选择一种
/// 第一种方法cert 与 key 分别属于两个.pem文件
/// 默认格式为PEM可以注释
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
//curl_setopt($ch, CURLOPT_SSLCERT, getcwd() . $this->PublicKey);
curl_setopt($ch, CURLOPT_SSLCERT, $this->PublicKey);
/// 默认格式为PEM可以注释
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
//curl_setopt($ch, CURLOPT_SSLKEY, getcwd() . $this->PrivateKey);
curl_setopt($ch, CURLOPT_SSLKEY, $this->PrivateKey);
/// ca证书
curl_setopt($ch, CURLOPT_CAINFO, $this->RootCA);
/// 第二种方式,两个文件合成一个.pem文件
///curl_setopt($ch, CURLOPT_SSLCERT, getcwd() . '/all.pem');
if (count($Header) >= 1)
curl_setopt($ch, CURLOPT_HTTPHEADER, $Header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $Data);
$Result = curl_exec($ch);
if ($Result)
{
$this->RequestErrorCode = 0;
curl_close($ch);
return $Result;
}
else
{
$this->RequestErrorCode = curl_errno($ch);
//echo "call faild, errorCode: {$this->RequestErrorCode}\n\n\n\n";
curl_close($ch);
return null;
}
}
/**
* 被请求方法示例参数固定为RequestParameter和ReturnParameter对象返回值固定为true(成功)和false(失败)
* @param RequestParameter $Request
* @param ReturnParameter $Return
* @return bool
*/
public function SendRedPack($Request, &$Return)
{
///https://proxytest.tscce.cn/api/Index.php?method=pay.wechat.SendRedPack&format=json&charset=utf-8&timestamp=1&version=1.0&biz_content={"act_name":"活动名称","open_id":"ogLT2v3XvvB1aphibzHyL8On4_sk","fee":"100","wishing":"红包祝福语","remark":"备注信息"}&user_auth_token=xxxxxxxx
$bill_no = date('YmdHis') . rand(1000, 9999); /// 订单号
$act_name = @$Request->biz_content['act_name']; /// 活动名称
$open_id = @$Request->biz_content['open_id']; /// 接受红包的用户用户在wxappid下的openid /// ogLT2v3XvvB1aphibzHyL8On4_sk
$fee = @$Request->biz_content['fee']; /// 付款金额,单位分
$wishing = @$Request->biz_content['wishing']; /// 红包祝福语
$remark = @$Request->biz_content['remark']; /// 备注信息
$this->RedPackData->SetMchBillNo($bill_no);
$this->RedPackData->SetActiveName($act_name);
$this->RedPackData->SetOpenId($open_id);
$this->RedPackData->SetAmount($fee);
$this->RedPackData->SetWishing($wishing);
$this->RedPackData->SetRemark($remark);
$this->RedPackData->SetSign(); /// 签名
/// 发送数据
$xml = $this->curl_post_ssl($this->RedPackData->RequestUrl, $this->RedPackData->ToXml());
if (empty($xml))
{
$Return->SetErrors(ERRORCODE_WECHATERROR, "curl call faild! error code: {$this->RequestErrorCode}");
return false;
}
$res = (array)simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
if (empty($res))
{
$Return->SetErrors(ERRORCODE_WECHATERROR, $xml);
return false;
}
if (strcasecmp('success', $res['return_code']) != 0)
{
$Return->SetErrors(ERRORCODE_WECHATERROR, $res['return_msg']);
return false;
}
if (strcasecmp('success', $res['result_code']) != 0)
{
$Return->SetErrors(ERRORCODE_WECHATERROR, $res['err_code_des']);
return false;
}
return true;
}
}