iOS支付封裝(微信/支付寶)
關于支付這塊,之前項目用的是Ping++支付,前些日子換成了官方SDK原生支付,為了使用方便,我封裝了一下,現分享出來供iOS程序猿(媛)們參考和指導。
前言:關于支付必要的配置,官方文檔說的很清楚了,這塊就不細講了(挺頭疼的,坑多)。以下主要針對的代碼封裝:
-
聲明一個單例類
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, /**< 支付參數解析錯誤 */
ALIPAYSUCESS = 1101, /**< 支付寶支付成功 */
ALIPAYERROR = 1102, /**< 支付寶支付錯誤 */
ALIPAYCANCEL = 1103, /**< 支付寶支付取消 */
};
微信支付
-
發起微信支付
- (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 ;
}
//設置必要的參數
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 ;
}
//發起微信支付
PayReq* req = [[PayReq alloc] init];
//微信分配的商戶號
req.partnerId = partnerid;
//微信返回的支付交易會話ID
req.prepayId = prepayid;
// 隨機字符串,不長于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 );
}
-
支付回調
// 微信終端返回給第三方的關于支付結果的結構體
- (void)onResp:(BaseResp *)resp
{
if ([resp isKindOfClass:[PayResp class]])
{
switch (resp.errCode) {
case WXSuccess:
self.PaySuccess(WXSUCESS);
break;
case WXErrCodeUserCancel: //用戶點擊取消并返回
self.PayError(WXSCANCEL);
break;
default: //剩余都是支付失敗
self.PayError(WXERROR);
break;
}
}
}
-
單例類回調處理
-(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";
//注:若公司服務器返回的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;
}
-
單例類回調處理
- (BOOL) handleOpenURL:(NSURL *) url
{
if ([url.host isEqualToString:@"safepay"])
{
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳轉支付寶客戶端支付的過程中,商戶app在后臺很可能被系統kill了,所以pay接口的callback就會失效,請商戶對standbyCallback返回的回調結果進行處理,就是在這個方法里面處理跟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;
}
}];
// 授權跳轉支付寶錢包進行支付,處理支付結果
[[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(@"授權結果 authCode = %@", authCode?:@"");
}];
return YES;
}
}
支付調用
好了,哪里用到寫哪里
-
微信
[[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];
}];
是不是很簡單那~~~
來自:http://www.jianshu.com/p/6105550fe070
本文由用戶 RonaldFerni 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!