<?php
/**
 * USDT支付网关 PHP SDK
 * 
 * @version 3.2.0
 * @author USDT Payment Team
 * 
 * 接口说明:
 * - /api/address/create  动态生成收款地址（支持多币种）
 * - /api/pay/create      创建支付订单
 * - /api/pay/query       查询订单状态
 *
 * 支持币种:
 * - USDT-TRC20  (TRON网络USDT)
 * - USDC-TRC20  (TRON网络USDC)
 * - ETH         (以太坊)
 * - USDT-ERC20  (ERC20 USDT)
 * - USDC-ERC20  (ERC20 USDC)
 * - BTC         (比特币)
 * - BSC         (币安链)
 * - USDT-BEP20  (BEP20 USDT)
 * - USDC-BEP20  (BEP20 USDC)
 * - POLYGON     (Polygon网络)
 * - USDT-POLYGON(Polygon USDT)
 * - USDC-POLYGON(Polygon USDC)
 */

class UsdtPaySDK {
    
    private $baseUrl;
    private $merchantNo;
    private $apiKey;
    private $apiSecret;
    
    /**
     * 构造函数
     * 
     * @param string $baseUrl    网关地址，如 https://xxxx.com
     * @param string $merchantNo 商户编号
     * @param string $apiKey     API Key
     * @param string $apiSecret  API Secret
     */
    public function __construct($baseUrl, $merchantNo, $apiKey, $apiSecret) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->merchantNo = $merchantNo;
        $this->apiKey = $apiKey;
        $this->apiSecret = $apiSecret;
    }
    
    /**
     * 动态生成收款地址
     * 
     * @param string $label    自定义标识（重要！建议传用户ID/订单号，充值回调时会原样返回）
     * @param string $coinType 币种类型: USDT-TRC20, ETH, USDT-ERC20, BTC, BSC, USDT-BEP20, POLYGON, USDT-POLYGON
     * @return array
     */
    public function createAddress($label = '', $coinType = 'USDT-TRC20') {
        $params = [
            'merchantNo' => $this->merchantNo,
            'timestamp' => $this->getTimestamp(),
        ];
        
        if (!empty($label)) {
            $params['label'] = $label;
        }
        if (!empty($coinType)) {
            $params['coinType'] = $coinType;
        }
        
        $params['sign'] = $this->generateSign($params);
        
        return $this->request('/api/address/create', $params);
    }
    
    /**
     * 创建支付订单
     * 
     * @param string $payAddress       收款地址（通过createAddress获取）
     * @param string $productName      商品名称
     * @param string $productDescription 商品描述（可选）
     * @return array
     */
    public function createOrder($payAddress, $productName, $productDescription = '') {
        $params = [
            'merchantNo' => $this->merchantNo,
            'payAddress' => $payAddress,
            'productName' => $productName,
            'timestamp' => $this->getTimestamp(),
        ];
        
        if (!empty($productDescription)) {
            $params['productDescription'] = $productDescription;
        }
        
        $params['sign'] = $this->generateSign($params);
        
        return $this->request('/api/pay/create', $params);
    }
    
    /**
     * 查询订单状态
     * 
     * @param string $orderNo 订单号
     * @return array
     */
    public function queryOrder($orderNo) {
        $params = [
            'merchantNo' => $this->merchantNo,
            'orderNo' => $orderNo,
            'timestamp' => $this->getTimestamp(),
        ];
        
        $params['sign'] = $this->generateSign($params);
        
        return $this->request('/api/pay/query', $params);
    }
    
    /**
     * 验证回调签名
     * 
     * @param array $data 回调数据
     * @return bool
     */
    public function verifyCallback($data) {
        if (!isset($data['sign'])) {
            return false;
        }
        
        $sign = $data['sign'];
        unset($data['sign']);
        
        $expectedSign = $this->generateSign($data);
        
        return hash_equals(strtolower($expectedSign), strtolower($sign));
    }
    
    /**
     * 生成签名
     * 签名算法: SHA256(参数按键名排序拼接 + key=apiSecret)
     * 拼接格式: key1=value1&key2=value2&...&key=apiSecret
     * 
     * @param array $params 参数
     * @return string
     */
    private function generateSign($params) {
        // 按键名排序
        ksort($params);
        
        // 拼接参数
        $signStr = '';
        foreach ($params as $key => $value) {
            if ($value !== '' && $value !== null) {
                $signStr .= $key . '=' . $value . '&';
            }
        }
        
        // 追加密钥
        $signStr .= 'key=' . $this->apiSecret;
        
        // SHA256加密
        return hash('sha256', $signStr);
    }
    
    /**
     * 发送HTTP请求
     */
    private function request($path, $params) {
        $url = $this->baseUrl . $path;
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'X-API-KEY: ' . $this->apiKey,
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            return ['code' => -1, 'message' => 'CURL_ERROR: ' . $error];
        }
        
        $result = json_decode($response, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            return ['code' => -1, 'message' => 'JSON_DECODE_ERROR', 'raw' => $response];
        }
        
        return $result;
    }
    
    /**
     * 获取当前时间戳（毫秒）
     */
    private function getTimestamp() {
        return intval(microtime(true) * 1000);
    }
}

