微信支付

简介:

1. 准备工作

  • 工程所需的微信支付SDK,如下图:

    1240

    导入工程的SDK文件

  • 微信支付所需的相关用户信息(由用户申请)

//微信支付商户号
 #define MCH_ID  @"YOUR_MCH_ID"//开户邮件中的(公众账号APPID或者应用APPID)#define WX_AppID @"YOUR_WX_AppID"//安全校验码(MD5)密钥,商户平台登录账户和密码登录http://pay.weixin.qq.com 平台设置的“API密钥”,为了安全,请设置为以数字和字母组成的32字符串。#define WX_PartnerKey @"YOUR_WX_PartnerKey"//获取用户openid,可使用APPID对应的公众平台登录http://mp.weixin.qq.com 的开发者中心获取AppSecret。#define WX_AppSecret @"YOUR_WX_AppSecret"

2. 集成开发流程

1 . iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes(跳转程序)列为白名单,才可正常检查其他应用是否安装(引自微信支付SDK1.6.2Readme.text)。如下图:

1240

info里面配置添加白名单


注:LSApplicationQueriesSchemes 下面其他的为友盟分享要添加的白名单,当然也包含微信。

2 . 在项目属性中的URL Types中添加URL Schemes,如图中标红位置所示。

1240

配置URL Schemes,用来进行程序之间的跳转

3 . 在项目工程Appdelegate.m文件里面添加注册微信支付信息,注:如果项目中第三方分享用的是友盟,在注册的时候要把友盟注册放在微信注册的前面执行。如下:

#pragma mark - 设置第三方 注册信息- (void)registerMethods {
/****************       友盟分享注册信息     *****************/
  [UMSocialData setAppKey:UMSocial_AppKey];

  //设置微信AppId、appSecret,分享url
  [UMSocialWechatHandler setWXAppId:WX_appID appSecret:WX_AppSecret url:@"http://www.umeng.com/social"];

  //设置手机QQ 的AppId,Appkey,和分享URL
  [UMSocialQQHandler setQQWithAppId:QQ_AppID appKey:QQ_AppKey url:@"http://www.umeng.com/social"];
  [UMSocialConfig hiddenNotInstallPlatforms:@[UMShareToQQ, UMShareToQzone, UMShareToWechatTimeline, UMShareToWechatTimeline]];

  //打开新浪微博的SSO开关,设置新浪微博回调地址,这里必须要和你在新浪微博后台设置的回调地址一致。
  // 添加SSO授权开关(使用微博原生SDK)
  [UMSocialSinaSSOHandler openNewSinaSSOWithAppKey:Sina_AppKey RedirectURL:@"http://sns.whalecloud.com/sina2/callback"];
  // 添加SSO授权开关(非微博原生SDK)
  [UMSocialSinaHandler openSSOWithRedirectURL:@"http://sns.whalecloud.com/sina2/callback"];
/****************       友盟分享注册信息     *****************/

  // 先调用友盟,然后调用微信清册信息
/****************       注册微信支付信息    *****************/
  [WXApi registerApp:WX_appID];
  // [WXApi registerApp:WX_appID withDescription:@"demo 2.0"];
  两个任选一行,还不清楚这个appdesc有何作用
}

4.配置DataMD5.m文件,本地对签名进行二次加密,如果忽略这个步骤,就会造成调起微信支付,只出现一个确定按钮。注:之前出现这个问题,被卡壳了两天才发现,FK。

1240

配置MD5加密文件,添加商户密钥

5 . 在要唤起微信支付的.m文件中,直接上代码方便ctrl+c, ctrl+v

