介紹
銀聯(lián)支付,支付寶支付惨好,微信支付的三大總結(jié)煌茴,之前也有寫過兩篇。
微信支付日川,支付寶支付蔓腐,銀聯(lián)支付——三大支付總結(jié):
http://blog.csdn.net/androidstarjack/article/details/72669394
支付寶植入總結(jié):
微信支付總結(jié):
備注:出于安全考慮,驗(yàn)簽我們都是放到后臺進(jìn)行驗(yàn)簽的龄句。對于我們移動端節(jié)省了很多的勞動力回论。
之前有做過支付寶支付和微信支付,所以這次做起來碰到的問題很少分歇,key申請下來之后很快就搞定了傀蓉。吼吼
效果圖:
由于用魯大師去截屏獲取gif,魯大師一針一針繪制圖片的時候應(yīng)該沒做好處理职抡,導(dǎo)致跳轉(zhuǎn)到相應(yīng)的界面出現(xiàn)黑屏現(xiàn)象葬燎。在手機(jī)上正常跳轉(zhuǎn),無黑屏現(xiàn)象繁调。大家不用擔(dān)心這個
****準(zhǔn)備****:
需要以公司名義萨蚕,在支付寶,微信等平臺上開通公司賬戶并且認(rèn)證蹄胰,如:支付過程中需要公司的帳號和商戶號岳遥。
支付寶支付
如果碰到一些坑的話,請參考我之前寫過的意一篇支付寶踩坑的文章:
- 首先支付寶申請并集成支付寶SDK 這里不再詳細(xì)介紹
參考文檔:
https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1
-
- 獲取訂單信息(根據(jù)自己公司的實(shí)際情況:可以在服務(wù)端完成裕寨,也可以在本地完成)
如:
price=12.5&num=12 //價格為12.5浩蓉,數(shù)量為12
- 客戶端拿這些訂單信息向服務(wù)器后臺進(jìn)行請求派继,返回支付簽名信息signInfo
- app攜帶支付信息,調(diào)用支付接口請求支付寶客戶端捻艳,從而調(diào)起支付界面
/**
* 支付寶進(jìn)行請求
*
* @param signInfo
*/
private void payToOrderService(final String signInfo) {
new Thread() {
@Override
public void run() {
super.run();
PayTask payTask = new PayTask(MyScannerPayActivity.this);
// String result = payTask.pay(signInfo, true);
Map<String, String> result = payTask.payV2(signInfo, true);
Message message = mHandler.obtainMessage();
message.what = SDK_PAY_FLAG;
message.obj = result;
mHandler.sendMessage(message);
}
}.start();
}
- 用戶操作驾窟,輸入密碼支付,支付成功认轨;直接返回取消支付绅络;出現(xiàn)錯誤,支付失斷易帧恩急;進(jìn)入支付界面,但輸入密碼支付纪蜒,支付待確認(rèn)衷恭;
- 支付寶客戶端將支付結(jié)果告訴app客戶端,商戶服務(wù)器通知app服務(wù)器支付結(jié)果纯续;
- app客戶端處理支付結(jié)果随珠;
- app服務(wù)器處理支付結(jié)果。
處理結(jié)果通知:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SDK_PAY_FLAG:
PayResult payResult = null;
try {
payResult = new PayResult((Map<String, String>) msg.obj);
} catch (Exception e) {
e.printStackTrace();
}
/**
對于支付結(jié)果猬错,請商戶依賴服務(wù)端的異步通知結(jié)果窗看。同步通知結(jié)果,僅作為支付結(jié)束的通知兔魂。
*/
String resultInfo = payResult.getResult();// 同步返回需要驗(yàn)證的信息
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為9000則代表支付成功
if (TextUtils.equals(resultStatus, PAY_OK)) {
ActivityUtils.showActivity(MyScannerPayActivity.this, ScannerPaySuccessActivity.class);
finish();
} else if (TextUtils.equals(resultStatus, PAY_FAILED)) {//------------------------->支付失敗
// 該筆訂單真實(shí)的支付結(jié)果烤芦,需要依賴服務(wù)端的異步通知。
Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();
} else if (TextUtils.equals(resultStatus, PAY_CANCLE)) {//-------------------------->交易取消
Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();
} else if (TextUtils.equals(resultStatus, PAY_NET_ERR)) {//------------------------->網(wǎng)絡(luò)出現(xiàn)錯誤
Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();
} else if (TextUtils.equals(resultStatus, PAY_WAIT_CONFIRM)) {//--------------------->交替等待
}
break;
}
}
};
銀聯(lián)支付
先看一下官方給我們的銀聯(lián)支付流程圖:
大家不要被這張圖片搞懵逼的了析校,其實(shí)很簡單构罗,這里我將其分為5小步。
-
第一步:根據(jù)官方文檔選擇符合自己的sdk
官方文檔:
https://open.unionpay.com/ajweb/help/file/techFile?productId=3
-
第二步:將相對應(yīng)的.so文件copy到 自己的工程里面去智玻。
特別注意:
.so文件要放在src/main 目錄下遂唧,和Java文件并行。還有就是把用到的權(quán)限復(fù)制到自己項(xiàng)目中)
第三步: 和支付寶一樣吊奢,APP客戶端帶著這些訂單號向服務(wù)器后臺請求訂單號orderNo
第四步:服務(wù)器后臺接收到購買信息之后盖彭,將信息提交給銀聯(lián)后臺,銀聯(lián)接收到后臺之后給服務(wù)器返回tn號
-
第五步:開啟調(diào)用銀聯(lián)支付页滚。APP客戶端帶著這個流水號召边,也就是第三步中服務(wù)器返回的tn號,調(diào)用銀聯(lián)SDK所提供的方法
注意:
這個訂單流水號為21位純數(shù)字號
調(diào)用方法: UPPayAssistEx.startPay(this, null, null, tn, mMode);
結(jié)果返回:
處理銀聯(lián)手機(jī)支付控件返回的支付結(jié)果
調(diào)用銀聯(lián)支付后裹驰,返回app的時候用了隧熙,看返回結(jié)果傳,成功幻林,失敗贞盯,或者是什么返回音念。
如圖所示:
最后注意在調(diào)用:
/*****************************************************************
* mMode參數(shù)解釋: "00" - 啟動銀聯(lián)正式環(huán)境 "01" - 連接銀聯(lián)測試環(huán)境
*****************************************************************/
private final String mMode = "00";
注意:
tn值就是上面第三后臺給的tn,給到服務(wù)器那里躏敢,
這里我這邊是通過后臺請求下來的闷愤,關(guān)于mMode,看第一步驟件余,自己改一下就行了讥脐,00開發(fā)環(huán)境,01測試環(huán)境蛾扇。但是要注意攘烛,這個只是個回調(diào)接口方法。
****總感覺銀聯(lián)支付的SDK調(diào)用起來怪怪的镀首,貌似回到了原始深林。****
微信支付:
- 建議先參考我之前寫的 Android 微信支付總結(jié)的一篇博文:
微信支付總結(jié):
http://blog.csdn.net/androidstarjack/article/details/50951941
接入流程圖:
-
接入流程:
- 申請開發(fā)者賬號
地址:https://open.weixin.qq.com/
進(jìn)入管理中心鼠次,創(chuàng)建移動應(yīng)用 - 申請支付能力
- 代碼集成微信支付
- 申請開發(fā)者賬號
-
代碼集成微信支付
- 1.客戶端代碼得到用戶購買的商品信息更哄,將之傳給自己公司app服務(wù)器,參數(shù)包含但不限于以下:
HashMap<String ,String> params = getHeadMap();
params.put("appid", appID);// 微信appid腥寇,選擇性上傳成翩,服務(wù)器寫死亦可
params.put("money", money);// 支付金額,單位:分
params.put("goodName", goodsName);// 商品名稱
params.put("productNum", String.valueOf(12));// 商品的數(shù)量
- 2.app服務(wù)器調(diào)用微信“統(tǒng)一下單”接口赦役,得到prePayId訂單號并返回prePayId給手機(jī)客戶端麻敌;
3.手機(jī)客戶端使用prePayId及商品信息調(diào)起微信客戶端進(jìn)行支付;
3.1用戶操作:輸入密碼進(jìn)行支付掂摔;返回鍵取消支付术羔;網(wǎng)絡(luò)無連接支付失敗等;
4.微信客戶端回調(diào)支付結(jié)果給咱們的APP客戶端乙漓;
5.微信服務(wù)器異步通知咱們公司app服務(wù)器支付結(jié)果(服務(wù)器的工作级历,與客戶端無關(guān))
相關(guān)的支付調(diào)用代碼:
IWXAPI mWxApi = WXAPIFactory.createWXAPI(mContext, WX_APPID, true);
mWxApi.registerApp(WX_APPID);
/**
* 請求app服務(wù)器得到的回調(diào)結(jié)果
*/
@Override
public void onGet(JSONObject jsonObject) {
if (mWxApi != null) {
PayReq req = new PayReq();
req.appId = WX_APPID;// 微信開放平臺審核通過的應(yīng)用APPID
try {
req.partnerId = jsonObject.getString("partnerid");// 微信支付分配的商戶號
req.prepayId = jsonObject.getString("prepayid");// 預(yù)支付訂單號,app服務(wù)器調(diào)用“統(tǒng)一下單”接口獲取
req.nonceStr = jsonObject.getString("noncestr");// 隨機(jī)字符串叭披,不長于32位寥殖,服務(wù)器小哥會給咱生成
req.timeStamp = jsonObject.getString("timestamp");// 時間戳,app服務(wù)器小哥給出
req.packageValue = jsonObject.getString("package");// 固定值Sign=WXPay涩蜘,可以直接寫死嚼贡,服務(wù)器返回的也是這個固定值
req.sign = jsonObject.getString("sign");// 簽名,服務(wù)器小哥給出同诫,他會根據(jù):https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3指導(dǎo)得到這個
} catch (JSONException e) {
e.printStackTrace();
}
mWxApi.sendReq(req);
Log.d("發(fā)起微信支付申請");
}
}
注意事項(xiàng):
-
1.首先如果要使用微信支付的話
必須先到微信開放平臺注冊應(yīng)用粤策,具體地址為https://open.weixin.qq.com/
注冊時需要填應(yīng)用的包名和簽名,注意這里的簽名是App正式版的簽名剩辟,可以找一個已上線的包或打一個正式包掐场,使用微信提供的工具(簽名工具下載地址為https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk)來獲取往扔,獲取后填上即可。
待審核通過后熊户,會得到一個AppID和AppSecret萍膛,AppID分享和支付都要用到,AppSecret沒什么實(shí)際用途嚷堡,此時微信分享能力是直接擁有的蝗罗,支付能力還要額外申請,其中涉及到財(cái)務(wù)信息等
最好讓公司財(cái)務(wù)部門去申請蝌戒,申請成功后會拿到一個商戶id串塑,后面生成sign時會用到。
只有所有審核都通過后北苟,才可調(diào)用微信支付功能桩匪,這點(diǎn)是前提。
2.微信分享和微信支付SDK是同一個架包友鼻,名為libammsdk.jar傻昙。
3.官方開發(fā)文檔中有一處錯誤,需要注意下彩扔,如下圖最后一行參數(shù)req應(yīng)該為request妆档,照搬代碼的估計(jì)IDE也不會放過你,哈哈
4.測試微信支付時虫碉,務(wù)必對自己的App做正式簽名贾惦,因?yàn)橐婚_始就在微信平臺注冊過簽名信息,微信SDK會做校驗(yàn)敦捧,只有這樣才能調(diào)起微信分享和微信支付须板,直接debug版的包則絕對調(diào)不起來,這點(diǎn)務(wù)必注意绞惦,很多人是跌在這里了逼纸!當(dāng)初做微信分享曾遇到過,所以會很留心济蝉,也因?yàn)槿绱私芄簦绻⑿欧窒砟苷{(diào)起來,微信支付不行王滤,那就不要懷疑簽名問題了贺嫂。
5.還是簽名,網(wǎng)上有人說要注意大小寫雁乡,這點(diǎn)其實(shí)是不必的第喳。在微信開放平臺看到審核通過的App的簽名是大寫的,而用微信簽名獲取工具獲得的則顯示小寫踱稍,這個沒關(guān)系曲饱,不要貿(mào)然改動平臺注冊信息悠抹,不然又可能導(dǎo)致漫長的審核等待,上面也說了扩淀,微信分享如可以楔敌,那就不是簽名問題。
6.來說下官方demo驻谆,這東西害人不淺奥汛铡!很多人參考其寫法胜臊,如生成sign放在客戶端啊勺卢,調(diào)支付的Activity添加intent-filter啊,最主要的還是簽名問題象对。其實(shí)客戶端邏輯很簡單黑忱,直接上手集成即可,demo看看邏輯就行勒魔,照抄小心掉坑里杨何。
7.網(wǎng)上有人說需要給調(diào)用支付的Activity配置如下intent-filter(見下圖),可能也是被demo誤導(dǎo)了
8.對于errCode返回-1沥邻,有人說清除微信緩存或切換賬戶就好了,這種解決方案治標(biāo)不治本啊羊娃,根本不能算解決方案唐全。雖然我沒遇到能用這方法解決的問題,但目測是簽名的問題蕊玷,建議還得找到真正的問題所在邮利。
-
9.生成sign時特別需要注意:
- 首先將key-value鍵值對拼成字符串,注意key都要小寫垃帅,如appid,noncestr,package,partnerid,prepayid,timestamp,key,并且名字得按上述名稱
- 我們遇到的錯誤就是因?yàn)閜artnerid寫成了partnerId,prepayid寫成了PrepayId延届,當(dāng)然我們是在服務(wù)端寫的,如果在客戶端生成sign的話贸诚,也需要注意大小寫及名稱方庭,詳細(xì)信息請參考官方文檔。
- 還有這里的key并非AppID或AppSectet酱固,而是在商戶平臺設(shè)置的械念,官方描述為“key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設(shè)置-->API安全-->密鑰設(shè)置”。對于noncestr运悲,申請prepayid和生成sign時兩次需要用到龄减,由于iOS同事看到相關(guān)文章說noncestr前后需要一致,因此這個隨機(jī)字符串我們是設(shè)置成一樣的了班眯,這樣做Android平臺也是OK的希停,不過個人感覺這里可以不一致烁巫,由于這個邏輯在服務(wù)器端,我并沒有驗(yàn)證宠能,方便的同學(xué)可以驗(yàn)證下亚隙。
10.req.packageValue=”Sign=WXPay”,一般都是這樣寫死這個參數(shù)值棍潘。也有人說寫成req.packageValue=”prepay_id=” + prepayid恃鞋,經(jīng)測試Android兩種寫法都是可以調(diào)起微信支付的,至少最新版本SDK是可以的亦歉,以后則不清楚恤浪,官方也建議寫Sign=WXPay,據(jù)說iOS只支持這種寫法肴楷。
Android集成微信支付的出現(xiàn)-1等錯誤需要注意的要點(diǎn)
1.微信支付和支付寶支付是現(xiàn)在APP常用的支付方式,但是真正接入過兩種支付方式的猿友會很明顯的感覺到微信支付真心比支付寶麻煩很多,會出現(xiàn)很多莫名其妙的錯誤,但是官方的文檔卻很難給出較好的解決方案.
2.前幾天公司的APP需要支付功能然后也需要這個-1問題,簡直感覺微信支付喪心病狂,這里總結(jié)下自己出現(xiàn)的問題和一些其他網(wǎng)友出現(xiàn)的問題做個總結(jié)
****reso.errCode = -1 官方的描述: -1 錯誤 可能的原因:簽名錯誤水由、未注冊APPID、項(xiàng)目設(shè)置APPID不正確赛蔫、注冊的APPID與設(shè)置的不匹配砂客、其他異常等。****
1.簽名錯誤:
(1).簽名的參數(shù)集合沒有按照參數(shù)名ASCII碼從小到大排序(字典序)
(2).簽名的是時候漏了使用key,(key的由來可以看下面第三條的分析)
(3).簽名的KEY錯誤. 這里用來簽名的key是申請支付功能以后,微信給你的一個商戶賬號里面設(shè)置的.具體key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)–>賬戶設(shè)置–>API安全–>密鑰設(shè)置
(4).簽名后的key沒有進(jìn)行轉(zhuǎn)化成大寫或者其他例如前面的簽名參數(shù)先排好序最后才加上key(key字段不參與ASCII碼的大小排序,而是直接放到最后)
(5),還有一些其他的格式錯誤請參看官方文檔的詳細(xì)說明 微信官方的簽名說明,請認(rèn)真對比.
(6),簽名問題的終極大招—–使用官方的簽名認(rèn)證工具一一對比.注:最好在連接生成的key和最終MD5之后的結(jié)果 在log下打印出來,可以方便查看出錯的位置 接口調(diào)試工具
2.APPID錯誤
- (1)APPID是在open.weixin.qq.com上創(chuàng)建的應(yīng)用,可以通過 點(diǎn)擊管理中心–>應(yīng)用詳情 來查看APPID
- (2)創(chuàng)建APP時候上傳的證書與現(xiàn)在使用的不一致.商戶在微信開放平臺申請開發(fā)應(yīng)用后呵恢,微信開放平臺會生成APP的唯一標(biāo)識APPID鞠值。由于需要保證支付安全,需要在開放平臺綁定商戶應(yīng)用包名和應(yīng)用簽名渗钉,設(shè)置好后才能正常發(fā)起支付彤恶。設(shè)置界面在【開放平臺】中的欄目【 管理中心 –> 修改應(yīng)用 –> 修改開發(fā)信息】里面
應(yīng)用包名:是在APP項(xiàng)目配置文件AndroidManifest.xml中聲明的package值,例如DEMO中的package=”com.nmm.paydemo”鳄橘。
應(yīng)用簽名:根據(jù)項(xiàng)目的應(yīng)用包名和編譯使用的keystore声离,可由簽名工具生成一個32位的md5串,在調(diào)試的手機(jī)上安裝簽名工具后瘫怜,運(yùn)行可生成應(yīng)用簽名串术徊,如圖8.9所示,綠色串即應(yīng)用簽名鲸湃。簽名工具下載地址
對比查看應(yīng)用簽名是否一致,特別注意,一般上傳都是使用release版本的key所以在測試的時候就需要使用簽名版的apk,普通的debug版本key是不一致的
微信支付相關(guān)的demo地址:
https://github.com/androidstarjack/MyWxPayTest
以上是我之前做微信支付的時候的一些總結(jié)赠涮,今天再次拿出來供大家參考
之前的歷史文章:
支付寶植入總結(jié):
微信支付總結(jié):
版權(quán):首發(fā)于我的csdn博客:https://codegoogler.blog.csdn.net/article/details/72669394
最后照舊安利一波我們的公眾號:「終端研發(fā)部」,目前每天都會推薦一篇優(yōu)質(zhì)的技術(shù)相關(guān)的文章唤锉,主要分享java相關(guān)的技術(shù)與面試技巧世囊,我們的目標(biāo)是: 知道是什么,為什么窿祥,打好基礎(chǔ)株憾,做好每一點(diǎn)!這個主創(chuàng)技術(shù)公眾號超級值得大家關(guān)注。