// ==================== 使用示例 ====================

/*
// 初始化SDK
$sdk = new UsdtPaySDK(
    'https://xxxx.com',  // 网关地址
    'M203254xxxx1709440',         // 商户编号
    'AK_xxxxxxxx',                  // API Key
    'AS_xxxxxxxx'                   // API Secret
);

// 1. 动态生成收款地址（默认USDT-TRC20）
$userId = '10086';  // 你系统中的用户ID
$result = $sdk->createAddress($userId);
print_r($result);

// 1.1 生成ETH地址
$result = $sdk->createAddress($userId, 'ETH');

// 1.2 生成USDT-ERC20地址
$result = $sdk->createAddress($userId, 'USDT-ERC20');

// 1.3 生成BTC地址
$result = $sdk->createAddress($userId, 'BTC');

// 1.4 生成BSC/BEP20 USDT地址
$result = $sdk->createAddress($userId, 'USDT-BEP20');

// 成功响应:
// {
//     "code": 200,
//     "data": {
//         "address": "T9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//         "coinType": "USDT-TRC20",
//         "label": "用户充值-订单123"
//     }
// }

// 获取地址
$payAddress = $result['data']['address'];

// 2. 创建支付订单
$result = $sdk->createOrder(
    $payAddress,                    // 收款地址
    '购买VIP会员',                   // 商品名称
    '购买1个月VIP会员服务'            // 商品描述
);
print_r($result);

// 3. 查询订单状态
$result = $sdk->queryOrder('P2032545595611709440');
print_r($result);
// status: 0=待支付, 1=已支付, 2=支付失败, 3=已取消

// 4. 验证回调（在回调接口中使用）
$callbackData = json_decode(file_get_contents('php://input'), true);
if ($sdk->verifyCallback($callbackData)) {
    // 签名验证通过，处理业务逻辑
    $orderNo = $callbackData['orderNo'];
    $status = $callbackData['status'];
    
    // 更新本地订单状态...
    
    echo 'success';
} else {
    echo 'sign error';
}
*/

/*
===================== 完整对接流程 =====================

1. 从商户后台获取凭证：
   - 商户编号 (merchantNo)
   - API Key
   - API Secret
   - 配置回调地址 (callbackUrl)

2. 用户发起充值时：
   a) 调用 createAddress($userId) 动态生成收款地址
      - label参数传用户ID，回调时会原样返回
   b) 展示收款地址给用户进行转账

3. 用户转账后：
   - 系统自动检测链上交易（约30秒扫描一次）
   - 检测到账后自动回调您的callbackUrl

4. 回调数据示例：
   {
       "type": "RECHARGE",
       "address": "T9xxx...",
       "label": "10086",         // 您传入的用户ID
       "amount": "100.000000",   // 充值金额(USDT)
       "txHash": "abc123...",    // 链上交易哈希
       "fromAddress": "T8xxx...",
       "coinType": "USDT-TRC20",
       "merchantNo": "M2032...",
       "status": "SUCCESS",
       "timestamp": 1710000000000,
       "sign": "xxx..."
   }

5. 验证回调签名，确认后给用户上分

=====================================================
*/
