优化接口,优化支付等。
This commit is contained in:
parent
a874973428
commit
ddd1310ac9
44
pom.xml
44
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.7.3</version>
|
||||
<version>1.7.3-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>weixin4j</name>
|
||||
<url>https://github.com/foxinmy/weixin4j</url>
|
||||
@ -44,7 +44,6 @@
|
||||
<module>weixin4j-mp</module>
|
||||
<module>weixin4j-qy</module>
|
||||
<module>weixin4j-server</module>
|
||||
<module>weixin4j-example</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@ -54,6 +53,18 @@
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@ -211,8 +222,8 @@
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.properties</include>
|
||||
<include>*.xml</include>
|
||||
<include>*.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
@ -248,14 +259,27 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>oss-snapshot</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>oss-release</id>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
<id>Project Releases</id>
|
||||
<name>Project Releases</name>
|
||||
<url>http://repo.wyying.com/nexus/content/repositories/releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>Project Snapshots</id>
|
||||
<name>Project Snapshots</name>
|
||||
<url>http://repo.wyying.com/nexus/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<!--<distributionManagement>-->
|
||||
<!--<snapshotRepository>-->
|
||||
<!--<id>oss-snapshot</id>-->
|
||||
<!--<url>https://oss.sonatype.org/content/repositories/snapshots/</url>-->
|
||||
<!--</snapshotRepository>-->
|
||||
<!--<repository>-->
|
||||
<!--<id>oss-release</id>-->
|
||||
<!--<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>-->
|
||||
<!--</repository>-->
|
||||
<!--</distributionManagement>-->
|
||||
</project>
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.7.3</version>
|
||||
<version>1.7.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-base</artifactId>
|
||||
<name>weixin4j-base</name>
|
||||
|
||||
@ -36,7 +36,7 @@ public class MchApi extends BaseApi {
|
||||
}
|
||||
|
||||
protected final WeixinPayAccount weixinAccount;
|
||||
protected final WeixinSignature weixinSignature;
|
||||
protected final WeixinPaymentSignature weixinSignature;
|
||||
private volatile WeixinRequestExecutor weixinSSLExecutor;
|
||||
|
||||
public MchApi(WeixinPayAccount weixinAccount) {
|
||||
|
||||
@ -16,6 +16,7 @@ import java.util.Map;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.exception.WeixinPayException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
@ -83,8 +84,14 @@ public class PayApi extends MchApi {
|
||||
String payJsRequestXml = XmlStream.toXML(payPackage);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
getRequestUri("order_create_uri"), payJsRequestXml);
|
||||
return response.getAsObject(new TypeReference<PrePay>() {
|
||||
boolean validatePaySign = weixinSignature.validatePaySign(response);
|
||||
if(validatePaySign) {
|
||||
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
|
||||
});
|
||||
prePay.setResponse(response.getAsString());
|
||||
return prePay;
|
||||
}
|
||||
throw new WeixinPayException("验证签名信息失败,返回数据可能被篡改");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,19 +129,20 @@ public class PayApi extends MchApi {
|
||||
MICROPayRequest microPayRequest = response
|
||||
.getAsObject(new TypeReference<MICROPayRequest>() {
|
||||
});
|
||||
microPayRequest.setResponse(response.getAsString());
|
||||
microPayRequest.setPaymentAccount(weixinAccount);
|
||||
return microPayRequest;
|
||||
}
|
||||
PrePay prePay = createPrePay(payPackage);
|
||||
if (TradeType.APP.name().equals(tradeType)) {
|
||||
return new APPPayRequest(prePay.getPrepayId(), weixinAccount);
|
||||
return new APPPayRequest(prePay, weixinAccount);
|
||||
} else if (TradeType.JSAPI.name().equals(tradeType)) {
|
||||
return new JSAPIPayRequest(prePay.getPrepayId(), weixinAccount);
|
||||
return new JSAPIPayRequest(prePay, weixinAccount);
|
||||
} else if (TradeType.NATIVE.name().equals(tradeType)) {
|
||||
return new NATIVEPayRequest(prePay.getPrepayId(),
|
||||
return new NATIVEPayRequest(prePay,
|
||||
prePay.getCodeUrl(), weixinAccount);
|
||||
} else if (TradeType.WAP.name().equals(tradeType)) {
|
||||
return new WAPPayRequest(prePay.getPrepayId(), weixinAccount);
|
||||
return new WAPPayRequest(prePay, weixinAccount);
|
||||
} else {
|
||||
throw new WeixinException("unknown tradeType:" + tradeType);
|
||||
}
|
||||
@ -170,6 +178,36 @@ public class PayApi extends MchApi {
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建JSAPI支付请求对象
|
||||
*
|
||||
* @param openId
|
||||
* 用户ID
|
||||
* @param body
|
||||
* 订单描述
|
||||
* @param outTradeNo
|
||||
* 订单号
|
||||
* @param totalFee
|
||||
* 订单总额(元)
|
||||
* @param notifyUrl
|
||||
* 支付通知地址
|
||||
* @param createIp
|
||||
* ip地址
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @see com.foxinmy.weixin4j.payment.mch.JSAPIPayRequest
|
||||
* @return JSAPI支付对象
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createJSPayRequest(String openId, String body,
|
||||
String outTradeNo, long totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.JSAPI, openId, null,
|
||||
null, attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 生成编辑地址请求
|
||||
@ -271,6 +309,43 @@ public class PayApi extends MchApi {
|
||||
return new NativePayResponse(weixinAccount, prePay.getPrepayId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)回调对象【模式一】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native回调对象
|
||||
* @see com.foxinmy.weixin4j.payment.mch.NativePayResponse
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public NativePayResponse createNativePayResponse(String productId,
|
||||
String body, String outTradeNo, long totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
|
||||
productId, attach);
|
||||
PrePay prePay = createPrePay(payPackage);
|
||||
return new NativePayResponse(weixinAccount, prePay.getPrepayId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式二】
|
||||
*
|
||||
@ -307,6 +382,42 @@ public class PayApi extends MchApi {
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Native支付(扫码支付)链接【模式二】
|
||||
*
|
||||
* @param productId
|
||||
* 商品ID
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return Native支付对象
|
||||
* @see com.foxinmy.weixin4j.payment.mch.NATIVEPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1">扫码支付
|
||||
* </a>
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5">模式二
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createNativePayRequest(String productId, String body,
|
||||
String outTradeNo, long totalFee, String notifyUrl,
|
||||
String createIp, String attach) throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.NATIVE, null, null,
|
||||
productId, attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建APP支付请求对象
|
||||
*
|
||||
@ -338,6 +449,37 @@ public class PayApi extends MchApi {
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建APP支付请求对象
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return APP支付对象
|
||||
* @see com.foxinmy.weixin4j.payment.mch.APPPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">
|
||||
* APP支付</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
|
||||
long totalFee, String notifyUrl, String createIp, String attach)
|
||||
throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.APP, null, null, null,
|
||||
attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建WAP支付请求对象
|
||||
*
|
||||
@ -369,6 +511,37 @@ public class PayApi extends MchApi {
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建WAP支付请求对象
|
||||
*
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param notifyUrl
|
||||
* 支付回调URL
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return WAP支付对象
|
||||
* @see com.foxinmy.weixin4j.payment.mch.WAPPayRequest
|
||||
* @see <a href=
|
||||
* "https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付
|
||||
* </a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createWapPayRequest(String body, String outTradeNo,
|
||||
long totalFee, String notifyUrl, String createIp, String attach)
|
||||
throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp, TradeType.WAP, null, null, null,
|
||||
attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付
|
||||
*
|
||||
@ -401,6 +574,38 @@ public class PayApi extends MchApi {
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交被扫支付
|
||||
*
|
||||
* @param authCode
|
||||
* 扫码支付授权码 ,设备读取用户微信中的条码或者二维码信息
|
||||
* @param body
|
||||
* 商品描述
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号
|
||||
* @param totalFee
|
||||
* 商品总额 单位元
|
||||
* @param createIp
|
||||
* 订单生成的机器 IP
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @return 支付的订单信息
|
||||
* @see com.foxinmy.weixin4j.payment.mch.MICROPayRequest
|
||||
* @see com.foxinmy.weixin4j.payment.mch.Order
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10">
|
||||
* 提交被扫支付API</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public MchPayRequest createMicroPayRequest(String authCode, String body,
|
||||
String outTradeNo, long totalFee, String createIp, String attach)
|
||||
throws WeixinException {
|
||||
MchPayPackage payPackage = new MchPayPackage(body, outTradeNo,
|
||||
totalFee, null, createIp, TradeType.MICROPAY, null, authCode,
|
||||
null, attach);
|
||||
return createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单查询
|
||||
* <p>
|
||||
@ -468,13 +673,51 @@ public class PayApi extends MchApi {
|
||||
double totalFee, double refundFee, CurrencyType refundFeeType,
|
||||
String opUserId, RefundAccountType refundAccountType)
|
||||
throws WeixinException {
|
||||
return applyRefund(idQuery, outRefundNo, DateUtil.formatYuan2Fen(totalFee), DateUtil.formatYuan2Fen(refundFee), refundFeeType, opUserId,
|
||||
refundAccountType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款(请求需要双向证书)
|
||||
* <p>
|
||||
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,
|
||||
* 按照退款规则将支付款按原路退到买家帐号上。
|
||||
* </p>
|
||||
* <p style="color:red">
|
||||
* 1.交易时间超过半年的订单无法提交退款;
|
||||
* 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交
|
||||
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
|
||||
* </p>
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @param refundFee
|
||||
* 退款总金额,单位为元,可以做部分退款
|
||||
* @param refundFeeType
|
||||
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY
|
||||
* @param opUserId
|
||||
* 操作员帐号, 默认为商户号
|
||||
* @param refundAccountType
|
||||
* @return 退款申请结果
|
||||
* @see com.foxinmy.weixin4j.payment.mch.RefundResult
|
||||
* @see <a href=
|
||||
* "http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4">
|
||||
* 申请退款API</a>
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo, long totalFee, long refundFee, CurrencyType refundFeeType,
|
||||
String opUserId, RefundAccountType refundAccountType) throws WeixinException {
|
||||
WeixinResponse response = null;
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("out_refund_no", outRefundNo);
|
||||
map.put("total_fee",
|
||||
Integer.toString(DateUtil.formatYuan2Fen(totalFee)));
|
||||
map.put("refund_fee",
|
||||
Integer.toString(DateUtil.formatYuan2Fen(refundFee)));
|
||||
map.put("total_fee", String.valueOf(totalFee));
|
||||
map.put("refund_fee", String.valueOf(refundFee));
|
||||
if (StringUtil.isBlank(opUserId)) {
|
||||
opUserId = weixinAccount.getMchId();
|
||||
}
|
||||
@ -505,7 +748,7 @@ public class PayApi extends MchApi {
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType, String)}
|
||||
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType, String,RefundAccountType)}
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee) throws WeixinException {
|
||||
@ -513,6 +756,23 @@ public class PayApi extends MchApi {
|
||||
null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请(全额退款)
|
||||
*
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
* transaction_id> out_trade_no
|
||||
* @param outRefundNo
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType, String,RefundAccountType)}
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
long totalFee) throws WeixinException {
|
||||
return applyRefund(idQuery, outRefundNo, totalFee, totalFee, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 冲正订单(需要证书)</br> 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口</br> 接口逻辑:支
|
||||
* 付失败的关单,支付成功的撤销支付</br> <font color="red">7天以内的单可撤销,其他正常支付的单
|
||||
@ -749,4 +1009,6 @@ public class PayApi extends MchApi {
|
||||
return response.getAsObject(new TypeReference<OpenIdResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.foxinmy.weixin4j.http.ContentType;
|
||||
import com.foxinmy.weixin4j.util.Consts;
|
||||
|
||||
public class StringEntity implements HttpEntity {
|
||||
|
||||
private final byte[] content;
|
||||
private final ContentType contentType;
|
||||
|
||||
@ -40,4 +42,10 @@ public class StringEntity implements HttpEntity {
|
||||
outstream.write(this.content);
|
||||
outstream.flush();
|
||||
}
|
||||
|
||||
|
||||
public String getContentString() {
|
||||
return new String(this.content, Consts.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -55,6 +55,10 @@ public class Pagedata<T> implements Serializable, Iterable<T> {
|
||||
return pageable == null ? null : pageable.getSort();
|
||||
}
|
||||
|
||||
public List<T> getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return hasContent() ? content.iterator() : null;
|
||||
|
||||
@ -127,6 +127,47 @@ public class PayPackage extends MerchantResult {
|
||||
this.goodsTag = goodsTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单对象
|
||||
*
|
||||
* @param body
|
||||
* 订单描述 必填
|
||||
* @param detail
|
||||
* 订单详情 非必填
|
||||
* @param outTradeNo
|
||||
* 商户内部ID 必填
|
||||
* @param totalFee
|
||||
* 订单总额 必填 <font color="red">单位为分</font>
|
||||
* @param notifyUrl
|
||||
* 回调地址 必填
|
||||
* @param createIp
|
||||
* 生成订单数据的机器IP 必填
|
||||
* @param attach
|
||||
* 附加数据 非必填
|
||||
* @param timeStart
|
||||
* 订单生成时间 非必填
|
||||
* @param timeExpire
|
||||
* 订单失效时间 非必填
|
||||
* @param goodsTag
|
||||
* 订单标记 非必填
|
||||
*/
|
||||
public PayPackage(String body, String detail, String outTradeNo,
|
||||
long totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, String goodsTag) {
|
||||
this.body = body;
|
||||
this.detail = detail;
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.totalFee = Long.valueOf(totalFee).intValue();
|
||||
this.notifyUrl = notifyUrl;
|
||||
this.createIp = createIp;
|
||||
this.attach = attach;
|
||||
this.timeStart = timeStart != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeStart) : null;
|
||||
this.timeExpire = timeExpire != null ? DateUtil
|
||||
.fortmat2yyyyMMddHHmmss(timeExpire) : null;
|
||||
this.goodsTag = goodsTag;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ public class PayRequest extends PayBaseInfo {
|
||||
@JSONField(serialize = false)
|
||||
private String partnerId;
|
||||
|
||||
|
||||
protected PayRequest() {
|
||||
// jaxb required
|
||||
}
|
||||
@ -69,6 +70,7 @@ public class PayRequest extends PayBaseInfo {
|
||||
this.partnerId = partnerId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "package" + packageInfo + ", prepayId=" + prepayId
|
||||
|
||||
@ -468,7 +468,7 @@ public class WeixinPayProxy {
|
||||
*
|
||||
* @throws IOException
|
||||
*
|
||||
* @see {@link #applyRefund(IdQuery, String, double, double, String,CurrencyType)}
|
||||
* @see {@link #applyRefund(IdQuery, String, double, double,CurrencyType,String,RefundAccountType)}
|
||||
*/
|
||||
public RefundResult applyRefund(IdQuery idQuery, String outRefundNo,
|
||||
double totalFee) throws WeixinException {
|
||||
|
||||
@ -20,8 +20,8 @@ import com.foxinmy.weixin4j.util.MapUtil;
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1">APP支付</a>
|
||||
*/
|
||||
public class APPPayRequest extends AbstractPayRequest {
|
||||
public APPPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
super(prePayId, payAccount);
|
||||
public APPPayRequest(PrePay prePay, WeixinPayAccount payAccount) {
|
||||
super(prePay.getPrepayId(),prePay.getResponse(), payAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -10,10 +10,14 @@ public abstract class AbstractPayRequest implements MchPayRequest {
|
||||
private final WeixinPayAccount paymentAccount;
|
||||
protected final WeixinSignature weixinSignature;
|
||||
|
||||
public AbstractPayRequest(String prePayId, WeixinPayAccount paymentAccount) {
|
||||
protected final String payResponse;
|
||||
|
||||
public AbstractPayRequest(String prePayId, String payResponse, WeixinPayAccount paymentAccount) {
|
||||
this.prePayId = prePayId;
|
||||
this.payResponse = payResponse;
|
||||
this.paymentAccount = paymentAccount;
|
||||
this.weixinSignature = new WeixinPaymentSignature(paymentAccount.getPaySignKey());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -25,4 +29,10 @@ public abstract class AbstractPayRequest implements MchPayRequest {
|
||||
public WeixinPayAccount getPaymentAccount() {
|
||||
return this.paymentAccount;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getResponseString() {
|
||||
return payResponse;
|
||||
}
|
||||
}
|
||||
@ -25,8 +25,8 @@ import com.foxinmy.weixin4j.type.TradeType;
|
||||
*/
|
||||
public class JSAPIPayRequest extends AbstractPayRequest {
|
||||
|
||||
public JSAPIPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
super(prePayId, payAccount);
|
||||
public JSAPIPayRequest(PrePay prePay, WeixinPayAccount payAccount) {
|
||||
super(prePay.getPrepayId(), prePay.getResponse(), payAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -27,6 +27,8 @@ public class MICROPayRequest extends Order implements MchPayRequest {
|
||||
@JSONField(serialize = false)
|
||||
private WeixinPayAccount paymentAccount;
|
||||
|
||||
private String response;
|
||||
|
||||
protected MICROPayRequest() {
|
||||
// jaxb required
|
||||
}
|
||||
@ -55,6 +57,16 @@ public class MICROPayRequest extends Order implements MchPayRequest {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void setResponse(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseString() {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">返回null,请不要尝试作为支付请求</font>
|
||||
*/
|
||||
|
||||
@ -108,6 +108,38 @@ public class MchPayPackage extends PayPackage {
|
||||
null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付
|
||||
*
|
||||
* @param body
|
||||
* 支付详情 必填
|
||||
* @param outTradeNo
|
||||
* 商户侧订单号 必填
|
||||
* @param totalFee
|
||||
* 支付金额(单位元) 必填
|
||||
* @param notifyUrl
|
||||
* 支付回调URL 必填
|
||||
* @param createIp
|
||||
* 发起支付的IP地址 必填
|
||||
* @param tradeType
|
||||
* 支付类型 必填
|
||||
* @param openId
|
||||
* 用户唯一标识 公众号JSAPI支付必填
|
||||
* @param authCode
|
||||
* 支付授权码 刷卡MICROPAY支付必填
|
||||
* @param productId
|
||||
* 商品ID 扫码NATIVE支付必填
|
||||
* @param attach
|
||||
* 支付时附加信息 非必填
|
||||
*/
|
||||
public MchPayPackage(String body, String outTradeNo, long totalFee,
|
||||
String notifyUrl, String createIp, TradeType tradeType,
|
||||
String openId, String authCode, String productId, String attach) {
|
||||
this(body, null, outTradeNo, totalFee, notifyUrl, createIp, tradeType,
|
||||
openId, authCode, productId, attach, null, null, null, null,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整参数
|
||||
*
|
||||
@ -147,12 +179,12 @@ public class MchPayPackage extends PayPackage {
|
||||
* 用户在子商户appid下的唯一标识 非必填
|
||||
* openid和sub_openid可以选传其中之一,如果选择传sub_openid ,则必须传sub_appid
|
||||
*/
|
||||
public MchPayPackage(String body, String detial, String outTradeNo,
|
||||
public MchPayPackage(String body, String detail, String outTradeNo,
|
||||
double totalFee, CurrencyType feeType, String notifyUrl,
|
||||
String createIp, TradeType tradeType, String openId,
|
||||
String authCode, String productId, String attach, Date timeStart,
|
||||
Date timeExpire, String goodsTag, String limitPay, String subOpenId) {
|
||||
super(body, detial, outTradeNo, totalFee, notifyUrl, createIp, attach,
|
||||
super(body, detail, outTradeNo, totalFee, notifyUrl, createIp, attach,
|
||||
timeStart, timeExpire, goodsTag);
|
||||
this.tradeType = tradeType != null ? tradeType.name() : null;
|
||||
this.feeType = feeType == null ? CurrencyType.CNY.name() : feeType
|
||||
@ -164,6 +196,58 @@ public class MchPayPackage extends PayPackage {
|
||||
this.subOpenId = subOpenId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整参数
|
||||
*
|
||||
* @param body
|
||||
* 商品描述 <font color="red">必填项</font>
|
||||
* @param detail
|
||||
* 商品名称明细列表 非必填项
|
||||
* @param outTradeNo
|
||||
* 商户内部唯一订单号 <font color="red">必填项</font>
|
||||
* @param totalFee
|
||||
* 商品总额 单位元 <font color="red">必填项</font>
|
||||
* @param notifyUrl
|
||||
* 支付回调URL <font color="red">必填项</font>
|
||||
* @param createIp
|
||||
* 订单生成的机器IP <font color="red">必填项</font>
|
||||
* @param tradeType
|
||||
* 交易类型 <font color="red">必填项</font>
|
||||
* @param openId
|
||||
* 用户ID <font color="red">tradeType=JSAPI时必填</font>
|
||||
* @param authCode
|
||||
* 刷卡支付授权码 <font color="red">tradeType=MICROPAY时必填</font>
|
||||
* @param productId
|
||||
* 产品ID <font color="red">tradeType=NATIVE时必填</font>
|
||||
* @param attach
|
||||
* 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 非必填项
|
||||
* @param timeStart
|
||||
* 订单生成时间,格式为yyyyMMddHHmmss 非必填项
|
||||
* @param timeExpire
|
||||
* 订单失效时间,格式为yyyyMMddHHmmss;注意:最短失效时间间隔必须大于5分钟 非必填项
|
||||
* @param goodsTag
|
||||
* 商品标记,代金券或立减优惠功能的参数 非必填项
|
||||
* @param limitPay
|
||||
* 指定支付方式:no_credit--指定不能使用信用卡支付 非必填项
|
||||
* @param subOpenId
|
||||
* 用户在子商户appid下的唯一标识 非必填
|
||||
* openid和sub_openid可以选传其中之一,如果选择传sub_openid ,则必须传sub_appid
|
||||
*/
|
||||
public MchPayPackage(String body, String detail, String outTradeNo,
|
||||
long totalFee, String notifyUrl, String createIp,
|
||||
TradeType tradeType, String openId, String authCode,
|
||||
String productId, String attach, Date timeStart, Date timeExpire,
|
||||
String goodsTag, String limitPay, String subOpenId) {
|
||||
super(body, detail, outTradeNo, totalFee, notifyUrl, createIp, attach,
|
||||
timeStart, timeExpire, goodsTag);
|
||||
this.tradeType = tradeType.name();
|
||||
this.openId = openId;
|
||||
this.authCode = authCode;
|
||||
this.productId = productId;
|
||||
this.limitPay = limitPay;
|
||||
this.subOpenId = subOpenId;
|
||||
}
|
||||
|
||||
public String getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
@ -52,4 +52,10 @@ public interface MchPayRequest {
|
||||
* @return
|
||||
*/
|
||||
public PayRequest toRequestObject();
|
||||
|
||||
/**
|
||||
* 支付请求返回的结果
|
||||
* @return
|
||||
*/
|
||||
public String getResponseString();
|
||||
}
|
||||
|
||||
@ -20,9 +20,9 @@ public class NATIVEPayRequest extends AbstractPayRequest {
|
||||
|
||||
private final String codeUrl;
|
||||
|
||||
public NATIVEPayRequest(String prePayId, String codeUrl,
|
||||
public NATIVEPayRequest(PrePay prePay, String codeUrl,
|
||||
WeixinPayAccount payAccount) {
|
||||
super(prePayId, payAccount);
|
||||
super(prePay.getPrepayId(), prePay.getResponse(), payAccount);
|
||||
this.codeUrl = codeUrl;
|
||||
}
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ public class Order extends MerchantTradeResult {
|
||||
/**
|
||||
* 现金支付货币类型,符合 ISO 4217 标准的三位字母代码,默认人民币:CNY
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.mp.type.CurrencyType
|
||||
* @see com.foxinmy.weixin4j.type.CurrencyType
|
||||
*/
|
||||
@XmlElement(name = "cash_fee_type")
|
||||
@JSONField(name = "cash_fee_type")
|
||||
|
||||
@ -40,6 +40,8 @@ public class PrePay extends MerchantResult {
|
||||
@XmlElement(name = "code_url")
|
||||
private String codeUrl;
|
||||
|
||||
private String response;
|
||||
|
||||
protected PrePay() {
|
||||
// jaxb required
|
||||
}
|
||||
@ -72,6 +74,14 @@ public class PrePay extends MerchantResult {
|
||||
this.codeUrl = codeUrl;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrePay [tradeType=" + tradeType + ", prepayId=" + prepayId
|
||||
|
||||
@ -138,6 +138,43 @@ public class Redpacket extends MerchantResult {
|
||||
this.amtType = totalNum > 1 ? "ALL_RAND" : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 红包
|
||||
*
|
||||
* @param outTradeNo
|
||||
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填
|
||||
* @param sendName
|
||||
* 红包发送者名称 必填
|
||||
* @param openId
|
||||
* 接受收红包的用户的openid 必填
|
||||
* @param totalAmount
|
||||
* 付款金额 <font color="red">单位为分,自动格式化为分</font> 必填
|
||||
* @param totalNum
|
||||
* 红包发放总人数 大于1视为裂变红包 必填
|
||||
* @param wishing
|
||||
* 红包祝福语 必填
|
||||
* @param clientIp
|
||||
* Ip地址 必填
|
||||
* @param actName
|
||||
* 活动名称 必填
|
||||
* @param remark
|
||||
* 备注 必填
|
||||
*/
|
||||
public Redpacket(String outTradeNo, String sendName, String openId,
|
||||
int totalAmount, int totalNum, String wishing, String clientIp,
|
||||
String actName, String remark) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
this.sendName = sendName;
|
||||
this.openId = openId;
|
||||
this.totalNum = totalNum;
|
||||
this.wishing = wishing;
|
||||
this.clientIp = clientIp;
|
||||
this.actName = actName;
|
||||
this.remark = remark;
|
||||
this.totalAmount = totalAmount;
|
||||
this.amtType = totalNum > 1 ? "ALL_RAND" : null;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
@ -22,8 +22,8 @@ import com.foxinmy.weixin4j.util.URLEncodingUtil;
|
||||
*/
|
||||
public class WAPPayRequest extends AbstractPayRequest {
|
||||
|
||||
public WAPPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
super(prePayId, payAccount);
|
||||
public WAPPayRequest(PrePay prePay, WeixinPayAccount payAccount) {
|
||||
super(prePay.getPrepayId(),prePay.getResponse(), payAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,19 +1,24 @@
|
||||
package com.foxinmy.weixin4j.sign;
|
||||
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.type.SignType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信支付签名实现
|
||||
*
|
||||
* @className WeixinPaymentSignature
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @className WeixinPaymentSignature
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/external/jsapi.php?chapter=4_3">支付签名说明</a>
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class WeixinPaymentSignature extends AbstractWeixinSignature {
|
||||
|
||||
/**
|
||||
* 支付密钥
|
||||
*/
|
||||
@ -33,4 +38,23 @@ public class WeixinPaymentSignature extends AbstractWeixinSignature {
|
||||
StringBuilder sb = join(obj).append("&key=").append(paySignKey);
|
||||
return DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
public boolean validatePaySign(WeixinResponse weixinResponse) {
|
||||
return this.validatePaySign(weixinResponse.getAsString());
|
||||
|
||||
}
|
||||
|
||||
public boolean validatePaySign(String xmlResult) {
|
||||
return this.validatePaySign(XmlStream.xml2map(xmlResult));
|
||||
}
|
||||
|
||||
public boolean validatePaySign(Map<String, String> map) {
|
||||
String sign1 = map.get("sign");
|
||||
map.remove("sign");
|
||||
String sign2 = this.sign(map);
|
||||
return sign1.equals(sign2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ import java.util.Map.Entry;
|
||||
/**
|
||||
* 文件工具类
|
||||
*
|
||||
* @className FileUtil
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @className FileUtil
|
||||
* @date 2014年11月21日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
@ -101,9 +101,6 @@ public class FileUtil {
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
*
|
||||
* @param is
|
||||
* @return
|
||||
*/
|
||||
public static String getFileType(InputStream is) {
|
||||
String fileType = "file";
|
||||
@ -114,8 +111,7 @@ public class FileUtil {
|
||||
String fileCode = bytesToHexString(b).toLowerCase();
|
||||
for (Entry<String, String> entry : FILE_TYPE_MAP.entrySet()) {
|
||||
String key = entry.getKey().toLowerCase();
|
||||
if (key.startsWith(fileCode) || fileCode.startsWith(key)
|
||||
|| key.endsWith(fileCode) || fileCode.endsWith(key)) {
|
||||
if (key.startsWith(fileCode) || fileCode.startsWith(key) || key.endsWith(fileCode) || fileCode.endsWith(key)) {
|
||||
fileType = entry.getValue();
|
||||
break;
|
||||
}
|
||||
@ -137,9 +133,6 @@ public class FileUtil {
|
||||
|
||||
/**
|
||||
* 获取文件后缀
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileExtension(String fileName) {
|
||||
int extensionPos = fileName.lastIndexOf(".");
|
||||
@ -149,13 +142,27 @@ public class FileUtil {
|
||||
int lastUnixPos = fileName.lastIndexOf("/");
|
||||
int lastWindowsPos = fileName.lastIndexOf("\\");
|
||||
int lastSeparator = Math.max(lastUnixPos, lastWindowsPos);
|
||||
return lastSeparator > extensionPos ? "" : fileName
|
||||
.substring(extensionPos + 1);
|
||||
return lastSeparator > extensionPos ? "" : fileName.substring(extensionPos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
public static boolean deleteFile(String filePath) {
|
||||
File file = new File(filePath);
|
||||
if (!file.exists()) {
|
||||
return true;
|
||||
}
|
||||
if (file.isFile()) {
|
||||
return file.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
InputStream is = new FileInputStream(new File(
|
||||
"/Users/jy/Downloads/test.mp4"));
|
||||
InputStream is = new FileInputStream(new File("/Users/jy/Downloads/test.mp4"));
|
||||
System.err.println(getFileType(is));
|
||||
System.err.println(URLConnection.guessContentTypeFromStream(is));
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -12,11 +13,11 @@ import java.nio.charset.Charset;
|
||||
/**
|
||||
* IOUtil
|
||||
*
|
||||
* @className IOUtil
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @className IOUtil
|
||||
* @date 2014年9月22日
|
||||
* @since JDK 1.6
|
||||
* @see org.apache.commons.io.IOUtils
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public class IOUtil {
|
||||
|
||||
@ -27,22 +28,19 @@ public class IOUtil {
|
||||
return toByteArray(input, Charset.defaultCharset());
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(Reader input, Charset encoding)
|
||||
throws IOException {
|
||||
public static byte[] toByteArray(Reader input, Charset encoding) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
copy(input, output, encoding);
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
public static void copy(Reader input, OutputStream output, Charset encoding)
|
||||
throws IOException {
|
||||
public static void copy(Reader input, OutputStream output, Charset encoding) throws IOException {
|
||||
OutputStreamWriter out = new OutputStreamWriter(output, encoding);
|
||||
copyLarge(input, out, new char[DEFAULT_BUFFER_SIZE]);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public static int copy(InputStream input, OutputStream output)
|
||||
throws IOException {
|
||||
public static int copy(InputStream input, OutputStream output) throws IOException {
|
||||
long count = copyLarge(input, output);
|
||||
if (count > Integer.MAX_VALUE) {
|
||||
return -1;
|
||||
@ -50,8 +48,7 @@ public class IOUtil {
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
private static long copyLarge(InputStream input, OutputStream output)
|
||||
throws IOException {
|
||||
private static long copyLarge(InputStream input, OutputStream output) throws IOException {
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
long count = 0;
|
||||
int n = 0;
|
||||
@ -68,8 +65,7 @@ public class IOUtil {
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
private static long copyLarge(InputStream input, OutputStream output,
|
||||
byte[] buffer) throws IOException {
|
||||
private static long copyLarge(InputStream input, OutputStream output, byte[] buffer) throws IOException {
|
||||
long count = 0;
|
||||
int n = 0;
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
@ -79,8 +75,7 @@ public class IOUtil {
|
||||
return count;
|
||||
}
|
||||
|
||||
private static long copyLarge(Reader input, Writer output, char[] buffer)
|
||||
throws IOException {
|
||||
private static long copyLarge(Reader input, Writer output, char[] buffer) throws IOException {
|
||||
long count = 0;
|
||||
int n = 0;
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
@ -89,4 +84,12 @@ public class IOUtil {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void close(Closeable stream) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,20 +17,22 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
/**
|
||||
* 接口调用错误获取
|
||||
*
|
||||
* @author jy
|
||||
* @className WeixinErrorUtil
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年5月12日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
* @since JDK 1.6
|
||||
*/
|
||||
public final class WeixinErrorUtil {
|
||||
|
||||
private static byte[] errorXmlByteArray;
|
||||
private final static Map<String, String> errorCacheMap;
|
||||
|
||||
static {
|
||||
errorCacheMap = new ConcurrentHashMap<String, String>();
|
||||
try {
|
||||
errorXmlByteArray = IOUtil.toByteArray(WeixinResponse.class
|
||||
.getResourceAsStream("error.xml"));
|
||||
errorXmlByteArray = IOUtil.toByteArray(WeixinResponse.class.getResourceAsStream("error.xml"));
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -50,20 +52,17 @@ public final class WeixinErrorUtil {
|
||||
private boolean findElement;
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName,
|
||||
Attributes attributes) throws SAXException {
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
codeElement = qName.equalsIgnoreCase("code");
|
||||
textElement = qName.equalsIgnoreCase("text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName)
|
||||
throws SAXException {
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
String _text = new String(ch, start, length);
|
||||
if (codeElement && _text.equalsIgnoreCase(code)) {
|
||||
findElement = true;
|
||||
@ -88,8 +87,7 @@ public final class WeixinErrorUtil {
|
||||
try {
|
||||
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
|
||||
xmlReader.setContentHandler(textHandler);
|
||||
xmlReader.parse(new InputSource(new ByteArrayInputStream(
|
||||
errorXmlByteArray)));
|
||||
xmlReader.parse(new InputSource(new ByteArrayInputStream(errorXmlByteArray)));
|
||||
text = textHandler.getText();
|
||||
errorCacheMap.put(code, text);
|
||||
} catch (IOException e) {
|
||||
@ -102,9 +100,10 @@ public final class WeixinErrorUtil {
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getText("40001"));
|
||||
System.out.println(getText("40001"));
|
||||
System.out.println(getText("30002"));
|
||||
System.out.println(getText("30002"));
|
||||
System.out.println(getText("1234"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.7.3</version>
|
||||
<version>1.7.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-mp</artifactId>
|
||||
<name>weixin4j-mp</name>
|
||||
|
||||
@ -307,6 +307,7 @@ public class MassApi extends MpApi {
|
||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">删除群发</a>
|
||||
* @see {@link #massByTagId(Tuple, int)}
|
||||
* @see {@link #massByOpenIds(Tuple, String...)
|
||||
|
||||
*/
|
||||
public ApiResult deleteMassNews(String msgid) throws WeixinException {
|
||||
JSONObject obj = new JSONObject();
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.foxinmy</groupId>
|
||||
<artifactId>weixin4j</artifactId>
|
||||
<version>1.7.3</version>
|
||||
<version>1.7.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>weixin4j-qy</artifactId>
|
||||
<name>weixin4j-qy</name>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user