為了在保證支付安全的前提下,帶給商戶簡單、一致且易用的開發(fā)體驗,我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請參考“APIv3接口規(guī)則”
備注:當前接口用于微信國內錢包
為了幫助開發(fā)者調用開放接口,我們提供了JAVA、PHP、GO三種語言版本的開發(fā)庫,封裝了簽名生成、簽名驗證、敏感信息加/解密、媒體文件上傳等基礎功能(更多語言版本的開發(fā)庫將在近期陸續(xù)提供)
測試步驟:
1、根據(jù)自身開發(fā)語言,選擇對應的開發(fā)庫并構建項目,具體配置請參考下面鏈接的詳細說明:
? wechatpay-java(推薦)wechatpay-apache-httpclient,適用于Java開發(fā)者。
? wechatpay-php(推薦)、wechatpay-guzzle-middleware,適用于PHP開發(fā)者
注:當前開發(fā)指引接口PHP示例代碼采用wechatpay-guzzle-middleware版本
? wechatpay-go,適用于Go開發(fā)者
更多資源可前往微信支付開發(fā)者社區(qū)搜索查看
2、創(chuàng)建加載商戶私鑰、加載平臺證書、初始化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、基于接口的示例代碼,替換請求參數(shù)后可發(fā)起測試
說明:
? 上面的開發(fā)庫為微信支付官方開發(fā)庫,其它沒有審核或者控制下的第三方工具和庫,微信支付不保證它們的安全性和可靠性
通過包管理工具引入SDK后,可根據(jù)下面每個接口的示例代碼替換相關參數(shù)后進行快速測試
? 開發(fā)者如果想詳細了解簽名生成、簽名驗證、敏感信息加/解密、媒體文件上傳等常用方法的具體代碼實現(xiàn),可閱讀下面的詳細說明:
1.簽名生成
2.簽名驗證
3.敏感信息加解密
? 如想更詳細的了解我們的接口規(guī)則,可查看我們的接口規(guī)則指引文檔
合單支付目前支持在微信外H5、APP、JSAPI、小程序、Native掃碼5個場景使用,下面依次為你介紹這5個場景需求進行的業(yè)務開發(fā)配置
開通H5支付權限:前往【微信支付商戶平臺—>產品中心—>H5支付—>申請開通】
設置H5支付域名:登錄【微信支付商戶平臺—>產品中心—>開發(fā)配置—>H5支付】,設置后一般10分鐘內生效。
注意:
? 域名必須通過ICP備案
? 域名填寫格式不包含http://或https://
一、注冊APP
APP接入微信支付,需要先將商戶APP在微信開放平臺進行注冊,登記APP開發(fā)參數(shù)以生成APPID。具體操作步驟如下:
1. 登錄微信開放平臺,進入【管理中心 → 移動應用 → 創(chuàng)建移動應用】;
2. 完成基本信息的錄入,商戶需要在本步驟提交APP對應的下載地址,應用官網(wǎng),應用水印,icon等業(yè)務信息;
3. 完成平臺信息的錄入,商戶需要在本步驟提交APP在Android及iOS端對應的開發(fā)參數(shù),包括Android端應用的包名,應用簽名,iOS端應用的bundle ID, universal link等;
注意:
? Android應用包名和簽名的相關說明,請參考1.2.3章節(jié)。
4. 以上信息全部提交完成后,即完成APP的注冊,商戶可在【管理中心 → 移動應用】中,選擇具體的應用查看其APPID及已獲得的接口能力;
5. 獲取到APP的APPID后,需要將該APPID與商戶的收款mch_id進行綁定,商戶可登錄商戶平臺后前往【產品中心 -> AppID賬號管理】界面中進行AppID的綁定及管理,界面如圖所示:
二、iOS開發(fā)要點說明:
? iOS系統(tǒng)opensdk升級指引:
由于蘋果公司在iOS13系統(tǒng)回收了查詢 App bundleID 的能力,導致微信無法保證授權憑證能正確返回給AppID對應的應用。為此,微信支付強烈要求所有商戶盡快升級到OpenSDK1.8.6,并讓用戶及時更新APP,否則安全風險將一直存在。謝謝配合!
詳細OpenSDK升級指引請參見:opensdk升級指引
注意:opensdk升級后請一定按照文檔要求完成驗證工作,確保opensddk升級成功。
? 開發(fā)配置:
以下項目開發(fā)環(huán)境以Xcode6.0,運行環(huán)境為IOS7.0為例,說明其開發(fā)中需要的操作。
1. 項目設置APPID
商戶在微信開放平臺申請開發(fā)APP應用后,微信開放平臺會生成APP的唯一標識APPID。在Xcode中打開項目,設置項目屬性中的URL Schemes為您的APPID。如圖8.7標紅位置所示。
2. 注冊APPID
商戶APP工程中引入微信lib庫和頭文件,調用API前,需要先向微信注冊您的APPID,代碼如下:
[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"demo 2.0"];
注意:
? OpenSDK前端拉起支付及SDK回調的相關說明,請參考章節(jié)2.2.2。
三、Android開發(fā)要點說明:
1. 后臺設置:
商戶在微信開放平臺申請開發(fā)應用后,微信開放平臺會生成APP的唯一標識APPID。由于需要保證支付安全,需要在開放平臺綁定商戶應用包名和應用簽名,設置好后才能正常發(fā)起支付。設置界面在【開放平臺】中的欄目【管理中心 / 修改應用 / 修改開發(fā)信息】里面,如圖紅框內所示。
應用包名:是在APP項目配置文件AndroidManifest.xml中聲明的package值,例如圖中的package="demo.wxpay.tenpay.com"。
應用簽名:根據(jù)項目的應用包名和編譯使用的keystore,可由簽名工具生成一個32位的md5串,在調試的手機上安裝簽名工具后,運行可生成應用簽名串,如圖8.9所示,綠色串即應用簽名。簽名工具下載地址。
2. 注冊APPID
商戶APP工程中引入微信JAR包,調用API前,需要先向微信注冊您的APPID,代碼如下:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
// 將該app注冊到微信
msgApi.registerApp("wxd930ea5d5a258f4f");
設置支付目錄
? 支付授權目錄說明:
1、商戶最后請求拉起微信支付收銀臺的頁面地址我們稱之為“支付目錄”,例如:https://www.weixin.com/pay.php。
2、商戶實際的支付目錄必須和在微信支付商戶平臺設置的一致,否則會報錯“當前頁面的URL未注冊:”
? 支付授權目錄設置說明:
登錄【微信支付商戶平臺-->產品中心-->開發(fā)配置】,設置后一般5分鐘內生效。(配置頁見下圖)
? 支付授權目錄校驗規(guī)則說明:
1、如果支付授權目錄設置為頂級域名(例如:https://www.weixin.com/ ),那么只校驗頂級域名,不校驗后綴;
2、如果支付授權目錄設置為多級目錄,就會進行全匹配,例如設置支付授權目錄為https://www.weixin.com/abc/123/,則實際請求頁面目錄不能為https://www.weixin.com/abc/,也不能為https://www.weixin.com/abc/123/pay/,必須為https://www.weixin.com/abc/123/
設置授權域名
授權域名說明:開發(fā)JSAPI支付時,在JSAPI下單接口中要求必傳用戶openid,而獲取openid則需要您在公眾平臺設置獲取openid的域名,只有被設置過的域名才是一個有效的獲取openid的域名,否則將獲取失敗。具體配置頁見下圖
授權域名設置說明:登錄【微信公眾平臺-->公眾號設置】
賬號申請指引:
a、小程序開通微信支付,即申請或復用微信支付商戶號 申請完小程序后,登錄小程序后臺。點擊左側導航欄的微信支付,在頁面中進行開通。(開通申請要求小程序已發(fā)布上線)
b、點擊開通按鈕后,有2種方式可以獲取微信支付能力,新申請微信支付商戶號或綁定一個已有的微信支付商戶號,請根據(jù)你的業(yè)務需要和具體情況選擇,只能二選一。詳見微信支付商戶接入指引
服務器配置要求:
a、小程序訪問商戶服務都是通過HTTPS,開發(fā)部署的時候需要HTTPS服務器
b、服務器域名配置
①、每個微信小程序需要事先設置通訊域名,小程序只可以跟指定的域名進行網(wǎng)絡通信。包括普通 HTTPS 請求(wx.request)、上傳文件(wx.uploadFile)、下載文件(wx.downloadFile)和 WebSocket 通信(wx.connectSocket)
②、從基礎庫 2.4.0 開始,網(wǎng)絡接口允許與局域網(wǎng) IP 通信,但要注意 不允許與本機 IP 通信
注意:
? 域名只支持 https (wx.request、wx.uploadFile、wx.downloadFile) 和 wss (wx.connectSocket) 協(xié)議
? 域名不能使用 IP 地址(小程序的局域網(wǎng) IP 除外)或 localhost
? 可以配置端口,如 https://myserver.com:8080,但是配置后只能向https://myserver.com:8080/發(fā)起請求。如果向https://myserver.com、https://myserver.com:9091等 URL 請求則會失敗
? 如果不配置端口。如https://myserver.com,那么請求的 URL 中也不能包含端口,甚至是默認的 443 端口也不可以。如果向https://myserver.com:443請求則會失敗
? 域名必須經過 ICP 備案
? 出于安全考慮,api.weixin.qq.com不能被配置為服務器域名,相關API也不能在小程序內調用。 開發(fā)者應將 AppSecret 保存到后臺服務器中,通過服務器使用 getAccessToken 接口獲取 access_token,并調用相關 API
? 不支持配置父域名,使用子域名
? 可查閱小程序網(wǎng)絡請求以了解更多信息
暫無需特殊配置內容
重要步驟說明:
本文檔展示了如何使用微信支付服務端 SDK 快速接入合單支付產品,完成與微信支付對接的部分。
注意
步驟說明:用戶在商戶側選擇商品下單購買時,商戶系統(tǒng)先調用該接口在微信支付服務后臺生成預支付交易單,然后使用我們提供的客戶端方法(下文介紹)調起微信支付收銀臺,即可完成支付。
合單下單接口為了區(qū)分用戶發(fā)起支付的5個場景:微信外H5、APP、JSAPI、小程序、Native掃碼,我們分別使用了4個不同接口地址對應這5個場景(小程序與公眾號合單下單接口地址相同):
https://api.mch.weixin.qq.com/v3/combine-transactions/h5——微信外H5場景合單下單接口地址
https://api.mch.weixin.qq.com/v3/combine-transactions/app——APP場景合單下單接口地址
https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi——JSAPI、小程序場景合單下單接口地址
https://api.mch.weixin.qq.com/v3/combine-transactions/native——Native掃碼場景合單下單接口地址
下面以JSAPI、小程序場景為例,為你展示合單JSAPI下單接口的請求示例。
示例代碼
public void CombineJsapiPrepay() throws Exception{
//請求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi");
// 請求body參數(shù)
String reqdata = "{"
+ "\"combine_out_trade_no\":\"1217752501201407033233368018\","
+ "\"combine_mchid\":\"1230000109\","
+ "\"combine_appid\":\"wxd678efh567hg6787\","
+ "\"scene_info\": {"
+ "\"device_id\":\"POS1:1\","
+ "\"payer_client_ip\":\"14.17.22.32\""
+ "},"
+ "\"sub_orders\": ["
+ "{"
+ "\"mchid\":\"1230000109\","
+ "\"attach\":\"深圳分店\","
+ "\"amount\": {"
+ "\"total_amount\":10,"
+ "\"currency\":\"CNY\""
+ "},"
+ "\"out_trade_no\":\"20150806125346\","
+ "\"sub_mchid\":\"1900000109\","
+ "\"description\":\"騰訊充值中心-QQ會員充值\""
+ "}"
+ "],"
+ "\"combine_payer_info\": {"
+ "\"openid\":\"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\""
+ "},"
+ "\"time_start\":\"2018-06-08T10:34:56+08:00\","
+ "\"time_expire\":\"2018-06-08T10:34:56+08:00\","
+ "\"notify_url\":\"https://yourapp.com/notify\""
+ "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請求
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();
}
}
重要入?yún)⒄f明:
? out_trade_no:商戶系統(tǒng)內部訂單號,只能是數(shù)字、大小寫字母_-*且在同一個商戶號下唯一
? description:商品描述
? notify_url:支付回調通知URL,該地址必須為直接可訪問的URL,不允許攜帶查詢串
? total:訂單總金額,單位為分
? openid:openid是微信用戶在appid下的唯一用戶標識(appid不同,則獲取到的openid就不同),可用于永久標記一個用戶。openid獲取方式請參考以下文檔小程序獲取openid、公眾號獲取openid、APP獲取openid
更多參數(shù)、響應詳情及錯誤碼請參見 JSAPI下單
步驟說明:通過合單下單API成功獲取預支付交易會話標識(prepay_id)后,需要通過JSAPI調起支付API來調起微信支付收銀臺
注意
示例代碼:
function onBridgeReady() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId": "wx2421b1c4370ecxxx", //公眾號ID,由商戶傳入
"timeStamp": "1395712654", //時間戳,自1970年以來的秒數(shù)
"nonceStr": "e61463f8efa94090b1f366cccfbbb444", //隨機串
"package": "prepay_id=up_wx21201855730335ac86f8c43d1889123400",
"signType": "RSA", //微信簽名方式:
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==" //微信簽名
},
function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判斷前端返回,微信團隊鄭重提示:
//res.err_msg將在用戶支付成功后返回ok,但并不保證它絕對可靠。
}
});
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
重要入?yún)⒄f明:
package:JSAPI下單接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=***
signType:該接口V3版本僅支持RSA
paySign:簽名
paySign生成規(guī)則、響應詳情及錯誤碼請參見 JSAPI調起支付接口文檔
步驟說明:通過APP下單API成功獲取預支付交易會話標識(prepay_id)后,需要通過OpenSDK來調起微信支付收銀臺
注意:
paySign生成規(guī)則、響應詳情及錯誤碼請參見APP調起支付接口文檔
iOS SDK調用說明
一、拉起支付
商戶服務器生成支付訂單,先調用合單APP下單API生成預付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調起微信支付的關鍵代碼:
PayReq *request = [[[PayReq alloc] init] autorelease];
request.partnerId = @"10000100";
request.prepayId= @"1101000000140415649af9fc314aa427";
request.package = @"Sign=WXPay";
request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";
request.timeStamp= @"1397527777";
request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";
[WXApi sendReq:request]
注意:該sign生成字段名列表見調起支付API
二、SDK結果回調
照微信SDK Sample,在類實現(xiàn)onResp函數(shù),支付完成后,微信APP會返回到商戶APP并回調onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結果再展示用戶實際支付結果。注意 一定不能以客戶端返回作為用戶支付的結果,應以服務器端的接收的支付結果通知或查詢API返回的結果為準。代碼示例如下:
-(void)onResp:(BaseResp*)resp{
if ([respisKindOfClass:[PayRespclass]]){
PayResp*response=(PayResp*)resp;
switch(response.errCode){
caseWXSuccess: //服務器端查詢支付結果通知或查詢API返回的結果再提示成功
NSlog(@"支付成功");
break;
default:
NSlog(@"支付失敗,retcode=%d",resp.errCode);
break;
}
}
}
回調中errCode值列表:
名稱 | 描述 | 解決方案 |
---|---|---|
0 | 成功 | 展示成功頁面 |
-1 | 錯誤 | 可能的原因:簽名錯誤、未注冊APPID、項目設置APPID不正確、注冊的APPID與設置的不匹配、其他異常等。 |
-2 | 用戶取消 | 無需處理。發(fā)生場景:用戶不支付了,點擊取消,返回APP。 |
Android SDK調用說明
一、SDK拉起支付
商戶服務器生成支付訂單,先調用【合單APP下單API】生成預付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調起微信支付的關鍵代碼:
IWXAPI api;
PayReq request = new PayReq();
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId= "1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr= "1101000000140429eb40476f8896f4c9";
request.timeStamp= "1398746574";
request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
api.sendReq(request);
注意:該sign生成字段名列表見調起支付API
二、支付結果回調
參照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路徑中實現(xiàn)WXPayEntryActivity類(包名或類名不一致會造成無法回調),在WXPayEntryActivity類中實現(xiàn)onResp函數(shù),支付完成后,微信APP會返回到商戶APP并回調onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結果再展示用戶實際支付結果。注意一定不能以客戶端返回作為用戶支付的結果,應以服務器端的接收的支付結果通知或查詢API返回的結果為準。代碼示例如下:
publicvoidonResp(BaseRespresp){
if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
Log.d(TAG,"onPayFinish,errCode="+resp.errCode);
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
}
}
回調中errCode值列表:
名稱 | 描述 | 解決方案 |
---|---|---|
0 | 成功 | 展示成功頁面 |
-1 | 錯誤 | 可能的原因:簽名錯誤、未注冊APPID、項目設置APPID不正確、注冊的APPID與設置的不匹配、其他異常等。 |
-2 | 用戶取消 | 無需處理。發(fā)生場景:用戶不支付了,點擊取消,返回APP。 |
步驟說明:通過小程序下單API成功獲取預支付交易會話標識(prepay_id)后,需要通過小程序調起支付API來調起微信支付收銀臺
注意:
示例代碼:
wx.requestPayment(
{
"timeStamp": "1414561699",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"package": "prepay_id=up_wx201410272009395522657a690389285100",
"signType": "RSA",
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==",
"success":function(res){},
"fail":function(res){},
"complete":function(res){}
})
重要入?yún)⒄f明:
paySign生成規(guī)則、響應詳情及錯誤碼請參見小程序調起支付API接口文檔
步驟說明:通過Native下單API成功獲取支付二維碼鏈接(code_url)后,需要在前端(PC網(wǎng)頁或POS機具)生成二維碼供用戶掃描支付。
注意:
code_url對應鏈接格式:weixin://weixin://www.tg885.com/bizpayurl/up?pr=NwY5Mz9&groupid=00。請商戶調用第三方庫將code_url生成二維碼圖片。該模式鏈接較短,生成的二維碼打印到結賬小票上的識別率較高。 >
例如,將weixin://weixin://www.tg885.com/bizpayurl/up?pr=NwY5Mz9&groupid=00 生成二維碼建下圖
更多二維碼的相關背景知識可參考
步驟說明:通過H5下單API成功獲取H5下單返回的支付中間頁(h5_url)后,用戶需要通過微信外部的瀏覽器調起微信支付收銀臺
注意:
1、微信支付中間頁調起微信收銀臺后超過5秒
2、用戶點擊“取消支付”或支付完成后點“完成”按鈕。因此無法保證頁面回跳時,支付流程已結束,所以商戶設置的redirect_url地址不能自動執(zhí)行查單操作,應讓用戶去點擊按鈕觸發(fā)查單操作,回跳頁面展示效果可參考下圖
更多參數(shù)、響應詳情及錯誤碼請參見H5調起支付API接口文檔
步驟說明:當用戶完成支付,微信會把相關支付結果將通過異步回調的方式通知商戶,商戶需要接收處理,并按文檔規(guī)范返回應答
特別提醒:
更多參數(shù)、響應詳情及錯誤碼請參見支付結果通知API接口文檔
步驟說明:當商戶后臺、網(wǎng)絡、服務器等出現(xiàn)異常,商戶系統(tǒng)最終未接收到支付結果通知時商戶可通過查詢訂單接口核實訂單支付狀態(tài)
示例代碼:
public void QueryOrder() throws Exception {
//請求URL
URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/P11093730578574");
uriBuilder.setParameter("mchid", mchId);
//完成簽名并執(zhí)行請求
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("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) {
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();
}
}
注意:
更多參數(shù)、響應詳情及錯誤碼請參見 查詢訂單API接口文檔
步驟說明:當商戶訂單支付失敗需要生成新單號重新發(fā)起支付,要對原訂單號調用關單,避免重復支付;系統(tǒng)下單后,用戶支付超時,系統(tǒng)退出不再受理,避免用戶繼續(xù),請調用關單接口
示例代碼:
public void CombineCloseOrder() throws Exception{
//請求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close");
// 請求body參數(shù)
String reqdata = "{"
+ "\"combine_appid \":\"wxd678efh567hg6787\","
+ "\"combine_out_trade_no\":\"P20150806125346\","
+ "\"sub_orders\": ["
+ "{"
+ "\"mchid\":\"1900000109\","
+ "\"out_trade_no\":\"20150806125346\","
+ "\"sub_mchid\":\"1230000109\","
+ "\"description\":\"騰訊充值中心-QQ會員充值\""
+ "}"
+ "]"
+ "}";
StringEntity entity = new StringEntity(reqdata,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成簽名并執(zhí)行請求
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();
}
}
注意:
更多參數(shù)、響應詳情及錯誤碼請參見 合單關單API接口文檔
步驟說明:微信支付按天提供交易賬單文件,商戶可以通過該接口獲取賬單文件的下載地址
示例代碼:
public void TradeBill() throws Exception {
//請求URL
URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/bill/tradebill");
uriBuilder.setParameter("bill_date", "2020-11-09");
uriBuilder.setParameter("bill_type", "ALL");
//完成簽名并執(zhí)行請求
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("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) {
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();
}
}
更多參數(shù)、響應詳情及錯誤碼請參見申請交易賬單API 接口文檔
步驟說明:通過申請交易賬單接口獲取到賬單下載地址(download_url)后,再通過該接口獲取到對應的賬單文件,文件內包含交易相關的金額、時間、營銷等信息,供商戶核對訂單、退款、銀行到賬等情況
示例代碼:
public void DownloadUrl(String download_url) throws Exception{
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
//初始化httpClient
//該接口無需進行簽名驗證、通過withValidator((response) -> true)實現(xiàn)
httpClient = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator((response) -> true).build();
//請求URL
//賬單文件的下載地址的有效時間為30s
URIBuilder uriBuilder = new URIBuilder(download_url);
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader("Accept", "application/json");
//執(zhí)行請求
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) {
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();
}
}
注意:
更多參數(shù)、響應詳情及錯誤碼請參見 下載賬單API接口文檔
Q:獲取OPENID接口報“此公眾號并沒有這些scope的權限,錯誤碼10005”,如下圖所示
A:請按以下步驟進行排查:
1.建議檢查一下公眾號的功能。比如是不是在訂閱號/未認證的公眾號里面嘗試調用認證服務號的功能
2.確認APPID是否認證過期或者APPID填寫錯誤
3.請嘗試使用snsapi_userinfo的授權登錄方式
A:請按以下步驟進行排查:
1.請檢查你的下單接口是否指定了支付用戶的身份,該功能需單獨開通指定身份支付權限方可使用
2.請確認你使用的商戶號是否有jsapi支付的權限,可登錄商戶平臺-產品中心查看
A:請檢查下單接口中使用的商戶號是否在商戶平臺(www.tg885.com)配置了對應的支付目錄,可參考“1.2.1設置支付目錄”章節(jié)說明
A:請按以下步驟進行排查:
1.檢查下單接口傳的appid與獲取openid接口的appid是否同一個(需一致)
2.檢查appid對應的公眾號后臺(mp.weixin.qq.com),是否配置的授權域名和獲取openid的域名一致。授權域名配置路徑:公眾平臺--設置--公眾號設置--功能設置–網(wǎng)頁授權域名
A:JSAPI支付只能從微信瀏覽器內發(fā)起支付請求