iOS 不用微信 SDK 唤起微信支付

Lou4523 8年前
   <h2><strong>要想知道微信SDK是如何调起微信客户端,那么咱们先看看微信SDK到底做了什么</strong></h2>    <h2><strong>SDK集成流程</strong></h2>    <ol>     <li>将解压的微信OpenSDK文件夹拷贝到项目文件夹下,并导入开发环境中。 libWeChatSDK.a<br> WechatAuthSDK.h<br> WXApi.h<br> WXApiObject.h</li>    </ol>    <h2><strong>导入系统依赖库</strong></h2>    <p>在link Binary With Libraries 里面添加</p>    <p>libc++.tbd<br> CoreTelephony.framework<br> libsqlite3.0.tbd<br> libz.tbd<br> SystemConfiguration.framework</p>    <p>还有之前导入的 libWeChatSDK.a</p>    <p>到这一步,SDK集成已经完毕</p>    <h2><strong>配置代码</strong></h2>    <ul>     <li> <p>添加URL Schemes</p> <p>点击项目名称,点击“Info”选项卡,在“URL Types”选项中,点击“+”, 在“URL Schemes”中输入微信的注册码</p> </li>    </ul>    <p><img src="https://simg.open-open.com/show/441e1917c8dfc2c8905991d9818e2b44.png"></p>    <p>c1000</p>    <ul>     <li>在支付的类里引用头文件:</li>    </ul>    <pre>  <code class="language-objectivec">#import "WXApi.h"  </code></pre>    <ul>     <li>配置wxpay支付</li>    </ul>    <pre>  <code class="language-objectivec">#pragma mark   ==============配置wxpay支付==============  - (void)payAction{        //发起网络请求,去你们服务器请求1.订单id,2. 钱(单位:分),3. 内容描述        //订单最好服务器生成,本文为了各位看的明白,所以在本地生成!      [NetWorkTooldingiD:[self generateTradeNO]andDetail:@"描述"success:^(NSDictionary *responseObject) {              //服务器返回数据             //调起微信支付          PayReq* wxreq            = [[PayReq alloc]init];          /** appid */          wxreq.openID              = responseObject[@"result"][@"appid"];          /** 商家向财付通申请的商家id */          wxreq.partnerId          = responseObject[@"result"][@"partnerid"];          /** 预支付订单 */          wxreq.prepayId            = responseObject[@"result"][@"prepayid"];          /** 随机串,防重发 */          wxreq.nonceStr            = responseObject[@"result"][@"noncestr"];          /** 时间戳,防重发 */          wxreq.timeStamp          = [responseObject[@"result"][@"timestamp"]intValue];          /** 商家根据财付通文档填写的数据和签名 */          wxreq.package            = responseObject[@"result"][@"package"];          /** 商家根据微信开放平台文档对数据做的签名 */          wxreq.sign                = responseObject[@"result"][@"sign"];          [WXApisendReq:wxreq];      }failure:^(NSError *error) {          NSLog(@"%@",error);      }];  }  #pragma mark   ==============产生随机订单号==============     - (NSString *)generateTradeNO  {      static int kNumber = 15;         NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";      NSMutableString *resultStr = [[NSMutableString alloc]init];      srand((unsigned)time(0));      for (int i = 0; i < kNumber; i++)      {          unsigned index = rand() % [sourceStrlength];          NSString *oneStr = [sourceStrsubstringWithRange:NSMakeRange(index, 1)];          [resultStrappendString:oneStr];      }      return resultStr;  }  </code></pre>    <ul>     <li>配置返回处理代码</li>    </ul>    <p>在 AppDelegate.h 文件中,增加微信协议:</p>    <pre>  <code class="language-objectivec">#import "WXApi.h"  @interface AppDelegate : UIResponder <UIApplicationDelegate,WXApiDelegate>  </code></pre>    <p>在 AppDelegate.m 文件中,增加引用代码:</p>    <pre>  <code class="language-objectivec">- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {      // 初始化微信sdk      [WXApiregisterApp:@"wx*********"];      return YES;  }        - (BOOL)application:(UIApplication *)applicationopenURL:(NSURL *)urlsourceApplication:(NSString *)sourceApplicationannotation:(id)annotation {      /*! @brief 处理微信通过URL启动App时传递的数据       *       * 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。       * @param url 微信启动第三方应用时传递过来的URL       * @param delegate  WXApiDelegate对象,用来接收微信触发的消息。       * @return 成功返回YES,失败返回NO。       */      return [WXApihandleOpenURL:urldelegate:self];  }     - (void)onResp:(BaseResp *)resp  {      //支付返回结果,实际支付结果需要去微信服务器端查询      NSString *strMsg = [NSStringstringWithFormat:@"支付结果"];      switch (resp.errCode) {          caseWXSuccess:              strMsg = @"支付结果:成功!";              NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);              break;          default:              strMsg = [NSStringstringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];              NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);              break;      }  }  </code></pre>    <h2><strong>不用微信SDK 唤起微信支付</strong></h2>    <ol>     <li>众所周知,iOS是一个封闭的系统,应用之间是不可以互相读取文件的,苹果就使用了URL Scheme来实现了这个功能。通过各个APP设计的符合苹果的统一规范的URL Scheme,Url Scheme 是可以用来传递信息的 <p>URL Scheme是为方便app之间互相调用而设计的。你可以通过一个类似URL的链接,通过系统的OpenURl来打开该app,并可以传递一些参数。每个URL必须能唯一标识一个APP,如果你设置的URL与别的APP的URL冲突,此时,你的APP不一定会被调用起来,原因是当APP在安装的时候就已经在系统里面注册了此APP的URL Scheme,如果你的一致但是是后安装的,那么系统不会调用你的APP,因为你的APP设置的URL scheme被覆盖了。</p> </li>     <li>分析得出,微信,支付宝等sdk 的分享,支付功能,都是通过URL scheme 进行传递内容的</li>     <li>那么我们可以查看微信SDK唤起微信客服端支付的时候,传递的URL Scheme 是什么内容,如果可以找到其编码规律,那么即可以不用sdk进行支付</li>    </ol>    <p>那么,发起支付的过程中,系统会唤起微信客户端,我们思路是查看微信sdk发送给微信客户端的URL Scheme内容,就要伪造一个微信,也就是向系统声明一个和微信URL Scheme相同的地址</p>    <h2><strong>查看微信URL Scheme地址</strong></h2>    <p>经测试: <strong>微信的URL Scheme是:weixin://</strong></p>    <p>那么,我们新建个工程,起名为:GetPayURLScheme</p>    <p>接着注册自定义 URL Scheme</p>    <p>点击 项目里info.plist (非test里面的info.plist)并选择 右键 Open As – Source Code:加入:</p>    <pre>  <code class="language-objectivec"><key>CFBundleURLTypes</key>      <array>          <dict>              <key>CFBundleURLSchemes</key>              <array>                  <string>weixin</string>              </array>              <key>CFBundleURLName</key>              <string>1111</string>          </dict>      </array>  </code></pre>    <p>这时候,点击 项目里info.plist (非test里面的info.plist)并选择 右键 Open As – list:</p>    <p>这样就生成了如下图的URLscheme:</p>    <p><img src="https://simg.open-open.com/show/ab62f2afeec02b03beff6fb33e4fde6b.png"></p>    <p>c1000</p>    <p>在 AppDelegate.m 里面添加</p>    <pre>  <code class="language-objectivec">//应用app接收urlScheme传值时会响应此方法     - (BOOL)application:(UIApplication *)applicationopenURL:(NSURL *)url    sourceApplication:(NSString *)sourceApplicationannotation:(id)annotation{      //显示截取的urlscheme      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"接收到的urlScheme"message:url.absoluteStringdelegate:nilcancelButtonTitle:nilotherButtonTitles:@"确定", nil];      [alertshow];      复制到剪贴板      UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];      pasteboard.string = url.absoluteString;         return YES;  }  </code></pre>    <p>运行到手机里面,这时候,你无论那个app要微信付款的时候,唤起的是刚才新建的名叫GetPayURLScheme工程 ,如下图:</p>    <p><img src="https://simg.open-open.com/show/5fd4a06cf222fef36a9920b1ad94698b.png"></p>    <p><img src="https://simg.open-open.com/show/7c3199178edf4c921f94ce1e2210127b.png"></p>    <p>可以看到:那个urlScheme:</p>    <pre>  <code class="language-objectivec">weixin://app/wxdf261c3b90ffbc25/pay/?nonceStr=Ho7nAFOALQpVqSM7&package=Sign%3DWXPay&partnerId=1236537302&prepayId=wx201606052201506009de63980169148758&timeStamp=1465135310&sign=5A3EF234382FD61D36CEC104723387ED&signType=SHA1  </code></pre>    <p>可以看出:它的拼接方法是:</p>    <pre>  <code class="language-objectivec">NSString *str = [NSStringstringWithFormat:@"weixin://app/%@/pay/?nonceStr=%@&package=Sign%%3DWXPay&partnerId=%@&prepayId=%@&timeStamp=%@&sign=%@&signType=SHA1",appid,noncestr,partnerid,prepayid,[NSStringstringWithFormat:@"%d",[timestampintValue]],sign];  </code></pre>    <h2><strong>不用SDK,只需要配置这么一段代码,微信支付即可完成!!!!!!!!</strong></h2>    <pre>  <code class="language-objectivec">- (void)payAction{        //发起网络请求,去你们服务器请求1.订单id,2. 钱(单位:分),3. 内容描述        //订单最好服务器生成,本文为了各位看的明白,所以在本地生成!      [NetWorkTooldingiD:[self generateTradeNO]andDetail:@"描述"success:^(NSDictionary *responseObject) {          /** appid */          NSString *appid          = responseObject[@"result"][@"appid"];          /** 商家向财付通申请的商家id */          NSString *partnerId      = responseObject[@"result"][@"partnerid"];          /** 预支付订单 */          NSString *prepayId        = responseObject[@"result"][@"prepayid"];          /** 随机串,防重发 */          NSString *nonceStr        = responseObject[@"result"][@"noncestr"];          /** 时间戳,防重发 */          NSString *timeStamp      = responseObject[@"result"][@"timestamp"];          /** 商家根据财付通文档填写的数据和签名 */          NSString *package        = responseObject[@"result"][@"package"];          /** 商家根据微信开放平台文档对数据做的签名 */          NSString *sign            = responseObject[@"result"][@"sign"];             //生成URLscheme          NSString *str = [NSStringstringWithFormat:@"weixin://app/%@/pay/?nonceStr=%@&package=Sign%%3DWXPay&partnerId=%@&prepayId=%@&timeStamp=%@&sign=%@&signType=SHA1",appid,nonceStr,partnerId,prepayId,[NSStringstringWithFormat:@"%d",[timeStampintValue] ],sign];             //通过openURL的方法唤起支付界面          [[UIApplication sharedApplication]openURL:[NSURLURLWithString:str]];         }failure:^(NSError *error) {          NSLog(@"%@",error);      }];  }  </code></pre>    <p><img src="https://simg.open-open.com/show/4a48fc71e99f5451f68751bc01aa3d4a.png"></p>    <p> </p>    <p> </p>    <p>来自:http://ios.jobbole.com/85793/</p>    <p> </p>