失效用户商品券组
更新时间:2025.11.27品牌方可以通过本接口将用户商品券组内的所有商品券同步失效
前置条件:已经给用户发券成功,且商品券的 usage_mode 为 PROGRESSIVE_BUNDLE
接口说明
支持商户:【品牌商户】
请求方式:【POST】/brand/marketing/product-coupon/users/{openid}/coupon-bundles/{user_coupon_bundle_id}/deactivate
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
接口限频:500/秒(品牌ID维度)
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
Content-Type 必填 string
请设置为application/json
Wechatpay-Serial 必填 string
【微信支付公钥ID】 请传入brand_id对应的微信支付公钥ID,接口将会校验两者的关联关系,参考微信支付公钥产品简介及使用说明获取微信支付公钥ID和相关的介绍。以下两种场景将使用到微信支付公钥: 1、接收到接口的返回内容,需要使用微信支付公钥进行验签; 2、调用含有敏感信息参数(如姓名、身份证号码)的接口时,需要使用微信支付公钥加密敏感信息后再传输参数,加密指引请参考微信支付公钥加密敏感信息指引。
path 路径参数
user_coupon_bundle_id 必填 string(40)
【用户券组ID】 用户券组的唯一标识,【向用户发放商品券批次组】时由微信支付生成,本接口会同步失效用户商品券组内所有用户商品券
openid 必填 string
【用户OpenID】 OpenID信息,用户在AppID下的唯一标识,获取方式参考OpenID
body 包体参数
product_coupon_id 必填 string
【商品券ID】 商品券的唯一标识,创建商品券时由微信支付生成
stock_bundle_id 必填 string
【批次组ID】 商品券批次组的唯一标识,【创建商品券(多次优惠)】或【添加商品券批次组】时由微信支付生成,请确保该批次组属于 product_coupon_id 对应的商品券
appid 必填 string
【公众账号ID】 公众账号ID也称AppID,是(微信开放平台、微信公众平台)为开发者提供的一个唯一标识,用于识别开发者的应用程序(APP、小程序、公众号)。 开发者需要先在微信开放平台或微信公众平台中申请ID,然后在品牌经营平台中绑定,详见品牌经营平台指引。
out_request_no 必填 string(40)
【失效请求单号】 品牌失效用户商品券的请求流水号,品牌侧需保持唯一性,可使用 数字、大小写字母、下划线_、短横线- 组成,长度在6-40个字符之间
deactivate_reason 必填 string(150)
【失效原因】 记录用户商品券的失效原因,长度不超过150个UTF-8字符
请求示例
POST
1curl -X POST \ 2 https://api.mch.weixin.qq.com/brand/marketing/product-coupon/users/oh-394z-6CGkNoJrsDLTTUKiAnp4/coupon-bundles/123446565767/deactivate \ 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 "product_coupon_id" : "1002323", 9 "stock_bundle_id" : "100232301", 10 "appid" : "wx233544546545989", 11 "out_request_no" : "1002600620019090123144054436", 12 "deactivate_reason" : "商品已下线,使用户商品券失效" 13 }' 14
需配合微信支付工具库 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 DeactivateUserProductCouponBundle { 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/users/{openid}/coupon-bundles/{user_coupon_bundle_id}/deactivate"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/brand/4015415289 32 DeactivateUserProductCouponBundle client = new DeactivateUserProductCouponBundle( 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 DeactivateUserProductCouponBundleRequest request = new DeactivateUserProductCouponBundleRequest(); 41 request.userCouponBundleId = "123446565767"; 42 request.openid = "oh-394z-6CGkNoJrsDLTTUKiAnp4"; 43 request.productCouponId = "1002323"; 44 request.stockBundleId = "100232301"; 45 request.appid = "wx233544546545989"; 46 request.outRequestNo = "1002600620019090123144054436"; 47 request.deactivateReason = "商品已下线,使用户商品券失效"; 48 try { 49 DeactivateUserProductCouponBundleResponse response = client.run(request); 50 // TODO: 请求成功,继续业务逻辑 51 System.out.println(response); 52 } catch (WXPayBrandUtility.ApiException e) { 53 // TODO: 请求失败,根据状态码执行不同的逻辑 54 e.printStackTrace(); 55 } 56 } 57 58 public DeactivateUserProductCouponBundleResponse run(DeactivateUserProductCouponBundleRequest request) { 59 String uri = PATH; 60 uri = uri.replace("{user_coupon_bundle_id}", WXPayBrandUtility.urlEncode(request.userCouponBundleId)); 61 uri = uri.replace("{openid}", WXPayBrandUtility.urlEncode(request.openid)); 62 String reqBody = WXPayBrandUtility.toJson(request); 63 64 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 65 reqBuilder.addHeader("Accept", "application/json"); 66 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 67 reqBuilder.addHeader("Authorization", WXPayBrandUtility.buildAuthorization(brand_id, certificateSerialNo,privateKey, METHOD, uri, reqBody)); 68 reqBuilder.addHeader("Content-Type", "application/json"); 69 RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); 70 reqBuilder.method(METHOD, requestBody); 71 Request httpRequest = reqBuilder.build(); 72 73 // 发送HTTP请求 74 OkHttpClient client = new OkHttpClient.Builder().build(); 75 try (Response httpResponse = client.newCall(httpRequest).execute()) { 76 String respBody = WXPayBrandUtility.extractBody(httpResponse); 77 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 78 // 2XX 成功,验证应答签名 79 WXPayBrandUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 80 httpResponse.headers(), respBody); 81 82 // 从HTTP应答报文构建返回数据 83 return WXPayBrandUtility.fromJson(respBody, DeactivateUserProductCouponBundleResponse.class); 84 } else { 85 throw new WXPayBrandUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 86 } 87 } catch (IOException e) { 88 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 89 } 90 } 91 92 private final String brand_id; 93 private final String certificateSerialNo; 94 private final PrivateKey privateKey; 95 private final String wechatPayPublicKeyId; 96 private final PublicKey wechatPayPublicKey; 97 98 public DeactivateUserProductCouponBundle(String brand_id, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 99 this.brand_id = brand_id; 100 this.certificateSerialNo = certificateSerialNo; 101 this.privateKey = WXPayBrandUtility.loadPrivateKeyFromPath(privateKeyFilePath); 102 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 103 this.wechatPayPublicKey = WXPayBrandUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 104 } 105 106 public static class DeactivateUserProductCouponBundleRequest { 107 @SerializedName("product_coupon_id") 108 public String productCouponId; 109 110 @SerializedName("stock_bundle_id") 111 public String stockBundleId; 112 113 @SerializedName("user_coupon_bundle_id") 114 @Expose(serialize = false) 115 public String userCouponBundleId; 116 117 @SerializedName("appid") 118 public String appid; 119 120 @SerializedName("openid") 121 @Expose(serialize = false) 122 public String openid; 123 124 @SerializedName("out_request_no") 125 public String outRequestNo; 126 127 @SerializedName("deactivate_reason") 128 public String deactivateReason; 129 } 130 131 public static class DeactivateUserProductCouponBundleResponse { 132 @SerializedName("user_coupon_bundle_id") 133 public String userCouponBundleId; 134 135 @SerializedName("user_product_coupon_list") 136 public List<UserProductCouponEntity> userProductCouponList = new ArrayList<UserProductCouponEntity>(); 137 } 138 139 public static class UserProductCouponEntity { 140 @SerializedName("coupon_code") 141 public String couponCode; 142 143 @SerializedName("coupon_state") 144 public UserProductCouponState couponState; 145 146 @SerializedName("valid_begin_time") 147 public String validBeginTime; 148 149 @SerializedName("valid_end_time") 150 public String validEndTime; 151 152 @SerializedName("receive_time") 153 public String receiveTime; 154 155 @SerializedName("send_request_no") 156 public String sendRequestNo; 157 158 @SerializedName("send_channel") 159 public UserProductCouponSendChannel sendChannel; 160 161 @SerializedName("confirm_request_no") 162 public String confirmRequestNo; 163 164 @SerializedName("confirm_time") 165 public String confirmTime; 166 167 @SerializedName("deactivate_request_no") 168 public String deactivateRequestNo; 169 170 @SerializedName("deactivate_time") 171 public String deactivateTime; 172 173 @SerializedName("deactivate_reason") 174 public String deactivateReason; 175 176 @SerializedName("progressive_bundle_usage_detail") 177 public CouponUsageDetail progressiveBundleUsageDetail; 178 179 @SerializedName("user_product_coupon_bundle_info") 180 public UserProductCouponBundleInfo userProductCouponBundleInfo; 181 182 @SerializedName("product_coupon") 183 public ProductCouponEntity productCoupon; 184 185 @SerializedName("stock") 186 public StockEntity stock; 187 188 @SerializedName("attach") 189 public String attach; 190 191 @SerializedName("channel_custom_info") 192 public String channelCustomInfo; 193 194 @SerializedName("coupon_tag_info") 195 public CouponTagInfo couponTagInfo; 196 } 197 198 public enum UserProductCouponState { 199 @SerializedName("CONFIRMING") 200 CONFIRMING, 201 @SerializedName("PENDING") 202 PENDING, 203 @SerializedName("EFFECTIVE") 204 EFFECTIVE, 205 @SerializedName("USED") 206 USED, 207 @SerializedName("EXPIRED") 208 EXPIRED, 209 @SerializedName("DELETED") 210 DELETED, 211 @SerializedName("DEACTIVATED") 212 DEACTIVATED 213 } 214 215 public enum UserProductCouponSendChannel { 216 @SerializedName("BRAND_MANAGE") 217 BRAND_MANAGE, 218 @SerializedName("API") 219 API, 220 @SerializedName("RECEIVE_COMPONENT") 221 RECEIVE_COMPONENT 222 } 223 224 public static class CouponUsageDetail { 225 @SerializedName("use_request_no") 226 public String useRequestNo; 227 228 @SerializedName("use_time") 229 public String useTime; 230 231 @SerializedName("return_request_no") 232 public String returnRequestNo; 233 234 @SerializedName("return_time") 235 public String returnTime; 236 237 @SerializedName("associated_order_info") 238 public UserProductCouponAssociatedOrderInfo associatedOrderInfo; 239 240 @SerializedName("associated_pay_score_order_info") 241 public UserProductCouponAssociatedPayScoreOrderInfo associatedPayScoreOrderInfo; 242 243 @SerializedName("saved_amount") 244 public Long savedAmount; 245 } 246 247 public static class UserProductCouponBundleInfo { 248 @SerializedName("user_coupon_bundle_id") 249 public String userCouponBundleId; 250 251 @SerializedName("user_coupon_bundle_index") 252 public Long userCouponBundleIndex; 253 254 @SerializedName("total_count") 255 public Long totalCount; 256 257 @SerializedName("used_count") 258 public Long usedCount; 259 } 260 261 public static class ProductCouponEntity { 262 @SerializedName("product_coupon_id") 263 public String productCouponId; 264 265 @SerializedName("scope") 266 public ProductCouponScope scope; 267 268 @SerializedName("type") 269 public ProductCouponType type; 270 271 @SerializedName("usage_mode") 272 public UsageMode usageMode; 273 274 @SerializedName("single_usage_info") 275 public SingleUsageInfo singleUsageInfo; 276 277 @SerializedName("progressive_bundle_usage_info") 278 public ProgressiveBundleUsageInfo progressiveBundleUsageInfo; 279 280 @SerializedName("display_info") 281 public ProductCouponDisplayInfo displayInfo; 282 283 @SerializedName("out_product_no") 284 public String outProductNo; 285 286 @SerializedName("state") 287 public ProductCouponState state; 288 289 @SerializedName("deactivate_request_no") 290 public String deactivateRequestNo; 291 292 @SerializedName("deactivate_time") 293 public String deactivateTime; 294 295 @SerializedName("deactivate_reason") 296 public String deactivateReason; 297 } 298 299 public static class StockEntity { 300 @SerializedName("product_coupon_id") 301 public String productCouponId; 302 303 @SerializedName("stock_id") 304 public String stockId; 305 306 @SerializedName("remark") 307 public String remark; 308 309 @SerializedName("coupon_code_mode") 310 public CouponCodeMode couponCodeMode; 311 312 @SerializedName("coupon_code_count_info") 313 public CouponCodeCountInfo couponCodeCountInfo; 314 315 @SerializedName("stock_send_rule") 316 public StockSendRule stockSendRule; 317 318 @SerializedName("progressive_bundle_usage_rule") 319 public StockUsageRule progressiveBundleUsageRule; 320 321 @SerializedName("stock_bundle_info") 322 public StockBundleInfo stockBundleInfo; 323 324 @SerializedName("usage_rule_display_info") 325 public UsageRuleDisplayInfo usageRuleDisplayInfo; 326 327 @SerializedName("coupon_display_info") 328 public CouponDisplayInfo couponDisplayInfo; 329 330 @SerializedName("notify_config") 331 public NotifyConfig notifyConfig; 332 333 @SerializedName("store_scope") 334 public StockStoreScope storeScope; 335 336 @SerializedName("sent_count_info") 337 public StockSentCountInfo sentCountInfo; 338 339 @SerializedName("state") 340 public StockState state; 341 342 @SerializedName("deactivate_request_no") 343 public String deactivateRequestNo; 344 345 @SerializedName("deactivate_time") 346 public String deactivateTime; 347 348 @SerializedName("deactivate_reason") 349 public String deactivateReason; 350 } 351 352 public static class CouponTagInfo { 353 @SerializedName("coupon_tag_list") 354 public List<UserProductCouponTag> couponTagList; 355 356 @SerializedName("member_tag_info") 357 public MemberTagInfo memberTagInfo; 358 } 359 360 public static class UserProductCouponAssociatedOrderInfo { 361 @SerializedName("transaction_id") 362 public String transactionId; 363 364 @SerializedName("out_trade_no") 365 public String outTradeNo; 366 367 @SerializedName("mchid") 368 public String mchid; 369 370 @SerializedName("sub_mchid") 371 public String subMchid; 372 } 373 374 public static class UserProductCouponAssociatedPayScoreOrderInfo { 375 @SerializedName("order_id") 376 public String orderId; 377 378 @SerializedName("out_order_no") 379 public String outOrderNo; 380 381 @SerializedName("mchid") 382 public String mchid; 383 384 @SerializedName("sub_mchid") 385 public String subMchid; 386 } 387 388 public enum ProductCouponScope { 389 @SerializedName("ALL") 390 ALL, 391 @SerializedName("SINGLE") 392 SINGLE 393 } 394 395 public enum ProductCouponType { 396 @SerializedName("NORMAL") 397 NORMAL, 398 @SerializedName("DISCOUNT") 399 DISCOUNT, 400 @SerializedName("EXCHANGE") 401 EXCHANGE 402 } 403 404 public enum UsageMode { 405 @SerializedName("SINGLE") 406 SINGLE, 407 @SerializedName("PROGRESSIVE_BUNDLE") 408 PROGRESSIVE_BUNDLE 409 } 410 411 public static class SingleUsageInfo { 412 @SerializedName("normal_coupon") 413 public NormalCouponUsageRule normalCoupon; 414 415 @SerializedName("discount_coupon") 416 public DiscountCouponUsageRule discountCoupon; 417 } 418 419 public static class ProgressiveBundleUsageInfo { 420 @SerializedName("count") 421 public Long count; 422 423 @SerializedName("interval_days") 424 public Long intervalDays; 425 } 426 427 public static class ProductCouponDisplayInfo { 428 @SerializedName("name") 429 public String name; 430 431 @SerializedName("image_url") 432 public String imageUrl; 433 434 @SerializedName("background_url") 435 public String backgroundUrl; 436 437 @SerializedName("detail_image_url_list") 438 public List<String> detailImageUrlList; 439 440 @SerializedName("original_price") 441 public Long originalPrice; 442 443 @SerializedName("combo_package_list") 444 public List<ComboPackage> comboPackageList; 445 } 446 447 public enum ProductCouponState { 448 @SerializedName("AUDITING") 449 AUDITING, 450 @SerializedName("EFFECTIVE") 451 EFFECTIVE, 452 @SerializedName("DEACTIVATED") 453 DEACTIVATED 454 } 455 456 public enum CouponCodeMode { 457 @SerializedName("WECHATPAY") 458 WECHATPAY, 459 @SerializedName("UPLOAD") 460 UPLOAD 461 } 462 463 public static class CouponCodeCountInfo { 464 @SerializedName("total_count") 465 public Long totalCount; 466 467 @SerializedName("available_count") 468 public Long availableCount; 469 } 470 471 public static class StockSendRule { 472 @SerializedName("max_count") 473 public Long maxCount; 474 475 @SerializedName("max_count_per_day") 476 public Long maxCountPerDay; 477 478 @SerializedName("max_count_per_user") 479 public Long maxCountPerUser; 480 } 481 482 public static class StockUsageRule { 483 @SerializedName("coupon_available_period") 484 public CouponAvailablePeriod couponAvailablePeriod; 485 486 @SerializedName("normal_coupon") 487 public NormalCouponUsageRule normalCoupon; 488 489 @SerializedName("discount_coupon") 490 public DiscountCouponUsageRule discountCoupon; 491 492 @SerializedName("exchange_coupon") 493 public ExchangeCouponUsageRule exchangeCoupon; 494 } 495 496 public static class StockBundleInfo { 497 @SerializedName("stock_bundle_id") 498 public String stockBundleId; 499 500 @SerializedName("stock_bundle_index") 501 public Long stockBundleIndex; 502 } 503 504 public static class UsageRuleDisplayInfo { 505 @SerializedName("coupon_usage_method_list") 506 public List<CouponUsageMethod> couponUsageMethodList = new ArrayList<CouponUsageMethod>(); 507 508 @SerializedName("mini_program_appid") 509 public String miniProgramAppid; 510 511 @SerializedName("mini_program_path") 512 public String miniProgramPath; 513 514 @SerializedName("app_path") 515 public String appPath; 516 517 @SerializedName("usage_description") 518 public String usageDescription; 519 520 @SerializedName("coupon_available_store_info") 521 public CouponAvailableStoreInfo couponAvailableStoreInfo; 522 } 523 524 public static class CouponDisplayInfo { 525 @SerializedName("code_display_mode") 526 public CouponCodeDisplayMode codeDisplayMode; 527 528 @SerializedName("background_color") 529 public String backgroundColor; 530 531 @SerializedName("entrance_mini_program") 532 public EntranceMiniProgram entranceMiniProgram; 533 534 @SerializedName("entrance_official_account") 535 public EntranceOfficialAccount entranceOfficialAccount; 536 537 @SerializedName("entrance_finder") 538 public EntranceFinder entranceFinder; 539 } 540 541 public static class NotifyConfig { 542 @SerializedName("notify_appid") 543 public String notifyAppid; 544 } 545 546 public enum StockStoreScope { 547 @SerializedName("NONE") 548 NONE, 549 @SerializedName("ALL") 550 ALL, 551 @SerializedName("SPECIFIC") 552 SPECIFIC 553 } 554 555 public static class StockSentCountInfo { 556 @SerializedName("total_count") 557 public Long totalCount; 558 559 @SerializedName("today_count") 560 public Long todayCount; 561 } 562 563 public enum StockState { 564 @SerializedName("AUDITING") 565 AUDITING, 566 @SerializedName("SENDING") 567 SENDING, 568 @SerializedName("PAUSED") 569 PAUSED, 570 @SerializedName("STOPPED") 571 STOPPED, 572 @SerializedName("DEACTIVATED") 573 DEACTIVATED 574 } 575 576 public enum UserProductCouponTag { 577 @SerializedName("MEMBER") 578 MEMBER 579 } 580 581 public static class MemberTagInfo { 582 @SerializedName("member_card_id") 583 public String memberCardId; 584 } 585 586 public static class NormalCouponUsageRule { 587 @SerializedName("threshold") 588 public Long threshold; 589 590 @SerializedName("discount_amount") 591 public Long discountAmount; 592 } 593 594 public static class DiscountCouponUsageRule { 595 @SerializedName("threshold") 596 public Long threshold; 597 598 @SerializedName("percent_off") 599 public Long percentOff; 600 } 601 602 public static class ComboPackage { 603 @SerializedName("name") 604 public String name; 605 606 @SerializedName("pick_count") 607 public Long pickCount; 608 609 @SerializedName("choice_list") 610 public List<ComboPackageChoice> choiceList = new ArrayList<ComboPackageChoice>(); 611 } 612 613 public static class CouponAvailablePeriod { 614 @SerializedName("available_begin_time") 615 public String availableBeginTime; 616 617 @SerializedName("available_end_time") 618 public String availableEndTime; 619 620 @SerializedName("available_days") 621 public Long availableDays; 622 623 @SerializedName("wait_days_after_receive") 624 public Long waitDaysAfterReceive; 625 626 @SerializedName("weekly_available_period") 627 public FixedWeekPeriod weeklyAvailablePeriod; 628 629 @SerializedName("irregular_available_period_list") 630 public List<TimePeriod> irregularAvailablePeriodList; 631 } 632 633 public static class ExchangeCouponUsageRule { 634 @SerializedName("threshold") 635 public Long threshold; 636 637 @SerializedName("exchange_price") 638 public Long exchangePrice; 639 } 640 641 public enum CouponUsageMethod { 642 @SerializedName("OFFLINE") 643 OFFLINE, 644 @SerializedName("MINI_PROGRAM") 645 MINI_PROGRAM, 646 @SerializedName("APP") 647 APP, 648 @SerializedName("PAYMENT_CODE") 649 PAYMENT_CODE 650 } 651 652 public static class CouponAvailableStoreInfo { 653 @SerializedName("description") 654 public String description; 655 656 @SerializedName("mini_program_appid") 657 public String miniProgramAppid; 658 659 @SerializedName("mini_program_path") 660 public String miniProgramPath; 661 } 662 663 public enum CouponCodeDisplayMode { 664 @SerializedName("INVISIBLE") 665 INVISIBLE, 666 @SerializedName("BARCODE") 667 BARCODE, 668 @SerializedName("QRCODE") 669 QRCODE 670 } 671 672 public static class EntranceMiniProgram { 673 @SerializedName("appid") 674 public String appid; 675 676 @SerializedName("path") 677 public String path; 678 679 @SerializedName("entrance_wording") 680 public String entranceWording; 681 682 @SerializedName("guidance_wording") 683 public String guidanceWording; 684 } 685 686 public static class EntranceOfficialAccount { 687 @SerializedName("appid") 688 public String appid; 689 } 690 691 public static class EntranceFinder { 692 @SerializedName("finder_id") 693 public String finderId; 694 695 @SerializedName("finder_video_id") 696 public String finderVideoId; 697 698 @SerializedName("finder_video_cover_image_url") 699 public String finderVideoCoverImageUrl; 700 } 701 702 public static class ComboPackageChoice { 703 @SerializedName("name") 704 public String name; 705 706 @SerializedName("price") 707 public Long price; 708 709 @SerializedName("count") 710 public Long count; 711 712 @SerializedName("image_url") 713 public String imageUrl; 714 715 @SerializedName("mini_program_appid") 716 public String miniProgramAppid; 717 718 @SerializedName("mini_program_path") 719 public String miniProgramPath; 720 } 721 722 public static class FixedWeekPeriod { 723 @SerializedName("day_list") 724 public List<WeekEnum> dayList = new ArrayList<WeekEnum>(); 725 726 @SerializedName("day_period_list") 727 public List<PeriodOfTheDay> dayPeriodList; 728 } 729 730 public static class TimePeriod { 731 @SerializedName("begin_time") 732 public String beginTime; 733 734 @SerializedName("end_time") 735 public String endTime; 736 } 737 738 public enum WeekEnum { 739 @SerializedName("MONDAY") 740 MONDAY, 741 @SerializedName("TUESDAY") 742 TUESDAY, 743 @SerializedName("WEDNESDAY") 744 WEDNESDAY, 745 @SerializedName("THURSDAY") 746 THURSDAY, 747 @SerializedName("FRIDAY") 748 FRIDAY, 749 @SerializedName("SATURDAY") 750 SATURDAY, 751 @SerializedName("SUNDAY") 752 SUNDAY 753 } 754 755 public static class PeriodOfTheDay { 756 @SerializedName("begin_time") 757 public Long beginTime; 758 759 @SerializedName("end_time") 760 public Long endTime; 761 } 762 763} 764
需配合微信支付工具库 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 := &DeactivateUserProductCouponBundleRequest{ 29 UserCouponBundleId: wxpay_brand_utility.String("123446565767"), 30 Openid: wxpay_brand_utility.String("oh-394z-6CGkNoJrsDLTTUKiAnp4"), 31 ProductCouponId: wxpay_brand_utility.String("1002323"), 32 StockBundleId: wxpay_brand_utility.String("100232301"), 33 Appid: wxpay_brand_utility.String("wx233544546545989"), 34 OutRequestNo: wxpay_brand_utility.String("1002600620019090123144054436"), 35 DeactivateReason: wxpay_brand_utility.String("商品已下线,使用户商品券失效"), 36 } 37 38 response, err := DeactivateUserProductCouponBundle(config, request) 39 if err != nil { 40 fmt.Printf("请求失败: %+v\n", err) 41 // TODO: 请求失败,根据状态码执行不同的处理 42 return 43 } 44 45 // TODO: 请求成功,继续业务逻辑 46 fmt.Printf("请求成功: %+v\n", response) 47} 48 49func DeactivateUserProductCouponBundle(config *wxpay_brand_utility.BrandConfig, request *DeactivateUserProductCouponBundleRequest) (response *DeactivateUserProductCouponBundleResponse, err error) { 50 const ( 51 host = "https://api.mch.weixin.qq.com" 52 method = "POST" 53 path = "/brand/marketing/product-coupon/users/{openid}/coupon-bundles/{user_coupon_bundle_id}/deactivate" 54 ) 55 56 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 57 if err != nil { 58 return nil, err 59 } 60 reqUrl.Path = strings.Replace(reqUrl.Path, "{user_coupon_bundle_id}", url.PathEscape(*request.UserCouponBundleId), -1) 61 reqUrl.Path = strings.Replace(reqUrl.Path, "{openid}", url.PathEscape(*request.Openid), -1) 62 reqBody, err := json.Marshal(request) 63 if err != nil { 64 return nil, err 65 } 66 httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody)) 67 if err != nil { 68 return nil, err 69 } 70 httpRequest.Header.Set("Accept", "application/json") 71 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 72 httpRequest.Header.Set("Content-Type", "application/json") 73 authorization, err := wxpay_brand_utility.BuildAuthorization(config.BrandId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody) 74 if err != nil { 75 return nil, err 76 } 77 httpRequest.Header.Set("Authorization", authorization) 78 79 client := &http.Client{} 80 httpResponse, err := client.Do(httpRequest) 81 if err != nil { 82 return nil, err 83 } 84 respBody, err := wxpay_brand_utility.ExtractResponseBody(httpResponse) 85 if err != nil { 86 return nil, err 87 } 88 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 89 // 2XX 成功,验证应答签名 90 err = wxpay_brand_utility.ValidateResponse( 91 config.WechatPayPublicKeyId(), 92 config.WechatPayPublicKey(), 93 &httpResponse.Header, 94 respBody, 95 ) 96 if err != nil { 97 return nil, err 98 } 99 response := &DeactivateUserProductCouponBundleResponse{} 100 if err := json.Unmarshal(respBody, response); err != nil { 101 return nil, err 102 } 103 104 return response, nil 105 } else { 106 return nil, wxpay_brand_utility.NewApiException( 107 httpResponse.StatusCode, 108 httpResponse.Header, 109 respBody, 110 ) 111 } 112} 113 114type DeactivateUserProductCouponBundleRequest struct { 115 ProductCouponId *string `json:"product_coupon_id,omitempty"` 116 StockBundleId *string `json:"stock_bundle_id,omitempty"` 117 UserCouponBundleId *string `json:"user_coupon_bundle_id,omitempty"` 118 Appid *string `json:"appid,omitempty"` 119 Openid *string `json:"openid,omitempty"` 120 OutRequestNo *string `json:"out_request_no,omitempty"` 121 DeactivateReason *string `json:"deactivate_reason,omitempty"` 122} 123 124func (o *DeactivateUserProductCouponBundleRequest) MarshalJSON() ([]byte, error) { 125 type Alias DeactivateUserProductCouponBundleRequest 126 a := &struct { 127 UserCouponBundleId *string `json:"user_coupon_bundle_id,omitempty"` 128 Openid *string `json:"openid,omitempty"` 129 *Alias 130 }{ 131 // 序列化时移除非 Body 字段 132 UserCouponBundleId: nil, 133 Openid: nil, 134 Alias: (*Alias)(o), 135 } 136 return json.Marshal(a) 137} 138 139type DeactivateUserProductCouponBundleResponse struct { 140 UserCouponBundleId *string `json:"user_coupon_bundle_id,omitempty"` 141 UserProductCouponList []UserProductCouponEntity `json:"user_product_coupon_list,omitempty"` 142} 143 144type UserProductCouponEntity struct { 145 CouponCode *string `json:"coupon_code,omitempty"` 146 CouponState *UserProductCouponState `json:"coupon_state,omitempty"` 147 ValidBeginTime *time.Time `json:"valid_begin_time,omitempty"` 148 ValidEndTime *time.Time `json:"valid_end_time,omitempty"` 149 ReceiveTime *string `json:"receive_time,omitempty"` 150 SendRequestNo *string `json:"send_request_no,omitempty"` 151 SendChannel *UserProductCouponSendChannel `json:"send_channel,omitempty"` 152 ConfirmRequestNo *string `json:"confirm_request_no,omitempty"` 153 ConfirmTime *time.Time `json:"confirm_time,omitempty"` 154 DeactivateRequestNo *string `json:"deactivate_request_no,omitempty"` 155 DeactivateTime *string `json:"deactivate_time,omitempty"` 156 DeactivateReason *string `json:"deactivate_reason,omitempty"` 157 ProgressiveBundleUsageDetail *CouponUsageDetail `json:"progressive_bundle_usage_detail,omitempty"` 158 UserProductCouponBundleInfo *UserProductCouponBundleInfo `json:"user_product_coupon_bundle_info,omitempty"` 159 ProductCoupon *ProductCouponEntity `json:"product_coupon,omitempty"` 160 Stock *StockEntity `json:"stock,omitempty"` 161 Attach *string `json:"attach,omitempty"` 162 ChannelCustomInfo *string `json:"channel_custom_info,omitempty"` 163 CouponTagInfo *CouponTagInfo `json:"coupon_tag_info,omitempty"` 164} 165 166type UserProductCouponState string 167 168func (e UserProductCouponState) Ptr() *UserProductCouponState { 169 return &e 170} 171 172const ( 173 USERPRODUCTCOUPONSTATE_CONFIRMING UserProductCouponState = "CONFIRMING" 174 USERPRODUCTCOUPONSTATE_PENDING UserProductCouponState = "PENDING" 175 USERPRODUCTCOUPONSTATE_EFFECTIVE UserProductCouponState = "EFFECTIVE" 176 USERPRODUCTCOUPONSTATE_USED UserProductCouponState = "USED" 177 USERPRODUCTCOUPONSTATE_EXPIRED UserProductCouponState = "EXPIRED" 178 USERPRODUCTCOUPONSTATE_DELETED UserProductCouponState = "DELETED" 179 USERPRODUCTCOUPONSTATE_DEACTIVATED UserProductCouponState = "DEACTIVATED" 180) 181 182type UserProductCouponSendChannel string 183 184func (e UserProductCouponSendChannel) Ptr() *UserProductCouponSendChannel { 185 return &e 186} 187 188const ( 189 USERPRODUCTCOUPONSENDCHANNEL_BRAND_MANAGE UserProductCouponSendChannel = "BRAND_MANAGE" 190 USERPRODUCTCOUPONSENDCHANNEL_API UserProductCouponSendChannel = "API" 191 USERPRODUCTCOUPONSENDCHANNEL_RECEIVE_COMPONENT UserProductCouponSendChannel = "RECEIVE_COMPONENT" 192) 193 194type CouponUsageDetail struct { 195 UseRequestNo *string `json:"use_request_no,omitempty"` 196 UseTime *time.Time `json:"use_time,omitempty"` 197 ReturnRequestNo *string `json:"return_request_no,omitempty"` 198 ReturnTime *time.Time `json:"return_time,omitempty"` 199 AssociatedOrderInfo *UserProductCouponAssociatedOrderInfo `json:"associated_order_info,omitempty"` 200 AssociatedPayScoreOrderInfo *UserProductCouponAssociatedPayScoreOrderInfo `json:"associated_pay_score_order_info,omitempty"` 201 SavedAmount *int64 `json:"saved_amount,omitempty"` 202} 203 204type UserProductCouponBundleInfo struct { 205 UserCouponBundleId *string `json:"user_coupon_bundle_id,omitempty"` 206 UserCouponBundleIndex *int64 `json:"user_coupon_bundle_index,omitempty"` 207 TotalCount *int64 `json:"total_count,omitempty"` 208 UsedCount *int64 `json:"used_count,omitempty"` 209} 210 211type ProductCouponEntity struct { 212 ProductCouponId *string `json:"product_coupon_id,omitempty"` 213 Scope *ProductCouponScope `json:"scope,omitempty"` 214 Type *ProductCouponType `json:"type,omitempty"` 215 UsageMode *UsageMode `json:"usage_mode,omitempty"` 216 SingleUsageInfo *SingleUsageInfo `json:"single_usage_info,omitempty"` 217 ProgressiveBundleUsageInfo *ProgressiveBundleUsageInfo `json:"progressive_bundle_usage_info,omitempty"` 218 DisplayInfo *ProductCouponDisplayInfo `json:"display_info,omitempty"` 219 OutProductNo *string `json:"out_product_no,omitempty"` 220 State *ProductCouponState `json:"state,omitempty"` 221 DeactivateRequestNo *string `json:"deactivate_request_no,omitempty"` 222 DeactivateTime *string `json:"deactivate_time,omitempty"` 223 DeactivateReason *string `json:"deactivate_reason,omitempty"` 224} 225 226type StockEntity struct { 227 ProductCouponId *string `json:"product_coupon_id,omitempty"` 228 StockId *string `json:"stock_id,omitempty"` 229 Remark *string `json:"remark,omitempty"` 230 CouponCodeMode *CouponCodeMode `json:"coupon_code_mode,omitempty"` 231 CouponCodeCountInfo *CouponCodeCountInfo `json:"coupon_code_count_info,omitempty"` 232 StockSendRule *StockSendRule `json:"stock_send_rule,omitempty"` 233 ProgressiveBundleUsageRule *StockUsageRule `json:"progressive_bundle_usage_rule,omitempty"` 234 StockBundleInfo *StockBundleInfo `json:"stock_bundle_info,omitempty"` 235 UsageRuleDisplayInfo *UsageRuleDisplayInfo `json:"usage_rule_display_info,omitempty"` 236 CouponDisplayInfo *CouponDisplayInfo `json:"coupon_display_info,omitempty"` 237 NotifyConfig *NotifyConfig `json:"notify_config,omitempty"` 238 StoreScope *StockStoreScope `json:"store_scope,omitempty"` 239 SentCountInfo *StockSentCountInfo `json:"sent_count_info,omitempty"` 240 State *StockState `json:"state,omitempty"` 241 DeactivateRequestNo *string `json:"deactivate_request_no,omitempty"` 242 DeactivateTime *time.Time `json:"deactivate_time,omitempty"` 243 DeactivateReason *string `json:"deactivate_reason,omitempty"` 244} 245 246type CouponTagInfo struct { 247 CouponTagList []UserProductCouponTag `json:"coupon_tag_list,omitempty"` 248 MemberTagInfo *MemberTagInfo `json:"member_tag_info,omitempty"` 249} 250 251type UserProductCouponAssociatedOrderInfo struct { 252 TransactionId *string `json:"transaction_id,omitempty"` 253 OutTradeNo *string `json:"out_trade_no,omitempty"` 254 Mchid *string `json:"mchid,omitempty"` 255 SubMchid *string `json:"sub_mchid,omitempty"` 256} 257 258type UserProductCouponAssociatedPayScoreOrderInfo struct { 259 OrderId *string `json:"order_id,omitempty"` 260 OutOrderNo *string `json:"out_order_no,omitempty"` 261 Mchid *string `json:"mchid,omitempty"` 262 SubMchid *string `json:"sub_mchid,omitempty"` 263} 264 265type ProductCouponScope string 266 267func (e ProductCouponScope) Ptr() *ProductCouponScope { 268 return &e 269} 270 271const ( 272 PRODUCTCOUPONSCOPE_ALL ProductCouponScope = "ALL" 273 PRODUCTCOUPONSCOPE_SINGLE ProductCouponScope = "SINGLE" 274) 275 276type ProductCouponType string 277 278func (e ProductCouponType) Ptr() *ProductCouponType { 279 return &e 280} 281 282const ( 283 PRODUCTCOUPONTYPE_NORMAL ProductCouponType = "NORMAL" 284 PRODUCTCOUPONTYPE_DISCOUNT ProductCouponType = "DISCOUNT" 285 PRODUCTCOUPONTYPE_EXCHANGE ProductCouponType = "EXCHANGE" 286) 287 288type UsageMode string 289 290func (e UsageMode) Ptr() *UsageMode { 291 return &e 292} 293 294const ( 295 USAGEMODE_SINGLE UsageMode = "SINGLE" 296 USAGEMODE_PROGRESSIVE_BUNDLE UsageMode = "PROGRESSIVE_BUNDLE" 297) 298 299type SingleUsageInfo struct { 300 NormalCoupon *NormalCouponUsageRule `json:"normal_coupon,omitempty"` 301 DiscountCoupon *DiscountCouponUsageRule `json:"discount_coupon,omitempty"` 302} 303 304type ProgressiveBundleUsageInfo struct { 305 Count *int64 `json:"count,omitempty"` 306 IntervalDays *int64 `json:"interval_days,omitempty"` 307} 308 309type ProductCouponDisplayInfo struct { 310 Name *string `json:"name,omitempty"` 311 ImageUrl *string `json:"image_url,omitempty"` 312 BackgroundUrl *string `json:"background_url,omitempty"` 313 DetailImageUrlList []string `json:"detail_image_url_list,omitempty"` 314 OriginalPrice *int64 `json:"original_price,omitempty"` 315 ComboPackageList []ComboPackage `json:"combo_package_list,omitempty"` 316} 317 318type ProductCouponState string 319 320func (e ProductCouponState) Ptr() *ProductCouponState { 321 return &e 322} 323 324const ( 325 PRODUCTCOUPONSTATE_AUDITING ProductCouponState = "AUDITING" 326 PRODUCTCOUPONSTATE_EFFECTIVE ProductCouponState = "EFFECTIVE" 327 PRODUCTCOUPONSTATE_DEACTIVATED ProductCouponState = "DEACTIVATED" 328) 329 330type CouponCodeMode string 331 332func (e CouponCodeMode) Ptr() *CouponCodeMode { 333 return &e 334} 335 336const ( 337 COUPONCODEMODE_WECHATPAY CouponCodeMode = "WECHATPAY" 338 COUPONCODEMODE_UPLOAD CouponCodeMode = "UPLOAD" 339) 340 341type CouponCodeCountInfo struct { 342 TotalCount *int64 `json:"total_count,omitempty"` 343 AvailableCount *int64 `json:"available_count,omitempty"` 344} 345 346type StockSendRule struct { 347 MaxCount *int64 `json:"max_count,omitempty"` 348 MaxCountPerDay *int64 `json:"max_count_per_day,omitempty"` 349 MaxCountPerUser *int64 `json:"max_count_per_user,omitempty"` 350} 351 352type StockUsageRule struct { 353 CouponAvailablePeriod *CouponAvailablePeriod `json:"coupon_available_period,omitempty"` 354 NormalCoupon *NormalCouponUsageRule `json:"normal_coupon,omitempty"` 355 DiscountCoupon *DiscountCouponUsageRule `json:"discount_coupon,omitempty"` 356 ExchangeCoupon *ExchangeCouponUsageRule `json:"exchange_coupon,omitempty"` 357} 358 359type StockBundleInfo struct { 360 StockBundleId *string `json:"stock_bundle_id,omitempty"` 361 StockBundleIndex *int64 `json:"stock_bundle_index,omitempty"` 362} 363 364type UsageRuleDisplayInfo struct { 365 CouponUsageMethodList []CouponUsageMethod `json:"coupon_usage_method_list,omitempty"` 366 MiniProgramAppid *string `json:"mini_program_appid,omitempty"` 367 MiniProgramPath *string `json:"mini_program_path,omitempty"` 368 AppPath *string `json:"app_path,omitempty"` 369 UsageDescription *string `json:"usage_description,omitempty"` 370 CouponAvailableStoreInfo *CouponAvailableStoreInfo `json:"coupon_available_store_info,omitempty"` 371} 372 373type CouponDisplayInfo struct { 374 CodeDisplayMode *CouponCodeDisplayMode `json:"code_display_mode,omitempty"` 375 BackgroundColor *string `json:"background_color,omitempty"` 376 EntranceMiniProgram *EntranceMiniProgram `json:"entrance_mini_program,omitempty"` 377 EntranceOfficialAccount *EntranceOfficialAccount `json:"entrance_official_account,omitempty"` 378 EntranceFinder *EntranceFinder `json:"entrance_finder,omitempty"` 379} 380 381type NotifyConfig struct { 382 NotifyAppid *string `json:"notify_appid,omitempty"` 383} 384 385type StockStoreScope string 386 387func (e StockStoreScope) Ptr() *StockStoreScope { 388 return &e 389} 390 391const ( 392 STOCKSTORESCOPE_NONE StockStoreScope = "NONE" 393 STOCKSTORESCOPE_ALL StockStoreScope = "ALL" 394 STOCKSTORESCOPE_SPECIFIC StockStoreScope = "SPECIFIC" 395) 396 397type StockSentCountInfo struct { 398 TotalCount *int64 `json:"total_count,omitempty"` 399 TodayCount *int64 `json:"today_count,omitempty"` 400} 401 402type StockState string 403 404func (e StockState) Ptr() *StockState { 405 return &e 406} 407 408const ( 409 STOCKSTATE_AUDITING StockState = "AUDITING" 410 STOCKSTATE_SENDING StockState = "SENDING" 411 STOCKSTATE_PAUSED StockState = "PAUSED" 412 STOCKSTATE_STOPPED StockState = "STOPPED" 413 STOCKSTATE_DEACTIVATED StockState = "DEACTIVATED" 414) 415 416type UserProductCouponTag string 417 418func (e UserProductCouponTag) Ptr() *UserProductCouponTag { 419 return &e 420} 421 422const ( 423 USERPRODUCTCOUPONTAG_MEMBER UserProductCouponTag = "MEMBER" 424) 425 426type MemberTagInfo struct { 427 MemberCardId *string `json:"member_card_id,omitempty"` 428} 429 430type NormalCouponUsageRule struct { 431 Threshold *int64 `json:"threshold,omitempty"` 432 DiscountAmount *int64 `json:"discount_amount,omitempty"` 433} 434 435type DiscountCouponUsageRule struct { 436 Threshold *int64 `json:"threshold,omitempty"` 437 PercentOff *int64 `json:"percent_off,omitempty"` 438} 439 440type ComboPackage struct { 441 Name *string `json:"name,omitempty"` 442 PickCount *int64 `json:"pick_count,omitempty"` 443 ChoiceList []ComboPackageChoice `json:"choice_list,omitempty"` 444} 445 446type CouponAvailablePeriod struct { 447 AvailableBeginTime *string `json:"available_begin_time,omitempty"` 448 AvailableEndTime *string `json:"available_end_time,omitempty"` 449 AvailableDays *int64 `json:"available_days,omitempty"` 450 WaitDaysAfterReceive *int64 `json:"wait_days_after_receive,omitempty"` 451 WeeklyAvailablePeriod *FixedWeekPeriod `json:"weekly_available_period,omitempty"` 452 IrregularAvailablePeriodList []TimePeriod `json:"irregular_available_period_list,omitempty"` 453} 454 455type ExchangeCouponUsageRule struct { 456 Threshold *int64 `json:"threshold,omitempty"` 457 ExchangePrice *int64 `json:"exchange_price,omitempty"` 458} 459 460type CouponUsageMethod string 461 462func (e CouponUsageMethod) Ptr() *CouponUsageMethod { 463 return &e 464} 465 466const ( 467 COUPONUSAGEMETHOD_OFFLINE CouponUsageMethod = "OFFLINE" 468 COUPONUSAGEMETHOD_MINI_PROGRAM CouponUsageMethod = "MINI_PROGRAM" 469 COUPONUSAGEMETHOD_APP CouponUsageMethod = "APP" 470 COUPONUSAGEMETHOD_PAYMENT_CODE CouponUsageMethod = "PAYMENT_CODE" 471) 472 473type CouponAvailableStoreInfo struct { 474 Description *string `json:"description,omitempty"` 475 MiniProgramAppid *string `json:"mini_program_appid,omitempty"` 476 MiniProgramPath *string `json:"mini_program_path,omitempty"` 477} 478 479type CouponCodeDisplayMode string 480 481func (e CouponCodeDisplayMode) Ptr() *CouponCodeDisplayMode { 482 return &e 483} 484 485const ( 486 COUPONCODEDISPLAYMODE_INVISIBLE CouponCodeDisplayMode = "INVISIBLE" 487 COUPONCODEDISPLAYMODE_BARCODE CouponCodeDisplayMode = "BARCODE" 488 COUPONCODEDISPLAYMODE_QRCODE CouponCodeDisplayMode = "QRCODE" 489) 490 491type EntranceMiniProgram struct { 492 Appid *string `json:"appid,omitempty"` 493 Path *string `json:"path,omitempty"` 494 EntranceWording *string `json:"entrance_wording,omitempty"` 495 GuidanceWording *string `json:"guidance_wording,omitempty"` 496} 497 498type EntranceOfficialAccount struct { 499 Appid *string `json:"appid,omitempty"` 500} 501 502type EntranceFinder struct { 503 FinderId *string `json:"finder_id,omitempty"` 504 FinderVideoId *string `json:"finder_video_id,omitempty"` 505 FinderVideoCoverImageUrl *string `json:"finder_video_cover_image_url,omitempty"` 506} 507 508type ComboPackageChoice struct { 509 Name *string `json:"name,omitempty"` 510 Price *int64 `json:"price,omitempty"` 511 Count *int64 `json:"count,omitempty"` 512 ImageUrl *string `json:"image_url,omitempty"` 513 MiniProgramAppid *string `json:"mini_program_appid,omitempty"` 514 MiniProgramPath *string `json:"mini_program_path,omitempty"` 515} 516 517type FixedWeekPeriod struct { 518 DayList []WeekEnum `json:"day_list,omitempty"` 519 DayPeriodList []PeriodOfTheDay `json:"day_period_list,omitempty"` 520} 521 522type TimePeriod struct { 523 BeginTime *string `json:"begin_time,omitempty"` 524 EndTime *string `json:"end_time,omitempty"` 525} 526 527type WeekEnum string 528 529func (e WeekEnum) Ptr() *WeekEnum { 530 return &e 531} 532 533const ( 534 WEEKENUM_MONDAY WeekEnum = "MONDAY" 535 WEEKENUM_TUESDAY WeekEnum = "TUESDAY" 536 WEEKENUM_WEDNESDAY WeekEnum = "WEDNESDAY" 537 WEEKENUM_THURSDAY WeekEnum = "THURSDAY" 538 WEEKENUM_FRIDAY WeekEnum = "FRIDAY" 539 WEEKENUM_SATURDAY WeekEnum = "SATURDAY" 540 WEEKENUM_SUNDAY WeekEnum = "SUNDAY" 541) 542 543type PeriodOfTheDay struct { 544 BeginTime *int64 `json:"begin_time,omitempty"` 545 EndTime *int64 `json:"end_time,omitempty"` 546} 547
应答参数
200 OK
user_coupon_bundle_id 必填 string(40)
【用户券组ID】 用户券组的唯一标识,【向用户发放商品券批次组】时由微信支付生成
user_product_coupon_list 必填 array[object]
【用户商品券列表】 用户商品券列表
| 属性 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coupon_code 必填 string(40) 【用户商品券Code】 用户商品券的唯一标识 coupon_state 必填 string 【用户商品券状态】 可选取值
valid_begin_time 必填 string 【有效期开始时间】 用户商品券可用开始时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间) valid_end_time 必填 string 【有效期结束时间】 用户商品券可用结束时间。遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间) receive_time 必填 string 【领券时间】 用户领券时间。遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间) send_request_no 必填 string(128) 【发券请求单号】 发券时传入的请求流水号 send_channel 必填 string 【发券渠道】 描述用户商品券是经由什么渠道发送的 可选取值
confirm_request_no 选填 string 【确认请求单号】 品牌方确认发券请求时传入的的请求流水号。当且仅当 品牌方调用【确认发放用户商品券API】后提供。 confirm_time 选填 string 【确认发放时间】 品牌方确认发券时间,当且仅当 品牌方调用【确认发放用户商品券API】后提供。遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间) deactivate_request_no 选填 string(128) 【失效请求单号】 品牌方失效券请求时传入的的请求流水号。当且仅当 deactivate_time 选填 string 【失效时间】 失效时间,当且仅当 deactivate_reason 选填 string(150) 【失效原因】 失效券的原因,当且仅当 progressive_bundle_usage_detail 选填 object 【多次优惠使用详情】 当且仅当
user_product_coupon_bundle_info 必填 object 【用户券组信息】 当前用户券所属用户券组的信息
product_coupon 必填 object 【商品券信息】 该用户商品券对应的商品券详情
stock 必填 object 【批次信息】 该用户商品券发券时使用的批次详情
attach 选填 string 【自定义附加信息】 调用发券接口时品牌方使用 注: 发券渠道多样,只有品牌方通过发券接口发放的券才会在查询和回调中携带此字段,其他渠道发放的券 channel_custom_info 选填 string(1000) 【渠道自定义信息】 使用微信支付提供的其他渠道(比如「摇一摇有优惠」)发放商品券时,渠道可能会设置该渠道特定的自定义信息,请根据 coupon_tag_info 选填 object 【用户商品券标签信息】 用户商品券标签信息
|
应答示例
200 OK
1{ 2 "user_coupon_bundle_id" : "123446565767", 3 "user_product_coupon_list" : [ 4 { 5 "coupon_code" : "123446565767", 6 "coupon_state" : "USED", 7 "valid_begin_time" : "2025-01-01T00:00+08:00", 8 "valid_end_time" : "2025-01-30T23:59:59+08:00", 9 "receive_time" : "2025-01-01T09:10:00+08:00", 10 "send_request_no" : "MCHSEND202003101234", 11 "send_channel" : "BRAND_MANAGE", 12 "confirm_request_no" : "MCHCONFIRM202003101234", 13 "confirm_time" : "2025-01-20T13:29:35+08:00", 14 "deactivate_request_no" : "1002600620019090123143254436", 15 "deactivate_time" : "2025-01-20T13:29:35+08:00", 16 "deactivate_reason" : "商品已下线", 17 "progressive_bundle_usage_detail" : { 18 "use_request_no" : "MCHUSE202003101234", 19 "use_time" : "2025-07-20T13:29:35+08:00", 20 "return_request_no" : "MCHRETURN202003101234", 21 "return_time" : "2025-07-20T14:29:35+08:00", 22 "associated_order_info" : { 23 "transaction_id" : "4200000000123456789123456789", 24 "out_trade_no" : "trade_no_20250724123456", 25 "mchid" : "1234567890", 26 "sub_mchid" : "1234567890" 27 }, 28 "associated_pay_score_order_info" : { 29 "order_id" : "1000000000201908301055157220022", 30 "out_order_no" : "order_no_20250724123456", 31 "mchid" : "1234567890", 32 "sub_mchid" : "1234567890" 33 }, 34 "saved_amount" : 1 35 }, 36 "user_product_coupon_bundle_info" : { 37 "user_coupon_bundle_id" : "7014123823561283749832", 38 "user_coupon_bundle_index" : 0, 39 "total_count" : 10, 40 "used_count" : 3 41 }, 42 "product_coupon" : { 43 "product_coupon_id" : "1002323", 44 "scope" : "ALL", 45 "type" : "NORMAL", 46 "usage_mode" : "SINGLE", 47 "single_usage_info" : { 48 "normal_coupon" : { 49 "threshold" : 10000, 50 "discount_amount" : 100 51 }, 52 "discount_coupon" : { 53 "threshold" : 10000, 54 "percent_off" : 30 55 } 56 }, 57 "progressive_bundle_usage_info" : { 58 "count" : 10, 59 "interval_days" : 1 60 }, 61 "display_info" : { 62 "name" : "全场满100可减10元", 63 "image_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx", 64 "background_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx", 65 "detail_image_url_list" : [ 66 "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx" 67 ], 68 "original_price" : 10000, 69 "combo_package_list" : [ 70 { 71 "name" : "咖啡2选1", 72 "pick_count" : 3, 73 "choice_list" : [ 74 { 75 "name" : "美式", 76 "price" : 10000, 77 "count" : 2, 78 "image_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx", 79 "mini_program_appid" : "wx4fd12345678", 80 "mini_program_path" : "/pages/index/index" 81 } 82 ] 83 } 84 ] 85 }, 86 "out_product_no" : "Product_1234567890", 87 "state" : "AUDITING", 88 "deactivate_request_no" : "1002600620019090123143254436", 89 "deactivate_time" : "2025-06-20T13:29:35+08:00", 90 "deactivate_reason" : "商品已下架" 91 }, 92 "stock" : { 93 "product_coupon_id" : "200000001", 94 "stock_id" : "123456789", 95 "remark" : "满减券", 96 "coupon_code_mode" : "UPLOAD", 97 "coupon_code_count_info" : { 98 "total_count" : 10000, 99 "available_count" : 999 100 }, 101 "stock_send_rule" : { 102 "max_count" : 10000000, 103 "max_count_per_day" : 10000, 104 "max_count_per_user" : 1 105 }, 106 "progressive_bundle_usage_rule" : { 107 "coupon_available_period" : { 108 "available_begin_time" : "2025-01-01T00:00:00+08:00", 109 "available_end_time" : "2025-10-01T00:00:00+08:00", 110 "available_days" : 10, 111 "wait_days_after_receive" : 1, 112 "weekly_available_period" : { 113 "day_list" : [ 114 "MONDAY" 115 ], 116 "day_period_list" : [ 117 { 118 "begin_time" : 60, 119 "end_time" : 86399 120 } 121 ] 122 }, 123 "irregular_available_period_list" : [ 124 { 125 "begin_time" : "2025-01-01T00:00:00+08:00", 126 "end_time" : "2025-10-01T00:00:00+08:00" 127 } 128 ] 129 }, 130 "normal_coupon" : { 131 "threshold" : 10000, 132 "discount_amount" : 100 133 }, 134 "discount_coupon" : { 135 "threshold" : 10000, 136 "percent_off" : 30 137 }, 138 "exchange_coupon" : { 139 "threshold" : 10000, 140 "exchange_price" : 100 141 } 142 }, 143 "stock_bundle_info" : { 144 "stock_bundle_id" : "123456789", 145 "stock_bundle_index" : 0 146 }, 147 "usage_rule_display_info" : { 148 "coupon_usage_method_list" : [ 149 "MINI_PROGRAM" 150 ], 151 "mini_program_appid" : "wx1234567890", 152 "mini_program_path" : "/pages/index/product", 153 "app_path" : "https://www.example.com/jump-to-app", 154 "usage_description" : "全场可用", 155 "coupon_available_store_info" : { 156 "description" : "可在上海市区的所有门店使用,详细列表参考小程序内信息为准", 157 "mini_program_appid" : "wx1234567890", 158 "mini_program_path" : "/pages/index/store-list" 159 } 160 }, 161 "coupon_display_info" : { 162 "code_display_mode" : "QRCODE", 163 "background_color" : "Color010", 164 "entrance_mini_program" : { 165 "appid" : "wx1234567890", 166 "path" : "/pages/index/product", 167 "entrance_wording" : "欢迎选购", 168 "guidance_wording" : "获取更多优惠" 169 }, 170 "entrance_official_account" : { 171 "appid" : "wx1234567890" 172 }, 173 "entrance_finder" : { 174 "finder_id" : "gh_12345678", 175 "finder_video_id" : "UDFsdf24df34dD456Hdf34", 176 "finder_video_cover_image_url" : "https://wxpaylogo.qpic.cn/wxpaylogo/xxxxx/xxx" 177 } 178 }, 179 "notify_config" : { 180 "notify_appid" : "wx4fd12345678" 181 }, 182 "store_scope" : "SPECIFIC", 183 "sent_count_info" : { 184 "total_count" : 100, 185 "today_count" : 10 186 }, 187 "state" : "SENDING", 188 "deactivate_request_no" : "1002600620019090123143254436", 189 "deactivate_time" : "2025-01-01T00:00+08:00", 190 "deactivate_reason" : "批次信息有误,重新创建" 191 }, 192 "attach" : "example_attach", 193 "channel_custom_info" : "example_channel_custom_info", 194 "coupon_tag_info" : { 195 "coupon_tag_list" : [ 196 "MEMBER" 197 ], 198 "member_tag_info" : { 199 "member_card_id" : "MemberCardId_1234567890" 200 } 201 } 202 } 203 ] 204} 205
错误码
以下是本接口返回的错误码列表。详细错误码规则,请参考微信支付接口规则-错误码和错误提示