#pragma mark - 微信支付相关方法- (void)weixinChooseAct {  NSString *appid,*mch_id,*nonce_str,*sign,*body,*out_trade_no,*total_fee,*spbill_create_ip,*notify_url,*trade_type,*partner;  //应用APPID
  appid = WX_appID;  //微信支付商户号
  mch_id = MCH_ID;  //产生随机字符串,这里最好使用和安卓端一致的生成逻辑
  nonce_str =[self generateTradeNO];
  body =@"微信支付时候看到的支付信息";  //随机产生订单号用于测试,正式使用请换成你从自己服务器获取的订单号
  out_trade_no = self.gold_sn;  //交易价格1表示0.01元,10表示0.1元
  total_fee = self.payCount;  //获取本机IP地址,请再wifi环境下测试,否则获取的ip地址为error,正确格式应该是8.8.8.8
  spbill_create_ip =[getIPhoneIP getIPAddress];  //交易结果通知网站此处用于测试,随意填写,正式使用时填写正确网站
  notify_url =@"www.cccuu.com";
  trade_type =@"APP";  //商户密钥
  partner = WX_partnerKey;  //获取sign签名
  DataMD5 *data = [[DataMD5 alloc] initWithAppid:appid mch_id:mch_id nonce_str:nonce_str partner_id:partner body:body out_trade_no:out_trade_no total_fee:total_fee spbill_create_ip:spbill_create_ip notify_url:notify_url trade_type:trade_type];
  sign = [data getSignForMD5];  //设置参数并转化成xml格式
  NSMutableDictionary *dic = [NSMutableDictionary dictionary];
  [dic setValue:appid forKey:@"appid"];//公众账号ID
  [dic setValue:mch_id forKey:@"mch_id"];//商户号
  [dic setValue:nonce_str forKey:@"nonce_str"];//随机字符串
  [dic setValue:sign forKey:@"sign"];//签名
  [dic setValue:body forKey:@"body"];//商品描述
  [dic setValue:out_trade_no forKey:@"out_trade_no"];//订单号
  [dic setValue:total_fee forKey:@"total_fee"];//金额
  [dic setValue:spbill_create_ip forKey:@"spbill_create_ip"];//终端IP
  [dic setValue:notify_url forKey:@"notify_url"];//通知地址
  [dic setValue:trade_type forKey:@"trade_type"];//交易类型
  // 转换成xml字符串
  NSString *string = [dic XMLString];
  [self http:string];
}#pragma mark - 拿到转换好的xml发送请求- (void)http:(NSString *)xml {
  [MBProgressHUD showMessage:@"正在获取支付订单..."];
  AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];  //这里传入的xml字符串只是形似xml,但是不是正确是xml格式,需要使用af方法进行转义
  manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
  [manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"];
  [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {        return xml;
  }];  //发起请求
  [manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml success:^(AFHTTPRequestOperation *operation, id responseObject) {      NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ;      // LXLog(@"responseString is %@",responseString);
      //将微信返回的xml数据解析转义成字典
      NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];      //判断返回的许可
      if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) {          //发起微信支付,设置参数
          PayReq *request = [[PayReq alloc] init];
          request.openID = [dic objectForKey:@"appid"];
          request.partnerId = [dic objectForKey:@"mch_id"];
          request.prepayId= [dic objectForKey:@"prepay_id"];
          request.package = @"Sign=WXPay";
          request.nonceStr= [dic objectForKey:@"nonce_str"];          //将当前事件转化成时间戳
          NSDate *datenow = [NSDate date];          NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];          UInt32 timeStamp =[timeSp intValue];
          request.timeStamp= timeStamp;          // 签名加密
          DataMD5 *md5 = [[DataMD5 alloc] init];
          request.sign=[md5 createMD5SingForPay:request.openID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];          // 调用微信
          [WXApi sendReq:request];
          [MBProgressHUD hideHUD];
      }else{
          LXLog(@"参数不正确,请检查参数");
          [MBProgressHUD hideHUD];
          [MBProgressHUD showError:@"支付错误!"];
      }
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      LXLog(@"error is %@",error);
      [MBProgressHUD hideHUD];
      [MBProgressHUD showError:@"未完成支付"];
  }];
}#pragma mark - 产生随机订单号- (NSString *)generateTradeNO {  static int kNumber = 15;  NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";  NSMutableString *resultStr = [[NSMutableString alloc] init];
  srand(time(0)); // 此行代码有警告: 
  for (int i = 0; i < kNumber; i++) {      unsigned index = rand() % [sourceStr length];      NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
      [resultStr appendString:oneStr];
  }  return resultStr;
}

注:上面 stand(time(0));报警告,如下图:

1240

类型不匹配,不知道应该怎么改,有知道的下方赐教

6 . 最后在Appdelegate.m文件中添加微信支付结果 onResp 回调方法,非常重要:给后台发送数据进行后台数据的更新(例如:充值浩方Vip会员,微信钱包钱已经扣了,而后台没有收到信息,钱不就白花了 - - 、),如下:

