新增退款接口

This commit is contained in:
jy.hu
2014-11-06 20:46:35 +08:00
parent f489667109
commit 26d04798c5
34 changed files with 752 additions and 502 deletions
@@ -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);
}
}