APP支付:IOS手機端+java後台版,appios
APP支付(IOS手機端+java後台)版0.介紹預覽
針對需要在IOS手機上接入原生支付情境,調用進行支付。
1.資料準備
1.1帳號註冊
1.2開發人員認證
登入,進入帳號中心,進行開發人員資質認證。
1.3註冊應用
認證完成後,進入管理中心,建立行動裝置 App。填寫應用資料,其中android版應用簽名可通過掃碼安裝溫馨提供的應用獲得,詳細參考文檔。建立完成後點擊查看,申請開通支付。一切準備就緒!
2.
Java後台開發
添加依賴
[html]view plaincopy
print?
org.xmlpull
xmlpull
1.1.3.1
net.sf.json-lib
json-lib
2.3
jdk15
com.thoughtworks.xstream
xstream
1.4.5
com.ning
async-http-client
1.8.13
產生統一訂單
[java]view plaincopy
print?
@RequestMapping(value="/pay/wxpay/params",produces="application/json;charset=utf-8")
@ResponseBody
publicStringsignprams(HttpServletRequestrequest){
Stringres="{code:404}";
try{
//儲值金額
Stringaccount=request.getParameter("account");
//使用者id
Stringsid=request.getParameter("sid");
Stringsubject="訂單標題";
Stringbody="訂單描述";
intacc=(int)(Double.valueOf(account)*100);
Stringappid="您的APPID";
Stringout_trade_no="產生您的訂單號";
//產生訂單資料
SortedMappayMap=genOrderData(request,subject,body,acc,appid,out_trade_no);
savePayLog(out_trade_no,account,sid,body,payMap.get("paySign"),nid,2);
//4.返回資料
res=buildPayRes(payMap,out_trade_no);
}catch(Exceptione){
e.printStackTrace();
res="{code:500}";
}
returnres;
}
privateSortedMapgenOrderData(HttpServletRequestrequest,Stringsubject,Stringbody,
intacc,Stringappid,Stringout_trade_no)
throwsIOException,ExecutionException,InterruptedException,XmlPullParserException{
SortedMapparaMap=newTreeMap();
paraMap.put("appid",appid);
paraMap.put("attach",subject);
paraMap.put("body",body);
paraMap.put("mch_id","您的商戶id,到商戶平台查看");
paraMap.put("nonce_str",create_nonce_str());
paraMap.put("notify_url","https://pay.xxxxx.com/pay/wxpay/notify.htm");//此路徑是伺服器調用支付結果通知路徑
paraMap.put("out_trade_no",out_trade_no);
paraMap.put("spbill_create_ip",request.getRemoteAddr());
paraMap.put("total_fee",acc+"");
paraMap.put("trade_type","APP");
Stringsign=createSign(paraMap);
paraMap.put("sign",sign);
//統一下單https://api.mch.weixin.qq.com/pay/unifiedorder
Stringurl="https://api.mch.weixin.qq.com/pay/unifiedorder";
Stringxml=getRequestXml(paraMap);
StringxmlStr=HttpKit.post(url,xml);
//預付商品id
Stringprepay_id="";
if(xmlStr.indexOf("SUCCESS")!=-1){
Mapmap=WXRequestUtil.doXMLParse(xmlStr);
prepay_id=(String)map.get("prepay_id");
}
SortedMappayMap=newTreeMap();
payMap.put("appid",appid);
payMap.put("partnerid","您的商戶id,到商戶平台查看");
payMap.put("prepayid",prepay_id);
payMap.put("package","Sign=WXPay");
payMap.put("noncestr",create_nonce_str());
payMap.put("timestamp",WXRequestUtil.create_timestamp());
StringpaySign=createSign(payMap);
payMap.put("paySign",paySign);
returnpayMap;
}
//請求xml組裝
publicstaticStringgetRequestXml(SortedMapparameters){
Stringsign="";
StringBuffersb=newStringBuffer();
sb.append("
Setes=parameters.entrySet();
Iteratorit=es.iterator();
while(it.hasNext()){
Map.Entryentry=(Map.Entry)it.next();
Stringkey=(String)entry.getKey();
Stringvalue=(String)entry.getValue();
//if("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)){
//sb.append("<"+key+">"+value+"");
//}
if("sign".equalsIgnoreCase(key)){
sign="<"+key+">"+value+"";
}else{
sb.append("<"+key+">"+value+"");
}
}
sb.append(sign);
sb.append("");
returnsb.toString();
}
//產生簽名
publicStringcreateSign(SortedMapparameters){
StringBuffersb=newStringBuffer();
Setes=parameters.entrySet();
Iteratorit=es.iterator();
while(it.hasNext()){
Map.Entryentry=(Map.Entry)it.next();
Stringk=(String)entry.getKey();
Objectv=entry.getValue();
if(null!=v&&!"".equals(v)
&&!"sign".equals(k)&&!"key".equals(k)){
sb.append(k+"="+v+"&");
}
}
sb.append("key="+WXConfig.APP_PERTNER_KEY);
System.out.println(sb.toString());
Stringsign=MD5Utils.MD5Encode(sb.toString(),"UTF-8").toUpperCase();
returnsign;
}
publicStringcreate_nonce_str(){
Stringchars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Stringres="";
for(inti=0;i<32;i++){
Randomrd=newRandom();
res+=chars.charAt(rd.nextInt(chars.length()-1));
}
returnres;
}
3.IOS用戶端開發
匯入開發包
添加URL Types
在AppDelegate.m中註冊應用
[objc]view plaincopy
print?
#import"AppDelegate.h"
#import"XSTabBarViewController.h"
#import
#import"WXApi.h"
@interfaceAppDelegate()
@end
@implementationAppDelegate
-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{
//Overridepointforcustomizationafterapplicationlaunch.
//[NSThreadsleepForTimeInterval:2.0];
//進入主控制器
self.window=[[UIWindowalloc]init];
self.window.frame=[UIScreenmainScreen].bounds;
self.window.rootViewController=[[XSTabBarViewControlleralloc]init];
[self.windowmakeKeyAndVisible];
//向註冊應用。
[WXApiregisterApp:@"wxfb96c2a9b531be26"];
returnYES;
}
-(void)onResp:(BaseResp*)resp
{
//NSLog(@"----onResp%@",resp);
/*
ErrCodeERR_OK=0(使用者同意)
ERR_AUTH_DENIED=-4(使用者拒絕授權)
ERR_USER_CANCEL=-2(使用者取消)
code使用者換取access_token的code,僅在ErrCode為0時有效
state第三方程式發送時用來標識其請求的唯一性的標誌,由第三方程式調用sendReq時傳入,由終端回傳,state字串長度不能超過1K
lang用戶端當前語言
country使用者當前國家資訊
*/
if([respisKindOfClass:[SendAuthRespclass]])//判斷是否為授權請求,否則與支付等功能發生衝突
{
SendAuthResp*aresp=(SendAuthResp*)resp;
if(aresp.errCode==0)
{
//NSLog(@"code%@",aresp.code);
[[NSNotificationCenterdefaultCenter]postNotificationName:@"wechatDidLoginNotification"object:selfuserInfo:@{@"code":aresp.code}];
}
}else{//支付請求回調
//支付返回結果,實際支付結果需要去伺服器端查詢
NSString*strMsg=[NSStringstringWithFormat:@"支付結果"];
NSString*respcode=@"0";
switch(resp.errCode){
caseWXSuccess:
strMsg=@"支付結果:成功!";
//NSLog(@"支付成功-PaySuccess,retcode=%d",resp.errCode);
respcode=@"1";
break;
default:
strMsg=[NSStringstringWithFormat:@"支付結果:失敗!retcode=%d,retstr=%@",resp.errCode,resp.errStr];
//NSLog(@"錯誤,retcode=%d,retstr=%@",resp.errCode,resp.errStr);
respcode=@"0";
break;
}
[[NSNotificationCenterdefaultCenter]postNotificationName:@"wechatDidPayNotification"object:selfuserInfo:@{@"respcode":respcode}];
}
}
//iOS9.0之前的處理方法不保證正確,如有錯誤還望指正
-(BOOL)application:(UIApplication*)applicationopenURL:(NSURL*)urlsourceApplication:(NSString*)sourceApplicationannotation:(id)annotation
{
NSLog(@"iOS9.0之前");
return[selfapplicationOpenURL:url];
}
-(BOOL)application:(UIApplication*)appopenURL:(NSURL*)urloptions:(NSDictionary*)options{
NSLog(@"iOS9.0之後");
return[selfapplicationOpenURL:url];
}
-(BOOL)applicationOpenURL:(NSURL*)url
{
if([[urlabsoluteString]rangeOfString:@"wxfb96c2a9b531be26://pay"].location==0){
return[WXApihandleOpenURL:urldelegate:self];
}
if([url.hostisEqualToString:@"safepay"])
{
[[AlipaySDKdefaultService]processOrderWithPaymentResult:urlstandbyCallback:nil];
returnYES;
}
returnYES;
}
}
在需要支付的Controller中接受支付通知
[objc]view plaincopy
print?
-(void)viewDidLoad{
[superviewDidLoad];
//接受支付通知
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(wechatDidPayNotification:)name:@"wechatDidPayNotification"object:nil];
}
向伺服器端擷取統一訂單,並拉起進行支付
[objc]view plaincopy
print?
-(void)weixinPay
{
NSString*userUrlStr=[NSStringstringWithFormat:@"%@?sid=%@&account=%@&desc=%@",WX_PREPAY_URL,self.student.sid,self.payJinE,self.student.nid];
NSURL*url=[NSURLURLWithString:userUrlStr];
//NSLog(@"userUrlStr=%@",userUrlStr);
NSURLRequest*request=[NSURLRequestrequestWithURL:url];
AFHTTPRequestOperation*operation=[[AFHTTPRequestOperationalloc]initWithRequest:request];
[MBProgressHUDshowMessage:@"跳轉中,請稍候"];
[operationsetCompletionBlockWithSuccess:^(AFHTTPRequestOperation*operation,NSDictionary*responseObject){
[MBProgressHUDhideHUD];
//NSLog(@"支付的response=%@",operation.responseString);
NSData*JSONData=[operation.responseStringdataUsingEncoding:NSUTF8StringEncoding];
NSDictionary*userDict=[NSJSONSerializationJSONObjectWithData:JSONDataoptions:NSJSONReadingMutableLeaveserror:nil];
//調用支付
PayReq*request=[[PayReqalloc]init];
/**商家向財付通申請的商家id*/
request.partnerId=[userDictobjectForKey:@"partnerid"];
/**預支付訂單*/
request.prepayId=[userDictobjectForKey:@"prepayid"];
/**商家根據財付通文檔填寫的資料和簽名*/
request.package=[userDictobjectForKey:@"package"];
/**隨機串,防重發*/
request.nonceStr=[userDictobjectForKey:@"noncestr"];
/**時間戳記,防重發*/
request.timeStamp=[[userDictobjectForKey:@"timestamp"]intValue];
/**商家根據開放平台文檔對資料做的簽名*/
request.sign=[userDictobjectForKey:@"sign"];
self.sign=request.sign;
self.ordnum=[userDictobjectForKey:@"ordnum"];
[WXApisendReq:request];
}failure:^(AFHTTPRequestOperation*operation,NSError*error){
[MBProgressHUDhideHUD];
NSLog(@"發生錯誤!%@",error);
}];
NSOperationQueue*queue=[[NSOperationQueuealloc]init];
[queueaddOperation:operation];
}
//支付結果
-(void)wechatDidPayNotification:(NSNotification*)notification
{
//NSLog(@"wechatDidPayNotification");
NSDictionary*nameDictionary=[notificationuserInfo];
NSString*respcode=[nameDictionaryobjectForKey:@"respcode"];
if([respcodeisEqualToString:@"1"]){
//支付成功,更新使用者資訊
[selfpayDidFinish];
}else{
//支付失敗,
[selfsetupAlertControllerWithTitle:@"支付結果"messge:@"本次支付未完成,您可以稍後重試!"confirm:@"好的"];
}
}