新增退款接口
This commit is contained in:
@@ -47,7 +47,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
*/
|
||||
public class HttpRequest {
|
||||
private final String SUCCESS = "success";
|
||||
private AbstractHttpClient client;
|
||||
protected AbstractHttpClient client;
|
||||
|
||||
public HttpRequest() {
|
||||
this(150, 100, 10000, 10000);
|
||||
@@ -155,17 +155,17 @@ public class HttpRequest {
|
||||
HttpResponse httpResponse = client.execute(request);
|
||||
StatusLine statusLine = httpResponse.getStatusLine();
|
||||
HttpEntity httpEntity = httpResponse.getEntity();
|
||||
|
||||
int status = statusLine.getStatusCode();
|
||||
if (status != HttpStatus.SC_OK) {
|
||||
throw new WeixinException(status + "", "request fail");
|
||||
throw new WeixinException(Integer.toString(status),
|
||||
"request fail");
|
||||
}
|
||||
// 301或者302
|
||||
if (status == HttpStatus.SC_MOVED_PERMANENTLY
|
||||
|| status == HttpStatus.SC_MOVED_TEMPORARILY) {
|
||||
throw new WeixinException(status + "", String.format(
|
||||
"the page was redirected to %s",
|
||||
httpResponse.getFirstHeader("location")));
|
||||
throw new WeixinException(Integer.toString(status),
|
||||
String.format("the page was redirected to %s",
|
||||
httpResponse.getFirstHeader("location")));
|
||||
}
|
||||
byte[] data = EntityUtils.toByteArray(httpEntity);
|
||||
response = new Response();
|
||||
@@ -186,8 +186,8 @@ public class HttpRequest {
|
||||
JsonResult jsonResult = response.getAsJsonResult();
|
||||
response.setJsonResult(true);
|
||||
if (jsonResult.getCode() != 0) {
|
||||
throw new WeixinException(jsonResult.getCode() + "",
|
||||
jsonResult.getDesc());
|
||||
throw new WeixinException(Integer.toString(jsonResult
|
||||
.getCode()), jsonResult.getDesc());
|
||||
}
|
||||
return response;
|
||||
} catch (JSONException e) {
|
||||
@@ -205,7 +205,7 @@ public class HttpRequest {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
throw new WeixinException("-1", e.getMessage());
|
||||
} finally {
|
||||
request.releaseConnection();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.foxinmy.weixin4j.http;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
|
||||
/**
|
||||
* ssl请求
|
||||
*
|
||||
* @className SSLHttpRequest
|
||||
* @author jy
|
||||
* @date 2014年11月6日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class SSLHttpRequest extends HttpRequest {
|
||||
|
||||
public SSLHttpRequest(String password, File file) throws IOException {
|
||||
this(password, new FileInputStream(file));
|
||||
}
|
||||
|
||||
public SSLHttpRequest(String password, InputStream inputStream) {
|
||||
super();
|
||||
try {
|
||||
KeyStore trustStore = KeyStore.getInstance("PKCS12");
|
||||
trustStore.load(inputStream, password.toCharArray());
|
||||
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore,
|
||||
password);
|
||||
client.getConnectionManager().getSchemeRegistry()
|
||||
.register(new Scheme("https", 443, socketFactory));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ public class Token implements Serializable {
|
||||
private String accessToken;
|
||||
@JSONField(name = "expires_in")
|
||||
private int expiresIn;
|
||||
private String openid;
|
||||
private long time;
|
||||
|
||||
public String getAccessToken() {
|
||||
@@ -43,14 +42,6 @@ public class Token implements Serializable {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
@@ -69,6 +60,7 @@ public class Token implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn + ", openid=" + openid + ", time=" + time + "]";
|
||||
return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn
|
||||
+ ", time=" + time + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 微信账户信息
|
||||
*
|
||||
@@ -9,9 +11,16 @@ package com.foxinmy.weixin4j.model;
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class WeixinAccount extends WeixinConfig {
|
||||
public class WeixinAccount implements Serializable {
|
||||
private static final long serialVersionUID = 3689999353867189585L;
|
||||
|
||||
private String token;
|
||||
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
||||
private String openId;
|
||||
// 公众号身份的唯一标识
|
||||
private String appId;
|
||||
// 公众平台接口 API 的权限获取所需密钥 Key
|
||||
private String appSecret;
|
||||
// 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
|
||||
private String paySignKey;
|
||||
// 财付通商户身份的标识
|
||||
@@ -30,6 +39,38 @@ public class WeixinAccount extends WeixinConfig {
|
||||
// 是否是订阅号
|
||||
private boolean isSubscribe;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getAppSecret() {
|
||||
return appSecret;
|
||||
}
|
||||
|
||||
public void setAppSecret(String appSecret) {
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
public String getPaySignKey() {
|
||||
return paySignKey;
|
||||
}
|
||||
@@ -98,19 +139,51 @@ public class WeixinAccount extends WeixinConfig {
|
||||
|
||||
}
|
||||
|
||||
public WeixinAccount(String appId, String appSecret) {
|
||||
this.appId = appId;
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* V3版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param mchId
|
||||
*/
|
||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
||||
String mchId) {
|
||||
super(appId, appSecret);
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* V2版本字段
|
||||
*
|
||||
* @param appId
|
||||
* @param appSecret
|
||||
* @param paySignKey
|
||||
* @param partnerId
|
||||
* @param partnerKey
|
||||
*/
|
||||
public WeixinAccount(String appId, String appSecret, String paySignKey,
|
||||
String partnerId, String partnerKey) {
|
||||
super(appId, appSecret);
|
||||
this(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.partnerId = partnerId;
|
||||
this.partnerKey = partnerKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinAccount [token=" + token + ", openId=" + openId
|
||||
+ ", appId=" + appId + ", appSecret=" + appSecret
|
||||
+ ", paySignKey=" + paySignKey + ", partnerId=" + partnerId
|
||||
+ ", partnerKey=" + partnerKey + ", mchId=" + mchId
|
||||
+ ", deviceInfo=" + deviceInfo + ", isAlive=" + isAlive
|
||||
+ ", isService=" + isService + ", isSubscribe=" + isSubscribe
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class WeixinConfig implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3454743453282851243L;
|
||||
|
||||
private String token;
|
||||
// 支付场景下为用户的openid 其余情况可能是公众号的原始ID
|
||||
private String openId;
|
||||
// 公众号身份的唯一标识
|
||||
private String appId;
|
||||
// 除了支付请求需要用到 paySignKey,公众平台接口 API 的权限获取所需密 钥 Key
|
||||
private String appSecret;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getAppSecret() {
|
||||
return appSecret;
|
||||
}
|
||||
|
||||
public void setAppSecret(String appSecret) {
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
public WeixinConfig() {
|
||||
|
||||
}
|
||||
|
||||
public WeixinConfig(String appId, String appSecret) {
|
||||
this.appId = appId;
|
||||
this.appSecret = appSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinConfig [token=" + token + ", openId=" + openId
|
||||
+ ", appId=" + appId + ", appSecret=" + appSecret + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.foxinmy.weixin4j.token;
|
||||
|
||||
import com.foxinmy.weixin4j.http.HttpRequest;
|
||||
import com.foxinmy.weixin4j.model.WeixinConfig;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
@@ -16,17 +16,17 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
public abstract class AbstractTokenHolder implements TokenHolder {
|
||||
protected final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||
protected final HttpRequest request = new HttpRequest();
|
||||
private final WeixinConfig weixinConfig;
|
||||
private final WeixinAccount weixinAccount;
|
||||
|
||||
public AbstractTokenHolder() {
|
||||
this.weixinConfig = ConfigUtil.getWeixinConfig();
|
||||
this.weixinAccount = ConfigUtil.getWeixinAccount();
|
||||
}
|
||||
|
||||
public AbstractTokenHolder(String appid, String appsecret) {
|
||||
this.weixinConfig = new WeixinConfig(appid, appsecret);
|
||||
public AbstractTokenHolder(WeixinAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
}
|
||||
|
||||
public WeixinConfig getConfig() {
|
||||
return this.weixinConfig;
|
||||
public WeixinAccount getAccount() {
|
||||
return weixinAccount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.Response;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.xml.XStream;
|
||||
|
||||
@@ -32,8 +33,12 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
super();
|
||||
}
|
||||
|
||||
public FileTokenHolder(WeixinAccount weixinAccount) {
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
public FileTokenHolder(String appid, String appsecret) {
|
||||
super(appid, appsecret);
|
||||
this(new WeixinAccount(appid, appsecret));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,8 +55,8 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
*/
|
||||
@Override
|
||||
public Token getToken() throws WeixinException {
|
||||
String appid = getConfig().getAppId();
|
||||
String appsecret = getConfig().getAppSecret();
|
||||
String appid = getAccount().getAppId();
|
||||
String appsecret = getAccount().getAppSecret();
|
||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
||||
throw new IllegalArgumentException(
|
||||
"appid or appsecret not be null!");
|
||||
@@ -65,7 +70,6 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
if (token_file.exists()) {
|
||||
token = XStream.get(new FileInputStream(token_file),
|
||||
Token.class);
|
||||
|
||||
long expise_time = token.getTime()
|
||||
+ (token.getExpiresIn() * 1000) - 3;
|
||||
if (expise_time > now_time) {
|
||||
@@ -79,7 +83,6 @@ public class FileTokenHolder extends AbstractTokenHolder {
|
||||
token = response.getAsObject(new TypeReference<Token>() {
|
||||
});
|
||||
token.setTime(now_time);
|
||||
token.setOpenid(appid);
|
||||
XStream.to(token, new FileOutputStream(token_file));
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException("-1", "IO ERROR");
|
||||
|
||||
@@ -10,6 +10,7 @@ import redis.clients.jedis.exceptions.JedisException;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
|
||||
/**
|
||||
* 基于redis保存的Token获取类
|
||||
@@ -26,17 +27,7 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
|
||||
private JedisPool jedisPool;
|
||||
|
||||
public RedisTokenHolder() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String appid, String appsecret) {
|
||||
this(appid, appsecret, "localhost", 6379);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String appid, String appsecret, String host,
|
||||
int port) {
|
||||
super(appid, appsecret);
|
||||
private void createPool(String host, int port) {
|
||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
poolConfig.setMaxTotal(50);
|
||||
poolConfig.setMaxIdle(5);
|
||||
@@ -46,10 +37,33 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
this.jedisPool = new JedisPool(poolConfig, host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder() {
|
||||
this("localhost", 6379);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String host, int port) {
|
||||
super();
|
||||
createPool(host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(WeixinAccount weixinAccount) {
|
||||
this(weixinAccount, "localhost", 6379);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(String appId, String appSecret, String host,
|
||||
int port) {
|
||||
this(new WeixinAccount(appId, appSecret), host, port);
|
||||
}
|
||||
|
||||
public RedisTokenHolder(WeixinAccount weixinAccount, String host, int port) {
|
||||
super(weixinAccount);
|
||||
createPool(host, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token getToken() throws WeixinException {
|
||||
String appid = getConfig().getAppId();
|
||||
String appsecret = getConfig().getAppSecret();
|
||||
String appid = getAccount().getAppId();
|
||||
String appsecret = getAccount().getAppSecret();
|
||||
if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) {
|
||||
throw new IllegalArgumentException(
|
||||
"appid or appsecret not be null!");
|
||||
@@ -68,13 +82,12 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
});
|
||||
jedis.setex(key, token.getExpiresIn() - 3,
|
||||
token.getAccessToken());
|
||||
token.setTime(System.currentTimeMillis());
|
||||
} else {
|
||||
token = new Token();
|
||||
token.setAccessToken(accessToken);
|
||||
token.setExpiresIn(jedis.ttl(key).intValue());
|
||||
}
|
||||
token.setTime(System.currentTimeMillis());
|
||||
token.setOpenid(appid);
|
||||
} catch (JedisException e) {
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
} finally {
|
||||
@@ -82,4 +95,4 @@ public class RedisTokenHolder extends AbstractTokenHolder {
|
||||
}
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.foxinmy.weixin4j.token;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinConfig;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
|
||||
/**
|
||||
* 获取Token接口
|
||||
@@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.model.WeixinConfig;
|
||||
* @see com.foxinmy.weixin4j.token.RedisTokenHolder
|
||||
*/
|
||||
public interface TokenHolder {
|
||||
public WeixinConfig getConfig();
|
||||
public WeixinAccount getAccount();
|
||||
|
||||
public Token getToken() throws WeixinException;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.model.WeixinConfig;
|
||||
|
||||
/**
|
||||
* 商户配置工具类
|
||||
@@ -38,9 +37,4 @@ public class ConfigUtil {
|
||||
String text = getValue("account");
|
||||
return JSON.parseObject(text, WeixinAccount.class);
|
||||
}
|
||||
|
||||
public static WeixinConfig getWeixinConfig() {
|
||||
String text = getValue("account");
|
||||
return JSON.parseObject(text, WeixinConfig.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@@ -25,7 +26,16 @@ public class DateUtil {
|
||||
return new SimpleDateFormat(yyyyMMddHHmmss).format(date);
|
||||
}
|
||||
|
||||
public static String format2fee(double fee) {
|
||||
public static Date parse2yyyyMMddHHmmss(String date) {
|
||||
try {
|
||||
return new SimpleDateFormat(yyyyMMddHHmmss).parse(date);
|
||||
} catch (ParseException e) {
|
||||
;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String formaFee2Fen(double fee) {
|
||||
return new DecimalFormat("#").format(fee * 100);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user