關(guān)于支付這塊秤朗,之前項(xiàng)目用的是Ping++支付,前些日子換成了官方SDK原生支付光坝,為了使用方便,我封裝了一下甥材,現(xiàn)分享出來供iOS程序猿(媛)們參考和指導(dǎo)盯另。
前言:關(guān)于支付必要的配置,官方文檔說的很清楚了洲赵,這塊就不細(xì)講了(挺頭疼的土铺,坑多)。以下主要針對的代碼封裝:
- 聲明一個單例類
static id _instance;
+(instancetype)sharedApi
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[MJPayApi alloc] init];
});
return _instance;
}
- 把支付返回的可能Code碼枚舉出來
typedef NS_ENUM(NSInteger, PayCode) {
WXSUCESS = 1001, /**< 成功 */
WXERROR = 1002, /**< 失敗 */
WXSCANCEL = 1003, /**< 取消 */
WXERROR_NOTINSTALL = 1004, /**< 未安裝微信 */
WXERROR_UNSUPPORT = 1005, /**< 微信不支持 */
WXERROR_PARAM = 1006, /**< 支付參數(shù)解析錯誤 */
ALIPAYSUCESS = 1101, /**< 支付寶支付成功 */
ALIPAYERROR = 1102, /**< 支付寶支付錯誤 */
ALIPAYCANCEL = 1103, /**< 支付寶支付取消 */
};
微信支付
- 發(fā)起微信支付
- (void)wxPayWithPayParam:(NSString *)pay_param
success:(void (^)(PayCode code))successBlock
failure:(void (^)(PayCode code))failBlock {
self.PaySuccess = successBlock;
self.PayError = failBlock;
//Json解析
NSData * data = [pay_param dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if(error != nil) {
failBlock(WXERROR_PARAM);
return ;
}
//設(shè)置必要的參數(shù)
NSString *appid = dic[@"appid"];
NSString *partnerid = dic[@"partnerid"];
NSString *prepayid = dic[@"prepayid"];
NSString *package = @"Sign=WXPay";
NSString *noncestr = dic[@"noncestr"];
NSString *timestamp = dic[@"timestamp"];
NSString *sign = dic[@"paySign"];
[WXApi registerApp:appid];
if(![WXApi isWXAppInstalled]) {
failBlock(WXERROR_NOTINSTALL);
return ;
}
if (![WXApi isWXAppSupportApi]) {
failBlock(WXERROR_UNSUPPORT);
return ;
}
//發(fā)起微信支付
PayReq* req = [[PayReq alloc] init];
//微信分配的商戶號
req.partnerId = partnerid;
//微信返回的支付交易會話ID
req.prepayId = prepayid;
// 隨機(jī)字符串板鬓,不長于32位
req.nonceStr = noncestr;
// 時間戳
req.timeStamp = timestamp.intValue;
//暫填寫固定值Sign=WXPay
req.package = package;
//簽名
req.sign = sign;
[WXApi sendReq:req];
//日志輸出
MJLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",appid,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
}
- 支付回調(diào)
// 微信終端返回給第三方的關(guān)于支付結(jié)果的結(jié)構(gòu)體
- (void)onResp:(BaseResp *)resp
{
if ([resp isKindOfClass:[PayResp class]])
{
switch (resp.errCode) {
case WXSuccess:
self.PaySuccess(WXSUCESS);
break;
case WXErrCodeUserCancel: //用戶點(diǎn)擊取消并返回
self.PayError(WXSCANCEL);
break;
default: //剩余都是支付失敗
self.PayError(WXERROR);
break;
}
}
}
- 單例類回調(diào)處理
-(BOOL) handleOpenURL:(NSURL *) url
{
//([url.host isEqualToString:@"pay"]) //微信支付
return [WXApi handleOpenURL:url delegate:self];
}
支付寶支付
- 支付寶支付
-(void)aliPayWithPayParam:(NSString *)pay_param
success:(void (^)(PayCode code))successBlock
failure:(void (^)(PayCode code))failBlock
{
self.PaySuccess = successBlock;
self.PayError = failBlock;
NSString * appScheme = @"APP Scheme";
//注:若公司服務(wù)器返回的json串可以直接使用悲敷,就不用下面的json解析了
NSData *jsonData = [pay_param dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
if(err) {
NSLog(@"json解析失敗:%@",err);
}
NSString * orderSS = [NSString stringWithFormat:@"app_id=%@&biz_content=%@&charset=%@&method=%@&sign_type=%@×tamp=%@&version=%@&format=%@¬ify_url=%@",dic[@"app_id"],dic[@"biz_content"],dic[@"charset"],dic[@"method"],dic[@"sign_type"],dic[@"timestamp"],dic[@"version"],dic[@"format"],dic[@"notify_url"]];
NSString * signedStr = [self urlEncodedString:dic[@"sign"]];
NSString * orderString = [NSString stringWithFormat:@"%@&sign=%@",orderSS, signedStr];
// MJLog(@"===%@",orderSS);
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
MJLog(@"----- %@",resultDic);
NSInteger resultCode = [resultDic[@"resultStatus"] integerValue];
switch (resultCode) {
case 9000: //支付成功
successBlock(ALIPAYSUCESS);
break;
case 6001: //支付取消
failBlock(ALIPAYCANCEL);
break;
default: //支付失敗
failBlock(ALIPAYERROR);
break;
}
}];
}
//url 編碼
- (NSString*)urlEncodedString:(NSString *)string
{
NSString * encodedString = (__bridge_transfer NSString*) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8 );
return encodedString;
}
- 單例類回調(diào)處理
- (BOOL) handleOpenURL:(NSURL *) url
{
if ([url.host isEqualToString:@"safepay"])
{
// 支付跳轉(zhuǎn)支付寶錢包進(jìn)行支付俭令,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳轉(zhuǎn)支付寶客戶端支付的過程中后德,商戶app在后臺很可能被系統(tǒng)kill了,所以pay接口的callback就會失效抄腔,請商戶對standbyCallback返回的回調(diào)結(jié)果進(jìn)行處理,就是在這個方法里面處理跟callback一樣的邏輯】
NSLog(@"result = %@",resultDic);
NSInteger resultCode = [resultDic[@"resultStatus"] integerValue];
switch (resultCode) {
case 9000: //支付成功
self.PaySuccess(ALIPAYSUCESS);
break;
case 6001: //支付取消
self.PaySuccess(ALIPAYCANCEL);
break;
default: //支付失敗
self.PaySuccess(ALIPAYERROR);
break;
}
}];
// 授權(quán)跳轉(zhuǎn)支付寶錢包進(jìn)行支付瓢湃,處理支付結(jié)果
[[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
MJLog(@"result = %@",resultDic);
// 解析 auth code
NSString *result = resultDic[@"result"];
NSString *authCode = nil;
if (result.length>0) {
NSArray *resultArr = [result componentsSeparatedByString:@"&"];
for (NSString *subResult in resultArr) {
if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
authCode = [subResult substringFromIndex:10];
break;
}
}
}
MJLog(@"授權(quán)結(jié)果 authCode = %@", authCode?:@"");
}];
return YES;
}
}
支付調(diào)用
好了,哪里用到寫哪里
- 微信
[[MJPayApi sharedApi]wxPayWithPayParam:data success:^(PayCode code)
{
[self payStatus:code Co_nbr:co_nbr];
} failure:^(PayCode code) {
[self payStatus:code Co_nbr:co_nbr];
}];
- 支付寶
[[MJPayApi sharedApi]aliPayWithPayParam:data success:^(PayCode code)
{
[self payStatus:code Co_nbr:co_nbr];
} failure:^(PayCode code) {
[self payStatus:code Co_nbr:co_nbr];
}];
是不是很簡單那~~~
重要:
封裝好之后赫蛇,收到了好多簡友的留言和私信绵患,所以抽個時間把項(xiàng)目傳到了github,如果能給正在蹲坑的碼友們一絲幫助悟耘,請標(biāo)個※星※落蝙。
Demo地址:喜歡,就標(biāo)個星吧