回复需要即时服务的投诉单
更新时间:2026.01.22商户可通过调用此接口,针对需要即时服务的投诉单(need_immediate_service为true)提交内容回复用户。此接口支持使用新版消息格式(NormalMessage),可发送富文本、图片、按钮组等多种消息类型。其中上传图片凭证需首先调用商户上传反馈图片接口,得到图片id,再将id填入请求。
首次回复用户后,投诉单状态将由待处理更新为处理中。
接口说明
支持商户:【普通服务商】 【从业机构(银行)】 【从业机构(支付机构)】 【渠道商】 【清算机构】
请求方式:【POST】/v3/merchant-service/complaints-v2/{complaint_id}/response-immediate-service
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
Content-Type 必填 string
请设置为application/json
path 路径参数
complaint_id 必填 string(64)
【投诉单号】 投诉单对应的投诉单号
body 包体参数
complainted_mchid 必填 string(64)
【被诉商户号】 投诉单对应的被诉商户号
message 必填 object
【消息内容】 使用新版消息格式的消息内容,支持文本、图片、链接、推荐问题、按钮和按钮组等多种消息类型。商户可通过组合不同的消息块来构建丰富的回复内容
| 属性 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
blocks 选填 array[object] 【消息内容】 消息内容块列表,支持文本、图片、链接、推荐FAQ、按钮和按钮组等多种类型的消息块
sender_identity 选填 string 【发送者身份类别】 发送者身份类别,标识消息是由人工还是机器发送 可选取值
custom_data 选填 string(4096) 【自定义透传信息】 商户自定义的透传数据,用于传递业务相关信息 |
idempotent_id 必填 string(128)
【幂等ID】 幂等性控制ID,用于保证同一请求的重复提交不会产生重复操作。建议使用UUID或时间戳+随机字符串的组合,确保唯一性。相同idempotent_id的请求只会被处理一次
请求示例
POST
1curl -X POST \ 2 https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/200201820200101080076610000/response-immediate-service \ 3 -H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \ 4 -H "Accept: application/json" \ 5 -H "Content-Type: application/json" \ 6 -d '{ 7 "complainted_mchid" : "1900012181", 8 "message" : { 9 "blocks" : [ 10 { 11 "type" : "TEXT", 12 "text" : { 13 "text" : "example_text", 14 "color" : "DEFAULT", 15 "is_bold" : false 16 }, 17 "image" : { 18 "media_id" : "example_media_id", 19 "image_style_type" : "IMAGE_STYLE_TYPE_NARROW" 20 }, 21 "link" : { 22 "text" : "example_text", 23 "action" : { 24 "action_type" : "ACTION_TYPE_SEND_MESSAGE", 25 "jump_url" : "example_jump_url", 26 "mini_program_jump_info" : { 27 "appid" : "example_appid", 28 "path" : "example_path" 29 }, 30 "message_info" : { 31 "content" : "example_content", 32 "custom_data" : "example_custom_data" 33 }, 34 "action_id" : "example_action_id" 35 }, 36 "invalid_info" : { 37 "expired_time" : "example_expired_time", 38 "multi_clickable" : false 39 } 40 }, 41 "faq_list" : { 42 "faqs" : [ 43 { 44 "faq_id" : "example_faq_id", 45 "faq_title" : "example_faq_title", 46 "action" : { 47 "action_type" : "ACTION_TYPE_SEND_MESSAGE", 48 "jump_url" : "example_jump_url", 49 "mini_program_jump_info" : { 50 "appid" : "example_appid", 51 "path" : "example_path" 52 }, 53 "message_info" : { 54 "content" : "example_content", 55 "custom_data" : "example_custom_data" 56 }, 57 "action_id" : "example_action_id" 58 } 59 } 60 ] 61 }, 62 "button" : { 63 "text" : "example_text", 64 "action" : { 65 "action_type" : "ACTION_TYPE_SEND_MESSAGE", 66 "jump_url" : "example_jump_url", 67 "mini_program_jump_info" : { 68 "appid" : "example_appid", 69 "path" : "example_path" 70 }, 71 "message_info" : { 72 "content" : "example_content", 73 "custom_data" : "example_custom_data" 74 }, 75 "action_id" : "example_action_id" 76 }, 77 "invalid_info" : { 78 "expired_time" : "example_expired_time", 79 "multi_clickable" : false 80 } 81 }, 82 "button_group" : { 83 "buttons" : [ 84 { 85 "text" : "example_text", 86 "action" : { 87 "action_type" : "ACTION_TYPE_SEND_MESSAGE", 88 "jump_url" : "example_jump_url", 89 "mini_program_jump_info" : { 90 "appid" : "example_appid", 91 "path" : "example_path" 92 }, 93 "message_info" : { 94 "content" : "example_content", 95 "custom_data" : "example_custom_data" 96 }, 97 "action_id" : "example_action_id" 98 } 99 } 100 ], 101 "button_layout" : "LAYOUT_UNKNOWN", 102 "invalid_info" : { 103 "expired_time" : "example_expired_time", 104 "multi_clickable" : false 105 } 106 } 107 } 108 ], 109 "sender_identity" : "UNKNOWN", 110 "custom_data" : "example_custom_data" 111 }, 112 "idempotent_id" : "550e8400-e29b-41d4-a716-446655440000" 113 }' 114
需配合微信支付工具库 WXPayUtility 使用,请参考Java
1package com.java.demo; 2 3import com.java.utils.WXPayUtility; // 引用微信支付工具库,参考:https://pay.weixin.qq.com/doc/v3/partner/4014985777 4 5import com.google.gson.annotations.SerializedName; 6import com.google.gson.annotations.Expose; 7import okhttp3.MediaType; 8import okhttp3.OkHttpClient; 9import okhttp3.Request; 10import okhttp3.RequestBody; 11import okhttp3.Response; 12 13import java.io.IOException; 14import java.io.UncheckedIOException; 15import java.security.PrivateKey; 16import java.security.PublicKey; 17import java.util.ArrayList; 18import java.util.HashMap; 19import java.util.List; 20import java.util.Map; 21 22/** 23 * 回复需要即时服务的投诉单 24 */ 25public class ResponseComplaintImmediateService { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "POST"; 28 private static String PATH = "/v3/merchant-service/complaints-v2/{complaint_id}/response-immediate-service"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 32 ResponseComplaintImmediateService client = new ResponseComplaintImmediateService( 33 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 34 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 35 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 36 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 37 "/path/to/wxp_pub.pem" // 微信支付公钥文件路径,本地文件路径 38 ); 39 40 ResponseComplaintImmediateServiceRequest request = new ResponseComplaintImmediateServiceRequest(); 41 request.complaintId = "200201820200101080076610000"; 42 request.complaintedMchid = "1900012181"; 43 request.message = new NormalMessage(); 44 request.message.blocks = new ArrayList<>(); 45 { 46 Block blocksItem = new Block(); 47 blocksItem.type = BlockType.TEXT; 48 blocksItem.text = new Text(); 49 blocksItem.text.text = "example_text"; 50 blocksItem.text.color = TextColor.DEFAULT; 51 blocksItem.text.isBold = false; 52 blocksItem.image = new Image(); 53 blocksItem.image.mediaId = "example_media_id"; 54 blocksItem.image.imageStyleType = ImageStyleType.IMAGE_STYLE_TYPE_NARROW; 55 blocksItem.link = new Link(); 56 blocksItem.link.text = "example_text"; 57 blocksItem.link.action = new ClickAction(); 58 blocksItem.link.action.actionType = ActionType.ACTION_TYPE_SEND_MESSAGE; 59 blocksItem.link.action.jumpUrl = "example_jump_url"; 60 blocksItem.link.action.miniProgramJumpInfo = new MiniProgramJump(); 61 blocksItem.link.action.miniProgramJumpInfo.appid = "example_appid"; 62 blocksItem.link.action.miniProgramJumpInfo.path = "example_path"; 63 blocksItem.link.action.messageInfo = new MessageInfo(); 64 blocksItem.link.action.messageInfo.content = "example_content"; 65 blocksItem.link.action.messageInfo.customData = "example_custom_data"; 66 blocksItem.link.action.actionId = "example_action_id"; 67 blocksItem.link.invalidInfo = new InvalidInfo(); 68 blocksItem.link.invalidInfo.expiredTime = "example_expired_time"; 69 blocksItem.link.invalidInfo.multiClickable = false; 70 blocksItem.faqList = new FaqList(); 71 blocksItem.faqList.faqs = new ArrayList<>(); 72 { 73 FaqListItem faqsItem = new FaqListItem(); 74 faqsItem.faqId = "example_faq_id"; 75 faqsItem.faqTitle = "example_faq_title"; 76 faqsItem.action = new ClickAction(); 77 faqsItem.action.actionType = ActionType.ACTION_TYPE_SEND_MESSAGE; 78 faqsItem.action.jumpUrl = "example_jump_url"; 79 faqsItem.action.miniProgramJumpInfo = new MiniProgramJump(); 80 faqsItem.action.miniProgramJumpInfo.appid = "example_appid"; 81 faqsItem.action.miniProgramJumpInfo.path = "example_path"; 82 faqsItem.action.messageInfo = new MessageInfo(); 83 faqsItem.action.messageInfo.content = "example_content"; 84 faqsItem.action.messageInfo.customData = "example_custom_data"; 85 faqsItem.action.actionId = "example_action_id"; 86 blocksItem.faqList.faqs.add(faqsItem); 87 }; 88 blocksItem.button = new Button(); 89 blocksItem.button.text = "example_text"; 90 blocksItem.button.action = new ClickAction(); 91 blocksItem.button.action.actionType = ActionType.ACTION_TYPE_SEND_MESSAGE; 92 blocksItem.button.action.jumpUrl = "example_jump_url"; 93 blocksItem.button.action.miniProgramJumpInfo = new MiniProgramJump(); 94 blocksItem.button.action.miniProgramJumpInfo.appid = "example_appid"; 95 blocksItem.button.action.miniProgramJumpInfo.path = "example_path"; 96 blocksItem.button.action.messageInfo = new MessageInfo(); 97 blocksItem.button.action.messageInfo.content = "example_content"; 98 blocksItem.button.action.messageInfo.customData = "example_custom_data"; 99 blocksItem.button.action.actionId = "example_action_id"; 100 blocksItem.button.invalidInfo = new InvalidInfo(); 101 blocksItem.button.invalidInfo.expiredTime = "example_expired_time"; 102 blocksItem.button.invalidInfo.multiClickable = false; 103 blocksItem.buttonGroup = new ButtonGroup(); 104 blocksItem.buttonGroup.buttons = new ArrayList<>(); 105 { 106 InnerButton buttonsItem = new InnerButton(); 107 buttonsItem.text = "example_text"; 108 buttonsItem.action = new ClickAction(); 109 buttonsItem.action.actionType = ActionType.ACTION_TYPE_SEND_MESSAGE; 110 buttonsItem.action.jumpUrl = "example_jump_url"; 111 buttonsItem.action.miniProgramJumpInfo = new MiniProgramJump(); 112 buttonsItem.action.miniProgramJumpInfo.appid = "example_appid"; 113 buttonsItem.action.miniProgramJumpInfo.path = "example_path"; 114 buttonsItem.action.messageInfo = new MessageInfo(); 115 buttonsItem.action.messageInfo.content = "example_content"; 116 buttonsItem.action.messageInfo.customData = "example_custom_data"; 117 buttonsItem.action.actionId = "example_action_id"; 118 blocksItem.buttonGroup.buttons.add(buttonsItem); 119 }; 120 blocksItem.buttonGroup.buttonLayout = ButtonLayout.LAYOUT_UNKNOWN; 121 blocksItem.buttonGroup.invalidInfo = new InvalidInfo(); 122 blocksItem.buttonGroup.invalidInfo.expiredTime = "example_expired_time"; 123 blocksItem.buttonGroup.invalidInfo.multiClickable = false; 124 request.message.blocks.add(blocksItem); 125 }; 126 request.message.senderIdentity = SenderIdentity.UNKNOWN; 127 request.message.customData = "example_custom_data"; 128 request.idempotentId = "550e8400-e29b-41d4-a716-446655440000"; 129 try { 130 ResponseComplaintImmediateServiceResponse response = client.run(request); 131 // TODO: 请求成功,继续业务逻辑 132 System.out.println(response); 133 } catch (WXPayUtility.ApiException e) { 134 // TODO: 请求失败,根据状态码执行不同的逻辑 135 e.printStackTrace(); 136 } 137 } 138 139 public ResponseComplaintImmediateServiceResponse run(ResponseComplaintImmediateServiceRequest request) { 140 String uri = PATH; 141 uri = uri.replace("{complaint_id}", WXPayUtility.urlEncode(request.complaintId)); 142 String reqBody = WXPayUtility.toJson(request); 143 144 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 145 reqBuilder.addHeader("Accept", "application/json"); 146 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 147 reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo,privateKey, METHOD, uri, reqBody)); 148 reqBuilder.addHeader("Content-Type", "application/json"); 149 RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); 150 reqBuilder.method(METHOD, requestBody); 151 Request httpRequest = reqBuilder.build(); 152 153 // 发送HTTP请求 154 OkHttpClient client = new OkHttpClient.Builder().build(); 155 try (Response httpResponse = client.newCall(httpRequest).execute()) { 156 String respBody = WXPayUtility.extractBody(httpResponse); 157 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 158 // 2XX 成功,验证应答签名 159 WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 160 httpResponse.headers(), respBody); 161 162 // 从HTTP应答报文构建返回数据 163 return WXPayUtility.fromJson(respBody, ResponseComplaintImmediateServiceResponse.class); 164 } else { 165 throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 166 } 167 } catch (IOException e) { 168 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 169 } 170 } 171 172 private final String mchid; 173 private final String certificateSerialNo; 174 private final PrivateKey privateKey; 175 private final String wechatPayPublicKeyId; 176 private final PublicKey wechatPayPublicKey; 177 178 public ResponseComplaintImmediateService(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 179 this.mchid = mchid; 180 this.certificateSerialNo = certificateSerialNo; 181 this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); 182 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 183 this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 184 } 185 186 public static class ResponseComplaintImmediateServiceRequest { 187 @SerializedName("complaint_id") 188 @Expose(serialize = false) 189 public String complaintId; 190 191 @SerializedName("complainted_mchid") 192 public String complaintedMchid; 193 194 @SerializedName("message") 195 public NormalMessage message; 196 197 @SerializedName("idempotent_id") 198 public String idempotentId; 199 } 200 201 public static class ResponseComplaintImmediateServiceResponse { 202 @SerializedName("log_id") 203 public String logId; 204 } 205 206 public static class NormalMessage { 207 @SerializedName("blocks") 208 public List<Block> blocks; 209 210 @SerializedName("sender_identity") 211 public SenderIdentity senderIdentity; 212 213 @SerializedName("custom_data") 214 public String customData; 215 } 216 217 public static class Block { 218 @SerializedName("type") 219 public BlockType type; 220 221 @SerializedName("text") 222 public Text text; 223 224 @SerializedName("image") 225 public Image image; 226 227 @SerializedName("link") 228 public Link link; 229 230 @SerializedName("faq_list") 231 public FaqList faqList; 232 233 @SerializedName("button") 234 public Button button; 235 236 @SerializedName("button_group") 237 public ButtonGroup buttonGroup; 238 } 239 240 public enum SenderIdentity { 241 @SerializedName("UNKNOWN") 242 UNKNOWN, 243 @SerializedName("MANUAL") 244 MANUAL, 245 @SerializedName("MACHINE") 246 MACHINE 247 } 248 249 public enum BlockType { 250 @SerializedName("TEXT") 251 TEXT, 252 @SerializedName("IMAGE") 253 IMAGE, 254 @SerializedName("LINK") 255 LINK, 256 @SerializedName("FAQ_LIST") 257 FAQ_LIST, 258 @SerializedName("BUTTON") 259 BUTTON, 260 @SerializedName("BUTTON_GROUP") 261 BUTTON_GROUP 262 } 263 264 public static class Text { 265 @SerializedName("text") 266 public String text; 267 268 @SerializedName("color") 269 public TextColor color; 270 271 @SerializedName("is_bold") 272 public Boolean isBold; 273 } 274 275 public static class Image { 276 @SerializedName("media_id") 277 public String mediaId; 278 279 @SerializedName("image_style_type") 280 public ImageStyleType imageStyleType; 281 } 282 283 public static class Link { 284 @SerializedName("text") 285 public String text; 286 287 @SerializedName("action") 288 public ClickAction action; 289 290 @SerializedName("invalid_info") 291 public InvalidInfo invalidInfo; 292 } 293 294 public static class FaqList { 295 @SerializedName("faqs") 296 public List<FaqListItem> faqs; 297 } 298 299 public static class Button { 300 @SerializedName("text") 301 public String text; 302 303 @SerializedName("action") 304 public ClickAction action; 305 306 @SerializedName("invalid_info") 307 public InvalidInfo invalidInfo; 308 } 309 310 public static class ButtonGroup { 311 @SerializedName("buttons") 312 public List<InnerButton> buttons; 313 314 @SerializedName("button_layout") 315 public ButtonLayout buttonLayout; 316 317 @SerializedName("invalid_info") 318 public InvalidInfo invalidInfo; 319 } 320 321 public enum TextColor { 322 @SerializedName("DEFAULT") 323 DEFAULT, 324 @SerializedName("SECONDARY") 325 SECONDARY 326 } 327 328 public enum ImageStyleType { 329 @SerializedName("IMAGE_STYLE_TYPE_NARROW") 330 IMAGE_STYLE_TYPE_NARROW, 331 @SerializedName("IMAGE_STYLE_TYPE_WIDE") 332 IMAGE_STYLE_TYPE_WIDE 333 } 334 335 public static class ClickAction { 336 @SerializedName("action_type") 337 public ActionType actionType; 338 339 @SerializedName("jump_url") 340 public String jumpUrl; 341 342 @SerializedName("mini_program_jump_info") 343 public MiniProgramJump miniProgramJumpInfo; 344 345 @SerializedName("message_info") 346 public MessageInfo messageInfo; 347 348 @SerializedName("action_id") 349 public String actionId; 350 } 351 352 public static class InvalidInfo { 353 @SerializedName("expired_time") 354 public String expiredTime; 355 356 @SerializedName("multi_clickable") 357 public Boolean multiClickable; 358 } 359 360 public static class FaqListItem { 361 @SerializedName("faq_id") 362 public String faqId; 363 364 @SerializedName("faq_title") 365 public String faqTitle; 366 367 @SerializedName("action") 368 public ClickAction action; 369 } 370 371 public static class InnerButton { 372 @SerializedName("text") 373 public String text; 374 375 @SerializedName("action") 376 public ClickAction action; 377 } 378 379 public enum ButtonLayout { 380 @SerializedName("LAYOUT_UNKNOWN") 381 LAYOUT_UNKNOWN, 382 @SerializedName("LAYOUT_HORIZONTAL") 383 LAYOUT_HORIZONTAL, 384 @SerializedName("LAYOUT_VERTICAL") 385 LAYOUT_VERTICAL 386 } 387 388 public enum ActionType { 389 @SerializedName("ACTION_TYPE_SEND_MESSAGE") 390 ACTION_TYPE_SEND_MESSAGE, 391 @SerializedName("ACTION_TYPE_JUMP_URL") 392 ACTION_TYPE_JUMP_URL, 393 @SerializedName("ACTION_TYPE_JUMP_MINI_PROGRAM") 394 ACTION_TYPE_JUMP_MINI_PROGRAM 395 } 396 397 public static class MiniProgramJump { 398 @SerializedName("appid") 399 public String appid; 400 401 @SerializedName("path") 402 public String path; 403 } 404 405 public static class MessageInfo { 406 @SerializedName("content") 407 public String content; 408 409 @SerializedName("custom_data") 410 public String customData; 411 } 412 413} 414
需配合微信支付工具库 wxpay_utility 使用,请参考Go
1package main 2 3import ( 4 "bytes" 5 "demo/wxpay_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/v3/partner/4015119446 6 "encoding/json" 7 "fmt" 8 "net/http" 9 "net/url" 10 "strings" 11) 12 13func main() { 14 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 15 config, err := wxpay_utility.CreateMchConfig( 16 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 17 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 18 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 19 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 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 // TODO: 请求失败,根据状态码执行不同的处理 135 return 136 } 137 138 // TODO: 请求成功,继续业务逻辑 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 // 2XX 成功,验证应答签名 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 // 序列化时移除非 Body 字段 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
应答参数
200 OK
log_id 必填 string(64)
【操作流水号】 本次回复操作的操作流水号,可用于查询该操作的详细信息。该流水号与查询投诉单协商历史接口返回的log_id对应,可用于追踪和去重
应答示例
200 OK
1{ 2 "log_id" : "300285320210322170000071077" 3} 4
错误码
以下是本接口返回的错误码列表。详细错误码规则,请参考微信支付接口规则-错误码和错误提示

