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

微信支付,支付宝支付的集成和注意部分

2016-09-06 00:13 501 查看

一.支付宝支付

1. 集成说明

1.1 作为当下最热门的支付宝和微信支付,相信有很多的app都很乐意的将支付宝集成在app中,毕竟只要你开发的app有一点涉及到买卖的,都需要集成支付宝或者微信支付.那么接下来我将为大家一一列举举出我在集成支付宝和微信中遇到的难点和其中出现的一些坑.

2. 集成前的准备(里面的步骤在集成文档中都有介绍)

2.1 注册支付宝帐号(账户最好采用公司邮箱注册)——附上网址

https://www.baidu.com/s?wd=%E6%94%AF%E4%BB%98%E5%AE%9D%E5%BC%80%E5%8F%91%E8%80%85%E5%B9%B3%E5%8F%B0&rsv_spt=1&rsv_iqid=0xfe0a29290002df6b&issp=1&f=3&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=monline_3_dg&rsv_enter=1&rsv_sug3=14&rsv_sug1=10&rsv_sug7=100&rsv_sug2=0&prefixsug=%E6%94%AF%E4%BB%98%E5%AE%9D%E9%9B%86%E6%88%90&rsp=4&inputT=9885&rsv_sug4=10467


2.2 设置(申请)支付密码

2.3 设置密码提示问题

2.4 绑定手机

2.5 创建应用(目的 : 获取APPID帐号)

2.6 然后就等待支付宝那边审核通过了

3. 开始集成

3.1 打开集成文档

https://doc.open.alipay.com/


3.2 按步骤执行

3.2.1 点击文档中的 支付能力—->App支付—->SDK下载(https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1)—->SDK&DEMO(将demo和sdk下载下来)

3.2.2 运行支付宝支付Demo,了解支付宝整个支付的流程(如果里面出现错误,直接百度或者查看文档,里面有详细的解释,我这里就不再一一说明了)

4. 系统交互流程(红色部分是重点部分)



4.1 流程 : 商户客户端发送请求(获取签名后的订单信息)—->商户服务端(返回签名后的订单信息sign)—->调用支付宝支付接口,发送支付请求—->返回支付结果

5. 订单 : 由服务器生成

6. 注意 : 只需得到服务器返回的sign

7. 导入相关文件(此处导入文件最好看官方文档,比较正式)



8. 导入相关库

8.1 TARGETS—->General—->Linked Frameworks and Libraries—->点击”+”导入相关的库(此处导入的文件当已开发文档中规定的为主)

8.2 填写支付宝URL Schemes : TARGETS—-> info—-> URL Types(5)—-> 点击”+”对支付宝的添加(此处当已开发文档中规定的为主)—-> 结果图如下



9. 说明

9.1 支付宝的集成本来是和Demo上代码书写的顺序一样,但是由于我们后台是第一次做支付,所以最终无法返回一个正确的sign,这样导致我们集成的时候中间有一个步骤是多余的.

10. 集成

10.1 发送请求给后台,请求需要的字串(由于我们做的app设计到需要传入10个参数给后台,才能返回结果)—-> 下面贴上请求代码

long activityId = _activitiy.ActivityId;
NSString *stringActivityId = [@(activityId) stringValue];         //活动ID
NSString *userId = [AppConfig shareInstance].UserID;
//用户ID
[self.paramDic setObject:stringActivityId forKey:@"activityId"];
[self.paramDic setObject:userId forKey:@"userId"];
NSString *bodyStr = _activitiy.title;
NSString *subjectStr = _activitiy.title;
NSInteger total_amount = _activitiy.totalFee;
NSDateFormatter* formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDictionary *lastDic = @{
@"body":bodyStr,
@"subject":subjectStr,
@"total_amount":[NSString stringWithFormat:@"%.2ld",(long)total_amount],
@"spbillCreateip":[self deviceIPAdress]
};
NSMutableDictionary *bigDic = [lastDic mutableCopy];
[bigDic addEntriesFromDictionary:dic];


10.2 发送请求(里面包含了调用支付宝的接口)

[[[SpeedService alloc]init]FetchUserPayProduct:nil paramDic:bigDic completionBlock:^(id response, NSError *error) {
NSLog(@"++++%@",response);
//服务器返回的订单信息

NSDictionary *samllDic = [response objectForKey:@"result"];

//服务器返回的签名
NSString *sign = [samllDic objectForKey:@"sign"];
//签名Encode编码
NSString *locationSignEncode = [self encodeValue:sign];
//创建订单模型对象并且赋值
Order *order = [Order new];

order.biz_content = [BizContent new];

order.app_id             = [samllDic objectForKey:@"app_id"];
order.biz_content        = [samllDic objectForKey:@"biz_content"];

order.charset            = [samllDic objectForKey:@"charset"];
order.method             = [samllDic objectForKey:@"method"];
order.notify_url         = [samllDic objectForKey:@"notify_url"];
order.sign_type          = [samllDic objectForKey:@"sign_type"];
order.timestamp          = [samllDic objectForKey:@"timestamp"];
order.version            = [samllDic objectForKey:@"version"];

//订单信息Encode编码
NSString *messageEncode = [order orderInfoEncoded:YES];

//最终订单信息字符串Encode编码
NSString *orderOneString = [NSString stringWithFormat:@"%@&sign=%@",
messageEncode, locationSignEncode];

[[AlipaySDK defaultService] payOrder:orderOneString fromScheme:Scheme callback:^(NSDictionary *resultDic) {
NSLog(@"服务器返回的结果:%@",resultDic);
}];
}];


