您的位置:首页 > 移动开发

iOS调起微信,qq,支付宝app支付总结

2015-08-19 09:26 886 查看

一.调起微信支付

申请应用id见官方文档

需要的资源文件SDK文件包括 libWeChatSDK.a,WXApi.h,WXApiObject.h

info中添加申请的微信key,idenfifirer为weixin,urlSchema为申请的key

appdelegate中添加如下代码:

//如果是微信的话 那么
- (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为计算出的结果,大小写一定要对应正确

二.调起QQ支付

已有appname和appkey,appname用于url,app之间跳转,identifier为appname,url为urlschema的内容.添加到info的url中.

appdelegate中注册,并在url代理方法中添加返回结果的处理代码,如下:

- (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.在实际支付集成中尽量把每一个参数都对应好,很多错误是没有错误日志.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: