最近在做支付宝和微信支付的时候遇到很多坑,先说一下微信支付,前面的继承和配置我就不说了,大家看开发文档就好,按照开发文档一步步来是没有问题的
- 坑1:首先调用自己服务器接口获取订单ID,以及下一步调用支付的一些请求参数,都是从这个接口返回。
就是这些参数,都是从你公司自己的后台服务器获取的,除了sign。这里最坑爹的就是竟然这个sign也有返回给我,搞得我窝心烦躁。所以一定要和后台沟通好。
其实这个sign还要自己进行签名生成,不然跳转到微信的时候提示签名失败
以下是我签名的代码,大家可以借鉴以下:
/** 微信付款*/
if (self.payWayID == 10) {
PayReq *req = [[PayReq alloc] init];
req.partnerId = [param objectForKey:@"partnerid"] ;
req.prepayId = [param objectForKey:@"prepayid"];
req.package = [param objectForKey:@"package"];
req.nonceStr = [param objectForKey:@"noncestr"];
req.timeStamp = (UInt32)[param objectForKey:@"timestamp"];
/**以上参数都是从后台获取的*/
req.sign = [self createMD5SingForPay:@"wxaeaf71a68a176bf8" partnerid:req.partnerId prepayid:req.prepayId package:req.package noncestr:req.nonceStr timestamp:req.timeStamp];
[WXApi sendReq:req];
}
//创建发起支付时的sign签名
-(NSString *)createMD5SingForPay:(NSString *)appid_key
partnerid:(NSString *)partnerid_key
prepayid:(NSString *)prepayid_key
package:(NSString *)package_key
noncestr:(NSString *)noncestr_key
timestamp:(UInt32)timestamp_key
{
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject:appid_key forKey:@"appid"];
[signParams setObject:noncestr_key forKey:@"noncestr"];
[signParams setObject:package_key forKey:@"package"];
[signParams setObject:partnerid_key forKey:@"partnerid"];
[signParams setObject:prepayid_key forKey:@"prepayid"];
[signParams setObject:[NSString stringWithFormat:@"%u",(unsigned int)timestamp_key] forKey:@"timestamp"];
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [signParams allKeys];
//按字母顺序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *categoryId in sortedArray) {
if ( ![[signParams objectForKey:categoryId] isEqualToString:@""]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"sign"]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"key"]
)
{
[contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]];
}
}
//添加商户密钥key字段
[contentString appendFormat:@"key=%@", @"QiuCoo2016618YYinfo20170705Qiuku"];
NSString *result = [self md5:contentString];
return result;
}
// MD5加密算法
-(NSString *) md5:(NSString *)str
{
const char *cStr = [str UTF8String];
//加密规则,因为逗比微信没有出微信支付demo,这里加密规则是参照安卓demo来得
unsigned char result[16]= "0123456789abcdef";
CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
//这里的x是小写则产生的md5也是小写,x是大写则md5是大写,这里只能用大写,逗比微信的大小写验证很逗
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
//支付结果回调
-(void)onResp:(BaseResp *)resp
{
//errCode
switch (resp.errCode) {
case WXSuccess:
//成功回调
break;
default:
DLog(@"微信支付错误=%@",resp.errStr);
break;
}
}
注意:在官方demo里面的BaseReq
实例里面有一个openID
的字段,上面是这样说的“由用户微信号和AppID组成的唯一标识,发送请求时第三方程序必须填写,用于校验微信用户是否换号登录”
,但是我没填,也同样能付款。如果大家弄清楚了欢迎指教。
我这里加密签名是完全按照微信官方文档上面的说明来的,试了好几遍。