{"id":23684026,"url":"https://github.com/yop-platform/yop-dotnet-sdk","last_synced_at":"2026-02-14T06:32:34.476Z","repository":{"id":105167940,"uuid":"361699238","full_name":"yop-platform/yop-dotnet-sdk","owner":"yop-platform","description":"YOP .net SDK","archived":false,"fork":false,"pushed_at":"2026-01-20T10:49:21.000Z","size":6015,"stargazers_count":1,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-20T19:05:34.279Z","etag":null,"topics":["csharp","sdk","yop"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yop-platform.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-04-26T09:53:29.000Z","updated_at":"2025-08-07T05:31:46.000Z","dependencies_parsed_at":"2024-04-22T12:27:13.086Z","dependency_job_id":"33e55a63-d792-4277-aa76-a295e848b43e","html_url":"https://github.com/yop-platform/yop-dotnet-sdk","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/yop-platform/yop-dotnet-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yop-platform%2Fyop-dotnet-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yop-platform%2Fyop-dotnet-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yop-platform%2Fyop-dotnet-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yop-platform%2Fyop-dotnet-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yop-platform","download_url":"https://codeload.github.com/yop-platform/yop-dotnet-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yop-platform%2Fyop-dotnet-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29438772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T05:24:35.651Z","status":"ssl_error","status_checked_at":"2026-02-14T05:24:34.830Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","sdk","yop"],"created_at":"2024-12-29T20:32:42.362Z","updated_at":"2026-02-14T06:32:34.470Z","avatar_url":"https://github.com/yop-platform.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YOP .NET SDK\n\nYOP .NET SDK 是易宝支付开放平台提供的官方 .NET SDK，用于简化商户与易宝支付平台的集成。本 SDK 基于 .NET 8.0 开发，支持 RESTful API 调用、数据加密、签名验证等功能。\n\n## 概述\n\n**版本信息**：4.0.0  \n**支持框架**：.NET 8.0 LTS (长期支持版本)  \n**最新版本密钥格式**：PKCS8格式（3.5.0及以后版本），3.5.0以前版本使用PKCS1格式\n\n## 核心功能\n\n- 支持多种HTTP请求方式（GET、POST、文件上传下载）\n- 自动签名和加密处理\n- 支持JSON数据格式\n- 完善的异常处理机制\n- 支持多应用配置\n- 支持请求和响应加密\n\n## 快速开始\n\n### 1. 环境要求\n\n- .NET 8.0 LTS 或更高版本\n- Visual Studio 2022 或 Visual Studio Code\n\n**注意**：本SDK基于.NET 8.0 LTS构建，同时兼容.NET 10.0环境。推荐使用.NET 8.0 LTS以获得最佳稳定性和长期支持。\n\n### 2. 安装SDK\n\n将 SDK 项目添加到您的解决方案中，或直接引用编译后的程序集。\n\n### 3. 配置初始化\n\n```csharp\nusing SDK.yop.client;\n\n// 配置服务器地址\n// 测试环境\nYopConfig.setServerRoot(\"https://sandbox.yeepay.com/yop-center\");\nYopConfig.setYosServerRoot(\"https://sandbox.yeepay.com/yop-center\");\n\n// 生产环境\n// YopConfig.setServerRoot(\"https://openapi.yeepay.com/yop-center\");\n// YopConfig.setYosServerRoot(\"https://yos.yeepay.com/yop-center\");\n```\n\n### 4. 创建请求对象\n\n```csharp\n// 使用全局配置创建请求\nvar request = new YopRequest();\n\n// 或指定应用信息创建请求\nvar request = new YopRequest(\"appKey\", \"secretKey\", \"yopPublicKey\");\n```\n\n### 5. 添加请求参数\n\n```csharp\n// 添加普通参数\nrequest.addParam(\"merchantNo\", \"YOUR_MERCHANT_NO\");\nrequest.addParam(\"orderId\", \"ORDER_123456\");\nrequest.addParam(\"orderAmount\", \"100.00\");\n\n// 添加文件参数（用于文件上传）\nrequest.addFile(\"merQual\", \"/path/to/your/file.txt\");\n\n```\n\n## API调用示例\n\n### 1. GET请求示例\n\n```csharp\npublic void TestGetForm()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey, YopPublicKey);\n        request.addParam(\"file\", \"test_file\");\n        request.addParam(\"fileFileSize\", \"1024\");\n        request.addParam(\"fileMd5\", \"d41d8cd98f00b204e9800998ecf8427e\");\n        request.addParam(\"fileOriginalFileName\", \"test.txt\");\n        request.addParam(\"fileBucket\", \"test-bucket\");\n\n        // 使用YopRsaClient发起请求\n        var response = YopRsaClient.get(\"/rest/v1.0/lx-test/lx-getform-old\", request);\n\n        if (response != null \u0026\u0026 response.result != null)\n        {\n            Console.WriteLine($\"GET Form API响应: {FormatJson(response.result.ToString())}\");\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"GET Form API测试异常: {ex.Message}\");\n    }\n}\n```\n\n### 2. POST Form请求示例\n\n```csharp\npublic void TestPostForm()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey, YopPublicKey);\n        request.addParam(\"file\", \"test_file\");\n        request.addParam(\"fileFileSize\", \"1024\");\n        request.addParam(\"fileMd5\", \"d41d8cd98f00b204e9800998ecf8427e\");\n        request.addParam(\"fileOriginalFileName\", \"test.txt\");\n        request.addParam(\"fileBucket\", \"test-bucket\");\n\n        // 使用YopRsaClient发起POST请求\n        var response = YopRsaClient.post(\"/rest/v1.0/lx-test/lx-postform-old\", request);\n\n        if (response != null \u0026\u0026 response.result != null)\n        {\n            Console.WriteLine($\"POST Form API响应: {FormatJson(response.result.ToString())}\");\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"POST Form API测试异常: {ex.Message}\");\n    }\n}\n```\n\n### 3. POST JSON请求示例\n\n```csharp\npublic void TestPostJson()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey, YopPublicKey);\n\n        var parameters = new Dictionary\u003cstring, object\u003e\n        {\n            { \"file\", \"test_file\" },\n            { \"fileFileSize\", \"1024\" },\n            { \"fileMd5\", \"d41d8cd98f00b204e9800998ecf8427e\" },\n            { \"fileOriginalFileName\", \"test.txt\" },\n            { \"fileBucket\", \"test-bucket\" }\n        };\n\n        var jsonContent = JsonConvert.SerializeObject(parameters);\n        request.setContent(jsonContent);\n\n        // 使用YopRsaClient发起POST JSON请求\n        var response = YopRsaClient.post(\"/rest/v1.0/lx-test/lx-postjson-old\", request);\n\n        if (response != null \u0026\u0026 response.result != null)\n        {\n            Console.WriteLine($\"POST JSON API响应: {FormatJson(response.result.ToString())}\");\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"POST JSON API测试异常: {ex.Message}\");\n    }\n}\n```\n\n### 4. 文件上传示例\n\n```csharp\npublic void TestUploadOldApi()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey, YopPublicKey);\n        \n        // 创建临时文件\n        var tempFilePath = Path.GetTempFileName();\n        try\n        {\n            File.WriteAllText(tempFilePath, \"hello world\");\n            request.addFile(\"merQual\", tempFilePath);\n            request.addParam(\"merQualOriginalFileName\", \"test.txt\");\n            \n            // 使用YopRsaClient发起上传请求\n            var response = YopRsaClient.upload(\"/yos/v1.0/test/mer-file-upload/upload/backupload\", request);\n            \n            if (response != null \u0026\u0026 response.result != null)\n            {\n                Console.WriteLine($\"上传API响应: {FormatJson(response.result.ToString())}\");\n            }\n        }\n        finally\n        {\n            if (File.Exists(tempFilePath))\n            {\n                File.Delete(tempFilePath);\n            }\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"上传API测试异常: {ex.Message}\");\n    }\n}\n```\n\n### 5. 文件下载示例\n\n```csharp\npublic void TestDownloadOldApi()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey, YopPublicKey);\n        request.addParam(\"fileName\", \"test.txt\");\n\n        // 使用YopRsaClient发起下载请求\n        var response = YopRsaClient.get(\"/yos/v1.0/test/test/ceph-download\", request);\n\n        if (response != null \u0026\u0026 response.result != null)\n        {\n            Console.WriteLine($\"下载API响应: {FormatJson(response.result.ToString())}\");\n        }\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"下载API测试异常: {ex.Message}\");\n    }\n}\n```\n\n## 高级功能\n\n### 1. 签名验证\n\nSDK 自动处理请求签名，并支持响应签名验证：\n\n```csharp\n// 检查响应签名是否有效\nif (response.isValidSign())\n{\n    // 签名验证通过\n}\nelse\n{\n    // 签名验证失败\n}\n```\n\n### 2. 请求配置和签名功能测试\n\n```csharp\npublic void TestRequestConfigAndSign()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey);\n        request.addParam(\"testParam\", \"testValue\");\n\n        // 验证请求参数\n        request.getAppKey().Should().Be(AppKey);\n        request.getSecretKey().Should().Be(SecretKey);\n\n        // 验证参数添加\n        request.getParamValue(\"testParam\").Should().Be(\"testValue\");\n\n        Console.WriteLine(\"请求配置和签名功能测试通过\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"请求配置和签名功能测试异常: {ex.Message}\");\n        throw;\n    }\n}\n```\n\n### 3. 响应处理功能测试\n\n```csharp\npublic void TestResponseHandling()\n{\n    try\n    {\n        var request = new YopRequest(AppKey, SecretKey);\n        var response = new YopResponse();\n\n        // 设置响应数据\n        response.state = \"SUCCESS\";\n        response.result = \"{\\\"test\\\":\\\"value\\\"}\";\n        response.ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n        response.validSign = true;\n\n        // 验证响应处理\n        response.isSuccess().Should().BeTrue();\n        response.isValidSign().Should().BeTrue();\n        response.result.Should().NotBeNull();\n\n        Console.WriteLine(\"响应处理功能测试通过\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"响应处理功能测试异常: {ex.Message}\");\n        throw;\n    }\n}\n```\n\n## 工具类使用\n\n### 1. 签名-收银台\n\n```csharp\npublic void TestSignForCashier()\n{\n    try\n    {\n        // 测试私钥\n        string private_key = \"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBHBdHbQXsPT+EpAhLA9k2Q5O8GLCAUFLWYB57Uhc4ZNa2YUhjrTFvFZMFQuMjaVgdmFGTvqfGYUQBRldHFhf9kuXf5LPb+m0BJ/R5AWCyTcX7DHouoGODMfxkCZrimILwYWDkwhYTHr5hEV58nGRQtHOIVB5a4i/y4Z1vvX1MIjA+8OJ3zpaxXKkj+46OtfmjloUPGFSzz+rqrRRtMqYePLkWZ0J+CmIXM1Kwl/kgYUq/YGSYy9Q5vTojN9WBKzk7euOoCcsWtRrBQysdyM3yDPXjhnXx7G0nh07hSUh+rMDZ7Zst0lVQol/7kPXzNwh6eUmRGY9lfruIMS5kg1ydAgMBAAECggEAD4yQf0rTCEOiQq7mkAu+SLVGRwYB6EMPeH2C1tE0V3EfLM5GgugmK9ij3u+U1HweATwLjYbzgXDBhgzA6FNqGRvj8JQ8u0C92DL8Z2XqAFFs2JsXl3uIp761oOR5GTfIi0x7/c928ZEvKSe54PTCyxDMoLSNQSonTDpIb//k/+U4xEOQ1mjlSvlOM5ic7/kdw+G+aP/Hk/T6kg/vIblWQHx8SB3WYpLb/R6oPO+05X+zcQ+vVX1TrQ/amDp6/PouWjTF5hf48JEBdM8+xJzUwnalrG9U7pChfyGAOXQT1fbDdywBJXt6pZsT/mz1RkUC5Uto5/aVQGIDD+IPm/ZDbQKBgQDEwF09sjUb5hHEdmG28RmMf4E0JCOEzCvxiUpovobymqapLM5bf2oLNXqGenEAMbfFQatJFVKx6YBZwFIj/xzQJt8fL/jRzlbLijaANP+1JacvTsfXKBXS888FN3rkKisTlhmYXI+4EwA1wbcRkLDH3vezdVCi9cszQ9HvwkVfOwKBgQD7QvzD3pirXIJ64JizWTS4MJMko3CWepsq9UZ5uyoHWh7tSz86H/2y0FK10YpJEJeGtyPXlnU+uQwjYMJRPLlNv8180pjCJX2ZTW2drB2vOJvormhMhDIYAZtPAHu2dajzdy4VRuvFTtH4FpW/KjAJrTLK3ze3K95ACYVBJ8EmBwKBgB0K8DiNN724hmLjvqTMjiLpJ19U/lE5+jqbM3qmtTDWl0ddr9BdzH9/E2kKZefLbv8VJH2TQjO07hdRhk599/jZ5BGseSQvOyysaEMgj6ZjunwHOwSNjDspdiOk/uTzPIyVmY2eDDD1zRAiWi2jmBTI2vOIm7CSa75TgofLu4XFAoGBAJrFM4+vYNlFXbY0/LqU+21ttmV+K471rPj0Jto7GPN4Zs6CaEr0g8COpDQNA6JoDv5Td0eIDWZ6c+ii5G9H+VjUCc6WprQIhepVkGzsJUjWlOrp66MeVwEElFdAk/PbXBvEUOWYTwi1uY6Y0trzMK31OvFOODKjWf6WHrf4tfgnAoGAOri6bX2D/zqpJT3mJ5MIVJJbn4D4Idx+TCUaVRSY1rBp+Y2ofW1W8ktu7xPO9/LwVQR7kJeosEBAFGTmGqll033ywu5+8X8J1bw6HCghkI0yHW752sOdfl30kXi3Ds8tQsvSEHRfnPb8yvWve2srZb9ubwOvpI0PtOIujZP4fYI=\";\n        \n        // 待签名原文\n        string plainText = \"这里是待签名原文呀123！@¥%……\u0026*。。\";\n        \n        // 使用SHA1withRSA进行签名\n        string signature = SHA1withRSA.signRsa(plainText, private_key);\n        \n        // 验证签名不为空\n        signature.Should().NotBeNullOrEmpty();\n        \n        Console.WriteLine($\"签名原文: {plainText}\");\n        Console.WriteLine($\"签名结果: {signature}\");\n        Console.WriteLine(\"签名功能测试通过\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"签名功能测试异常: {ex.Message}\");\n        throw;\n    }\n}\n```\n\n### 2. 通知解密\n\n```csharp\npublic void TestNoticeDecrypt()\n{\n    try\n    {\n        // 这是接收到的通知报文\n        var callContent = \"response=ZIcrArlonH0mxIWCRejL2VQS2qeK5EFz2gALzdMbusIU8eqwnWNgJRWiTwJElSQEhnT42KkU3jXWZr2dd0A8-bZSjT-hvNCUI0aoJZkadRtJrWoe_ygGhOLegj7cTbk8y7GOzfFQteIFbB9ALae1CqWVHgfgyozbTLgsse4MfuYjio9r3DOkCJJSkW6mEHB0G4rTXSWFni0h_Uhtu5jsuCTU4vWDPKrBIZI17rr1AIqmyOd8C8oLCAplC1JT4KnLq5QCir4cnvZJrGYB5-bI00gPOdGX2_v4Az3VqMkh8PqqPSDriJ-PqDo9T2dnjR5njYkTSSzUpIXg6cfhLaTNIQ$0sn1fsX0zRYXv-bb0tV531Brbhb-fPORrXYqe8JzHbnL8NkAwIPRkSaTXfq3etJnmslkkBlPpZeTc7639TWQlBrl3eVW-aQKIjFX4bhfyythIh5ByjBAHw1RaYwoHw10kkpbBBk01K-6pzE9QzT6TvjZLsSsXZ6O3WJdvrB8dtpJA-PI-sOzm7DXkBqfKOSufkN1C1mRvexBlcN3ScSH2TKo5ZwKw3Fo_93GsYFD0hzYmHpC6yCyHXeY1PPlHYqd_KsqXVo_xBtXMCadoKnldYnMljXdhAQJLRdlkwTgeD8FX18SQSJ18O6Ag0w3IM9QXkcgZVgIo1-_ZUncc5AtNXyQCvfT4tNyaIRFsXlFqj5tCc5bekMz8OzYeRTPfmfCLKXmjvg4ICMw0aIRboX1tyZpCHdHU269u0-wX90pMDNRqBZsLag6glNDSzEG8RQaB4vGrjvxYy0ixeUnogwni2qqnnGX5Gfhkst7FPYubAsi5HweDT_aJIrmE6kMiBrpMAOcIGZ6slYK854FOH3ODO9-raz7n2P__NUTpziTF4t4Jru_erJevVoGyHH81qq_msIMvK7IRx2z1QoExRL08A$AES$SHA256\u0026customerIdentification=app_Fe51qCyZWcEnDMtK\";\n        \n        // 获取 response 值 并 Url解码\n        var decodeData = System.Web.HttpUtility.UrlDecode(callContent.Split('\u0026').FirstOrDefault(p =\u003e p.StartsWith(\"response\")).Replace(\"response=\", \"\"));\n        \n        string isvPriKey = \"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCFqza8OmK0drABjmphX3erNEoLJ6kCqaE/AWvqEReAq5K8+3btAVEJYBiMbEJUvZpV4YCITDhyJeRzdfLl2EGnsvI4lrhvrvGAjW9lB34b7GdJSMFFj+ExrTuCQ7zDeUgATlmhLyHxWZ6IAVwf1a3G5bk2GhUipFc0dL8HviVk25CSAgCWKL8LZ0V4ec+FF3/Z6orJUChQOuvpNlclH65pHbdQ4Mr3rQUI0z7WSaW1U1EZeXSctRPf/3JQYLi+RW/yogXG8t+6zn9jE/tGuWJV0bm/ZUDU2XydjZgU0E/NzMutmNVSSKpBy74vt5SCNXkK0BgjRTXP8HGvEgA7IYfLAgMBAAECggEAQNlOxcUBrBHE1Ax22eTKFvpYTc8g9NS9EOcsprNCFr+mgh7xlIxF92lyn3XKPHh8DtxHUljALcjqa4W2oQHo4GY1k3Sz6CMUsUxs1bPr37oyZeBxO8FQ/JvRuiIIy0DkyJk6bLOEISZcfhlCy4MMOumqkG/Y/ySB1kYpg6UhWStlGdQZbHEL7NUBW1QVQqaDAtSV8cgNNXbinQ08pIMlfqnH57DM8J7lx+687li41ZkQgCc/r/zkV5Tf5ABlhDxmZZbHmU7jsvlqh6zxm12r7A0gOwnb/wVd0ZrpIE2TfsDGOQckfEmaD4uhsabDAVO7I6IDM86hH3Sm285hkQ/2eQKBgQC6eNRpJQv6TfXMqEoNMf503WGskWF0RFSU0mU/5dSX8GELhLkyAtAhZFnrOKcseZJng/Z6grfS2wIG3Y17kXIlbi8Wprk0F9AsUOSEFPFRW/I7y7aUDvGf8Jz/TsiYEatSE0SJCWZbpaO8+WoczNybWNyyHapq2g6+xHSlyEp9nQKBgQC3gjOIF1dt67lrWSogVDX1eEpp6yLxKXC0usGV/0sB2FK5S9KqEh2Ul+rWwlxXxLpVYHhHFr1k7PyFrnwsTUxNHj2joCD1yOhMoxgMoRm0/z43cV/0TeTcLTQkxdCtwZ6pQwHIAHenLRpxpnD8Y8EplA3VS9Lno7eSC9VjqgFShwKBgF83vfcm1LPuxTnJIW8VfUK9nNeasPHGxo3r1YnIWUNwmo1gK5UO/KpgbM4A8tRyC8FSEDVEtIs2DBXnYgycG3ZjiiX94opoMoO+lsGfVA5gbhP8lPGLo/Qw0GpKF4IXW60ga5myNBNORIsFrRqhvXCR8rf9D/1Z9beR56KT4P29AoGAV986+dHjhbk4wpShvXVVmUOOroVv5/cmBwTeqgrjSfDiO+R47gNassrEIy5StZx4dWWKctAKxQdOLF1PDI+/F7aBYZbN8aPQyNHYNEP4YVlP25Col/2st1nV/D3VHT730KlLcw/2O9E3NnCy7ch+uIAy145FYbJdtst/1QeVNoUCgYEAtv3w9xNugsYl4/yNkC/DIXat9u/56sVjnYzxvwHZT8jtg4uo3qqlRqqm4OcUmzcsYodrsbn8upizq9ZS2NVdPrGIPFOZBgNUKWL1Ok/dJgfBcdpo72/UX4+KQ2/9c1ZrjjMs4sglsrzvZTXqkryXkPKxKk1EcjDaKiOExFnk6Y8=\";\n        string yopPubKey = \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4g7dPL+CBeuzFmARI2GFjZpKODUROaMG+E6wdNfv5lhPqC3jjTIeljWU8AiruZLGRhl92QWcTjb3XonjaV6k9rf9adQtyv2FLS7bl2Vz2WgjJ0FJ5/qMaoXaT+oAgWFk2GypyvoIZsscsGpUStm6BxpWZpbPrGJR0N95un/130cQI9VCmfvgkkCaXt7TU1BbiYzkc8MDpLScGm/GUCB2wB5PclvOxvf5BR/zNVYywTEFmw2Jo0hIPPSWB5Yyf2mx950Fx8da56co/FxLdMwkDOO51Qg3fbaExQDVzTm8Odi++wVJEP1y34tlmpwFUVbAKIEbyyELmi/2S6GG0j9vNwIDAQAB\";\n        \n        // 使用SHA1withRSA进行通知解密\n        string cipherText = SHA1withRSA.NoticeDecrypt(decodeData, isvPriKey, yopPubKey);\n        \n        // 验证解密结果不为空\n        cipherText.Should().NotBeNullOrEmpty();\n        \n        Console.WriteLine($\"解密结果: {cipherText}\");\n        Console.WriteLine(\"通知解密功能测试通过\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"通知解密功能测试异常: {ex.Message}\");\n        throw;\n    }\n}\n```\n\n### 3. AES加密解密工具\n\n```csharp\npublic void TestEncryptDecrypt()\n{\n    try\n    {\n        var originalText = \"test encryption data\";\n        var aesKey = \"1234567890123456\"; // 16位密钥\n\n        // 测试AES加密解密\n        var encrypted = AESHelper.AESEncrypt(originalText, aesKey);\n        var decrypted = AESHelper.AESDecrypt(encrypted, aesKey);\n\n        decrypted.Trim().Should().Be(originalText);\n\n        Console.WriteLine(\"加密解密功能测试通过\");\n    }\n    catch (Exception ex)\n    {\n        Console.WriteLine($\"加密解密功能测试异常: {ex.Message}\");\n        throw;\n    }\n}\n```\n\n### 4. JSON格式化工具\n\n```csharp\n/// \u003csummary\u003e\n/// 格式化JSON字符串以便更好地显示\n/// \u003c/summary\u003e\n/// \u003cparam name=\"json\"\u003eJSON字符串\u003c/param\u003e\n/// \u003creturns\u003e格式化后的JSON字符串\u003c/returns\u003e\nprivate string FormatJson(string json)\n{\n    try\n    {\n        var parsedObject = JsonConvert.DeserializeObject(json);\n        return JsonConvert.SerializeObject(parsedObject, Formatting.Indented);\n    }\n    catch\n    {\n        return json;\n    }\n}\n```\n\n## 测试用例\n\n### 综合测试方法\n\n```csharp\n[Fact]\npublic void TestAllApis()\n{\n    // 测试下载API\n    TestDownloadOldApi();\n\n    // 测试GET Form API\n    TestGetForm();\n\n    // 测试POST Form API\n    TestPostForm();\n\n    // 测试POST JSON API\n    TestPostJson();\n\n    // 测试上传API\n    TestUploadOldApi();\n}\n```\n\n## 最佳实践\n\n1. **密钥安全**：妥善保管您的密钥，不要在代码中硬编码，建议使用配置文件或环境变量。\n\n2. **异常处理**：始终使用try-catch块处理SDK调用，确保程序稳定运行。\n\n3. **超时设置**：根据网络环境合理设置超时时间，避免长时间等待。\n\n4. **日志记录**：记录请求和响应信息，便于问题排查。\n\n5. **签名验证**：对于重要业务，建议启用响应签名验证，确保数据完整性。\n\n6. **重试机制**：对于网络不稳定的情况，可以实现适当的重试机制。\n\n7. **文件处理**：上传文件后及时清理临时文件，避免占用磁盘空间。\n\n## 环境配置\n\n### 测试环境配置\n\n```csharp\n// 测试环境，商户私钥\nprivate const string AppKey = \"app_100800191870146\";\nprivate const string SecretKey = \"YOUR_SECRET_KEY\";\n// 测试环境，平台公钥\nprivate const string YopPublicKey = \"YOP_PUBLIC_KEY\";\n// 测试环境，请求端点地址\nprivate const string ServerRoot = \"https://sandbox.yeepay.com/yop-center\";\nprivate const string YosServerRoot = \"https://sandbox.yeepay.com/yop-center\";\n```\n\n### 生产环境配置\n\n```csharp\n// 生产环境，平台公钥\n// private const string YopPublicKey = \"YOP_PUBLIC_KEY\";\n// 生产环境，请求端点地址\n// private const string ServerRoot = \"https://openapi.yeepay.com/yop-center\";\n// private const string YosServerRoot = \"https://yos.yeepay.com/yop-center\";\n```\n\n## 常见问题\n\n### Q: 如何切换测试环境和生产环境？\nA: 通过设置不同的服务器地址：\n```csharp\n// 测试环境\nYopConfig.setServerRoot(\"https://sandbox.yeepay.com/yop-center\");\nYopConfig.setYosServerRoot(\"https://sandbox.yeepay.com/yop-center\");\n\n// 生产环境\nYopConfig.setServerRoot(\"https://openapi.yeepay.com/yop-center\");\nYopConfig.setYosServerRoot(\"https://yos.yeepay.com/yop-center\");\n```\n\n### Q: 如何处理大文件上传？\nA: SDK支持文件上传，但对于大文件建议分片上传或使用断点续传。\n\n### Q: 如何验证响应签名？\nA: 设置`request.setSignRet(true)`，SDK会自动验证响应签名，可通过`response.isValidSign()`检查结果。\n\n### Q: 如何处理网络超时？\nA: 合理设置连接超时和读取超时时间，并实现重试机制。\n\n### Q: 如何添加JSON内容到请求？\nA: 使用`request.setContent(jsonContent)`方法添加JSON内容。\n\n## 技术支持\n\n如有问题，请联系易宝支付技术支持或查阅官方文档。\n\n---\n\n*本文档基于YOP .NET SDK v4.0.0版本编写，最新信息请参考官方文档。有关版本更新详情，请参阅 [CHANGELOG.md](./CHANGELOG.md)。*","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyop-platform%2Fyop-dotnet-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyop-platform%2Fyop-dotnet-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyop-platform%2Fyop-dotnet-sdk/lists"}