目录: (没闲工夫看扯淡的第一部分, 可直接看第二和第三部分. 没有任何影响)
一, 写文档的初衷, 和遇到的一些问题 (包含扯淡)
二, 集成步骤 (主要是官方文档部分), 偷懒了很多页面, 你们自己根据流程点击
三, 实现代码 (不包含第二部分的配置)
四, 注意点 / 可能会遇到的问题
五, 参考文章
一 , 扯淡
先说一下为啥要写这个demo教程, 不是有官方文档吗?
因为官方文档真心不咋地!!!!! 更新不及时, 好多地方也不说清楚
官方demo也运行不了. 有问题了想找个客服问, 只能给技术人员发邮件, 发邮件!!!
微信支付技术支持的邮箱: wepayTS@tencent.com
我带着问题一堆问题问, 人家只会一两句: 你的key设置的有问题吧.
我真想呵呵. 问了两次, 还是没告诉我咋弄, 就说我key有问题.
最后我解决问题了, 也不是key的问题. 等着客服邮件给你解决, 真是浪费生命, 浪费时间.
二, 集成步骤
-
前提, 申请成开发者, 和商户.( 商户, 商户. ). 这个没啥坑. 按照文档一步步弄就行.
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317780&token=&lang=zh_CN
正式开始集成 -
如果项目之前没有集成过微信SDK, 那么跟着下面的文档集成一下.
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417694084&token=&lang=zh_CN -
如果及集成过, 检查一下这几个框架是否已经加入
SystemConfiguration.framework, libz.dylib, libsqlite3.0.dylib, libc++.dylib, Security.framework, CoreTelephony.framework, CFNetwork.framework -
接着官方文档集成 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
(需要看注意点 2)
三, 代码, 这只是.m文件, 商户信息啦, appid啦, key啦, 自己替换,
#import "WXApi.h"
#import "WXApiRequestHandler.h"
#import "WXApiManager.h"
#import "AFNetworking.h"
#import <CommonCrypto/CommonDigest.h>
@interface WXApiRequestHandler()
@property (nonatomic, strong) AFHTTPSessionManager *mgr;
@end
@implementation WXApiRequestHandler
- (AFHTTPSessionManager *)mgr {
if (_mgr == nil) {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_mgr = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:@"http://xxxxxxxxx"] sessionConfiguration:config];
_mgr.requestSerializer.timeoutInterval = 10;
_mgr.responseSerializer = [AFJSONResponseSerializer serializer];
_mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/x-json", @"text/plain",@"text/html", nil];
// _mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
}
return _mgr;
}
#pragma mark - 支付
- (NSString *)jumpToBizPay {
NSMutableDictionary *dictc = [NSMutableDictionary dictionary];
[self.mgr POST:@"xxxxxxr" parameters:dictc success:^(NSURLSessionDataTask *task, NSDictionary *dict) {
NSLog(@"dict:%@", dict);
// 这俩字典, 你们别搞混了 dict, 是服务器返回的, dict2是处理过, 加了sign的字典
// 就干了一件事, 生成sign
NSMutableDictionary *dict2 = [self getSign:dict];
// 我服务器传过来的时间戳, 谁生成都无所谓, 注意一定是只精确到秒, 是个10位的数字串
NSMutableString *stamp = [dict2 objectForKey:@"timestamp"];
//调起微信支付
PayReq* req = [[PayReq alloc] init];
req.nonceStr = [dict2 objectForKey:@"noncestr"];// 随机字符串
req.package = @"Sign=WXPay"; // 微信说暂时写死
req.partnerId = [dict2 objectForKey:@"partnerid"];// 就是mch_id, 商户id
req.prepayId = [dict2 objectForKey:@"prepayid"];// 微信返回的
req.timeStamp = stamp.intValue;
req.sign = [dict2 objectForKey:@"sign"];
[WXApi sendReq:req];
//日志输出
NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dict objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"失败了");
}];
return @"";
}
// 这段是为了组成sign签名所需的key, 微信的文档表述的, 让新手看不懂, 会傻一会儿,
// 具体可以看 文章的"注意点5"
- (NSMutableDictionary *)getSign:(NSDictionary *)dict{
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: @"wxd1111111111111" forKey:@"appid"];
[signParams setObject: @"1111111111" forKey:@"partnerid"];
[signParams setObject: dict[@"nonce_str"] forKey:@"noncestr"];
[signParams setObject: @"Sign=WXPay" forKey:@"package"];
[signParams setObject: dict[@"timestamp"] forKey:@"timestamp"];
[signParams setObject: dict[@"prepay_id"] forKey:@"prepayid"];
//生成签名
NSString *sign = [self createMd5Sign:signParams];
//添加签名
[signParams setObject: sign forKey:@"sign"];
return signParams;
}
#pragma mark - 获取签名
-(NSString *) createMd5Sign:(NSMutableDictionary*)dict
{
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [dict allKeys];
//按字母顺序排序, 不要自己排序!!!!! 不要自己排序!!!!!
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *categoryId in sortedArray) {
if (![categoryId isEqualToString:@"sign"] && ![categoryId isEqualToString:@"key"])
{
[contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
}
}
//添加key字段, 设置路径 微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
[contentString appendFormat:@"key=%@", @"xxxxxxxxxxxxxxxxxxxxxx"];
//得到MD5 sign签名, 一定要转大写!!!!!! 一定要转大写!!!!!!
NSString *md5Sign =[[self md5:contentString] uppercaseString];
NSLog(@"md5:%@", md5Sign);
return md5Sign;
}
// 这段微信没写
- (NSString *) md5:(NSString *) input {
const char *cStr = [input UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
@end
四, 注意点:
-
如果没有加入CFNetwork.framework, 项目随便编译不报错, 但是会运行会崩溃在
[WXApi registerApp:@"wxd1111111111111" ]; 这句. -
微信文档 注册APPID 那段代码已经不对了, 要写成上面"注意点1" 那样.
[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"demo 2.0"]; // 错的
包括微信支付的官方demo, 这句也是错的. -
微信支付的官方demo, 里面的地址也不能用了, demo里面的微信SDK都不是最新的, 呵呵了
- key的设置路径: 微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
不超过32位的字符串, , 需要自己生成, 并且设置到该路径 - sign签名key
贴图所在页 : https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12
五:
-
http://www.2cto.com/kf/201505/403114.html
文章中包含ios生成服务器统一下单代码(临时) -
https://pay.weixin.qq.com/wiki/tools/signverify/
生成sign时, 校验页面
网友评论