You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

405 lines
16 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Wechat_lib
{
protected $ci;
private $wechat_config;
private $wechat_host;
public function __construct()
{
$this->ci =& get_instance();
$this->ci->config->load("wechat", true);
}
public function response_to_wx($response_arr=null)
{
if ($response_arr===null) {
echo "";
}
$response_body = $this->to_xml($response_arr);
echo $response_body;
return false;
}
/**
* 转发到微信客服
* @param string $text
* @param string $to_user
* @param string $from_operator
*/
public function response_customer_service($text=null, $to_user=null, $from_operator=null)
{
$content_arr = $text===null ? null :
array(
"ToUserName" => $to_user,
"FromUserName" => $from_operator,
"CreateTime" => time(),
"MsgType" => "transfer_customer_service",
"Content" => $text
);
return $this->response_to_wx($content_arr);
}
public function response_text($text=null, $to_user=null, $from_operator=null)
{
$content_arr = $text===null ? null :
array(
"ToUserName" => $to_user,
"FromUserName" => $from_operator,
"CreateTime" => time(),
"MsgType" => "text",
"Content" => $text
);
return $this->response_to_wx($content_arr);
}
/**
* 开发者认证token
* @param array $input:微信的GET请求数据
*/
public function auth_signature($input, $token)
{
$s = $input["signature"];
$t = $input["timestamp"];
$n = $input["nonce"];
$e = $input["echostr"];
$tmpArr = array($t, $n, $token);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
// $ee = 'V3xwtddYXPES064KgVh0uxqfPVV2qDK1HvfX7PIRvxR';
ob_clean();
if( $s == $tmpStr ){
echo $e;
}else{
echo "";
}
return false;
}
public function call_wechat($wechat_host, $url, $get_data=array(), $post_data=null)
{
$this->wechat_host = $wechat_host;
$this->wechat_config = $this->ci->config->item($wechat_host, 'wechat');
if ( false === array_key_exists('code', $get_data)) {
$access_token = $this->get_access_token();
$get_data = array_merge($get_data, array("access_token" => $access_token) );
}
$url = $this->ci->config->item('url_domain', 'wechat') . $url . "?" . http_build_query($get_data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_URL, $url);
if ($post_data !== null) {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
}
$output = curl_exec($curl);
if (curl_errno($curl)) {
log_message('error', "curl error code: ".curl_error($curl)."; curl postBodyString: ".$post_data);
} else {
$httpStatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode) {
log_message('error', "Request html Status Code: ".$httpStatusCode."; curl postBodyString: ".$post_data);
}
$output_arr = json_decode($output, true);
if (false !== stripos($output, "errcode")
&& 0 !== intval($output_arr['errcode'])
) {
log_message('error','wechat reponse error:' . var_export($output, 1));
curl_close($curl);
return null;
}
}
curl_close($curl);
return $output;
}
private function get_access_token()
{
$url = $this->ci->config->item('url_domain', 'wechat') . "/cgi-bin/token?grant_type=client_credential&appid=" . $this->wechat_config['app_id'] . "&secret=" . $this->wechat_config['app_secret'];
$curl = curl_init();
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_URL, $url);
$output = curl_exec($curl);
if (curl_errno($curl)) {
log_message('error', "curl error code: ".curl_error($curl));
} else {
$httpStatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode) {
log_message('error', "Request html Status Code: ".$httpStatusCode);
}
$output_arr = json_decode($output, true);
if (false !== stripos($output, "errcode")
&& 0 !== intval($output_arr['errcode'])
) {
log_message('error','wechat reponse error:' . var_export($output, 1));
curl_close($curl);
return null;
}
}
curl_close($curl);
$access_token_arr = json_decode($output, true);
return $access_token_arr['access_token'];
}
/**
* 发送文本消息给已关注用户
* 当用户和公众号产生特定动作的交互时, 允许在48小时内调用此接口发送消息给用户
* 允许的<特定动作>
* * 用户发送信息
* * 点击自定义菜单仅有点击推事件、扫码推事件、扫码推事件且弹出“消息接收中”提示框这3种菜单类型是会触发客服接口的
* * 关注公众号
* * 扫描二维码
* * 支付成功
* * 用户维权
* @param [type] $wechat_host
* @param 用户openid $to_user
* @param 文本内容 $text
*/
public function send_text_customer($wechat_host, $to_user, $text)
{
$url = "/cgi-bin/message/custom/send";
$post = array(
"touser" => $to_user,
"msgtype" => "text",
"text" => array(
"content" => $text
)
);
return $this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
}
/**
* 已下单未支付
* @param [type] $wechat_host
* @param [type] $openid
* @param array $order
*/
public function push_book_ok($wechat_host, $openid, $order=array())
{
$this->ci->load->model('Wechat_service_model');
$url = "/cgi-bin/message/template/send";
$order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
$post = array(
"touser" => $openid,
"template_id" => 'eSnnOFczriQFJSPy4q7797iKi4HCh6im5vP8iLlIHAU',
"url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
"topcolor" => '#173177',
"data" => array(
"first" => array(
"value" => 'Thanks for booking with Trippest. Click to follow up the payment now.',
"color" => '#173177'
),
"OrderID" => array(
"value" => 'Booking Reference # ' . $order['orderTour'][0]['orderId'],
"color" => '#173177'
),
"PkgName" => array(
"value" => $order['orderTour'][0]['tourName'],
"color" => '#173177'
),
"TakeOffDate" => array(
"value" => 'Tour Date ' . date('M.d, Y', strtotime($order['orderTour'][0]['startDate'])),
"color" => '#173177'
),
"Remark" => array(
"value" => 'For more information…',
"color" => '#173177'
)
),
);
$this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
$push_arr = array(
"wp_wu_id" => $order['wechat']['wu_id'],
"wp_msgtype" => "template",
"wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
"wp_templateid" => $post['template_id'],
"wp_templatename" => "旅游订单待支付",
"wp_createtime" => date('Y-m-d H:i:s'),
"wp_wc_id" => $order['wechat']['wc_id']
);
$this->ci->Wechat_service_model->insert_wechat_push($push_arr);
return true;
}
/**
* 行程即将开始
* 导游司机等调度信息
* @param [type] $wechat_host
* @param [type] $openid
* @param array $order
*/
public function push_arrangement($wechat_host, $openid, $order=array())
{
$this->ci->load->model('Wechat_service_model');
$url = "/cgi-bin/message/template/send";
$order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
$post = array(
"touser" => $openid,
"template_id" => 'wqfkOjDe5VpJn1hYC2lhO3w2qQ96o-a1ylt0wl9-1JE',
"url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
"topcolor" => '#173177',
"data" => array(
"first" => array(
"value" => 'Booking Reference # ' . $order['orderTour'][0]['orderId'],
"color" => '#173177'
),
"keyword1" => array(
"value" => $order['orderTour'][0]['tourName'],
"color" => '#173177'
),
"keyword2" => array(
"value" => 'Start Date: ' . $order['orderTour'][0]['startDate'],
"color" => '#173177'
),
"remark" => array(
"value" => 'Tap this card to find more details.', // TODO: Guide:北京禹昭Helen, Mobile:15333241912
"color" => '#173177'
)
),
);
$this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
$push_arr = array(
"wp_wu_id" => $order['wechat']['wu_id'],
"wp_msgtype" => "template",
"wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
"wp_templateid" => $post['template_id'],
"wp_templatename" => "行程即将开始",
"wp_createtime" => date('Y-m-d H:i:s'),
"wp_wc_id" => $order['wechat']['wc_id']
);
$this->ci->Wechat_service_model->insert_wechat_push($push_arr);
return true;
}
public function push_wechat_paid($wechat_host, $payment=array(), $order=array() )
{
$this->ci->load->model('Wechat_service_model');
$url = "/cgi-bin/message/template/send";
$order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
bcscale(2);
$total_fee = bcdiv($payment['total_fee'], $this->ci->config->item('currency_unit', 'wechat'));
$post = array(
"touser" => $payment['openid'],
"template_id" => '2ar2YEdmcylhGJr2e6C9SLresnCWMLfDK8RPr2caj04',
"url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
"topcolor" => '#173177',
"data" => array(
"first" => array(
"value" => 'Payment successful and your booking is confirmed.',
"color" => '#173177'
),
"keyword1" => array(
"value" => $order['orderTour'][0]['leader'],
"color" => '#173177'
),
"keyword2" => array(
"value" => 'BR# ' . $order['orderTour'][0]['orderId'],
"color" => '#173177'
),
"keyword3" => array(
"value" => 'Total payment ' . $payment['fee_type'] . $total_fee,
"color" => '#173177'
),
"keyword4" => array(
"value" => $order['orderTour'][0]['tourName'],
"color" => '#173177'
),
"remark" => array(
"value" => 'Youll receive a notice about guides/driver info at the night before tour started.',
"color" => '#173177'
)
),
);
$this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
$push_arr = array(
"wp_wu_id" => $order['wechat']['wu_id'],
"wp_msgtype" => "template",
"wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
"wp_templateid" => $post['template_id'],
"wp_templatename" => "支付成功",
"wp_createtime" => date('Y-m-d H:i:s'),
"wp_wc_id" => $order['wechat']['wc_id']
);
$this->ci->Wechat_service_model->insert_wechat_push($push_arr);
return true;
}
/**
* 格式化参数格式化成url参数
*/
public function to_url_params($xml_arr)
{
$buff = "";
foreach ($xml_arr as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 输出xml字符
* @throws WxPayException
**/
function to_xml($arr)
{
if(!is_array($arr) || count($arr) <= 0)
{
return false;
}
$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;
}
/**
* 将xml转为array
* @param string $xml
* @throws WxPayException
*/
function from_xml($xml)
{
if(!$xml){
return false;
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
}
}
/* End of file Wechat_lib.php */