背景:
之前做过一个微信小程序扫描发票二维码,记录发票内容。日前公司财务收到了一种新的发票(区块链电子发票),之前的小程序解析不了这种新的二维码。
区块链电子发票是由深圳税务局和腾讯公司合作完成的一款创新型产品,详情大家可以去百度一下 ^_^。
这款电子发票的二维码内容和传统发票的二维码不太一致;
传统发票的二维码内容,大家可以参考一下我之前写的博客,具体链接如下:传送门
区块链电子发票的二维码返回的一个具体的 url(参数已替换成伪值):
https://bcfp.shenzhen.chinatax.gov.cn/verify/scan?hash=...xxx...&bill_num=...xxx...&total_amount=...xxx...
打开可以看到详细的发票信息(比传统的发票二维码多了一些信息):
查看页面的请求信息,我们可以看到具体的页面内容是通过如下请求得到的:
// 请求路劲:
https://bcfp.shenzhen.chinatax.gov.cn/dzswj/bers_ep_web/query_bill_detail
// 参数:
bill_num
total_amount
tx_hash
//对应的值就是URL中的三个参数的值
bill_num
total_amount
hash //(这个参数名和上面不一样,注意一下)
下面我们只要通过后台访问该链接,就能得到我们想要的内容了,话不多说,直接上代码,这里我使用的是 RestTemplate,大家可以自行根据自己的喜欢使用不同的方法进行访问:
// 首先,区分是哪种类型的二维码
if (invoiceStr.startsWith("01")) {
getTraditionalInvoiceVo(invoiceStr);
} else if (invoiceStr.startsWith("https")) {
getBlockChainInvoiceRecordVo(invoiceStr);
} else {
...
}
// getBlockChainInvoiceRecordVo
{
final String host = "bcfp.shenzhen.chinatax.gov.cn";
try {
URI uri = new URI(invoiceStr);
HashMap paraMap = HttpUtils.getUrlPara(uri.getQuery());
if (!host.equalsIgnoreCase(uri.getHost()) || paraMap == null) return null;
String url = uri.getScheme() + "://" + uri.getHost() + "/dzswj/bers_ep_web/query_bill_detail";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
JSONObject postParameters = new JSONObject();
postParameters.put("bill_num", paraMap.get("bill_num").toString());
postParameters.put("total_amount", paraMap.get("total_amount").toString());
postParameters.put("tx_hash", paraMap.get("hash").toString());
HttpEntity<String> entity = new HttpEntity<String>(postParameters.toJSONString(), headers);
ResponseEntity<JSONObject> response = restTemplate.exchange(url, HttpMethod.POST, entity, JSONObject.class);
if (response == null || !"200".equals(response.getStatusCode().toString()))
return null;
LinkedHashMap<Object, Object> billRecord = (LinkedHashMap) response.getBody().get("bill_record");
// billRecord.get("") 拿出想要的数据,这里的金额需要注意一下
// 取出来的具体值需要 * 0.01,才是我们需要的值
// bill_code
// bill_num
// amount:不含税总金额
// tax_amount:税额
// total_amount:总金额(含税)
// time
// seller_name
// seller_taxpayer_id
// buyer_name
} catch (URISyntaxException e) {
return null;
}
}
// HttpUtils.getUrlPara
public static HashMap<String, String> getUrlPara(String query) {
if (StringUtils.isBlank(query)) return null;
HashMap<String, String> paraMap = new HashMap<>();
String[] paraArr = query.split("&");
for (String item : paraArr) {
int index = item.indexOf("=");
if (index == -1) continue;
String paraName = item.substring(0, index).toLowerCase();
String paraValue = item.substring(index + 1);
paraMap.put(paraName, paraValue);
}
return paraMap;
}
如上述描述有误,请留言指出,我会及时修正,谢谢~