为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,我们推出了全新的微信支付APIv3接口。该版本API的具体规则请参考“APIv3接口规则”
备注:当前接口用于微信国内钱包
为了帮助开发者调用开放接口,我们提供了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();
}
3、基于接口的示例代码,替换请求参数后可发起测试
说明:
• 上面的开发库为微信支付官方开发库,其它没有审核或者控制下的第三方工具和库,微信支付不保证它们的安全性和可靠性
通过包管理工具引入SDK后,可根据下面每个接口的示例代码替换相关参数后进行快速测试
• 开发者如果想详细了解签名生成、签名验证、敏感信息加/解密、媒体文件上传等常用方法的具体代码实现,可阅读下面的详细说明:
1.签名生成
2.签名验证
3.敏感信息加解密
• 如想更详细的了解我们的接口规则,可查看我们的接口规则指引文档
重点步骤说明:
步骤5 商户创建商家券后,可通过《创建全场满额送活动》接口创建支付有礼活动,微信支付生成支付有礼活动并返回活动ID给到商户。
步骤20 支付有礼活动创建后,商户可通过《查询活动详情接口》查询管理活动。
步骤22 活动创建后,如需结束活动,可通过《终止活动》接口,结束活动。
文档展示了如何使用微信支付服务端 SDK 快速接入支付有礼,完成与微信支付对接的部分。
注意:
步骤说明:商户可以创建满额送活动,用户支付后送全场券,提升交易额。
示例代码:
public void CreateActivity() throws Exception{
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/unique-threshold-activity");
// 请求body参数
String reqdata = "{"
+ "\"activity_base_info\": {"
+ "\"activity_name\":\"良品铺子回馈活动\","
+ "\"activity_second_title\":\"海飞丝的券\","
+ "\"merchant_logo_url\":\"https://tool.oschina.net/regex.jpg\","
+ "\"background_color\":\"COLOR010\","
+ "\"begin_time\":\"2015-05-20T13:29:35+08:00\","
+ "\"end_time\":\"2015-05-20T13:29:35+08:00\","
+ "\"available_periods\": {"
+ "\"available_time\": ["
+ "{"
+ "\"begin_time\":\"2015-05-20T00:00:00+08:00\","
+ "\"end_time\":\"2015-05-20T23:59:59+08:00\""
+ "}"
+ "],"
+ "\"available_day_time\": ["
+ "{"
+ "\"begin_day_time\":\"110000\","
+ "\"end_day_time\":\"135959\""
+ "}"
+ "]"
+ "},"
+ "\"out_request_no\":\"100002322019090134234sfdf\","
+ "\"delivery_purpose\":\"OFF_LINE_PAY\","
+ "\"mini_programs_appid\":\"wx23232232323\","
+ "\"mini_programs_path\":\"/path/index/index\""
+ "},"
+ "\"award_send_rule\": {"
+ "\"transaction_amount_minimum\":100,"
+ "\"send_content\":\"SINGLE_COUPON\","
+ "\"award_type\":\"BUSIFAVOR\","
+ "\"award_list\": ["
+ "{"
+ "\"stock_id\":\"98065001\","
+ "\"original_image_url\":\"https://tool.oschina.net/regex.jpg\","
+ "\"thumbnail_url\":\"https://tool.oschina.net/regex.jpg\""
+ "}"
+ "],"
+ "\"merchant_option\":\"MANUAL_INPUT_MERCHANT\","
+ "\"merchant_id_list\": ["
+ "\"0\":\"10000022\","
+ "\"1\":\"10000023\""
+ "]"
+ "},"
+ "\"advanced_setting\": {"
+ "\"delivery_user_category\":\"DELIVERY_MEMBER_PERSON\","
+ "\"merchant_member_appid\":\"34567890\","
+ "\"goods_tags\": ["
+ "\"0\":\"xxx\","
+ "\"1\":\"yyy\""
+ "]"
+ "}"
+ "}";
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();
}
}
重要入参说明:
• activity_name:活动名称
• activity_second_title:活动副标题
• merchant_logo_url:商户logo,送出优惠券时展示, 仅支持通过《图片上传API》接口获取的图片URL地址。
• out_request_no:商户请求单号,商户创建批次凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性,可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。
• delivery_purpose:投放目的。枚举值:
OFF_LINE_PAY:拉用户回店消费
JUMP_MINI_APP:引导用户前往小程序消费
• send_content:发放内容,可选单张券或礼包,选礼包时奖品限定3-5个。枚举值:
SINGLE_COUPON:单张券
GIFT_PACKAGE:礼包
注意:
更多参数、响应详情及错误码请参见创建全场满额送活动接口文档
步骤说明:商户创建活动后,可以通过该接口查询支付有礼的活动详情,用于管理活动。
示例代码:
public void QueryActivity() throws Exception{
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001");
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();
}
}
重要入参说明:
步骤说明:商户创建活动后,可以通过该接口查询支付有礼的发券商户号,用于管理活动。
示例代码:
public void QueryActivityMch() throws Exception{
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/merchants");
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();
}
}
重要入参说明:
步骤说明:商户创建活动后,可以通过该接口查询支付有礼的活动指定商品,用于管理活动。
示例代码:
public void QueryActivityGoods() throws Exception{
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/goods");
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();
}
}
重要入参说明:
步骤说明:商户可通过该接口停止支付有礼活动。
示例代码:
public void TerminateActivity() throws Exception{
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/terminate");
// 请求body参数
String reqdata ="";
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();
}
}
重要入参说明:
步骤说明:商户创建活动后,可以通过该接口增加支付有礼的发券商户号,用于管理活动。
示例代码:
public void GetActivityList() throws Exception{
// 加载商户私钥(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"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/merchants/add");
// 请求body参数
String reqdata = "{"
+ "\"merchant_id_list\": ["
+ "\"100123456\","
+ "\"100123457\""
+ "],"
+ "\"add_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();
}
}
重要入参说明:
• activity_id:活动id
• add_request_no:请求业务单据号,商户添加发券商户号的凭据号,商户侧需保持唯一性
注意:
更多参数、响应详情及错误码请参见新增活动发券商户号接口文档
步骤说明:商户根据一定过滤条件,查询已创建的支付有礼活动。
示例代码:
public void GetActivityList() throws Exception{
// 加载商户私钥(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"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities?offset=0&limit=10&activity_status=ONGOING_ACT_STATUS");
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();
}
}
重要入参说明:
步骤说明:商户创建活动后,可以通过该接口删除支付有礼的发券商户号,用于管理活动。
示例代码:
public void DelActivityMch() throws Exception{
// 加载商户私钥(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"));
CloseableHttpClient httpClient = HttpClients.createDefault();
// 初始化httpClient
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNo, merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier)).build();
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/126002309/merchants/delete");
// 请求body参数
String reqdata = "{"
+ "\"merchant_id_list\": ["
+ "\"100123456\","
+ "\"100123457\""
+ "],"
+ "\"delete_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();
}
}
重要入参说明:
A1:支付有礼活动的曝光商户号必须是商家券归属商户号的同品牌。同品牌商户号是指同一企业/集团/品牌/公司旗下,如果存在多个微信支付商户号,该企业/集团/品牌/公司可以授权财付通支付科技有限公司将其旗下的多个商户号创建为同品牌商户号组合。主要用于更便利使用免充值营销产品功能,包括开通产品权限、配置组合内商户号为可用商户、配置活动后可用商户免审核等
A2:支付有礼中投放批次的校验,请按照以下几点排查
1. 单张券/券包中所有的券开始时间需早于支付有礼活动的开始时间,结束时间需晚于支付有礼的结束时间
2. 如果批次为上传code模式,需先上传code再投放到支付有礼
3. 添加券包时,库存、限领和归属商户号需要保持一致
4. 曝光商户号、批次的归属商户号需要全部为同品牌
A3:间隔需要小于31536000s,即需要小于365天
A4:查询活动发券商户号API才会有这个字段返回,接口文档地址
A5:请检查对应的批次,调用创建商家券接口时是否有设置事件通知APPID参数(notify_appid)