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
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)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|