為了在保證支付安全的前提下,帶給商戶(hù)簡(jiǎn)單、一致且易用的開(kāi)發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請(qǐng)參考“APIv3接口規(guī)則”
為了幫助開(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)建加載商戶(hù)私鑰、加載平臺(tái)證書(shū)、初始化httpClient的通用方法
@Before
public void setup() throws IOException {
// 加載商戶(hù)私鑰(privateKey:私鑰字符串)
PrivateKey merchantPrivateKey = PemUtil
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
// 加載平臺(tái)證書(shū)(mchId:商戶(hù)號(hào),mchSerialNo:商戶(hù)證書(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ī)則指引文檔
步驟4 商戶(hù)調(diào)用《建立合作關(guān)系》接口,將指定優(yōu)惠券批次(支付券或商家券)授權(quán)給指定APPID
步驟7 用戶(hù)在商家小程序直播間,可領(lǐng)取對(duì)應(yīng)優(yōu)惠券;(優(yōu)惠券領(lǐng)取后,自動(dòng)插入用戶(hù)微信卡包)
文檔展示了如何使用微信支付服務(wù)端 SDK 快速接入委托營(yíng)銷(xiāo)產(chǎn)品,完成與微信支付對(duì)接的部分。
注意:
步驟說(shuō)明:該接口主要為商戶(hù)提供營(yíng)銷(xiāo)資源的授權(quán)能力,可授權(quán)給其他商戶(hù)或小程序,方便商戶(hù)間的互利合作。
示例代碼:
public void BuildRelations() throws Exception{
//請(qǐng)求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/marketing/partnerships/build");
// 請(qǐng)求body參數(shù)
String reqdata = "{"
+ "\"authorized_data\": {"
+ "\"business_type\":\"FAVOR_STOCK\","
+ "\"stock_id\":\"2433405\""
+ "},"
+ "\"partner\": {"
+ "\"appid\":\"wx4e1916a585d1f4e9\","
+ "\"type\":\"APPID\""
+ "}"
+ "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Idempotency-Key","12345");
//完成簽名并執(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ō)明:
? type:合作方類(lèi)別,枚舉值:
APPID:合作方為APPID
MERCHANT:合作方為商戶(hù)
? business_type:授權(quán)業(yè)務(wù)類(lèi)別,枚舉值:
FAVOR_STOCK:代金券批次
BUSIFAVOR_STOCK:商家券批次
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)建立合作關(guān)系接口文檔
步驟說(shuō)明:該接口主要為商戶(hù)提供合作關(guān)系列表的查詢(xún)能力。
示例代碼:
public void QueryRelations() throws Exception{
//請(qǐng)求URL
HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/marketing/partnerships?authorized_data=%7b%22business_type%22%3a%22BUSIFAVOR_STOCK%22%7d&partner=%7b%22type%22%3a%22APPID%22%7d&offset=0&limit=5");
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ō)明:
? business_type:授權(quán)業(yè)務(wù)類(lèi)別,枚舉值:
FAVOR_STOCK:代金券批次
BUSIFAVOR_STOCK:商家券批次
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請(qǐng)參見(jiàn)查詢(xún)合作關(guān)系列表接口文檔
A:請(qǐng)按照以下幾點(diǎn)檢查:
1. appid或mch_id填寫(xiě)錯(cuò)誤,請(qǐng)確認(rèn)appid和mch_id是否正確
2. appid與mch_id未綁定,請(qǐng)綁定后再調(diào)用接口,綁定步驟請(qǐng)參考《綁定指引》文檔
A商戶(hù)號(hào)不存在,請(qǐng)確認(rèn)請(qǐng)求頭中的商戶(hù)號(hào)是否正確或者是否有空格
A:請(qǐng)按照以下幾點(diǎn)檢查:
1. 簽名與生成Authorization用的同一個(gè)時(shí)間戳跟隨機(jī)串
2. 構(gòu)造簽名串時(shí),里面的url不需要ToLowCase(),不用UrlEncode(),商戶(hù)請(qǐng)求的url后綴是什么,簽名用的url后綴就是什么
3. 查詢(xún)訂單使用的是GET,構(gòu)建簽名串時(shí),里面的請(qǐng)求報(bào)文為空且需要換行符
4. 檢查證書(shū)和商戶(hù)號(hào)是否正確,如為服務(wù)商模式,則需使用服務(wù)商的相關(guān)證書(shū)。簽名相關(guān)問(wèn)題請(qǐng)參考《接口規(guī)則》文檔
A:請(qǐng)求頭中的API證書(shū)序列號(hào)錯(cuò)誤,請(qǐng)排查確認(rèn)。證書(shū)序列號(hào)查看路徑:【商戶(hù)平臺(tái)->API安全->API證書(shū)->查看證書(shū)】
A:Http頭缺少Accept或User-Agent,請(qǐng)根據(jù)V3接口規(guī)則內(nèi)容進(jìn)行排查