# 1. 接口規(guī)則
為了在保證支付安全的前提下,帶給商戶簡單、一致且易用的開發(fā)體驗(yàn),我們推出了全新的微信支付APIv3接口。該版本API的具體規(guī)則請參考APIv3接口規(guī)則 (opens new window)。
# 2. 開發(fā)準(zhǔn)備
# 2.1. 搭建和配置開發(fā)環(huán)境
為了幫助開發(fā)者調(diào)用開放接口,我們提供了JAVA、PHP、GO三種語言版本的開發(fā)庫,封裝了簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等基礎(chǔ)功能(更多語言版本的開發(fā)庫將在近期陸續(xù)提供)
測試步驟:
1、根據(jù)自身開發(fā)語言,選擇對應(yīng)的開發(fā)庫并構(gòu)建項(xiàng)目,具體配置請參考下面鏈接的詳細(xì)說明:
- wechatpay-java (opens new window)(推薦)、wechatpay-apache-httpclient (opens new window),適用于Java開發(fā)者。
- 注:當(dāng)前開發(fā)指引接口JAVA示例代碼采用wechatpay-apache-httpclient版本
- wechatpay-php (opens new window)(推薦)、wechatpay-guzzle-middleware (opens new window),適用于PHP開發(fā)者。
- 注:當(dāng)前開發(fā)指引接口PHP示例代碼采用wechatpay-guzzle-middleware版本。
- wechatpay-go (opens new window),適用于Go開發(fā)者。
更多資源可前往微信支付開發(fā)者社區(qū) (opens new window)搜索查看。
2、創(chuàng)建加載商戶私鑰、加載平臺(tái)證書、初始化httpClient的通用方法。
3、基于接口的示例代碼,替換請求參數(shù)后可發(fā)起測試。
說明:
- 上面的開發(fā)庫為微信支付官方開發(fā)庫,其它沒有審核或者控制下的第三方工具和庫,微信支付不保證它們的安全性和可靠性。通過包管理工具引入SDK后,可根據(jù)下面每個(gè)接口的示例代碼替換相關(guān)參數(shù)后進(jìn)行快速測試。
- 開發(fā)者如果想詳細(xì)了解簽名生成、簽名驗(yàn)證、敏感信息加/解密、媒體文件上傳等常用方法的具體代碼實(shí)現(xiàn),可閱讀下面的詳細(xì)說明:
- 簽名生成 (opens new window)
- 簽名驗(yàn)證 (opens new window)
- 敏感信息加解密 (opens new window)
- merchantPrivateKey(私鑰) (opens new window)
- wechatpayCertificates(平臺(tái)證書) (opens new window)
- APIV3Key(V3 key) (opens new window)
- 如想更詳細(xì)的了解我們的接口規(guī)則,可查看我們的接口規(guī)則 (opens new window)指引文檔。
# 2.2. 業(yè)務(wù)開發(fā)配置
合單支付目前支持在微信外H5、App、JSAPI、小程序、Native掃碼5個(gè)場景使用,下面為你介紹App場景業(yè)務(wù)開發(fā)配置。
# 2.2.1. 注冊App
App接入微信支付,需要先將商戶App在微信開放平臺(tái)進(jìn)行注冊,登記App開發(fā)參數(shù)以生成AppID。具體操作步驟如下:
1、登錄微信開放平臺(tái),進(jìn)入【管理中心 > 移動(dòng)應(yīng)用 > 創(chuàng)建移動(dòng)應(yīng)用】;
2、完成基本信息的錄入,商戶需要在本步驟提交App對應(yīng)的下載地址,應(yīng)用官網(wǎng),應(yīng)用水印,icon等業(yè)務(wù)信息;
3、完成平臺(tái)信息的錄入,商戶需要在本步驟提交App在Android及iOS端對應(yīng)的開發(fā)參數(shù),包括Android端應(yīng)用的包名,應(yīng)用簽名,iOS端應(yīng)用的bundle ID, universal link等;
注意
Android應(yīng)用包名和簽名的相關(guān)說明,請參考Andriod開發(fā)要點(diǎn)說明。
4、以上信息全部提交完成后,即完成App的注冊,商戶可在【管理中心 > 移動(dòng)應(yīng)用】中,選擇具體的應(yīng)用查看其AppID及已獲得的接口能力;
5、獲取到App的AppID后,需要將該AppID與商戶的收款mchid進(jìn)行綁定,商戶可登錄商戶平臺(tái)后前往【產(chǎn)品中心 > AppID賬號(hào)管理】界面中進(jìn)行AppID的綁定及管理,界面如圖所示:
# 2.2.2. iOS開發(fā)要點(diǎn)說明
1、iOS系統(tǒng)opensdk升級(jí)指引:
由于蘋果公司在iOS13系統(tǒng)回收了查詢 App bundleID 的能力,導(dǎo)致微信無法保證授權(quán)憑證能正確返回給AppID對應(yīng)的應(yīng)用。為此,微信支付強(qiáng)烈要求所有商戶盡快升級(jí)到OpenSDK1.8.6,并讓用戶及時(shí)更新App,否則安全風(fēng)險(xiǎn)將一直存在。謝謝配合!
詳細(xì)OpenSDK升級(jí)指引請參見:opensdk升級(jí)指引 (opens new window)。
注意
opensdk升級(jí)后請一定按照文檔要求完成驗(yàn)證工作,確保opensddk升級(jí)成功。
2、開發(fā)配置:
以下項(xiàng)目開發(fā)環(huán)境以Xcode6.0,運(yùn)行環(huán)境為IOS7.0為例,說明其開發(fā)中需要的操作。
a. 項(xiàng)目設(shè)置AppID
商戶在微信開放平臺(tái)申請開發(fā)App應(yīng)用后,微信開放平臺(tái)會(huì)生成App的唯一標(biāo)識(shí)AppID。在Xcode中打開項(xiàng)目,設(shè)置項(xiàng)目屬性中的URL Schemes為您的AppID。如圖標(biāo)紅位置所示。
b. 注冊AppID
商戶App工程中引入微信lib庫和頭文件,調(diào)用API前,需要先向微信注冊您的AppID,代碼如下:
1[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"demo 2.0"];
注意
OpenSDK前端拉起支付及SDK回調(diào)的相關(guān)說明,請參考App調(diào)起支付。
# 2.2.3. Android開發(fā)要點(diǎn)說明
1、后臺(tái)設(shè)置
商戶在微信開放平臺(tái)申請開發(fā)應(yīng)用后,微信開放平臺(tái)會(huì)生成App的唯一標(biāo)識(shí)AppID。由于需要保證支付安全,需要在開放平臺(tái)綁定商戶應(yīng)用包名和應(yīng)用簽名,設(shè)置好后才能正常發(fā)起支付。設(shè)置界面在【開放平臺(tái)】中的欄目【管理中心 > 修改應(yīng)用 > 修改開發(fā)信息】里面,如圖紅框內(nèi)所示。
應(yīng)用包名:是在App項(xiàng)目配置文件AndroidManifest.xml中聲明的package
值,例如圖中的package="demo.wxpay.tenpay.com"
。
應(yīng)用簽名:根據(jù)項(xiàng)目的應(yīng)用包名和編譯使用的keystore,可由簽名工具生成一個(gè)32位的md5串,在調(diào)試的手機(jī)上安裝簽名工具后,運(yùn)行可生成應(yīng)用簽名串,如圖8.9所示,綠色串即應(yīng)用簽名。下載地址: 簽名工具下載地址 (opens new window)。
2、注冊AppID
商戶App工程中引入微信JAR包,調(diào)用API前,需要先向微信注冊您的AppID,代碼如下:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null)
;
// 將該App注冊到微信
msgApi.registerApp("wxd930ea5d5a258f4f")
;
# 3. 快速接入
# 3.1. 業(yè)務(wù)流程圖
業(yè)務(wù)流程時(shí)序圖如下。
重點(diǎn)步驟說明:
步驟1:用戶在商戶側(cè)發(fā)起支付請求,商戶先通過后臺(tái)接口合單下單-App接口創(chuàng)建合單支付訂單。
步驟2:商戶再根據(jù)用戶發(fā)起支付請求的具體場景通過App頁面調(diào)起微信支付收銀臺(tái),完成支付請求。
步驟3:用戶支付成功后,商戶可接收到支付結(jié)果回調(diào)通知。
步驟4:如果商戶長時(shí)間未收到回調(diào)通知,可通過合單查詢訂單接口主動(dòng)查詢訂單支付狀態(tài)。
# 3.2. API接入(含示例代碼)
文檔展示了如何使用微信支付服務(wù)端SDK快速接入商家券產(chǎn)品,完成與微信支付對接的部分。
注意
- 文檔中的代碼示例是用來闡述API基本使用方法,代碼中的示例參數(shù)需替換成商戶自己賬號(hào)及請求參數(shù)才能跑通。
- 以下接入步驟僅提供參考,請商戶結(jié)合自身業(yè)務(wù)需求進(jìn)行評(píng)估、修改。
# 3.2.1. 【服務(wù)端】合單下單-App
步驟說明:用戶在商戶側(cè)選擇商品下單購買時(shí),商戶系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺(tái)生成預(yù)支付交易單,然后使用我們提供的客戶端方法(下文介紹)調(diào)起微信支付收銀臺(tái),即可完成支付。
示例代碼:
重要入?yún)⒄f明:
- out_trade_no:商戶系統(tǒng)內(nèi)部訂單號(hào),只能是數(shù)字、大小寫字母_-*且在同一個(gè)商戶號(hào)下唯一。
- description:商品描述。
- notify_url:支付回調(diào)通知URL,該地址必須為直接可訪問的URL,不允許攜帶查詢串。
- total:訂單總金額,單位為分。
- OpenID:OpenID是微信用戶在AppID下的唯一用戶標(biāo)識(shí)(AppID不同,則獲取到的OpenID就不同),可用于永久標(biāo)記一個(gè)用戶。OpenID獲取方式請參考以下文檔小程序獲取OpenID (opens new window)、公眾號(hào)獲取OpenID (opens new window)、App獲取OpenID (opens new window)。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見合單下單-App。
# 3.2.2.【客戶端】App調(diào)起支付
步驟說明:通過App下單API成功獲取預(yù)支付交易會(huì)話標(biāo)識(shí)(prepay_id
) 后,需要通過OpenSDK來調(diào)起微信支付收銀臺(tái)。
注意:
- 該步驟請使用開放平臺(tái)的官方OpenSDK,可前往開放平臺(tái)資源中心 (opens new window)下載。
- SDK的調(diào)用需要攜帶簽名(參與簽名的參數(shù)為:
appid
、partnerid
、prepayid
、package
、noncestr
、timestamp
,參數(shù)區(qū)分大小寫)。
重要入?yún)⒄f明:
- package: 取固定值
Sign=WXPay
- signType: 該接口V3版本僅支持RSA
- paySign: 簽名
paySign生成規(guī)則、響應(yīng)詳情及錯(cuò)誤碼請參見App調(diào)起支付 (opens new window)接口文檔。
一、iOS SDK調(diào)用說明:
1、拉起支付
商戶服務(wù)器生成支付訂單,先調(diào)用合單App下單API生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給App發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:
1PayReq *request = [[[PayReq alloc] init] autorelease];2request.partnerId = @"10000100";3request.prepayId= @"1101000000140415649af9fc314aa427";4request.package = @"Sign=WXPay";5request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";6request.timeStamp= @"1397527777";7request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";8[WXApi sendReq:request]
注意
該sign
生成字段名列表見調(diào)起支付API (opens new window)。
2、SDK結(jié)果回調(diào)
照微信SDK Sample,在類實(shí)現(xiàn)onResp函數(shù),支付完成后,微信App會(huì)返回到商戶App并回調(diào)onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯(cuò)誤碼,如果支付成功則去后臺(tái)查詢支付結(jié)果再展示用戶實(shí)際支付結(jié)果。注意 一定不能以客戶端返回作為用戶支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付結(jié)果通知或查詢API返回的結(jié)果為準(zhǔn)。代碼示例如下:
1-(void)onResp:(BaseResp*)resp{2 if ([respisKindOfClass:[PayRespclass]]){3 PayResp*response=(PayResp*)resp;4 switch(response.errCode){5 caseWXSuccess: //服務(wù)器端查詢支付結(jié)果通知或查詢API返回的結(jié)果再提示成功6 NSlog(@"支付成功");7 break;8 default:9 NSlog(@"支付失敗,retcode=%d",resp.errCode);10 break;11 }12 }13}
回調(diào)中errCode值列表:
名稱 | 描述 | 解決方案 |
---|---|---|
0 | 成功 | 展示成功頁面 |
-1 | 錯(cuò)誤 | 可能的原因:簽名錯(cuò)誤、未注冊AppID、項(xiàng)目設(shè)置AppID不正確、注冊的AppID與設(shè)置的不匹配、其他異常等。 |
-2 | 用戶取消 | 無需處理。發(fā)生場景:用戶不支付了,點(diǎn)擊取消,返回App。 |
二、Android SDK調(diào)用說明
1、SDK拉起支付
商戶服務(wù)器生成支付訂單,先調(diào)用【合單App下單API】生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給App發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:
1IWXAPI api;2PayReq request = new PayReq();3request.appId = "wxd930ea5d5a258f4f";4request.partnerId = "1900000109";5request.prepayId= "1101000000140415649af9fc314aa427",;6request.packageValue = "Sign=WXPay";7request.nonceStr= "1101000000140429eb40476f8896f4c9";8request.timeStamp= "1398746574";9request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";10api.sendReq(request);
注意
該sign生成字段名列表見調(diào)起支付API (opens new window)。
2、支付結(jié)果回調(diào)
參照微信SDK Sample,在商戶包名.wxapi包路徑中實(shí)現(xiàn)WXPayEntryActivity類(包名或類名不一致會(huì)造成無法回調(diào)),在WXPayEntryActivity類中實(shí)現(xiàn)onResp函數(shù),支付完成后,微信App會(huì)返回到商戶App并回調(diào)onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯(cuò)誤碼,如果支付成功則去后臺(tái)查詢支付結(jié)果再展示用戶實(shí)際支付結(jié)果。注意一定不能以客戶端返回作為用戶支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付結(jié)果通知或查詢API返回的結(jié)果為準(zhǔn)。代碼示例如下:
1publicvoidonResp(BaseRespresp){2 if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){3 Log.d(TAG,"onPayFinish,errCode="+resp.errCode);4 AlertDialog.Builderbuilder=newAlertDialog.Builder(this);5 builder.setTitle(R.string.app_tip);6 }7}
回調(diào)中errCode值列表:
名稱 | 描述 | 解決方案 |
---|---|---|
0 | 成功 | 展示成功頁面 |
-1 | 錯(cuò)誤 | 可能的原因:簽名錯(cuò)誤、未注冊AppID、項(xiàng)目設(shè)置AppID不正確、注冊的AppID與設(shè)置的不匹配、其他異常等。 |
-2 | 用戶取消 | 無需處理。發(fā)生場景:用戶不支付了,點(diǎn)擊取消,返回App。 |
# 3.2.3.【服務(wù)端】接收支付結(jié)果通知
步驟說明:當(dāng)用戶完成支付,微信會(huì)把相關(guān)支付結(jié)果將通過異步回調(diào)的方式通知商戶,商戶需要接收處理,并按文檔規(guī)范返回應(yīng)答。
- 支付結(jié)果通知的地址需要在請求App下單API時(shí)傳入
notify_url
參數(shù)中。 - 支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知URL,通知的數(shù)據(jù)以JSON 格式通過請求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情。
- 加密不能保證通知請求來自微信。微信會(huì)對發(fā)送給商戶的通知進(jìn)行簽名,并將簽名值放在通知的HTTP頭
Wechatpay-Signature
。商戶應(yīng)當(dāng)驗(yàn)證簽名,以確認(rèn)請求來自微信,而不是其他的第三方。簽名驗(yàn)證的算法請參考 《微信支付API v3簽名驗(yàn)證 (opens new window)》。 - 支付結(jié)果通知HTTP應(yīng)答碼為200或204才會(huì)當(dāng)作正常接收,當(dāng)回調(diào)處理異常時(shí),應(yīng)答的HTTP狀態(tài)碼應(yīng)為500,或者4xx。
- 商戶成功接收到回調(diào)通知后應(yīng)返回成功的HTTP應(yīng)答碼為200或204。
- 同樣的通知可能會(huì)多次發(fā)送給商戶系統(tǒng)。商戶系統(tǒng)必須能夠正確處理重復(fù)的通知。
- 后臺(tái)通知交互時(shí),如果微信收到商戶的應(yīng)答不符合規(guī)范或超時(shí),微信會(huì)判定本次通知失敗,重新發(fā)送通知,直到成功為止,但微信不保證通知最終一定能成功。
特別提醒:
- 商戶系統(tǒng)對于支付結(jié)果通知的內(nèi)容一定要做簽名驗(yàn)證,并校驗(yàn)返回的訂單金額是否與商戶側(cè)的訂單金額一致,防止數(shù)據(jù)泄露導(dǎo)致出現(xiàn)“假通知”,造成資金損失。
- 當(dāng)收到通知進(jìn)行處理時(shí),首先檢查對應(yīng)業(yè)務(wù)數(shù)據(jù)的狀態(tài),判斷該通知是否已經(jīng)處理過,如果沒有處理過再進(jìn)行處理,如果處理過直接返回結(jié)果成功。在對業(yè)務(wù)數(shù)據(jù)進(jìn)行狀態(tài)檢查和處理之前,要采用數(shù)據(jù)鎖進(jìn)行并發(fā)控制,以避免函數(shù)重入造成的數(shù)據(jù)混亂。
- 技術(shù)人員可登進(jìn)微信商戶后臺(tái) (opens new window)掃描加入接口報(bào)警群,獲取接口告警信息。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見支付結(jié)果通知API接口文檔。
# 3.2.4. 【服務(wù)端】合單查詢訂單
步驟說明:當(dāng)商戶后臺(tái)、網(wǎng)絡(luò)、服務(wù)器等出現(xiàn)異常,商戶系統(tǒng)最終未接收到支付結(jié)果通知時(shí)商戶可通過查詢訂單接口核實(shí)訂單支付狀態(tài)。
示例代碼:
注意
查詢訂單可通過合單商戶訂單號(hào)查詢。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見查詢訂單API接口文檔。
# 3.2.5. 【服務(wù)端】合單關(guān)閉訂單
步驟說明:當(dāng)商戶訂單支付失敗需要生成新單號(hào)重新發(fā)起支付,要對原訂單號(hào)調(diào)用關(guān)單,避免重復(fù)支付;系統(tǒng)下單后,用戶支付超時(shí),系統(tǒng)退出不再受理,避免用戶繼續(xù),請調(diào)用關(guān)單接口。
示例代碼:
注意
- 訂單生成后不能馬上調(diào)用關(guān)單接口,最短調(diào)用時(shí)間間隔為5分鐘。
- 已支付成功的訂單不能關(guān)閉。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見合單關(guān)單API接口文檔。
# 3.2.6. 【服務(wù)端】申請交易賬單
步驟說明:微信支付按天提供交易賬單文件,商戶可以通過該接口獲取賬單文件的下載地址。
示例代碼:
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見申請交易賬單API (opens new window)接口文檔。
# 3.2.7. 【服務(wù)端】下載賬單
步驟說明:通過申請交易賬單接口獲取到賬單下載地址(download_url)后,再通過該接口獲取到對應(yīng)的賬單文件,文件內(nèi)包含交易相關(guān)的金額、時(shí)間、營銷等信息,供商戶核對訂單、退款、銀行到賬等情況。
示例代碼:
注意
- 賬單文件的下載地址的有效時(shí)間為30s。
- 強(qiáng)烈建議商戶將實(shí)際賬單文件的哈希值和之前從接口獲取到的哈希值進(jìn)行比對,以確認(rèn)數(shù)據(jù)的完整性。
更多參數(shù)、響應(yīng)詳情及錯(cuò)誤碼請參見下載賬單API (opens new window)接口文檔。
# 4. 常見問題
問: 獲取OpenID接口報(bào)“此公眾號(hào)并沒有這些scope的權(quán)限,錯(cuò)誤碼10005”,如下圖所示。
答: 請按以下步驟進(jìn)行排查:
- 建議檢查一下公眾號(hào)的功能。比如是不是在訂閱號(hào)/未認(rèn)證的公眾號(hào)里面嘗試調(diào)用認(rèn)證服務(wù)號(hào)的功能。
- 確認(rèn)AppID是否認(rèn)證過期或者AppID填寫錯(cuò)誤。
- 請嘗試使用snsapi_userinfo的授權(quán)登錄方式。
問:獲取OpenID接口報(bào)“redirect_url域名與后臺(tái)配置不一致,錯(cuò)誤碼:10003”。
答:請按以下步驟進(jìn)行排查:
- 本錯(cuò)誤是公眾號(hào)獲取OpenID接口報(bào)的錯(cuò)誤,可參考文檔檢查是否符合開發(fā)規(guī)范:網(wǎng)頁授權(quán) (opens new window)
- 檢查下單接口傳的AppID與獲取OpenID接口的AppID是否同一個(gè)(需一致)。
- 檢查AppID對應(yīng)的公眾號(hào)后臺(tái) (opens new window),是否配置的授權(quán)域名和獲取OpenID的域名一致。授權(quán)域名配置路徑:【公眾平臺(tái) (opens new window)-> 設(shè)置-> 公眾號(hào)設(shè)置-> 功能設(shè)置–> 網(wǎng)頁授權(quán)域名】。