iOS微信支付签名验证失败原因

2017-03-31  本文已影响5928人  哔哩哔哩智能喵

1.首先确认后台预支付的订单是否和微信支付对象PayReq中的属性值是否一一对应

  //需要创建这个支付对象
    PayReq *req   = [[PayReq alloc] init];
    //由用户微信号和AppID组成的唯一标识,用于校验微信用户
    req.openID = @" 唯一标识";
    // 商家id,在注册的时候给的
    req.partnerId = @"商家 id";
    
    // 预支付订单这个是后台跟微信服务器交互后,微信服务器传给你们服务器的,你们服务器再传给你
    req.prepayId  = self.payOrderItem.prepay_id;
    // 根据财付通文档填写的数据和签名
    //这个比较特殊,是固定的,只能是即req.package = Sign=WXPay
    req.package   = @"Sign=WXPay";

    // 随机编码,为了防止重复的,在后台生成
    req.nonceStr  = self.payOrderItem.nonce_str;
    
    NSDate *datenow = [NSDate date];
    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
    UInt32 timeStamp =[timeSp intValue];
    // 这个是时间戳,也是在后台生成的,为了验证支付的
    req.timeStamp = timeStamp;

2.确认sign 的值,微信中的支付对象有一个sing 属性,该属性为签名。该属性的值比较特殊,需要后台做好二次签名后才可以直接使用,如果后台没有做二次签名需要我们自己做的话需要用一下方法对,sign 值进行处理

// 这个签名也是后台做的,但是后台没有做
    req.sign = self.payOrderItem.sign;
    req.sign = [self createMD5SingForPayWithAppID:req.openID partnerid:req.partnerId prepayid:req.prepayId package:req.package noncestr:req.nonceStr timestamp:req.timeStamp];
    
    //发送请求到微信,等待微信返回onResp
    [WXApi sendReq:req];
}
-(NSString *)createMD5SingForPayWithAppID:(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"];//微信appid 例如wxfb132134e5342
        [signParams setObject:noncestr_key forKey:@"noncestr"];//随机字符串
        [signParams setObject:package_key forKey:@"package"];//扩展字段  参数为 Sign=WXPay
        [signParams setObject:partnerid_key forKey:@"partnerid"];//商户账号
        [signParams setObject:prepayid_key forKey:@"prepayid"];//此处为统一下单接口返回的预支付订单号
        [signParams setObject:[NSString stringWithFormat:@"%u",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字段  API 密钥
        [contentString appendFormat:@"key=%@", @"商户秘钥"];
        NSString *result = [contentString md5String];//md5加密
        return result;
    }

MD5加密的字符串分类

- (NSString *)md5String
    {
        if(self == nil || [self length] == 0) return nil;
        unsigned char digest[CC_MD5_DIGEST_LENGTH], i;
        CC_MD5([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
        NSMutableString *ms = [NSMutableString string];
        for(i=0;i<CC_MD5_DIGEST_LENGTH;i++)
        {
            [ms appendFormat: @"%02x", (int)(digest[i])];
        }
        return [ms copy];
}
上一篇下一篇

猜你喜欢

热点阅读