• iOS应用之微信支付集成-直接前端集成


    所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单)。
    注:官方给的是v3&v4支付流程,签名和加密都是在服务器端进行,由于没有对接过,所以就暂时没有办法分享。

    1. 准备工作

    • 微信支付所需的相关用户信息(由用户申请)
    //微信支付商户号
     #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)。如下图:

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

    ios9之后让应用可以支持http请求

    bitcode配置

    2 . 在项目属性中的URL Types中添加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文件,本地对签名进行二次加密,如果忽略这个步骤,就会造成调起微信支付,只出现一个确定按钮。

    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));报警告,如下图:

    改为 srand( (unsigned)time(0) );

     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;
          }
      }
    }

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

    转载自:http://www.jianshu.com/p/94dcc220b2aa

     在AppDelegate.m中介绍微信支付成功和失败的回调,成功的时候通过通知的方式在相应的页面完成接下来的工作。

  • 相关阅读:
    nodejs获取服务器数据到页面
    Struts 2
    JQuery
    JDBC
    Hiberbate
    EasyUi
    JavaScript
    利用 HashSet 去过滤元素是否重复
    HTML
    MySQL
  • 原文地址:https://www.cnblogs.com/yipingios/p/5773625.html
Copyright © 2020-2023  润新知