微信支付

  • 微信支付
    1:去微信开放平台注册应用
    https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=2c0fee9c43e1eb8f9febcc7cb73abf598e2d4011
Paste_Image.png

创建移动应用并成功之后会收到腾讯发来的邮件,

微信支付_第1张图片
Paste_Image.png

通过邮件你能获得重要的参数:
(1):AppID
(2):微信支付商户号
(4):前往商户平台完成入驻
(4):API秘钥(自己设置即可,注意一定要32位字母加数字的组合)记得保存好秘钥,以后要使用


微信支付_第2张图片
Paste_Image.png
微信支付_第3张图片
Paste_Image.png
  • 支付所需要的可以写成宏以供调用
#define KWinXin @"App ID"  // 回调ID
/**************微信支付************/
#define APP_ID          @"APPID"               //APPID
#define APP_SECRET      @"App Secret" //appsecret
//商户号,填写商户对应参数
#define MCH_ID          @"商户ID"
//商户API密钥,填写相应参数
#define PARTNER_ID      @"API秘钥"
//支付结果回调页面
#define NOTIFY_URL      @"后台给你的支付成功之后回调的地址"
//获取服务器端支付数据地址(商户自定义)
#define SP_URL          @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php"
/*****************微信支付***************/```

2:完成入驻之后,下载微信官方SDK和官方demo
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1

(1):导入项目

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-662468e54a90098a.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

onlyPhone指的是只能真机运行,不然会报错

(2):导入生成签名的文件(在官方demo中获得)

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-0fe369ee357eb33d.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

(3):运行之后会报错
解决办法:
1:添加 FrameWork 文件到工程在工程中修改 Other � Linker � Flags 后,需要修改编译步骤的链接库设置,避免链接阶段由于库的设置错误导致程序崩溃。方法:程序 � Target->Buid � Phases->Link � Binary � With � Libraries 下添加以下 Framework 至工程中。需要添加的 Frameworks为 : QuartzCore.framework 、 ImageIO.framework 、SystemConfiguration.framework 、 Security.framework 、CoreTelephony.framework 、 CoreText.framework 、 UIKit.framework 、Foundation.framework 和 CoreGraphics.framework
。 �
2:在工程中引入静态库之后,需要在编译时添加 � –objC � 编译选项,避免静态库中类加载 � 不全造成程序崩溃。方法:程序 � Target->Buid � Settings->Linking � 下 � Other � Linker � Flags � 项添加-ObjC。
3:写入ARC、MRC混编代码

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-c4e2abea241037f3.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-a8302305c5d9a289.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-874558269997a1ab.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

4:运行之后如果没有错的话,开始正式写支付
(1):引入微信支付头文件并在项目的info中设置回调ID

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-8d0327a106f566b8.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

import "WXApi.h"```

(2):在程序启动完成的时候注册微信支付

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 微信支付
    [WXApi registerApp:@"App ID" withDescription:@"应用名称"];
}```

(3):在支付页面发放中发起支付
- 微信支付、签名头文件(如果服务器端不做的情况下)

import "WXApi.h" // 微信支付头文件

import "WXApiObject.h" // 回调头文件

import "payRequsestHandler.h" // 签名相关头文件


- 支付方法

/**

  • 微信支付
    */
  • (void)sendPay
    {

    //创建一次支付签名对象
    payRequsestHandler *req = [[payRequsestHandler alloc] init];
    //初始化支付签名对象
    [req init:APP_ID mch_id:MCH_ID];
    //设置密钥
    [req setKey:PARTNER_ID];

    //获取到实际调起微信支付的参数后,在app端调起支付,即下单并获得二次签名
    NSMutableDictionary *dict = [req sendPay_demo];

    if(dict == nil){
    //错误提示
    NSString *debug = [req getDebugifo];

      [self alert:@"提示信息" msg:debug];
      
      NSLog(@"%@\n\n",debug);
    

    }else{
    NSLog(@"%@\n\n",[req getDebugifo]);

      NSMutableString *stamp  = [dict objectForKey:@"timestamp"];
      
      //调起微信支付
      PayReq* req             = [[PayReq alloc] init];
      req.openID              = [dict objectForKey:@"appid"];
      req.partnerId           = [dict objectForKey:@"partnerid"];
      req.prepayId            = [dict objectForKey:@"prepayid"];
      req.nonceStr            = [dict objectForKey:@"noncestr"];
      req.timeStamp           = stamp.intValue;
      req.package             = [dict objectForKey:@"package"];
      req.sign                = [dict objectForKey:@"sign"];
      
      [WXApi sendReq:req];    // 发起支付
    

    }
    }```

上面调用了demo中的生成签名的类,还有下单的方法如下:

  • 一次签名
