小程序
小游戏
企业微信
微信支付
扫描小程序码分享
1.创建client,在wechatpay-go官方库说,使用option.WithWechayPayAutoAuthCipher会自动帮忙验签2.在使用post,调用/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file这个接口,一直验签失败。在truncated_sign_message中没有看到有请求体。。请问应该如何使用POST调用上传电子发票文件接口
2 个回答
加粗
标红
插入代码
插入链接
插入图片
上传视频
抄这个 https://github.com/wechatpay-apiv3/wechatpay-go/blob/main/services/fileuploader/marketing_image_uploader.go
// Copyright 2021 Tencent Inc. All rights reserved. package fileuploader import ( "context" "io" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/services" ) // MarketingImageUploadResponse 图片上传API(营销专用)返回结果 type MarketingImageUploadResponse struct { MediaUrl *string `json:"media_url"` // revive:disable-line:var-naming } // MarketingImageUploader 图片上传API(营销专用) // // 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用, // 包括商家券、代金券、支付有礼等。 // 接口文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml type MarketingImageUploader services.Service // Upload 上传图片至微信支付营销系统 func (u *MarketingImageUploader) Upload( ctx context.Context, fileReader io.Reader, filename string, contentType string, ) (*MarketingImageUploadResponse, *core.APIResult, error) { result, err := (*baseFileUploader)(u).upload( ctx, "/v3/marketing/favor/media/image-upload", fileReader, filename, contentType, map[string]interface{}{}, ) if err != nil { return nil, result, err } var resp = new(MarketingImageUploadResponse) if err = core.UnMarshalResponse(result.Response, resp); err != nil { return nil, result, err } return resp, result, nil }
你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。
@ApiOperation("上传电子发票文件") @PostMapping("uploadFapiaoFile") public Result uploadFapiaoFile() throws IOException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException, InvalidKeyException { String url = wxPay.getDomain() + "/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file"; HttpUrl parse = HttpUrl.parse(url); String path = "E:\\online-consultation\\处方.pdf"; String sm3 = FileUtils.sm3(path); // String sm3 = FileUtils.sm3(path); log.info("SM3[{}]", sm3); JSONObject meta = new JSONObject(); meta.put("file_type", "PDF"); meta.put("digest", sm3); meta.put("digest_algorithm", "SM3"); String signatureString = WxSignatureUtil.getSignatureString("POST", parse, meta.toString()); log.info("signature[{}]", signatureString); MultipartBody multipartBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("meta", "meta", RequestBody.create(MediaType.parse("application/json"), meta.toString())) .addFormDataPart("file", "file", RequestBody.create(new File(path), MediaType.parse("pdf/plain"))) .build(); OkHttpClient client = new OkHttpClient(); Request build = new Request.Builder() .addHeader("Content-Type", "multipart/form-data") .addHeader("Authorization", signatureString) .addHeader("Accept", "application/json") .url(url) .post(multipartBody) .build(); Response response = client.newCall(build).execute(); ResponseBody responseBody = response.body(); String string = responseBody.string(); return Result.ok(string); } public static String sm3(String path) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); try (FileInputStream fis = new FileInputStream(path); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { baos.write(buffer, 0, bytesRead); } SM3.Digest sm3 = new SM3.Digest(); sm3.update(baos.toByteArray()); byte[] digest = sm3.digest(); return Hex.toHexString(digest); } catch (Exception e) { throw new RuntimeException(e); } } @Slf4j public class WxSignatureUtil { private static String serial = ""; private static String mchid = ""; public static String getSignatureString(String method, HttpUrl url, String body) throws UnsupportedEncodingException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { String nonceStr = RandomStrUtils.getRandomString(32); long timestamp = System.currentTimeMillis() / 1000; String message = buildMessage(method, url, timestamp, nonceStr, body); String signature = sign(message.getBytes("utf-8")); log.info("签名值:[{}]", signature); return "WECHATPAY2-SHA256-RSA2048 mchid=\"" + mchid + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\"" + serial + "\"," + "signature=\"" + signature + "\""; } public static String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { Signature sign = Signature.getInstance("SHA256withRSA"); InputStream resourceAsStream = WxSignatureUtil.class.getClassLoader().getResourceAsStream("apiclient_key.pem"); sign.initSign(PemUtil.loadPrivateKey(resourceAsStream)); sign.update(message); return Base64.getEncoder().encodeToString(sign.sign()); } public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) { String canonicalUrl = url.encodedPath(); if (url.encodedQuery() != null) { canonicalUrl += "?" + url.encodedQuery(); } StringBuilder sb = new StringBuilder(method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n"); if (!StringUtils.isEmpty(body)) { sb.append(body + "\n"); } else { sb.append(""+"\n"); } String str = sb.toString(); log.info("构造签名体:[{}]", str); return str; } }
{
"code": "SIGN_ERROR",
"detail": {
"issue": "sign not match"
},
"field": "signature",
"location": "authorization",
"sign_information": {
"method": "POST",
"sign_message_length": 116,
"truncated_sign_message": "POST\n/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file\n1722331061\nHp19Fkd3BaYXp3rMXSjzA88wJCT5GE32\n\n",
"url": "/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file"
}
"message": "错误的签名,验签失败"
}我也遇到这种情况,兄弟你解决了吗
关注后,可在微信内接收相应的重要提醒。
请使用微信扫描二维码关注 “微信开放社区” 公众号
抄这个 https://github.com/wechatpay-apiv3/wechatpay-go/blob/main/services/fileuploader/marketing_image_uploader.go
// Copyright 2021 Tencent Inc. All rights reserved. package fileuploader import ( "context" "io" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/services" ) // MarketingImageUploadResponse 图片上传API(营销专用)返回结果 type MarketingImageUploadResponse struct { MediaUrl *string `json:"media_url"` // revive:disable-line:var-naming } // MarketingImageUploader 图片上传API(营销专用) // // 通过本接口上传图片后可获得图片url地址。图片url可在微信支付营销相关的API使用, // 包括商家券、代金券、支付有礼等。 // 接口文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_0_1.shtml type MarketingImageUploader services.Service // Upload 上传图片至微信支付营销系统 func (u *MarketingImageUploader) Upload( ctx context.Context, fileReader io.Reader, filename string, contentType string, ) (*MarketingImageUploadResponse, *core.APIResult, error) { result, err := (*baseFileUploader)(u).upload( ctx, "/v3/marketing/favor/media/image-upload", fileReader, filename, contentType, map[string]interface{}{}, ) if err != nil { return nil, result, err } var resp = new(MarketingImageUploadResponse) if err = core.UnMarshalResponse(result.Response, resp); err != nil { return nil, result, err } return resp, result, nil }
@ApiOperation("上传电子发票文件") @PostMapping("uploadFapiaoFile") public Result uploadFapiaoFile() throws IOException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException, InvalidKeyException { String url = wxPay.getDomain() + "/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file"; HttpUrl parse = HttpUrl.parse(url); String path = "E:\\online-consultation\\处方.pdf"; String sm3 = FileUtils.sm3(path); // String sm3 = FileUtils.sm3(path); log.info("SM3[{}]", sm3); JSONObject meta = new JSONObject(); meta.put("file_type", "PDF"); meta.put("digest", sm3); meta.put("digest_algorithm", "SM3"); String signatureString = WxSignatureUtil.getSignatureString("POST", parse, meta.toString()); log.info("signature[{}]", signatureString); MultipartBody multipartBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("meta", "meta", RequestBody.create(MediaType.parse("application/json"), meta.toString())) .addFormDataPart("file", "file", RequestBody.create(new File(path), MediaType.parse("pdf/plain"))) .build(); OkHttpClient client = new OkHttpClient(); Request build = new Request.Builder() .addHeader("Content-Type", "multipart/form-data") .addHeader("Authorization", signatureString) .addHeader("Accept", "application/json") .url(url) .post(multipartBody) .build(); Response response = client.newCall(build).execute(); ResponseBody responseBody = response.body(); String string = responseBody.string(); return Result.ok(string); } public static String sm3(String path) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); try (FileInputStream fis = new FileInputStream(path); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { baos.write(buffer, 0, bytesRead); } SM3.Digest sm3 = new SM3.Digest(); sm3.update(baos.toByteArray()); byte[] digest = sm3.digest(); return Hex.toHexString(digest); } catch (Exception e) { throw new RuntimeException(e); } } @Slf4j public class WxSignatureUtil { private static String serial = ""; private static String mchid = ""; public static String getSignatureString(String method, HttpUrl url, String body) throws UnsupportedEncodingException, NoSuchAlgorithmException, SignatureException, InvalidKeyException { String nonceStr = RandomStrUtils.getRandomString(32); long timestamp = System.currentTimeMillis() / 1000; String message = buildMessage(method, url, timestamp, nonceStr, body); String signature = sign(message.getBytes("utf-8")); log.info("签名值:[{}]", signature); return "WECHATPAY2-SHA256-RSA2048 mchid=\"" + mchid + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\"" + serial + "\"," + "signature=\"" + signature + "\""; } public static String sign(byte[] message) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { Signature sign = Signature.getInstance("SHA256withRSA"); InputStream resourceAsStream = WxSignatureUtil.class.getClassLoader().getResourceAsStream("apiclient_key.pem"); sign.initSign(PemUtil.loadPrivateKey(resourceAsStream)); sign.update(message); return Base64.getEncoder().encodeToString(sign.sign()); } public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) { String canonicalUrl = url.encodedPath(); if (url.encodedQuery() != null) { canonicalUrl += "?" + url.encodedQuery(); } StringBuilder sb = new StringBuilder(method + "\n" + canonicalUrl + "\n" + timestamp + "\n" + nonceStr + "\n"); if (!StringUtils.isEmpty(body)) { sb.append(body + "\n"); } else { sb.append(""+"\n"); } String str = sb.toString(); log.info("构造签名体:[{}]", str); return str; } }
{
"code": "SIGN_ERROR",
"detail": {
"detail": {
"issue": "sign not match"
},
"field": "signature",
"location": "authorization",
"sign_information": {
"method": "POST",
"sign_message_length": 116,
"truncated_sign_message": "POST\n/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file\n1722331061\nHp19Fkd3BaYXp3rMXSjzA88wJCT5GE32\n\n",
"url": "/v3/new-tax-control-fapiao/fapiao-applications/upload-fapiao-file"
}
},
"message": "错误的签名,验签失败"
}我也遇到这种情况,兄弟你解决了吗