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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容