查询车牌服务开通信息
更新时间:2025.02.21该接口仅支持停车场景,商户首先请求查询车牌服务开通信息接口,确认该车牌,是否被该用户开通车主服务,以及车牌具体服务开通状态,包括正常服务,和暂停服务,以及未开通三个状态。
接口说明
支持商户:【普通服务商】
请求方式:【GET】/v3/vehicle/parking/services/find
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
query 查询参数
appid 必填 string(32)
【公众账号ID】AppID是商户在微信申请公众号或移动应用成功后分配的账号ID,登录平台为mp.weixin.qq.com或open.weixin.qq.com
sub_mchid 必填 string(32)
【子商户号】微信支付分配的子商户号,服务商模式下必传
plate_number 必填 string(32)
【车牌号】车牌号,仅包括省份+车牌,不包括特殊字符。
openid 必填 string(32)
【用户标识】用户在商户对应AppID下的唯一标识
plate_color 必填 string
【车牌颜色】车牌颜色
可选取值:
BLUE
: 蓝色
GREEN
: 绿色
YELLOW
: 黄色
BLACK
: 黑色
WHITE
: 白色
LIMEGREEN
: 黄绿色
请求示例
GET
1curl -X GET \ 2 https://api.mch.weixin.qq.com/v3/vehicle/parking/services/find?appid=wxcbda96de0b165486&sub_mchid=1900000109&plate_number=粤B888888&plate_color=BLUE&openid=oUpF8uMuAJOM2pxb1Q \ 3 -H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \ 4 -H "Accept: application/json" 5
需配合微信支付工具库 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 QueryPlateService { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "GET"; 28 private static String PATH = "/v3/vehicle/parking/services/find"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 32 QueryPlateService client = new QueryPlateService( 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 QueryPlateServiceRequest request = new QueryPlateServiceRequest(); 41 request.appid = "wxcbda96de0b165486"; 42 request.subMchid = "1900000109"; 43 request.plateNumber = "粤B888888"; 44 request.plateColor = PlateColor.BLUE; 45 request.openid = "oUpF8uMuAJOM2pxb1Q"; 46 try { 47 PlateService response = client.run(request); 48 // TODO: 请求成功,继续业务逻辑 49 System.out.println(response); 50 } catch (WXPayUtility.ApiException e) { 51 // TODO: 请求失败,根据状态码执行不同的逻辑 52 e.printStackTrace(); 53 } 54 } 55 56 public PlateService run(QueryPlateServiceRequest request) { 57 String uri = PATH; 58 Map<String, Object> args = new HashMap<>(); 59 args.put("appid", request.appid); 60 args.put("sub_mchid", request.subMchid); 61 args.put("plate_number", request.plateNumber); 62 args.put("plate_color", request.plateColor); 63 args.put("openid", request.openid); 64 String queryString = WXPayUtility.urlEncode(args); 65 if (!queryString.isEmpty()) { 66 uri = uri + "?" + queryString; 67 } 68 69 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 70 reqBuilder.addHeader("Accept", "application/json"); 71 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 72 reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, null)); 73 reqBuilder.method(METHOD, null); 74 Request httpRequest = reqBuilder.build(); 75 76 // 发送HTTP请求 77 OkHttpClient client = new OkHttpClient.Builder().build(); 78 try (Response httpResponse = client.newCall(httpRequest).execute()) { 79 String respBody = WXPayUtility.extractBody(httpResponse); 80 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 81 // 2XX 成功,验证应答签名 82 WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 83 httpResponse.headers(), respBody); 84 85 // 从HTTP应答报文构建返回数据 86 return WXPayUtility.fromJson(respBody, PlateService.class); 87 } else { 88 throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 89 } 90 } catch (IOException e) { 91 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 92 } 93 } 94 95 private final String mchid; 96 private final String certificateSerialNo; 97 private final PrivateKey privateKey; 98 private final String wechatPayPublicKeyId; 99 private final PublicKey wechatPayPublicKey; 100 101 public QueryPlateService(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 102 this.mchid = mchid; 103 this.certificateSerialNo = certificateSerialNo; 104 this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); 105 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 106 this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 107 } 108 109 public static class QueryPlateServiceRequest { 110 @SerializedName("appid") 111 @Expose(serialize = false) 112 public String appid; 113 114 @SerializedName("sub_mchid") 115 @Expose(serialize = false) 116 public String subMchid; 117 118 @SerializedName("plate_number") 119 @Expose(serialize = false) 120 public String plateNumber; 121 122 @SerializedName("openid") 123 @Expose(serialize = false) 124 public String openid; 125 126 @SerializedName("plate_color") 127 @Expose(serialize = false) 128 public PlateColor plateColor; 129 } 130 131 public static class PlateService { 132 @SerializedName("plate_number") 133 public String plateNumber; 134 135 @SerializedName("plate_color") 136 public PlateColor plateColor; 137 138 @SerializedName("service_open_time") 139 public String serviceOpenTime; 140 141 @SerializedName("openid") 142 public String openid; 143 144 @SerializedName("service_state") 145 public String serviceState; 146 } 147 148 public enum PlateColor { 149 @SerializedName("BLUE") 150 BLUE, 151 @SerializedName("GREEN") 152 GREEN, 153 @SerializedName("YELLOW") 154 YELLOW, 155 @SerializedName("BLACK") 156 BLACK, 157 @SerializedName("WHITE") 158 WHITE, 159 @SerializedName("LIMEGREEN") 160 LIMEGREEN 161 } 162 163} 164
需配合微信支付工具库 wxpay_utility 使用,请参考Go
1package main 2 3import ( 4 "demo/wxpay_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/v3/partner/4015119446 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9 "time" 10) 11 12func main() { 13 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 14 config, err := wxpay_utility.CreateMchConfig( 15 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 16 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 17 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 18 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 19 "/path/to/wxp_pub.pem", // 微信支付公钥文件路径,本地文件路径 20 ) 21 if err != nil { 22 fmt.Println(err) 23 return 24 } 25 26 request := &QueryPlateServiceRequest{ 27 Appid: wxpay_utility.String("wxcbda96de0b165486"), 28 SubMchid: wxpay_utility.String("1900000109"), 29 PlateNumber: wxpay_utility.String("粤B888888"), 30 PlateColor: PLATECOLOR_BLUE.Ptr(), 31 Openid: wxpay_utility.String("oUpF8uMuAJOM2pxb1Q"), 32 } 33 34 response, err := QueryPlateService(config, request) 35 if err != nil { 36 fmt.Printf("请求失败: %+v\n", err) 37 // TODO: 请求失败,根据状态码执行不同的处理 38 return 39 } 40 41 // TODO: 请求成功,继续业务逻辑 42 fmt.Printf("请求成功: %+v\n", response) 43} 44 45func QueryPlateService(config *wxpay_utility.MchConfig, request *QueryPlateServiceRequest) (response *PlateService, err error) { 46 const ( 47 host = "https://api.mch.weixin.qq.com" 48 method = "GET" 49 path = "/v3/vehicle/parking/services/find" 50 ) 51 52 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 53 if err != nil { 54 return nil, err 55 } 56 query := reqUrl.Query() 57 if request.Appid != nil { 58 query.Add("appid", *request.Appid) 59 } 60 if request.SubMchid != nil { 61 query.Add("sub_mchid", *request.SubMchid) 62 } 63 if request.PlateNumber != nil { 64 query.Add("plate_number", *request.PlateNumber) 65 } 66 if request.PlateColor != nil { 67 query.Add("plate_color", fmt.Sprintf("%v", *request.PlateColor)) 68 } 69 if request.Openid != nil { 70 query.Add("openid", *request.Openid) 71 } 72 reqUrl.RawQuery = query.Encode() 73 httpRequest, err := http.NewRequest(method, reqUrl.String(), nil) 74 if err != nil { 75 return nil, err 76 } 77 httpRequest.Header.Set("Accept", "application/json") 78 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 79 authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), nil) 80 if err != nil { 81 return nil, err 82 } 83 httpRequest.Header.Set("Authorization", authorization) 84 85 client := &http.Client{} 86 httpResponse, err := client.Do(httpRequest) 87 if err != nil { 88 return nil, err 89 } 90 respBody, err := wxpay_utility.ExtractResponseBody(httpResponse) 91 if err != nil { 92 return nil, err 93 } 94 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 95 // 2XX 成功,验证应答签名 96 err = wxpay_utility.ValidateResponse( 97 config.WechatPayPublicKeyId(), 98 config.WechatPayPublicKey(), 99 &httpResponse.Header, 100 respBody, 101 ) 102 if err != nil { 103 return nil, err 104 } 105 response := &PlateService{} 106 if err := json.Unmarshal(respBody, response); err != nil { 107 return nil, err 108 } 109 110 return response, nil 111 } else { 112 return nil, wxpay_utility.NewApiException( 113 httpResponse.StatusCode, 114 httpResponse.Header, 115 respBody, 116 ) 117 } 118} 119 120type QueryPlateServiceRequest struct { 121 Appid *string `json:"appid,omitempty"` 122 SubMchid *string `json:"sub_mchid,omitempty"` 123 PlateNumber *string `json:"plate_number,omitempty"` 124 Openid *string `json:"openid,omitempty"` 125 PlateColor *PlateColor `json:"plate_color,omitempty"` 126} 127 128func (o *QueryPlateServiceRequest) MarshalJSON() ([]byte, error) { 129 type Alias QueryPlateServiceRequest 130 a := &struct { 131 Appid *string `json:"appid,omitempty"` 132 SubMchid *string `json:"sub_mchid,omitempty"` 133 PlateNumber *string `json:"plate_number,omitempty"` 134 Openid *string `json:"openid,omitempty"` 135 PlateColor *PlateColor `json:"plate_color,omitempty"` 136 *Alias 137 }{ 138 // 序列化时移除非 Body 字段 139 Appid: nil, 140 SubMchid: nil, 141 PlateNumber: nil, 142 Openid: nil, 143 PlateColor: nil, 144 Alias: (*Alias)(o), 145 } 146 return json.Marshal(a) 147} 148 149type PlateService struct { 150 PlateNumber *string `json:"plate_number,omitempty"` 151 PlateColor *PlateColor `json:"plate_color,omitempty"` 152 ServiceOpenTime *time.Time `json:"service_open_time,omitempty"` 153 Openid *string `json:"openid,omitempty"` 154 ServiceState *string `json:"service_state,omitempty"` 155} 156 157type PlateColor string 158 159func (e PlateColor) Ptr() *PlateColor { 160 return &e 161} 162 163const ( 164 PLATECOLOR_BLUE PlateColor = "BLUE" 165 PLATECOLOR_GREEN PlateColor = "GREEN" 166 PLATECOLOR_YELLOW PlateColor = "YELLOW" 167 PLATECOLOR_BLACK PlateColor = "BLACK" 168 PLATECOLOR_WHITE PlateColor = "WHITE" 169 PLATECOLOR_LIMEGREEN PlateColor = "LIMEGREEN" 170) 171
应答参数
|
plate_number 必填 string(32)
【车牌号】车牌号,仅包括省份+车牌,不包括特殊字符。
plate_color 必填 string
【车牌颜色】车牌颜色
可选取值:
BLUE
: 蓝色
GREEN
: 绿色
YELLOW
: 黄色
BLACK
: 黑色
WHITE
: 白色
LIMEGREEN
: 黄绿色
service_open_time 选填 string(32)
【车牌服务开通时间】车牌服务开通时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒。
openid 必填 string(32)
【用户标识】用户在商户对应AppID下的唯一标识,此处返回商户请求中的OpenID
service_state 必填 string(32)
【车牌服务开通状态】车牌服务开通状态,
NORMAL 正常服务
PAUSE 暂停服务
OUT_SERVICE 未开通
商户根据状态带用户跳转至对应的微信支付分停车服务小程序页面。 其中NORMAL 和 PAUSE状态,可跳转至车牌管理页,进行车牌服务状态管理。OUT_SERVICE状态,可跳转至服务开通页面。
应答示例
200 OK
1{ 2 "plate_number" : "粤B888888", 3 "plate_color" : "BLUE", 4 "service_open_time" : "2017-08-26T10:43:39+08:00", 5 "openid" : "oUpF8uMuAJOM2pxb1Q", 6 "service_state" : "PAUSE" 7} 8
错误码
公共错误码
状态码 | 错误码 | 描述 | 解决方案 |
---|---|---|---|
400 | PARAM_ERROR | 参数错误 | 请根据错误提示正确传入参数 |
400 | INVALID_REQUEST | HTTP 请求不符合微信支付 APIv3 接口规则 | 请参阅 接口规则 |
401 | SIGN_ERROR | 验证不通过 | 请参阅 签名常见问题 |
500 | SYSTEM_ERROR | 系统异常,请稍后重试 | 请稍后重试 |
业务错误码
状态码 | 错误码 | 描述 | 解决方案 |
---|---|---|---|
400 | INVALID_REQUEST | 子商户号不存在,请检查后再试 | 商户所传子商户号不存在,请使用正确的子商户号进行接口请求 |
400 | INVALID_REQUEST | 用户信息有误,请检查OpenID | 使用正确的微信OpenID重试 |
403 | NO_AUTH | 商户未入驻 | 当前扣款商户无权限扣款,请确认当前扣款商户已开通微信支付分停车产品权限。修复商户权限后可原参数重试 |
429 | RATELIMIT_EXCEEDED | 达到调用速率限制 | 接口调用频率过快,请降低请求频率 |
500 | SYSTEM_ERROR | 出现内部服务器错误 | 5开头的错误码均为系统错误,请使用相同的参数稍后重试 |