#pragma mark - WXApiDelegate-(void)onResp:(BaseResp *)resp {  if ([resp isKindOfClass:[PayResp class]]) {
      PayResp*response=(PayResp*)resp;  // 微信终端返回给第三方的关于支付结果的结构体
      switch (response.errCode) {          case WXSuccess:
          {// 支付成功,向后台发送消息
              LXLog(@"支付成功");
              [[NSNotificationCenter defaultCenter] postNotificationName:@"WX_PaySuccess" object:nil];
        }              break;          case WXErrCodeCommon:
          { //签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
              [MBProgressHUD showError:@"支付失败"];
              LXLog(@"支付失败");
        }              break;          case WXErrCodeUserCancel:
          { //用户点击取消并返回
              LXLog(@"取消支付");
              [MBProgressHUD showError:@"取消支付"];
          }              break;          case WXErrCodeSentFail:
          { //发送失败
              LXLog(@"发送失败");
              [MBProgressHUD showError:@"发送失败"];
          }              break;          case WXErrCodeUnsupport:
          { //微信不支持
              LXLog(@"微信不支持");
              [MBProgressHUD showError:@"微信不支持"];
          }              break;          case WXErrCodeAuthDeny:
          { //授权失败
              LXLog(@"授权失败");
              [MBProgressHUD showError:@"授权失败"];
          }              break;          default:              break;
      }
  }
}

到此结束,忘能正常唤起微信支付。

3. 总结

  1. 按照官方Demo来看,加密证书之类的操作也是在服务器端完成,这样商户的信息就不会暴露在前端,才能达到 "TA好,我也好"。 ps:此方法本人没有做过,以和后台司马同学商量过,后期整理出来 

  2. 第一次用MarkDown记录,感觉自己用着好笨,对于代码部分的应用非常不得手,多多练习。

  3. 银联支付集成,待续。










本文转自 卓行天下  51CTO博客,原文链接:http://blog.51cto.com/9951038/1759089,如需转载请自行联系原作者
目录
相关文章
|
XML 移动开发 API
微信支付开发(7) H5支付
关键字:微信支付 微信支付v3 H5支付 wap支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3_h5.html    本文介绍微信支付下的H5支付实现流程。
2849 0
|
8月前
|
安全 Java API
支付宝支付接口遇到的问题总结
支付宝支付接口遇到的问题总结
|
8月前
|
安全 算法 小程序
从零玩转系列之微信支付安全
从零玩转系列之微信支付安全
64 0
从零玩转系列之微信支付安全
|
XML 前端开发 Dubbo
微信支付的两种模式,扫码支付
微信支付的两种模式,扫码支付
839 0
|
机器学习/深度学习
关于支付宝/微信免签实现个人支付
最近一直在了解关于个人支付的问题。由于之前一直想实现个人支付,但是目前微信和支付宝的支付接口都需要企业或个体户资质,导致没办法实现,无奈只能走向这个道路。 说是免签,实际上就是拿到收款金额来做些事情。
关于支付宝/微信免签实现个人支付
|
XML Java 数据格式
关于微信支付和支付宝支付java实现
目前支付宝支付和微信支付是算是目前app的标配了 支付宝支付在更新过后有了官方专门的sdk和demo,所以相对而言比较简单,而微信支付稍微复杂一点,下面的文章会附实例代码,微信支付也是参考的github上的某位大神级人物的代码。
1145 0
微信支付(销客多)配置
1、后台各种参数要配置对了。 2、公众号:3个地方填写的域名要配置对了。 3、pay站点: 支付目录:填写2个, xxx域名.com/pay/  和  xxx域名.com/Pay/    ,这2个的差距就是p有大写和小写。
984 0
|
Web App开发 移动开发 前端开发
微信H5支付
本篇文件来聊聊微信服务商模式以及商户模式下微信H5支付 先说一个事情。8月1号开始微信公众平台支付的开发配置页面迁移至商户平台 详细说明参考这个或者看下面的截图 官方文档 普通商户版-微信H5支付 服务商版-微信H5支付 1、申请开通微信H5支付 服务商模式下点击申请开通会立即开通,邀请子商户时需要填写子商户的信息。
4413 0