This commit is contained in:
2025-05-08 01:46:38 -07:00
parent a08d512911
commit 3f639f35d1
4 changed files with 567 additions and 0 deletions

9
config.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
return array(
"api_url"=>"",//易支付地址
"api_pid"=>"",//易支付PID
"api_key"=>"",//易支付KEY
"goedge_api_url"=>"",//GoEdge系统API URL
"goedge_access_id"=>"",//GoEdge系统Access ID
"goedge_access_key"=>"",//GoEdge系统中Access KEY
);

225
notify.php Normal file
View File

@@ -0,0 +1,225 @@
<?php
// 包含配置文件
$config = include('config.php');
// 记录所有请求数据
$log_file = 'notify.log';
file_put_contents($log_file, date('Y-m-d H:i:s') . " 收到请求:\n", FILE_APPEND);
file_put_contents($log_file, "GET: " . json_encode($_GET) . "\n", FILE_APPEND);
file_put_contents($log_file, "POST: " . json_encode($_POST) . "\n", FILE_APPEND);
// 获取订单号
$out_trade_no = $_GET['out_trade_no'] ?? '';
if (empty($out_trade_no)) {
file_put_contents($log_file, "错误:缺少订单号\n", FILE_APPEND);
die("错误:无效的请求参数。");
}
try {
// 获取访问令牌
$token = getAccessToken();
if (!$token) {
file_put_contents($log_file, "错误:无法获取访问令牌\n", FILE_APPEND);
die("error");
}
// 先查询订单详情
$orderInfo = findOrder($out_trade_no, $token);
if (!$orderInfo) {
file_put_contents($log_file, "错误:无法找到订单 $out_trade_no\n", FILE_APPEND);
die("error");
}
// 记录订单详情
file_put_contents($log_file, "订单详情: " . json_encode($orderInfo) . "\n", FILE_APPEND);
// 尝试不同的参数组合完成订单
$result = false;
// 方法1使用orderCode参数
$result = finishOrder($out_trade_no, $token, ["orderCode" => $out_trade_no]);
if ($result) {
file_put_contents($log_file, "成功使用orderCode参数完成订单\n", FILE_APPEND);
echo "success";
exit;
}
// 方法2尝试使用orderId参数
if (isset($orderInfo['userOrder']['id'])) {
$result = finishOrder($out_trade_no, $token, ["orderId" => $orderInfo['userOrder']['id']]);
if ($result) {
file_put_contents($log_file, "成功使用orderId参数完成订单\n", FILE_APPEND);
echo "success";
exit;
}
}
// 方法3使用完整的订单数据
if (isset($orderInfo['userOrder'])) {
$orderData = $orderInfo['userOrder'];
$orderData['isFinished'] = true;
$result = finishOrder($out_trade_no, $token, $orderData);
if ($result) {
file_put_contents($log_file, "成功:使用完整订单数据完成订单\n", FILE_APPEND);
echo "success";
exit;
}
}
// 如果所有方法都失败尝试多种不同API路径
$apiPaths = [
"/UserOrderService/finishUserOrder",
"/UserOrderService/updateUserOrder",
"/UserOrderService/updateOrderFinished",
"/UserOrderService/payUserOrder"
];
foreach ($apiPaths as $apiPath) {
$result = callAPI($apiPath, ["orderCode" => $out_trade_no], $token);
file_put_contents($log_file, "尝试API $apiPath 结果: " . json_encode($result) . "\n", FILE_APPEND);
if ($result && isset($result['code']) && $result['code'] == 200) {
file_put_contents($log_file, "成功:使用 $apiPath 完成订单\n", FILE_APPEND);
echo "success";
exit;
}
}
// 如果前面的方法都失败,返回错误
file_put_contents($log_file, "错误:所有方法都无法完成订单\n", FILE_APPEND);
die("error");
} catch (Exception $e) {
file_put_contents($log_file, "异常:" . $e->getMessage() . "\n", FILE_APPEND);
die("error");
}
// 获取访问令牌
function getAccessToken() {
global $config, $log_file;
$api_url = $config['goedge_api_url'] . "/APIAccessTokenService/getAPIAccessToken";
$auth_data = [
"type" => "admin",
"accessKeyId" => $config['goedge_access_id'],
"accessKey" => $config['goedge_access_key']
];
file_put_contents($log_file, "请求访问令牌: " . $api_url . "\n", FILE_APPEND);
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($auth_data));
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$errno = curl_errno($ch);
curl_close($ch);
if ($errno) {
return false;
}
$result = json_decode($response, true);
if (!$result || !isset($result['data']['token'])) {
return false;
}
file_put_contents($log_file, "成功获取访问令牌\n", FILE_APPEND);
return $result['data']['token'];
}
// 查询订单
function findOrder($orderCode, $token) {
global $config, $log_file;
$api_url = $config['goedge_api_url'] . "/UserOrderService/findEnabledUserOrder";
$data = [
"code" => $orderCode
];
file_put_contents($log_file, "查询订单: " . $api_url . "\n", FILE_APPEND);
file_put_contents($log_file, "查询参数: " . json_encode($data) . "\n", FILE_APPEND);
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Edge-Access-Token: ' . $token
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$errno = curl_errno($ch);
curl_close($ch);
if ($errno) {
file_put_contents($log_file, "查询订单失败: cURL错误\n", FILE_APPEND);
return false;
}
file_put_contents($log_file, "查询订单响应: " . $response . "\n", FILE_APPEND);
$result = json_decode($response, true);
if (!$result || $result['code'] != 200 || !isset($result['data'])) {
file_put_contents($log_file, "查询订单失败: 无效响应\n", FILE_APPEND);
return false;
}
return $result['data'];
}
// 完成订单
function finishOrder($orderCode, $token, $data) {
global $config, $log_file;
$api_url = $config['goedge_api_url'] . "/UserOrderService/finishUserOrder";
file_put_contents($log_file, "完成订单: " . $api_url . "\n", FILE_APPEND);
file_put_contents($log_file, "订单数据: " . json_encode($data) . "\n", FILE_APPEND);
$result = callAPI($api_url, $data, $token);
if (!$result || !isset($result['code']) || $result['code'] != 200) {
file_put_contents($log_file, "完成订单失败: " . json_encode($result) . "\n", FILE_APPEND);
return false;
}
return true;
}
// 调用API
function callAPI($url, $data, $token) {
global $config, $log_file;
if (strpos($url, 'http') !== 0) {
$url = $config['goedge_api_url'] . $url;
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'X-Edge-Access-Token: ' . $token
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno) {
file_put_contents($log_file, "API调用失败: ($errno) $error\n", FILE_APPEND);
return false;
}
return json_decode($response, true);
}
?>

