IT之家8月9日消息 今天微軟發(fā)布了Win10 SDK Build 16257預(yù)覽版下載,與此同時(shí)微軟還推出了Win10 Mobile模擬器Build 15235。值得注意的是,Win10 SDK Build 16257已經(jīng)是功能完善版SDK,微軟后續(xù)只會(huì)修復(fù)Bug,提升穩(wěn)定性和可靠性等。
已知問題:
在Visual Studio中的Designer窗口中查看XAML時(shí),控件無法呈現(xiàn)。這可以通過使用Visual Studio 2017.3 Preview來解決。
在非Windows 10平臺上編譯失敗;
在此前的平臺上構(gòu)建應(yīng)用程序時(shí),可能會(huì)收到錯(cuò)誤。
Win10 SDK和模擬器下載:請點(diǎn)此鏈接。
想看到更多這類內(nèi)容?去APP商店搜IT之家,天天都有小歡喜。
聲明本篇博客為作者原創(chuàng),本篇是繼支付寶支付之后本人又學(xué)習(xí)的第二種支付實(shí)現(xiàn),本篇著重于原理與注意事項(xiàng)的學(xué)習(xí)。
微信支付的開發(fā)文檔相比支付寶的比較簡單,但是使用功能絲毫也不含糊,我覺得簡單易讀的文檔是吸引開發(fā)者做出喜好選擇的第一步。但是個(gè)人覺得,微信支付與支付寶的支付的實(shí)現(xiàn)思路大致雷同,并不能說是微信另開思路進(jìn)行支付創(chuàng)新。
微信支付的官方文檔中提供了掃碼支付、公眾號支付、App支付支付模式。開發(fā)者要實(shí)現(xiàn)用微信支付的功能,需要商戶向微信官方申請微信支付權(quán)限,商戶獲得權(quán)限后,將支付賬戶信息告訴開發(fā)者。
商戶申請的支付賬號信息表如下:
好了下面將要卻別兩個(gè)概念,什么是公眾號?什么是開放平臺?
參考公眾賬號就是面向企業(yè)、團(tuán)體、機(jī)構(gòu)、公司、政府等等的擁有一定運(yùn)營能力一個(gè)團(tuán)結(jié)的集合的公眾號,用來作為一個(gè)自媒體或者服務(wù)窗口來用,強(qiáng)調(diào)信息流。開放平臺是面向那些擁有成熟的應(yīng)用程序,能夠?qū)⑿畔⒎窒斫o社交圈子的一種偏向技術(shù)實(shí)現(xiàn)的平臺,是面向開發(fā)者來說。看看shareSDK中都能夠的一些社交平臺都是一種開放平臺。個(gè)人理解。
微信支付的模式有:(參考)刷卡支付、掃碼支付、公眾號支付、App支付
刷卡支付:(非驗(yàn)密支付)門店收銀臺生成訂單->用戶打開客戶端生成支付條碼->門店掃碼->后臺生成sign->后臺調(diào)用刷卡API請求支付->微信支付系統(tǒng)驗(yàn)證支付信息->通過驗(yàn)證處理數(shù)據(jù)->給商戶后臺->商戶后臺對得到的支付結(jié)果進(jìn)行簽名驗(yàn)證和處理->{處理成功:微信支付系統(tǒng)會(huì)將支付結(jié)果返回給商戶,同時(shí)把支付結(jié)果通知給用戶(以短信、微信消息的形式通知)}(驗(yàn)密支付)門店收銀臺生成訂單->向后臺發(fā)起支付請求->后臺調(diào)用【提交刷卡支付API】請求支付生成支付交易->微信支付系統(tǒng)驗(yàn)證請求支付信息驗(yàn)證->通過驗(yàn)證要求用戶輸入密碼->微信支付系統(tǒng)返回USERPAYING狀態(tài)->給商戶后臺返回收銀臺應(yīng)答結(jié)果->微支付系統(tǒng)通知用戶輸入密碼->用戶輸入密碼,提交微信支付,萬成支付->微信客戶端提示微信后臺返回在支付結(jié)果->用戶得到來自微信后臺的提示短息->商戶收銀臺得到USERPAYING狀態(tài)經(jīng)過商戶后臺調(diào)用【查詢訂單API】查詢實(shí)際支付結(jié)果->如果支付結(jié)果仍為USERPAYING,則每隔5秒循環(huán)調(diào)用【查詢訂單API】判斷實(shí)際支付結(jié)果,如果用戶取消支付或累計(jì)30秒用戶都未支付,商戶收銀臺退出查詢流程后繼續(xù)調(diào)用【撤銷訂單API】撤銷支付交易。
支付的異常處理:
用戶遇到支付異常,請按如下說明處理
(1)用戶微信端彈出系統(tǒng)錯(cuò)誤提示框,用戶可在交易列表查看交易情況,如果未找到訂單,需要商戶重新發(fā)起支付交易;如果訂單顯示成功支付,商戶收銀系統(tǒng)再次調(diào)用【查詢訂單API】查詢實(shí)際支付結(jié)果;
(2)用戶微信端彈出支付失敗提示,例如:余額不足,信用卡失效。需要重新發(fā)起支付;
(3)當(dāng)交易超時(shí)或支付交易失敗,商戶收銀系統(tǒng)必須調(diào)用【撤銷訂單API】,撤銷此交易。
(4)由于銀行系統(tǒng)異常、用戶余額不足、不支持用戶卡種等原因使當(dāng)前支付交易失敗,商戶收銀系統(tǒng)應(yīng)該把錯(cuò)誤提示明確展示給收銀員。
(5)根據(jù)返回的錯(cuò)誤碼,判斷是否需要撤銷交易,具體詳見API返回錯(cuò)誤碼列表
下面是微信支付的協(xié)議規(guī)則:
微信支付也要使用到簽名(加密)
關(guān)于簽名:
第一步生成簽名:
(1)生成簽名,在生成簽名之前,與支付寶的一樣,也是要將訂單的信心以URL鍵值對的格式即key1=value1&key2=value2…)拼接成字符串stringA。對于該鍵值對要進(jìn)行排序,按照(參數(shù)名ASII碼排序,就是第一個(gè)字母排序,如果首字母相同,就對第二個(gè)字母進(jìn)行排序,依次排序....)
(2)不對空的鍵值對進(jìn)行簽名,在準(zhǔn)備訂單信息的時(shí)候如出現(xiàn)空值,則該空值對應(yīng)的鍵不被簽名
(3)參數(shù)有大小寫之分,并且鍵 sign 不參與簽名
(4)如果訂單中除了微信給出的字段,又增添若干字段,
第二步得到臨時(shí)sign:
在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進(jìn)行MD5運(yùn)算,再將得到的字符串所有字符轉(zhuǎn)換為大寫,得到sign值signValue。
key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設(shè)置-->API安全-->密鑰設(shè)置
樣例參照官方文檔:參照如何使用在線簽名驗(yàn)證的操作:參照
在官方文檔中說明 “生成個(gè)隨機(jī)數(shù)算法” 有這樣一句話:字段nonce_str,主要保證簽名不可預(yù)測。我覺得這與支付寶中的:時(shí)間戳、隨機(jī)串都是要實(shí)現(xiàn)一樣的功能,增加簽名的復(fù)雜性與唯一性。微信這個(gè)nonce_str就相當(dāng)于支付寶的Order.h中聲明的時(shí)間戳屬性字段。
在微信中凡是涉及資金的接口都需要獲取商戶的證書。如:資金回滾、退款、撤銷接口。
關(guān)于商戶證書:參考就支付寶簽名要用到的公鑰與私鑰與微信的簽名機(jī)制比較,微信是采用的是證書機(jī)制,首先在商戶服務(wù)器上部署微信根證書,私鑰包含在證書里面,要想對訂單信息進(jìn)行簽名,就需要對證書進(jìn)行驗(yàn)證,由于根證書放在商戶的有訪問權(quán)限控制的非虛擬目錄中(防止非法下載,防止病毒木馬,他人非法盜取),所以不論是請求還是回調(diào)都要使用https安全的傳輸協(xié)議。
注意事項(xiàng):微信官方文檔建議商戶使用較高版本的微信SSL、建議在調(diào)用支付API時(shí),使用IPV4解析 參考
要使用微信支付前,必須要仔細(xì)閱讀官方文檔,要做到對上面的API的各種參數(shù)了解,明白怎么使用,也要注意文檔中的注意事項(xiàng)。
有可能官方的SDK會(huì)修改,文檔會(huì)變動(dòng),所以還是要及時(shí)關(guān)注官方的文檔去學(xué)習(xí)。在我的下一篇博客中我會(huì)去重點(diǎn)寫一下使用微信支付的SDK環(huán)境搭建,以及如何從微信的官方demo中抽出有用的組件到我們的工程中。關(guān)于主要的參數(shù)本篇不再贅述。
下面僅僅是模擬微信支付的實(shí)現(xiàn),因?yàn)槲⑿胖Ц妒窃谖⑿胚@個(gè)App中不存在調(diào)用網(wǎng)頁支付。所以本文不能看到支付的界面。
首先建立一個(gè)新的工程作為我們的工程,工程名字為weixin_study
使用故事版為其關(guān)聯(lián)一個(gè)支付的按鈕,按鈕名字為:weixinPay_Button
(1)注冊微信的開放平臺申請Appid 注冊
這里注冊的測試 Appid 是 “wx920fde9f97d60569”
在工程->info->URL Types 中作如下配置
(2)從官網(wǎng)得到的demo中取出名字為 “SDKExport” 的文件夾拖入我們的工程中
(2)在工程->Build Phases->Link Binary With Libraries 中引入下面組件
致此支付的環(huán)境已經(jīng)配置好了,下面實(shí)現(xiàn)支付的功能
我們模擬的訂單信息是:
{
"status": 200,
"message": "成功!",
"data": {
"payId": 14187,
"orderId": 16257,
"orderNo": "2016011215151844904636",
"amount": 300,
"name": "【內(nèi)飾清洗】微利天弘汽車美容裝飾",
"description": "微利天弘汽車美容裝飾 內(nèi)飾清洗服務(wù)",
"notifyUrl": "http://app.cheguchina.com/wash/weixinpay/mobilenotify",
"payType": 30,
"ip": "218.28.20.138",
"prepay": {
"appId": "wx920fde9f97d60569",
"partnerId": "1220277201",
"prepayId": "920103900011129271ad0485b2fa00",
"package": "Sign=WXPay",
"timeStamp": "1452582979",
"nonce": "xl27JbHJSLcs52tv",
"sign": "1f3da1f83f60cbda0f715e6b0b9a0241b790d4"
}
在Appdeleagate.m中注冊商戶App,,并導(dǎo)入相關(guān)頭文件
下面是主要的關(guān)鍵代碼:
#import "AppDelegate.h" #import "WXApi.h" #import "WXApiObject.h" @interface AppDelegate <WXApiDelegate> @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //1.AppID : 微信開發(fā)者平臺注冊后給的一個(gè)應(yīng)用標(biāo)示 //2.description : 沒什么用只是給開發(fā)者一種解釋的作用 [WXApi registerApp:@"wx920fde9f97d60569" withDescription:@"demo 2.0"]; return YES; } -(void)onResp:(BaseResp*)resp{ if ([resp isKindOfClass:[PayResp class]]){ PayResp *response=(PayResp*)resp; //通知中心傳值 [[NSNotificationCenter defaultCenter] postNotificationName:@"weixinzhifu" object:response]; } }
View Code Appdeleagate.m
#import "ViewController.h" #import "WXApi.h" #import "WXApiObject.h" @interface ViewController <WXApiDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (IBAction)wxAtcion:(id)sender { //微信支付方法 PayReq *request=[[PayReq alloc] init]; //** 商家向財(cái)付通申請的商家id */ request.partnerId=@"1220277201"; //預(yù)支付訂單 (包含商品的信息 如價(jià)格 : 標(biāo)題 , 描述 等信息) request.prepayId=@"8201038000160122a3971f85dc6f20d"; //商家根據(jù)財(cái)付通文檔填寫的數(shù)據(jù)和簽名 類似一種標(biāo)示 request.package=@"Sign=WXPay"; //隨機(jī)串 request.nonceStr=@"5xv1tGmFhe1cq5IZ"; //時(shí)間戳 (從1970年到現(xiàn)在的秒數(shù)) request.timeStamp=1452582950; //商家根據(jù)微信開放平臺文檔對數(shù)據(jù)做的簽名 (對數(shù)據(jù)的一種加密形勢) request.sign=@"0ac8963b331100acf5461e4d1ab726f7877912e"; //調(diào)用微信支付的方法 [WXApi sendReq:request]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //接受通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(weiXinPayBack:) name:@"weixinzhifu" object:nil]; } //通知中心觸發(fā)的方法 - (void)weiXinPayBack:(NSNotification *)notification { PayResp *response=notification.object; switch(response.errCode){ case WXSuccess: //服務(wù)器端查詢支付通知或查詢API返回的結(jié)果再提示成功 NSLog(@"支付成功"); break; default: NSLog(@"支付失敗,retcode=%d",response.errCode); break; } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[NSNotificationCenter debugDescription] removeObserver:self forKeyPath:@"weixinzhifu"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
View Code ViewController.m
這里已經(jīng)能夠完成實(shí)現(xiàn)支付了,如果數(shù)據(jù)是真正從服務(wù)器獲得的數(shù)據(jù)就可以查看到支付結(jié)果了。