為了在保證支付安全的前提下,帶給商戶簡(jiǎn)單、一致且易用的開發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請(qǐng)參考“APIv3接口規(guī)則”
備注:當(dāng)前接口用于微信國(guó)內(nèi)錢包
為了幫助開發(fā)者調(diào)用開放接口,我們提供了JAVA、PHP、GO三種語(yǔ)言版本的開發(fā)庫(kù),封裝了簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等基礎(chǔ)功能(更多語(yǔ)言版本的開發(fā)庫(kù)將在近期陸續(xù)提供)
測(cè)試步驟:
1、根據(jù)自身開發(fā)語(yǔ)言,選擇對(duì)應(yīng)的開發(fā)庫(kù)并構(gòu)建項(xiàng)目,具體配置請(qǐng)參考下面鏈接的詳細(xì)說(shuō)明:
? wechatpay-java(推薦)wechatpay-apache-httpclient,適用于Java開發(fā)者。
? wechatpay-php(推薦)、wechatpay-guzzle-middleware,適用于PHP開發(fā)者
注:當(dāng)前開發(fā)指引接口PHP示例代碼采用wechatpay-guzzle-middleware版本
? wechatpay-go,適用于Go開發(fā)者
更多資源可前往微信支付開發(fā)者社區(qū)搜索查看
2、創(chuàng)建加載商戶私鑰、加載平臺(tái)證書、初始化httpClient的通用方法
@Before
public void setup() throws IOException {
// 加載商戶私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(mchId:商戶號(hào),mchSerialNo:商戶證書序列號(hào),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、基于接口的示例代碼,替換請(qǐng)求參數(shù)后可發(fā)起測(cè)試
說(shuō)明:
? 上面的開發(fā)庫(kù)為微信支付官方開發(fā)庫(kù),其它沒(méi)有審核或者控制下的第三方工具和庫(kù),微信支付不保證它們的安全性和可靠性
通過(guò)包管理工具引入SDK后,可根據(jù)下面每個(gè)接口的示例代碼替換相關(guān)參數(shù)后進(jìn)行快速測(cè)試
? 開發(fā)者如果想詳細(xì)了解簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等常用方法的具體代碼實(shí)現(xiàn),可閱讀下面的詳細(xì)說(shuō)明:
1.簽名生成
3.敏感信息加解密
5.wechatpayCertificates(平臺(tái)證書)
? 如想更詳細(xì)的了解我們的接口規(guī)則,可查看我們的接口規(guī)則指引文檔
重點(diǎn)步驟說(shuō)明:
步驟5 商戶創(chuàng)建商家券后,可通過(guò)《創(chuàng)建全場(chǎng)滿額送活動(dòng)》接口創(chuàng)建支付有禮活動(dòng),微信支付生成支付有禮活動(dòng)并返回活動(dòng)ID給到商戶。
步驟20 支付有禮活動(dòng)創(chuàng)建后,商戶可通過(guò)《查詢活動(dòng)詳情接口》查詢管理活動(dòng)。
步驟22 活動(dòng)創(chuàng)建后,如需結(jié)束活動(dòng),可通過(guò)《終止活動(dòng)》接口,結(jié)束活動(dòng)。
文檔展示了如何使用微信支付服務(wù)端 SDK 快速接入支付有禮,完成與微信支付對(duì)接的部分。
注意:
步驟說(shuō)明:商戶可以創(chuàng)建滿額送活動(dòng),用戶支付后送全場(chǎng)券,提升交易額。
示例代碼:
public void CreateActivity() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/unique-threshold-activity");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
+ "\"activity_base_info\": {"
+ "\"activity_name\":\"良品鋪?zhàn)踊仞伝顒?dòng)\","
+ "\"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");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
? activity_name:活動(dòng)名稱
? activity_second_title:活動(dòng)副標(biāo)題
? merchant_logo_url:商戶logo,送出優(yōu)惠券時(shí)展示, 僅支持通過(guò)《圖片上傳API》接口獲取的圖片URL地址。
? out_request_no:商戶請(qǐng)求單號(hào),商戶創(chuàng)建批次憑據(jù)號(hào)(格式:商戶id+日期+流水號(hào)),商戶側(cè)需保持唯一性,可包含英文字母,數(shù)字,|,_,*,-等內(nèi)容,不允許出現(xiàn)其他不合法符號(hào)。
? delivery_purpose:投放目的。枚舉值:
OFF_LINE_PAY:拉用戶回店消費(fèi)
JUMP_MINI_APP:引導(dǎo)用戶前往小程序消費(fèi)
? send_content:發(fā)放內(nèi)容,可選單張券或禮包,選禮包時(shí)獎(jiǎng)品限定3-5個(gè)。枚舉值:
SINGLE_COUPON:?jiǎn)螐埲?br> GIFT_PACKAGE:禮包
注意:
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見創(chuàng)建全場(chǎng)滿額送活動(dòng)接口文檔
步驟說(shuō)明:商戶創(chuàng)建活動(dòng)后,可以通過(guò)該接口查詢支付有禮的活動(dòng)詳情,用于管理活動(dòng)。
示例代碼:
public void QueryActivity() throws Exception{
//請(qǐng)求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001");
httpGet.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
步驟說(shuō)明:商戶創(chuàng)建活動(dòng)后,可以通過(guò)該接口查詢支付有禮的發(fā)券商戶號(hào),用于管理活動(dòng)。
示例代碼:
public void QueryActivityMch() throws Exception{
//請(qǐng)求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/merchants");
httpGet.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
步驟說(shuō)明:商戶創(chuàng)建活動(dòng)后,可以通過(guò)該接口查詢支付有禮的活動(dòng)指定商品,用于管理活動(dòng)。
示例代碼:
public void QueryActivityGoods() throws Exception{
//請(qǐng)求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/goods");
httpGet.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
步驟說(shuō)明:商戶可通過(guò)該接口停止支付有禮活動(dòng)。
示例代碼:
public void TerminateActivity() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/terminate");
// 請(qǐng)求body參數(shù)
String reqdata ="";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
步驟說(shuō)明:商戶創(chuàng)建活動(dòng)后,可以通過(guò)該接口增加支付有禮的發(fā)券商戶號(hào),用于管理活動(dòng)。
示例代碼:
public void GetActivityList() throws Exception{
// 加載商戶私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(mchId:商戶號(hào),mchSerialNo:商戶證書序列號(hào),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();
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/10028001/merchants/add");
// 請(qǐng)求body參數(shù)
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");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
? activity_id:活動(dòng)id
? add_request_no:請(qǐng)求業(yè)務(wù)單據(jù)號(hào),商戶添加發(fā)券商戶號(hào)的憑據(jù)號(hào),商戶側(cè)需保持唯一性
注意:
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見新增活動(dòng)發(fā)券商戶號(hào)接口文檔
步驟說(shuō)明:商戶根據(jù)一定過(guò)濾條件,查詢已創(chuàng)建的支付有禮活動(dòng)。
示例代碼:
public void GetActivityList() throws Exception{
// 加載商戶私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(mchId:商戶號(hào),mchSerialNo:商戶證書序列號(hào),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();
//請(qǐng)求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");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
? offset:分頁(yè)頁(yè)碼,頁(yè)面從0開始
? limit:分頁(yè)大小。特殊規(guī)則:最大取值為100,最小為1
注意:
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見獲取支付有禮活動(dòng)列表接口文檔
步驟說(shuō)明:商戶創(chuàng)建活動(dòng)后,可以通過(guò)該接口刪除支付有禮的發(fā)券商戶號(hào),用于管理活動(dòng)。
示例代碼:
public void DelActivityMch() throws Exception{
// 加載商戶私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(mchId:商戶號(hào),mchSerialNo:商戶證書序列號(hào),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();
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/paygiftactivity/activities/126002309/merchants/delete");
// 請(qǐng)求body參數(shù)
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");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(wú)返回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();
}
}
重要入?yún)⒄f(shuō)明:
A1:支付有禮活動(dòng)的曝光商戶號(hào)必須是商家券歸屬商戶號(hào)的同品牌。同品牌商戶號(hào)是指同一企業(yè)/集團(tuán)/品牌/公司旗下,如果存在多個(gè)微信支付商戶號(hào),該企業(yè)/集團(tuán)/品牌/公司可以授權(quán)財(cái)付通支付科技有限公司將其旗下的多個(gè)商戶號(hào)創(chuàng)建為同品牌商戶號(hào)組合。主要用于更便利使用免充值營(yíng)銷產(chǎn)品功能,包括開通產(chǎn)品權(quán)限、配置組合內(nèi)商戶號(hào)為可用商戶、配置活動(dòng)后可用商戶免審核等
A2:支付有禮中投放批次的校驗(yàn),請(qǐng)按照以下幾點(diǎn)排查
1. 單張券/券包中所有的券開始時(shí)間需早于支付有禮活動(dòng)的開始時(shí)間,結(jié)束時(shí)間需晚于支付有禮的結(jié)束時(shí)間
2. 如果批次為上傳code模式,需先上傳code再投放到支付有禮
3. 添加券包時(shí),庫(kù)存、限領(lǐng)和歸屬商戶號(hào)需要保持一致
4. 曝光商戶號(hào)、批次的歸屬商戶號(hào)需要全部為同品牌
A3:間隔需要小于31536000s,即需要小于365天
A4:查詢活動(dòng)發(fā)券商戶號(hào)API才會(huì)有這個(gè)字段返回,接口文檔地址
A5:請(qǐng)檢查對(duì)應(yīng)的批次,調(diào)用創(chuàng)建商家券接口時(shí)是否有設(shè)置事件通知APPID參數(shù)(notify_appid)