京東支付沒有現成的SDK, 使用的是加載html。因此,在集成京東支付的時候,我們使用webView來進行加載顯示支付的頁面。
京東支付需要傳遞多個參數才能拉起支付頁面,那麼我們怎麼樣獲得和傳遞參數呢?
1.我們需要與自己的後台進行交互,通過網絡請求,獲取到拉起支付頁面所需要的參數,並將參數解析成字符串進行保存。
2.在選擇京東支付方式之後, 跳轉到一個由Viewcontroller控制webView的場景下,將webView的delegate指向當前的ViewController。將獲取到的參數, 通過網絡請求傳遞給京東的後台進行驗證,京東後台及html頁面地址為 : https://m.jdpay.com/wepay/web/pay
在viewDidLoad方法中調用如下方法:
-(void)viewDidLoad {
//通過AFN向京東發送參數並進行驗證,並獲取支付的html路徑
[selfloadTheJDRequest];
}
-(void)loadTheJDRequest {
ShowIndicatorWithMessage(@"正在跳轉請稍後");
NSMutableDictionary *formDic = [[NSMutableDictionaryalloc]init];
[formDic setObject:self.getDic[@"successCallbackUrl"] ? self.getDic[@"successCallbackUrl"] :@""forKey:@"successCallbackUrl"];
[formDic setObject:self.getDic[@"tradeDescription"] ? self.getDic[@"tradeDescription"] :@""forKey:@"tradeDescription"];
[formDic setObject:self.getDic[@"tradeTime"] ? self.getDic[@"tradeTime"] :@""forKey:@"tradeTime"];
[formDic setObject:self.getDic[@"tradeNum"] ? self.getDic[@"tradeNum"] :@""forKey:@"tradeNum"];
[formDic setObject:self.getDic[@"tradeName"] ? self.getDic[@"tradeName"] :@""forKey:@"tradeName"];
[formDic setObject:self.getDic[@"merchantRemark"] ? self.getDic[@"merchantRemark"] :@""forKey:@"merchantRemark"];
[formDic setObject:self.getDic[@"version"] ? self.getDic[@"version"] :@""forKey:@"version"];
[formDic setObject:self.getDic[@"currency"] ? self.getDic[@"currency"] :@""forKey:@"currency"];
[formDic setObject:self.getDic[@"merchantSign"] ? self.getDic[@"merchantSign"] :@""forKey:@"merchantSign"];
//獲取本地保存的token值
NSString *JDToken = [[NSUserDefaultsstandardUserDefaults]objectForKey:@"JDTOKEN"];
NSLog(@"-------------%@",JDToken);
[formDic setObject:JDToken ? JDToken :@""forKey:@"token"];
[formDic setObject:self.getDic[@"tradeAmount"] ? self.getDic[@"tradeAmount"] :@""forKey:@"tradeAmount"];
[formDic setObject:self.getDic[@"notifyUrl"] ? self.getDic[@"notifyUrl"] :@""forKey:@"notifyUrl"];
[formDic setObject:self.getDic[@"merchantNum"] ? self.getDic[@"merchantNum"] :@""forKey:@"merchantNum"];
[formDic setObject:self.getDic[@"failCallbackUrl"] ? self.getDic[@"failCallbackUrl"] :@""forKey:@"failCallbackUrl"];
//通過AFN提交參數
AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManagermanager];
manager.responseSerializer.acceptableContentTypes=[NSSetsetWithObjects:@"text/html",@"text/javascript",nil];
manager.responseSerializer=[AFHTTPResponseSerializerserializer];
[manager POST:self.getDic[@"jdReqUrl"]parameters:formDicsuccess:^(AFHTTPRequestOperation *operation,id responseObject) {
NSString *htmlstring=[[NSStringalloc]initWithData:responseObjectencoding:NSUTF8StringEncoding];
//將第二次請求出來的html字符串加載到webview
[self.chargeWebViewloadHTMLString:htmlstringbaseURL:[NSURLURLWithString:self.getDic[@"jdReqUrl"]]];
} failure:^(AFHTTPRequestOperation *operation,NSError *error) {
}];
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
ShowTips(@"數據加載出錯啦!");
}
-(void)viewWillDisappear:(BOOL)animated {
[superviewWillDisappear:animated];
HideIndicator();
}
3.根據回調進行判斷是否支付成功, 回調地址中包含token字段及其信息, 則表示支付成功,否則支付失敗。 此處的token值獲取到之後, 保存在本地, 在步驟2中向京東發送參數時, token不為空時,拉起的支付頁面顯示帶有銀行卡的界面, 若token為空時, 則顯示京東的登錄界面。
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"============%@",request.URL);
if ([request.URL.absoluteStringrangeOfString:@"call_back_url"].location !=NSNotFound) {
if ([request.URL.absoluteStringrangeOfString:@"token"].location !=NSNotFound) {
NSLog(@"-------------充值成功");
NSString *token = [[request.URL.absoluteStringcomponentsSeparatedByString:@"token="]lastObject];
NSString *gettoken = [[tokencomponentsSeparatedByString:@"&"]firstObject];
NSLog(@"-------------%@",gettoken);
[[NSUserDefaultsstandardUserDefaults]setObject:gettoken forKey:@"JDTOKEN"];
[[NSUserDefaultsstandardUserDefaults]synchronize];
[self.navigationControllerpopToViewController:self.navigationController.viewControllers[self.navigationController.viewControllers.count - 3] animated:YES];
} else {
NSLog(@"-------------充值失敗");
UIAlertView *alt=[[UIAlertViewalloc]initWithTitle:@"支付失敗"message:nildelegate:selfcancelButtonTitle:@"稍後嘗試"otherButtonTitles:@"再次提交",nil];
alt.tag=1000;
[alt show];
}
}
returnYES;
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag ==1000) {
if (buttonIndex == alertView.cancelButtonIndex) {
[self.navigationControllerpopToViewController:self.navigationController.viewControllers[self.navigationController.viewControllers.count - 3] animated:YES];
} else {
[selfloadTheJDRequest];
}
}
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
HideIndicator();
}
5.注意事項:
(1)京東支付,每天只有五次支付機會,支付五次之後,會提示一些京東默認的錯誤信息及帶有錯誤信息的界面。
(2)首次與後台交互時,返回的token值必定為空,拉起之後進入登錄界面, 當支付成功之後,才會有token的信息在京東的回調地址中,此時前端或者後端截取之後保存到本地即可下次直接之用
(3)回調地址中包含token才表示成功, 否則失敗。