135
pay.php Normal file
View File

@@ -0,0 +1,135 @@
<?php
// 接收Goedge传递的参数
$config = include('config.php');
$orderMethod = $_GET['EdgeOrderMethod'] ?? '';
$orderCode = $_GET['EdgeOrderCode'] ?? '';
$orderAmount = $_GET['EdgeOrderAmount'] ?? '';
$orderTimestamp = $_GET['EdgeOrderTimestamp'] ?? '';
$orderSign = $_GET['EdgeOrderSign'] ?? '';
// 校验接收到的参数
if (empty($orderCode) || empty($orderAmount) || empty($orderSign)) {
die("Invalid request.");
}
auth();
// 验证签名逻辑可以根据需要进行添加
// 发起支付请求
callPaymentApi($orderCode, $orderAmount,$orderMethod);
function auth()
{
global $config,$orderCode;
$auth_info = [
"type"=> "admin",
"accessKeyId"=> $config['goedge_access_id'],
"accessKey"=> $config['goedge_access_key']
];
$access_token_json = sendPostJson($config['goedge_api_url']."/APIAccessTokenService/getAPIAccessToken",json_encode($auth_info,true),"none");
$access_token = json_decode($access_token_json,true);
$token = $access_token['data']['token'];
$code = [
"code"=>$orderCode,
];
$status = sendPostJson($config['goedge_api_url']."/UserOrderService/findEnabledUserOrder",json_encode($code,true),$token);
$status_decode = json_decode($status,true);
if ($status_decode['code'] != 200 or $status_decode['data']['userOrder']['code'] != $orderCode) {
exit("验证失败");
}
}
function callPaymentApi($orderCode, $orderAmount,$type) {
// 商户ID、密钥
global $config;
$merchant_id = $config['api_pid']; // 请替换为您的商户ID
$merchant_key = $config['api_key']; // 替换为真实密钥
// 支付接口URL
$api_url = $config['api_url']."/submit.php";
// 请求参数
$params = [
'pid' => $merchant_id,
'type' => $type, // 支付方式,您可以选择 'wxpay' 或其他方式
'out_trade_no' => $orderCode, // 商户订单号
'notify_url' => "https://gateway.tools.tf/api".'/notify.php', // 异步通知地址 请注意这里应该改为当前网站!!
'return_url' => "https://gateway.tools.tf/api".'/return.php', // 页面跳转通知地址 请注意这里应该改为当前网站!!
'name' => 'DokiDoki CDN', // 商品名称
'money' => $orderAmount, // 订单金额
'sign_type' => "MD5"
];
// 生成签名
$params['sign'] = generateSign($params, $merchant_key);
// 发起POST请求
$response = sendPostRequest($api_url, $params);
// 解析返回的JSON数据
$result = json_decode($response, true);
echo "<html><body onload='document.forms[0].submit()'>";
echo "<form action='{$api_url}' method='post'>";
foreach ($params as $key => $value) {
echo "<input type='hidden' name='{$key}' value='{$value}'>";
}
echo "</form></body></html>";
}
// 生成签名的函数
function generateSign($params, $key) {
// 1. 按照参数名的ASCII码排序
ksort($params);
// 2. 拼接成键值对的字符串
$signStr = '';
foreach ($params as $k => $v) {
if ($k != "sign" && $k != "sign_type" && $v != '') {
$signStr .= $k . '=' . $v . '&';
}
}
// 3. 将密钥拼接到字符串后
$signStr = substr($signStr,0,-1);
$signStr .= $key;
// 4. MD5加密并返回小写签名
return md5($signStr);
}
// 发送POST请求的函数
function sendPostRequest($url, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function sendPostJson($url, $json,$token) {
// 初始化cURL
$ch = curl_init($url);
// 设置cURL选项
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json', // 设置请求头为JSON
'Content-Length: ' . strlen($json), // 设置请求体长度
'X-Edge-Access-Token: ' . $token
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $json); // 传递JSON数据
// 执行请求并获取响应
$response = curl_exec($ch);
// 错误处理
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// 关闭cURL会话
curl_close($ch);
// 返回响应
return $response;
}
?>

