zoukankan      html  css  js  c++  java
  • iOS- 微信支付 (服务器调起支付 )以及回调不成功的原因 不看后悔

    写的不错,给留个言哈...

    一. 支付准备工作

    1. 微信相关准备工作

    (1) 向微信官方开通支付功能. 这个不是前端的工作.

    (2) 导入官方下载的微信支付SDK包. 我用的是微信开放平台下载的SDK 1.6.2

    (3) 导入必要的库文件

         SystemConfiguration.framework,

         libz.dylib,

         libsqlite3.0.dylib,

         libc++.dylib,

         CoreTelephoy.framework (坑一: 这个库是必要的,但是微信官方文档中没有说到要导入)

    (4) 该项目中的Bundle Identifier 应该填向微信注册的Bundle Identifier

    (5) 注册微信 (回调的时候用到,告诉微信,从微信返回到哪个APP)

         Target --> info --> URL Types --> +按钮 --> 填写identifier 和 URL Schemes. 前一个是标识符,一般填@"weixin".后一个是注册的微信appId. 比如"wx19a984b788a8a0b1".(注释: 假的appid)

    (6) 添加微信白名单

         info.plist --> 右击 --> open as  --> source Code --> 添加白名单

         我是在<key>CFBundleVersion</key>这一行上面添加的. 注意保持正确的键值对.别插错了.

    <key>LSApplicationQueriesSchemes</key>
        <array>
            <string>wechat</string>
            <string>weixin</string>
        </array>

    (7) 如果支付成功,回调方法不执行,或者回调不成功.请再次确认(4)(5)(6),是否填写正确. 

    (8) 运行一下,不报错.报错,再次确认(1)--(7)步骤.

    二.代码相关

    1. 在AppDelegate.h中

    (1) 导入微信类 #import @"WXApi.h".

    (2) 遵守微信代理方法 <WXApiDelegate>

    2. 在APPDelegate.m中

    (1) 注册微信

    #pragma mark 注册微信
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    { 
        //注册 微信
        /**
         参数1 : 微信Appid
         参数2 : 对项目的描述信息(用项目名称)
         */
        [WXApi registerApp:@"微信Appid" withDescription:@"云宴"];
        
        return YES;
    }

     (2) 跳转方法,并设置代理

    #pragma mark 跳转处理
    //被废弃的方法. 但是在低版本中会用到.建议写上
    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    //被废弃的方法. 但是在低版本中会用到.建议写上
    
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    //新的方法
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
    {
        return [WXApi handleOpenURL:url delegate:self];
    }

    (3) 微信回调方法 (注意: 不要写成Req方法了)

    #pragma mark 微信回调方法
    
    - (void)onResp:(BaseResp *)resp
    {
        NSString * strMsg = [NSString stringWithFormat:@"errorCode: %d",resp.errCode];
        NSLog(@"strMsg: %@",strMsg);
    
        NSString * errStr       = [NSString stringWithFormat:@"errStr: %@",resp.errStr];
        NSLog(@"errStr: %@",errStr);
    
        
        NSString * strTitle;
        //判断是微信消息的回调 --> 是支付回调回来的还是消息回调回来的.
        if ([resp isKindOfClass:[SendMessageToWXResp class]])
        {
            strTitle = [NSString stringWithFormat:@"发送媒体消息的结果"];
        }
    
        NSString * wxPayResult;
        //判断是否是微信支付回调 (注意是PayResp 而不是PayReq)
    
        if ([resp isKindOfClass:[PayResp class]])
        {
            //支付返回的结果, 实际支付结果需要去微信服务器端查询
            strTitle = [NSString stringWithFormat:@"支付结果"];
            switch (resp.errCode)
            {
                case WXSuccess:
                {
                    strMsg = @"支付结果:";
                    NSLog(@"支付成功: %d",resp.errCode);
                    wxPayResult = @"success";
                    break;
                }
    case WXErrCodeUserCancel: { strMsg = @"用户取消了支付"; NSLog(@"用户取消支付: %d",resp.errCode); wxPayResult = @"cancel"; break; } default: { strMsg = [NSString stringWithFormat:@"支付失败! code: %d errorStr: %@",resp.errCode,resp.errStr]; NSLog(@":支付失败: code: %d str: %@",resp.errCode,resp.errStr); wxPayResult = @"faile"; break; } } //发出通知 从微信回调回来之后,发一个通知,让请求支付的页面接收消息,并且展示出来,或者进行一些自定义的展示或者跳转 NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:wxPayResult]; [[NSNotificationCenter defaultCenter] postNotification:notification]; } }

     3. 在ViewController.h (进行支付请求的类)

     暂时没有任何操作

    4. 在ViewController.m中(进行支付的请求的类)

    (1) 导入微信库 #import @"WXApi.h"

    (2) 监听APPDelegate.m中发送的通知

    #pragma mark 监听通知
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:YES];
        
        //检测是否装了微信软件
        if ([WXApi isWXAppInstalled])
        {
            
            //监听通知
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"WXPay" object:nil];
        }
    }
    #pragma mark - 事件
    - (void)getOrderPayResult:(NSNotification *)notification
    {
        NSLog(@"userInfo: %@",notification.userInfo);
        
        if ([notification.object isEqualToString:@"success"])
        {
            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"支付成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
            [alertView show];
        }
        else
        {
            [self alert:@"提示" msg:@"支付失败"];
        }
    }
    
    //客户端提示信息
    - (void)alert:(NSString *)title msg:(NSString *)msg
    {
        UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alter show];
    }

    (3) 移除通知

    #pragma mark 移除通知
    - (void)dealloc 
    {
    //移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; }

    (4) 调起微信去支付

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        [self pay_button];
    }
    
    #pragma mark - 实现方法
    
    #pragma mark 创建支付按钮
    - (void)pay_button
    {
        self.payButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.payButton.frame = CGRectMake(10, 100, 300, 40);
        self.payButton.backgroundColor = [UIColor orangeColor];
        [self.payButton setTitle:@"去支付" forState:UIControlStateNormal];
        [self.payButton addTarget:self action:@selector(payButtonClicked) forControlEvents:UIControlEventTouchUpInside];
        
        [self.view addSubview:self.payButton];
    }
    
    #pragma mark - 点击事件
    - (void)payButtonClicked
    {
        [self sendNetWorking_WXPay];
    }
    
    - (void)sendNetWorking_WXPay
    {
        NSString * urlStr = [NSString stringWithFormat:@"%@%@",YYIP,@"wx/pay"];
        
        NSDictionary * parameter = @{
                                     @"pay_type"       : @"1",
                                     @"total_price"    : @"10",
                                     @"appointment_id" : @"208"
                                     };
        
        [self sendNetWorkingWith:urlStr andParameter:parameter];
    }
    
    #pragma mark 网络请求 -->> post
    - (void)sendNetWorkingWith:(NSString *)url andParameter:(NSDictionary *)parameter
    {
        AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
        
        [manager POST:url parameters:parameter progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"%@",responseObject);
            
            //网络请求回来的8个参数.详见微信开发平台
            
            NSDictionary * result = responseObject[@"result"];
            
            NSString * appid         = result[@"appid"];
            NSString * noncestr      = result[@"noncestr"];
            NSString * package1      = result[@"package1"];
            NSString * partnerid     = result[@"partnerid"];
            NSString * paySign       = result[@"paySign"];
            NSString * prepayid      = result[@"prepayid"];
            NSString * timestamp     = result[@"timestamp"];
            
            
    //        NSString * err_code      = result[@"err_code"];
    //        NSString * timeStamp     = result[@"timeStamp"];
    //        NSString * tradeid       = result[@"tradeid"];
    
            
        [self WXPayRequest:appid nonceStr:noncestr package:package1 partnerId:partnerid prepayId:prepayid timeStamp:timestamp sign:paySign];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@",error);
        }];
    }
    
    #pragma mark - 调起微信支付
    - (void)WXPayRequest:(NSString *)appId nonceStr:(NSString *)nonceStr package:(NSString *)package partnerId:(NSString *)partnerId prepayId:(NSString *)prepayId timeStamp:(NSString *)timeStamp sign:(NSString *)sign{
        //调起微信支付
        PayReq* wxreq             = [[PayReq alloc] init];
        
        wxreq.openID              = appId; // 微信的appid
        wxreq.partnerId           = partnerId;
        wxreq.prepayId            = prepayId;
        wxreq.nonceStr            = nonceStr;
        wxreq.timeStamp           = [timeStamp intValue];
        wxreq.package             = package;
        wxreq.sign                = sign;
        
        [WXApi sendReq:wxreq];
    }

    三.上代码

    1. AppDelegate.h

    #import <UIKit/UIKit.h>
    
    #import "WXApi.h"
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate,WXApiDelegate>
    
    @property (strong, nonatomic) UIWindow *window;
    
    @end

    2. AppDelegate.m

    #import "AppDelegate.h"
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    
    #pragma mark 注册微信
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        
        //注册 微信
        /**
         参数1 : 微信Appid
         参数2 : 对项目的描述信息(用项目名称)
         */
        [WXApi registerApp:@"wx09a984b788a8a0b0" withDescription:@"云宴"];
        
        return YES;
    }
    
    #pragma mark 跳转处理
    //被废弃的方法. 但是在低版本中会用到.建议写上
    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    //被废弃的方法. 但是在低版本中会用到.建议写上
    
    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    //新的方法
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
    {
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    #warning 这一步中  不要错误的把req 当成了 resp
    #pragma mark 微信回调方法
    - (void)onResp:(BaseResp *)resp
    {
        NSString * strMsg = [NSString stringWithFormat:@"errorCode: %d",resp.errCode];
        NSLog(@"strMsg: %@",strMsg);
        
        NSString * errStr       = [NSString stringWithFormat:@"errStr: %@",resp.errStr];
        NSLog(@"errStr: %@",errStr);
        
        
        NSString * strTitle;
        //判断是微信消息的回调
        if ([resp isKindOfClass:[SendMessageToWXResp class]])
        {
            strTitle = [NSString stringWithFormat:@"发送媒体消息的结果"];
        }
        
        
        NSString * wxPayResult;
        //判断是否是微信支付回调 (注意是PayResp 而不是PayReq)
        if ([resp isKindOfClass:[PayResp class]])
        {
            //支付返回的结果, 实际支付结果需要去微信服务器端查询
            
            strTitle = [NSString stringWithFormat:@"支付结果"];
            
            switch (resp.errCode)
            {
                case WXSuccess:
                {
                    strMsg = @"支付结果:";
                    NSLog(@"支付成功: %d",resp.errCode);
                    wxPayResult = @"success";
                    break;
                }
                    case WXErrCodeUserCancel:
                {
                    strMsg = @"用户取消了支付";
                    NSLog(@"用户取消支付: %d",resp.errCode);
                    wxPayResult = @"cancel";
                    break;
                }
                default:
                {
                    strMsg = [NSString stringWithFormat:@"支付失败! code: %d  errorStr: %@",resp.errCode,resp.errStr];
                    NSLog(@":支付失败: code: %d str: %@",resp.errCode,resp.errStr);
                    wxPayResult = @"faile";
                    break;
                }
            }
            
            //发出通知
            NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:wxPayResult];
            [[NSNotificationCenter defaultCenter] postNotification:notification];
        }
    }
    
    @end

    3. ViewController.h

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    
    @end

    4. ViewController.m

    #import "ViewController.h"
    
    #import "AFHTTPSessionManager.h"
    #import "WXApi.h"
    
    #define YYIP       @"http:公司IP地址"
    
    
    @interface ViewController ()
    
    @property (nonatomic, strong) UIButton * payButton;
    
    
    @end
    
    @implementation ViewController
    
    #pragma mark 监听通知
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:YES];
        
        //检测是否装了微信软件
        if ([WXApi isWXAppInstalled])
        {
            
            //监听通知
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"WXPay" object:nil];
        }
    }
    
    #pragma mark 移除通知
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:YES];
        
        //移除通知
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        [self pay_button];
    
    }
    
    #pragma mark - 实现方法
    
    #pragma mark 创建支付按钮
    - (void)pay_button
    {
        self.payButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.payButton.frame = CGRectMake(10, 100, 300, 40);
        self.payButton.backgroundColor = [UIColor orangeColor];
        [self.payButton setTitle:@"去支付" forState:UIControlStateNormal];
        [self.payButton addTarget:self action:@selector(payButtonClicked) forControlEvents:UIControlEventTouchUpInside];
        
        [self.view addSubview:self.payButton];
    }
    
    #pragma mark - 点击事件
    - (void)payButtonClicked
    {

        if ([WXApi isWXAppInstalled])

        {

          [self sendNetWorking_WXPay];

        }

         else

        {

          [self alert:@"提示" msg:@"未安装微信"];

        }

    }

    - (void)sendNetWorking_WXPay
    {
        NSString * urlStr = [NSString stringWithFormat:@"%@%@",YYIP,@"wx/pay"];
           
        NSDictionary * parameter = @{
                                     @"pay_type"       : @"1",
                                     @"total_price"    : @"10",
                                     @"appointment_id" : @"208"
                                     };
        
        [self sendNetWorkingWith:urlStr andParameter:parameter];
    }
    
    #pragma mark 网络请求 -->> post
    - (void)sendNetWorkingWith:(NSString *)url andParameter:(NSDictionary *)parameter
    {
        AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
        
        [manager POST:url parameters:parameter progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSLog(@"%@",responseObject);
            
            //网络请求回来的8个参数.详见微信开发平台
            
            NSDictionary * result = responseObject[@"result"];
            
            NSString * appid         = result[@"appid"];
            NSString * noncestr      = result[@"noncestr"];
            NSString * package1      = result[@"package1"];
            NSString * partnerid     = result[@"partnerid"];
            NSString * paySign       = result[@"paySign"];
            NSString * prepayid      = result[@"prepayid"];
            NSString * timestamp     = result[@"timestamp"];
            
            
    //        NSString * err_code      = result[@"err_code"];
    //        NSString * timeStamp     = result[@"timeStamp"];
    //        NSString * tradeid       = result[@"tradeid"];
    
            
        [self WXPayRequest:appid nonceStr:noncestr package:package1 partnerId:partnerid prepayId:prepayid timeStamp:timestamp sign:paySign];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            NSLog(@"%@",error);
        }];
    }
    
    #pragma mark - 调起微信支付
    - (void)WXPayRequest:(NSString *)appId nonceStr:(NSString *)nonceStr package:(NSString *)package partnerId:(NSString *)partnerId prepayId:(NSString *)prepayId timeStamp:(NSString *)timeStamp sign:(NSString *)sign{
        //调起微信支付
        PayReq* wxreq             = [[PayReq alloc] init];
        
        wxreq.openID              = appId; // 微信的appid
        wxreq.partnerId           = partnerId;
        wxreq.prepayId            = prepayId;
        wxreq.nonceStr            = nonceStr;
        wxreq.timeStamp           = [timeStamp intValue];
        wxreq.package             = package;
        wxreq.sign                = sign;
        
        [WXApi sendReq:wxreq];
    }
    
    
    #pragma mark - 事件
    - (void)getOrderPayResult:(NSNotification *)notification
    {
        NSLog(@"userInfo: %@",notification.userInfo);
        
        if ([notification.object isEqualToString:@"success"])
        {
            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"支付成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
            [alertView show];
        }
    else if([notification.object isEqualToString:@"cancel"])
    {
    [self alert:@"提示" msg:@"用户取消了支付"];
    }
    else { [self alert:@"提示" msg:@"支付失败"]; } } //客户端提示信息 - (void)alert:(NSString *)title msg:(NSString *)msg { UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alter show]; } @end
    你的一次推荐就是对我莫大的支持。感觉不错,给个推荐或者评论吧。
  • 相关阅读:
    防火墙透明模式
    HP管理工具System Management Homepage安装配置
    kbmmw 中JSON 中使用SQL 查询
    kbmmw 中JSON 操作入门
    第一个kbmmw for Linux 服务器
    kbmmw 5.02发布
    kbmmw 5.01 发布
    使用delphi 10.2 开发linux 上的Daemon
    使用unidac 在linux 上无驱动直接访问MS SQL SERVER
    使用delphi 10.2 开发linux 上的webservice
  • 原文地址:https://www.cnblogs.com/mancong/p/5422192.html
Copyright © 2011-2022 走看看