背景:
之前做過一個微信小程序掃描發票二維碼,記錄發票內容。日前公司財務收到了一種新的發票(區塊鏈電子發票),之前的小程序解析不了這種新的二維碼。
區塊鏈電子發票是由深圳稅務局和騰訊公司合作完成的一款創新型產品,詳情大家可以去百度一下 ^_^。
這款電子發票的二維碼內容和傳統發票的二維碼不太一致;
傳統發票的二維碼內容,大家可以參考一下我之前寫的博客,具體鏈接如下:傳送門
區塊鏈電子發票的二維碼返回的一個具體的 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;
}
如上述描述有誤,請留言指出,我會及時修正,謝謝~