美文网首页IOS 收藏
iOS支付封装(微信,支付宝,银联)

iOS支付封装(微信,支付宝,银联)

作者: WSKing的杂货铺 | 来源:发表于2017-04-17 10:28 被阅读434次

    1,微信支付:微信支付其实还好,文档比较清楚:1,请求预支付码(服务器需要跟微信做好处理);2,发起支付;

    2,支付宝支付:支付宝,额...略坑,在这里就不说签约的那些坑了,签约的问题可以直接去平台搞定,遇到问题基本网上也有解决办法.在ios端,主要有两个步骤:1,支付宝获取订单信息(服务器去跟支付宝做好处理);2,发起支付.

    3,银联支付:银联支付一般性的用的比较少,所以可能会有人觉得很难,其实不然,银联支付感觉比微信支付更简单(当然只是对一个程序员来说而已,使用起来还是挺麻烦的).银联的平台提供了很多方式,在我们当然是选择手机控件支付咯.下载文档后,里面的SDK和文档说明都是非常清楚的,当然还有测试和开发的区别的.也是主要两个步骤需要移动端完成:1,本地服务器请求订单信息(tn);2,发起支付;

    支付相关总览

    支付界面:(这里我把我自己的支付界面贴出来,当然不同的设计肯定也是不同的,但是都是大同小异)

    微信进行了是否安装的处理,没安装显然就不显示了,因为微信已经不支持网页支付了,支付宝和银联就不用了,他们没有安装app也可以支付.(我这里是模拟器,就没有显示微信了,手机上还是有的).

    支付视图

    直接上代码,就不截图了,直接代码贴上来吧.(我是代码+XIB的,单元格的就不贴了,XIB也不用贴了吧,上面的图一眼就可以看出来)

    支付页面.h文件

    #import@interface PayToolView : UIView

    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewHeight;

    @property (weak, nonatomic) IBOutlet UITableView *tableView;

    @property (nonatomic, strong) NSString *totalFee;

    @property (nonatomic, strong) NSString *orderNo;

    +(instancetype)instanceView;

    @end

    .m文件(单元格的代码我就不贴了)

    #import "PayToolView.h"

    #import "PayToolCell.h"

    #import "PayToolFooterView.h"

    #import "WXApi.h"

    #import "PayTool.h"

    @interface PayToolView ()

    @property (nonatomic, strong) NSMutableArray *dataList;//支付方式

    @property (nonatomic, strong) UIView *headerView;

    @property (nonatomic, strong) PayToolFooterView *footerView;

    @property (nonatomic, assign) NSInteger index;

    @property (nonatomic, strong) NSString *payType;//支付类型

    @end

    @implementation PayToolView

    static PayToolView *_toolView;

    +(instancetype)instanceView {

    _toolView = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([PayToolView class]) owner:nil options:nil].lastObject;

    return _toolView;

    }

    - (void)awakeFromNib {

    [super awakeFromNib];

    self.tableView.delegate = self;

    self.tableView.dataSource = self;

    [self addSubview:self.footerView];

    [self bringSubviewToFront:self.footerView];

    [self.footerView mas_makeConstraints:^(MASConstraintMaker *make) {

    make.left.right.equalTo(self);

    make.bottom.equalTo(self).offset(0);

    make.height.equalTo(@150);

    }];

    self.tableView.backgroundColor = [UIColor whiteColor];

    self.tableView.alpha = 1;

    [self.tableView  registerNib:[UINib nibWithNibName:NSStringFromClass([PayToolCell class]) bundle:nil] forCellReuseIdentifier:NSStringFromClass([PayToolCell class])];

    self.userInteractionEnabled = YES;

    [self installReloadData];

    NSDictionary *dic = self.dataList.firstObject;

    self.payType = [dic valueForKey:@"type"];

    self.tableViewHeight.constant = 150 + 56 *self.dataList.count + 100 + FB_FIX_SIZE_HEIGHT(50);//tableView的高度,不是很规范这样写

    }

    #pragma mark ---tableView delegate

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.dataList.count;

    }

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 56;

    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    PayToolCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([PayToolCell class]) forIndexPath:indexPath];

    NSDictionary *dic = self.dataList[indexPath.row];

    cell.imgView.image = [UIImage imageNamed:[dic valueForKey:@"image"]];

    cell.toolTypeLabel.text = [dic valueForKey:@"title"];

    cell.detailLael.text = [dic valueForKey:@"detail"];

    cell.payType = [dic valueForKey:@"type"];

    __weak typeof(self)weakSelf = self;

    [cell setSelectedPayTool:^(NSString *type) {

    __strong typeof(weakSelf)strongSelf = weakSelf;

    weakSelf.index = indexPath.row;

    [strongSelf.tableView reloadData];

    self.payType = type;

    }];

    cell.hasSelected = self.index == indexPath.row;

    return cell;

    }

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    self.index = indexPath.row;

    [self.tableView reloadData];

    PayToolCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    self.payType = cell.payType;

    }

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 80)];

    view.backgroundColor = [UIColor whiteColor];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, SCREEN_WIDTH, 40)];

    titleLabel.backgroundColor = [UIColor whiteColor];

    titleLabel.textAlignment = NSTextAlignmentCenter;

    titleLabel.text = @"付款详情";

    titleLabel.textColor = [UIColor blackColor];

    [view addSubview:titleLabel];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, titleLabel.bottom + 10, SCREEN_WIDTH, 30)];

    label.textAlignment = NSTextAlignmentLeft;

    label.font = [UIFont systemFontOfSize:14];

    label.textColor = [UIColor darkGrayColor];

    label.backgroundColor = [UIColor whiteColor];

    label.text = @"付款方式";

    [view addSubview:label];

    return view;

    }

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    return 90;

    }

    #pragma mark --actions//点击空白处隐藏

    - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint point = [touch locationInView:self];

    if (point.y < SCREEN_HEIGHT - 400) {

    [UIView animateWithDuration:0.5 animations:^{

    self.alpha = 0;

    } completion:^(BOOL finished) {

    [self removeFromSuperview];

    }];

    }

    }

    //总价

    - (void)setTotalFee:(NSString *)totalFee {

    _totalFee = totalFee;

    self.footerView.totalFeeLabel.text = [NSString stringWithFormat:@"%@元",totalFee];

    }

    //点击支付按钮

    - (void)payAction:(UIButton *)sender {

    NSLog(@"%@--付款",self.footerView.totalFeeLabel.text);

    CGFloat total = [self.totalFee floatValue];

    //微信支付

    if ([self.payType isEqualToString:@"WeChat"]) {

    if ( [WXApi isWXAppInstalled]) {

    if ([WXApi isWXAppSupportApi]) {

    PayTool *tool = [PayTool shareInstance];

    [tool weChatPayWithTotalFee:[NSString stringWithFormat:@"%.0f",total] andOrderNo:self.orderNo];

    }else{

    NSLog(@"不支持微信支付");

    }

    }else {

    [MBProgressHUD showMessage:@"您的手机还没有安装微信,请选择其他支付方式" toView:self.superview hideAfterDelay:1];

    }

    //支付宝支付

    }else if ([self.payType isEqualToString:@"AliPay"]) {

    NSLog(@"支付-%@--%f",self.payType,total);

    PayTool *tool = [PayTool shareInstance];

    [tool aliPayWithOrderNo:self.orderNo andTotalFee:[NSString stringWithFormat:@"%.2f",total] andBody:@"可以商品中有,自己定义也可以" andSubject:@"可以商品中有,自己定义也可以"];

    }else {

    PayTool *tool = [PayTool shareInstance];

    [tool uppaymentWithOrderNo:self.orderNo andTotalFee:[NSString stringWithFormat:@"%.0f",total] withViewCOntroller:[self getViewController]];

    }

    }

    - (void)installReloadData {

    [self.dataList addObject:@{@"image":@"支付宝",@"title":@"支付宝支付",@"detail":@"支付宝安全支付",@"type":@"AliPay"}];

    if ([WXApi isWXAppInstalled]) {

    [self.dataList addObject:@{@"image":@"微信",@"title":@"微信支付",@"detail":@"微信安全支付",@"type":@"WeChat"}

    ];

    }

    [self.dataList addObject:@{@"image":@"uppayment",@"title":@"银联支付",@"detail":@"银联安全支付",@"type":@"UPPayment"}

    ];

    [self.tableView reloadData];

    }

    - (NSMutableArray *)dataList {

    if (!_dataList) {

    _dataList = [NSMutableArray array];

    }

    return _dataList;

    }

    - (UIView *)headerView {

    if(!_headerView) {

    _headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 60)];

    _headerView.backgroundColor = [UIColor whiteColor];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, SCREEN_WIDTH, 40)];

    titleLabel.backgroundColor = [UIColor whiteColor];

    [titleLabel sizeToFit];

    titleLabel.textAlignment = NSTextAlignmentCenter;

    titleLabel.text = @"付款详情";

    [_headerView addSubview:titleLabel];

    }

    return _headerView;

    }

    - (PayToolFooterView *)footerView {

    if (!_footerView) {

    _footerView = [PayToolFooterView instanceView];

    [_footerView.payButton addTarget:self action:@selector(payAction:) forControlEvents:UIControlEventTouchUpInside];

    }

    return _footerView;

    }

    @end

    支付的封装:进入正题,上面的支付页面可以看到#import "PayTool.h",这里就封装了三个支付了,OK,开始贴代码(前提是你的后台已经把三个平台的订单信息都处理好了,后台处理肯定是比较安全的)

    PayTool.h代码

    (这里的网络请求都是我项目中已经封装的,本地服务器的数据请求每个人的习惯不一样,大家替换成自己的就好)

    #import#import "WXParamModel.h"

    @interface PayTool : NSObject

    +(PayTool *)shareInstance;

    //微信支付

    - (void)weChatPayWithTotalFee:(NSString *)totalFee andOrderNo:(NSString *)orderNo;

    //支付宝支付

    - (void)aliPayWithOrderNo:(NSString *)orderNo andTotalFee:(NSString *)totalFee andBody:(NSString *)body andSubject:(NSString *)subject;

    //银联

    - (void)uppaymentWithOrderNo:(NSString *)orderNo andTotalFee:(NSString *)totalFee withViewCOntroller:(UIViewController *)viewController;

    @end

    PayTool.mm代码

    (这里为什么用.mm?由于银联的原因,银联的文档说的比较清楚)

    #import "PayTool.h"

    #import "WXApi.h"

    #import "UPPaymentControl.h"

    @interface PayTool ()

    @property (nonatomic, strong) UPPaymentControl *payment;

    @end

    static PayTool *_tool;

    @implementation PayTool

    +(PayTool *)shareInstance {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    _tool = [[PayTool alloc] init];

    });

    return _tool;

    }

    //预支付码微信

    -(void)weChatPayWithTotalFee:(NSString *)totalFee andOrderNo:(NSString *)orderNo {

    UserModel *user = [UserLocal user];

    //LYHttpTool是我自己的数据请求方法

    [LYHttpTool requestDateWithUrlString:WX_PREPAY_URL

    params:@{

    @"Access_Token":ACCESS_TOKEN,

    @"orderNo":orderNo,

    @"UserId":user.MemberID,

    @"chargeamount":totalFee,

    @"spbill_create_ip":[DeviceTool publicNetworkIp]

    }

    showAllResponse:YES

    success:^(id responseObject) {

    NSString *Error = [responseObject valueForKey:@"Error"];

    NSInteger errcorCode = [Error integerValue];

    if (errcorCode == 0) {

    WXParamModel *model = [WXParamModel mj_objectWithKeyValues:[responseObject valueForKey:@"Result"]];

    [self dealWithWXPay:model];

    }

    } failure:^(NSString *errorMsg) {

    }];

    }

    //向微信发起支付

    - (void)dealWithWXPay:(WXParamModel *)model {

    PayReq *req = [[PayReq alloc] init];

    req.partnerId = model.partnerId;

    req.prepayId = model.prepayId;

    req.package = model.packageValue;

    req.nonceStr = model.nonceStr;

    req.timeStamp = model.timeStamp;

    req.sign = model.sign;

    [WXApi sendReq:req];

    }

    //支付宝

    - (void)aliPayWithOrderNo:(NSString *)orderNo andTotalFee:(NSString *)totalFee andBody:(NSString *)body andSubject:(NSString *)subject {

    //向自己的服务器请求订单信息

    [LYHttpTool requestDateWithUrlString:ALI_PAY_PAYMENT

    params:@{

    @"Access_Token":ACCESS_TOKEN,

    @"Body":body,

    @"Subject":subject,

    @"TotalAmount":totalFee,

    @"ProductCode":@"QUICK_MSECURITY_PAY",

    @"OutTradeNo":orderNo,

    @"TimeoutExpress":@"30m"

    }

    showAllResponse:YES

    success:^(id responseObject) {

    NSString *order = [responseObject valueForKey:@"Result"];

    [[AlipaySDK defaultService] payOrder:order fromScheme:@"alisdkLicaishen" callback:^(NSDictionary *resultDic) {

    NSInteger resultCode = [resultDic[@"resultStatus"] integerValue];

    switch (resultCode) {

    case 9000:    //支付成功

    NSLog(@"支付成功");

    break;

    case 6001:    //支付取消

    NSLog(@"支付取消");

    break;

    default:        //支付失败

    NSLog(@"支付失败");

    break;

    }

    }];

    } failure:^(NSString *errorMsg) {

    }];

    }

    //银联

    - (void)uppaymentWithOrderNo:(NSString *)orderNo andTotalFee:(NSString *)totalFee withViewCOntroller:(UIViewController *)viewController {

    NSInteger fee = [totalFee integerValue];

    NSInteger fenFee = fee * 10 *10;

    NSString *money = [NSString stringWithFormat:@"%ld",(long)fenFee];

    //向自己的服务器请求订单信息

    [LYHttpTool requestDateWithUrlString:UPPAYMENT_TN_URL

    params:@{@"Access_Token":ACCESS_TOKEN,

    @"orderId":orderNo,

    @"txnAmt":money}

    showAllResponse:YES

    success:^(id responseObject) {

    NSLog(@"%@",responseObject);

    NSString *error = [responseObject valueForKey:@"Error"];

    if ([error integerValue] == 0) {

    [self.payment startPay:[responseObject valueForKey:@"Result"]

    fromScheme:@"licaishenUPPayment"

    mode:@"00"

    viewController:viewController];

    }

    } failure:^(NSString *errorMsg) {

    NSLog(@"%@",errorMsg);

    }];

    }

    - (UPPaymentControl *)payment {

    if (!_payment) {

    _payment = [UPPaymentControl defaultControl];

    }

    return _payment;

    }

    @end

    ok ,上面还用到了一个WXParamModel,这个是后台请求下来的微信预支付的订单信息,直接给图吧这个:

    微信预支付订单信息Model

    回调:在上面的tool中,支付宝的结果是有的,但是好像并没有什么卵用,所以回调还是在Appdelegate 中.(用通知的方式通知其他类,以方便自己做处理)

    一样,直接贴代码:

    #pragma mark --支付回调

    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options {

    NSLog(@"%@",url);

    //处理支付宝支付结果

    if ([url.host isEqualToString:@"safepay"]) {

    [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {

    NSLog(@"result = %@",resultDic);

    [[NSNotificationCenter defaultCenter] postNotificationName:ALIPayResult object:resultDic];

    }];

    }else if ([url.host isEqualToString:@"pay"]) {

    // 处理微信的支付结果

    [WXApi handleOpenURL:url delegate:self];

    }else if ([url.host isEqualToString:@"uppayresult"]) {

    //银联支付结果

    NSString *result = [AppDelegate setupUPPaymentResultWithUrl:url];

    NSLog(@"%@",result);

    [[NSNotificationCenter defaultCenter] postNotificationName:UPPaymentResult object:[NSDictionary dictionaryWithObject:result forKey:@"result"]];

    }

    return YES;

    }

    处理银联支付的时候我用了一个AppDelegate+UPPayment,原因还是因为用到银联要用.mm.

    .h文件

    #import "AppDelegate.h"

    @interface AppDelegate (UPPayment)

    + (NSString *)setupUPPaymentResultWithUrl:(NSURL *)url;

    @end

    .mm文件

    #import "AppDelegate+UPPayment.h"

    #import "UPPaymentControl.h"

    @implementation AppDelegate (UPPayment)

    + (NSString *)setupUPPaymentResultWithUrl:(NSURL *)url {

    UPPaymentControl *control = [UPPaymentControl defaultControl];

    __block NSString *resultCode;

    [control handlePaymentResult:url completeBlock:^(NSString *code, NSDictionary *data) {

    resultCode = code;

    }];

    return resultCode;

    }

    @end

    OK,到这里,支付就基本完成了!希望能对大家有帮助.有问题希望大家可以提出来,大家一起探讨完善.

    支付demo(需要将链接,Key等换成自己公司的才可运行成功)

    相关文章

      网友评论

        本文标题:iOS支付封装(微信,支付宝,银联)

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