一、使用GET请求获取微信access_token
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。建议公众号开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务。
NSDictionary *parm = @{
@"grant_type":@"client_credential",
@"appid":appid,
@"secret":secret,
};
NSString *url = @"https://api.weixin.qq.com/cgi-bin/token";
二、使用拿到的access_token通过GET请求拿到ticket
ticket用于加强安全性。ticket的有效期目前为2个小时,需定时刷新。建议公众号开发者使用中控服务器统一获取和刷新ticket
NSDictionary *parm = @{
@"type":@"wx_card",
@"access_token":token,
};
NSString *url = @"https://api.weixin.qq.com/cgi-bin/ticket/getticket";
三、对拿到的ticket等信息进行排序加密,生成cardSign
将 api_ticket、appid、location_id、timestamp、nonce_str、card_id、card_type的value值进行字符串的字典序排序
将所有参数字符串拼接成一个字符串进行sha1加密,得到cardSign
NSMutableDictionary *cardSignDic = [NSMutableDictionary dictionary];
[cardSignDic setObject:nonceStr forKey:@"nonceStr"];
[cardSignDic setObject:timeStr forKey:@"timestamp"];
[cardSignDic setObject:apiTicket forKey:@"api_ticket"];
[cardSignDic setObject:@"INVOICE" forKey:@"cardType"];
[cardSignDic setObject:appid forKey:@"appid"];
NSMutableString *contentString = [NSMutableString string];
NSArray *values = [cardSignDic allValues];
//按字母顺序排序
NSArray *sortedArray = [values sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *value in sortedArray) {
[contentString appendFormat:@"%@", value];
}
NSString *cardSign = [self sha1:contentString];
sha1加密
- (NSString *)sha1:(NSString *)input {
NSData *data = [input 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;
}
四、通过调用微信Api跳转微信(注:传入的时间戳要和之前进行sha1加密的时间戳相同)
WXChooseInvoiceReq *cardReq = [[WXChooseInvoiceReq alloc]init];
cardReq.appID = appid;
cardReq.timeStamp = timeStamp;
cardReq.nonceStr = @"sfim_invoice";
cardReq.cardSign = cardSign;
[WXApi sendReq:cardReq];
五、在AppDelegate转发回调
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if ([WXApi handleOpenURL:url delegate:[weChatManager shareInstance]]) {
return YES;
}
if ([self application:application handleOpenURL:url]) {
return YES;
}
return NO;
}
六、在onResp方法里拿到发票的id,再用POST请求 拿到发票详细的信息
WXChooseInvoiceResp *chooseInvoiceResp = (WXChooseInvoiceResp *)resp;
NSArray *itemArray = chooseInvoiceResp.cardAry;
NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:itemArray.count];
for (WXInvoiceItem *item in itemArray) {
NSMutableDictionary *dicM = [NSMutableDictionary dictionary];
[dicM setObject:item.cardId ? item.cardId : @"" forKey:@"card_id"];
[dicM setObject:item.encryptCode ? item.encryptCode : @"" forKey:@"encrypt_code"];
[resultArray addObject:dicM];
}
NSDictionary *listParm = @{
@"item_list":resultArray,
};
NSString *url = [NSString stringWithFormat:@"https://api.weixin.qq.com/card/invoice/reimburse/getinvoicebatch?access_token=%@",self.accessToken];
网友评论