using System; using System.Collections.Generic; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace UsdtPayment.SDK { /// /// USDT支付网关 C# SDK v3.2.0 /// /// 接口说明: /// - /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) /// public class UsdtPaySDK { private readonly string _baseUrl; private readonly string _merchantNo; private readonly string _apiKey; private readonly string _apiSecret; private readonly HttpClient _httpClient; public UsdtPaySDK(string baseUrl, string merchantNo, string apiKey, string apiSecret) { _baseUrl = baseUrl.TrimEnd('/'); _merchantNo = merchantNo; _apiKey = apiKey; _apiSecret = apiSecret; _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }; } /// /// 动态生成收款地址 /// /// 地址别名(可选) /// 币种类型: USDT-TRC20, ETH, USDT-ERC20, BTC, BSC, USDT-BEP20, POLYGON, USDT-POLYGON /// 响应JSON字符串 public async Task CreateAddressAsync(string label = null, string coinType = "USDT-TRC20") { long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var parameters = new Dictionary { { "merchantNo", _merchantNo }, { "timestamp", timestamp } }; if (!string.IsNullOrEmpty(label)) { parameters["label"] = label; } if (!string.IsNullOrEmpty(coinType)) { parameters["coinType"] = coinType; } string sign = GenerateSign(parameters); parameters["sign"] = sign; return await RequestAsync("/api/address/create", parameters); } /// /// 创建支付订单 /// public async Task CreateOrderAsync(string payAddress, string productName, string productDescription = null) { long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var parameters = new Dictionary { { "merchantNo", _merchantNo }, { "payAddress", payAddress }, { "productName", productName }, { "timestamp", timestamp } }; if (!string.IsNullOrEmpty(productDescription)) { parameters["productDescription"] = productDescription; } string sign = GenerateSign(parameters); parameters["sign"] = sign; return await RequestAsync("/api/pay/create", parameters); } /// /// 查询订单状态 /// public async Task QueryOrderAsync(string orderNo) { long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var parameters = new Dictionary { { "merchantNo", _merchantNo }, { "orderNo", orderNo }, { "timestamp", timestamp } }; string sign = GenerateSign(parameters); parameters["sign"] = sign; return await RequestAsync("/api/pay/query", parameters); } /// /// 验证回调签名 /// public bool VerifyCallback(Dictionary data) { if (!data.ContainsKey("sign")) return false; string sign = data["sign"].ToString(); var signData = new Dictionary(data); signData.Remove("sign"); string expectedSign = GenerateSign(signData); return sign.Equals(expectedSign, StringComparison.OrdinalIgnoreCase); } /// /// 生成签名 /// 签名算法: SHA256(参数按键名排序拼接 + key=apiSecret) /// 拼接格式: key1=value1&key2=value2&...&key=apiSecret /// private string GenerateSign(Dictionary parameters) { // 按键名排序 var sortedParams = new SortedDictionary(parameters); // 拼接参数 var sb = new StringBuilder(); foreach (var entry in sortedParams) { if (entry.Value != null && !string.IsNullOrEmpty(entry.Value.ToString())) { sb.Append(entry.Key).Append("=").Append(entry.Value).Append("&"); } } // 追加密钥 sb.Append("key=").Append(_apiSecret); return Sha256Hex(sb.ToString()); } private string Sha256Hex(string input) { using (var sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } private async Task RequestAsync(string path, Dictionary parameters) { string url = _baseUrl + path; string json = JsonSerializer.Serialize(parameters); var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = new StringContent(json, Encoding.UTF8, "application/json") }; request.Headers.Add("X-API-KEY", _apiKey); var response = await _httpClient.SendAsync(request); return await response.Content.ReadAsStringAsync(); } } // ==================== 使用示例 ==================== class Program { static async Task Main(string[] args) { var sdk = new UsdtPaySDK( "https://xxxx.com", "M203254xxxx1709440", // 商户编号 "AK_xxxxxxxx", // API Key "AS_xxxxxxxx" // API Secret ); // 1. 动态生成收款地址(默认USDT-TRC20) string result = await sdk.CreateAddressAsync("用户充值-订单123"); Console.WriteLine("生成TRC20地址: " + result); // 1.1 生成ETH地址 result = await sdk.CreateAddressAsync("用户充值-ETH", "ETH"); Console.WriteLine("生成ETH地址: " + result); // 1.2 生成USDT-ERC20地址 result = await sdk.CreateAddressAsync("用户充值-ERC20", "USDT-ERC20"); Console.WriteLine("生成ERC20地址: " + result); // 1.3 生成BTC地址 result = await sdk.CreateAddressAsync("用户充值-BTC", "BTC"); Console.WriteLine("生成BTC地址: " + result); // 1.4 生成BSC USDT地址 result = await sdk.CreateAddressAsync("用户充值-BEP20", "USDT-BEP20"); Console.WriteLine("生成BEP20地址: " + result); // 2. 创建支付订单 result = await sdk.CreateOrderAsync( "T9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "购买VIP会员", "购买1个月VIP会员服务" ); Console.WriteLine("创建订单结果: " + result); // 3. 查询订单状态 result = await sdk.QueryOrderAsync("P2032545595611709440"); Console.WriteLine("查询订单结果: " + result); } } } /* ===================== 完整对接流程 ===================== 1. 从商户后台获取凭证: - 商户编号 (merchantNo) - API Key - API Secret 2. 用户发起支付时: a) 调用 CreateAddressAsync() 动态生成收款地址 b) 调用 CreateOrderAsync() 创建支付订单 c) 展示收款地址给用户进行转账 3. 用户转账后: - 系统自动检测链上交易 - 支付成功后回调您的通知地址 4. 验证回调签名,更新订单状态 ===================================================== */