支付功能在app中的实现及支付功能模块化调用流程图

时间:2021-09-10 22:15:12

支付宝IOS2.2.1支付

将Demo中AlipaySDK.bundle AlipaySDK.framework libel.a lib crypto.a openssl Util加入到工程,在需要调用的地方加#import

-(void)apily{


    /* *商户的唯一的parnter和seller。 *签约后,支付宝会为每个商户分配一个唯一的 parnter 和 seller。 */

    /*============================================================================*/
    /*=======================需要填写商户app申请的===================================*/
    /*============================================================================*/
    NSString *partner = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Partner"];
    NSString *seller = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"Seller"];
    NSString *privateKey = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RSA private key"];
    /*============================================================================*/
    /*============================================================================*/
    /*============================================================================*/

    //partner和seller获取失败,提示
    if ([partner length] == 0 ||
        [seller length] == 0 ||
        [privateKey length] == 0)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                        message:@"缺少partner或者seller或者私钥。"
                                                       delegate:self
                                              cancelButtonTitle:@"确定"
                                              otherButtonTitles:nil];
        [alert show];
        return;
    }

    /* *生成订单信息及签名 */
    //将商品信息赋予AlixPayOrder的成员变量
    Order *order = [[Order alloc] init];
    order.partner = partner;
    order.seller = seller;
    order.tradeNO = [self.dict valueForKey:@"orderNumber"]; //订单ID(由商家自行制定)
    order.productName =@"标题"; //商品标题
    order.productDescription = @"描述"; //商品描述
    order.amount =self.strMoney; //商品价格
// order.amount =@"0.01"; //商品价格
    order.notifyURL = @"http://test.testcom.cn:8081/phone/test/shopRechageRequestAlipayResult.htm"; //回调URL

    order.service = @"mobile.securitypay.pay";
    order.paymentType = @"1";
    order.inputCharset = @"utf-8";
    order.itBPay =[CommonUtils getDateForStringTime:[self.dict valueForKey:@"disableTime"] withFormat:nil];
    order.showUrl = @"m.alipay.com";

    //应用注册scheme,在AlixPayDemo-Info.plist定义URL types
    NSString *appScheme = @"mddy";

    //将商品信息拼接成字符串
    NSString *orderSpec = [order description];
    NSLog(@"~~~~~~~~~~~~~~~~~~~~~~~~~~~orderSpec = %@",orderSpec);

    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(privateKey);
    NSString *signedString = [signer signString:orderSpec];

    //将签名成功字符串格式化为订单字符串,请严格按照该格式
    NSString *orderString = nil;
    if (signedString != nil) {
        orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                       orderSpec, signedString, @"RSA"];

        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            NSLog(@"!!!!reslut = %@",resultDic);
             NSLog(@"@@@memo = %@,resultStatus =%@",[resultDic valueForKey:@"memo"],[resultDic valueForKey:@"resultStatus"]);

            if ([[[resultDic valueForKey:@"resultStatus"] toString]isEqualToString:@"9000"]) {

                [[NSNotificationCenter defaultCenter]postNotificationName:ZHIDURESULT object:self userInfo:@{@"info":@"1"}];
            }else{

                [[NSNotificationCenter defaultCenter]postNotificationName:ZHIDURESULT object:self userInfo:@{@"info":@"0"}];

            }

        }];

    }



}

上面这段代码,payOrder 没有客户端的情况是从这里进的,支付流程中响应事件也是这个方法,但当客户端的时候,auth_V2WithInfo 会进入,响应事件的方法是下面processAuth_V2Result 方法,但是,当payOrder ,auth_V2WithInfo 在一起的时候,会很纠结,结果是wap或者客户端总有一个回调方法不响应,可能是自己搞不清文档的意思,可是你妹的写清楚点行不。然后,wap的时候进入的方法不变,客户端的时候响应方法加上processOrderWithPaymentResult ,你会发现,响应的方法和wap的方法是同一个,好像是把支付流程重新传入了payOrder里边。