198
return.php Normal file
View File

@@ -0,0 +1,198 @@
<?php
// 页面跳转通知处理
$config = include('config.php');
// 使用 $_GET 获取回调参数
$pid = $_GET['pid'] ?? '';
$trade_no = $_GET['trade_no'] ?? '';
$out_trade_no = $_GET['out_trade_no'] ?? '';
$type = $_GET['type'] ?? '';
$name = $_GET['name'] ?? '';
$money = $_GET['money'] ?? '';
$trade_status = $_GET['trade_status'] ?? '';
$sign_from_request = $_GET['sign'] ?? null;
$sign_type = $_GET['sign_type'] ?? 'MD5';
// 记录回调请求的参数,便于调试
error_log('Callback received: ' . json_encode($_GET));
// 验证签名
if (validateSign($_GET, $config['api_key'])) {
if ($trade_status == 'TRADE_SUCCESS') {
// 处理支付成功的逻辑
$api_response = set_order_success($out_trade_no);
$message = '支付成功';
$alert_class = 'alert-success';
$icon = 'fas fa-check-circle';
$additional_info = '感谢您的支付!您的订单已成功处理。';
$button_text = '返回主页';
$button_link = '/';
} else {
// 支付失败或状态异常
$message = '支付失败';
$alert_class = 'alert-danger';
$icon = 'fas fa-exclamation-circle';
$additional_info = '您的订单号:' . htmlspecialchars($out_trade_no) . '<br>支付过程中出现了问题,请发送工单联系管理员处理。';
$button_text = '联系管理员';
$button_link = 'mailto:pghkipy@gmail.com';
}
} else {
// 签名验证失败
$message = '签名无效';
$alert_class = 'alert-danger';
$icon = 'fas fa-exclamation-circle';
$additional_info = '签名验证失败,请联系管理员。';
$button_text = '联系管理员';
$button_link = 'mailto:pghkipy@gmail.com';
}
// HTML 页面开始
?>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>支付结果 - DokiDoki CDN 心跳网络</title>
<!-- Bootstrap v4.6 CSS -->
<link rel="stylesheet" href="https://www.dnm.ink/www/assets/bootstrap.min.css" crossorigin="anonymous">
<!-- Font Awesome for icons -->
<link rel="stylesheet" href="https://www.dnm.ink/www/assets/fontawesome-free-5.15.4-web/css/all.min.css"/>
<link rel="shortcut icon" href="https://www.dnm.ink/www/images/icon.png"/>
<style>
body {
background: linear-gradient(180deg, #f0e7ff 0%, #e6d9ff 100%);
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
color: #333;
line-height: 1.6;
transition: background 0.3s ease;
}
.container {
padding-top: 50px;
text-align: center;
}
.card {
border: none;
border-radius: 15px;
box-shadow: 0 6px 25px rgba(0, 0, 0, 0.05);
background: linear-gradient(145deg, #fff, #f8f9ff);
margin: 0 auto;
max-width: 500px;
padding: 20px;
}
.btn-primary {
background: linear-gradient(135deg, #3176d6, #5b95e8);
border: none;
border-radius: 30px;
padding: 12px 35px;
font-weight: 600;
box-shadow: 0 4px 15px rgba(49, 118, 214, 0.2);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn-primary:hover {
background: linear-gradient(135deg, #255ca3, #4b7bc8);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(49, 118, 214, 0.3);
}
.alert {
border-radius: 15px;
font-size: 1.1rem;
padding: 20px;
}
.alert-success {
background: linear-gradient(145deg, #d4edda, #c3e6cb);
color: #155724;
}
.alert-danger {
background: linear-gradient(145deg, #f8d7da, #f5c6cb);
color: #721c24;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="alert <?php echo $alert_class; ?>" role="alert">
<i class="<?php echo $icon; ?> mr-2"></i> <?php echo $message; ?>
</div>
<p class="text-muted"><?php echo $additional_info; ?></p>
<a href="<?php echo $button_link; ?>" class="btn btn-primary mt-3"><?php echo $button_text; ?></a>
</div>
</div>
<!-- Bootstrap JS and dependencies -->
<script src="https://www.dnm.ink/www/assets/jquery.slim.min.js" crossorigin="anonymous"></script>
<script src="https://www.dnm.ink/www/assets/popper.min.js" crossorigin="anonymous"></script>
<script src="https://www.dnm.ink/www/assets/bootstrap.min.js" crossorigin="anonymous"></script>
</body>
</html>
<?php
// 结束 PHP 代码
// 以下是辅助函数
function validateSign($received_params, $api_key) {
$original_sign = $received_params['sign'] ?? null;
if ($original_sign === null) {
error_log('签名验证失败URL中缺少 "sign" 参数。');
return false;
}
$calculated_sign = generateSign($received_params, $api_key);
if ($calculated_sign === $original_sign) {
return true;
} else {
error_log('签名验证失败:计算签名与原始签名不匹配。');
return false;
}
}
function generateSign($params, $key) {
ksort($params);
$signStr = '';
foreach ($params as $k => $v) {
if ($k != "sign" && $k != "sign_type" && $v !== '' && $v !== null) {
$signStr .= $k . '=' . $v . '&';
}
}
$signStr = rtrim($signStr, '&');
$signStr .= $key;
return md5($signStr);
}
function set_order_success($order_no){
global $config;
$auth_info = [
"type"=> "admin",
"accessKeyId"=> $config['goedge_access_id'],
"accessKey"=> $config['goedge_access_key']
];
$access_token_json = sendPostJson($config['goedge_api_url']."/APIAccessTokenService/getAPIAccessToken",json_encode($auth_info,true),"none");
$access_token_obj = json_decode($access_token_json,true);
if (isset($access_token_obj['data']['token'])) {
$token = $access_token_obj['data']['token'];
$code = ["code"=>$order_no];
$finish_order = sendPostJson($config['goedge_api_url']."/UserOrderService/finishUserOrder",json_encode($code,true),$token);
return $finish_order;
} else {
error_log("获取 access token 失败: " . $access_token_json);
return "获取 access token 失败: " . $access_token_json;
}
}
function sendPostJson($url, $json_data, $token) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($json_data),
'X-Edge-Access-Token: ' . $token
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
$response = curl_exec($ch);
if (curl_errno($ch)) {
error_log('cURL Error in sendPostJson to ' . $url . ': ' . curl_error($ch));
return "cURL Error: " . curl_error($ch);
}
curl_close($ch);
return $response;
}
?>