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

554 lines
21 KiB

<?php
defined('BASE_PATH') or exit('No direct script access allowed');
session_start();
class wxpay
{
private $parameters; // cft 参数
private $payment; // 配置信息
/**
* 对openid加密的算法
*/
public function encrypt($plaintext)
{
$length = mb_strlen($plaintext);
$ciphertext = '';
for ($i = 0; $i < $length; $i += 2) {
$ciphertext .= mb_substr($plaintext, $i + 1, 1) . mb_substr($plaintext, $i, 1);
}
return $ciphertext;
}
/**
* 对openid解密的算法
*/
public function decrypt($ciphertext)
{
$length = mb_strlen($ciphertext);
$plaintext = '';
for ($i = 0; $i < $length; $i += 2) {
$plaintext .= mb_substr($ciphertext, $i + 1, 1) . mb_substr($ciphertext, $i, 1);
}
return $plaintext;
}
/**
* 递归include文件
*/
public function includeDirectory($directory)
{
if ($handle = opendir($directory)) {
while (($file = readdir($handle)) !== false) {
if ($file != '.' && $file != '..') {
$filePath = $directory . '/' . $file;
if (is_dir($filePath)) {
$this->includeDirectory($filePath); // 递归调用,处理子目录
} elseif (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
include_once $filePath;
echo $filePath . '\n\r';
}
}
}
closedir($handle);
}
}
/**
* 生成支付代码
* @param array $order 订单信息
* @param array $payment 支付方式信息
*/
public function get_code($order, $payment)
{
include_once(BASE_PATH . 'helpers/payment_helper.php');
// 配置参数
$this->payment = $payment;
// 网页授权获取用户openid
// if (!isset($_SESSION['openid']) || empty($_SESSION['openid'])) {
// $button = '<a class="box-flex btn-submit" type="button" onclick="">微信支付</a>';
// return $button;
// 应该重新发起授权登录
// require_once("../connect/wechat.php");
// return wxchat::redirect("shop/mobile");
// $_SESSION['openid'] = 'sdf4asgdf2ag1';
// return false;
// $openid = $this->get_openid();
// 将当前页面url保存到$_SESSION中,供其他页面跳转
// $url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// $_SESSION['prev_url'] = $url;
// header('Location: https://shop.heavenk.com/mobile/blank.php');
// exit; // 终止当前脚本的执行,确保页面跳转生效
// $_SESSION['openid'] = $openid;
// $_SESSION['openid'] = 'oCTanxBeiVFWIekJT_GiPZM2UiGY'; //sc_test l or I
// }
// $_SESSION['openid'] = 'oCTanxBeiVFWIekJT_GiPZM2UiGY';
// echo "openid: \r\n";
// var_dump($_SESSION['openid']);
// 访问大连支付接口
// $url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// var_dump($url);
// $_SESSION['prev_url'] = $url;
// var_dump($_SESSION['prev_url']);
// header('Location: https://shop.heavenk.com/mobile/source/helpers/dalianpay/demo/pay.php?openid=' .
// $this->encrypt($_SESSION['openid']) .
// '&reqsn=' . $order['order_sn'] .
// '&trxamt=' . $order_amount
// );
// // header('Location: https://www.baidu.com');
// exit; // 终止当前脚本的执行,确保页面跳转生效
// echo "Hi there........\r\n";
// echo BASE_PATH . "\n\r";
// echo $_SESSION['openid'] . "\n\r";
// echo $order['order_sn'] . "\n\r";
// echo $order_amount . "\n\r";
// $directory = BASE_PATH . '../plugins/payment'; // /data/www/wwwroot/dcs1.3/mobile/source/
// $files = scandir($directory);
// // 遍历文件列表并打印文件名
// foreach ($files as $file) {
// // 排除当前目录(.)和上级目录(..)
// if ($file != '.' && $file != '..') {
// echo $file . "<br>";
// }
// }
// echo "123546579\r\n";
$order_amount = $order['order_amount'] * 100;
// 调用大连支付接口
require_once(BASE_PATH . 'helpers/dalianpay/demo/dalianpay.php');
$new_plugin = new dalianpay();
$response_data = $new_plugin->pay($this->encrypt($_SESSION['openid']), $order['order_sn'], $order_amount);
// 获取微信支付需要的其他参数
$payinfo = $response_data['payinfo'];
$payinfo = json_decode($payinfo, true);
// var_dump($response_data);
$appId = $payinfo['appId'];
$timeStamp = $payinfo['timeStamp'];
$nonceStr = $payinfo['nonceStr'];
$signType = $payinfo['signType'];
$paySign = $payinfo['paySign'];
// ....实现自己的$this->getPrepayId()
// 获取prepay_id 和其他必要参数
$package = $payinfo['package'];
$map = [];
parse_str($package, $map);
$prepay_id = $map['prepay_id'];
// var_dump($prepay_id);
// echo "payinfo: " . $payinfo;
// echo "\r\n payinfo: \r\n";
// var_dump($payinfo);
// var_dump($package);
// echo "1234";
// 处理dalianpay统一支付接口传回的参数
// $_SESSION['response_data_json']
// 设置必填参数
// 根目录url
$order_amount = $order['order_amount'] * 100;
$this->setParameter("openid", "$_SESSION[openid]"); // 用户openid
$this->setParameter("body", $order['order_sn']); // 商品描述
$this->setParameter("out_trade_no", $order['order_sn'] . $order_amount . 'O' . $order['log_id']); // 商户订单号
$this->setParameter("total_fee", $order_amount); // 总金额
$this->setParameter("notify_url", __URL__ . 'wxpay.php'); // 通知地址 待修改
$this->setParameter("trade_type", "JSAPI"); // 交易类型
// 从大连支付接口返回的参数
$this->parameters["appid"] = $payinfo['appId']; // 公众账号ID
// 调用秘钥里的配置文件
if (!isset($_SESSION['org_num'])) {
echo "org_num is not set!\r\n";
}
$org_num = $_SESSION['org_num'];
// echo "\r\n" . $org_num . "\r\n";
unset($_SESSION['org_num']);
// echo "\r\n" . $org_num . "\r\n";
$this->parameters["mch_id"] = $org_num; // 商户号 sc_test
// $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR']; // 终端ip
$this->parameters["nonce_str"] = $payinfo['nonceStr']; // 随机字符串
$this->parameters["sign"] = $payinfo['paySign']; // 签名
// $prepay_id = $this->getPrepayId(); // 要通过大连支付接口获取到
// $jsApiParameters = $this->getParameters($prepay_id);
// 准备支付参数
// echo "\r\n appId: \r\n";
// var_dump($appId);
// echo "\r\n";
$total_fee = $order_amount;
$jsApiParameters = array(
'appId' => $appId,
'timeStamp' => $timeStamp,
'nonceStr' => $nonceStr,
'package' => $package,
'signType' => $signType,
'paySign' => $paySign,
// 'total_fee' => $total_fee.'',
);
// var_dump($paySign);
// echo "\r\n ";
// var_dump($signType);
// echo "\r\n";
// var_dump($package);
$jsApiParameters = json_encode($jsApiParameters);
// 接收回调front_url参数
$front_url = $_SESSION['front_url'];
// var_dump($front_url);
$jsApiParameterss=urlencode($jsApiParameters);
// location.href="' . return_url(basename(__FILE__, '.php')) . '"
// wxjsbridge
$js = '
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
<script language="javascript">
function jsApiCall(){
WeixinJSBridge.invoke("getBrandWCPayRequest",
' . $jsApiParameters . ',
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok")
{
location.href="' . $front_url . '"
}else
{
// 支付失败或取消支付的逻辑
}
}
)
};
function callpay()
{
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
wx.miniProgram.getEnv((res)=>{
if (res.miniprogram) {
// 在微信小程序中打开
wx.miniProgram.navigateTo({url: \'/pages/pay/pay?paydata='.$jsApiParameterss.'\'});
}else{
//false代表在公众号里
if (typeof WeixinJSBridge == "undefined")
{
if( document.addEventListener )
{
document.addEventListener("WeixinJSBridgeReady", jsApiCall, false);
}else if (document.attachEvent)
{
document.attachEvent("WeixinJSBridgeReady", jsApiCall);
document.attachEvent("onWeixinJSBridgeReady", jsApiCall);
}
}else
{
jsApiCall();
}
}
})
}
}
</script>';
// window.location.href = "{U(\'flow/index/done\')}";
$button = '<a class="box-flex btn-submit" type="button" onclick="callpay()">微信支付</a>' . $js;
// $button = '<a class="box-flex btn-submit" type="button" onclick="">微信支付(测试)</a>';
return $button;
}
/**
* 同步通知
* @param $data
* @return mixed
*/
public function callback($data)
{
return true;
}
/**
* 异步通知
* @param $data
* @return mixed
*/
public function notify($data)
{
include_once(BASE_PATH . 'helpers/payment_helper.php');
if (!empty($data['postStr'])) {
$payment = get_payment($data['code']);
$postdata = json_decode(json_encode(simplexml_load_string($data['postStr'], 'SimpleXMLElement', LIBXML_NOCDATA)), true);
/* 检查插件文件是否存在,如果存在则验证支付是否成功,否则则返回失败信息 */
// 微信端签名
$wxsign = $postdata['sign'];
unset($postdata['sign']);
foreach ($postdata as $k => $v) {
$Parameters[$k] = $v;
}
// 签名步骤一:按字典序排序参数
ksort($Parameters);
$buff = "";
foreach ($Parameters as $k => $v) {
$buff .= $k . "=" . $v . "&";
}
$String;
if (strlen($buff) > 0) {
$String = substr($buff, 0, strlen($buff) - 1);
}
// 签名步骤二:在string后加入KEY
$String = $String . "&key=" . $payment['wxpay_key'];
// 签名步骤三:MD5加密
$String = md5($String);
// 签名步骤四:所有字符转为大写
$sign = strtoupper($String);
// 验证成功
if ($wxsign == $sign) {
// 交易成功
if ($postdata['result_code'] == 'SUCCESS') {
// 获取log_id
$out_trade_no = explode('O', $postdata['out_trade_no']);
$order_sn = $out_trade_no[1]; // 订单号log_id
// 改变订单状态
order_paid($order_sn, 2);
// 修改订单信息(openid,tranid)
model()->table('pay_log')
->data(array('openid' => $postdata['openid'], 'transid' => $postdata['transaction_id']))
->where(array('log_id' => $order_sn))
->update();
/*if(method_exists('WechatController', 'do_oauth')){
// 如果需要,微信通知 wanglu
$order_id = model('Base')->model->table('order_info')
->field('order_id')
->where('order_sn = "' . $out_trade_no[0] . '"')
->getOne();
$order_url = __HOST__ . url('user/order_detail', array(
'order_id' => $order_id
));
$order_url = urlencode(base64_encode($order_url));
send_wechat_message('pay_remind', '', $out_trade_no[0] . ' 订单已支付', $order_url, $out_trade_no[0]);
}*/
}
$returndata['return_code'] = 'SUCCESS';
} else {
$returndata['return_code'] = 'FAIL';
$returndata['return_msg'] = '签名失败';
}
} else {
$returndata['return_code'] = 'FAIL';
$returndata['return_msg'] = '无数据返回';
}
// 数组转化为xml
$xml = "<xml>";
foreach ($returndata as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
$xml .= "</xml>";
echo $xml;
exit();
}
function trimString($value)
{
$ret = null;
if (null != $value) {
$ret = $value;
if (strlen($ret) == 0) {
$ret = null;
}
}
return $ret;
}
/**
* 作用:产生随机字符串,不长于32位
*/
public function createNoncestr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 作用:设置请求参数
*/
function setParameter($parameter, $parameterValue)
{
$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}
/**
* 作用:生成签名
*/
public function getSign($Obj)
{
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
// 签名步骤一:按字典序排序参数
ksort($Parameters);
$buff = "";
foreach ($Parameters as $k => $v) {
$buff .= $k . "=" . $v . "&";
}
$String = "";
if (strlen($buff) > 0) {
$String = substr($buff, 0, strlen($buff) - 1);
}
// echo '【string1】'.$String.'</br>';
// 签名步骤二:在string后加入KEY
$String = $String . "&key=" . $this->payment['wxpay_key'];
// echo "【string2】".$String."</br>";
// 签名步骤三:MD5加密
$String = md5($String);
// echo "【string3】 ".$String."</br>";
// 签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
// echo "【result】 ".$result_."</br>";
return $result_;
}
/**
* 作用:以post方式提交xml到对应的接口url
*/
public function postXmlCurl($xml, $url, $second = 30)
{
// 初始化curl
$ch = curl_init();
// 设置超时
curl_setopt($ch, CURLOP_TIMEOUT, $second);
// 这里设置代理,如果有的话
// curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
// 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);
// 设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
// 要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
// post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
// 运行curl
$data = curl_exec($ch);
curl_close($ch);
// 返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "curl出错,错误码:$error" . "<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($ch);
return false;
}
}
/**
* 获取prepay_id
*/
function getPrepayId()
{
// 设置接口链接
// $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$url = "https://epay.dalianpay.cn/payapi/unitorder/pay";
try {
// 检测必填参数
if ($this->parameters["out_trade_no"] == null) {
throw new Exception("缺少统一支付接口必填参数out_trade_no!" . "<br>");
} elseif ($this->parameters["body"] == null) {
throw new Exception("缺少统一支付接口必填参数body!" . "<br>");
} elseif ($this->parameters["total_fee"] == null) {
throw new Exception("缺少统一支付接口必填参数total_fee!" . "<br>");
} elseif ($this->parameters["notify_url"] == null) {
throw new Exception("缺少统一支付接口必填参数notify_url!" . "<br>");
} elseif ($this->parameters["trade_type"] == null) {
throw new Exception("缺少统一支付接口必填参数trade_type!" . "<br>");
} elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL) {
throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "<br>");
}
$this->parameters["appid"] = $this->payment['wxpay_appid']; // 公众账号ID
$this->parameters["mch_id"] = $this->payment['wxpay_mchid']; // 商户号
$this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR']; // 终端ip
$this->parameters["nonce_str"] = $this->createNoncestr(); // 随机字符串
$this->parameters["sign"] = $this->getSign($this->parameters); // 签名
$xml = "<xml>";
foreach ($this->parameters as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
} catch (Exception $e) {
die($e->getMessage());
}
// $response = $this->postXmlCurl($xml, $url, 30);
$response = \libraries\Http::curlPost($url, $xml, 30);
$result = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
$prepay_id = $result["prepay_id"];
return $prepay_id;
}
/**
* 作用:设置jsapi的参数
*/
public function getParameters($prepay_id)
{
$jsApiObj["appId"] = $this->payment['wxpay_appid'];
$timeStamp = time();
$jsApiObj["timeStamp"] = "$timeStamp";
$jsApiObj["nonceStr"] = $this->createNoncestr();
$jsApiObj["package"] = "prepay_id=$prepay_id";
$jsApiObj["signType"] = "RSA";
$jsApiObj["paySign"] = $this->getSign($jsApiObj);
$this->parameters = json_encode($jsApiObj);
return $this->parameters;
}
/**
* 订单查询
* @return mixed
*/
public function query($order, $payment)
{
}
}