//创建一次支付签名对象
    payRequsestHandler *req = [[payRequsestHandler alloc] init];
    //初始化支付签名对象
    [req init:APP_ID mch_id:MCH_ID];
    //设置密钥
    [req setKey:PARTNER_ID];```

- 成成订单的方法

  • ( NSMutableDictionary *)sendPay_demo
    {

    //订单标题,展示给用户
    NSString *order_name = @"V3支付测试";
    //订单金额,单位(分)
    NSString *order_price = @"1";//1分钱测试

    //================================
    //预付单参数订单设置
    //================================
    srand( (unsigned)time(0) );
    NSString *noncestr = [NSString stringWithFormat:@"%d", rand()];
    NSString *orderno = [NSString stringWithFormat:@"%ld",time(0)];
    NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];

    [packageParams setObject: appid forKey:@"appid"]; //开放平台appid
    [packageParams setObject: mchid forKey:@"mch_id"]; //商户号
    [packageParams setObject: noncestr forKey:@"nonce_str"]; //随机串
    [packageParams setObject: @"APP" forKey:@"trade_type"]; //支付类型,固定为APP
    [packageParams setObject: order_name forKey:@"body"]; //订单描述,展示给用户
    [packageParams setObject: NOTIFY_URL forKey:@"notify_url"]; //支付结果异步通知
    [packageParams setObject: orderno forKey:@"out_trade_no"];//商户订单号
    [packageParams setObject: @"196.168.1.1" forKey:@"spbill_create_ip"];//发器支付的机器ip
    [packageParams setObject: order_price forKey:@"total_fee"]; //订单金额,单位为分

    //获取prepayId(预支付交易会话标识)
    NSString *prePayid;
    prePayid = [self sendPrepay:packageParams];
    if ( prePayid != nil) {
    //获取到prepayid后进行第二次签名

      NSString    *package, *time_stamp, *nonce_str;
      //设置支付参数
      time_t now;
      time(&now);
      time_stamp  = [NSString stringWithFormat:@"%ld", now];
      nonce_str = [WXUtil md5:time_stamp];
      //重新按提交格式组包,微信客户端暂只支持package=Sign=WXPay格式,须考虑升级后支持携带package具体参数的情况
      //package       = [NSString stringWithFormat:@"Sign=%@",package];
      package         = @"Sign=WXPay";
      //第二次签名参数列表
      NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
      [signParams setObject: appid        forKey:@"appid"];
      [signParams setObject: nonce_str    forKey:@"noncestr"];
      [signParams setObject: package      forKey:@"package"];
      [signParams setObject: mchid        forKey:@"partnerid"];
      [signParams setObject: time_stamp   forKey:@"timestamp"];
      [signParams setObject: prePayid     forKey:@"prepayid"];
      //[signParams setObject: @"MD5"       forKey:@"signType"];
      //生成签名
      NSString *sign  = [self createMd5Sign:signParams];
      
      //添加签名
      [signParams setObject: sign         forKey:@"sign"];
      
      [debugInfo appendFormat:@"第二步签名成功,sign=%@\n",sign];
      
      //返回参数列表
      return signParams;
    

    } else {
    [debugInfo appendFormat:@"获取prepayid失败!\n"];
    }
    return nil;
    }```

4:应用跳转到微信支付完毕,返回App,我们通过在App Delegate中的设置代理回调并通知支付页面支付成功

  • 遵守代理


    微信支付_第4张图片
    Paste_Image.png
  • 设置回调代理并发送通知

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    if ([url.scheme hasPrefix:KWinXin]) {
        [MobClick event:@"wxShare" label:@"微信分享"];
        return   [WXApi handleOpenURL:url delegate:self];
    }

    return YES;
}```

- 在代理方法中发送通知并传递微信支付返回的数据

pragma mark - 微信支付回调代理方法

-(void)onResp:(BaseResp*)resp
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"send" object:resp];
}```

  • 在支付页面注册通知并处理支付后的操作

  • 注册通知

// 微信支付成功回调通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendPay:) name:@"send" object:nil];```

- 实现通知方法

pragma mark - 微信支付回调通知方法

  • (void)sendPay:(id)sender {
    BaseResp * resp = [sender object];
    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
    NSString *strTitle;

    if([resp isKindOfClass:[SendMessageToWXResp class]])
    {
    strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];
    }
    if([resp isKindOfClass:[PayResp class]]){
    //支付返回结果,实际支付结果需要去微信服务器端查询
    strTitle = [NSString stringWithFormat:@"支付结果"];

      switch (resp.errCode) {
          case WXSuccess:
          {
              strMsg = @"支付结果:成功!";
              NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
              // 跳转到成功页面
              PaySuccessfulViewController *paySuccessful = [PaySuccessfulViewController new];
              [self.navigationController pushViewController:paySuccessful animated:YES];
          }
              break;
              
          default:
              strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
              NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
              break;
      }
    

    }
    }```

你可能感兴趣的:(微信支付)