---
url: "https://pay.weixin.qq.com/doc/v3/partner/4012691648-java.md"
title: "查询投诉单详情-请求示例-java"
doc_id: 4012691648
example_lang: "java"
---

## Java


需配合微信支付工具库 WXPayUtility 使用，请参考 [Java](https://pay.weixin.qq.com/doc/v3/partner/4014985777.md)

```
package com.java.demo;

import com.java.utils.WXPayUtility; // 引用微信支付工具库，参考：https://pay.weixin.qq.com/doc/v3/partner/4014985777

import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 查询投诉单详情
 */
public class QueryComplaintV2 {
  private static String HOST = "https://api.mch.weixin.qq.com";
  private static String METHOD = "GET";
  private static String PATH = "/v3/merchant-service/complaints-v2/{complaint_id}";

  public static void main(String[] args) {
    // TODO: 请准备商户开发必要参数，参考：https://pay.weixin.qq.com/doc/v3/partner/4013080340
    QueryComplaintV2 client = new QueryComplaintV2(
      "19xxxxxxxx",                    // 商户号，是由微信支付系统生成并分配给每个商户的唯一标识符，商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340
      "1DDE55AD98Exxxxxxxxxx",         // 商户API证书序列号，如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924
      "/path/to/apiclient_key.pem",     // 商户API证书私钥文件路径，本地文件路径
      "PUB_KEY_ID_xxxxxxxxxxxxx",      // 微信支付公钥ID，如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589
      "/path/to/wxp_pub.pem"           // 微信支付公钥文件路径，本地文件路径
    );

    QueryComplaintV2Request request = new QueryComplaintV2Request();
    request.complaintId = "200201820200101080076610000";
    try {
      ComplaintInfo response = client.run(request);
        // TODO: 请求成功，继续业务逻辑
        System.out.println(response);
    } catch (WXPayUtility.ApiException e) {
        // TODO: 请求失败，根据状态码执行不同的逻辑
        e.printStackTrace();
    }
  }

  public ComplaintInfo run(QueryComplaintV2Request request) {
    String uri = PATH;
    uri = uri.replace("{complaint_id}", WXPayUtility.urlEncode(request.complaintId));

    Request.Builder reqBuilder = new Request.Builder().url(HOST + uri);
    reqBuilder.addHeader("Accept", "application/json");
    reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId);
    reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, null));
    reqBuilder.method(METHOD, null);
    Request httpRequest = reqBuilder.build();

    // 发送HTTP请求
    OkHttpClient client = new OkHttpClient.Builder().build();
    try (Response httpResponse = client.newCall(httpRequest).execute()) {
      String respBody = WXPayUtility.extractBody(httpResponse);
      if (httpResponse.code() >= 200 && httpResponse.code() < 300) {
        // 2XX 成功，验证应答签名
        WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey,
            httpResponse.headers(), respBody);

        // 从HTTP应答报文构建返回数据
        return WXPayUtility.fromJson(respBody, ComplaintInfo.class);
      } else {
        throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers());
      }
    } catch (IOException e) {
      throw new UncheckedIOException("Sending request to " + uri + " failed.", e);
    }
  }

  private final String mchid;
  private final String certificateSerialNo;
  private final PrivateKey privateKey;
  private final String wechatPayPublicKeyId;
  private final PublicKey wechatPayPublicKey;

  public QueryComplaintV2(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
    this.mchid = mchid;
    this.certificateSerialNo = certificateSerialNo;
    this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath);
    this.wechatPayPublicKeyId = wechatPayPublicKeyId;
    this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath);
  }

  public static class QueryComplaintV2Request {
    @SerializedName("complaint_id")
    @Expose(serialize = false)
    public String complaintId;
  }

  public static class ComplaintInfo {
    @SerializedName("complaint_id")
    public String complaintId;

    @SerializedName("complaint_time")
    public String complaintTime;

    @SerializedName("complaint_detail")
    public String complaintDetail;

    @SerializedName("complaint_state")
    public String complaintState;

    @SerializedName("complainted_mchid")
    public String complaintedMchid;

    @SerializedName("payer_phone")
    public String payerPhone;

    @SerializedName("payer_openid")
    public String payerOpenid;

    @SerializedName("complaint_order_info")
    public List<ComplaintOrderInfo> complaintOrderInfo;

    @SerializedName("complaint_full_refunded")
    public Boolean complaintFullRefunded;

    @SerializedName("incoming_user_response")
    public Boolean incomingUserResponse;

    @SerializedName("user_complaint_times")
    public Long userComplaintTimes;

    @SerializedName("complaint_media_list")
    public List<ComplaintMedia> complaintMediaList;

    @SerializedName("problem_description")
    public String problemDescription;

    @SerializedName("problem_type")
    public ProblemType problemType;

    @SerializedName("apply_refund_amount")
    public Long applyRefundAmount;

    @SerializedName("user_tag_list")
    public List<UserTag> userTagList;

    @SerializedName("service_order_info")
    public List<ServiceOrderInfo> serviceOrderInfo;

    @SerializedName("additional_info")
    public AdditionalInfo additionalInfo;

    @SerializedName("in_platform_service")
    public Boolean inPlatformService;

    @SerializedName("need_immediate_service")
    public Boolean needImmediateService;

    @SerializedName("is_agent_mode")
    public Boolean isAgentMode;
  }

  public static class ComplaintOrderInfo {
    @SerializedName("transaction_id")
    public String transactionId;

    @SerializedName("out_trade_no")
    public String outTradeNo;

    @SerializedName("amount")
    public Long amount;
  }

  public static class ComplaintMedia {
    @SerializedName("media_type")
    public ComplaintMediaType mediaType;

    @SerializedName("media_url")
    public List<String> mediaUrl = new ArrayList<String>();
  }

  public enum ProblemType {
    @SerializedName("REFUND")
    REFUND,
    @SerializedName("SERVICE_NOT_WORK")
    SERVICE_NOT_WORK,
    @SerializedName("OTHERS")
    OTHERS
  }

  public enum UserTag {
    @SerializedName("TRUSTED")
    TRUSTED,
    @SerializedName("HIGH_RISK")
    HIGH_RISK
  }

  public static class ServiceOrderInfo {
    @SerializedName("order_id")
    public String orderId;

    @SerializedName("out_order_no")
    public String outOrderNo;

    @SerializedName("state")
    public ServiceOrderState state;
  }

  public static class AdditionalInfo {
    @SerializedName("type")
    public AdditionalType type;

    @SerializedName("share_power_info")
    public SharePowerInfo sharePowerInfo;
  }

  public enum ComplaintMediaType {
    @SerializedName("USER_COMPLAINT_IMAGE")
    USER_COMPLAINT_IMAGE,
    @SerializedName("OPERATION_IMAGE")
    OPERATION_IMAGE
  }

  public enum ServiceOrderState {
    @SerializedName("DOING")
    DOING,
    @SerializedName("REVOKED")
    REVOKED,
    @SerializedName("WAITPAY")
    WAITPAY,
    @SerializedName("DONE")
    DONE
  }

  public enum AdditionalType {
    @SerializedName("SHARE_POWER_TYPE")
    SHARE_POWER_TYPE
  }

  public static class SharePowerInfo {
    @SerializedName("return_time")
    public String returnTime;

    @SerializedName("return_address_info")
    public ReturnAddressInfo returnAddressInfo;

    @SerializedName("is_returned_to_same_machine")
    public Boolean isReturnedToSameMachine;
  }

  public static class ReturnAddressInfo {
    @SerializedName("return_address")
    public String returnAddress;

    @SerializedName("longitude")
    public String longitude;

    @SerializedName("latitude")
    public String latitude;
  }

}

```
