扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
0.介绍预览
创新互联服务项目包括池州网站建设、池州网站制作、池州网页制作以及池州网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,池州网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到池州省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
针对需要在IOS手机上接入原生微信支付场景,调用微信进行支付。如图:
1.资料准备
1.1 账号注册
打开https://open.weixin.qq.com,注册微信开放平台开发者账号
1.2 开发者认证
登录,进入账号中心,进行开发者资质认证。
1.3 注册应用
认证完成后,进入管理中心,新建移动应用。填写应用资料,其中android版应用签名可通过扫码安装温馨提供的应用获得,详细参考微信文档。创建完成后点击查看,申请开通微信支付。一切准备就绪!
2.Java后台开发
添加依赖
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
生成统一订单
@RequestMapping(value="/pay/wxpay/params",produces="application/json;charset=utf-8") @ResponseBody public String signprams(HttpServletRequest request){ String res = "{code:404}"; try{ // 充值金额 String account = request.getParameter("account"); // 用户id String sid = request.getParameter("sid"); String subject = "订单标题"; String body = "订单描述"; int acc = (int) (Double.valueOf(account) * 100); String appid = "您的APPID"; String out_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 (Exception e){ e.printStackTrace(); res = "{code:500}"; } return res; } private SortedMap genOrderData(HttpServletRequest request, String subject, String body, int acc, String appid, String out_trade_no) throws IOException, ExecutionException, InterruptedException, XmlPullParserException { SortedMap paraMap = new TreeMap (); 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", "http://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"); String sign = createSign(paraMap); paraMap.put("sign", sign); // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String xml = getRequestXml(paraMap); String xmlStr = HttpKit.post(url, xml); // 预付商品id String prepay_id = ""; if (xmlStr.indexOf("SUCCESS") != -1) { Map map = WXRequestUtil.doXMLParse(xmlStr); prepay_id = (String) map.get("prepay_id"); } SortedMap payMap = new TreeMap (); 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()); String paySign = createSign(payMap); payMap.put("paySign", paySign); return payMap; } //请求xml组装 public static String getRequestXml(SortedMap parameters){ String sign = ""; StringBuffer sb = new StringBuffer(); sb.append(" "); Set es = parameters.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String key = (String)entry.getKey(); String value = (String)entry.getValue(); // if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) { // sb.append("<"+key+">"+value+""+key+">"); // } if ("sign".equalsIgnoreCase(key)){ sign = "<"+key+">"+value+""+key+">"; }else { sb.append("<"+key+">"+value+""+key+">"); } } sb.append(sign); sb.append(" "); return sb.toString(); } //生成签名 public String createSign(SortedMapparameters){ StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = 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()); String sign = MD5Utils.MD5Encode(sb.toString(),"UTF-8").toUpperCase(); return sign; } public String create_nonce_str() { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < 32; i++) { Random rd = new Random(); res += chars.charAt(rd.nextInt(chars.length() - 1)); } return res; }
3.IOS客户端开发
导入微信开发包
添加URL Types
在AppDelegate.m中注册应用
#import "AppDelegate.h" #import "XSTabBarViewController.h" #import#import "WXApi.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // [NSThread sleepForTimeInterval:2.0]; // 进入主控制器 self.window = [[UIWindow alloc] init]; self.window.frame = [UIScreen mainScreen].bounds; self.window.rootViewController = [[XSTabBarViewController alloc] init]; [self.window makeKeyAndVisible]; //向微信注册应用。 [WXApi registerApp:@"wxfb96c2a9b531be26"]; return YES; } -(void) onResp:(BaseResp*)resp { // NSLog(@" ----onResp %@",resp); /* ErrCode ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消) code 用户换取access_token的code,仅在ErrCode为0时有效 state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K lang 微信客户端当前语言 country 微信用户当前国家信息 */ if ([resp isKindOfClass:[SendAuthResp class]]) //判断是否为授权请求,否则与微信支付等功能发生冲突 { SendAuthResp *aresp = (SendAuthResp *)resp; if (aresp.errCode== 0) { // NSLog(@"code %@",aresp.code); [[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidLoginNotification" object:self userInfo:@{@"code":aresp.code}]; } }else{ // 支付请求回调 //支付返回结果,实际支付结果需要去微信服务器端查询 NSString *strMsg = [NSString stringWithFormat:@"支付结果"]; NSString *respcode = @"0"; switch (resp.errCode) { case WXSuccess: strMsg = @"支付结果:成功!"; // NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode); respcode = @"1"; break; default: strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr]; // NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr); respcode = @"0"; break; } [[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidPayNotification" object:self userInfo:@{@"respcode":respcode}]; } } //iOS 9.0 之前的处理方法不保证正确,如有错误还望指正 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { NSLog(@"iOS 9.0 之前"); return [self applicationOpenURL:url]; } -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { NSLog(@"iOS 9.0 之后"); return [self applicationOpenURL:url]; } - (BOOL)applicationOpenURL:(NSURL *)url { if([[url absoluteString] rangeOfString:@"wxfb96c2a9b531be26://pay"].location == 0){ return [WXApi handleOpenURL:url delegate:self]; } if ([url.host isEqualToString:@"safepay"]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:nil]; return YES; } return YES; } }
在需要支付的Controller中接受微信支付通知
- (void)viewDidLoad { [super viewDidLoad]; // 接受微信支付通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wechatDidPayNotification:) name:@"wechatDidPayNotification" object:nil]; }
向服务器端获取统一订单,并拉起微信进行支付
-(void)weixinPay { NSString *userUrlStr = [NSString stringWithFormat:@"%@?sid=%@&account=%@&desc=%@", WX_PREPAY_URL, self.student.sid,self.payJinE,self.student.nid]; NSURL *url = [NSURL URLWithString:userUrlStr]; // NSLog(@"userUrlStr = %@", userUrlStr); NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request]; [MBProgressHUD showMessage:@"跳转中,请稍候"]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) { [MBProgressHUD hideHUD]; // NSLog(@"微信支付的response = %@", operation.responseString); NSData *JSONData = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *userDict = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:nil]; // 调用微信支付 PayReq *request = [[PayReq alloc] init]; /** 商家向财付通申请的商家id */ request.partnerId = [userDict objectForKey:@"partnerid"]; /** 预支付订单 */ request.prepayId= [userDict objectForKey:@"prepayid"]; /** 商家根据财付通文档填写的数据和签名 */ request.package = [userDict objectForKey:@"package"]; /** 随机串,防重发 */ request.nonceStr= [userDict objectForKey:@"noncestr"]; /** 时间戳,防重发 */ request.timeStamp= [[userDict objectForKey:@"timestamp"] intValue]; /** 商家根据微信开放平台文档对数据做的签名 */ request.sign= [userDict objectForKey:@"sign"]; self.sign = request.sign; self.ordnum = [userDict objectForKey:@"ordnum"]; [WXApi sendReq: request]; }failure:^(AFHTTPRequestOperation *operation, NSError *error) { [MBProgressHUD hideHUD]; NSLog(@"发生错误!%@",error); }]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperation:operation]; } // 微信支付结果 -(void)wechatDidPayNotification:(NSNotification *)notification { // NSLog(@"wechatDidPayNotification"); NSDictionary *nameDictionary = [notification userInfo]; NSString *respcode = [nameDictionary objectForKey:@"respcode"]; if([respcode isEqualToString:@"1"]){ // 支付成功,更新用户信息 [self payDidFinish]; }else{ // 支付失败, [self setupAlertControllerWithTitle:@"微信支付结果" messge:@"本次支付未完成,您可以稍后重试!" confirm:@"好的"]; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流