10.3 签名Encode编码

- (NSString*)encodeValue:(NSString*)value
{
NSString* encodedValue = value;
if (value.length > 0) {
encodedValue = (__bridge_transfer  NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)value, NULL, (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8 );
}
return encodedValue;
}


10.4 注意

1. 订单信息Encode编码就不需要自己手动编码了,直接调用支付宝提供的接口,接口里面已经对排序,编码进行了设置,直接调用就行

2. 里面的集成步骤和Demo中的有所不同,你们也可以根据自己的需求,酌情的增加或者减少.

11. 支付宝如果按照上面的步骤集成,应该是没问题的,文章结尾后会贴上我集成的时候遇见的bug和坑,敬请期待(支付宝集成完毕)

二 . 微信支付

1. 集成说明 : 相对于支付宝集成,微信集成要简单的多了

2. 集成前的准备(完成一下需要的帐号信息)

2.1 微信帐号

2.2 微信帐号密码

2.3 微信支付商户号

2.4 商户平台登录帐号

2.5 商户平台登录密码

2.6 应用APPID

3. 注意 : 以上步骤在微信支付平台上都有说明,我这里就不一一介绍了

4. 微信开放平台(附上网址:只要注册过了,就可以直接登录查看相关信息)—>选择

[微信支付]APP支付开发者文档

https://www.baidu.com/s?wd=%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98%E5%B9%B3%E5%8F%B0&rsv_spt=1&rsv_iqid=0x970a0db100003d17&issp=1&f=3&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=monline_3_dg&rsv_enter=1&rsv_sug3=12&rsv_sug1=9&rsv_sug7=100&rsv_sug2=0&prefixsug=%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98&rsp=8&inputT=7099&rsv_sug4=7846


5. 下载微信支付sdk

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1




6. 运行Demo(如果出现错误,直接照着官方文档修改或者百度就行—>通常下载微信支付sdk运行是不存在问题的)

7. 交互时序图(红色框是重点部分)



8. 总结 : 我们只需要给后台请求,返回需要的7个参数就可以了

9. 导入相关文件(注意 : 以微信支付开发文档为准)



10. 添加 URL Types(5)微信—-> 如果在集成微信支付之前使用了微信分享,那该步骤可以省略

TARGETS—->info—->URL Types(5)—->点击”+”添加微信URL Schemes(如下图)



11. 向微信注册AppID(代码如下)—-> 第一个空 : AppID(最好使用宏) 第二个空 : 可以随便填写

11.1 注意 : 如果在集成微信支付之前集成了微信分享,那么该句代码必须写在分享注册的代码之后

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:WXapp_id withDescription:@"测试demo"];
}


12. 集成代码一(给服务器发送请求—->得到需要的7个参数openID,partnerId,prepayId,nonceStr,timeStamp,package,sign)

#pragma mark - 微信支付
- (void)setUpWxPay
{
long activityId = _activitiy.ActivityId;
NSString *stringActivityId = [@(activityId) stringValue];
NSString *userId = [AppConfig shareInstance].UserID;
NSString *userTel = [self.paramDic objectForKey:@"mobile"];
if (userTel.length == 0 || userTel.length > 11) {
[SVProgressHUD showErrorWithStatus:@"请输入正确的联系电话"];
return;
}
NSString *userName = [self.paramDic objectForKey:@"name"];
if (userName.length == 0) {
[SVProgressHUD showErrorWithStatus:@"请输入姓名"];
return;
}
NSString *userIdentity = [self.paramDic objectForKey:@"identity"];
BOOL identity = [self isCorrect:userIdentity];
NSString *userEmail = [self.paramDic objectForKey:@"email"];
if (userEmail.length == 0) {
[SVProgressHUD showErrorWithStatus:@"请输入邮箱号"];
return;
}
NSInteger totalFee = _activitiy.totalFee;
NSString *body = _activitiy.title;
NSString *subject = _activitiy.title;
NSString *spbillCreateip = [self deviceIPAdress];
SpeedService *speedService = [[SpeedService alloc] init];
NSDictionary *dict = @{
@"body":body,
@"subject":subject,
@"userId":userId,
@"activityId":stringActivityId,
@"name":userName,
@"email":userEmail,
@"mobile":userTel,
@"identity":userIdentity,
@"total_amount":[NSString stringWithFormat:@"%d",totalFee],
@"spbillCreateip":spbillCreateip
};
NSLog(@"字典是 : %@",dict);
if (identity == YES) {
//判断是否安装了微信
if ([WXApi isWXAppInstalled]){
[speedService FetchUserWxPayProduct:dict completionBlock:^(id response, NSError *error) {
if (!error) {
NSLog(@"返回的结果是 : %@",response);
NSString * str = [response objectForKey:@"code"];
if ([str isEqualToString:@"0000"]) {
NSDictionary *dic = [NSDictionary dictionaryWithDictionary:[response objectForKey:@"result"]];
[self configRequest:dic stringStr:nil];
}

}else{

NSLog(@"网络超时,返回的错误信息是 : %@",error);
}
}];

}else{

[SVProgressHUD showErrorWithStatus:@"请安装微信"];
}

}else{
[SVProgressHUD showErrorWithStatus:@"请输入正确的身份证号码"];
return;
}
}


