分页查询投放计划列表
更新时间:2026.03.16分页查询投放计划列表
接口说明
支持商户:【品牌商户】
请求方式:【GET】/brand/marketing/delivery-plan/delivery-plans
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
接口限频:100/秒(品牌ID维度)
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
Wechatpay-Serial 必填 string
【微信支付公钥ID】 请传入brand_id对应的微信支付公钥ID,接口将会校验两者的关联关系,参考微信支付公钥产品简介及使用说明获取微信支付公钥ID和相关的介绍。以下两种场景将使用到微信支付公钥: 1、接收到接口的返回内容,需要使用微信支付公钥进行验签; 2、调用含有敏感信息参数(如姓名、身份证号码)的接口时,需要使用微信支付公钥加密敏感信息后再传输参数,加密指引请参考微信支付公钥加密敏感信息指引。
query 查询参数
page_size 选填 integer
【分页大小】 批量查询下每页的数量,最大不超过50。不填默认为10。
offset 选填 integer
【offset】 该次请求资源的起始位置。第一页从0开始
plan_state 选填 string
【投放计划状态】 不填写表示查询所有状态的投放计划,填写表示查询特定状态的投放计划。已终止、已过期是终态。
可选取值
CREATED: 创建成功TERMINATED: 已终止EXPIRED: 已过期DELIVERING: 投放中PAUSED: 已暂停
audit_state 选填 string
【投放计划审核状态】 不填写表示查询所有审核状态的投放计划,填写则表示查询特定状态的投放计划。
可选取值
AUDIT_INITIAL: 待提审AUDIT_PROCESSING: 审批中AUDIT_PASSED: 审批通过AUDIT_REJECTED: 审批拒绝
plan_id 选填 string
【投放计划ID】 投放计划ID,如果填入该字段,则只返回该ID对应的投放计划
请求示例
GET
1curl -X GET \ 2 https://api.mch.weixin.qq.com/brand/marketing/delivery-plan/delivery-plans?page_size=5&offset=10&plan_state=CREATED&audit_state=AUDIT_INITIAL&plan_id=12000 \ 3 -H "Authorization: WECHATPAY-BRAND-SHA256-RSA2048 brand_id=\"XXXX\",..." \ 4 -H "Accept: application/json" \ 5 -H "Wechatpay-Serial: PUB_KEY_ID_XXXX" 6
需配合微信支付工具库 WXPayUtility 使用,请参考Java
1package com.java.demo; 2 3import com.java.utils.WXPayBrandUtility; // 引用微信支付工具库,参考:https://pay.weixin.qq.com/doc/brand/4015826861 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 ListDeliveryPlans { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "GET"; 28 private static String PATH = "/brand/marketing/delivery-plan/delivery-plans"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/brand/4015415289 32 ListDeliveryPlans client = new ListDeliveryPlans( 33 "xxxxxxxx", // 品牌ID,是由微信支付系统生成并分配给每个品牌方的唯一标识符,品牌ID获取方式参考 https://pay.weixin.qq.com/doc/brand/4015415289 34 "1DDE55AD98Exxxxxxxxxx", // 品牌API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015407570 35 "/path/to/apiclient_key.pem", // 品牌API证书私钥文件路径,本地文件路径 36 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015453439 37 "/path/to/wxp_pub.pem" // 微信支付公钥文件路径,本地文件路径 38 ); 39 40 ListDeliveryPlansRequest request = new ListDeliveryPlansRequest(); 41 request.pageSize = 5L; 42 request.offset = 10L; 43 request.planState = PlanState.CREATED; 44 request.auditState = PlanAuditState.AUDIT_INITIAL; 45 request.planId = "12000"; 46 try { 47 ListDeliveryPlansResponse response = client.run(request); 48 // TODO: 请求成功,继续业务逻辑 49 System.out.println(response); 50 } catch (WXPayBrandUtility.ApiException e) { 51 // TODO: 请求失败,根据状态码执行不同的逻辑 52 e.printStackTrace(); 53 } 54 } 55 56 public ListDeliveryPlansResponse run(ListDeliveryPlansRequest request) { 57 String uri = PATH; 58 Map<String, Object> args = new HashMap<>(); 59 args.put("page_size", request.pageSize); 60 args.put("offset", request.offset); 61 args.put("plan_state", request.planState); 62 args.put("audit_state", request.auditState); 63 args.put("plan_id", request.planId); 64 String queryString = WXPayBrandUtility.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", WXPayBrandUtility.buildAuthorization(brand_id, 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 = WXPayBrandUtility.extractBody(httpResponse); 80 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 81 // 2XX 成功,验证应答签名 82 WXPayBrandUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 83 httpResponse.headers(), respBody); 84 85 // 从HTTP应答报文构建返回数据 86 return WXPayBrandUtility.fromJson(respBody, ListDeliveryPlansResponse.class); 87 } else { 88 throw new WXPayBrandUtility.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 brand_id; 96 private final String certificateSerialNo; 97 private final PrivateKey privateKey; 98 private final String wechatPayPublicKeyId; 99 private final PublicKey wechatPayPublicKey; 100 101 public ListDeliveryPlans(String brand_id, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 102 this.brand_id = brand_id; 103 this.certificateSerialNo = certificateSerialNo; 104 this.privateKey = WXPayBrandUtility.loadPrivateKeyFromPath(privateKeyFilePath); 105 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 106 this.wechatPayPublicKey = WXPayBrandUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 107 } 108 109 public static class ListDeliveryPlansRequest { 110 @SerializedName("page_size") 111 @Expose(serialize = false) 112 public Long pageSize; 113 114 @SerializedName("offset") 115 @Expose(serialize = false) 116 public Long offset; 117 118 @SerializedName("plan_id") 119 @Expose(serialize = false) 120 public String planId; 121 122 @SerializedName("plan_state") 123 @Expose(serialize = false) 124 public PlanState planState; 125 126 @SerializedName("audit_state") 127 @Expose(serialize = false) 128 public PlanAuditState auditState; 129 } 130 131 public static class ListDeliveryPlansResponse { 132 @SerializedName("total_count") 133 public Long totalCount; 134 135 @SerializedName("plan_list") 136 public List<DeliveryPlan> planList; 137 } 138 139 public enum PlanState { 140 @SerializedName("CREATED") 141 CREATED, 142 @SerializedName("TERMINATED") 143 TERMINATED, 144 @SerializedName("EXPIRED") 145 EXPIRED, 146 @SerializedName("DELIVERING") 147 DELIVERING, 148 @SerializedName("PAUSED") 149 PAUSED 150 } 151 152 public enum PlanAuditState { 153 @SerializedName("AUDIT_INITIAL") 154 AUDIT_INITIAL, 155 @SerializedName("AUDIT_PROCESSING") 156 AUDIT_PROCESSING, 157 @SerializedName("AUDIT_PASSED") 158 AUDIT_PASSED, 159 @SerializedName("AUDIT_REJECTED") 160 AUDIT_REJECTED 161 } 162 163 public static class DeliveryPlan { 164 @SerializedName("plan_id") 165 public String planId; 166 167 @SerializedName("plan_name") 168 public String planName; 169 170 @SerializedName("plan_state") 171 public PlanState planState; 172 173 @SerializedName("delivery_start_time") 174 public String deliveryStartTime; 175 176 @SerializedName("delivery_end_time") 177 public String deliveryEndTime; 178 179 @SerializedName("product_coupon_id") 180 public String productCouponId; 181 182 @SerializedName("usage_mode") 183 public ProductUsageMode usageMode; 184 185 @SerializedName("stock_id") 186 public String stockId; 187 188 @SerializedName("stock_bundle_id") 189 public String stockBundleId; 190 191 @SerializedName("recommend_word") 192 public String recommendWord; 193 194 @SerializedName("total_count") 195 public Long totalCount; 196 197 @SerializedName("user_limit") 198 public Long userLimit; 199 200 @SerializedName("daily_limit") 201 public Long dailyLimit; 202 203 @SerializedName("reuse_coupon_config") 204 public Boolean reuseCouponConfig; 205 206 @SerializedName("brand_id") 207 public String brandId; 208 } 209 210 public enum ProductUsageMode { 211 @SerializedName("SINGLE") 212 SINGLE, 213 @SerializedName("PROGRESSIVE_BUNDLE") 214 PROGRESSIVE_BUNDLE 215 } 216 217} 218
需配合微信支付工具库 wxpay_utility 使用,请参考Go
1package main 2 3import ( 4 "demo/wxpay_brand_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/brand/4015826866 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9) 10 11func main() { 12 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/brand/4015415289 13 config, err := wxpay_brand_utility.CreateBrandConfig( 14 "xxxxxxxx", // 品牌ID,是由微信支付系统生成并分配给每个品牌方的唯一标识符,品牌ID获取方式参考 https://pay.weixin.qq.com/doc/brand/4015415289 15 "1DDE55AD98Exxxxxxxxxx", // 品牌API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015407570 16 "/path/to/apiclient_key.pem", // 品牌API证书私钥文件路径,本地文件路径 17 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015453439 18 "/path/to/wxp_pub.pem", // 微信支付公钥文件路径,本地文件路径 19 ) 20 if err != nil { 21 fmt.Println(err) 22 return 23 } 24 25 request := &ListDeliveryPlansRequest{ 26 PageSize: wxpay_brand_utility.Int64(5), 27 Offset: wxpay_brand_utility.Int64(10), 28 PlanState: PLANSTATE_CREATED.Ptr(), 29 AuditState: PLANAUDITSTATE_AUDIT_INITIAL.Ptr(), 30 PlanId: wxpay_brand_utility.String("12000"), 31 } 32 33 response, err := ListDeliveryPlans(config, request) 34 if err != nil { 35 fmt.Printf("请求失败: %+v\n", err) 36 // TODO: 请求失败,根据状态码执行不同的处理 37 return 38 } 39 40 // TODO: 请求成功,继续业务逻辑 41 fmt.Printf("请求成功: %+v\n", response) 42} 43 44func ListDeliveryPlans(config *wxpay_brand_utility.BrandConfig, request *ListDeliveryPlansRequest) (response *ListDeliveryPlansResponse, err error) { 45 const ( 46 host = "https://api.mch.weixin.qq.com" 47 method = "GET" 48 path = "/brand/marketing/delivery-plan/delivery-plans" 49 ) 50 51 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 52 if err != nil { 53 return nil, err 54 } 55 query := reqUrl.Query() 56 if request.PageSize != nil { 57 query.Add("page_size", fmt.Sprintf("%v", *request.PageSize)) 58 } 59 if request.Offset != nil { 60 query.Add("offset", fmt.Sprintf("%v", *request.Offset)) 61 } 62 if request.PlanState != nil { 63 query.Add("plan_state", fmt.Sprintf("%v", *request.PlanState)) 64 } 65 if request.AuditState != nil { 66 query.Add("audit_state", fmt.Sprintf("%v", *request.AuditState)) 67 } 68 if request.PlanId != nil { 69 query.Add("plan_id", *request.PlanId) 70 } 71 reqUrl.RawQuery = query.Encode() 72 httpRequest, err := http.NewRequest(method, reqUrl.String(), nil) 73 if err != nil { 74 return nil, err 75 } 76 httpRequest.Header.Set("Accept", "application/json") 77 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 78 authorization, err := wxpay_brand_utility.BuildAuthorization(config.BrandId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), nil) 79 if err != nil { 80 return nil, err 81 } 82 httpRequest.Header.Set("Authorization", authorization) 83 84 client := &http.Client{} 85 httpResponse, err := client.Do(httpRequest) 86 if err != nil { 87 return nil, err 88 } 89 respBody, err := wxpay_brand_utility.ExtractResponseBody(httpResponse) 90 if err != nil { 91 return nil, err 92 } 93 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 94 // 2XX 成功,验证应答签名 95 err = wxpay_brand_utility.ValidateResponse( 96 config.WechatPayPublicKeyId(), 97 config.WechatPayPublicKey(), 98 &httpResponse.Header, 99 respBody, 100 ) 101 if err != nil { 102 return nil, err 103 } 104 response := &ListDeliveryPlansResponse{} 105 if err := json.Unmarshal(respBody, response); err != nil { 106 return nil, err 107 } 108 109 return response, nil 110 } else { 111 return nil, wxpay_brand_utility.NewApiException( 112 httpResponse.StatusCode, 113 httpResponse.Header, 114 respBody, 115 ) 116 } 117} 118 119type ListDeliveryPlansRequest struct { 120 PageSize *int64 `json:"page_size,omitempty"` 121 Offset *int64 `json:"offset,omitempty"` 122 PlanId *string `json:"plan_id,omitempty"` 123 PlanState *PlanState `json:"plan_state,omitempty"` 124 AuditState *PlanAuditState `json:"audit_state,omitempty"` 125} 126 127func (o *ListDeliveryPlansRequest) MarshalJSON() ([]byte, error) { 128 type Alias ListDeliveryPlansRequest 129 a := &struct { 130 PageSize *int64 `json:"page_size,omitempty"` 131 Offset *int64 `json:"offset,omitempty"` 132 PlanId *string `json:"plan_id,omitempty"` 133 PlanState *PlanState `json:"plan_state,omitempty"` 134 AuditState *PlanAuditState `json:"audit_state,omitempty"` 135 *Alias 136 }{ 137 // 序列化时移除非 Body 字段 138 PageSize: nil, 139 Offset: nil, 140 PlanId: nil, 141 PlanState: nil, 142 AuditState: nil, 143 Alias: (*Alias)(o), 144 } 145 return json.Marshal(a) 146} 147 148type ListDeliveryPlansResponse struct { 149 TotalCount *int64 `json:"total_count,omitempty"` 150 PlanList []DeliveryPlan `json:"plan_list,omitempty"` 151} 152 153type PlanState string 154 155func (e PlanState) Ptr() *PlanState { 156 return &e 157} 158 159const ( 160 PLANSTATE_CREATED PlanState = "CREATED" 161 PLANSTATE_TERMINATED PlanState = "TERMINATED" 162 PLANSTATE_EXPIRED PlanState = "EXPIRED" 163 PLANSTATE_DELIVERING PlanState = "DELIVERING" 164 PLANSTATE_PAUSED PlanState = "PAUSED" 165) 166 167type PlanAuditState string 168 169func (e PlanAuditState) Ptr() *PlanAuditState { 170 return &e 171} 172 173const ( 174 PLANAUDITSTATE_AUDIT_INITIAL PlanAuditState = "AUDIT_INITIAL" 175 PLANAUDITSTATE_AUDIT_PROCESSING PlanAuditState = "AUDIT_PROCESSING" 176 PLANAUDITSTATE_AUDIT_PASSED PlanAuditState = "AUDIT_PASSED" 177 PLANAUDITSTATE_AUDIT_REJECTED PlanAuditState = "AUDIT_REJECTED" 178) 179 180type DeliveryPlan struct { 181 PlanId *string `json:"plan_id,omitempty"` 182 PlanName *string `json:"plan_name,omitempty"` 183 PlanState *PlanState `json:"plan_state,omitempty"` 184 DeliveryStartTime *string `json:"delivery_start_time,omitempty"` 185 DeliveryEndTime *string `json:"delivery_end_time,omitempty"` 186 ProductCouponId *string `json:"product_coupon_id,omitempty"` 187 UsageMode *ProductUsageMode `json:"usage_mode,omitempty"` 188 StockId *string `json:"stock_id,omitempty"` 189 StockBundleId *string `json:"stock_bundle_id,omitempty"` 190 RecommendWord *string `json:"recommend_word,omitempty"` 191 TotalCount *int64 `json:"total_count,omitempty"` 192 UserLimit *int64 `json:"user_limit,omitempty"` 193 DailyLimit *int64 `json:"daily_limit,omitempty"` 194 ReuseCouponConfig *bool `json:"reuse_coupon_config,omitempty"` 195 BrandId *string `json:"brand_id,omitempty"` 196} 197 198type ProductUsageMode string 199 200func (e ProductUsageMode) Ptr() *ProductUsageMode { 201 return &e 202} 203 204const ( 205 PRODUCTUSAGEMODE_SINGLE ProductUsageMode = "SINGLE" 206 PRODUCTUSAGEMODE_PROGRESSIVE_BUNDLE ProductUsageMode = "PROGRESSIVE_BUNDLE" 207) 208
应答参数
200 OK
total_count 必填 integer
【资源总条数】 返回资源总条数
plan_list 选填 array[object]
【投放计划列表】 投放计划列表,当有满足查询条件的投放计划时返回该字段
| 属性 | |
plan_id 必填 string(32) 【投放计划ID】 投放计划ID plan_name 必填 string(36) 【投放计划名称】 投放计划名称 plan_state 必填 string 【投放计划状态】 投放计划状态,已终止、已过期是终态。 可选取值
delivery_start_time 必填 string 【投放开始时间】 投放开始时间,遵循 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秒。 delivery_end_time 必填 string 【投放结束时间】 投放结束时间,遵循 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秒。 product_coupon_id 必填 string(40) 【商品券ID】 商品券ID,通过请求创建商品券接口获得,具体可查看创建商品券 usage_mode 必填 string 【使用模式】 商品券使用模式 可选取值
stock_id 选填 string(40) 【投放批次ID】 投放的商品券批次ID,通过请求创建商品券接口获得,具体可查看创建商品券 ,当且仅当 usage_mode 为 SINGLE 时必传。 stock_bundle_id 选填 string 【投放批次组ID】 投放的批次组ID,通过请求创建商品券接口获得,具体可查看创建商品券 ,当且仅当 usage_mode 为 PROGRESSIVE_BUNDLE 时必填。 recommend_word 选填 string(27) 【营销标签】 用于在优惠左上角展示的运营推荐语信息。自定义文案,不超过9个中文字符或18个英文字符。若创建时未设置则不返回。 total_count 必填 integer 【投放总库存数量】 约定了投放计划的总投放库存。 user_limit 必填 integer 【单用户限领】 约定了投放计划单用户维度的限领数量; 非必填,如创建时未填写,则修改时不支持填写。 daily_limit 必填 integer 【单日限领】 用于约定投放计划单日可领取的最大数量,如创建时未填写,则修改时不支持填写。 reuse_coupon_config 必填 boolean 【是否复用商品券和批次信息】 是:表示从商品券和批次获取信息自动填充plan_name、total_count、user_limit、daily_limit、delivery_start_time、delivery_end_time。当投放计划在投放中状态时,若商品券批次的库存发生变化,投放计划会自动更新最新库存。 brand_id 必填 string 【品牌ID】 品牌ID |
应答示例
200 OK
1{ 2 "total_count" : 1234, 3 "plan_list" : [ 4 { 5 "plan_id" : "12000", 6 "plan_name" : "冬季优惠投放", 7 "plan_state" : "CREATED", 8 "delivery_start_time" : "2025-01-01T00:00:00+08:00", 9 "delivery_end_time" : "2025-01-01T00:00:00+08:00", 10 "product_coupon_id" : "1000000013", 11 "usage_mode" : "SINGLE", 12 "stock_id" : "123456789", 13 "stock_bundle_id" : "123456789", 14 "recommend_word" : "天天有惊喜", 15 "total_count" : 11000, 16 "user_limit" : 5, 17 "daily_limit" : 100, 18 "reuse_coupon_config" : false, 19 "brand_id" : "40016" 20 } 21 ] 22} 23
错误码
以下是本接口返回的错误码列表。详细错误码规则,请参考微信支付接口规则-错误码和错误提示

