<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-5-20
 */


require_once dirname(__DIR__) . '/core/db/db.php';

$cfg = require dirname(__DIR__) . '/core/db/config.php';

function log_notify($msg, $data = []) {
    $log = date('Y-m-d H:i:s') . " [$msg] " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n";
    @file_put_contents(dirname(__DIR__) . '/data/logs/pay_notify.log', $log, FILE_APPEND);
}

// 确保日志目录存在
$log_dir = dirname(__DIR__) . '/data/logs';
if (!is_dir($log_dir)) {
    @mkdir($log_dir, 0777, true);
}

// ========== 微信支付V3回调 ==========
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_WECHATPAY_SERIAL'])) {
    $body = file_get_contents('php://input');
    log_notify('wechat_raw', ['body' => $body]);

    $headers = getallheaders();
    $timestamp = $headers['Wechatpay-Timestamp'] ?? '';
    $nonce = $headers['Wechatpay-Nonce'] ?? '';
    $signature = $headers['Wechatpay-Signature'] ?? '';

    if (empty($signature)) {
        echo 'FAIL';
        exit;
    }

    // 获取微信配置
    $wechat_cfg = [];
    $configs = $db->fetchAll("SELECT config_key, config_value FROM {$db->table('config')} WHERE config_group = 'payment'");
    foreach ($configs as $c) {
        $wechat_cfg[$c['config_key']] = $c['config_value'];
    }
    $apiv3_key = $wechat_cfg['wechat_apikey'] ?? '';

    if (empty($apiv3_key)) {
        log_notify('wechat_no_apiv3_key', []);
        echo 'FAIL';
        exit;
    }

    // 验证签名 - 使用APIv3密钥进行HMAC验证
    $sign_str = $timestamp . "\n" . $nonce . "\n" . $body . "\n";
    $calc_signature = base64_encode(hash_hmac('sha256', $sign_str, $apiv3_key, true));

    // 解密回调数据
    $resource = json_decode($body, true)['resource'] ?? null;
    if (!$resource) {
        log_notify('wechat_no_resource', []);
        echo 'FAIL';
        exit;
    }

    $ciphertext = base64_decode($resource['ciphertext']);
    $nonce_str = base64_decode($resource['nonce']);
    $associated_data = base64_decode($resource['associated_data']);

    // WeChatPay V3 GCM: auth_tag是16字节，在密文末尾
    $auth_tag = substr($ciphertext, -16);
    $ciphertext_data = substr($ciphertext, 0, -16);

    $plaintext = openssl_decrypt(
        $ciphertext_data,
        'aes-256-gcm',
        $apiv3_key,
        OPENSSL_RAW_DATA,
        $nonce_str,
        $auth_tag,
        $associated_data
    );

    if (!$plaintext) {
        log_notify('wechat_decrypt_fail', []);
        echo 'FAIL';
        exit;
    }

    $notify = json_decode($plaintext, true);
    log_notify('wechat_notify', $notify);

    $out_trade_no = $notify['out_trade_no'] ?? '';
    $trade_state = $notify['trade_state'] ?? '';
    $transaction_id = $notify['transaction_id'] ?? '';

    if ($trade_state === 'SUCCESS' && $out_trade_no) {
        // 更新支付订单
        $order = $db->fetch("SELECT * FROM {$db->table('pay_order')} WHERE order_sn = ? AND status = 0", [$out_trade_no]);
        if ($order) {
            $db->update('pay_order', [
                'status' => 1,
                'pay_type' => 1,
                'transaction_id' => $transaction_id,
                'pay_time' => time()
            ], 'order_sn = ?', [$out_trade_no]);

            log_notify('wechat_paid', ['order_no' => $out_trade_no, 'transaction_id' => $transaction_id]);
        }
    }

    echo 'SUCCESS';
    exit;
}

// ========== 支付宝回调 ==========
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['trade_status'])) {
    $post_data = $_POST;
    log_notify('alipay_raw', $post_data);

    $sign = $post_data['sign'] ?? '';
    $trade_status = $post_data['trade_status'] ?? '';
    $out_trade_no = $post_data['out_trade_no'] ?? '';
    $trade_no = $post_data['trade_no'] ?? '';

    // 获取支付宝配置
    $alipay_cfg = [];
    $configs = $db->fetchAll("SELECT config_key, config_value FROM {$db->table('config')} WHERE config_group = 'payment'");
    foreach ($configs as $c) {
        $alipay_cfg[$c['config_key']] = $c['config_value'];
    }
    $alipay_public_key = $alipay_cfg['alipay_public_key'] ?? '';

    if (empty($alipay_public_key)) {
        log_notify('alipay_no_pubkey', []);
        echo 'FAIL';
        exit;
    }

    // 验证签名
    ksort($post_data);
    $sign_data = [];
    foreach ($post_data as $k => $v) {
        if ($k !== 'sign' && $k !== 'sign_type' && $v !== '') {
            $sign_data[$k] = $v;
        }
    }
    $sign_str = urldecode(http_build_query($sign_data));

    $key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($alipay_public_key, 64, "\n") . "-----END PUBLIC KEY-----\n";
    $pubkey = openssl_pkey_get_public($key);
    $result = openssl_verify($sign_str, base64_decode($sign), $pubkey, OPENSSL_ALGO_SHA256);

    if ($result !== 1) {
        log_notify('alipay_sign_fail', ['sign' => $sign]);
        echo 'FAIL';
        exit;
    }

    // 处理支付成功
    if ($trade_status === 'TRADE_SUCCESS' || $trade_status === 'TRADE_FINISHED') {
        $order = $db->fetch("SELECT * FROM {$db->table('pay_order')} WHERE order_sn = ? AND status = 0", [$out_trade_no]);
        if ($order) {
            $db->update('pay_order', [
                'status' => 1,
                'pay_type' => 2,
                'transaction_id' => $trade_no,
                'pay_time' => time()
            ], 'order_sn = ?', [$out_trade_no]);

            log_notify('alipay_paid', ['order_no' => $out_trade_no, 'trade_no' => $trade_no]);
        }
    }

    echo 'success';
    exit;
}

// 默认
echo 'FAIL';
?>