iOS支付封裝(微信,支付寶,銀聯(lián))

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ā)起支付;


支付相關(guān)總覽


支付界面:(這里我把我自己的支付界面貼出來,當(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è):


微信預(yù)支付訂單信息Model

回調(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ì)大家有幫助.有問題希望大家可以提出來,大家一起探討完善.

支付demo(需要將鏈接,Key等換成自己公司的才可運(yùn)行成功)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子寂嘉,更是在濱河造成了極大的恐慌押搪,老刑警劉巖纯陨,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暖璧,死亡現(xiàn)場(chǎng)離奇詭異碱蒙,居然都是意外死亡琴儿,警方通過查閱死者的電腦和手機(jī)役衡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門茵休,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人映挂,你說我怎么就攤上這事泽篮。” “怎么了柑船?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵帽撑,是天一觀的道長。 經(jīng)常有香客問我鞍时,道長亏拉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任逆巍,我火速辦了婚禮及塘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锐极。我一直安慰自己笙僚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布灵再。 她就那樣靜靜地躺著肋层,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翎迁。 梳的紋絲不亂的頭發(fā)上栋猖,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音汪榔,去河邊找鬼蒲拉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛痴腌,可吹牛的內(nèi)容都是我干的雌团。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼士聪,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼锦援!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起戚嗅,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤雨涛,失蹤者是張志新(化名)和其女友劉穎枢舶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體替久,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凉泄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蚯根。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片后众。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖颅拦,靈堂內(nèi)的尸體忽然破棺而出蒂誉,到底是詐尸還是另有隱情,我是刑警寧澤距帅,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布右锨,位于F島的核電站,受9級(jí)特大地震影響碌秸,放射性物質(zhì)發(fā)生泄漏绍移。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一讥电、第九天 我趴在偏房一處隱蔽的房頂上張望蹂窖。 院中可真熱鬧,春花似錦恩敌、人聲如沸瞬测。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽月趟。三九已至,卻和暖如春抗碰,著一層夾襖步出監(jiān)牢的瞬間狮斗,已是汗流浹背绽乔。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工弧蝇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人折砸。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓看疗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睦授。 傳聞我的和親對(duì)象是個(gè)殘疾皇子两芳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容