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

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等换成自己公司的才可运行成功)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容