1,微信支付:微信支付其實(shí)還好,文檔比較清楚:1,請(qǐng)求預(yù)支付碼(服務(wù)器需要跟微信做好處理);2,發(fā)起支付;
2,支付寶支付:支付寶,額...略坑,在這里就不說簽約的那些坑了,簽約的問題可以直接去平臺(tái)搞定,遇到問題基本網(wǎng)上也有解決辦法.在ios端,主要有兩個(gè)步驟:1,支付寶獲取訂單信息(服務(wù)器去跟支付寶做好處理);2,發(fā)起支付.
3,銀聯(lián)支付:銀聯(lián)支付一般性的用的比較少,所以可能會(huì)有人覺得很難,其實(shí)不然,銀聯(lián)支付感覺比微信支付更簡單(當(dāng)然只是對(duì)一個(gè)程序員來說而已,使用起來還是挺麻煩的).銀聯(lián)的平臺(tái)提供了很多方式,在我們當(dāng)然是選擇手機(jī)控件支付咯.下載文檔后,里面的SDK和文檔說明都是非常清楚的,當(dāng)然還有測(cè)試和開發(fā)的區(qū)別的.也是主要兩個(gè)步驟需要移動(dòng)端完成:1,本地服務(wù)器請(qǐng)求訂單信息(tn);2,發(fā)起支付;
支付界面:(這里我把我自己的支付界面貼出來,當(dāng)然不同的設(shè)計(jì)肯定也是不同的,但是都是大同小異)
微信進(jìn)行了是否安裝的處理,沒安裝顯然就不顯示了,因?yàn)槲⑿乓呀?jīng)不支持網(wǎng)頁支付了,支付寶和銀聯(lián)就不用了,他們沒有安裝app也可以支付.(我這里是模擬器,就沒有顯示微信了,手機(jī)上還是有的).
直接上代碼,就不截圖了,直接代碼貼上來吧.(我是代碼+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的高度,不是很規(guī)范這樣寫
}
#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//點(diǎn)擊空白處隱藏
- (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];
}];
}
}
//總價(jià)
- (void)setTotalFee:(NSString *)totalFee {
_totalFee = totalFee;
self.footerView.totalFeeLabel.text = [NSString stringWithFormat:@"%@元",totalFee];
}
//點(diǎn)擊支付按鈕
- (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:@"您的手機(jī)還沒有安裝微信,請(qǐng)選擇其他支付方式" 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":@"銀聯(lián)支付",@"detail":@"銀聯(lián)安全支付",@"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
支付的封裝:進(jìn)入正題,上面的支付頁面可以看到#import "PayTool.h",這里就封裝了三個(gè)支付了,OK,開始貼代碼(前提是你的后臺(tái)已經(jīng)把三個(gè)平臺(tái)的訂單信息都處理好了,后臺(tái)處理肯定是比較安全的)
PayTool.h代碼
(這里的網(wǎng)絡(luò)請(qǐng)求都是我項(xiàng)目中已經(jīng)封裝的,本地服務(wù)器的數(shù)據(jù)請(qǐng)求每個(gè)人的習(xí)慣不一樣,大家替換成自己的就好)
#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;
//銀聯(lián)
- (void)uppaymentWithOrderNo:(NSString *)orderNo andTotalFee:(NSString *)totalFee withViewCOntroller:(UIViewController *)viewController;
@end
PayTool.mm代碼
(這里為什么用.mm?由于銀聯(lián)的原因,銀聯(lián)的文檔說的比較清楚)
#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;
}
//預(yù)支付碼微信
-(void)weChatPayWithTotalFee:(NSString *)totalFee andOrderNo:(NSString *)orderNo {
UserModel *user = [UserLocal user];
//LYHttpTool是我自己的數(shù)據(jù)請(qǐng)求方法
[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) {
}];
}
//向微信發(fā)起支付
- (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 {
//向自己的服務(wù)器請(qǐng)求訂單信息
[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) {
}];
}
//銀聯(lián)
- (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];
//向自己的服務(wù)器請(qǐng)求訂單信息
[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 ,上面還用到了一個(gè)WXParamModel,這個(gè)是后臺(tái)請(qǐng)求下來的微信預(yù)支付的訂單信息,直接給圖吧這個(gè):
回調(diào):在上面的tool中,支付寶的結(jié)果是有的,但是好像并沒有什么卵用,所以回調(diào)還是在Appdelegate 中.(用通知的方式通知其他類,以方便自己做處理)
一樣,直接貼代碼:
#pragma mark --支付回調(diào)
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options {
NSLog(@"%@",url);
//處理支付寶支付結(jié)果
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"]) {
// 處理微信的支付結(jié)果
[WXApi handleOpenURL:url delegate:self];
}else if ([url.host isEqualToString:@"uppayresult"]) {
//銀聯(lián)支付結(jié)果
NSString *result = [AppDelegate setupUPPaymentResultWithUrl:url];
NSLog(@"%@",result);
[[NSNotificationCenter defaultCenter] postNotificationName:UPPaymentResult object:[NSDictionary dictionaryWithObject:result forKey:@"result"]];
}
return YES;
}
處理銀聯(lián)支付的時(shí)候我用了一個(gè)AppDelegate+UPPayment,原因還是因?yàn)橛玫姐y聯(lián)要用.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,到這里,支付就基本完成了!希望能對(duì)大家有幫助.有問題希望大家可以提出來,大家一起探討完善.