微信小微商户–申请入驻API上传图片(java)
小微商户接口文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_2
- 需要用到的maven依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.6</version>
</dependency>
- 代码实现
package com.demo.pay;
import com.roncoo.pay.common.core.utils.StringUtil;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class UploadDemo {
private static final Logger logger = LoggerFactory.getLogger(UploadDemo.class);
public static void main(String[] args) {
File file = new File("C:\\Users\\LYQ\\Desktop\\20181229160100.jpg");
upload(file, "微信服务商商户号", "C:\\Users\\LYQ\\Desktop\\apiclient_cert.p12", "https://api.mch.weixin.qq.com/secapi/mch/uploadmedia", "服务商商户号对应的商户密钥");
}
/**
* 真实上传方法
*
* @param file
* @param mch_id
* @param keyStoreUrl
* @param requestUrl
* @param payKey
*/
public static void upload(File file, String mch_id, String keyStoreUrl, String requestUrl, String payKey) {
try {
String media_hash = md5HashCode(new FileInputStream(file));
String sign_type = "HMAC-SHA256";
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("mch_id", mch_id);
paramMap.put("media_hash", media_hash);
paramMap.put("sign_type", sign_type);
String sign = sha256Sign(paramMap, payKey);
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.addTextBody("mch_id", mch_id, ContentType.MULTIPART_FORM_DATA);
multipartEntityBuilder.addBinaryBody("media", file, ContentType.create("image/jpg"), file.getName());
multipartEntityBuilder.addTextBody("media_hash", media_hash, ContentType.MULTIPART_FORM_DATA);
multipartEntityBuilder.addTextBody("sign_type", sign_type, ContentType.MULTIPART_FORM_DATA);
multipartEntityBuilder.addTextBody("sign", sign, ContentType.MULTIPART_FORM_DATA);
FileInputStream instream = null;
SSLContext sslcontext = null;
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
instream = new FileInputStream(new File(keyStoreUrl));
keyStore.load(instream, mch_id.toCharArray());// 这里写密码..默认是你的MCHID
sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();
} catch (Exception e) {
logger.error("官方微信--证书加载失败!{}", e);
} finally {
try {
if (instream != null) {
instream.close();
}
} catch (IOException e) {
logger.error("官方微信--证书加载失败!{}", e);
}
}
@SuppressWarnings("deprecation")
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
try {
HttpPost httpPost = new HttpPost(requestUrl);
RequestConfig config = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();
httpPost.setConfig(config);
这里的Content-type要设置为"multipart/form-data",否则返回“参数填写有误,请检查后重试”
httpPost.addHeader(HTTP.CONTENT_TYPE, "multipart/form-data; charset=UTF-8");
httpPost.addHeader(HTTP.USER_AGENT, "wxpay sdk java v1.0 " + mch_id);
httpPost.setEntity(multipartEntityBuilder.build());
CloseableHttpResponse response = httpclient.execute(httpPost);
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
logger.info("官方微信--请求返回结果:{}", result);
} catch (Exception e) {
logger.error("官方微信--请求失败!{}", e);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 对上次文件进行MD5获取其Hash值
*
* @param fis
* @return
*/
public static String md5HashCode(InputStream fis) {
try {
MessageDigest MD5 = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[8192];
int length;
while ((length = fis.read(buffer)) != -1) {
MD5.update(buffer, 0, length);
}
return new String(Hex.encodeHex(MD5.digest()));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取HMAC-SHA256签名
*
* @param paramMap 签名参数(sign不参与签名)
* @param key 签名密钥
* @return HMAC-SHA256签名结果
*/
public final static String sha256Sign(Map<String, Object> paramMap, String key) {
try {
String payParam = getSignTemp(paramMap, key);
logger.info("签名原文:{}", payParam);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(payParam.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
String sign = sb.toString().toUpperCase();
logger.info("签名结果:{}", sign);
return sign;
} catch (Exception e) {
return null;
}
}
/**
* 获取签名参数字符串
*
* @param paramMap 签名参数(sign字段不参与签名)
* @param payKey 签名密钥
* @return 待签名字符串
*/
private final static String getSignTemp(Map<String, Object> paramMap, String payKey) {
ArrayList<String> keyList = new ArrayList<>(paramMap.keySet());
Collections.sort(keyList);
StringBuilder signParam = new StringBuilder();
for (String key : keyList) {
if (!"sign".equals(key) && StringUtil.isNotNull(paramMap.get(key))) {
signParam.append(key).append("=").append(paramMap.get(key)).append("&");
}
}
signParam.delete(signParam.length() - 1, signParam.length());
signParam.append("&key=").append(payKey);
return signParam.toString();
}
}