美文网首页iOS Dev
iOS微信支付全流程与坑的躲闪

iOS微信支付全流程与坑的躲闪

作者: NateLam | 来源:发表于2017-01-11 15:07 被阅读403次

    微信官方文档说的"统一下单"这一步交给后台做, 安(sheng)全(shi).
    感谢http://www.open-open.com/lib/view/open1460718945871.html

    1.去微信开放平台注册应用

    https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=2c0fee9c43e1eb8f9febcc7cb73abf598e2d4011

    注册应用后收到的邮件1 ![Uploading 注册应用后收到的邮件2_685107.jpeg . . .].jpeg

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

    注册应用后收到的邮件2.jpeg

    在商户平台不止可以查看关于密钥之类的内容, 以后统计汇款数据, 或者退款也都是在商户平台进行, 每次进入都要输入密码和验证码

    商户平台.jpeg
    1. 这些东西整完后, 就可以向工程导入SDK, 我是直接在下面官方文档中心下载后拽进来的, 作为一个cocoaPods党, copy if needed要勾选
      readMe.txt与官方文档网站中的app开发步骤的配置环境好好看, 叫你做的一个都别放过

    https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5#

    1. 在AppDelegate.m文件中, 引入WXApi.h, 引入<WXApiDelegate>

    然后在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 注册, 据说如果同时还注册了友盟, 要先注册友盟, 再注册微信

    [WXApi registerApp:WX_AppID];

    1. 商户服务器生成支付订单,先调用【统一下单API】生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:
     - (IBAction)weChatPayButtonAction:(id)sender
    {
    PayReq *request = [[PayReq alloc] init];
    /** 商家向财付通申请的商家id */
    request.partnerId = @"1220277201";
    /** 预支付订单 */
    request.prepayId= @"82010380001603250865be9c4c063c30";
    /** 商家根据财付通文档填写的数据和签名 */
    request.package = @"Sign=WXPay";
    /** 随机串,防重发 */
    request.nonceStr= @"lUu5qloVJV7rrJlr";
    /** 时间戳,防重发 */
    request.timeStamp= 1458893985;
    /** 商家根据微信开放平台文档对数据做的签名 */
    request.sign= @"b640c1a4565b476db096f4d34b8a9e71960b0123";
    /*! @brief 发送请求到微信,等待微信返回onResp
     *
     * 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
     * SendAuthReq、SendMessageToWXReq、PayReq等。
     * @param req 具体的发送请求,在调用函数后,请自己释放。
     * @return 成功返回YES,失败返回NO。
     */
    [WXApi sendReq: request];
    }
    

    现在我们只需要在控制器上添加一个button, 名字改成微信支付就可以了

    1. 关于支付回来, 无论支付成功或失败或取消, 我们如果需要的话都要做相应处理, 回到appDelegate.m
    //前面的两个方法被iOS9弃用了,如果是Xcode7.2网上的话会出现无法进入进入微信的onResp回调方法,就是这个原因。本来我是不想写着两个旧方法的,但是一看官方的demo上写的这两个,我就也写了。。。。
    //9.0前的方法,为了适配低版本 保留
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    return [WXApi handleOpenURL:url delegate:self];
    }
    
    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
        return [WXApi handleOpenURL:url delegate:self];
    }
    //9.0后的方法
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
        //这里判断是否发起的请求为微信支付,如果是的话,用WXApi的方法调起微信客户端的支付页面(://pay 之前的那串字符串就是你的APPID,)
        return  [WXApi handleOpenURL:url delegate:self];
    }
    
    
    //微信SDK自带的方法,处理从微信客户端完成操作后返回程序之后的回调方法,显示支付结果的
    - (void)onResp:(BaseResp *)resp
    {
      //启动微信支付的response
    NSString *payResoult = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
    NSDictionary *dicOfResult = @{
                                  @"weixin_pay_result":resp
                                  };
    //将支付结果发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTI_WEI_XIN_PAY_RESULT object:dicOfResult];
    
    if([resp isKindOfClass:[PayResp class]]){
       
        //支付返回结果,实际支付结果需要去微信服务器端查询
        switch (resp.errCode) {
            case 0:
                payResoult = @"支付结果:成功!";
                NSLog(@"%@", payResoult);
                break;
            case -1:
                payResoult = @"支付结果:失败!";
                NSLog(@"%@", payResoult);
                break;
            case -2:
                payResoult = @"用户已经退出支付!";
                NSLog(@"%@", payResoult);
                break;
            default:
                payResoult = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                NSLog(@"%@", payResoult);
                break;
        }
    }
    }
    

    5.至此似乎是完成了支付大业, but, 假如ios9+用户点击状态栏返回我们自家app呢, 以上的支付方法回调是不走的!
    以下内容感谢http://www.jianshu.com/p/9744c53b5498

    但是从微信回来, 无论支付结果如何, 都会走
    - (void)applicationWillEnterForeground:(UIApplication *)application{}
    我们需要在这里面判断, 是否是因为支付从微信回来, 如果是的话, 去通知刚才跳转支付那个vc, 请求我们自家后台, 告诉我们这个客户钱给了没, 然后我们再做响应操作;

    但是, 如果用户在微信支付成功后点击navigation右按钮确认并返回我们的app, 那么wilEnterForeground先走,

     - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
    

    后走, 这种情况我们也要加以判断, 避免发送两次通知给调起支付的vc

    具体实现是这样: 在发起支付的时候, 进行NSUserDefault的本地记录, 强制写入本地

    相关文章

      网友评论

        本文标题:iOS微信支付全流程与坑的躲闪

        本文链接:https://www.haomeiwen.com/subject/klrrbttx.html