13. 调用微信支付代码,即可完成微信支付

#pragma mark - 调用微信支付的接口
- (void)configRequest:(NSDictionary *)dic stringStr:(NSString *)stringStr{

//需要创建这个支付对象
PayReq *req = [[PayReq alloc] init];

//由用户微信号和AppID组成的唯一标识,用于校验微信用户
req.openID = [dic objectForKey:@"appid"];

// 商家id,在注册的时候给的
req.partnerId = [dic objectForKey:@"partnerid"];

// 预支付订单这个是后台跟微信服务器交互后,微信服务器传给你们服务器的,你们服务器再传给你
req.prepayId  = [dic objectForKey:@"prepayid"];

// 随机编码,为了防止重复的,在后台生成
req.nonceStr  = [dic objectForKey:@"noncestr"];

// 这个是时间戳,也是在后台生成的,为了验证支付的
NSMutableString *stamp = [dic objectForKey:@"timestamp"];
req.timeStamp = stamp.intValue;

// 根据财付通文档填写的数据和签名
//这个比较特殊,是固定的,只能是即req.package = Sign=WXPay
req.package = [dic objectForKey:@"package"];

// 这个签名也是后台做的
req.sign = [dic objectForKey:@"sign"];

//发送请求到微信,等待微信返回onResp
[WXApi sendReq:req];
}


14. 特别说明 : 由于调用微信支付的7个参数都是服务器返回来的,不需要客户端做任何事情.当然有些参数客户端也是可以自己生成的,这就留给你们自己去处理了.

三. 总结

1. 集成支付宝出现的错误 :

1.1 能拿到服务器那边的sign,但是在调用支付宝接口的时候,代码运行并不会执行支付宝接口的block块,并且打印信息直接是提示今天已经注册报道了.

—-> 1.1.1 解决办法:将info–URL Types(5)–URL Schemes中配置的长度该为高于6个字串,很有可能是因为重名的问题.(直接重命名就行)

1.2 支付宝注册时间问题 : 在8月9号之前注册的用户,使用支付宝2.0的版本会出现问题,但是可以使用支付宝1.0版本的(重申:如果解签再重新签约的话,就可以使用支付宝2.0,并且兼容支付宝1.0的sdk)

—-> 1.2.1 解决办法 : 解签,再重新签约大约花1个工作日的时间

1.3 集成支付宝的时候,给自己的服务器发送请求得到sign.当打印请求拼接的参数的时候,经过仔细对比,发现其中会出现key和value值顺序颠倒问题

—-> 1.3.1 解决办法:将原来导入的sdk删除,重新倒入一次sdk就可以解决问题(很有可能是sdk造成的问题,我重新导入就解决了这问题)

1.4 签名(sign)出现的问题: 运用服务器返回的sign拼接成字符串,真机上出现系统繁忙,请重试.

—-> 1.4.1 解决方案 : 经过和支付宝提供的demo对比,支付宝的demo是完全可以实现支付功能,但是字符串加上后台返回的sign就出现这样的错误提示,说明签名有问题,这时只能叫后台返回正确的签名.

1.5 顺序问题 :如果服务器返回的sign没问题,那么最终就是的发送给支付宝参数拼接顺序问题了,要严格按照服务器返回的字串顺序拼接,然后再请求支付宝接口.(最后的出的结论是,不需要程序员手动按照顺序拼接,直接调用支付宝提供的方法,就可以完成拼接).

2. 微信支付出现的错误 :

1.1 集成完微信支付之后,真机运行,微信支付的时候只出现一个白的确定按钮,点击的时候跳回原来的app,并且返回-2



—-> 1.1.1 解决办法 : 肯定是参数的问题,如果你能确定你这里没错,那么就是后台返回的参数有问题(我做的时候是后台将一个参数的小写写成了大写,所以出现了这样的问题.其它错误是不会造成这样的结果的.仔细检查参数就可以解决)

四. 写在最后

这段时间由于很忙,拖欠了很多博客没有更新,后续我一定会慢慢补上来.最后如果大家觉得我写的还可以,麻烦关注我的官方博客,谢谢!!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息