#define ZHIDURESULT @"zhifuResult" //收到支付后发出
RechQueRenViewController.m文件
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:0xededed];
    self.navigationItem.hidesBackButton = YES;
    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"backWithTitle.png"] forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, 53, 19);
    UIBarButtonItem* rithtBarItem = [[UIBarButtonItem alloc]initWithCustomView:button];
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = rithtBarItem ;
    button = nil;
    rithtBarItem = nil;

    self.title = @"充值确认";
    self.tableView =[[UITableView alloc]initWithFrame:CGRectMake(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT-64) style:UITableViewStyleGrouped];
    self.tableView.delegate =self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
    self.isAiLiPay = YES;

    UIButton* buttonCancel = [UIButton buttonWithType:UIButtonTypeCustom];
    [buttonCancel addTarget:self action:@selector(buttonPressedQueRen) forControlEvents:UIControlEventTouchUpInside];
    [buttonCancel setTitle:@"确认支付" forState:UIControlStateNormal];
    float red = 252/255.0;
    float green = 102/255.0;
    float blue = 5/255.0;
    [buttonCancel setBackgroundColor: [UIColor colorWithRed:red green:green blue:blue alpha:1.0]];
    buttonCancel.layer.cornerRadius = 3;
// buttonCancel.frame = CGRectMake(16, 195+80+50, WINDOW_WIDTH-32, 44);
// [self.tableView addSubview:buttonCancel];
    buttonCancel.frame = CGRectMake(16, WINDOW_HEIGHT-44-64-10, WINDOW_WIDTH-32, 44);
    [self.view addSubview:buttonCancel];
    self.tableView.bounces = NO;
    self.isCanPay = YES;
    self.isCanAlert =YES;


    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(zhifuResult:) name:ZHIDURESULT object:nil];
    // Do any additional setup after loading the view.
}
-(void)zhifuResult:(NSString*)result{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
    if ([result isEqualToString:@"1"]) {
        for (UIViewController* vc in self.navigationController.viewControllers) {
            if ([vc isKindOfClass:[AccountRechargeViewController class]]) {
                [self.navigationController  popToViewController:vc animated:YES];

            }
        }
        [[NSNotificationCenter defaultCenter]postNotificationName:ZHIFUSUCCESS object:self];
    }else{//建行支付失败,返回到支付页面,进行提示
        [self.navigationController popViewControllerAnimated:YES];
        [[NSNotificationCenter defaultCenter]postNotificationName:ZHIDURESULT object:self userInfo:@{@"info":@"0"}];  
    }
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

    if ([url.host isEqualToString:@"safepay"]) {
// 
// [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
// NSLog(@"result = %@",resultDic);
// NSString *resultStr = resultDic[@"result"];
// NSLog(@"memo = %@,resultStatus =%@",[resultDic valueForKey:@"memo"],[resultDic valueForKey:@"resultStatus"]);
// 
// if ([[[resultDic valueForKey:@"resultStatus"] toString]isEqualToString:@"9000"]) {
// 
// }else{

// 
// }];
        [[AlipaySDK defaultService]processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);

        }];
    }
// if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回authCode
// [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
// NSLog(@"result = %@",resultDic);
// }];
// }

    return YES;
}

notifyURL 是客户端传给支付宝的,当客户端支付完成后,支付宝会根据这个url异步调用服务端的接口,同步支付结果的数据,这个要服务器给的,确保你的私钥,合作者id是准确的。

建设银行支付
只支持html5的方式访问,建行等N多银行没有提供由生态系统直接实现的SDK,当然html5页面的建行支付需要我们伟大的前端工程师实现了,我们只能通过向服务器发送请求加载html5页面。
注意:html5有四种加载方式。
第一种,在h5页面加入工程,本地加载方式。
第二种,判断本地是否有h5页面文件,若没有向服务发送文件请求,下载h5页面,然后本地加载。
第三种,不经过服务器以加载页面的方式加载页面。
第四种,向服务器发送请求获得html5页面的加载方式。
详细的见博客:http://blog.csdn.net/jia12216/article/details/46966425
下面是以第四种方式加载h5页面为例子。

JianHangWebView.m文件

- (void)viewDidLoad {
    self.title = @"建行卡支付";
    [self jianHangPay];

    self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:0xededed];
    self.button = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.button setTitle:@"00:00" forState:UIControlStateNormal];
    [self.button setTitleColor:UICOLOR(248, 78, 11, 1) forState:UIControlStateNormal];
    self.button.frame = CGRectMake(0, 0, 53, 19);
    UIBarButtonItem* rithtBarItem = [[UIBarButtonItem alloc]initWithCustomView:self.button];
    self.navigationItem.rightBarButtonItem = rithtBarItem ;
    rithtBarItem = nil;


    self.navigationItem.hidesBackButton = YES;
    UIButton* button1 = [UIButton buttonWithType:UIButtonTypeCustom];
    [button1 setImage:[UIImage imageNamed:@"backWithTitle.png"] forState:UIControlStateNormal];
    button1.frame = CGRectMake(0, 0, 53, 19);
    UIBarButtonItem* leftBarItem = [[UIBarButtonItem alloc]initWithCustomView:button1];
    [button1 addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = leftBarItem ;
    button1 = nil;
    leftBarItem = nil;


    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
    self.timer =   [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(progressTimerChangeJianHang) userInfo:nil repeats:YES];
    [self.timer fire];

}

-(void)jianHangPay{
    self.view.backgroundColor = [UIColor colorWithHex:0xf5f5f5];
    if (!self.webView) {
        self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT-64)];
        self.webView.backgroundColor = [UIColor whiteColor];
        [self.webView setScalesPageToFit:YES];
        [self.view addSubview:self.webView];



        [WebViewJavascriptBridge enableLogging];

        _bridge = [WebViewJavascriptBridge bridgeForWebView:self.webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {
            FLDDLogDebug(@"ObjC received message from JS: %@", data);
            responseCallback(@"Response for message from ObjC");
        }];

// [_bridge registerHandler:@"testJavascriptHandler" handler:^(id data, WVJBResponseCallback responseCallback) {
// FLDDLogDebug(@"reloadPage");
// // [self reLoginReloadPage];
// }];

        [_bridge registerHandler:@"mddyCallback" handler:^(id data, WVJBResponseCallback responseCallback) {
            FLDDLogDebug(@"testObjcCallback called: %@", data);


            NSString *html = [data toString];
// NSLog(@"%@",html);
            if ([html isEqualToString:@"true"]) {
                [self zhifuResult:@"1"];
            }else{
// [self resultFailReXiaDan];
                [self zhifuResult:@"0"];


            }


            responseCallback(@"Response from testObjcCallback");
        }];

// [_bridge registerHandler:@"WebViewJavascriptBridgeReady" handler:^(id data, WVJBResponseCallback responseCallback) {
// FLDDLogDebug(@"testObjcCallback called: %@", data);
// 
// 
// NSString *html = [data toString];c
// NSLog(@"%@",html);
// 
// responseCallback(@"Response from testObjcCallback");
// }];

        [_bridge send:@"123"];

// [_bridge send:@"A string sent from ObjC to JS" responseCallback:^(id response) {
// NSLog(@"sendMessage got response: %@", response);
// }];

        NSURLRequest *request = [User getBookPageRequestWithOrderNumb:[self.dict valueForKey:@"orderNumber"]];
        if(request != nil)
        {
            [self.webView loadRequest:request];
        }

    }


}

现在的公司代码不能贴出来。分享下支付功能模块化后的调用流程图吧!对咱们程序猿来说,流程图比实际的代码更重要,可以根据流程图做出不同的模块,完全抄袭不单牵涉到知识产权问题,也不利于扩展。
支付功能在app中的实现及支付功能模块化调用流程图