為了在保證支付安全的前提下,帶給商戶簡(jiǎn)單、一致且易用的開(kāi)發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請(qǐng)參考“APIv3接口規(guī)則”
備注:當(dāng)前接口用于微信國(guó)內(nèi)錢包
為了幫助開(kāi)發(fā)者調(diào)用開(kāi)放接口,我們提供了JAVA、PHP、GO三種語(yǔ)言版本的開(kāi)發(fā)庫(kù),封裝了簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等基礎(chǔ)功能(更多語(yǔ)言版本的開(kāi)發(fā)庫(kù)將在近期陸續(xù)提供)
測(cè)試步驟:
1、根據(jù)自身開(kāi)發(fā)語(yǔ)言,選擇對(duì)應(yīng)的開(kāi)發(fā)庫(kù)并構(gòu)建項(xiàng)目,具體配置請(qǐng)參考下面鏈接的詳細(xì)說(shuō)明:
? wechatpay-java(推薦)wechatpay-apache-httpclient,適用于Java開(kāi)發(fā)者。
? wechatpay-php(推薦)、wechatpay-guzzle-middleware,適用于PHP開(kāi)發(fā)者
注:當(dāng)前開(kāi)發(fā)指引接口PHP示例代碼采用wechatpay-guzzle-middleware版本
? wechatpay-go,適用于Go開(kāi)發(fā)者
更多資源可前往微信支付開(kāi)發(fā)者社區(qū)搜索查看
2、創(chuàng)建加載商戶私鑰、加載平臺(tái)證書(shū)、初始化httpClient的通用方法
@Before
public void setup() throws IOException {
// 加載商戶私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(shū)(mchId:商戶號(hào),mchSerialNo:商戶證書(shū)序列號(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ō)明:
? 上面的開(kāi)發(fā)庫(kù)為微信支付官方開(kāi)發(fā)庫(kù),其它沒(méi)有審核或者控制下的第三方工具和庫(kù),微信支付不保證它們的安全性和可靠性
通過(guò)包管理工具引入SDK后,可根據(jù)下面每個(gè)接口的示例代碼替換相關(guān)參數(shù)后進(jìn)行快速測(cè)試
? 開(kāi)發(fā)者如果想詳細(xì)了解簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等常用方法的具體代碼實(shí)現(xiàn),可閱讀下面的詳細(xì)說(shuō)明:
1.簽名生成
3.敏感信息加解密
5.wechatpayCertificates(平臺(tái)證書(shū))
? 如想更詳細(xì)的了解我們的接口規(guī)則,可查看我們的接口規(guī)則指引文檔
1、登錄【微信支付服務(wù)商平臺(tái)】后,通過(guò)路徑【產(chǎn)品中心—>我的產(chǎn)品—>支付即服務(wù)—>產(chǎn)品設(shè)置】,即可開(kāi)通支付即服務(wù),開(kāi)通后完成產(chǎn)品設(shè)置。
2、【產(chǎn)品設(shè)置】頁(yè)面如下圖所示,具體內(nèi)容包括上傳商家logo、選擇服務(wù)人員名稱及選擇名片功能模塊。
重點(diǎn)步驟說(shuō)明:
步驟6 使用企業(yè)微信的商戶,通過(guò)《服務(wù)人員注冊(cè)API》接口傳入服務(wù)人員信息進(jìn)行注冊(cè),微信支付返回服務(wù)人員ID給到商戶,商戶需將服務(wù)人員注冊(cè)信息和對(duì)應(yīng)的服務(wù)人員ID進(jìn)行妥善保存。
步驟11 商戶在下單時(shí)生成商戶訂單號(hào),接著調(diào)用《服務(wù)人員分配API》傳入“商戶訂單號(hào)+服務(wù)人員ID”,隨后按照原有流程和支付接口完成支付即可。
文檔展示了如何使用微信支付服務(wù)端 SDK 快速接入支付即服務(wù)產(chǎn)品,完成與微信支付對(duì)接的部分。
注意:
步驟說(shuō)明:服務(wù)人員注冊(cè)接口用于商戶開(kāi)發(fā)者為商戶注冊(cè)服務(wù)人員使用。
注意:
示例代碼
public void RegSmartGuide() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/smartguide/guides");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
+ "\"sub_mchid\":\"1234567890\","
+ "\"store_id\":1234,"
+ "\"corpid\":\"1234567890\","
+ "\"name\":\"pVd1HJ6v/69bDnuC4EL5Kz4jBHLiCa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==\","
+ "\"mobile\":\"pVd1HJ6v/69bDnuC4EL5Kz4jBHLiCa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==\","
+ "\"qr_code\":\"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx\","
+ "\"avatar\":\"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0\","
+ "\"group_qrcode\":\"http://p.qpic.cn/wwhead/nMl9ssowtibVGyrmvBiaibzDtp/0\","
+ "\"userid\":\"robert\""
+ "}";
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ō)明:
? store_id:門店在微信支付商戶平臺(tái)的唯一標(biāo)識(shí)(查找路徑:登錄商戶平臺(tái)—>營(yíng)銷中心—>門店管理,若無(wú)門店則需先創(chuàng)建門店)
? name:?jiǎn)T工在商戶企業(yè)微信通訊錄上的姓名,需使用微信支付平臺(tái)公鑰加密該字段需進(jìn)行加密處理,加密方法詳見(jiàn)敏感信息加密說(shuō)明。特殊規(guī)則:加密前字段長(zhǎng)度限制為64個(gè)字節(jié)
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)服務(wù)人員注冊(cè)API接口文檔
步驟說(shuō)明:服務(wù)人員分配接口用于商戶開(kāi)發(fā)者在顧客下單后為顧客分配服務(wù)人員使用。
注意:
示例代碼:
public void AssignGuide() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/smartguide/guides/LLA3WJ6DSZUfiaZDS79FH5Wm5m4X69TBic/assign");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
+ "\"out_trade_no\":\"20150806125346\""
+ "\"sub_mchid\":\"1234567890\""
+ "}";
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ō)明:
? out_trade_no:商戶系統(tǒng)內(nèi)部訂單號(hào),要求32個(gè)字符內(nèi),僅支持使用字母、數(shù)字、中劃線-、下劃線_、豎線|、星號(hào)*這些英文半角字符的組合,請(qǐng)勿使用漢字或全角等特殊字符,且在同一個(gè)商戶號(hào)下唯一。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)服務(wù)人員分配API接口文檔
步驟說(shuō)明:服務(wù)人員查詢接口用于商戶開(kāi)發(fā)者查詢已注冊(cè)的服務(wù)人員ID等信息。
注意:
個(gè)人微信商家
企業(yè)微信商家
服務(wù)人員注冊(cè)API和查詢API請(qǐng)求URL相同,區(qū)別主要是在body和query,請(qǐng)注意區(qū)分。
示例代碼:
public void QueryGuide() throws Exception{
//請(qǐng)求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/smartguide/guides?store_id=1234&sub_mchid=1234567890");
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ō)明:
? userid:?jiǎn)T工在商戶企業(yè)微信通訊錄使用的唯一標(biāo)識(shí),企業(yè)微信商家可傳入該字段查詢單個(gè)服務(wù)人員信息;不傳則查詢整個(gè)門店下的服務(wù)人員信息。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)服務(wù)人員查詢API接口文檔
步驟說(shuō)明:服務(wù)人員信息更新接口用于商戶開(kāi)發(fā)者為商戶更新門店服務(wù)人員的姓名、頭像等信息。
注意:
示例代碼:
public void UpdateGuide() throws Exception{
//請(qǐng)求URL
HttpPatch httpPatch = new HttpPatch("https://api.mch.weixin.qq.com/v3/smartguide/guides/LLA3WJ6DSZUfiaZDS79FH5Wm5m4X69TBic");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
+
"\"sub_mchid\":\"1234567890\","
+
"\"name\":\"pVd1HJ6v/69bDnuC4EL5Kz4jBHLiCa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==\","
+ "\"mobile\":\"pVd1HJ6v/69bDnuC4EL5Kz4jBHLiCa8MRtelw/wDa4SzfeespQO/0kjiwfqdfg==\","
+ "\"qr_code\":\"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx\","
+ "\"avatar\":\"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0\","
+ "\"group_qrcode\":\"http://p.qpic.cn/wwhead/nMl9ssowtibVGyrmvBiaibzDtp/0\""
+ "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPatch.setEntity(entity);
httpPatch.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請(qǐng)求
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) { //處理成功,無(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ō)明:
? guide_id:務(wù)人員在支付即服務(wù)系統(tǒng)中的唯一標(biāo)識(shí)。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)服務(wù)人員信息更新API接口文檔
A:如果是普通特約商戶自己調(diào)接口,不傳即可;如果是服務(wù)商幫普通特約商戶調(diào)接口,傳普通特約商戶的商戶號(hào)
A:獲取corpid可進(jìn)入企業(yè)微信的管理后臺(tái),查找路徑:【我的企業(yè)->企業(yè)信息→查看“企業(yè)ID”】(需要有管理員權(quán)限)
A:是的,注冊(cè)時(shí)必須傳入門店ID。該門店ID是微信支付門店系統(tǒng)的編碼,查找路徑:【登錄商戶平臺(tái)->營(yíng)銷中心→門店管理】,門店管理頁(yè)面下的門店編號(hào)即為需要填寫的門店ID(該門店信息與企業(yè)微信的門店系統(tǒng)無(wú)關(guān))。
若未創(chuàng)建門店,則需創(chuàng)建門店并通過(guò)騰訊地圖審核后,方可使用門店ID進(jìn)行注冊(cè)。
A:支付前。建議當(dāng)商家生成當(dāng)前交易的“商戶訂單號(hào)”時(shí),通過(guò)“服務(wù)人員分配API”將“服務(wù)人員ID+商戶訂單號(hào)”傳給微信支付,并按照原有流程引導(dǎo)用戶完成支付即可。若分配服務(wù)人員晚于支付完成,則將無(wú)法在支付憑證上出現(xiàn)服務(wù)人員名片入口
A:使用服務(wù)人員分配API進(jìn)行分配時(shí),服務(wù)人員的分配機(jī)制由商家內(nèi)部閉環(huán),可以靈活掌控。在支付前調(diào)用分配接口時(shí),商家可自行決定分配哪名服務(wù)人員,商家可選擇隨機(jī)分配、按時(shí)間段分配,或?yàn)槟彻P訂單指定特定服務(wù)人員的分配方式(例如在線下門店支付時(shí),可分配當(dāng)前為該顧客提供服務(wù)的服務(wù)人員)。使用免開(kāi)發(fā)版本時(shí),商戶號(hào)下的所有訂單將隨機(jī)分配給不同服務(wù)人員,商家可通過(guò)小程序調(diào)整服務(wù)人員分配的時(shí)間段,但是不能針對(duì)不同訂單分配特定的服務(wù)人員