//如果是微信的话 那么
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if([[url absoluteString] hasPrefix:ONEWeiXin]) {
[WXApi handleOpenURL:url delegate:self];
}
//other ...
return YES;
}
//appdelegate 为代理实现下面两个代理方法处理请求和返回
-(void) onReq:(BaseReq*)req {
DDLogInfo(@"wx :openid - >%@",req.openID);
}
//处理微信回调结果
-(void) onResp:(BaseResp*)resp {
if ([resp isKindOfClass:[PayResp class]]) {
if (payResponse.errCode == WXSuccess) {
//微信SDK支付成功消息
NSLog(@"PayResp WXSuccess");
//微信SDK支付成功
}
else {
//用户取消微信支付
if (payResponse.errCode == WXErrCodeUserCancel) {
//微信SDK用户取消微信支付,无需处理
NSLog(@"PayResp WXErrCodeUserCancel");
}
//其他错误
else {
//微信SDK其他支付错误
NSString *eventStr = [NSString stringWithFormat:@"PayResp error other:%d", payResponse.errCode];
NSLog(@"%@", eventStr);
}
}
}
}
在微信实际调起代码中加入如下代码:
- (void)launchWxpay {
//使用appid注册微信
BOOL registerApp = [WXApi registerApp:@"##"];
if (!registerApp) {
NSLog(@"WXApi registerApp Failed!");
}
ONEPrePayResponse *prepay = [[ONEPayStore sharedInstance] prePayData];
prepay.package = @"Sign=WXPay";
PayReq *payRequest = [[PayReq alloc] init];
payRequest.openID = prepay.appid;
payRequest.partnerId = prepay.partnerid;
payRequest.prepayId = prepay.prepayid;
payRequest.nonceStr = [prepay.noncestr stringValue];
payRequest.timeStamp = [prepay.timestamp intValue];
payRequest.package = prepay.package;
payRequest.sign = [self generateSignWithPay:prepay];
BOOL isResult = [WXApi sendReq:payRequest];
if (isResult) {
//添加事件监听微信支付成功消息
[self addNotifications];
}
else {
if (![WXApi isWXAppInstalled]) {
NSString *tipMsg = @"您的手机未安装手机微信或微信版本过低,请升级微信后方可使用微信支付";
[UIAlertView alertWithCallBackBlock:^(NSInteger buttonIndex) {}
title:@""
message:tipMsg
cancelButtonName:@"我知道了"
otherButtonTitles:nil, nil];
[self postNotificationWithStatus:ONEPayState_WeiXinPay_NotInstalled];
return;
}
else {
//用户手机未安装微信、微信版本太低、微信客户端卡住、WXApi的registerApp的appid参数有误
[UIAlertView alertWithCallBackBlock:^(NSInteger buttonIndex) {}
title:nil
message:@"支付繁忙,请稍候再试~"
cancelButtonName:@"确定"
otherButtonTitles:nil, nil];
[self postNotificationWithStatus:ONEPayState_WeiXinPay_Fail];
}
}
}
//计算签名
- (NSString *)generateSignWithPay:(ONEPrePayResponse *)response
{
// 构造参数列表
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setValue:kWebChatKey forKey:@"appid"];
[params setValue:response.appkey forKey:@"appkey"];
[params setValue:[NSString stringWithFormat:@"%@",response.noncestr] forKey:@"noncestr"];
[params setValue:response.package forKey:@"package"];
[params setValue:response.partnerid forKey:@"partnerid"];
[params setValue:response.prepayid forKey:@"prepayid"];
[params setValue:response.timestamp forKey:@"timestamp"];
NSArray *keys = [params allKeys];
keys = [keys sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
return [str1 compare:str2];
}];
NSMutableString *sig = [NSMutableString string];
for (int i = 0; i < [keys count]; ++i) {
NSString *key = [keys objectAtIndex:i];
NSString *value = [params objectForKey:key];
[sig appendString:key];
[sig appendString:@"="];
[sig appendString:value];
[sig appendString:@"&"];
}
NSString *signStr = [sig substringToIndex:sig.length - 1];
return [WeChatPayWay sha1:signStr];
}
+ (NSString *)sha1:(NSString *)str
{
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
{
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
注意package固定值,sign为计算出的结果,大小写一定要对应正确
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/*注册qq钱包支付*/
[QQWalletSDK registerQQWalletApplication:ONEQQPay // app id
urlScheme:kQQpayURLScheme
name:kQQpayAppName];
//....
}
//处理url
#pragma mark - UIApplicationDelegate
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
//处理qq钱包支付流程
[QQWalletSDK QQWalletSDKHanldeApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];
return YES;
}
//调用代码
/*
开始q钱包支付
0 --- 成功
1 --- 支付过程中用户取消
3 --- 参数错误
-11000 --- 用户操作中离线(可能同帐号在其他设备登录)
-11001 --- 支付过程中用户取消
-11003 --- 参数错误
28027608 -- 用户绑卡过程中,手机号码与帐号登记的号码不符合,无法继续
28027201 -- 该订单已经支付
66210007 -- 帐号未登录,或者登录已超时
*/
- (void)launchQQPay {
if (![QQWalletSDK isSupportQQWallet]) {
[UIAlertView alertWithCallBackBlock:^(NSInteger buttonIndex) {}
title:nil
message:@"请先安装手机QQ"
cancelButtonName:@"确定"
otherButtonTitles:nil, nil];
} else {
ONEPrePayResponse *resp = [[ONEPayStore sharedInstance] prePayData];
if (!resp.appId || !resp.bargainorId || !resp.token_id || !resp.sig || !resp.nonce) {
DDLogInfo(@"qqpay resp: %@", resp);
[UIAlertView alertWithCallBackBlock:^(NSInteger buttonIndex) {} title:nil message:@"QQ钱包支付失败,请稍后再试!" cancelButtonName:@"确定" otherButtonTitles:nil, nil];
} else {
[QQWalletSDK startPayWithAppId:resp.appId bargainorId:resp.bargainorId tokenId:resp.token_id signature:resp.sig nonce:resp.nonce completion:^(QWMessage *message, NSError *error) {
/**
0 --- 成功
1 --- 支付过程中用户取消
3 --- 参数错误
-11000 --- 用户操作中离线(可能同帐号在其他设备登录)
-11001 --- 支付过程中用户取消
-11003 --- 参数错误
28027608 -- 用户绑卡过程中,手机号码与帐号登记的号码不符合,无法继续
28027201 -- 该订单已经支付
66210007 -- 帐号未登录,或者登录已超时
*/
ONEOrderPayStatus status = ONEPayState_default;
if (error) {
DDLogError(@"%@",[error localizedDescription]);
status = PayState_QQPay_PayError;
} else {
switch (message.code) {
case 0:
status = PayState_QQPay_PaySuccess;
break;
case 1:
case 11001:
status = PayState_QQPay_PayCancel;
break;
case 3:
status = PayState_QQPay_PayParamError;
break;
case 11000:
status = PayState_QQPay_PayOffeline;
break;
case 28027608:
status = PayState_QQPay_PayPhoneNumError;
break;
case 28027201:
status = PayState_QQPay_PayHavePaid;
break;
case 66210007:
status = PayState_QQPay_PayLoginError;
default:
break;
}
}
[self postNotificationWithStatus:status];
}];
}
}
}
注意bundleid一定要对应对.
1.appdelegate中处理url代码里添加跳转处理代码,这里处理回调
if([[url absoluteString] hasPrefix:AliPay]){//支付宝支付的key,是申请的
//如果极简 SDK 不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给 SDK
if ([url.host isEqualToString:@"safepay"]) {
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"safepay result = %@",resultDic);
}];
}
if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"platformapi result = %@",resultDic);
}];
}
}
2.实际调起代码如下
- (void)launchAliPay {
@weakify(self)
[[AlipaySDK defaultService] payOrder:prepay.prepaystr fromScheme:prepay.appkey callback:^(NSDictionary *resultDic) {
@strongify(self)
int completeState = ONEPayState_default;
int resCode = [[resultDic objectForKey:@"resultStatus"] intValue];
NSString * resultStr = [resultDic objectForKey:@"result"];
NSString *trueStr = @"";
if(resultStr && [resultStr length] > 0){
NSString *subStr = @"&success=";
NSRange range = [resultStr rangeOfString:subStr];
if(resultStr.length > range.length + 5){//起码大于5以上 才能截取5
trueStr = [resultStr substringWithRange:NSMakeRange (range.location+ range.length + 1, 4)];
}
}
if (resCode == 9000 && [trueStr isEqualToString:@"true"])//支付成功
{
completeState = PayState_Alipay_PaySucess;
}else if (resCode == 8000){
completeState = PayState_Alipay_PayIng;
}else if (resCode == 4000){
completeState = PayState_Alipay_PayError;
}else if (resCode == 6001){
completeState = PayState_Alipay_PayCancel;
}else if (resCode == 6002){
completeState = PayState_Alipay_NetError;
}else {
completeState = PayState_Alipay_NotKnow_Error;
}
[self postNotificationWithStatus:completeState];
}];
}
支付宝的秘钥等放在服务端,有服务端传递回参数
ps.在实际支付集成中尽量把每一个参数都对应好,很多错误是没有错误日志.