支付相关总览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,到这里,支付就基本完成了!希望能对大家有帮助.有问题希望大家可以提出来,大家一起探讨完善.
网友评论