---
url: "https://pay.weixin.qq.com/doc/v3/merchant/4017151596-go.md"
title: "回复需要即时服务的投诉单-请求示例-go"
doc_id: 4017151596
example_lang: "go"
---

## Go


需配合微信支付工具库 wxpay\_utility 使用，请参考 [Go](https://pay.weixin.qq.com/doc/v3/merchant/4015119334.md)

```
package main

import (
	"bytes"
	"demo/wxpay_utility" // 引用微信支付工具库，参考 https://pay.weixin.qq.com/doc/v3/merchant/4015119334
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
)

func main() {
	// TODO: 请准备商户开发必要参数，参考：https://pay.weixin.qq.com/doc/v3/merchant/4013070756
	config, err := wxpay_utility.CreateMchConfig(
		"19xxxxxxxx",                 // 商户号，是由微信支付系统生成并分配给每个商户的唯一标识符，商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/merchant/4013070756
		"1DDE55AD98Exxxxxxxxxx",      // 商户API证书序列号，如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053
		"/path/to/apiclient_key.pem", // 商户API证书私钥文件路径，本地文件路径
		"PUB_KEY_ID_xxxxxxxxxxxxx",   // 微信支付公钥ID，如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013038816
		"/path/to/wxp_pub.pem",       // 微信支付公钥文件路径，本地文件路径
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	request := &ResponseComplaintImmediateServiceRequest{
		ComplaintId:      wxpay_utility.String("200201820200101080076610000"),
		ComplaintedMchid: wxpay_utility.String("1900000001"),
		Message: &NormalMessage{
			Blocks: []Block{Block{
				Type: BLOCKTYPE_TEXT.Ptr(),
				Text: &Text{
					Text:   wxpay_utility.String("example_text"),
					Color:  TEXTCOLOR_DEFAULT.Ptr(),
					IsBold: wxpay_utility.Bool(false),
				},
				Image: &Image{
					MediaId:        wxpay_utility.String("example_media_id"),
					ImageStyleType: IMAGESTYLETYPE_IMAGE_STYLE_TYPE_NARROW.Ptr(),
				},
				Link: &Link{
					Text: wxpay_utility.String("example_text"),
					Action: &ClickAction{
						ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
						JumpUrl:    wxpay_utility.String("example_jump_url"),
						MiniProgramJumpInfo: &MiniProgramJump{
							Appid: wxpay_utility.String("example_appid"),
							Path:  wxpay_utility.String("example_path"),
						},
						MessageInfo: &MessageInfo{
							Content:    wxpay_utility.String("example_content"),
							CustomData: wxpay_utility.String("example_custom_data"),
						},
						ActionId: wxpay_utility.String("example_action_id"),
					},
					InvalidInfo: &InvalidInfo{
						ExpiredTime:    wxpay_utility.String("example_expired_time"),
						MultiClickable: wxpay_utility.Bool(false),
					},
				},
				FaqList: &FaqList{
					Faqs: []FaqListItem{FaqListItem{
						FaqId:    wxpay_utility.String("example_faq_id"),
						FaqTitle: wxpay_utility.String("example_faq_title"),
						Action: &ClickAction{
							ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
							JumpUrl:    wxpay_utility.String("example_jump_url"),
							MiniProgramJumpInfo: &MiniProgramJump{
								Appid: wxpay_utility.String("example_appid"),
								Path:  wxpay_utility.String("example_path"),
							},
							MessageInfo: &MessageInfo{
								Content:    wxpay_utility.String("example_content"),
								CustomData: wxpay_utility.String("example_custom_data"),
							},
							ActionId: wxpay_utility.String("example_action_id"),
						},
					}},
				},
				Button: &Button{
					Text: wxpay_utility.String("example_text"),
					Action: &ClickAction{
						ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
						JumpUrl:    wxpay_utility.String("example_jump_url"),
						MiniProgramJumpInfo: &MiniProgramJump{
							Appid: wxpay_utility.String("example_appid"),
							Path:  wxpay_utility.String("example_path"),
						},
						MessageInfo: &MessageInfo{
							Content:    wxpay_utility.String("example_content"),
							CustomData: wxpay_utility.String("example_custom_data"),
						},
						ActionId: wxpay_utility.String("example_action_id"),
					},
					InvalidInfo: &InvalidInfo{
						ExpiredTime:    wxpay_utility.String("example_expired_time"),
						MultiClickable: wxpay_utility.Bool(false),
					},
				},
				ButtonGroup: &ButtonGroup{
					Buttons: []InnerButton{InnerButton{
						Text: wxpay_utility.String("example_text"),
						Action: &ClickAction{
							ActionType: ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE.Ptr(),
							JumpUrl:    wxpay_utility.String("example_jump_url"),
							MiniProgramJumpInfo: &MiniProgramJump{
								Appid: wxpay_utility.String("example_appid"),
								Path:  wxpay_utility.String("example_path"),
							},
							MessageInfo: &MessageInfo{
								Content:    wxpay_utility.String("example_content"),
								CustomData: wxpay_utility.String("example_custom_data"),
							},
							ActionId: wxpay_utility.String("example_action_id"),
						},
					}},
					ButtonLayout: BUTTONLAYOUT_LAYOUT_UNKNOWN.Ptr(),
					InvalidInfo: &InvalidInfo{
						ExpiredTime:    wxpay_utility.String("example_expired_time"),
						MultiClickable: wxpay_utility.Bool(false),
					},
				},
			}},
			SenderIdentity: SENDERIDENTITY_UNKNOWN.Ptr(),
			CustomData:     wxpay_utility.String("example_custom_data"),
		},
		IdempotentId: wxpay_utility.String("550e8400-e29b-41d4-a716-446655440000"),
	}

	response, err := ResponseComplaintImmediateService(config, request)
	if err != nil {
		fmt.Printf("请求失败: %+v\n", err)
		// TODO: 请求失败，根据状态码执行不同的处理
		return
	}

	// TODO: 请求成功，继续业务逻辑
	fmt.Printf("请求成功: %+v\n", response)
}

func ResponseComplaintImmediateService(config *wxpay_utility.MchConfig, request *ResponseComplaintImmediateServiceRequest) (response *ResponseComplaintImmediateServiceResponse, err error) {
	const (
		host   = "https://api.mch.weixin.qq.com"
		method = "POST"
		path   = "/v3/merchant-service/complaints-v2/{complaint_id}/response-immediate-service"
	)

	reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path))
	if err != nil {
		return nil, err
	}
	reqUrl.Path = strings.Replace(reqUrl.Path, "{complaint_id}", url.PathEscape(*request.ComplaintId), -1)
	reqBody, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}
	httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody))
	if err != nil {
		return nil, err
	}
	httpRequest.Header.Set("Accept", "application/json")
	httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId())
	httpRequest.Header.Set("Content-Type", "application/json")
	authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody)
	if err != nil {
		return nil, err
	}
	httpRequest.Header.Set("Authorization", authorization)

	client := &http.Client{}
	httpResponse, err := client.Do(httpRequest)
	if err != nil {
		return nil, err
	}
	respBody, err := wxpay_utility.ExtractResponseBody(httpResponse)
	if err != nil {
		return nil, err
	}
	if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 {
		// 2XX 成功，验证应答签名
		err = wxpay_utility.ValidateResponse(
			config.WechatPayPublicKeyId(),
			config.WechatPayPublicKey(),
			&httpResponse.Header,
			respBody,
		)
		if err != nil {
			return nil, err
		}
		response := &ResponseComplaintImmediateServiceResponse{}
		if err := json.Unmarshal(respBody, response); err != nil {
			return nil, err
		}

		return response, nil
	} else {
		return nil, wxpay_utility.NewApiException(
			httpResponse.StatusCode,
			httpResponse.Header,
			respBody,
		)
	}
}

type ResponseComplaintImmediateServiceRequest struct {
	ComplaintId      *string        `json:"complaint_id,omitempty"`
	ComplaintedMchid *string        `json:"complainted_mchid,omitempty"`
	Message          *NormalMessage `json:"message,omitempty"`
	IdempotentId     *string        `json:"idempotent_id,omitempty"`
}

func (o *ResponseComplaintImmediateServiceRequest) MarshalJSON() ([]byte, error) {
	type Alias ResponseComplaintImmediateServiceRequest
	a := &struct {
		ComplaintId *string `json:"complaint_id,omitempty"`
		*Alias
	}{
		// 序列化时移除非 Body 字段
		ComplaintId: nil,
		Alias:       (*Alias)(o),
	}
	return json.Marshal(a)
}

type ResponseComplaintImmediateServiceResponse struct {
	LogId *string `json:"log_id,omitempty"`
}

type NormalMessage struct {
	Blocks         []Block         `json:"blocks,omitempty"`
	SenderIdentity *SenderIdentity `json:"sender_identity,omitempty"`
	CustomData     *string         `json:"custom_data,omitempty"`
}

type Block struct {
	Type        *BlockType   `json:"type,omitempty"`
	Text        *Text        `json:"text,omitempty"`
	Image       *Image       `json:"image,omitempty"`
	Link        *Link        `json:"link,omitempty"`
	FaqList     *FaqList     `json:"faq_list,omitempty"`
	Button      *Button      `json:"button,omitempty"`
	ButtonGroup *ButtonGroup `json:"button_group,omitempty"`
}

type SenderIdentity string

func (e SenderIdentity) Ptr() *SenderIdentity {
	return &e
}

const (
	SENDERIDENTITY_UNKNOWN SenderIdentity = "UNKNOWN"
	SENDERIDENTITY_MANUAL  SenderIdentity = "MANUAL"
	SENDERIDENTITY_MACHINE SenderIdentity = "MACHINE"
)

type BlockType string

func (e BlockType) Ptr() *BlockType {
	return &e
}

const (
	BLOCKTYPE_TEXT         BlockType = "TEXT"
	BLOCKTYPE_IMAGE        BlockType = "IMAGE"
	BLOCKTYPE_LINK         BlockType = "LINK"
	BLOCKTYPE_FAQ_LIST     BlockType = "FAQ_LIST"
	BLOCKTYPE_BUTTON       BlockType = "BUTTON"
	BLOCKTYPE_BUTTON_GROUP BlockType = "BUTTON_GROUP"
)

type Text struct {
	Text   *string    `json:"text,omitempty"`
	Color  *TextColor `json:"color,omitempty"`
	IsBold *bool      `json:"is_bold,omitempty"`
}

type Image struct {
	MediaId        *string         `json:"media_id,omitempty"`
	ImageStyleType *ImageStyleType `json:"image_style_type,omitempty"`
}

type Link struct {
	Text        *string      `json:"text,omitempty"`
	Action      *ClickAction `json:"action,omitempty"`
	InvalidInfo *InvalidInfo `json:"invalid_info,omitempty"`
}

type FaqList struct {
	Faqs []FaqListItem `json:"faqs,omitempty"`
}

type Button struct {
	Text        *string      `json:"text,omitempty"`
	Action      *ClickAction `json:"action,omitempty"`
	InvalidInfo *InvalidInfo `json:"invalid_info,omitempty"`
}

type ButtonGroup struct {
	Buttons      []InnerButton `json:"buttons,omitempty"`
	ButtonLayout *ButtonLayout `json:"button_layout,omitempty"`
	InvalidInfo  *InvalidInfo  `json:"invalid_info,omitempty"`
}

type TextColor string

func (e TextColor) Ptr() *TextColor {
	return &e
}

const (
	TEXTCOLOR_DEFAULT   TextColor = "DEFAULT"
	TEXTCOLOR_SECONDARY TextColor = "SECONDARY"
)

type ImageStyleType string

func (e ImageStyleType) Ptr() *ImageStyleType {
	return &e
}

const (
	IMAGESTYLETYPE_IMAGE_STYLE_TYPE_NARROW ImageStyleType = "IMAGE_STYLE_TYPE_NARROW"
	IMAGESTYLETYPE_IMAGE_STYLE_TYPE_WIDE   ImageStyleType = "IMAGE_STYLE_TYPE_WIDE"
)

type ClickAction struct {
	ActionType          *ActionType      `json:"action_type,omitempty"`
	JumpUrl             *string          `json:"jump_url,omitempty"`
	MiniProgramJumpInfo *MiniProgramJump `json:"mini_program_jump_info,omitempty"`
	MessageInfo         *MessageInfo     `json:"message_info,omitempty"`
	ActionId            *string          `json:"action_id,omitempty"`
}

type InvalidInfo struct {
	ExpiredTime    *string `json:"expired_time,omitempty"`
	MultiClickable *bool   `json:"multi_clickable,omitempty"`
}

type FaqListItem struct {
	FaqId    *string      `json:"faq_id,omitempty"`
	FaqTitle *string      `json:"faq_title,omitempty"`
	Action   *ClickAction `json:"action,omitempty"`
}

type InnerButton struct {
	Text   *string      `json:"text,omitempty"`
	Action *ClickAction `json:"action,omitempty"`
}

type ButtonLayout string

func (e ButtonLayout) Ptr() *ButtonLayout {
	return &e
}

const (
	BUTTONLAYOUT_LAYOUT_UNKNOWN    ButtonLayout = "LAYOUT_UNKNOWN"
	BUTTONLAYOUT_LAYOUT_HORIZONTAL ButtonLayout = "LAYOUT_HORIZONTAL"
	BUTTONLAYOUT_LAYOUT_VERTICAL   ButtonLayout = "LAYOUT_VERTICAL"
)

type ActionType string

func (e ActionType) Ptr() *ActionType {
	return &e
}

const (
	ACTIONTYPE_ACTION_TYPE_SEND_MESSAGE      ActionType = "ACTION_TYPE_SEND_MESSAGE"
	ACTIONTYPE_ACTION_TYPE_JUMP_URL          ActionType = "ACTION_TYPE_JUMP_URL"
	ACTIONTYPE_ACTION_TYPE_JUMP_MINI_PROGRAM ActionType = "ACTION_TYPE_JUMP_MINI_PROGRAM"
)

type MiniProgramJump struct {
	Appid *string `json:"appid,omitempty"`
	Path  *string `json:"path,omitempty"`
}

type MessageInfo struct {
	Content    *string `json:"content,omitempty"`
	CustomData *string `json:"custom_data,omitempty"`
}

```
