
1package main
2
3import (
4 "bytes"
5 "demo/wxpay_utility"
6 "encoding/json"
7 "fmt"
8 "net/http"
9 "net/url"
10 "strings"
11)
12
13func main() {
14
15 config, err := wxpay_utility.CreateMchConfig(
16 "19xxxxxxxx",
17 "1DDE55AD98Exxxxxxxxxx",
18 "/path/to/apiclient_key.pem",
19 "PUB_KEY_ID_xxxxxxxxxxxxx",
20 "/path/to/wxp_pub.pem",
21 )
22 if err != nil {
23 fmt.Println(err)
24 return
25 }
26
27 request := &ResponseComplaintImmediateServiceRequest{
28 ComplaintId: wxpay_utility.String("200201820200101080076610000"),
29 ComplaintedMchid: wxpay_utility.String("1900012181"),
30 Message: &NormalMessage{
31 Blocks: []Block{Block{
32 Type: BLOCKTYPE_TEXT.Ptr(),
33 Text: &Text{
34 Text: wxpay_utility.String("example_text"),
35 Color: TEXTCOLOR_DEFAULT.Ptr(),
36 IsBold: wxpay_utility.Bool(false),
37 },
38 Image: &Image{
39 MediaId: wxpay_utility.String("example_media_id"),
40 ImageStyleType: IMAGESTYLETYPE_IMAGE_STYLE_TYPE_NARROW.Ptr(),
41 },
42 Link: &Link{
43 Text: wxpay_utility.String("example_text"),
44 Action: &ClickAction{
45 ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
46 JumpUrl: wxpay_utility.String("example_jump_url"),
47 MiniProgramJumpInfo: &MiniProgramJump{
48 Appid: wxpay_utility.String("example_appid"),
49 Path: wxpay_utility.String("example_path"),
50 },
51 MessageInfo: &MessageInfo{
52 Content: wxpay_utility.String("example_content"),
53 CustomData: wxpay_utility.String("example_custom_data"),
54 },
55 ActionId: wxpay_utility.String("example_action_id"),
56 },
57 InvalidInfo: &InvalidInfo{
58 ExpiredTime: wxpay_utility.String("example_expired_time"),
59 MultiClickable: wxpay_utility.Bool(false),
60 },
61 },
62 FaqList: &FaqList{
63 Faqs: []FaqListItem{FaqListItem{
64 FaqId: wxpay_utility.String("example_faq_id"),
65 FaqTitle: wxpay_utility.String("example_faq_title"),
66 Action: &ClickAction{
67 ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
68 JumpUrl: wxpay_utility.String("example_jump_url"),
69 MiniProgramJumpInfo: &MiniProgramJump{
70 Appid: wxpay_utility.String("example_appid"),
71 Path: wxpay_utility.String("example_path"),
72 },
73 MessageInfo: &MessageInfo{
74 Content: wxpay_utility.String("example_content"),
75 CustomData: wxpay_utility.String("example_custom_data"),
76 },
77 ActionId: wxpay_utility.String("example_action_id"),
78 },
79 }},
80 },
81 Button: &Button{
82 Text: wxpay_utility.String("example_text"),
83 Action: &ClickAction{
84 ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
85 JumpUrl: wxpay_utility.String("example_jump_url"),
86 MiniProgramJumpInfo: &MiniProgramJump{
87 Appid: wxpay_utility.String("example_appid"),
88 Path: wxpay_utility.String("example_path"),
89 },
90 MessageInfo: &MessageInfo{
91 Content: wxpay_utility.String("example_content"),
92 CustomData: wxpay_utility.String("example_custom_data"),
93 },
94 ActionId: wxpay_utility.String("example_action_id"),
95 },
96 InvalidInfo: &InvalidInfo{
97 ExpiredTime: wxpay_utility.String("example_expired_time"),
98 MultiClickable: wxpay_utility.Bool(false),
99 },
100 },
101 ButtonGroup: &ButtonGroup{
102 Buttons: []InnerButton{InnerButton{
103 Text: wxpay_utility.String("example_text"),
104 Action: &ClickAction{
105 ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
106 JumpUrl: wxpay_utility.String("example_jump_url"),
107 MiniProgramJumpInfo: &MiniProgramJump{
108 Appid: wxpay_utility.String("example_appid"),
109 Path: wxpay_utility.String("example_path"),
110 },
111 MessageInfo: &MessageInfo{
112 Content: wxpay_utility.String("example_content"),
113 CustomData: wxpay_utility.String("example_custom_data"),
114 },
115 ActionId: wxpay_utility.String("example_action_id"),
116 },
117 }},
118 ButtonLayout: BUTTONLAYOUT_LAYOUT_UNKNOWN.Ptr(),
119 InvalidInfo: &InvalidInfo{
120 ExpiredTime: wxpay_utility.String("example_expired_time"),
121 MultiClickable: wxpay_utility.Bool(false),
122 },
123 },
124 }},
125 SenderIdentity: SENDERIDENTITY_UNKNOWN.Ptr(),
126 CustomData: wxpay_utility.String("example_custom_data"),
127 },
128 IdempotentId: wxpay_utility.String("550e8400-e29b-41d4-a716-446655440000"),
129 }
130
131 response, err := ResponseComplaintImmediateService(config, request)
132 if err != nil {
133 fmt.Printf("请求失败: %+v\n", err)
134
135 return
136 }
137
138
139 fmt.Printf("请求成功: %+v\n", response)
140}
141
142func ResponseComplaintImmediateService(config *wxpay_utility.MchConfig, request *ResponseComplaintImmediateServiceRequest) (response *ResponseComplaintImmediateServiceResponse, err error) {
143 const (
144 host = "https://api.mch.weixin.qq.com"
145 method = "POST"
146 path = "/v3/merchant-service/complaints-v2/{complaint_id}/response-immediate-service"
147 )
148
149 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path))
150 if err != nil {
151 return nil, err
152 }
153 reqUrl.Path = strings.Replace(reqUrl.Path, "{complaint_id}", url.PathEscape(*request.ComplaintId), -1)
154 reqBody, err := json.Marshal(request)
155 if err != nil {
156 return nil, err
157 }
158 httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody))
159 if err != nil {
160 return nil, err
161 }
162 httpRequest.Header.Set("Accept", "application/json")
163 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId())
164 httpRequest.Header.Set("Content-Type", "application/json")
165 authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody)
166 if err != nil {
167 return nil, err
168 }
169 httpRequest.Header.Set("Authorization", authorization)
170
171 client := &http.Client{}
172 httpResponse, err := client.Do(httpRequest)
173 if err != nil {
174 return nil, err
175 }
176 respBody, err := wxpay_utility.ExtractResponseBody(httpResponse)
177 if err != nil {
178 return nil, err
179 }
180 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 {
181
182 err = wxpay_utility.ValidateResponse(
183 config.WechatPayPublicKeyId(),
184 config.WechatPayPublicKey(),
185 &httpResponse.Header,
186 respBody,
187 )
188 if err != nil {
189 return nil, err
190 }
191 response := &ResponseComplaintImmediateServiceResponse{}
192 if err := json.Unmarshal(respBody, response); err != nil {
193 return nil, err
194 }
195
196 return response, nil
197 } else {
198 return nil, wxpay_utility.NewApiException(
199 httpResponse.StatusCode,
200 httpResponse.Header,
201 respBody,
202 )
203 }
204}
205
206type ResponseComplaintImmediateServiceRequest struct {
207 ComplaintId *string `json:"complaint_id,omitempty"`
208 ComplaintedMchid *string `json:"complainted_mchid,omitempty"`
209 Message *NormalMessage `json:"message,omitempty"`
210 IdempotentId *string `json:"idempotent_id,omitempty"`
211}
212
213func (o *ResponseComplaintImmediateServiceRequest) MarshalJSON() ([]byte, error) {
214 type Alias ResponseComplaintImmediateServiceRequest
215 a := &struct {
216 ComplaintId *string `json:"complaint_id,omitempty"`
217 *Alias
218 }{
219
220 ComplaintId: nil,
221 Alias: (*Alias)(o),
222 }
223 return json.Marshal(a)
224}
225
226type ResponseComplaintImmediateServiceResponse struct {
227 LogId *string `json:"log_id,omitempty"`
228}
229
230type NormalMessage struct {
231 Blocks []Block `json:"blocks,omitempty"`
232 SenderIdentity *SenderIdentity `json:"sender_identity,omitempty"`
233 CustomData *string `json:"custom_data,omitempty"`
234}
235
236type Block struct {
237 Type *BlockType `json:"type,omitempty"`
238 Text *Text `json:"text,omitempty"`
239 Image *Image `json:"image,omitempty"`
240 Link *Link `json:"link,omitempty"`
241 FaqList *FaqList `json:"faq_list,omitempty"`
242 Button *Button `json:"button,omitempty"`
243 ButtonGroup *ButtonGroup `json:"button_group,omitempty"`
244}
245
246type SenderIdentity string
247
248func (e SenderIdentity) Ptr() *SenderIdentity {
249 return &e
250}
251
252const (
253 SENDERIDENTITY_UNKNOWN SenderIdentity = "UNKNOWN"
254 SENDERIDENTITY_MANUAL SenderIdentity = "MANUAL"
255 SENDERIDENTITY_MACHINE SenderIdentity = "MACHINE"
256)
257
258type BlockType string
259
260func (e BlockType) Ptr() *BlockType {
261 return &e
262}
263
264const (
265 BLOCKTYPE_TEXT BlockType = "TEXT"
266 BLOCKTYPE_IMAGE BlockType = "IMAGE"
267 BLOCKTYPE_LINK BlockType = "LINK"
268 BLOCKTYPE_FAQ_LIST BlockType = "FAQ_LIST"
269 BLOCKTYPE_BUTTON BlockType = "BUTTON"
270 BLOCKTYPE_BUTTON_GROUP BlockType = "BUTTON_GROUP"
271)
272
273type Text struct {
274 Text *string `json:"text,omitempty"`
275 Color *TextColor `json:"color,omitempty"`
276 IsBold *bool `json:"is_bold,omitempty"`
277}
278
279type Image struct {
280 MediaId *string `json:"media_id,omitempty"`
281 ImageStyleType *ImageStyleType `json:"image_style_type,omitempty"`
282}
283
284type Link struct {
285 Text *string `json:"text,omitempty"`
286 Action *ClickAction `json:"action,omitempty"`
287 InvalidInfo *InvalidInfo `json:"invalid_info,omitempty"`
288}
289
290type FaqList struct {
291 Faqs []FaqListItem `json:"faqs,omitempty"`
292}
293
294type Button struct {
295 Text *string `json:"text,omitempty"`
296 Action *ClickAction `json:"action,omitempty"`
297 InvalidInfo *InvalidInfo `json:"invalid_info,omitempty"`
298}
299
300type ButtonGroup struct {
301 Buttons []InnerButton `json:"buttons,omitempty"`
302 ButtonLayout *ButtonLayout `json:"button_layout,omitempty"`
303 InvalidInfo *InvalidInfo `json:"invalid_info,omitempty"`
304}
305
306type TextColor string
307
308func (e TextColor) Ptr() *TextColor {
309 return &e
310}
311
312const (
313 TEXTCOLOR_DEFAULT TextColor = "DEFAULT"
314 TEXTCOLOR_SECONDARY TextColor = "SECONDARY"
315)
316
317type ImageStyleType string
318
319func (e ImageStyleType) Ptr() *ImageStyleType {
320 return &e
321}
322
323const (
324 IMAGESTYLETYPE_IMAGE_STYLE_TYPE_NARROW ImageStyleType = "IMAGE_STYLE_TYPE_NARROW"
325 IMAGESTYLETYPE_IMAGE_STYLE_TYPE_WIDE ImageStyleType = "IMAGE_STYLE_TYPE_WIDE"
326)
327
328type ClickAction struct {
329 ActionType *ActionType `json:"action_type,omitempty"`
330 JumpUrl *string `json:"jump_url,omitempty"`
331 MiniProgramJumpInfo *MiniProgramJump `json:"mini_program_jump_info,omitempty"`
332 MessageInfo *MessageInfo `json:"message_info,omitempty"`
333 ActionId *string `json:"action_id,omitempty"`
334}
335
336type InvalidInfo struct {
337 ExpiredTime *string `json:"expired_time,omitempty"`
338 MultiClickable *bool `json:"multi_clickable,omitempty"`
339}
340
341type FaqListItem struct {
342 FaqId *string `json:"faq_id,omitempty"`
343 FaqTitle *string `json:"faq_title,omitempty"`
344 Action *ClickAction `json:"action,omitempty"`
345}
346
347type InnerButton struct {
348 Text *string `json:"text,omitempty"`
349 Action *ClickAction `json:"action,omitempty"`
350}
351
352type ButtonLayout string
353
354func (e ButtonLayout) Ptr() *ButtonLayout {
355 return &e
356}
357
358const (
359 BUTTONLAYOUT_LAYOUT_UNKNOWN ButtonLayout = "LAYOUT_UNKNOWN"
360 BUTTONLAYOUT_LAYOUT_HORIZONTAL ButtonLayout = "LAYOUT_HORIZONTAL"
361 BUTTONLAYOUT_LAYOUT_VERTICAL ButtonLayout = "LAYOUT_VERTICAL"
362)
363
364type ActionType string
365
366func (e ActionType) Ptr() *ActionType {
367 return &e
368}
369
370const (
371 ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE ActionType = "ACTION_TYPE_SEND_MESSAGE"
372 ACTIONTYPE_ACTION_TYPE_JUMP_URL ActionType = "ACTION_TYPE_JUMP_URL"
373 ACTIONTYPE_ACTION_TYPE_JUMP_MINI_PROGRAM ActionType = "ACTION_TYPE_JUMP_MINI_PROGRAM"
374)
375
376type MiniProgramJump struct {
377 Appid *string `json:"appid,omitempty"`
378 Path *string `json:"path,omitempty"`
379}
380
381type MessageInfo struct {
382 Content *string `json:"content,omitempty"`
383 CustomData *string `json:"custom_data,omitempty"`
384}
385