diff --git a/xy_sh/example_test.go b/xy_sh/example_test.go new file mode 100644 index 0000000..128aa70 --- /dev/null +++ b/xy_sh/example_test.go @@ -0,0 +1,227 @@ +package xy_sh + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/http" + "net/http/httptest" + "strings" +) + +// ExampleClient_PlaceOrder 演示卡券/直充权益下单 +func ExampleClient_PlaceOrder() { + // 模拟供应商服务端 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // 读取请求体 + var req EncryptedRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + + // 验证签名(实际生产环境需要验证) + timestamp := r.Header.Get("timestamp") + sign := r.Header.Get("sign") + _ = timestamp + _ = sign + + // 模拟响应 + resp := EncryptedResponse{ + Code: 0, + Msg: "请求成功", + Data: strPtr(`{"orderNo":"HM17575805323790000127073398f3772c00","expireTime":"2025-09-12 00:00:00","couponNo":"27073398f3772c00","couponCode":"27073398f3772c00","status":1}`), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + })) + defer server.Close() + + // 初始化客户端 + // 注意:SM4密钥必须为16字节 + sm4Key := []byte("1234567890abcdef") // 16字节密钥 + sm3Salt := "my_sm3_salt_value" + baseURL := server.URL + + client, err := NewClient(sm4Key, sm3Salt, baseURL) + if err != nil { + log.Fatalf("创建客户端失败: %v", err) + } + + // 调用下单接口 + req := &PlaceOrderRequest{ + ActCode: "ACT001", + GoodsCode: "123456", + ActOrderNum: "00001", + Account: "19912345678", + CallbackUrl: "https://xxx/notice", + } + + resp, data, err := client.PlaceOrder(context.Background(), req) + if err != nil { + log.Fatalf("下单失败: %v", err) + } + + if resp.Code != 0 { + fmt.Printf("下单失败: %s\n", resp.Msg) + return + } + + fmt.Printf("订单号: %s\n", data.OrderNo) + fmt.Printf("卡号: %s\n", data.CouponNo) + fmt.Printf("卡密: %s\n", data.CouponCode) + fmt.Printf("状态: %d\n", data.Status) + fmt.Printf("有效期: %s\n", data.ExpireTime) + + // Output: + // 订单号: HM17575805323790000127073398f3772c00 + // 卡号: 27073398f3772c00 + // 卡密: 27073398f3772c00 + // 状态: 1 + // 有效期: 2025-09-12 00:00:00 +} + +// ExampleClient_QueryOrder 演示订单查询 +func ExampleClient_QueryOrder() { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp := EncryptedResponse{ + Code: 0, + Msg: "请求成功", + Data: strPtr(`{"orderNo":"HM1757046717684000102707339840b23222","cardInfo":"{\"couponNo\":\"11111\",\"couponCode\":\"12334\",\"expireTime\":\"2029-03-09 00:00:00\"}","status":3}`), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + })) + defer server.Close() + + client, _ := NewClient([]byte("1234567890abcdef"), "my_sm3_salt", server.URL) + + req := &QueryOrderRequest{ + ActCode: "FBG6vdYqGE4mGX7EH/woEg==", + OrderNo: "HM1757046717684000102707339840b23222", + } + + resp, data, err := client.QueryOrder(context.Background(), req) + if err != nil { + log.Fatalf("查询失败: %v", err) + } + + if resp.Code != 0 { + fmt.Printf("查询失败: %s\n", resp.Msg) + return + } + + fmt.Printf("订单号: %s\n", data.OrderNo) + fmt.Printf("状态: %d\n", data.Status) + if data.CardInfo != nil { + fmt.Printf("卡号: %s\n", data.CardInfo.CouponNo) + fmt.Printf("卡密: %s\n", data.CardInfo.CouponCode) + fmt.Printf("过期时间: %s\n", data.CardInfo.ExpireTime) + } + + // Output: + // 订单号: HM1757046717684000102707339840b23222 + // 状态: 3 + // 卡号: 11111 + // 卡密: 12334 + // 过期时间: 2029-03-09 00:00:00 +} + +// ExampleClient_WechatRecharge 演示微信立减金充值 +func ExampleClient_WechatRecharge() { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp := EncryptedResponse{ + Code: 0, + Msg: "请求成功", + Data: strPtr(`{"orderNo":"0001","couponId":"123456","status":1}`), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + })) + defer server.Close() + + client, _ := NewClient([]byte("1234567890abcdef"), "my_sm3_salt", server.URL) + + req := &WechatRechargeRequest{ + ActCode: "FBG6vdYqGE4mGX7EH/woEg==", + GoodsCode: "0001", + ActOrderNum: "0001", + OpenId: "0001", + AppId: "00001", + } + + resp, data, err := client.WechatRecharge(context.Background(), req) + if err != nil { + log.Fatalf("充值失败: %v", err) + } + + if resp.Code != 0 { + fmt.Printf("充值失败: %s\n", resp.Msg) + return + } + + fmt.Printf("订单号: %s\n", data.OrderNo) + fmt.Printf("优惠ID: %s\n", data.CouponId) + fmt.Printf("状态: %d\n", data.Status) + + // Output: + // 订单号: 0001 + // 优惠ID: 123456 + // 状态: 1 +} + +// ExampleClient_ParseNotifyRequest 演示解析回调通知 +func ExampleClient_ParseNotifyRequest() { + client, _ := NewClient([]byte("1234567890abcdef"), "my_sm3_salt", "http://example.com") + + // 模拟供应商发来的回调通知 + notifyData := NotifyRequest{ + OrderNo: "HM202509291010001", + ActOrderNum: "XY2025092910100001", + Status: 3, + Account: "19912345678", + } + + // 加密并签名(模拟供应商端操作) + encryptedData, timestamp, sign, err := client.encryptAndSign(notifyData) + if err != nil { + log.Fatalf("加密失败: %v", err) + } + + // 构建HTTP请求 + reqBody := fmt.Sprintf(`{"encryptedData":"%s"}`, encryptedData) + httpReq := httptest.NewRequest(http.MethodPost, "/notify", strings.NewReader(reqBody)) + httpReq.Header.Set("Content-Type", "application/json") + httpReq.Header.Set("timestamp", timestamp) + httpReq.Header.Set("sign", sign) + + // 解析回调通知 + notifyReq, err := client.ParseNotifyRequest(httpReq) + if err != nil { + log.Fatalf("解析回调通知失败: %v", err) + } + + fmt.Printf("订单号: %s\n", notifyReq.OrderNo) + fmt.Printf("活动方订单号: %s\n", notifyReq.ActOrderNum) + fmt.Printf("状态: %d\n", notifyReq.Status) + fmt.Printf("账号: %s\n", notifyReq.Account) + + // 生成成功响应 + statusCode, body := NotifyResponseOK() + fmt.Printf("响应状态码: %d\n", statusCode) + fmt.Printf("响应内容: %s\n", body) + + // Output: + // 订单号: HM202509291010001 + // 活动方订单号: XY2025092910100001 + // 状态: 3 + // 账号: 19912345678 + // 响应状态码: 200 + // 响应内容: ok +} + +// strPtr 辅助函数:返回字符串指针 +func strPtr(s string) *string { + return &s +} \ No newline at end of file