商户进件
特约商户进件
基础支付
JSAPI支付
APP支付
H5支付
Native支付
小程序支付
合单支付
付款码支付
经营能力
支付即服务
点金计划
行业方案
平台收付通
智慧商圈
微信支付分停车服务
电子发票
营销工具
代金券
商家券
委托营销
支付有礼
小程序发券插件
H5发券
图片上传(营销专用)
现金红包
资金应用
分账
连锁品牌分账
风险合规
商户开户意愿确认
消费者投诉2.0
商户平台处置通知
其他能力
图片上传
视频上传
微信支付平台证书

商家券开发指引

1. 接口规则

为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则

2. 开发准备

2.1. 搭建和配置开发环境

为了帮助开发者调用开放接口,我们提供了JAVA、PHP、GO三种语言版本的开发库,封装了签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能(更多语言版本的开发库将在近期陆续提供

测试步骤

1、根据自身开发语言,选择对应的开发库并构建项目,具体配置请参考下面链接的详细说明:

    • wechatpay-java(推荐)wechatpay-apache-httpclient,适用于Java开发者。

    • wechatpay-php(推荐)、wechatpay-guzzle-middleware,适用于PHP开发者

    注:当前开发指引接口PHP示例代码采用wechatpay-guzzle-middleware版本

    • wechatpay-go,适用于Go开发者

更多资源可前往微信支付开发者社区搜索查看

2、创建加载商户私钥、加载平台证书、初始化httpClient的通用方法


@Before
public void setup() throws IOException {
    // 加载商户私钥(privateKey:私钥字符串)
    PrivateKey merchantPrivateKey = PemUtil
            .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
 
    // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
            new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
 
    // 初始化httpClient
    httpClient = WechatPayHttpClientBuilder.create()
            .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
            .withValidator(new WechatPay2Validator(verifier)).build();
}
 
@After
public void after() throws IOException {
    httpClient.close();
}

use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use GuzzleHttp\HandlerStack;
 
// 商户相关配置,
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('./path/to/mch/private/key.pem'); // 商户私钥文件路径
 
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('./path/to/wechatpay/cert.pem'); // 微信支付平台证书文件路径
 
// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
    ->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
    ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书,参数类型为array
    ->build();
 
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
 
// 创建Guzzle HTTP Client时,将HandlerStack传入,接下来,正常使用Guzzle发起API请求,WechatPayMiddleware会自动地处理签名和验签
$client = new GuzzleHttp\Client(['handler' => $stack]);

/*
    Package core 微信支付api v3 go http-client 基础库,你可以使用它来创建一个client,并向微信支付发送http请求
    只需要你在初始化客户端的时候,传递credential以及validator
    credential用来生成http header中的authorization信息
    validator则用来校验回包是否被篡改
    如果http请求返回的err为nil,一般response.Body 都不为空,你可以尝试对其进行序列化
    请注意及时关闭response.Body
    注意:使用微信支付apiv3 go库需要引入相关的包,该示例代码必须引入的包名有以下信息

    "context"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "log"
    "github.com/wechatpay-apiv3/wechatpay-go/core"
    "github.com/wechatpay-apiv3/wechatpay-go/core/option"
    "github.com/wechatpay-apiv3/wechatpay-go/utils"

    */
func SetUp() (opt []option.ClientOption, err error) {
    //商户号
    mchID := ""
    //商户证书序列号
    mchCertSerialNumber := ""
    //商户私钥文件路径
    privateKeyPath := ""
    //平台证书文件路径
    wechatCertificatePath := ""

    // 加载商户私钥
    privateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
    if err != nil {
        log.Printf("load private err:%s", err.Error())
        return nil, err
    }
    // 加载微信支付平台证书
    wechatPayCertificate, err := utils.LoadCertificateWithPath(wechatCertificatePath)
    if err != nil {
        log.Printf("load certificate err:%s",err)
        return nil, err
    }
    //设置header头中authorization信息
    opts := []option.ClientOption{
        option.WithMerchant(mchID, mchCertSerialNumber, privateKey), // 设置商户相关配置
        option.WithWechatPay([]*x509.Certificate{wechatPayCertificate}), // 设置微信支付平台证书,用于校验回包信息用
    }
    return opts, nil
}

3、基于接口的示例代码,替换请求参数后可发起测试

说明:

• 上面的开发库为微信支付官方开发库,其它没有审核或者控制下的第三方工具和库,微信支付不保证它们的安全性和可靠性

通过包管理工具引入SDK后,可根据下面每个接口的示例代码替换相关参数后进行快速测试

开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现,可阅读下面的详细说明:

    1.签名生成

    2.签名验证

    3.敏感信息加解密

    4.merchantPrivateKey(私钥)

    5.wechatpayCertificates(平台证书)

    6.APIV3Key(V3 key)

如想更详细的了解我们的接口规则,可查看我们的接口规则指引文档

2.2. 业务开发配置

2.2.1. 开通营销事件推送能力

• 开通营销事件推送能力说明

a. 用于设置接收商家券相关事件通知的URL,可接收商家券相关的事件通知、包括发放通知等。需要设置接收通知的URL,并在服务商平台开通营销事件推送的能力,即可接收到相关通知。

b. 营销事件推送:点击开通产品权限。 由商家券批次创建方登录Pay平台,操作开通

3. 快速接入

3.1. 业务流程图

业务流程时序图:


重点步骤说明:

步骤1 商户发起创建商家券请求,可通过《创建商家券》接口创建商家券,微信支付生成商家券批次后并返回商家券批次号给到商户。
请求参数商户logo(merchant_url)的内容要求使用图片上传(营销专用)接口上传后获取

步骤4.2 商户获取到商家券批次号,需要调用《小程序发券插件》来发放商户券,并获取微信支付返回商家券发放结果。

步骤7.2 商户发券成功后,商户可通过《查询商家券详情》、《根据过滤条件查询用户券》、《查询用户券详情》等商家券管理接口进行券管理,商户需核销用户券时,可通过调用《核销用户券》来核销用户微信卡包中具体某一张商家券。

3.2. API接入(含示例代码)

文档展示了如何使用微信支付服务端 SDK 快速接入商家券产品,完成与微信支付对接的部分。

注意

  • 文档中的代码示例是用来阐述 API 基本使用方法,代码中的示例参数需替换成商户自己账号及请求参数才能跑通
  • 以下接入步骤仅提供参考,请商户结合自身业务需求进行评估、修改。
3.2.1. 【服务端】创建商家券

步骤说明:通过此接口可为有需求的商户创建商家券。当前支持创建的商家券类型包含满减券、换购券和折扣券三种。

示例代码


public void CreateBusiStocks() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks");
    // 请求body参数
    String reqdata = "{"
                + "\"stock_name\":\"8月1日活动券\","
                + "\"belong_merchant\":\"1900008361\","
                + "\"comment\":\"活动使用\","
                + "\"goods_name\":\"填写代金券可适用的商品或服务\","
                + "\"stock_type\":\"NORMAL\","
                + "\"coupon_use_rule\": {"
                + "\"coupon_available_time\": {"
                + "\"available_begin_time\":\"2021-04-20T13:29:35+08:00\","
                + "\"available_end_time\":\"2021-04-25T13:29:35+08:00\","
                + "\"available_day_after_receive\":3,"
                + "\"wait_days_after_receive\":7"
                + "},"
                + "\"fixed_normal_coupon\": {"
                + "\"discount_amount\":5,"
                + "\"transaction_minimum\":100"
                + "},"
                + "\"use_method\":\"OFF_LINE\""
                + "},"
                + "\"stock_send_rule\": {"
                + "\"max_coupons\":100,"
                + "\"max_coupons_per_user\":5,"
                + "\"max_coupons_by_day\":100,"
                + "\"natural_person_limit\":false,"
                + "\"prevent_api_abuse\":false,"
                + "\"transferable\":false,"
                + "\"shareable\":false"
                + "},"
                + "\"out_request_no\":\"100002322019090134234sfdf\","
                + "\"coupon_code_mode\":\"WECHATPAY_MODE\""
                + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks', //请求URL
        [
            // JSON请求体
            'json' => [
                "stock_name" => "8月1日活动券",
                "belong_merchant" => "10000098",
                "comment" => "活动使用",
                "goods_name" => "填写代金券可适用的商品或服务",
                "stock_type" => "NORMAL",
                "coupon_use_rule" => [
                    "coupon_available_time" => [
                        "available_begin_time" => "2015-05-20T13:29:35+08:00",
                        "available_end_time" => "2015-05-20T13:29:35+08:00",
                        "available_day_after_receive" => 3,
                        "wait_days_after_receive" => 7,
                        "available_week" => [
                            "week_day" => [
                                "0" => 1,
                                "1" => 2,
                            ],
                            "available_day_time" => [
                                [
                                    "begin_time" => 3600,
                                    "end_time" => 86399,
                                ],
                            ],
                        ],
                        "irregulary_avaliable_time" => [
                            [
                                "begin_time" => "2015-05-20T13:29:35+08:00",
                                "end_time" => "2015-05-20T13:29:35+08:00",
                            ],
                        ],
                    ],
                    "fixed_normal_coupon" => [
                        "discount_amount" => 5,
                        "transaction_minimum" => 100,
                    ],
                    "use_method" => "OFF_LINE",
                    "mini_programs_appid" => "wx23232232323",
                    "mini_programs_path" => "/path/index/index",
                ],
                "stock_send_rule" => [
                    "max_coupons" => 100,
                    "max_coupons_per_user" => 5,
                    "max_coupons_by_day" => 100,
                    "natural_person_limit" => false,
                    "prevent_api_abuse" => false,
                    "transferable" => false,
                    "shareable" => false,
                ],
                "out_request_no" => "100002322019090134234sfdf",
                "custom_entrance" => [
                    "mini_programs_info" => [
                        "mini_programs_appid" => "wx234545656765876",
                        "mini_programs_path" => "/path/index/index",
                        "entrance_words" => "欢迎选购",
                        "guiding_words" => "获取更多优惠",
                    ],
                    "appid" => "wx324345hgfhfghfg",
                    "hall_id" => "233455656",
                    "store_id" => "233554655",
                ],
                "display_pattern_info" => [
                    "description" => "xxx门店可用",
                    "merchant_logo_url" => "https://xxx",
                    "merchant_name" => "微信支付",
                    "background_color" => "Color020",
                    "coupon_image_url" => "https://qpic.cn/xxx",
                ],
                "coupon_code_mode" => "WECHATPAY_MODE",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func CreateBusiStocks() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
 URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "stock_name": "8月1日活动券",
    "belong_merchant": "10000098",
    "comment": "活动使用",
    "goods_name": "填写代金券可适用的商品或服务",
    "stock_type": "NORMAL",
    "coupon_use_rule": map[string]interface{}{
      "coupon_available_time": map[string]interface{}{
        "available_begin_time": "2015-05-20T13:29:35+08:00",
        "available_end_time": "2015-05-20T13:29:35+08:00",
        "available_day_after_receive": 3,
        "wait_days_after_receive": 7,
     },
      "fixed_normal_coupon": map[string]interface{}{
        "discount_amount": 5,
        "transaction_minimum": 100,
     },
      "use_method": "OFF_LINE",
    },
    "stock_send_rule": map[string]interface{}{
      "max_coupons": 100,
      "max_coupons_per_user": 5,
      "max_coupons_by_day": 100,
      "natural_person_limit": false,
      "prevent_api_abuse": false,
      "transferable": false,
      "shareable": false,
    },
    "out_request_no": "100002322019090134234sfdf",
    "coupon_code_mode": "WECHATPAY_MODE",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

belong_merchant:批次归属商户号,批次归属于哪个商户。服务商模式填写为子商户号,间连模式填写为子商户号

out_request_no:商户请求单号,商户创建批次凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性。

max_coupons: 批次最大发放个数,批次最大可发放个数限制。特殊规则:取值范围 1 ≤ value ≤ 1000000000

notify_appid:事件通知appid,用于回调通知时,计算返回操作用户的openid(诸如领券用户),支持小程序or公众号的APPID;如该字段不填写,则回调通知中涉及到用户身份信息的openid与unionid都将为空。

注意

更多参数、响应详情及错误码请参见 创建商家券接口文档

3.2.2. 【服务端】查询商家券详情

步骤说明:商户可通过该接口查询已创建的商家券批次详情信息。

示例代码


public void GetBusiStocksInfo() throws Exception{
    //请求URL
    HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/1212");
    httpGet.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpGet);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/1212', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func GetBusiStocksInfo() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
   URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/1212"
  // 发起请求
  response, err := client.Get(ctx, URL)
  if err != nil{
    log.Printf("client get err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

注意

更多参数、响应详情及错误码请参见 查询商家券详情接口文档

3.2.3. 【服务端】核销用户券

步骤说明:在用户满足优惠门槛后,服务商可通过该接口核销用户微信卡包中具体某一张商家券。

示例代码


public void SetBusiStockUse() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/use");
    // 请求body参数
    String reqdata = "{"
            + "\"coupon_code\":\"sxxe34343434\","
            + "\"stock_id\":\"100088\","
            + "\"appid\":\"wx1234567889999\","
            + "\"use_time\":\"2015-05-20T13:29:35+08:00\","
            + "\"use_request_no\":\"1002600620019090123143254435\","
            + "\"openid\":\"xsd3434454567676\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/use', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code" => "sxxe34343434",
                "stock_id" => "100088",
                "appid" => "wx1234567889999",
                "use_time" => "2015-05-20T13:29:35+08:00",
                "use_request_no" => "1002600620019090123143254435",
                "openid" => "xsd3434454567676",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func SetBusiStockUse() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
    //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/use"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code": "sxxe34343434",
    "stock_id": "100088",
    "appid": "wx1234567889999",
    "use_time": "2015-05-20T13:29:35+08:00",
    "use_request_no": "1002600620019090123143254435",
    "openid": "xsd3434454567676",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

coupon_code:券code,券的唯一标识。

appid:公众账号ID,支持传入与当前调用接口商户号有绑定关系的appid。支持小程序appid与公众号appid。核销接口返回的openid会在该传入appid下进行计算获得。

use_request_no:核销请求单据号,每次核销请求的唯一标识,商户需保证唯一。

注意

更多参数、响应详情及错误码请参见 核销用户券接口文档

3.2.4. 【服务端】根据过滤条件查询用户券

步骤说明:商户自定义筛选条件(如创建商户号、归属商户号、发放商户号等),查询指定微信用户卡包中满足对应条件的所有商家券信息。

示例代码


public void FilterUserStocks() throws Exception{
    //请求URL
    HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/o4GgauInH_RCEdvrrNGrntXDu6D4/coupons?appid=wx233544546545989&stock_id=9865000&coupon_state=USED&creator_merchant=1000000001&offset=0&limit=20");
    httpGet.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpGet);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/o4GgauInH_RCEdvrrNGrntXDu6D4/coupons?appid=wx233544546545989&stock_id=9865000&coupon_state=USED&creator_merchant=1000000001&offset=0&limit=20', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func FilterUserStocks() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
   URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/2323dfsdf342342/coupons?appid=wx233544546545989&stock_id=9865000&coupon_state=USED&creator_merchant=1000000001&offset=0&limit=20"
  // 发起请求
  response, err := client.Get(ctx, URL)
  if err != nil{
    log.Printf("client get err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
}
    

重要入参说明

openid:用户标识,Openid信息,用户在appid下的唯一标识。

appid:公众账号ID,支持传入与当前调用接口商户号有绑定关系的appid。支持小程序appid与公众号appid。

注意

更多参数、响应详情及错误码请参见 根据过滤条件查询用户券接口文档

3.2.5. 【服务端】查询用户单张券详情

步骤说明:服务商可通过该接口查询微信用户卡包中某一张商家券的详情信息。

示例代码


public void FilterUserStocks() throws Exception{
    //请求URL
    HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/o4GgauInH_RCEdvrrNGrntXDu6D4/coupons/123446565767/appids/wx233544546545989");
    httpGet.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpGet);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/o4GgauInH_RCEdvrrNGrntXDu6D4/coupons/123446565767/appids/wx233544546545989', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func FilterUserStocks() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
   URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/users/2323dfsdf342342/coupons/123446565767/appids/wx233544546545989"
  // 发起请求
  response, err := client.Get(ctx, URL)
  if err != nil{
    log.Printf("client get err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
}
    

重要入参说明

coupon_code:券code,券的唯一标识。

openid:用户标识,Openid信息,用户在appid下的唯一标识。

appid:公众账号ID,支持传入与当前调用接口商户号有绑定关系的appid。支持小程序appid与公众号appid。

注意

更多参数、响应详情及错误码请参见 查询用户单张券详情接口文档

3.2.6. 【服务端】上传预存code

步骤说明:商家券的Code码可由微信后台随机分配,同时支持商户自定义。如商家已有自己的优惠券系统,可直接使用自定义模式。即商家预先向微信支付上传券Code,当券在发放时,微信支付自动从已导入的Code中随机取值(不能指定),派发给用户。

示例代码


public void UploadBusiStockCodes() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/98065001/couponcodes");
    // 请求body参数
    String reqdata = "{"
            + "\"coupon_code_list\": ["
            + "\"0\":\"ABC9588200\","
            + "\"1\":\"ABC9588201\""
            + "],"
            + "\"upload_request_no\":\"100002322019090134234sfdf\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/98065001/couponcodes', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code_list" => [
                    "0" => "ABC9588200",
                    "1" => "ABC9588201",
                ],
                "upload_request_no" => "100002322019090134234sfdf",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]

    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func UploadBusiStockCodes() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
 //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/{stock_id}/couponcodes"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code_list": []map[string]interface{}{
      "ABC9588200",
      "ABC9588201",
    },
    "upload_request_no": "100002322019090134234sfdf",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

upload_request_no:请求业务单据号,商户上传code的凭据号,商户侧需保持唯一性。

注意

更多参数、响应详情及错误码请参见 上传预存code接口文档

3.2.7. 【服务端】设置商家券事件通知地址

步骤说明:用于设置接收商家券相关事件通知的URL,可接收商家券相关的事件通知、包括发放通知等。需要设置接收通知的URL,并在服务商平台开通营销事件推送的能力,即可接收到相关通知。

示例代码


public void SetBusiStockCallback() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks");
    // 请求body参数
    String reqdata = "{"
            + "\"mchid\":\"10000098\","
            + "\"notify_url\":\"https://pay.weixin.qq.com\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks', //请求URL
        [
            // JSON请求体
            'json' => [
                "mchid" => "10000098",
                "notify_url" => "https://pay.weixin.qq.com",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func SetBusiStockCallback() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "mchid": "10000098",
    "notify_url": "https://pay.weixin.qq.com",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

notify_url:通知URL地址,商户提供的用于接收商家券事件通知的url地址,必须支持https。

注意

更多参数、响应详情及错误码请参见 设置商家券事件通知地址接口文档

3.2.8. 【服务端】查询商家券事件通知地址

步骤说明:通过调用此接口可查询设置的通知URL。

示例代码


public void QueryBusiStockCallback() throws Exception {

  //请求URL
  HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks?mchid=10000098");
  httpGet.setHeader("Accept", "application/json");

  //完成签名并执行请求
  CloseableHttpResponse response = httpClient.execute(httpGet);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //处理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //处理成功,无返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}

try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks?mchid=10000098', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func QueryBusiStockCallback() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
   URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/callbacks?mchid=10000098"
  // 发起请求
  response, err := client.Get(ctx, URL)
  if err != nil{
    log.Printf("client get err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

mchid:商户号,微信支付商户的商户号,由微信支付生成并下发,不填默认查询调用方商户的通知URL。

注意

更多参数、响应详情及错误码请参见 查询商家券事件通知地址接口文档

3.2.9. 【服务端】关联订单信息

步骤说明:将有效态(未核销)的商家券与订单信息关联,用于后续参与摇奖&返佣激励等操作的统计。

示例代码


public void AssociateBusiStockOrder() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/associate");
    // 请求body参数
    String reqdata = "{"
            + "\"coupon_code\":\"sxxe34343434\","
            + "\"out_trade_no\":\"MCH_102233445\","
            + "\"stock_id\":\"100088\","
            + "\"out_request_no\":\"1002600620019090123143254435\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/associate', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code" => "sxxe34343434",
                "out_trade_no" => "MCH_102233445",
                "stock_id" => "100088",
                "out_request_no" => "1002600620019090123143254435",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func AssociateBusiStockOrder() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/associate"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code": "sxxe34343434",
    "out_trade_no": "MCH_102233445",
    "stock_id": "100088",
    "out_request_no": "1002600620019090123143254435",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

out_trade_no:关联的商户订单号,微信支付下单时的商户订单号,预与该商家券关联的微信支付

out_request_no:商户请求单号,商户创建批次凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性,可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。

注意

更多参数、响应详情及错误码请参见 关联订单信息接口文档

3.2.10. 【服务端】取消关联订单信息

步骤说明:取消商家券与订单信息的关联关系

示例代码


public void CancelAssociateBusiStockOrder() throws Exception {
//请求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/disassociate");
  // 请求body参数
  String reqdata = "{"
          + "\"coupon_code\":\"213dsadfsa\","
          + "\"out_trade_no\":\"treads8a9f980\","
          + "\"stock_id\":\"100088\","
          + "\"out_request_no\":\"fdsafdsafdsa231321\""
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");

  //完成签名并执行请求
  CloseableHttpResponse response = httpClient.execute(httpPost);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //处理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //处理成功,无返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/disassociate', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code" => "213dsadfsa",
                "out_trade_no" => "treads8a9f980",
                "stock_id" => "100088",
                "out_request_no" => "fdsafdsafdsa231321",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func CancelAssociateBusiStockOrder() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/disassociate"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code": "213dsadfsa",
    "out_trade_no": "treads8a9f980",
    "stock_id": "100088",
    "out_request_no": "fdsafdsafdsa231321",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

out_trade_no:关联的商户订单号,微信支付下单时的商户订单号,预与该商家券关联的微信支付

out_request_no:商户请求单号,商户创建批次凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性,可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。

注意

更多参数、响应详情及错误码请参见 取消关联订单信息接口文档

3.2.11. 【服务端】修改批次预算

步骤说明:商户可以通过该接口修改批次单天发放上限数量或者批次最大发放数量

示例代码


public void UpdataBusiStockBudget() throws Exception{
    //请求URL
    HttpPatch httpPatch = new HttpPatch("https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/98065001/budget");
    // 请求body参数
    String reqdata = "{"
            + "\"target_max_coupons\":3000,"
            + "\"current_max_coupons\":500,"
            + "\"modify_budget_request_no\":\"1002600620019090123143254436\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPatch.setEntity(entity);
    httpPatch.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPatch);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'PATCH',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/98065001/budget', //请求URL
        [
            // JSON请求体
            'json' => [
                "target_max_coupons" => 3000,
                "current_max_coupons" => 500,
                "modify_budget_request_no" => "1002600620019090123143254436",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func UpdataBusiStockBudget() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

modify_budget_request_no:修改预算请求单据号(格式:商户id+日期+流水号),商户侧需保持唯一性。

注意

更多参数、响应详情及错误码请参见 修改批次预算接口文档

3.2.12. 【服务端】修改商家券基本信息

步骤说明:商户可以通过该接口修改商家券基本信息

示例代码


public void UpdataBusiStockInfo() throws Exception{
    //请求URL
    HttpPatch httpPatch = new HttpPatch("https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/101156451224");
    // 请求body参数
    String reqdata = "{"
            + "\"custom_entrance\": {"
            + "\"mini_programs_info\": {"
            + "\"mini_programs_appid\":\"wx234545656765876\","
            + "\"mini_programs_path\":\"/path/index/index\","
            + "\"entrance_words\":\"欢迎选购\","
            + "\"guiding_words\":\"获取更多优惠\""
            + "},"
            + "\"appid\":\"wx324345hgfhfghfg\","
            + "\"hall_id\":\"233455656\","
            + "\"code_display_mode\":\"BARCODE\""
            + "},"
            + "\"stock_name\":\"8月1日活动券\","
            + "\"comment\":\"活动使用\","
            + "\"goods_name\":\"xxx商品使用\","
            + "\"out_request_no\":\"6122352020010133287985742\","
            + "\"display_pattern_info\": {"
            + "\"description\":\"xxx门店可用\","
            + "\"merchant_logo_url\":\"https://xxx\","
            + "\"merchant_name\":\"微信支付\","
            + "\"background_color\":\"xxxxx\","
            + "\"coupon_image_url\":\"图片cdn地址\""
            + "},"
            + "\"coupon_use_rule\": {"
            + "\"use_method\":\"OFF_LINE\","
            + "\"mini_programs_appid\":\"wx23232232323\","
            + "\"mini_programs_path\":\"/path/index/index\""
            + "},"
            + "\"stock_send_rule\": {"
            + "\"prevent_api_abuse\":false"
            + "},"
            + "\"notify_config\": {"
            + "\"notify_appid\":\"wx23232232323\""
            + "}"
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPatch.setEntity(entity);
    httpPatch.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPatch);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'PATCH',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/stocks/101156451224', //请求URL
        [
            // JSON请求体
            'json' => [
                "custom_entrance" => [
                    "mini_programs_info" => [
                        "mini_programs_appid" => "wx234545656765876",
                        "mini_programs_path" => "/path/index/index",
                        "entrance_words" => "欢迎选购",
                        "guiding_words" => "获取更多优惠",
                    ],
                    "appid" => "wx324345hgfhfghfg",
                    "hall_id" => "233455656",
                    "code_display_mode" => "BARCODE",
                ],
                "stock_name" => "8月1日活动券",
                "comment" => "活动使用",
                "goods_name" => "xxx商品使用",
                "out_request_no" => "6122352020010133287985742",
                "display_pattern_info" => [
                    "description" => "xxx门店可用",
                    "merchant_logo_url" => "https://xxx",
                    "merchant_name" => "微信支付",
                    "background_color" => "xxxxx",
                    "coupon_image_url" => "图片cdn地址",
                ],
                "coupon_use_rule" => [
                    "use_method" => "OFF_LINE",
                    "mini_programs_appid" => "wx23232232323",
                    "mini_programs_path" => "/path/index/index",
                ],
                "stock_send_rule" => [
                    "prevent_api_abuse" => false,
                ],
                "notify_config" => [
                    "notify_appid" => "wx23232232323",
                ]
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func UpdataBusiStockInfo() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

out_request_no:商户请求单号,商户修改批次凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性。

注意

更多参数、响应详情及错误码请参见 修改商家券基本信息接口文档

3.2.13. 【服务端】申请退券

步骤说明:商户可以通过该接口为已核销的券申请退券

示例代码


public void ReturnBusiStock() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/return");
    // 请求body参数
    String reqdata = "{"
            + "\"coupon_code\":\"sxxe34343434\","
            + "\"stock_id\":\"1234567891\","
            + "\"return_request_no\":\"1002600620019090123143254436\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/return', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code" => "sxxe34343434",
                "stock_id" => "1234567891",
                "return_request_no" => "1002600620019090123143254436",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func ReturnBusiStock() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/return"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code": "sxxe34343434",
    "stock_id": "1234567891",
    "return_request_no": "1002600620019090123143254436",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

return_request_no:退券请求单据号,每次退券请求的唯一标识,商户需保证唯一

注意

更多参数、响应详情及错误码请参见 申请退券接口文档

3.2.14. 【服务端】使券失效

步骤说明:商户可通过该接口将单张领取后未核销的券进行失效处理

示例代码


public void DeactivateBusiStock() throws Exception{
    //请求URL
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/deactivate");
    // 请求body参数
    String reqdata = "{"
            + "\"coupon_code\":\"sxxe34343434\","
            + "\"stock_id\":\"1234567891\","
            + "\"deactivate_request_no\":\"1002600620019090123143254436\","
            + "\"deactivate_reason\":\"此券使用时间设置错误\""
            + "}";
    StringEntity entity = new StringEntity(reqdata,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");

    //完成签名并执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost);

    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
        } else if (statusCode == 204) { //处理成功,无返回Body
            System.out.println("success");
        } else {
            System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
            throw new IOException("request failed");
        }
    } finally {
        response.close();
    }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/deactivate', //请求URL
        [
            // JSON请求体
            'json' => [
                "coupon_code" => "sxxe34343434",
                "stock_id" => "1234567891",
                "deactivate_request_no" => "1002600620019090123143254436",
                "deactivate_reason" => "此券使用时间设置错误",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func DeactivateBusiStock() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
  //设置请求地址
  URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/coupons/deactivate"
  //设置请求信息,此处也可以使用结构体来进行请求
  mapInfo := map[string]interface{}{
    "coupon_code": "sxxe34343434",
    "stock_id": "1234567891",
    "deactivate_request_no": "1002600620019090123143254436",
    "deactivate_reason": "此券使用时间设置错误",
  }

  // 发起请求
  response, err := client.Post(ctx, URL, mapInfo)
  if err != nil{
    log.Printf("client post err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}   

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

deactivate_request_no:失效请求单据号,每次失效请求的唯一标识,商户需保证唯一

注意

更多参数、响应详情及错误码请参见 使券失效接口文档

3.2.15. 【服务端】营销补差付款

步骤说明:商户可以通过该接口给核销了商家券的商户做营销资金补差

示例代码


public void CreateSubsidyPay() throws Exception {

  //请求URL
  HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/busifavor/subsidy/pay-receipts");
  // 请求body参数
  String reqdata = "{"
          + "\"stock_id\":\"128888000000001\","
          + "\"coupon_code\":\"ABCD12345678\","
          + "\"transaction_id\":\"4200000913202101152566792388\","
          + "\"payer_merchant\":\"1900000001\","
          + "\"payee_merchant\":\"1900000002\","
          + "\"amount\":100,"
          + "\"description\":\"20210115DESCRIPTION\","
          + "\"out_subsidy_no\":\"subsidy-abcd-12345678\""
          + "}";
  StringEntity entity = new StringEntity(reqdata,"utf-8");
  entity.setContentType("application/json");
  httpPost.setEntity(entity);
  httpPost.setHeader("Accept", "application/json");

  //完成签名并执行请求
  CloseableHttpResponse response = httpClient.execute(httpPost);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //处理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //处理成功,无返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}

try {
    $resp = $client->request(
        'POST',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/subsidy/pay-receipts', //请求URL
        [
            // JSON请求体
            'json' => [
                "stock_id" => "128888000000001",
                "coupon_code" => "ABCD12345678",
                "transaction_id" => "4200000913202101152566792388",
                "payer_merchant" => "1900000001",
                "payee_merchant" => "1900000002",
                "amount" => 100,
                "description" => "20210115DESCRIPTION",
                "out_subsidy_no" => "subsidy-abcd-12345678",
            ],
            'headers' => [ 'Accept' => 'application/json' ]
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func CreateSubsidyPay() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

deactivate_request_no:失效请求单据号,每次失效请求的唯一标识,商户需保证唯一

注意

更多参数、响应详情及错误码请参见 营销补差付款接口文档

3.2.16. 【服务端】查询营销补差付款单详情

步骤说明:商户可以通过该接口查询商家券营销补差付款单详情

示例代码


public void QuerySubsidyPay() throws Exception {

  //请求URL
  HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/busifavor/subsidy/pay-receipts/1120200119165100000000000001");
  httpGet.setHeader("Accept", "application/json");

  //完成签名并执行请求
  CloseableHttpResponse response = httpClient.execute(httpGet);

  try {
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) { //处理成功
          System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
      } else if (statusCode == 204) { //处理成功,无返回Body
          System.out.println("success");
      } else {
          System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
          throw new IOException("request failed");
      }
  } finally {
      response.close();
  }
}


try {
    $resp = $client->request(
        'GET',
        'https://api.mch.weixin.qq.com/v3/marketing/busifavor/subsidy/pay-receipts/1120200119165100000000000001', //请求URL
        [
            'headers' => [ 'Accept' => 'application/json']
        ]
    );
    $statusCode = $resp->getStatusCode();
    if ($statusCode == 200) { //处理成功
        echo "success,return body = " . $resp->getBody()->getContents()."\n";
    } else if ($statusCode == 204) { //处理成功,无返回Body
        echo "success";
    }
} catch (RequestException $e) {
    // 进行错误处理
    echo $e->getMessage()."\n";
    if ($e->hasResponse()) {
        echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
    }
    return;
}
      

func QuerySubsidyPay() {
       // 初始化客户端
    ctx := context.TODO()
    opts, err := SetUp()
    if err != nil {
        return
    }
    client, err := core.NewClient(ctx, opts...,)
    if err != nil{
        log.Printf("init client err:%s",err)
        return
    }
   //设置请求地址
   URL := "https://api.mch.weixin.qq.com/v3/marketing/busifavor/subsidy/pay-receipts/1120200119165100000000000001"
  // 发起请求
  response, err := client.Get(ctx, URL)
  if err != nil{
    log.Printf("client get err:%s",err)
    return
  }
  // 校验回包内容是否有逻辑错误
  err = core.CheckResponse(response)
  if err != nil{
    log.Printf("check response err:%s",err)
    return
  }
  // 读取回包信息
  body, err := ioutil.ReadAll(response.Body)
  if err != nil{
    log.Printf("read response body err:%s",err)
    return
  }
  fmt.Println(string(body))
}
    

重要入参说明

stock_id:批次号,微信为每个商家券批次分配的唯一ID

coupon_code:券code,券的唯一标识。

deactivate_request_no:失效请求单据号,每次失效请求的唯一标识,商户需保证唯一

注意

更多参数、响应详情及错误码请参见 查询营销补差付款单详情接口文档

3.2.17.【服务端】领券事件回调通知

步骤说明:领券完成后,微信会把相关领券结果和用户信息发送给商户,商户需要接收处理,并按照文档规范返回应答。出于安全的考虑,我们对支付结果数据进行了加密,商户需要先对通知数据进行解密,才能得到支付结果数据。

注意

  • 领券事件通知是以POST 方法访问商户设置的通知url,通知的数据以JSON 格式通过请求主体(BODY)传输。通知的数据包括了加密的支付结果详情
  • 加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名,并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名,以确认请求来自微信,而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》
  • 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx
  • 商户成功接收到回调通知后应返回成功的http应答码为200或204
  • 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
  • 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。(通知频率为60s/次 - 总计11次 )

更多参数、响应详情及错误码请参见 领券事件回调通知支付通知API接口文档

4. 常见问题

Q:调用创建商家券接口返回“非法敏感图片”

A:请求参数商户logo(merchant_url)的内容要求使用图片上传(营销专用)接口上传后获取,请检查确认。

Q:创建商家券接口,goods_name字段展示在哪里?

A:展示在商家券详情里面的优惠说明中

Q:调用修改商家券基本信息API返回:无法将输入源“/body/stock_id”映射到目标字段“批次号”中,此字段并非多重字段但被输入源“/uri_template/stock_id”映射过了

A:请注意参数stock_id传到请求url里面,body里面就不用传该参数

Q:商家券领券回调,正常设置地址,为什么接收不到回调信息?

A:请按以下几点检查

1. 请检查是否有正确设置apiv3。设置步骤如下: 【微信服务商平台—>账户设置—>API安全—>设置apiv3】

2. 请检查回调url是否能正常公网访问

3. 如果是http地址,建议更换支持https

4. 是否开启了防火墙,如果开户了防火墙,请添加微信支付营销回调IP:

  • 上海电信出口网段 101.226.103.0/2
  • 上海联通出口网段 140.207.54.0/25
  • 上海CAP出口网段 121.51.58.128/25
Q:商家券消费门槛字段transaction_minimum不填写为什么会报错?

A:该字段属于必填字段,可以填写为0



技术咨询

文档反馈