新增Weixin4jSettings配置类
This commit is contained in:
parent
c4bf06d372
commit
2e2d207e76
@ -629,4 +629,8 @@
|
||||
|
||||
* 2016-01-26
|
||||
|
||||
+ weixin4j-qy:新增上传图文消息内的图片接口
|
||||
+ weixin4j-qy:新增上传图文消息内的图片接口
|
||||
|
||||
* 2016-01-29
|
||||
|
||||
+ 新增Weixin4jSettings配置类
|
||||
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.7</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>weixin4j</name>
|
||||
<url>https://github.com/foxinmy/weixin4j</url>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.7</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-base</artifactId>
|
||||
<name>weixin4j-base</name>
|
||||
|
||||
@ -5,11 +5,6 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
|
||||
/**
|
||||
* API基础
|
||||
@ -45,21 +40,4 @@ public abstract class BaseApi {
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties文件中的公众号信息
|
||||
*/
|
||||
public final static WeixinAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
|
||||
/**
|
||||
* 默认token使用File的方式存储
|
||||
*/
|
||||
public final static TokenStorager DEFAULT_TOKEN_STORAGER;
|
||||
|
||||
static {
|
||||
DEFAULT_WEIXIN_ACCOUNT = Weixin4jConfigUtil.getWeixinAccount();
|
||||
DEFAULT_TOKEN_STORAGER = new FileTokenStorager(
|
||||
Weixin4jConfigUtil.getValue("token.path",
|
||||
Weixin4jConst.DEFAULT_TOKEN_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class CashApi {
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
@ -71,7 +71,7 @@ public class CashApi {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor
|
||||
.post(redpacket.getTotalNum() > 1 ? PayURLConsts.MCH_REDPACK_GROUPSEND_URL
|
||||
: PayURLConsts.MCH_REDPACKSEND_URL, param);
|
||||
@ -92,7 +92,7 @@ public class CashApi {
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
@ -116,7 +116,7 @@ public class CashApi {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_REDPACKQUERY_URL,
|
||||
param);
|
||||
} finally {
|
||||
@ -136,7 +136,7 @@ public class CashApi {
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param mpPayment
|
||||
* 付款信息
|
||||
* @return 付款结果
|
||||
@ -160,7 +160,7 @@ public class CashApi {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYMENT_URL,
|
||||
param);
|
||||
} finally {
|
||||
@ -184,7 +184,7 @@ public class CashApi {
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
@ -206,7 +206,7 @@ public class CashApi {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYQUERY_URL,
|
||||
param);
|
||||
} finally {
|
||||
|
||||
@ -44,7 +44,7 @@ public class CouponApi {
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
* @param partnerTradeNo
|
||||
@ -81,7 +81,7 @@ public class CouponApi {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_COUPONSEND_URL,
|
||||
param);
|
||||
} finally {
|
||||
|
||||
@ -29,12 +29,12 @@ import com.foxinmy.weixin4j.payment.MicroPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.payment.mch.APPPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.NativePayResponse;
|
||||
import com.foxinmy.weixin4j.payment.mch.OpenIdResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
@ -51,8 +51,6 @@ import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
@ -496,7 +494,7 @@ public class Pay3Api {
|
||||
* </p>
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
@ -539,7 +537,7 @@ public class Pay3Api {
|
||||
map.put("sign", sign);
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_REFUNDAPPLY_URL,
|
||||
param);
|
||||
} finally {
|
||||
@ -559,7 +557,7 @@ public class Pay3Api {
|
||||
* 退款申请(全额退款)
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
@ -582,7 +580,7 @@ public class Pay3Api {
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
@ -594,7 +592,7 @@ public class Pay3Api {
|
||||
throws WeixinException {
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getMchId(), ca);
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = DigestUtil.paysignMd5(map,
|
||||
weixinAccount.getPaySignKey());
|
||||
@ -681,13 +679,15 @@ public class Pay3Api {
|
||||
* @param billType
|
||||
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* @param billPath
|
||||
* 对账单保存路径
|
||||
* @return excel表格
|
||||
* @since V3
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6">下载对账单API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public File downloadBill(Date billDate, BillType billType)
|
||||
public File downloadBill(Date billDate, BillType billType, String billPath)
|
||||
throws WeixinException {
|
||||
if (billDate == null) {
|
||||
Calendar now = Calendar.getInstance();
|
||||
@ -698,11 +698,9 @@ public class Pay3Api {
|
||||
billType = BillType.ALL;
|
||||
}
|
||||
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
||||
String bill_path = Weixin4jConfigUtil.getValue("bill.path",
|
||||
Weixin4jConst.DEFAULT_BILL_PATH);
|
||||
String fileName = String.format("%s_%s_%s.txt", formatBillDate,
|
||||
billType.name().toLowerCase(), weixinAccount.getId());
|
||||
File file = new File(String.format("%s/%s", bill_path, fileName));
|
||||
File file = new File(String.format("%s/%s", billPath, fileName));
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
@ -820,13 +818,12 @@ public class Pay3Api {
|
||||
* @param authCode
|
||||
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
|
||||
* @return 查询结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult
|
||||
* @see com.foxinmy.weixin4j.payment.mch.OpenIdResult
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">授权码查询OPENID</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public AuthCodeOpenIdResult authCode2openId(String authCode)
|
||||
throws WeixinException {
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
map.put("auth_code", authCode);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
@ -834,7 +831,7 @@ public class Pay3Api {
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_AUTHCODE_OPENID_URL, param);
|
||||
return response.getAsObject(new TypeReference<AuthCodeOpenIdResult>() {
|
||||
return response.getAsObject(new TypeReference<OpenIdResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,10 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* 微信支付分配的商户号(商户平台版)
|
||||
*/
|
||||
private String mchId;
|
||||
/**
|
||||
* 加载支付证书文件的密码(商户平台版)
|
||||
*/
|
||||
private String certificateKey;
|
||||
/**
|
||||
* 微信支付分配的子商户号,受理模式下必填(商户平台版)
|
||||
*/
|
||||
@ -40,10 +44,6 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* 微信支付分配的设备号(商户平台版)
|
||||
*/
|
||||
private String deviceInfo;
|
||||
/**
|
||||
* 微信支付版本号(如果无则按照mchId来做判断)
|
||||
*/
|
||||
private int version;
|
||||
|
||||
/**
|
||||
* 商户平台版本(V3)字段
|
||||
@ -57,8 +57,9 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号(必填)
|
||||
*/
|
||||
public WeixinPayAccount(String appId, String appSecret, String paySignKey, String mchId) {
|
||||
this(appId, appSecret, paySignKey, mchId, null, null, null, null);
|
||||
public WeixinPayAccount(String appId, String appSecret, String paySignKey,
|
||||
String mchId) {
|
||||
this(appId, appSecret, paySignKey, mchId, null, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,6 +73,8 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* 支付密钥字符串(必填)
|
||||
* @param mchId
|
||||
* 微信支付分配的商户号(V3商户平台版必填)
|
||||
* @param certificateKey
|
||||
* 加载支付证书文件的密码(商户平台版)
|
||||
* @param subMchId
|
||||
* 微信支付分配的子商户号,受理模式下必填(V3商户平台版 非必须)
|
||||
* @param deviceInfo
|
||||
@ -82,13 +85,19 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
* 财付通商户权限密钥Key(V2版本必填)
|
||||
*/
|
||||
@JSONCreator
|
||||
public WeixinPayAccount(@JSONField(name = "id") String appId, @JSONField(name = "secret") String appSecret,
|
||||
@JSONField(name = "paySignKey") String paySignKey, @JSONField(name = "mchId") String mchId,
|
||||
@JSONField(name = "subMchId") String subMchId, @JSONField(name = "deviceInfo") String deviceInfo,
|
||||
@JSONField(name = "partnerId") String partnerId, @JSONField(name = "partnerKey") String partnerKey) {
|
||||
public WeixinPayAccount(@JSONField(name = "id") String appId,
|
||||
@JSONField(name = "secret") String appSecret,
|
||||
@JSONField(name = "paySignKey") String paySignKey,
|
||||
@JSONField(name = "mchId") String mchId,
|
||||
@JSONField(name = "certificateKey") String certificateKey,
|
||||
@JSONField(name = "subMchId") String subMchId,
|
||||
@JSONField(name = "deviceInfo") String deviceInfo,
|
||||
@JSONField(name = "partnerId") String partnerId,
|
||||
@JSONField(name = "partnerKey") String partnerKey) {
|
||||
super(appId, appSecret);
|
||||
this.paySignKey = paySignKey;
|
||||
this.mchId = mchId;
|
||||
this.certificateKey = certificateKey;
|
||||
this.subMchId = subMchId;
|
||||
this.deviceInfo = deviceInfo;
|
||||
this.partnerId = partnerId;
|
||||
@ -119,17 +128,16 @@ public class WeixinPayAccount extends WeixinAccount {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
if (version == 0) {
|
||||
return StringUtil.isNotBlank(mchId) ? 3 : 2;
|
||||
}
|
||||
return version;
|
||||
public String getCertificateKey() {
|
||||
return StringUtil.isBlank(certificateKey) ? mchId : certificateKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinPayAccount [" + super.toString() + ", paySignKey=" + paySignKey + ", partnerId=" + partnerId
|
||||
+ ", partnerKey=" + partnerKey + ", mchId=" + mchId + ", subMchId=" + subMchId + ", deviceInfo="
|
||||
+ deviceInfo + ", version=" + getVersion() + "]";
|
||||
return "WeixinPayAccount [" + super.toString() + ", paySignKey="
|
||||
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
|
||||
+ partnerKey + ", mchId=" + mchId + ", certificateKey="
|
||||
+ getCertificateKey() + ", subMchId=" + subMchId
|
||||
+ ", deviceInfo=" + deviceInfo + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.api.CashApi;
|
||||
import com.foxinmy.weixin4j.api.CouponApi;
|
||||
import com.foxinmy.weixin4j.api.Pay3Api;
|
||||
@ -18,25 +17,24 @@ import com.foxinmy.weixin4j.payment.coupon.CouponDetail;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponResult;
|
||||
import com.foxinmy.weixin4j.payment.coupon.CouponStock;
|
||||
import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPayment;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.MPPaymentResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
|
||||
import com.foxinmy.weixin4j.payment.mch.NativePayResponse;
|
||||
import com.foxinmy.weixin4j.payment.mch.OpenIdResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.payment.mch.Redpacket;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RedpacketSendResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
@ -54,26 +52,26 @@ public class WeixinPayProxy {
|
||||
private final CouponApi couponApi;
|
||||
private final CashApi cashApi;
|
||||
|
||||
private final WeixinPayAccount payAccount;
|
||||
private final Weixin4jPaySettings settings;
|
||||
|
||||
/**
|
||||
* 使用weixin4j.properties配置的账号信息
|
||||
* 使用weixin4j.properties配置的支付账号信息
|
||||
*/
|
||||
public WeixinPayProxy() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
this(new Weixin4jPaySettings());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param weixinAccount
|
||||
* 支付相关的公众号账号信息
|
||||
* @param settings
|
||||
* 支付相关配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jPaySettings
|
||||
*/
|
||||
public WeixinPayProxy(WeixinPayAccount payAccount) {
|
||||
this.payAccount = payAccount;
|
||||
this.pay3Api = new Pay3Api(payAccount);
|
||||
this.couponApi = new CouponApi(payAccount);
|
||||
this.cashApi = new CashApi(payAccount);
|
||||
public WeixinPayProxy(Weixin4jPaySettings settings) {
|
||||
this.settings = settings;
|
||||
this.pay3Api = new Pay3Api(settings.getPayAccount());
|
||||
this.couponApi = new CouponApi(settings.getPayAccount());
|
||||
this.cashApi = new CashApi(settings.getPayAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,9 +80,7 @@ public class WeixinPayProxy {
|
||||
* @return
|
||||
*/
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
// clone ...
|
||||
String text = JSON.toJSONString(payAccount);
|
||||
return JSON.parseObject(text, WeixinPayAccount.class);
|
||||
return this.settings.getPayAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -429,7 +425,7 @@ public class WeixinPayProxy {
|
||||
* </p>
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
@ -461,7 +457,7 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请(全额退款)采用properties中配置的ca文件
|
||||
* 退款申请(全额退款)
|
||||
*
|
||||
* @throws IOException
|
||||
*
|
||||
@ -470,12 +466,9 @@ public class WeixinPayProxy {
|
||||
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
|
||||
IdQuery idQuery, String outRefundNo, double totalFee)
|
||||
throws WeixinException, IOException {
|
||||
return pay3Api
|
||||
.refundApply(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
idQuery, outRefundNo, totalFee);
|
||||
return pay3Api.refundApply(
|
||||
new FileInputStream(settings.getCertificatePath()), idQuery,
|
||||
outRefundNo, totalFee);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -521,7 +514,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public File downloadBill(Date billDate, BillType billType)
|
||||
throws WeixinException {
|
||||
return pay3Api.downloadBill(billDate, billType);
|
||||
return pay3Api.downloadBill(billDate, billType, settings.getBillPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -546,7 +539,7 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正撤销:默认采用properties中配置的ca文件
|
||||
* 冲正撤销
|
||||
*
|
||||
* @param idQuery
|
||||
* transaction_id、out_trade_no 二选一
|
||||
@ -557,12 +550,8 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException,
|
||||
IOException {
|
||||
return pay3Api
|
||||
.reverseOrder(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
idQuery);
|
||||
return pay3Api.reverseOrder(
|
||||
new FileInputStream(settings.getCertificatePath()), idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -635,7 +624,7 @@ public class WeixinPayProxy {
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
* @param partnerTradeNo
|
||||
@ -659,18 +648,15 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券采用properties中配置的ca文件
|
||||
* 发放代金券
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendCoupon(InputStream, String, String, String, String)}
|
||||
*/
|
||||
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
|
||||
String openId) throws WeixinException, IOException {
|
||||
return couponApi
|
||||
.sendCoupon(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
couponStockId, partnerTradeNo, openId, null);
|
||||
return couponApi.sendCoupon(
|
||||
new FileInputStream(settings.getCertificatePath()),
|
||||
couponStockId, partnerTradeNo, openId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -711,7 +697,7 @@ public class WeixinPayProxy {
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
* @return 发放结果
|
||||
@ -728,25 +714,21 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包采用properties中配置的ca文件
|
||||
* 发放红包
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#sendRedpack(InputStream, Redpacket)}
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(Redpacket redpacket)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi
|
||||
.sendRedpack(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
redpacket);
|
||||
return cashApi.sendRedpack(
|
||||
new FileInputStream(settings.getCertificatePath()), redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
* @return 红包记录
|
||||
@ -762,25 +744,21 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询红包采用properties中配置的ca文件
|
||||
* 查询红包
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#queryRedpack(InputStream,String)}
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(String outTradeNo)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi
|
||||
.queryRedpack(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
outTradeNo);
|
||||
return cashApi.queryRedpack(
|
||||
new FileInputStream(settings.getCertificatePath()), outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param mpPayment
|
||||
* 付款信息
|
||||
* @return 付款结果
|
||||
@ -797,25 +775,21 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款采用properties中配置的ca文件
|
||||
* 企业付款
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPayment(InputStream, MPPayment)}
|
||||
*/
|
||||
public MPPaymentResult mpPayment(MPPayment mpPayment)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi
|
||||
.mchPayment(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
mpPayment);
|
||||
return cashApi.mchPayment(
|
||||
new FileInputStream(settings.getCertificatePath()), mpPayment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param ca
|
||||
* 证书文件(V3版本后缀为*.p12)
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
* @return 付款记录
|
||||
@ -831,18 +805,14 @@ public class WeixinPayProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询采用properties中配置的ca文件
|
||||
* 企业付款查询
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#mpPaymentQuery(InputStream, String)}
|
||||
*/
|
||||
public MPPaymentRecord mpPaymentQuery(String outTradeNo)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi
|
||||
.mchPaymentQuery(
|
||||
new FileInputStream(Weixin4jConfigUtil
|
||||
.getClassPathValue("certificate.file",
|
||||
Weixin4jConst.DEFAULT_CAFILE_PATH)),
|
||||
outTradeNo);
|
||||
return cashApi.mchPaymentQuery(
|
||||
new FileInputStream(settings.getCertificatePath()), outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -852,15 +822,14 @@ public class WeixinPayProxy {
|
||||
* 扫码支付授权码,设备读取用户微信中的条码或者二维码信息
|
||||
* @return 查询结果
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
* @see com.foxinmy.weixin4j.payment.mch.AuthCodeOpenIdResult
|
||||
* @see com.foxinmy.weixin4j.payment.mch.OpenIdResult
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9">授权码查询OPENID</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public AuthCodeOpenIdResult authCode2openId(String authCode)
|
||||
throws WeixinException {
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
return pay3Api.authCode2openId(authCode);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.6.6";
|
||||
public final static String VERSION = "1.6.7";
|
||||
}
|
||||
|
||||
@ -80,7 +80,6 @@ public class CouponDetail extends ApiResult {
|
||||
@XmlElement(name = "coupon_type")
|
||||
@JSONField(name = "coupon_type")
|
||||
private int couponType;
|
||||
|
||||
/**
|
||||
* 代金券描述
|
||||
*/
|
||||
|
||||
@ -5,8 +5,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* Native支付回调时POST的信息
|
||||
* Native支付回调时POST的信息
|
||||
*
|
||||
* @className PayNativeNotify
|
||||
* @author jy
|
||||
@ -16,27 +18,37 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class NativePayNotify extends ApiResult {
|
||||
public class NativePayNotify extends OpenIdResult {
|
||||
|
||||
private static final long serialVersionUID = 4515471400239795492L;
|
||||
|
||||
/**
|
||||
* 用户是否关注公众账号,Y- 关注,N-未关注,仅在公众 账号类型支付有效
|
||||
*/
|
||||
@XmlElement(name = "is_subscribe")
|
||||
@JSONField(name = "is_subscribe")
|
||||
private String isSubscribe;
|
||||
/**
|
||||
* 产品ID 可视为订单ID
|
||||
*/
|
||||
@XmlElement(name = "product_id")
|
||||
@JSONField(name = "product_id")
|
||||
private String productId;
|
||||
|
||||
protected NativePayNotify() {
|
||||
// jaxb required
|
||||
}
|
||||
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public String getIsSubscribe() {
|
||||
return isSubscribe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NativePayNotify [productId=" + productId + ", "
|
||||
+ super.toString() + "]";
|
||||
return "NativePayNotify [productId=" + productId + ", isSubscribe="
|
||||
+ isSubscribe + ", " + super.toString() + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
/**
|
||||
* authcode2openid
|
||||
*
|
||||
* @className AuthCodeOpenIdResult
|
||||
* @className OpenIdResult
|
||||
* @author jy
|
||||
* @date 2015年7月23日
|
||||
* @since JDK 1.6
|
||||
@ -18,7 +18,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class AuthCodeOpenIdResult extends ApiResult {
|
||||
public class OpenIdResult extends ApiResult {
|
||||
|
||||
private static final long serialVersionUID = 902743989722741814L;
|
||||
|
||||
@ -35,7 +35,7 @@ public class AuthCodeOpenIdResult extends ApiResult {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AuthCodeOpenIdResult [openId=" + openId + ", "
|
||||
return "OpenIdResult [openId=" + openId + ", "
|
||||
+ super.toString() + "]";
|
||||
}
|
||||
}
|
||||
@ -144,10 +144,6 @@ public class Redpacket implements Serializable {
|
||||
return amtType;
|
||||
}
|
||||
|
||||
public void setAmtType(String amtType) {
|
||||
this.amtType = amtType;
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
/**
|
||||
* 微信请求配置相关(待实现
|
||||
*
|
||||
* @className Weixin4jHttpSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jHttpSettings {
|
||||
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信支付配置相关
|
||||
*
|
||||
* @className Weixin4jPaySettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jPaySettings {
|
||||
|
||||
private final WeixinPayAccount payAccount;
|
||||
|
||||
public Weixin4jPaySettings() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
}
|
||||
|
||||
public Weixin4jPaySettings(WeixinPayAccount payAccount) {
|
||||
this.payAccount = payAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付账号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
return this.payAccount;
|
||||
}
|
||||
|
||||
private String billPath;
|
||||
|
||||
/**
|
||||
* 对账单保存路径
|
||||
*
|
||||
* @param billPath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jPaySettings billPath(String billPath) {
|
||||
this.billPath = billPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认对账单保存路径
|
||||
*/
|
||||
public static final String DEFAULT_BILL_PATH = "/tmp/weixin4j/bill";
|
||||
|
||||
/**
|
||||
* 对账单保存路径,默认值为{@link #DEFAULT_BILL_PATH}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getBillPath() {
|
||||
if (StringUtil.isBlank(billPath)) {
|
||||
this.billPath = Weixin4jConfigUtil.getClassPathValue("bill.path",
|
||||
DEFAULT_BILL_PATH);
|
||||
}
|
||||
return this.billPath;
|
||||
}
|
||||
|
||||
private String certificatePath;
|
||||
|
||||
/**
|
||||
* ca证书存放路径
|
||||
*
|
||||
* @param certificatePath
|
||||
* 硬盘目录
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jPaySettings certificatePath(String certificatePath) {
|
||||
this.certificatePath = certificatePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认ca证书存放路径
|
||||
*/
|
||||
public static final String DEFAULT_CAFILE_PATH = "classpath:ca.p12";
|
||||
|
||||
/**
|
||||
* ca证书存放路径,默认值为{@link #DEFAULT_CAFILE_PATH}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCertificatePath() {
|
||||
if (StringUtil.isBlank(certificatePath)) {
|
||||
this.certificatePath = Weixin4jConfigUtil.getClassPathValue(
|
||||
"certificate.path", DEFAULT_CAFILE_PATH);
|
||||
}
|
||||
return this.certificatePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jPaySettings [payAccount=" + payAccount + ", billPath="
|
||||
+ getBillPath() + ", certificatePath=" + getCertificatePath()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,168 @@
|
||||
package com.foxinmy.weixin4j.settings;
|
||||
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信基础配置相关
|
||||
*
|
||||
* @className Weixin4jSettings
|
||||
* @author jy
|
||||
* @date 2016年1月28日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class Weixin4jSettings {
|
||||
|
||||
private final WeixinAccount account;
|
||||
|
||||
public Weixin4jSettings() {
|
||||
this(Weixin4jConfigUtil.getWeixinAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* 应用唯一标识 appid/corpid
|
||||
* @param secret
|
||||
* 应用接口密钥
|
||||
*/
|
||||
public Weixin4jSettings(String id, String secret) {
|
||||
this(new WeixinAccount(id, secret));
|
||||
}
|
||||
|
||||
public Weixin4jSettings(WeixinAccount account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信账号信息
|
||||
*/
|
||||
public WeixinAccount getAccount() {
|
||||
return this.account;
|
||||
}
|
||||
|
||||
private String tokenPath;
|
||||
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径
|
||||
*
|
||||
* @param tokenPath
|
||||
* 硬盘目录
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jSettings setTokenPath(String tokenPath) {
|
||||
this.tokenPath = tokenPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认token的存放路径
|
||||
*/
|
||||
public static final String DEFAULT_TOKEN_PATH = "/tmp/weixin4j/token";
|
||||
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径,默认值为{@link #DEFAULT_TOKEN_PATH}
|
||||
*/
|
||||
public String getTokenPath() {
|
||||
if (StringUtil.isBlank(tokenPath)) {
|
||||
tokenPath = Weixin4jConfigUtil.getClassPathValue("token.path",
|
||||
DEFAULT_TOKEN_PATH);
|
||||
}
|
||||
return tokenPath;
|
||||
}
|
||||
|
||||
private String qrcodePath;
|
||||
|
||||
/**
|
||||
* 二维码保存路径
|
||||
*
|
||||
* @param qrcodePath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jSettings setQrcodePath(String qrcodePath) {
|
||||
this.qrcodePath = qrcodePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认二维码保存路径
|
||||
*/
|
||||
public static final String DEFAULT_QRCODE_PATH = "/tmp/weixin4j/qrcode";
|
||||
|
||||
/**
|
||||
* 二维码保存路径,默认值为{@link #DEFAULT_QRCODE_PATH}
|
||||
*/
|
||||
public String getQrcodePath() {
|
||||
if (StringUtil.isBlank(qrcodePath)) {
|
||||
this.qrcodePath = Weixin4jConfigUtil.getClassPathValue(
|
||||
"qrcode.path", DEFAULT_QRCODE_PATH);
|
||||
}
|
||||
return this.qrcodePath;
|
||||
}
|
||||
|
||||
private String mediaPath;
|
||||
|
||||
/**
|
||||
* 媒体文件保存路径
|
||||
*
|
||||
* @param mediaPath
|
||||
* 硬盘目录
|
||||
*/
|
||||
public Weixin4jSettings setMediaPath(String mediaPath) {
|
||||
this.mediaPath = mediaPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认媒体文件保存路径
|
||||
*/
|
||||
public static final String DEFAULT_MEDIA_PATH = "/tmp/weixin4j/media";
|
||||
|
||||
/**
|
||||
* 媒体文件保存路径,默认值为{@link #DEFAULT_MEDIA_PATH}
|
||||
*/
|
||||
public String getMediaPath() {
|
||||
if (StringUtil.isBlank(mediaPath)) {
|
||||
this.mediaPath = Weixin4jConfigUtil.getClassPathValue("media.path",
|
||||
DEFAULT_MEDIA_PATH);
|
||||
}
|
||||
return this.mediaPath;
|
||||
}
|
||||
|
||||
private TokenStorager tokenStorager;
|
||||
|
||||
/**
|
||||
* token存储
|
||||
*
|
||||
* @param tokenStorager
|
||||
* @return
|
||||
*/
|
||||
public Weixin4jSettings setTokenStorager(TokenStorager tokenStorager) {
|
||||
this.tokenStorager = tokenStorager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token存储方式 默认为FileTokenStorager
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TokenStorager getTokenStorager() {
|
||||
if (tokenStorager == null) {
|
||||
this.tokenStorager = new FileTokenStorager(getTokenPath());
|
||||
}
|
||||
return this.tokenStorager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weixin4jSettings [account=" + account + ", tokenPath="
|
||||
+ getTokenPath() + ", qrcodePath=" + getQrcodePath()
|
||||
+ ", mediaPath=" + getMediaPath() + ", tokenStorager="
|
||||
+ getTokenStorager() + "]";
|
||||
}
|
||||
}
|
||||
@ -44,7 +44,7 @@ public interface CacheStorager<T> {
|
||||
T evict(String cacheKey);
|
||||
|
||||
/**
|
||||
* 清除所有缓存对象(<font color="red">请慎重</a>)
|
||||
* 清除所有缓存对象(<font color="red">请慎重</font>)
|
||||
*/
|
||||
void clear();
|
||||
}
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.payment.mch.NativePayNotify;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 签名工具类
|
||||
@ -130,4 +135,12 @@ public final class DigestUtil {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
NativePayNotify notify = XmlStream.fromXML(new FileInputStream(
|
||||
new File("/Users/jy/Downloads/weixin4j.xml")),
|
||||
NativePayNotify.class);
|
||||
notify.setSign(null);
|
||||
System.err.println(paysignMd5(notify, "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ public class Weixin4jConfigUtil {
|
||||
value = getValue(key);
|
||||
} catch (MissingResourceException e) {
|
||||
;
|
||||
}catch (NullPointerException e){
|
||||
} catch (NullPointerException e) {
|
||||
;
|
||||
}
|
||||
return value;
|
||||
@ -88,8 +88,7 @@ public class Weixin4jConfigUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String getClassPathValue(String key) {
|
||||
return new File(getValue(key).replaceFirst(CLASSPATH_PREFIX,
|
||||
CLASSPATH_VALUE)).getPath();
|
||||
return getValue(key).replaceFirst(CLASSPATH_PREFIX, CLASSPATH_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,18 +98,18 @@ public class Weixin4jConfigUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String getClassPathValue(String key, String defaultValue) {
|
||||
return new File(getValue(key, defaultValue).replaceFirst(
|
||||
CLASSPATH_PREFIX, CLASSPATH_VALUE)).getPath();
|
||||
return getValue(key, defaultValue).replaceFirst(CLASSPATH_PREFIX,
|
||||
CLASSPATH_VALUE);
|
||||
}
|
||||
|
||||
public static WeixinAccount getWeixinAccount() {
|
||||
if (weixinBundle == null) {
|
||||
return null;
|
||||
}
|
||||
WeixinAccount account = null;
|
||||
try {
|
||||
account = JSON
|
||||
.parseObject(getValue("account"), WeixinAccount.class);
|
||||
} catch (NullPointerException e) {
|
||||
System.err
|
||||
.println("'weixin4j.account' key not found in weixin4j.properties.");
|
||||
} catch (MissingResourceException e) {
|
||||
System.err
|
||||
.println("'weixin4j.account' key not found in weixin4j.properties.");
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
/**
|
||||
* 常量配置
|
||||
*
|
||||
* @className Weixin4jConst
|
||||
* @author jy
|
||||
* @date 2015年7月1日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public final class Weixin4jConst {
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径
|
||||
*/
|
||||
public static final String DEFAULT_TOKEN_PATH = "/tmp/weixin4j/token";
|
||||
/**
|
||||
* 二维码保存路径
|
||||
*/
|
||||
public static final String DEFAULT_QRCODE_PATH = "/tmp/weixin4j/qrcode";
|
||||
/**
|
||||
* 媒体文件保存路径
|
||||
*/
|
||||
public static final String DEFAULT_MEDIA_PATH = "/tmp/weixin4j/media";
|
||||
/**
|
||||
* 对账单保存路径
|
||||
*/
|
||||
public static final String DEFAULT_BILL_PATH = "/tmp/weixin4j/bill";
|
||||
/**
|
||||
* ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
*/
|
||||
public static final String DEFAULT_CAFILE_PATH = "classpath:ca.p12";
|
||||
}
|
||||
@ -67,7 +67,9 @@ public class HttpClientTest {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for(int i=0;i<100000;i++){
|
||||
test1();
|
||||
}
|
||||
System.out.println("---------------------");
|
||||
test2();
|
||||
System.out.println("---------------------");
|
||||
|
||||
@ -58,21 +58,27 @@ weixin4j.properties说明
|
||||
|
||||
完整填写示例(properties中换行用右斜杆\\)
|
||||
|
||||
weixin4j.account={"id":"appId","secret":"appSecret",\
|
||||
"mchId":"V3.x版本下的微信商户号",\
|
||||
"partnerId":"V2版本下的财付通的商户号",\
|
||||
"partnerKey":"V2版本下的财付通商户权限密钥Key",\
|
||||
"paySignKey":"微信支付中调用API的密钥"}
|
||||
weixin4j.account={"id":"appid","secret":"appsecret",\
|
||||
"mchId":"V3.x版本下的微信商户号 微信支付时需要填入",\
|
||||
"certificateKey":"加载支付证书文件的密码 如果不填写则默认获取mchId作为密码",\
|
||||
"partnerId":"V2版本下的财付通的商户号 微信支付时需要填入",\
|
||||
"partnerKey":"V2版本下的财付通商户权限密钥Key 微信支付时需要填入",\
|
||||
"paySignKey":"微信支付中调用API的密钥 微信支付时需要填入"}
|
||||
|
||||
# 使用FileTokenStorager时token的存放路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# 二维码保存路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# 媒体文件保存路径(如果不填则默认为Weixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# 对账单保存路径(如果不填则默认为Weixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
#classpath路径下:weixin4j.certificate.file=classpath:xxxxx.p12
|
||||
# classpath路径下可以这么写(如果不填则默认为Weixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
#公众号登陆授权的重定向路径(使用OauthApi时需要填写)
|
||||
# 用户oauth授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.user.oauth.redirect.uri=http://xxx
|
||||
|
||||
2.实例化微信公众号接口代理对象,调用具体的API方法
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.7</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-mp</artifactId>
|
||||
<name>weixin4j-mp</name>
|
||||
|
||||
@ -14,6 +14,7 @@ import com.foxinmy.weixin4j.model.MediaItem;
|
||||
import com.foxinmy.weixin4j.model.MediaRecord;
|
||||
import com.foxinmy.weixin4j.model.MediaUploadResult;
|
||||
import com.foxinmy.weixin4j.model.Pageable;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
||||
import com.foxinmy.weixin4j.mp.api.DataApi;
|
||||
import com.foxinmy.weixin4j.mp.api.GroupApi;
|
||||
@ -21,7 +22,6 @@ import com.foxinmy.weixin4j.mp.api.HelperApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MassApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MenuApi;
|
||||
import com.foxinmy.weixin4j.mp.api.MpApi;
|
||||
import com.foxinmy.weixin4j.mp.api.NotifyApi;
|
||||
import com.foxinmy.weixin4j.mp.api.QrApi;
|
||||
import com.foxinmy.weixin4j.mp.api.TmplApi;
|
||||
@ -47,8 +47,8 @@ import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.mp.type.DatacubeType;
|
||||
import com.foxinmy.weixin4j.mp.type.IndustryType;
|
||||
import com.foxinmy.weixin4j.mp.type.Lang;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.tuple.MassTuple;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.MpVideo;
|
||||
@ -80,45 +80,26 @@ public class WeixinProxy {
|
||||
private final DataApi dataApi;
|
||||
|
||||
private final TokenHolder tokenHolder;
|
||||
private String appId;
|
||||
private Weixin4jSettings settings;
|
||||
|
||||
/**
|
||||
* 默认使用文件方式保存token、使用weixin4j.properties配置的账号信息
|
||||
*/
|
||||
public WeixinProxy() {
|
||||
this(MpApi.DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的账号信息
|
||||
*
|
||||
* @param tokenStorager
|
||||
*/
|
||||
public WeixinProxy(TokenStorager tokenStorager) {
|
||||
this(MpApi.DEFAULT_WEIXIN_ACCOUNT.getId(), MpApi.DEFAULT_WEIXIN_ACCOUNT
|
||||
.getSecret(), tokenStorager);
|
||||
this(new Weixin4jSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param appid
|
||||
* @param appsecret
|
||||
* @param settings
|
||||
* 配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jSettings
|
||||
*/
|
||||
public WeixinProxy(String appid, String appsecret) {
|
||||
this(appid, appsecret, MpApi.DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param appid
|
||||
* @param appsecret
|
||||
* @param tokenStorager
|
||||
*/
|
||||
public WeixinProxy(String appid, String appsecret,
|
||||
TokenStorager tokenStorager) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(appid, appsecret),
|
||||
tokenStorager));
|
||||
this.appId = appid;
|
||||
public WeixinProxy(Weixin4jSettings settings) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount()
|
||||
.getId(), settings.getAccount().getSecret()),
|
||||
settings.getTokenStorager()));
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,12 +124,12 @@ public class WeixinProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取appid
|
||||
* 获取微信账号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getAppId() {
|
||||
return this.appId;
|
||||
public WeixinAccount getWeixinAccount() {
|
||||
return this.settings.getAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,8 +149,9 @@ public class WeixinProxy {
|
||||
* @return
|
||||
*/
|
||||
public TokenHolder getTicketHolder(TicketType ticketType) {
|
||||
return new TokenHolder(new WeixinTicketCreator(this.appId, ticketType,
|
||||
this.tokenHolder), this.tokenHolder.getTokenStorager());
|
||||
return new TokenHolder(new WeixinTicketCreator(getWeixinAccount()
|
||||
.getId(), ticketType, this.tokenHolder),
|
||||
this.tokenHolder.getTokenStorager());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,10 +230,8 @@ public class WeixinProxy {
|
||||
*
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @param mediaType
|
||||
* 媒体类型
|
||||
* @param isMaterial
|
||||
* 是否永久素材
|
||||
* 是否下载永久素材
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
@ -261,7 +241,8 @@ public class WeixinProxy {
|
||||
*/
|
||||
public File downloadMediaFile(String mediaId, boolean isMaterial)
|
||||
throws WeixinException {
|
||||
return mediaApi.downloadMediaFile(mediaId, isMaterial);
|
||||
return mediaApi.downloadMediaFile(mediaId, isMaterial,
|
||||
settings.getMediaPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1215,11 +1196,13 @@ public class WeixinProxy {
|
||||
* 生成带参数的二维码
|
||||
*
|
||||
* @return 硬盘存储的文件对象
|
||||
* @param parameter
|
||||
* 二维码参数
|
||||
* @throws WeixinException
|
||||
* @see {@link #createQR(QRParameter)}
|
||||
*/
|
||||
public File createQRFile(QRParameter parameter) throws WeixinException {
|
||||
return qrApi.createQRFile(parameter);
|
||||
return qrApi.createQRFile(parameter, settings.getQrcodePath());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1463,5 +1446,5 @@ public class WeixinProxy {
|
||||
return dataApi.datacube(datacubeType, date);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.6.6";
|
||||
public final static String VERSION = "1.6.7";
|
||||
}
|
||||
|
||||
@ -48,8 +48,6 @@ import com.foxinmy.weixin4j.util.IOUtil;
|
||||
import com.foxinmy.weixin4j.util.ObjectId;
|
||||
import com.foxinmy.weixin4j.util.RegexUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
import com.foxinmy.weixin4j.util.WeixinErrorUtil;
|
||||
|
||||
/**
|
||||
@ -238,7 +236,11 @@ public class MediaApi extends MpApi {
|
||||
*
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
|
||||
* @param isMaterial
|
||||
* 是否下载永久素材
|
||||
* @param mediaPath
|
||||
* 媒体素材保存路径
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/11/07b6b76a6b6e8848e855a435d5e34a5f.html">下载临时媒体文件</a>
|
||||
@ -246,12 +248,10 @@ public class MediaApi extends MpApi {
|
||||
* href="http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html">下载永久媒体素材</a>
|
||||
* @see {@link #downloadMedia(String,boolean)}
|
||||
*/
|
||||
public File downloadMediaFile(String mediaId, boolean isMaterial)
|
||||
throws WeixinException {
|
||||
String media_path = Weixin4jConfigUtil.getValue("media.path",
|
||||
Weixin4jConst.DEFAULT_MEDIA_PATH);
|
||||
public File downloadMediaFile(String mediaId, boolean isMaterial,
|
||||
String mediaPath) throws WeixinException {
|
||||
final String prefixName = String.format("%s.", mediaId);
|
||||
File[] files = new File(media_path).listFiles(new FilenameFilter() {
|
||||
File[] files = new File(mediaPath).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.startsWith(prefixName);
|
||||
@ -261,7 +261,7 @@ public class MediaApi extends MpApi {
|
||||
return files[0];
|
||||
}
|
||||
MediaDownloadResult result = downloadMedia(mediaId, isMaterial);
|
||||
File file = new File(media_path + File.separator + result.getFileName());
|
||||
File file = new File(mediaPath + File.separator + result.getFileName());
|
||||
OutputStream os = null;
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
|
||||
@ -7,11 +7,12 @@ import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.mp.model.OauthToken;
|
||||
import com.foxinmy.weixin4j.mp.model.User;
|
||||
import com.foxinmy.weixin4j.mp.type.Lang;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* oauth授权
|
||||
@ -25,13 +26,23 @@ import com.foxinmy.weixin4j.util.StringUtil;
|
||||
*/
|
||||
public class OauthApi extends MpApi {
|
||||
|
||||
private final WeixinAccount account;
|
||||
|
||||
public OauthApi() {
|
||||
this(Weixin4jConfigUtil.getWeixinAccount());
|
||||
}
|
||||
|
||||
public OauthApi(WeixinAccount account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link #getAuthorizeURL(String, String,String)}
|
||||
*
|
||||
* @return 请求授权的URL
|
||||
*/
|
||||
public String getAuthorizeURL() {
|
||||
String appId = DEFAULT_WEIXIN_ACCOUNT.getId();
|
||||
String appId = account.getId();
|
||||
String redirectUri = Weixin4jConfigUtil
|
||||
.getValue("user.oauth.redirect.uri");
|
||||
return getAuthorizeURL(appId, redirectUri, "state", "snsapi_base");
|
||||
@ -67,8 +78,7 @@ public class OauthApi extends MpApi {
|
||||
* @return
|
||||
*/
|
||||
public OauthToken getOauthToken(String code) throws WeixinException {
|
||||
return getOauthToken(code, DEFAULT_WEIXIN_ACCOUNT.getId(),
|
||||
DEFAULT_WEIXIN_ACCOUNT.getSecret());
|
||||
return getOauthToken(code, account.getId(), account.getSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,7 +110,7 @@ public class OauthApi extends MpApi {
|
||||
* @return
|
||||
*/
|
||||
public OauthToken refreshToken(String refreshToken) throws WeixinException {
|
||||
return refreshToken(DEFAULT_WEIXIN_ACCOUNT.getId(), refreshToken);
|
||||
return refreshToken(account.getId(), refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -40,6 +40,9 @@ import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2;
|
||||
import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
@ -51,8 +54,6 @@ import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
|
||||
/**
|
||||
@ -66,23 +67,27 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
*/
|
||||
public class Pay2Api extends MpApi {
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
private final Weixin4jPaySettings settings;
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public Pay2Api() {
|
||||
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
|
||||
WeixinPayAccount.class));
|
||||
this(new Weixin4jPaySettings());
|
||||
}
|
||||
|
||||
public Pay2Api(WeixinPayAccount weixinAccount) {
|
||||
this(weixinAccount, DEFAULT_TOKEN_STORAGER);
|
||||
public Pay2Api(Weixin4jPaySettings settings) {
|
||||
this(settings, new FileTokenStorager(
|
||||
Weixin4jSettings.DEFAULT_TOKEN_PATH));
|
||||
}
|
||||
|
||||
public Pay2Api(WeixinPayAccount weixinAccount, TokenStorager tokenStorager) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
weixinAccount.getId(), weixinAccount.getSecret()),
|
||||
tokenStorager);
|
||||
public Pay2Api(Weixin4jPaySettings settings, TokenStorager tokenStorager) {
|
||||
this.settings = settings;
|
||||
this.tokenHolder = new TokenHolder(
|
||||
new WeixinTokenCreator(settings.getPayAccount().getId(),
|
||||
settings.getPayAccount().getSecret()), tokenStorager);
|
||||
}
|
||||
|
||||
public WeixinPayAccount getPayAccount() {
|
||||
return this.settings.getPayAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,20 +142,20 @@ public class Pay2Api extends MpApi {
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, double transportFee,
|
||||
double productFee, String goodsTag) {
|
||||
PayPackageV2 payPackage = new PayPackageV2(
|
||||
weixinAccount.getPartnerId(), body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp);
|
||||
PayPackageV2 payPackage = new PayPackageV2(settings.getPayAccount()
|
||||
.getPartnerId(), body, outTradeNo, totalFee, notifyUrl,
|
||||
createIp);
|
||||
payPackage.setAttach(attach);
|
||||
payPackage.setTimeStart(timeStart);
|
||||
payPackage.setTimeExpire(timeExpire);
|
||||
payPackage.setTransportFee(transportFee);
|
||||
payPackage.setProductFee(productFee);
|
||||
payPackage.setGoodsTag(goodsTag);
|
||||
PayRequest payRequest = new PayRequest(weixinAccount.getId(),
|
||||
DigestUtil.packageSign(payPackage,
|
||||
weixinAccount.getPartnerKey()));
|
||||
payRequest.setPaySign(DigestUtil.paysignSha(payRequest,
|
||||
weixinAccount.getPaySignKey()));
|
||||
PayRequest payRequest = new PayRequest(getPayAccount().getId(),
|
||||
DigestUtil.packageSign(payPackage, getPayAccount()
|
||||
.getPartnerKey()));
|
||||
payRequest.setPaySign(DigestUtil.paysignSha(payRequest, getPayAccount()
|
||||
.getPaySignKey()));
|
||||
payRequest.setSignType(SignType.SHA1);
|
||||
return JSON.toJSONString(payRequest);
|
||||
}
|
||||
@ -166,14 +171,14 @@ public class Pay2Api extends MpApi {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
String timestamp = DateUtil.timestamp2string();
|
||||
String noncestr = RandomUtil.generateString(16);
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("appid", getPayAccount().getId());
|
||||
map.put("timestamp", timestamp);
|
||||
map.put("noncestr", noncestr);
|
||||
map.put("productid", productId);
|
||||
map.put("appkey", weixinAccount.getPaySignKey());
|
||||
map.put("appkey", getPayAccount().getPaySignKey());
|
||||
String sign = DigestUtil.paysignSha(map, null);
|
||||
String ordernative_v2_uri = getRequestUri("ordernative_v2_uri");
|
||||
return String.format(ordernative_v2_uri, sign, weixinAccount.getId(),
|
||||
return String.format(ordernative_v2_uri, sign, getPayAccount().getId(),
|
||||
productId, timestamp, noncestr);
|
||||
}
|
||||
|
||||
@ -193,23 +198,23 @@ public class Pay2Api extends MpApi {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(idQuery.getType().getName()).append("=")
|
||||
.append(idQuery.getId());
|
||||
sb.append("&partner=").append(weixinAccount.getPartnerId());
|
||||
sb.append("&partner=").append(getPayAccount().getPartnerId());
|
||||
String part = sb.toString();
|
||||
sb.append("&key=").append(weixinAccount.getPartnerKey());
|
||||
sb.append("&key=").append(getPayAccount().getPartnerKey());
|
||||
String sign = DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
sb.delete(0, sb.length());
|
||||
sb.append(part).append("&sign=").append(sign);
|
||||
|
||||
String timestamp = DateUtil.timestamp2string();
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("appid", weixinAccount.getId());
|
||||
obj.put("appkey", weixinAccount.getPaySignKey());
|
||||
obj.put("appid", getPayAccount().getId());
|
||||
obj.put("appkey", getPayAccount().getPaySignKey());
|
||||
obj.put("package", sb.toString());
|
||||
obj.put("timestamp", timestamp);
|
||||
String signature = DigestUtil.paysignSha(obj, null);
|
||||
|
||||
obj.clear();
|
||||
obj.put("appid", weixinAccount.getId());
|
||||
obj.put("appid", getPayAccount().getId());
|
||||
obj.put("package", sb.toString());
|
||||
obj.put("timestamp", timestamp);
|
||||
obj.put("app_signature", signature);
|
||||
@ -271,20 +276,20 @@ public class Pay2Api extends MpApi {
|
||||
// 填写为 1.0 时,操作员密码为明文
|
||||
// 填写为 1.1 时,操作员密码为 MD5(密码)值
|
||||
map.put("service_version", "1.1");
|
||||
map.put("partner", weixinAccount.getPartnerId());
|
||||
map.put("partner", getPayAccount().getPartnerId());
|
||||
map.put("out_refund_no", outRefundNo);
|
||||
map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
|
||||
map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
if (StringUtil.isBlank(opUserId)) {
|
||||
opUserId = weixinAccount.getPartnerId();
|
||||
opUserId = getPayAccount().getPartnerId();
|
||||
}
|
||||
map.put("op_user_id", opUserId);
|
||||
if (mopara != null && !mopara.isEmpty()) {
|
||||
map.putAll(mopara);
|
||||
}
|
||||
String sign = DigestUtil.paysignMd5(map,
|
||||
weixinAccount.getPartnerKey());
|
||||
String sign = DigestUtil.paysignMd5(map, getPayAccount()
|
||||
.getPartnerKey());
|
||||
map.put("sign", sign.toUpperCase());
|
||||
|
||||
SSLContext ctx = null;
|
||||
@ -319,8 +324,8 @@ public class Pay2Api extends MpApi {
|
||||
KeyManagerFactory kmf = KeyManagerFactory
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
|
||||
ks = KeyStore.getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12);
|
||||
ks.load(ca, weixinAccount.getPartnerId().toCharArray());
|
||||
kmf.init(ks, weixinAccount.getPartnerId().toCharArray());
|
||||
ks.load(ca, getPayAccount().getPartnerId().toCharArray());
|
||||
kmf.init(ks, getPayAccount().getPartnerId().toCharArray());
|
||||
|
||||
ctx = SSLContext.getInstance(com.foxinmy.weixin4j.model.Consts.TLS);
|
||||
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
|
||||
@ -451,23 +456,22 @@ public class Pay2Api extends MpApi {
|
||||
billType = BillType.ALL;
|
||||
}
|
||||
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
|
||||
String bill_path = Weixin4jConfigUtil.getValue("bill.path",
|
||||
Weixin4jConst.DEFAULT_BILL_PATH);
|
||||
String fileName = String.format("%s_%s_%s.txt", formatBillDate,
|
||||
billType.name().toLowerCase(), weixinAccount.getId());
|
||||
File file = new File(String.format("%s/%s", bill_path, fileName));
|
||||
billType.name().toLowerCase(), getPayAccount().getId());
|
||||
File file = new File(String.format("%s/%s", settings.getBillPath(),
|
||||
fileName));
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
String downloadbill_uri = getRequestUri("downloadbill_v2_uri");
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<String, String>();
|
||||
map.put("spid", weixinAccount.getPartnerId());
|
||||
map.put("spid", getPayAccount().getPartnerId());
|
||||
map.put("trans_time", DateUtil.fortmat2yyyy_MM_dd(billDate));
|
||||
map.put("stamp", DateUtil.timestamp2string());
|
||||
map.put("cft_signtype", "0");
|
||||
map.put("mchtype", Integer.toString(billType.getVal()));
|
||||
map.put("key", weixinAccount.getPartnerKey());
|
||||
map.put("key", getPayAccount().getPartnerKey());
|
||||
String sign = DigestUtil.MD5(MapUtil.toJoinString(map, false, false));
|
||||
map.put("sign", sign.toLowerCase());
|
||||
WeixinResponse response = weixinExecutor.get(downloadbill_uri, map);
|
||||
@ -517,9 +521,10 @@ public class Pay2Api extends MpApi {
|
||||
String refundquery_uri = getRequestUri("refundquery_v2_uri");
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("input_charset", Consts.UTF_8.name());
|
||||
map.put("partner", weixinAccount.getPartnerId());
|
||||
map.put("partner", getPayAccount().getPartnerId());
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPartnerKey());
|
||||
String sign = DigestUtil.paysignMd5(map, getPayAccount()
|
||||
.getPartnerKey());
|
||||
map.put("sign", sign.toLowerCase());
|
||||
WeixinResponse response = weixinExecutor.get(refundquery_uri, map);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
@ -549,8 +554,8 @@ public class Pay2Api extends MpApi {
|
||||
Token token = tokenHolder.getToken();
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("appkey", weixinAccount.getPaySignKey());
|
||||
map.put("appid", getPayAccount().getId());
|
||||
map.put("appkey", getPayAccount().getPaySignKey());
|
||||
map.put("openid", openId);
|
||||
map.put("transid", transid);
|
||||
map.put("out_trade_no", outTradeNo);
|
||||
|
||||
@ -13,8 +13,6 @@ import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.mp.model.QRResult;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.util.IOUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
|
||||
/**
|
||||
* 二维码相关API
|
||||
@ -55,7 +53,8 @@ public class QrApi extends MpApi {
|
||||
QRResult result = response.getAsObject(new TypeReference<QRResult>() {
|
||||
});
|
||||
qr_uri = getRequestUri("qr_image_uri");
|
||||
response = weixinExecutor.get(String.format(qr_uri, result.getTicket()));
|
||||
response = weixinExecutor
|
||||
.get(String.format(qr_uri, result.getTicket()));
|
||||
try {
|
||||
result.setContent(IOUtil.toByteArray(response.getBody()));
|
||||
} catch (IOException e) {
|
||||
@ -72,6 +71,8 @@ public class QrApi extends MpApi {
|
||||
*
|
||||
* @param parameter
|
||||
* 二维码参数
|
||||
* @param qrcodePath
|
||||
* 二维码保存路径
|
||||
* @return 硬盘存储的文件对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
@ -79,13 +80,12 @@ public class QrApi extends MpApi {
|
||||
* @see #createQR(QRParameter)
|
||||
* @see com.foxinmy.weixin4j.mp.model.QRParameter
|
||||
*/
|
||||
public File createQRFile(QRParameter parameter) throws WeixinException {
|
||||
String qr_path = Weixin4jConfigUtil.getValue("qrcode.path",
|
||||
Weixin4jConst.DEFAULT_QRCODE_PATH);
|
||||
public File createQRFile(QRParameter parameter, String qrcodePath)
|
||||
throws WeixinException {
|
||||
String filename = String.format("%s_%s_%d.jpg", parameter.getQrType()
|
||||
.name(), parameter.getSceneValue(), parameter
|
||||
.getExpireSeconds());
|
||||
File file = new File(qr_path + File.separator + filename);
|
||||
File file = new File(qrcodePath + File.separator + filename);
|
||||
if (parameter.getQrType().ordinal() > 0 && file.exists()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -1,23 +1,24 @@
|
||||
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||
# \u516c\u4f17\u53f7\u4fe1\u606f
|
||||
weixin4j.account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
|
||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"partnerId":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
|
||||
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"certificateKey":"\u52a0\u8f7d\u652f\u4ed8\u8bc1\u4e66\u6587\u4ef6\u7684\u5bc6\u7801 \u5982\u679c\u4e0d\u586b\u5199\u5219\u9ed8\u8ba4\u83b7\u53d6mchId\u4f5c\u4e3a\u5bc6\u7801",\
|
||||
"partnerId":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7 \u8001\u7248\u672c\u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u8001\u7248\u672c\u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
|
||||
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84
|
||||
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84 (V2\u7248\u672c\u540e\u7f00\u4e3a*.pfx,V3\u7248\u672c\u540e\u7f00\u4e3a*.p12)
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# \u7528\u6237oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
# \u7528\u6237oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
@ -94,7 +94,8 @@ public class MediaTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void download2() throws WeixinException, IOException {
|
||||
File file = mediaApi.downloadMediaFile("8790403529", true);
|
||||
File file = mediaApi.downloadMediaFile("8790403529", true,
|
||||
"/tmp/weixin4j/media");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
|
||||
|
||||
@ -19,12 +19,11 @@ import com.foxinmy.weixin4j.payment.mch.ApiResult;
|
||||
import com.foxinmy.weixin4j.payment.mch.MchPayPackage;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.payment.mch.PrePay;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jPaySettings;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.type.IdType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
public class PayTest {
|
||||
protected final static Pay2Api PAY2;
|
||||
@ -33,14 +32,13 @@ public class PayTest {
|
||||
protected final static WeixinPayAccount ACCOUNT3;
|
||||
static {
|
||||
ACCOUNT2 = new WeixinPayAccount("请填入v2版本的appid", "请填入v2版本的appSecret",
|
||||
"请填入v2版本的paysignkey", null, null, null, "请填入v2版本的partnerId",
|
||||
"请填入v2版本的partnerKey");
|
||||
PAY2 = new Pay2Api(ACCOUNT2, new FileTokenStorager(
|
||||
Weixin4jConfigUtil
|
||||
.getValue("token.path", "/tmp/weixin4j/token")));
|
||||
"请填入v2版本的paysignkey", null, null, null, null,
|
||||
"请填入v2版本的partnerId", "请填入v2版本的partnerKey");
|
||||
PAY2 = new Pay2Api(new Weixin4jPaySettings(ACCOUNT2));
|
||||
ACCOUNT3 = new WeixinPayAccount("请填入v3版本的appid", "请填入v3版本的appSecret",
|
||||
"请填入v3版本的paysignkey", "请填入v3版本的mchid", null, null, null, null);
|
||||
PAY3 = new WeixinPayProxy(ACCOUNT3);
|
||||
"请填入v3版本的paysignkey", "请填入v3版本的mchid", null, null, null, null,
|
||||
null);
|
||||
PAY3 = new WeixinPayProxy(new Weixin4jPaySettings(ACCOUNT3));
|
||||
}
|
||||
/**
|
||||
* 商户证书文件
|
||||
@ -55,7 +53,6 @@ public class PayTest {
|
||||
|
||||
@Test
|
||||
public void refundV2() throws WeixinException {
|
||||
File caFile = new File("证书文件,如12333.pfx");
|
||||
IdQuery idQuery = new IdQuery("D15020300005", IdType.TRADENO);
|
||||
System.err.println(PAY2.refundApply(caFile, idQuery, "1422925555037",
|
||||
16d, 16d, "1221928801", "111111", null, null, null));
|
||||
@ -84,7 +81,8 @@ public class PayTest {
|
||||
System.err.println(order);
|
||||
String sign = order.getSign();
|
||||
order.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(order, ACCOUNT3.getPaySignKey());
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(order, ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
@ -98,7 +96,8 @@ public class PayTest {
|
||||
// 这里的验证签名需要把details循环拼接
|
||||
String sign = record.getSign();
|
||||
record.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(record, ACCOUNT3.getPaySignKey());
|
||||
String valiSign = DigestUtil.paysignMd5(record,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
@ -118,7 +117,6 @@ public class PayTest {
|
||||
|
||||
@Test
|
||||
public void refundV3() throws WeixinException, IOException {
|
||||
File caFile = new File("签名文件如123.p12");
|
||||
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
|
||||
com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY3
|
||||
.refundApply(new FileInputStream(caFile), idQuery, "TT_R"
|
||||
@ -127,7 +125,8 @@ public class PayTest {
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result, ACCOUNT3.getPaySignKey());
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
@ -154,7 +153,8 @@ public class PayTest {
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(result, ACCOUNT3.getPaySignKey());
|
||||
String valiSign = DigestUtil.paysignMd5(result,
|
||||
ACCOUNT3.getPaySignKey());
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
|
||||
@ -29,19 +29,23 @@ public class QRTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void temp_qr() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(QRParameter.createTemporary(1200, 1200));
|
||||
File file = qrApi.createQRFile(QRParameter.createTemporary(1200, 1200),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_int() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(QRParameter.createPermanenceInt(2));
|
||||
File file = qrApi.createQRFile(QRParameter.createPermanenceInt(2),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_str() throws WeixinException, IOException {
|
||||
File file = qrApi.createQRFile(QRParameter.createPermanenceStr("1200中文"));
|
||||
File file = qrApi.createQRFile(
|
||||
QRParameter.createPermanenceStr("1200中文"),
|
||||
"/tmp/weixin4j/qrcode");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,3 +168,7 @@
|
||||
* 2016-01-23
|
||||
|
||||
+ 新增获取客服列表接口
|
||||
|
||||
* 2016-01-26
|
||||
|
||||
+ 新增上传图文消息内的图片接口
|
||||
@ -25,13 +25,13 @@ weixin4j-qy
|
||||
|
||||
* PartyApi `部门管理API`
|
||||
|
||||
* ProviderApi `服务商API`
|
||||
* ProviderApi `服务商API`
|
||||
|
||||
* SuiteApi `第三方应用API`
|
||||
* SuiteApi `第三方应用API`
|
||||
|
||||
* TagApi `标签管理API`
|
||||
* TagApi `标签管理API`
|
||||
|
||||
* UserApi `成员管理API`
|
||||
* UserApi `成员管理API`
|
||||
|
||||
|
||||
如何使用
|
||||
@ -61,25 +61,32 @@ weixin4j.properties说明
|
||||
示例(properties中换行用右斜杆\\)
|
||||
|
||||
weixin4j.account={"id":"corpid","secret":"corpsecret",\
|
||||
"suites":[{"id":"应用套件的id","secret":"应用套件的secret"}],\
|
||||
"providerSecret:"第三方提供商secret(企业号登陆)",\
|
||||
"chatSecret":"消息服务secret(企业号消息服务,暂时没用到)"}
|
||||
"suites":[{"id":"应用套件的id","secret":"应用套件的secret"}],\
|
||||
"providerSecret":"第三方提供商secret(企业号登陆)",\
|
||||
"chatSecret":"消息服务secret(企业号消息服务,暂时没用到)",\
|
||||
"mchId":"微信商户号 微信支付时需要填入",\
|
||||
"certificateKey":"加载支付证书文件的密码 如果不填写则默认获取mchId作为密码",\
|
||||
"paySignKey":"微信支付中调用API的密钥 微信支付时需要填入"}
|
||||
|
||||
# 使用FileTokenStorager时token的存放路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# 二维码保存路径(如果不填则默认为Weixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.qrcode.path=/tmp/weixin4j/qrcode
|
||||
# 媒体文件保存路径(如果不填则默认为Weixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# 对账单保存路径(如果不填则默认为Weixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca证书存放的完整路径 (证书文件后缀为*.p12)
|
||||
# ca证书存放的完整路径
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
#classpath路径下:weixin4j.certificate.file=classpath:xxxxx.p12
|
||||
# classpath路径下可以这么写(如果不填则默认为Weixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
#企业号用户身份授权后重定向的url(使用OauthApi时需要填写)
|
||||
weixin4j.user.oauth.redirect.uri=http://xxx
|
||||
|
||||
#企业号第三方管理员授权后重定向的url(使用OauthApi时需要填写)
|
||||
weixin4j.third.oauth.redirect.uri=http://xxx
|
||||
|
||||
#企业号第三方应用套件授权后重定向的url(使用OauthApi时需要填写)
|
||||
weixin4j.suite.oauth.redirect.uri=http://xxx
|
||||
# 企业号用户身份授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
# 企业号第三方提供商授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.third.oauth.redirect.uri=
|
||||
# 企业号第三方应用套件授权后重定向的url(在使用OauthApi时填写)
|
||||
weixin4j.suite.oauth.redirect.uri=
|
||||
|
||||
2.实例化微信企业号接口代理对象,调用具体的API方法
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.7</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-qy</artifactId>
|
||||
<name>weixin4j-qy</name>
|
||||
|
||||
@ -14,6 +14,7 @@ import com.foxinmy.weixin4j.model.MediaItem;
|
||||
import com.foxinmy.weixin4j.model.MediaRecord;
|
||||
import com.foxinmy.weixin4j.model.MediaUploadResult;
|
||||
import com.foxinmy.weixin4j.model.Pageable;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.api.AgentApi;
|
||||
import com.foxinmy.weixin4j.qy.api.BatchApi;
|
||||
import com.foxinmy.weixin4j.qy.api.ChatApi;
|
||||
@ -22,7 +23,6 @@ import com.foxinmy.weixin4j.qy.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.qy.api.MenuApi;
|
||||
import com.foxinmy.weixin4j.qy.api.NotifyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.PartyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.QyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.TagApi;
|
||||
import com.foxinmy.weixin4j.qy.api.UserApi;
|
||||
import com.foxinmy.weixin4j.qy.message.ChatMessage;
|
||||
@ -47,6 +47,7 @@ import com.foxinmy.weixin4j.qy.type.ChatType;
|
||||
import com.foxinmy.weixin4j.qy.type.InviteType;
|
||||
import com.foxinmy.weixin4j.qy.type.KfType;
|
||||
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
@ -76,50 +77,27 @@ public class WeixinProxy {
|
||||
private final ChatApi chatApi;
|
||||
|
||||
private final TokenHolder tokenHolder;
|
||||
private String corpId;
|
||||
|
||||
private Weixin4jSettings settings;
|
||||
|
||||
/**
|
||||
* 默认使用文件方式保存token、使用weixin4j.properties配置的账号信息
|
||||
*/
|
||||
public WeixinProxy() {
|
||||
this(QyApi.DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的账号信息
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储策略
|
||||
*/
|
||||
public WeixinProxy(TokenStorager tokenStorager) {
|
||||
this(QyApi.DEFAULT_WEIXIN_ACCOUNT.getId(), QyApi.DEFAULT_WEIXIN_ACCOUNT
|
||||
.getSecret(), tokenStorager);
|
||||
}
|
||||
|
||||
/**
|
||||
* corpid,corpsecret
|
||||
*
|
||||
* @param corpid
|
||||
* @param corpsecret
|
||||
*/
|
||||
public WeixinProxy(String corpid, String corpsecret) {
|
||||
this(corpid, corpsecret, QyApi.DEFAULT_TOKEN_STORAGER);
|
||||
this(new Weixin4jSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param corpid
|
||||
* 企业号ID
|
||||
* @param corpsecret
|
||||
* 企业号secret
|
||||
* @param tokenStorager
|
||||
* 企业号token存储器
|
||||
* @param settings
|
||||
* 配置信息
|
||||
* @see com.foxinmy.weixin4j.settings.Weixin4jSettings
|
||||
*/
|
||||
public WeixinProxy(String corpid, String corpsecret,
|
||||
TokenStorager tokenStorager) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(corpid, corpsecret),
|
||||
tokenStorager));
|
||||
this.corpId = corpid;
|
||||
public WeixinProxy(Weixin4jSettings settings) {
|
||||
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount()
|
||||
.getId(), settings.getAccount().getSecret()),
|
||||
settings.getTokenStorager()));
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +111,7 @@ public class WeixinProxy {
|
||||
public WeixinProxy(WeixinTokenSuiteCreator tokenCreator,
|
||||
TokenStorager tokenStorager) {
|
||||
this(new TokenHolder(tokenCreator, tokenStorager));
|
||||
this.corpId = tokenCreator.getAuthCorpId();
|
||||
this.settings = new Weixin4jSettings(tokenCreator.getAuthCorpId(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,12 +145,12 @@ public class WeixinProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业号ID
|
||||
* 获取微信账号信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCorpId() {
|
||||
return this.corpId;
|
||||
public WeixinAccount getWeixinAccount() {
|
||||
return this.settings.getAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,8 +161,9 @@ public class WeixinProxy {
|
||||
* @return
|
||||
*/
|
||||
public TokenHolder getTicketHolder(TicketType ticketType) {
|
||||
return new TokenHolder(new WeixinTicketCreator(this.corpId, ticketType,
|
||||
this.tokenHolder), this.tokenHolder.getTokenStorager());
|
||||
return new TokenHolder(new WeixinTicketCreator(getWeixinAccount()
|
||||
.getId(), ticketType, this.tokenHolder),
|
||||
this.tokenHolder.getTokenStorager());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,6 +291,25 @@ public class WeixinProxy {
|
||||
return menuApi.deleteMenu(agentid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图文消息内的图片:用于上传图片到企业号服务端,接口返回图片url,请注意,该url仅可用于图文消息的发送,
|
||||
* 且每个企业每天最多只能上传100张图片。
|
||||
*
|
||||
* @param is
|
||||
* 图片数据
|
||||
* @param fileName
|
||||
* 文件名
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E5%9B%BE%E6%96%87%E6%B6%88%E6%81%AF%E5%86%85%E7%9A%84%E5%9B%BE%E7%89%87">上传图文消息内的图片</a>
|
||||
* @return 图片url
|
||||
* @see com.foxinmy.weixin4j.qy.api.MediaApi
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String uploadImage(InputStream is, String fileName)
|
||||
throws WeixinException {
|
||||
return mediaApi.uploadImage(is, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传媒体文件
|
||||
* <p>
|
||||
@ -348,7 +346,7 @@ public class WeixinProxy {
|
||||
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.qy.api.MediaApi
|
||||
* @see com.foxinmy.weixin4j.type.MediaType
|
||||
@ -356,7 +354,8 @@ public class WeixinProxy {
|
||||
*/
|
||||
public File downloadMediaFile(int agentid, String mediaId)
|
||||
throws WeixinException {
|
||||
return mediaApi.downloadMediaFile(agentid, mediaId);
|
||||
return mediaApi.downloadMediaFile(agentid, mediaId,
|
||||
settings.getMediaPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1334,5 +1333,5 @@ public class WeixinProxy {
|
||||
return chatApi.sendChatMessage(message);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.6.6";
|
||||
public final static String VERSION = "1.6.7";
|
||||
}
|
||||
|
||||
@ -3,19 +3,22 @@ package com.foxinmy.weixin4j.qy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.api.ProviderApi;
|
||||
import com.foxinmy.weixin4j.qy.api.QyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.SuiteApi;
|
||||
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator;
|
||||
import com.foxinmy.weixin4j.qy.type.LoginTargetType;
|
||||
import com.foxinmy.weixin4j.settings.Weixin4jSettings;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信第三方应用接口实现
|
||||
@ -34,20 +37,16 @@ public class WeixinSuiteProxy {
|
||||
private ProviderApi providerApi;
|
||||
|
||||
public WeixinSuiteProxy() {
|
||||
this(QyApi.DEFAULT_TOKEN_STORAGER);
|
||||
this(Weixin4jSettings.DEFAULT_TOKEN_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param suiteId
|
||||
* 应用ID
|
||||
* @param suiteSecret
|
||||
* 应用secret
|
||||
* @throws WeixinException
|
||||
* @param tokenPath
|
||||
* 使用文件存储token的保存路径
|
||||
*/
|
||||
public WeixinSuiteProxy(String suiteId, String suiteSecret) {
|
||||
this(QyApi.DEFAULT_TOKEN_STORAGER, null, null, new WeixinAccount(
|
||||
suiteId, suiteSecret));
|
||||
public WeixinSuiteProxy(String tokenPath) {
|
||||
this(new FileTokenStorager(tokenPath));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +55,8 @@ public class WeixinSuiteProxy {
|
||||
* token存储
|
||||
*/
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager) {
|
||||
this(tokenStorager, QyApi.DEFAULT_WEIXIN_ACCOUNT);
|
||||
this(tokenStorager, JSON.parseObject(
|
||||
Weixin4jConfigUtil.getValue("account"), WeixinQyAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,14 +76,14 @@ public class WeixinSuiteProxy {
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储
|
||||
* @param corpId
|
||||
* @param providerCorpId
|
||||
* 服务商的企业号ID <font color="red">使用服务商API时必填项</font>
|
||||
* @param providerSecret
|
||||
* 服务商secret <font color="red">使用服务商API时必填项</font>
|
||||
* @param suites
|
||||
* 套件信息 <font color="red">使用套件API时必填项</font>
|
||||
*/
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager, String corpId,
|
||||
public WeixinSuiteProxy(TokenStorager tokenStorager, String providerCorpId,
|
||||
String providerSecret, WeixinAccount... suites) {
|
||||
if (suites != null) {
|
||||
this.suiteMap = new HashMap<String, SuiteApi>();
|
||||
@ -94,11 +94,11 @@ public class WeixinSuiteProxy {
|
||||
this.suiteMap.put(null, suiteMap.get(suites[0].getId()));
|
||||
}
|
||||
}
|
||||
if (StringUtil.isNotBlank(corpId)
|
||||
if (StringUtil.isNotBlank(providerCorpId)
|
||||
&& StringUtil.isNotBlank(providerSecret)) {
|
||||
this.providerApi = new ProviderApi(new TokenHolder(
|
||||
new WeixinProviderTokenCreator(corpId, providerSecret),
|
||||
tokenStorager));
|
||||
new WeixinProviderTokenCreator(providerCorpId,
|
||||
providerSecret), tokenStorager));
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,5 +160,5 @@ public class WeixinSuiteProxy {
|
||||
return providerApi.getLoginUrl(corpId, targetType, agentId);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.6.6";
|
||||
public final static String VERSION = "1.6.7";
|
||||
}
|
||||
|
||||
@ -51,8 +51,6 @@ import com.foxinmy.weixin4j.util.IOUtil;
|
||||
import com.foxinmy.weixin4j.util.ObjectId;
|
||||
import com.foxinmy.weixin4j.util.RegexUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
import com.foxinmy.weixin4j.util.WeixinErrorUtil;
|
||||
|
||||
/**
|
||||
@ -199,17 +197,17 @@ public class MediaApi extends QyApi {
|
||||
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
|
||||
* @param mediaId
|
||||
* 存储在微信服务器上的媒体标识
|
||||
* @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
|
||||
* @param mediaPath
|
||||
* 媒体素材保存路径
|
||||
* @return 写入硬盘后的文件对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.type.MediaType
|
||||
* @see {@link #downloadMedia(int,String)}
|
||||
*/
|
||||
public File downloadMediaFile(int agentid, String mediaId)
|
||||
public File downloadMediaFile(int agentid, String mediaId, String mediaPath)
|
||||
throws WeixinException {
|
||||
String media_path = Weixin4jConfigUtil.getValue("media.path",
|
||||
Weixin4jConst.DEFAULT_MEDIA_PATH);
|
||||
final String prefixName = String.format("%d_%s.", agentid, mediaId);
|
||||
File[] files = new File(media_path).listFiles(new FilenameFilter() {
|
||||
File[] files = new File(mediaPath).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.startsWith(prefixName);
|
||||
@ -219,7 +217,7 @@ public class MediaApi extends QyApi {
|
||||
return files[0];
|
||||
}
|
||||
MediaDownloadResult result = downloadMedia(agentid, mediaId);
|
||||
File file = new File(media_path + File.separator + result.getFileName());
|
||||
File file = new File(mediaPath + File.separator + result.getFileName());
|
||||
OutputStream os = null;
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
|
||||
@ -4,6 +4,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
@ -21,6 +22,15 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83">企业号第三方套件应用授权说明</a>
|
||||
*/
|
||||
public class OauthApi extends QyApi {
|
||||
private final WeixinAccount account;
|
||||
|
||||
public OauthApi() {
|
||||
this(Weixin4jConfigUtil.getWeixinAccount());
|
||||
}
|
||||
|
||||
public OauthApi(WeixinAccount account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业号用户身份授权
|
||||
@ -30,7 +40,7 @@ public class OauthApi extends QyApi {
|
||||
* @return 请求授权的URL
|
||||
*/
|
||||
public String getUserAuthorizeURL() {
|
||||
String corpId = DEFAULT_WEIXIN_ACCOUNT.getId();
|
||||
String corpId = account.getId();
|
||||
String redirectUri = Weixin4jConfigUtil
|
||||
.getValue("user.oauth.redirect.uri");
|
||||
return getUserAuthorizeURL(corpId, redirectUri, "state");
|
||||
@ -69,7 +79,7 @@ public class OauthApi extends QyApi {
|
||||
* @return 请求授权的URL
|
||||
*/
|
||||
public String getThirdAuthorizeURL() {
|
||||
String corpId = DEFAULT_WEIXIN_ACCOUNT.getId();
|
||||
String corpId = account.getId();
|
||||
String redirectUri = Weixin4jConfigUtil
|
||||
.getValue("third.oauth.redirect.uri");
|
||||
return getThirdAuthorizeURL(corpId, redirectUri, "state");
|
||||
|
||||
@ -2,10 +2,7 @@ package com.foxinmy.weixin4j.qy.api;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.api.BaseApi;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号API
|
||||
@ -20,16 +17,9 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
||||
public class QyApi extends BaseApi {
|
||||
|
||||
private final static ResourceBundle WEIXIN_BUNDLE;
|
||||
/**
|
||||
* 默认使用weixin4j.properties文件中的企业号信息
|
||||
*/
|
||||
public final static WeixinQyAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
|
||||
static {
|
||||
WEIXIN_BUNDLE = ResourceBundle
|
||||
.getBundle("com/foxinmy/weixin4j/qy/api/weixin");
|
||||
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
||||
Weixin4jConfigUtil.getValue("account"), WeixinQyAccount.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -47,9 +47,6 @@ public class SuiteApi extends QyApi {
|
||||
*
|
||||
* @param suiteTicketHolder
|
||||
* 套件ticket存取
|
||||
* @param tokenStorager
|
||||
* 应用token存储器
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public SuiteApi(SuiteTicketHolder suiteTicketHolder) {
|
||||
this.suiteTicketHolder = suiteTicketHolder;
|
||||
|
||||
@ -1,26 +1,29 @@
|
||||
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
|
||||
# \u4f01\u4e1a\u53f7\u4fe1\u606f
|
||||
weixin4j.account={"id":"id","secret":"secret",\
|
||||
weixin4j.account={"id":"wx5132afc5da26d661","secret":"GsnKLVDI1pWArdB60Ze4iP2cwFvcW5KCAs2vLJldipilmSYxtbkcAiBcGSHHvu_I",\
|
||||
"suites":[{"id":"\u5e94\u7528\u5957\u4ef6\u7684id","secret":"\u5e94\u7528\u5957\u4ef6\u7684secret"}],\
|
||||
"providerSecret":"\u7b2c\u4e09\u65b9\u63d0\u4f9b\u5546secret(\u4f01\u4e1a\u53f7\u767b\u9646)",\
|
||||
"chatSecret":"\u6d88\u606f\u670d\u52a1secret(\u4f01\u4e1a\u53f7\u6d88\u606f\u670d\u52a1,\u6682\u65f6\u6ca1\u7528\u5230)"}
|
||||
"chatSecret":"\u6d88\u606f\u670d\u52a1secret(\u4f01\u4e1a\u53f7\u6d88\u606f\u670d\u52a1,\u6682\u65f6\u6ca1\u7528\u5230)",\
|
||||
"mchId":"\u5fae\u4fe1\u5546\u6237\u53f7 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
|
||||
"certificateKey":"\u52a0\u8f7d\u652f\u4ed8\u8bc1\u4e66\u6587\u4ef6\u7684\u5bc6\u7801 \u5982\u679c\u4e0d\u586b\u5199\u5219\u9ed8\u8ba4\u83b7\u53d6mchId\u4f5c\u4e3a\u5bc6\u7801",\
|
||||
"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
|
||||
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_TOKEN_PATH)
|
||||
weixin4j.token.path=/tmp/weixin4j/token
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_MEDIA_PATH)
|
||||
weixin4j.media.path=/tmp/weixin4j/media
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84
|
||||
# \u5bf9\u8d26\u5355\u4fdd\u5b58\u8def\u5f84(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_BILL_PATH)
|
||||
weixin4j.bill.path=/tmp/weixin4j/bill
|
||||
# ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84 (V2\u7248\u672c\u540e\u7f00\u4e3a*.pfx,V3\u7248\u672c\u540e\u7f00\u4e3a*.p12)
|
||||
weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199
|
||||
# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199(\u5982\u679c\u4e0d\u586b\u5219\u9ed8\u8ba4\u4e3aWeixin4jConst#DEFAULT_CAFILE_PATH)
|
||||
# weixin4j.certificate.file=classpath:xxxxx.pfx
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u7528\u6237\u8eab\u4efd\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
# \u4f01\u4e1a\u53f7\u7528\u6237\u8eab\u4efd\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.user.oauth.redirect.uri=
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u7b2c\u4e09\u65b9\u63d0\u4f9b\u5546\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
# \u4f01\u4e1a\u53f7\u7b2c\u4e09\u65b9\u63d0\u4f9b\u5546\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.third.oauth.redirect.uri=
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u7b2c\u4e09\u65b9\u5e94\u7528\u5957\u4ef6\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
# \u4f01\u4e1a\u53f7\u7b2c\u4e09\u65b9\u5e94\u7528\u5957\u4ef6\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
|
||||
weixin4j.suite.oauth.redirect.uri=
|
||||
@ -47,7 +47,8 @@ public class MediaTest extends TokenTest {
|
||||
File file = mediaApi
|
||||
.downloadMediaFile(
|
||||
0,
|
||||
"1y0NWE5ochkfOoiyJsPwQ3Wg7gsyRHNp8SveqhGXY_1rOH7OcOMwfHDg8KH6s88osq59AfS3BX-MBBKvERB7Bvw");
|
||||
"1y0NWE5ochkfOoiyJsPwQ3Wg7gsyRHNp8SveqhGXY_1rOH7OcOMwfHDg8KH6s88osq59AfS3BX-MBBKvERB7Bvw",
|
||||
"/tmp/weixin4j/media");
|
||||
Assert.assertTrue(file.exists());
|
||||
}
|
||||
|
||||
|
||||
@ -28,8 +28,8 @@ public class TokenTest {
|
||||
WeixinAccount weixinAccount = Weixin4jConfigUtil.getWeixinAccount();
|
||||
tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
weixinAccount.getId(), weixinAccount.getSecret()),
|
||||
new FileTokenStorager(Weixin4jConfigUtil.getValue(
|
||||
"token.path", "/tmp/weixin4j/token")));
|
||||
new FileTokenStorager(Weixin4jConfigUtil.getValue("token.path",
|
||||
"/tmp/weixin4j/token")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -5,10 +5,10 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.7</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-server</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<version>1.1.6</version>
|
||||
<name>weixin4j-server</name>
|
||||
<url>https://github.com/foxinmy/weixin4j/tree/master/weixin4j-server</url>
|
||||
<description>微信消息netty服务器</description>
|
||||
|
||||
@ -315,5 +315,5 @@ public final class WeixinServerBootstrap {
|
||||
return this;
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.1.5";
|
||||
public final static String VERSION = "1.1.6";
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user