添加商品券批次组
更新时间:2025.11.27品牌方可以通过该接口为已有的「多次优惠」商品券添加更多批次组,每个批次组创建时会批量创建多个商品券批次。同一个商品券的多个批次组可以实现品牌方多样化的投放需求。
前置条件:已创建商品券且商品券的 usage_mode 为 PROGRESSIVE_BUNDLE
频率限制:20/s
接口说明
支持商户:【品牌商户】
请求方式:【POST】/brand/marketing/product-coupon/product-coupons/{product_coupon_id}/stock-bundles
请求域名:【主域名】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
Wechatpay-Serial 必填 string
【微信支付公钥ID】 请传入brand_id对应的微信支付公钥ID,接口将会校验两者的关联关系,参考微信支付公钥产品简介及使用说明获取微信支付公钥ID和相关的介绍。以下两种场景将使用到微信支付公钥: 1、接收到接口的返回内容,需要使用微信支付公钥进行验签; 2、调用含有敏感信息参数(如姓名、身份证号码)的接口时,需要使用微信支付公钥加密敏感信息后再传输参数,加密指引请参考微信支付公钥加密敏感信息指引。
path 路径参数
product_coupon_id 必填 string
【商品券ID】 商品券的唯一标识,创建商品券时由微信支付生成
body 包体参数
out_request_no 必填 string(40)
【创建请求单号】 品牌创建批次请求流水号,品牌侧需保持唯一性,可使用 数字、大小写字母、下划线_、短横线- 组成,长度在6-40个字符之间
stock_bundle 必填 object
【批次组】 为商品券创建的批次组详情
| 属性 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
remark 选填 string(20) 【备注】 仅配置品牌方可见,用于自定义信息,最多20个UTF-8字符 coupon_code_mode 必填 string 【券Code分配模式】 决定发券时用户商品券Code如何产生,批次组内每一个批次都会设置为此值 可选取值
stock_send_rule 必填 object 【发放规则】 批次的发放规则
progressive_bundle_usage_rule 选填 object 【多次优惠批次组使用规则】 包含组合内部每一个批次的优惠规则,会根据内部的优惠规则列表依次创建批次放入批次组,当且仅当
usage_rule_display_info 必填 object 【券使用规则展示信息】 券使用规则展示信息,批次组内每一个批次都会设置为此值
coupon_display_info 必填 object 【用户商品券展示信息】 用户商品券在卡包中的展示详情,包括引导用户的自定义入口,批次组内每一个批次都会设置为此值
notify_config 必填 object 【事件通知配置】 发生券相关事件时,微信支付会向品牌方发送通知,需要提供通知相关配置,批次组内每一个批次都会设置为此值
store_scope 必填 string 【可用门店范围】 控制该批次可以在品牌下哪些门店使用,批次组内每一个批次都会设置为此值 可选取值
|
请求示例
POST
1curl -X POST \ 2 https://api.mch.weixin.qq.com/brand/marketing/product-coupon/product-coupons/200000001/stock-bundles \ 3 -H "Authorization: WECHATPAY-BRAND-SHA256-RSA2048 brand_id=\"XXXX\",..." \ 4 -H "Accept: application/json" \ 5 -H "Wechatpay-Serial: PUB_KEY_ID_XXXX" \ 6 -H "Content-Type: application/json" \ 7 -d '{ 8 "out_request_no" : "34657_20250101_123456", 9 "stock_bundle" : { 10 "remark" : "满减券", 11 "coupon_code_mode" : "UPLOAD", 12 "stock_send_rule" : { 13 "max_count" : 10000000, 14 "max_count_per_day" : 10000, 15 "max_count_per_user" : 1 16 }, 17 "progressive_bundle_usage_rule" : { 18 "coupon_available_period" : { 19 "available_begin_time" : "2025-01-01T00:00:00+08:00", 20 "available_end_time" : "2025-10-01T00:00:00+08:00", 21 "available_days" : 10, 22 "wait_days_after_receive" : 1, 23 "weekly_available_period" : { 24 "day_list" : [ 25 "MONDAY" 26 ], 27 "day_period_list" : [ 28 { 29 "begin_time" : 60, 30 "end_time" : 86399 31 } 32 ] 33 }, 34 "irregular_available_period_list" : [ 35 { 36 "begin_time" : "2025-01-01T00:00:00+08:00", 37 "end_time" : "2025-10-01T00:00:00+08:00" 38 } 39 ] 40 }, 41 "normal_coupon_list" : [ 42 { 43 "threshold" : 10000, 44 "discount_amount" : 100 45 } 46 ], 47 "discount_coupon_list" : [ 48 { 49 "threshold" : 10000, 50 "percent_off" : 30 51 } 52 ], 53 "exchange_coupon_list" : [ 54 { 55 "threshold" : 10000, 56 "exchange_price" : 100 57 } 58 ] 59 }, 60 "usage_rule_display_info" : { 61 "coupon_usage_method_list" : [ 62 "MINI_PROGRAM" 63 ], 64 "mini_program_appid" : "wx1234567890", 65 "mini_program_path" : "/pages/index/product", 66 "app_path" : "https://www.example.com/jump-to-app", 67 "usage_description" : "全场可用", 68 "coupon_available_store_info" : { 69 "description" : "可在上海市区的所有门店使用,详细列表参考小程序内信息为准", 70 "mini_program_appid" : "wx1234567890", 71 "mini_program_path" : "/pages/index/store-list" 72 } 73 }, 74 "coupon_display_info" : { 75 "code_display_mode" : "QRCODE", 76 "background_color" : "Color010", 77 "entrance_mini_program" : { 78 "appid" : "wx1234567890", 79 "path" : "/pages/index/product", 80 "entrance_wording" : "欢迎选购", 81 "guidance_wording" : "获取更多优惠" 82 }, 83 "entrance_official_account" : { 84 "appid" : "wx1234567890" 85 }, 86 "entrance_finder" : { 87 "finder_id" : "gh_12345678", 88 "finder_video_id" : "UDFsdf24df34dD456Hdf34", 89 "finder_video_cover_image_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx" 90 } 91 }, 92 "notify_config" : { 93 "notify_appid" : "wx4fd12345678" 94 }, 95 "store_scope" : "SPECIFIC" 96 } 97 }' 98
需配合微信支付工具库 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 CreateStockBundle { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "POST"; 28 private static String PATH = "/brand/marketing/product-coupon/product-coupons/{product_coupon_id}/stock-bundles"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/brand/4015415289 32 CreateStockBundle client = new CreateStockBundle( 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 CreateStockBundleRequest request = new CreateStockBundleRequest(); 41 request.productCouponId = "200000001"; 42 request.outRequestNo = "34657_20250101_123456"; 43 request.stockBundle = new StockBundleForCreate(); 44 request.stockBundle.remark = "满减券"; 45 request.stockBundle.couponCodeMode = CouponCodeMode.UPLOAD; 46 request.stockBundle.stockSendRule = new StockSendRule(); 47 request.stockBundle.stockSendRule.maxCount = 10000000L; 48 request.stockBundle.stockSendRule.maxCountPerDay = 10000L; 49 request.stockBundle.stockSendRule.maxCountPerUser = 1L; 50 request.stockBundle.progressiveBundleUsageRule = new StockBundleUsageRule(); 51 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod = new CouponAvailablePeriod(); 52 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.availableBeginTime = "2025-01-01T00:00:00+08:00"; 53 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.availableEndTime = "2025-10-01T00:00:00+08:00"; 54 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.availableDays = 10L; 55 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.waitDaysAfterReceive = 1L; 56 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.weeklyAvailablePeriod = new FixedWeekPeriod(); 57 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.weeklyAvailablePeriod.dayList = new ArrayList<>(); 58 { 59 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.weeklyAvailablePeriod.dayList.add(WeekEnum.MONDAY); 60 }; 61 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.weeklyAvailablePeriod.dayPeriodList = new ArrayList<>(); 62 { 63 PeriodOfTheDay dayPeriodListItem = new PeriodOfTheDay(); 64 dayPeriodListItem.beginTime = 60L; 65 dayPeriodListItem.endTime = 86399L; 66 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.weeklyAvailablePeriod.dayPeriodList.add(dayPeriodListItem); 67 }; 68 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.irregularAvailablePeriodList = new ArrayList<>(); 69 { 70 TimePeriod irregularAvailablePeriodListItem = new TimePeriod(); 71 irregularAvailablePeriodListItem.beginTime = "2025-01-01T00:00:00+08:00"; 72 irregularAvailablePeriodListItem.endTime = "2025-10-01T00:00:00+08:00"; 73 request.stockBundle.progressiveBundleUsageRule.couponAvailablePeriod.irregularAvailablePeriodList.add(irregularAvailablePeriodListItem); 74 }; 75 request.stockBundle.progressiveBundleUsageRule.normalCouponList = new ArrayList<>(); 76 { 77 NormalCouponUsageRule normalCouponListItem = new NormalCouponUsageRule(); 78 normalCouponListItem.threshold = 10000L; 79 normalCouponListItem.discountAmount = 100L; 80 request.stockBundle.progressiveBundleUsageRule.normalCouponList.add(normalCouponListItem); 81 }; 82 request.stockBundle.progressiveBundleUsageRule.discountCouponList = new ArrayList<>(); 83 { 84 DiscountCouponUsageRule discountCouponListItem = new DiscountCouponUsageRule(); 85 discountCouponListItem.threshold = 10000L; 86 discountCouponListItem.percentOff = 30L; 87 request.stockBundle.progressiveBundleUsageRule.discountCouponList.add(discountCouponListItem); 88 }; 89 request.stockBundle.progressiveBundleUsageRule.exchangeCouponList = new ArrayList<>(); 90 { 91 ExchangeCouponUsageRule exchangeCouponListItem = new ExchangeCouponUsageRule(); 92 exchangeCouponListItem.threshold = 10000L; 93 exchangeCouponListItem.exchangePrice = 100L; 94 request.stockBundle.progressiveBundleUsageRule.exchangeCouponList.add(exchangeCouponListItem); 95 }; 96 request.stockBundle.usageRuleDisplayInfo = new UsageRuleDisplayInfo(); 97 request.stockBundle.usageRuleDisplayInfo.couponUsageMethodList = new ArrayList<>(); 98 { 99 request.stockBundle.usageRuleDisplayInfo.couponUsageMethodList.add(CouponUsageMethod.OFFLINE); 100 }; 101 request.stockBundle.usageRuleDisplayInfo.miniProgramAppid = "wx1234567890"; 102 request.stockBundle.usageRuleDisplayInfo.miniProgramPath = "/pages/index/product"; 103 request.stockBundle.usageRuleDisplayInfo.appPath = "https://www.example.com/jump-to-app"; 104 request.stockBundle.usageRuleDisplayInfo.usageDescription = "全场可用"; 105 request.stockBundle.usageRuleDisplayInfo.couponAvailableStoreInfo = new CouponAvailableStoreInfo(); 106 request.stockBundle.usageRuleDisplayInfo.couponAvailableStoreInfo.description = "可在上海市区的所有门店使用,详细列表参考小程序内信息为准"; 107 request.stockBundle.usageRuleDisplayInfo.couponAvailableStoreInfo.miniProgramAppid = "wx1234567890"; 108 request.stockBundle.usageRuleDisplayInfo.couponAvailableStoreInfo.miniProgramPath = "/pages/index/store-list"; 109 request.stockBundle.couponDisplayInfo = new CouponDisplayInfo(); 110 request.stockBundle.couponDisplayInfo.codeDisplayMode = CouponCodeDisplayMode.QRCODE; 111 request.stockBundle.couponDisplayInfo.backgroundColor = "Color010"; 112 request.stockBundle.couponDisplayInfo.entranceMiniProgram = new EntranceMiniProgram(); 113 request.stockBundle.couponDisplayInfo.entranceMiniProgram.appid = "wx1234567890"; 114 request.stockBundle.couponDisplayInfo.entranceMiniProgram.path = "/pages/index/product"; 115 request.stockBundle.couponDisplayInfo.entranceMiniProgram.entranceWording = "欢迎选购"; 116 request.stockBundle.couponDisplayInfo.entranceMiniProgram.guidanceWording = "获取更多优惠"; 117 request.stockBundle.couponDisplayInfo.entranceOfficialAccount = new EntranceOfficialAccount(); 118 request.stockBundle.couponDisplayInfo.entranceOfficialAccount.appid = "wx1234567890"; 119 request.stockBundle.couponDisplayInfo.entranceFinder = new EntranceFinder(); 120 request.stockBundle.couponDisplayInfo.entranceFinder.finderId = "gh_12345678"; 121 request.stockBundle.couponDisplayInfo.entranceFinder.finderVideoId = "UDFsdf24df34dD456Hdf34"; 122 request.stockBundle.couponDisplayInfo.entranceFinder.finderVideoCoverImageUrl = "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx"; 123 request.stockBundle.notifyConfig = new NotifyConfig(); 124 request.stockBundle.notifyConfig.notifyAppid = "wx4fd12345678"; 125 request.stockBundle.storeScope = StockStoreScope.SPECIFIC; 126 try { 127 StockBundleEntity response = client.run(request); 128 // TODO: 请求成功,继续业务逻辑 129 System.out.println(response); 130 } catch (WXPayBrandUtility.ApiException e) { 131 // TODO: 请求失败,根据状态码执行不同的逻辑 132 e.printStackTrace(); 133 } 134 } 135 136 public StockBundleEntity run(CreateStockBundleRequest request) { 137 String uri = PATH; 138 uri = uri.replace("{product_coupon_id}", WXPayBrandUtility.urlEncode(request.productCouponId)); 139 String reqBody = WXPayBrandUtility.toJson(request); 140 141 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 142 reqBuilder.addHeader("Accept", "application/json"); 143 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 144 reqBuilder.addHeader("Authorization", WXPayBrandUtility.buildAuthorization(brand_id, certificateSerialNo,privateKey, METHOD, uri, reqBody)); 145 reqBuilder.addHeader("Content-Type", "application/json"); 146 RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); 147 reqBuilder.method(METHOD, requestBody); 148 Request httpRequest = reqBuilder.build(); 149 150 // 发送HTTP请求 151 OkHttpClient client = new OkHttpClient.Builder().build(); 152 try (Response httpResponse = client.newCall(httpRequest).execute()) { 153 String respBody = WXPayBrandUtility.extractBody(httpResponse); 154 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 155 // 2XX 成功,验证应答签名 156 WXPayBrandUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 157 httpResponse.headers(), respBody); 158 159 // 从HTTP应答报文构建返回数据 160 return WXPayBrandUtility.fromJson(respBody, StockBundleEntity.class); 161 } else { 162 throw new WXPayBrandUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 163 } 164 } catch (IOException e) { 165 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 166 } 167 } 168 169 private final String brand_id; 170 private final String certificateSerialNo; 171 private final PrivateKey privateKey; 172 private final String wechatPayPublicKeyId; 173 private final PublicKey wechatPayPublicKey; 174 175 public CreateStockBundle(String brand_id, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 176 this.brand_id = brand_id; 177 this.certificateSerialNo = certificateSerialNo; 178 this.privateKey = WXPayBrandUtility.loadPrivateKeyFromPath(privateKeyFilePath); 179 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 180 this.wechatPayPublicKey = WXPayBrandUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 181 } 182 183 public static class CreateStockBundleRequest { 184 @SerializedName("out_request_no") 185 public String outRequestNo; 186 187 @SerializedName("product_coupon_id") 188 @Expose(serialize = false) 189 public String productCouponId; 190 191 @SerializedName("stock_bundle") 192 public StockBundleForCreate stockBundle; 193 } 194 195 public static class StockBundleEntity { 196 @SerializedName("stock_bundle_id") 197 public String stockBundleId; 198 199 @SerializedName("stock_list") 200 public List<StockEntityInBundle> stockList = new ArrayList<StockEntityInBundle>(); 201 } 202 203 public static class StockBundleForCreate { 204 @SerializedName("remark") 205 public String remark; 206 207 @SerializedName("coupon_code_mode") 208 public CouponCodeMode couponCodeMode; 209 210 @SerializedName("stock_send_rule") 211 public StockSendRule stockSendRule; 212 213 @SerializedName("progressive_bundle_usage_rule") 214 public StockBundleUsageRule progressiveBundleUsageRule; 215 216 @SerializedName("usage_rule_display_info") 217 public UsageRuleDisplayInfo usageRuleDisplayInfo; 218 219 @SerializedName("coupon_display_info") 220 public CouponDisplayInfo couponDisplayInfo; 221 222 @SerializedName("notify_config") 223 public NotifyConfig notifyConfig; 224 225 @SerializedName("store_scope") 226 public StockStoreScope storeScope; 227 } 228 229 public static class StockEntityInBundle { 230 @SerializedName("product_coupon_id") 231 public String productCouponId; 232 233 @SerializedName("stock_id") 234 public String stockId; 235 236 @SerializedName("remark") 237 public String remark; 238 239 @SerializedName("coupon_code_mode") 240 public CouponCodeMode couponCodeMode; 241 242 @SerializedName("coupon_code_count_info") 243 public CouponCodeCountInfo couponCodeCountInfo; 244 245 @SerializedName("stock_send_rule") 246 public StockSendRule stockSendRule; 247 248 @SerializedName("progressive_bundle_usage_rule") 249 public StockUsageRule progressiveBundleUsageRule; 250 251 @SerializedName("stock_bundle_info") 252 public StockBundleInfo stockBundleInfo; 253 254 @SerializedName("usage_rule_display_info") 255 public UsageRuleDisplayInfo usageRuleDisplayInfo; 256 257 @SerializedName("coupon_display_info") 258 public CouponDisplayInfo couponDisplayInfo; 259 260 @SerializedName("notify_config") 261 public NotifyConfig notifyConfig; 262 263 @SerializedName("store_scope") 264 public StockStoreScope storeScope; 265 266 @SerializedName("sent_count_info") 267 public StockSentCountInfo sentCountInfo; 268 269 @SerializedName("state") 270 public StockState state; 271 272 @SerializedName("deactivate_request_no") 273 public String deactivateRequestNo; 274 275 @SerializedName("deactivate_time") 276 public String deactivateTime; 277 278 @SerializedName("deactivate_reason") 279 public String deactivateReason; 280 } 281 282 public enum CouponCodeMode { 283 @SerializedName("WECHATPAY") 284 WECHATPAY, 285 @SerializedName("UPLOAD") 286 UPLOAD 287 } 288 289 public static class StockSendRule { 290 @SerializedName("max_count") 291 public Long maxCount; 292 293 @SerializedName("max_count_per_day") 294 public Long maxCountPerDay; 295 296 @SerializedName("max_count_per_user") 297 public Long maxCountPerUser; 298 } 299 300 public static class StockBundleUsageRule { 301 @SerializedName("coupon_available_period") 302 public CouponAvailablePeriod couponAvailablePeriod; 303 304 @SerializedName("normal_coupon_list") 305 public List<NormalCouponUsageRule> normalCouponList; 306 307 @SerializedName("discount_coupon_list") 308 public List<DiscountCouponUsageRule> discountCouponList; 309 310 @SerializedName("exchange_coupon_list") 311 public List<ExchangeCouponUsageRule> exchangeCouponList; 312 } 313 314 public static class UsageRuleDisplayInfo { 315 @SerializedName("coupon_usage_method_list") 316 public List<CouponUsageMethod> couponUsageMethodList = new ArrayList<CouponUsageMethod>(); 317 318 @SerializedName("mini_program_appid") 319 public String miniProgramAppid; 320 321 @SerializedName("mini_program_path") 322 public String miniProgramPath; 323 324 @SerializedName("app_path") 325 public String appPath; 326 327 @SerializedName("usage_description") 328 public String usageDescription; 329 330 @SerializedName("coupon_available_store_info") 331 public CouponAvailableStoreInfo couponAvailableStoreInfo; 332 } 333 334 public static class CouponDisplayInfo { 335 @SerializedName("code_display_mode") 336 public CouponCodeDisplayMode codeDisplayMode; 337 338 @SerializedName("background_color") 339 public String backgroundColor; 340 341 @SerializedName("entrance_mini_program") 342 public EntranceMiniProgram entranceMiniProgram; 343 344 @SerializedName("entrance_official_account") 345 public EntranceOfficialAccount entranceOfficialAccount; 346 347 @SerializedName("entrance_finder") 348 public EntranceFinder entranceFinder; 349 } 350 351 public static class NotifyConfig { 352 @SerializedName("notify_appid") 353 public String notifyAppid; 354 } 355 356 public enum StockStoreScope { 357 @SerializedName("NONE") 358 NONE, 359 @SerializedName("ALL") 360 ALL, 361 @SerializedName("SPECIFIC") 362 SPECIFIC 363 } 364 365 public static class CouponCodeCountInfo { 366 @SerializedName("total_count") 367 public Long totalCount; 368 369 @SerializedName("available_count") 370 public Long availableCount; 371 } 372 373 public static class StockUsageRule { 374 @SerializedName("coupon_available_period") 375 public CouponAvailablePeriod couponAvailablePeriod; 376 377 @SerializedName("normal_coupon") 378 public NormalCouponUsageRule normalCoupon; 379 380 @SerializedName("discount_coupon") 381 public DiscountCouponUsageRule discountCoupon; 382 383 @SerializedName("exchange_coupon") 384 public ExchangeCouponUsageRule exchangeCoupon; 385 } 386 387 public static class StockBundleInfo { 388 @SerializedName("stock_bundle_id") 389 public String stockBundleId; 390 391 @SerializedName("stock_bundle_index") 392 public Long stockBundleIndex; 393 } 394 395 public static class StockSentCountInfo { 396 @SerializedName("total_count") 397 public Long totalCount; 398 399 @SerializedName("today_count") 400 public Long todayCount; 401 } 402 403 public enum StockState { 404 @SerializedName("AUDITING") 405 AUDITING, 406 @SerializedName("SENDING") 407 SENDING, 408 @SerializedName("PAUSED") 409 PAUSED, 410 @SerializedName("STOPPED") 411 STOPPED, 412 @SerializedName("DEACTIVATED") 413 DEACTIVATED 414 } 415 416 public static class CouponAvailablePeriod { 417 @SerializedName("available_begin_time") 418 public String availableBeginTime; 419 420 @SerializedName("available_end_time") 421 public String availableEndTime; 422 423 @SerializedName("available_days") 424 public Long availableDays; 425 426 @SerializedName("wait_days_after_receive") 427 public Long waitDaysAfterReceive; 428 429 @SerializedName("weekly_available_period") 430 public FixedWeekPeriod weeklyAvailablePeriod; 431 432 @SerializedName("irregular_available_period_list") 433 public List<TimePeriod> irregularAvailablePeriodList; 434 } 435 436 public static class NormalCouponUsageRule { 437 @SerializedName("threshold") 438 public Long threshold; 439 440 @SerializedName("discount_amount") 441 public Long discountAmount; 442 } 443 444 public static class DiscountCouponUsageRule { 445 @SerializedName("threshold") 446 public Long threshold; 447 448 @SerializedName("percent_off") 449 public Long percentOff; 450 } 451 452 public static class ExchangeCouponUsageRule { 453 @SerializedName("threshold") 454 public Long threshold; 455 456 @SerializedName("exchange_price") 457 public Long exchangePrice; 458 } 459 460 public enum CouponUsageMethod { 461 @SerializedName("OFFLINE") 462 OFFLINE, 463 @SerializedName("MINI_PROGRAM") 464 MINI_PROGRAM, 465 @SerializedName("APP") 466 APP, 467 @SerializedName("PAYMENT_CODE") 468 PAYMENT_CODE 469 } 470 471 public static class CouponAvailableStoreInfo { 472 @SerializedName("description") 473 public String description; 474 475 @SerializedName("mini_program_appid") 476 public String miniProgramAppid; 477 478 @SerializedName("mini_program_path") 479 public String miniProgramPath; 480 } 481 482 public enum CouponCodeDisplayMode { 483 @SerializedName("INVISIBLE") 484 INVISIBLE, 485 @SerializedName("BARCODE") 486 BARCODE, 487 @SerializedName("QRCODE") 488 QRCODE 489 } 490 491 public static class EntranceMiniProgram { 492 @SerializedName("appid") 493 public String appid; 494 495 @SerializedName("path") 496 public String path; 497 498 @SerializedName("entrance_wording") 499 public String entranceWording; 500 501 @SerializedName("guidance_wording") 502 public String guidanceWording; 503 } 504 505 public static class EntranceOfficialAccount { 506 @SerializedName("appid") 507 public String appid; 508 } 509 510 public static class EntranceFinder { 511 @SerializedName("finder_id") 512 public String finderId; 513 514 @SerializedName("finder_video_id") 515 public String finderVideoId; 516 517 @SerializedName("finder_video_cover_image_url") 518 public String finderVideoCoverImageUrl; 519 } 520 521 public static class FixedWeekPeriod { 522 @SerializedName("day_list") 523 public List<WeekEnum> dayList; 524 525 @SerializedName("day_period_list") 526 public List<PeriodOfTheDay> dayPeriodList; 527 } 528 529 public static class TimePeriod { 530 @SerializedName("begin_time") 531 public String beginTime; 532 533 @SerializedName("end_time") 534 public String endTime; 535 } 536 537 public enum WeekEnum { 538 @SerializedName("MONDAY") 539 MONDAY, 540 @SerializedName("TUESDAY") 541 TUESDAY, 542 @SerializedName("WEDNESDAY") 543 WEDNESDAY, 544 @SerializedName("THURSDAY") 545 THURSDAY, 546 @SerializedName("FRIDAY") 547 FRIDAY, 548 @SerializedName("SATURDAY") 549 SATURDAY, 550 @SerializedName("SUNDAY") 551 SUNDAY 552 } 553 554 public static class PeriodOfTheDay { 555 @SerializedName("begin_time") 556 public Long beginTime; 557 558 @SerializedName("end_time") 559 public Long endTime; 560 } 561 562} 563
需配合微信支付工具库 wxpay_utility 使用,请参考Go
1package main 2 3import ( 4 "bytes" 5 "demo/wxpay_brand_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/brand/4015826866 6 "encoding/json" 7 "fmt" 8 "net/http" 9 "net/url" 10 "strings" 11 "time" 12) 13 14func main() { 15 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/brand/4015415289 16 config, err := wxpay_brand_utility.CreateBrandConfig( 17 "xxxxxxxx", // 品牌ID,是由微信支付系统生成并分配给每个品牌方的唯一标识符,品牌ID获取方式参考 https://pay.weixin.qq.com/doc/brand/4015415289 18 "1DDE55AD98Exxxxxxxxxx", // 品牌API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015407570 19 "/path/to/apiclient_key.pem", // 品牌API证书私钥文件路径,本地文件路径 20 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/brand/4015453439 21 "/path/to/wxp_pub.pem", // 微信支付公钥文件路径,本地文件路径 22 ) 23 if err != nil { 24 fmt.Println(err) 25 return 26 } 27 28 request := &CreateStockBundleRequest{ 29 ProductCouponId: wxpay_brand_utility.String("200000001"), 30 OutRequestNo: wxpay_brand_utility.String("34657_20250101_123456"), 31 StockBundle: &StockBundleForCreate{ 32 Remark: wxpay_brand_utility.String("满减券"), 33 CouponCodeMode: COUPONCODEMODE_UPLOAD.Ptr(), 34 StockSendRule: &StockSendRule{ 35 MaxCount: wxpay_brand_utility.Int64(10000000), 36 MaxCountPerDay: wxpay_brand_utility.Int64(10000), 37 MaxCountPerUser: wxpay_brand_utility.Int64(1), 38 }, 39 ProgressiveBundleUsageRule: &StockBundleUsageRule{ 40 CouponAvailablePeriod: &CouponAvailablePeriod{ 41 AvailableBeginTime: wxpay_brand_utility.String("2025-01-01T00:00:00+08:00"), 42 AvailableEndTime: wxpay_brand_utility.String("2025-10-01T00:00:00+08:00"), 43 AvailableDays: wxpay_brand_utility.Int64(10), 44 WaitDaysAfterReceive: wxpay_brand_utility.Int64(1), 45 WeeklyAvailablePeriod: &FixedWeekPeriod{ 46 DayList: []WeekEnum{WEEKENUM_MONDAY}, 47 DayPeriodList: []PeriodOfTheDay{PeriodOfTheDay{ 48 BeginTime: wxpay_brand_utility.Int64(60), 49 EndTime: wxpay_brand_utility.Int64(86399), 50 }}, 51 }, 52 IrregularAvailablePeriodList: []TimePeriod{TimePeriod{ 53 BeginTime: wxpay_brand_utility.String("2025-01-01T00:00:00+08:00"), 54 EndTime: wxpay_brand_utility.String("2025-10-01T00:00:00+08:00"), 55 }}, 56 }, 57 NormalCouponList: []NormalCouponUsageRule{NormalCouponUsageRule{ 58 Threshold: wxpay_brand_utility.Int64(10000), 59 DiscountAmount: wxpay_brand_utility.Int64(100), 60 }}, 61 DiscountCouponList: []DiscountCouponUsageRule{DiscountCouponUsageRule{ 62 Threshold: wxpay_brand_utility.Int64(10000), 63 PercentOff: wxpay_brand_utility.Int64(30), 64 }}, 65 ExchangeCouponList: []ExchangeCouponUsageRule{ExchangeCouponUsageRule{ 66 Threshold: wxpay_brand_utility.Int64(10000), 67 ExchangePrice: wxpay_brand_utility.Int64(100), 68 }}, 69 }, 70 UsageRuleDisplayInfo: &UsageRuleDisplayInfo{ 71 CouponUsageMethodList: []CouponUsageMethod{COUPONUSAGEMETHOD_OFFLINE}, 72 MiniProgramAppid: wxpay_brand_utility.String("wx1234567890"), 73 MiniProgramPath: wxpay_brand_utility.String("/pages/index/product"), 74 AppPath: wxpay_brand_utility.String("https://www.example.com/jump-to-app"), 75 UsageDescription: wxpay_brand_utility.String("全场可用"), 76 CouponAvailableStoreInfo: &CouponAvailableStoreInfo{ 77 Description: wxpay_brand_utility.String("可在上海市区的所有门店使用,详细列表参考小程序内信息为准"), 78 MiniProgramAppid: wxpay_brand_utility.String("wx1234567890"), 79 MiniProgramPath: wxpay_brand_utility.String("/pages/index/store-list"), 80 }, 81 }, 82 CouponDisplayInfo: &CouponDisplayInfo{ 83 CodeDisplayMode: COUPONCODEDISPLAYMODE_QRCODE.Ptr(), 84 BackgroundColor: wxpay_brand_utility.String("Color010"), 85 EntranceMiniProgram: &EntranceMiniProgram{ 86 Appid: wxpay_brand_utility.String("wx1234567890"), 87 Path: wxpay_brand_utility.String("/pages/index/product"), 88 EntranceWording: wxpay_brand_utility.String("欢迎选购"), 89 GuidanceWording: wxpay_brand_utility.String("获取更多优惠"), 90 }, 91 EntranceOfficialAccount: &EntranceOfficialAccount{ 92 Appid: wxpay_brand_utility.String("wx1234567890"), 93 }, 94 EntranceFinder: &EntranceFinder{ 95 FinderId: wxpay_brand_utility.String("gh_12345678"), 96 FinderVideoId: wxpay_brand_utility.String("UDFsdf24df34dD456Hdf34"), 97 FinderVideoCoverImageUrl: wxpay_brand_utility.String("https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx"), 98 }, 99 }, 100 NotifyConfig: &NotifyConfig{ 101 NotifyAppid: wxpay_brand_utility.String("wx4fd12345678"), 102 }, 103 StoreScope: STOCKSTORESCOPE_SPECIFIC.Ptr(), 104 }, 105 } 106 107 response, err := CreateStockBundle(config, request) 108 if err != nil { 109 fmt.Printf("请求失败: %+v\n", err) 110 // TODO: 请求失败,根据状态码执行不同的处理 111 return 112 } 113 114 // TODO: 请求成功,继续业务逻辑 115 fmt.Printf("请求成功: %+v\n", response) 116} 117 118func CreateStockBundle(config *wxpay_brand_utility.BrandConfig, request *CreateStockBundleRequest) (response *StockBundleEntity, err error) { 119 const ( 120 host = "https://api.mch.weixin.qq.com" 121 method = "POST" 122 path = "/brand/marketing/product-coupon/product-coupons/{product_coupon_id}/stock-bundles" 123 ) 124 125 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 126 if err != nil { 127 return nil, err 128 } 129 reqUrl.Path = strings.Replace(reqUrl.Path, "{product_coupon_id}", url.PathEscape(*request.ProductCouponId), -1) 130 reqBody, err := json.Marshal(request) 131 if err != nil { 132 return nil, err 133 } 134 httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody)) 135 if err != nil { 136 return nil, err 137 } 138 httpRequest.Header.Set("Accept", "application/json") 139 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 140 httpRequest.Header.Set("Content-Type", "application/json") 141 authorization, err := wxpay_brand_utility.BuildAuthorization(config.BrandId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody) 142 if err != nil { 143 return nil, err 144 } 145 httpRequest.Header.Set("Authorization", authorization) 146 147 client := &http.Client{} 148 httpResponse, err := client.Do(httpRequest) 149 if err != nil { 150 return nil, err 151 } 152 respBody, err := wxpay_brand_utility.ExtractResponseBody(httpResponse) 153 if err != nil { 154 return nil, err 155 } 156 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 157 // 2XX 成功,验证应答签名 158 err = wxpay_brand_utility.ValidateResponse( 159 config.WechatPayPublicKeyId(), 160 config.WechatPayPublicKey(), 161 &httpResponse.Header, 162 respBody, 163 ) 164 if err != nil { 165 return nil, err 166 } 167 response := &StockBundleEntity{} 168 if err := json.Unmarshal(respBody, response); err != nil { 169 return nil, err 170 } 171 172 return response, nil 173 } else { 174 return nil, wxpay_brand_utility.NewApiException( 175 httpResponse.StatusCode, 176 httpResponse.Header, 177 respBody, 178 ) 179 } 180} 181 182type CreateStockBundleRequest struct { 183 OutRequestNo *string `json:"out_request_no,omitempty"` 184 ProductCouponId *string `json:"product_coupon_id,omitempty"` 185 StockBundle *StockBundleForCreate `json:"stock_bundle,omitempty"` 186} 187 188func (o *CreateStockBundleRequest) MarshalJSON() ([]byte, error) { 189 type Alias CreateStockBundleRequest 190 a := &struct { 191 ProductCouponId *string `json:"product_coupon_id,omitempty"` 192 *Alias 193 }{ 194 // 序列化时移除非 Body 字段 195 ProductCouponId: nil, 196 Alias: (*Alias)(o), 197 } 198 return json.Marshal(a) 199} 200 201type StockBundleEntity struct { 202 StockBundleId *string `json:"stock_bundle_id,omitempty"` 203 StockList []StockEntityInBundle `json:"stock_list,omitempty"` 204} 205 206type StockBundleForCreate struct { 207 Remark *string `json:"remark,omitempty"` 208 CouponCodeMode *CouponCodeMode `json:"coupon_code_mode,omitempty"` 209 StockSendRule *StockSendRule `json:"stock_send_rule,omitempty"` 210 ProgressiveBundleUsageRule *StockBundleUsageRule `json:"progressive_bundle_usage_rule,omitempty"` 211 UsageRuleDisplayInfo *UsageRuleDisplayInfo `json:"usage_rule_display_info,omitempty"` 212 CouponDisplayInfo *CouponDisplayInfo `json:"coupon_display_info,omitempty"` 213 NotifyConfig *NotifyConfig `json:"notify_config,omitempty"` 214 StoreScope *StockStoreScope `json:"store_scope,omitempty"` 215} 216 217type StockEntityInBundle struct { 218 ProductCouponId *string `json:"product_coupon_id,omitempty"` 219 StockId *string `json:"stock_id,omitempty"` 220 Remark *string `json:"remark,omitempty"` 221 CouponCodeMode *CouponCodeMode `json:"coupon_code_mode,omitempty"` 222 CouponCodeCountInfo *CouponCodeCountInfo `json:"coupon_code_count_info,omitempty"` 223 StockSendRule *StockSendRule `json:"stock_send_rule,omitempty"` 224 ProgressiveBundleUsageRule *StockUsageRule `json:"progressive_bundle_usage_rule,omitempty"` 225 StockBundleInfo *StockBundleInfo `json:"stock_bundle_info,omitempty"` 226 UsageRuleDisplayInfo *UsageRuleDisplayInfo `json:"usage_rule_display_info,omitempty"` 227 CouponDisplayInfo *CouponDisplayInfo `json:"coupon_display_info,omitempty"` 228 NotifyConfig *NotifyConfig `json:"notify_config,omitempty"` 229 StoreScope *StockStoreScope `json:"store_scope,omitempty"` 230 SentCountInfo *StockSentCountInfo `json:"sent_count_info,omitempty"` 231 State *StockState `json:"state,omitempty"` 232 DeactivateRequestNo *string `json:"deactivate_request_no,omitempty"` 233 DeactivateTime *time.Time `json:"deactivate_time,omitempty"` 234 DeactivateReason *string `json:"deactivate_reason,omitempty"` 235} 236 237type CouponCodeMode string 238 239func (e CouponCodeMode) Ptr() *CouponCodeMode { 240 return &e 241} 242 243const ( 244 COUPONCODEMODE_WECHATPAY CouponCodeMode = "WECHATPAY" 245 COUPONCODEMODE_UPLOAD CouponCodeMode = "UPLOAD" 246) 247 248type StockSendRule struct { 249 MaxCount *int64 `json:"max_count,omitempty"` 250 MaxCountPerDay *int64 `json:"max_count_per_day,omitempty"` 251 MaxCountPerUser *int64 `json:"max_count_per_user,omitempty"` 252} 253 254type StockBundleUsageRule struct { 255 CouponAvailablePeriod *CouponAvailablePeriod `json:"coupon_available_period,omitempty"` 256 NormalCouponList []NormalCouponUsageRule `json:"normal_coupon_list,omitempty"` 257 DiscountCouponList []DiscountCouponUsageRule `json:"discount_coupon_list,omitempty"` 258 ExchangeCouponList []ExchangeCouponUsageRule `json:"exchange_coupon_list,omitempty"` 259} 260 261type UsageRuleDisplayInfo struct { 262 CouponUsageMethodList []CouponUsageMethod `json:"coupon_usage_method_list,omitempty"` 263 MiniProgramAppid *string `json:"mini_program_appid,omitempty"` 264 MiniProgramPath *string `json:"mini_program_path,omitempty"` 265 AppPath *string `json:"app_path,omitempty"` 266 UsageDescription *string `json:"usage_description,omitempty"` 267 CouponAvailableStoreInfo *CouponAvailableStoreInfo `json:"coupon_available_store_info,omitempty"` 268} 269 270type CouponDisplayInfo struct { 271 CodeDisplayMode *CouponCodeDisplayMode `json:"code_display_mode,omitempty"` 272 BackgroundColor *string `json:"background_color,omitempty"` 273 EntranceMiniProgram *EntranceMiniProgram `json:"entrance_mini_program,omitempty"` 274 EntranceOfficialAccount *EntranceOfficialAccount `json:"entrance_official_account,omitempty"` 275 EntranceFinder *EntranceFinder `json:"entrance_finder,omitempty"` 276} 277 278type NotifyConfig struct { 279 NotifyAppid *string `json:"notify_appid,omitempty"` 280} 281 282type StockStoreScope string 283 284func (e StockStoreScope) Ptr() *StockStoreScope { 285 return &e 286} 287 288const ( 289 STOCKSTORESCOPE_NONE StockStoreScope = "NONE" 290 STOCKSTORESCOPE_ALL StockStoreScope = "ALL" 291 STOCKSTORESCOPE_SPECIFIC StockStoreScope = "SPECIFIC" 292) 293 294type CouponCodeCountInfo struct { 295 TotalCount *int64 `json:"total_count,omitempty"` 296 AvailableCount *int64 `json:"available_count,omitempty"` 297} 298 299type StockUsageRule struct { 300 CouponAvailablePeriod *CouponAvailablePeriod `json:"coupon_available_period,omitempty"` 301 NormalCoupon *NormalCouponUsageRule `json:"normal_coupon,omitempty"` 302 DiscountCoupon *DiscountCouponUsageRule `json:"discount_coupon,omitempty"` 303 ExchangeCoupon *ExchangeCouponUsageRule `json:"exchange_coupon,omitempty"` 304} 305 306type StockBundleInfo struct { 307 StockBundleId *string `json:"stock_bundle_id,omitempty"` 308 StockBundleIndex *int64 `json:"stock_bundle_index,omitempty"` 309} 310 311type StockSentCountInfo struct { 312 TotalCount *int64 `json:"total_count,omitempty"` 313 TodayCount *int64 `json:"today_count,omitempty"` 314} 315 316type StockState string 317 318func (e StockState) Ptr() *StockState { 319 return &e 320} 321 322const ( 323 STOCKSTATE_AUDITING StockState = "AUDITING" 324 STOCKSTATE_SENDING StockState = "SENDING" 325 STOCKSTATE_PAUSED StockState = "PAUSED" 326 STOCKSTATE_STOPPED StockState = "STOPPED" 327 STOCKSTATE_DEACTIVATED StockState = "DEACTIVATED" 328) 329 330type CouponAvailablePeriod struct { 331 AvailableBeginTime *string `json:"available_begin_time,omitempty"` 332 AvailableEndTime *string `json:"available_end_time,omitempty"` 333 AvailableDays *int64 `json:"available_days,omitempty"` 334 WaitDaysAfterReceive *int64 `json:"wait_days_after_receive,omitempty"` 335 WeeklyAvailablePeriod *FixedWeekPeriod `json:"weekly_available_period,omitempty"` 336 IrregularAvailablePeriodList []TimePeriod `json:"irregular_available_period_list,omitempty"` 337} 338 339type NormalCouponUsageRule struct { 340 Threshold *int64 `json:"threshold,omitempty"` 341 DiscountAmount *int64 `json:"discount_amount,omitempty"` 342} 343 344type DiscountCouponUsageRule struct { 345 Threshold *int64 `json:"threshold,omitempty"` 346 PercentOff *int64 `json:"percent_off,omitempty"` 347} 348 349type ExchangeCouponUsageRule struct { 350 Threshold *int64 `json:"threshold,omitempty"` 351 ExchangePrice *int64 `json:"exchange_price,omitempty"` 352} 353 354type CouponUsageMethod string 355 356func (e CouponUsageMethod) Ptr() *CouponUsageMethod { 357 return &e 358} 359 360const ( 361 COUPONUSAGEMETHOD_OFFLINE CouponUsageMethod = "OFFLINE" 362 COUPONUSAGEMETHOD_MINI_PROGRAM CouponUsageMethod = "MINI_PROGRAM" 363 COUPONUSAGEMETHOD_APP CouponUsageMethod = "APP" 364 COUPONUSAGEMETHOD_PAYMENT_CODE CouponUsageMethod = "PAYMENT_CODE" 365) 366 367type CouponAvailableStoreInfo struct { 368 Description *string `json:"description,omitempty"` 369 MiniProgramAppid *string `json:"mini_program_appid,omitempty"` 370 MiniProgramPath *string `json:"mini_program_path,omitempty"` 371} 372 373type CouponCodeDisplayMode string 374 375func (e CouponCodeDisplayMode) Ptr() *CouponCodeDisplayMode { 376 return &e 377} 378 379const ( 380 COUPONCODEDISPLAYMODE_INVISIBLE CouponCodeDisplayMode = "INVISIBLE" 381 COUPONCODEDISPLAYMODE_BARCODE CouponCodeDisplayMode = "BARCODE" 382 COUPONCODEDISPLAYMODE_QRCODE CouponCodeDisplayMode = "QRCODE" 383) 384 385type EntranceMiniProgram struct { 386 Appid *string `json:"appid,omitempty"` 387 Path *string `json:"path,omitempty"` 388 EntranceWording *string `json:"entrance_wording,omitempty"` 389 GuidanceWording *string `json:"guidance_wording,omitempty"` 390} 391 392type EntranceOfficialAccount struct { 393 Appid *string `json:"appid,omitempty"` 394} 395 396type EntranceFinder struct { 397 FinderId *string `json:"finder_id,omitempty"` 398 FinderVideoId *string `json:"finder_video_id,omitempty"` 399 FinderVideoCoverImageUrl *string `json:"finder_video_cover_image_url,omitempty"` 400} 401 402type FixedWeekPeriod struct { 403 DayList []WeekEnum `json:"day_list,omitempty"` 404 DayPeriodList []PeriodOfTheDay `json:"day_period_list,omitempty"` 405} 406 407type TimePeriod struct { 408 BeginTime *string `json:"begin_time,omitempty"` 409 EndTime *string `json:"end_time,omitempty"` 410} 411 412type WeekEnum string 413 414func (e WeekEnum) Ptr() *WeekEnum { 415 return &e 416} 417 418const ( 419 WEEKENUM_MONDAY WeekEnum = "MONDAY" 420 WEEKENUM_TUESDAY WeekEnum = "TUESDAY" 421 WEEKENUM_WEDNESDAY WeekEnum = "WEDNESDAY" 422 WEEKENUM_THURSDAY WeekEnum = "THURSDAY" 423 WEEKENUM_FRIDAY WeekEnum = "FRIDAY" 424 WEEKENUM_SATURDAY WeekEnum = "SATURDAY" 425 WEEKENUM_SUNDAY WeekEnum = "SUNDAY" 426) 427 428type PeriodOfTheDay struct { 429 BeginTime *int64 `json:"begin_time,omitempty"` 430 EndTime *int64 `json:"end_time,omitempty"` 431} 432
应答参数
200 OK
stock_bundle_id 必填 string(40)
【批次组ID】 商品券批次组的唯一标识,由微信支付生成
stock_list 必填 array[object]
【批次列表】 批次组内批次列表
| 属性 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
product_coupon_id 必填 string(40) 【商品券ID】 商品券的唯一标识,由微信支付生成 stock_id 必填 string(40) 【批次ID】 商品券批次的唯一标识,由微信支付生成 remark 选填 string(20) 【备注】 仅配置品牌可见,用于自定义信息 coupon_code_mode 必填 string 【券Code分配模式】 决定发券时用户商品券Code如何产生 可选取值
coupon_code_count_info 选填 object 【品牌方预上传的券Code数量信息】 当且仅当
stock_send_rule 必填 object 【发放规则】 发放规则
progressive_bundle_usage_rule 选填 object 【多次优惠使用规则】 本批次属于某个多次优惠批次组,这里记录的是本批次的使用规则,当且仅当
stock_bundle_info 必填 object 【批次组信息】 批次所在批次组信息
usage_rule_display_info 必填 object 【券使用规则展示信息】 券使用规则展示信息
coupon_display_info 必填 object 【用户商品券展示信息】 用户商品券在卡包中的展示详情,包括引导用户的自定义入口
notify_config 必填 object 【事件通知配置】 发生券相关事件时,微信支付会向品牌方发送通知,需要提供通知相关配置
store_scope 必填 string 【可用门店范围】 控制该批次可以在品牌下哪些门店使用 可选取值
sent_count_info 必填 object 【已发放次数】 本批次已发放次数
state 必填 string 【批次状态】 商品券批次状态 可选取值
deactivate_request_no 选填 string(128) 【失效请求单号】 当且仅当 deactivate_time 选填 string 【失效时间】 当且仅当 deactivate_reason 选填 string(150) 【失效原因】 当且仅当 |
应答示例
200 OK
1{ 2 "stock_bundle_id" : "123456789", 3 "stock_list" : [ 4 { 5 "product_coupon_id" : "200000001", 6 "stock_id" : "123456789", 7 "remark" : "满减券", 8 "coupon_code_mode" : "UPLOAD", 9 "coupon_code_count_info" : { 10 "total_count" : 10000, 11 "available_count" : 999 12 }, 13 "stock_send_rule" : { 14 "max_count" : 10000000, 15 "max_count_per_day" : 10000, 16 "max_count_per_user" : 1 17 }, 18 "progressive_bundle_usage_rule" : { 19 "coupon_available_period" : { 20 "available_begin_time" : "2025-01-01T00:00:00+08:00", 21 "available_end_time" : "2025-10-01T00:00:00+08:00", 22 "available_days" : 10, 23 "wait_days_after_receive" : 1, 24 "weekly_available_period" : { 25 "day_list" : [ 26 "MONDAY" 27 ], 28 "day_period_list" : [ 29 { 30 "begin_time" : 60, 31 "end_time" : 86399 32 } 33 ] 34 }, 35 "irregular_available_period_list" : [ 36 { 37 "begin_time" : "2025-01-01T00:00:00+08:00", 38 "end_time" : "2025-10-01T00:00:00+08:00" 39 } 40 ] 41 }, 42 "normal_coupon" : { 43 "threshold" : 10000, 44 "discount_amount" : 100 45 }, 46 "discount_coupon" : { 47 "threshold" : 10000, 48 "percent_off" : 30 49 }, 50 "exchange_coupon" : { 51 "threshold" : 10000, 52 "exchange_price" : 100 53 } 54 }, 55 "stock_bundle_info" : { 56 "stock_bundle_id" : "123456789", 57 "stock_bundle_index" : 0 58 }, 59 "usage_rule_display_info" : { 60 "coupon_usage_method_list" : [ 61 "MINI_PROGRAM" 62 ], 63 "mini_program_appid" : "wx1234567890", 64 "mini_program_path" : "/pages/index/product", 65 "app_path" : "https://www.example.com/jump-to-app", 66 "usage_description" : "全场可用", 67 "coupon_available_store_info" : { 68 "description" : "可在上海市区的所有门店使用,详细列表参考小程序内信息为准", 69 "mini_program_appid" : "wx1234567890", 70 "mini_program_path" : "/pages/index/store-list" 71 } 72 }, 73 "coupon_display_info" : { 74 "code_display_mode" : "QRCODE", 75 "background_color" : "Color010", 76 "entrance_mini_program" : { 77 "appid" : "wx1234567890", 78 "path" : "/pages/index/product", 79 "entrance_wording" : "欢迎选购", 80 "guidance_wording" : "获取更多优惠" 81 }, 82 "entrance_official_account" : { 83 "appid" : "wx1234567890" 84 }, 85 "entrance_finder" : { 86 "finder_id" : "gh_12345678", 87 "finder_video_id" : "UDFsdf24df34dD456Hdf34", 88 "finder_video_cover_image_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx" 89 } 90 }, 91 "notify_config" : { 92 "notify_appid" : "wx4fd12345678" 93 }, 94 "store_scope" : "SPECIFIC", 95 "sent_count_info" : { 96 "total_count" : 100, 97 "today_count" : 10 98 }, 99 "state" : "SENDING", 100 "deactivate_request_no" : "1002600620019090123143254436", 101 "deactivate_time" : "2025-01-01T00:00+08:00", 102 "deactivate_reason" : "批次信息有误,重新创建" 103 } 104 ] 105} 106
错误码
以下是本接口返回的错误码列表。详细错误码规则,请参考微信支付接口规则-错误码和错误提示


