签名类接口化
This commit is contained in:
parent
0897575fe1
commit
40cf672715
@ -652,3 +652,5 @@
|
||||
+ weixin4j-base:v2和v3支付改名
|
||||
|
||||
+ weixin4j-base:支持服务商版支付
|
||||
|
||||
+ weixin4j-base:签名类接口化
|
||||
@ -2,25 +2,20 @@ package com.foxinmy.weixin4j.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.payment.mch.CorpPayment;
|
||||
import com.foxinmy.weixin4j.payment.mch.CorpPaymentRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.CorpPaymentResult;
|
||||
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.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
@ -36,18 +31,16 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @see <a
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
*/
|
||||
public class CashApi {
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
public class CashApi extends MchApi {
|
||||
|
||||
public CashApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
@ -58,22 +51,19 @@ public class CashApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">发放红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
redpacket.setSign(DigestUtil.paysignMd5(redpacket,
|
||||
weixinAccount.getPaySignKey()));
|
||||
public RedpacketSendResult sendRedpack(InputStream certificate,
|
||||
Redpacket redpacket) throws WeixinException {
|
||||
redpacket.setSign(weixinSignature.sign(redpacket));
|
||||
String param = XmlStream.map2xml((JSONObject) JSON.toJSON(redpacket));
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor
|
||||
.post(redpacket.getTotalNum() > 1 ? PayURLConsts.MCH_REDPACK_GROUPSEND_URL
|
||||
: PayURLConsts.MCH_REDPACKSEND_URL, param);
|
||||
response = createSSLRequestExecutor(certificate)
|
||||
.post(redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
|
||||
: getRequestUri("redpack_send_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -86,7 +76,7 @@ public class CashApi {
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
@ -96,28 +86,21 @@ public class CashApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(InputStream ca, String outTradeNo)
|
||||
throws WeixinException {
|
||||
Map<String, String> para = new HashMap<String, String>();
|
||||
para.put("nonce_str", RandomUtil.generateString(16));
|
||||
para.put("mch_id", weixinAccount.getMchId());
|
||||
public RedpacketRecord queryRedpack(InputStream certificate,
|
||||
String outTradeNo) throws WeixinException {
|
||||
Map<String, String> para = createBaseRequestMap(null);
|
||||
para.put("bill_type", "MCHT");
|
||||
para.put("appid", weixinAccount.getId());
|
||||
para.put("mch_billno", outTradeNo);
|
||||
String sign = DigestUtil
|
||||
.paysignMd5(para, weixinAccount.getPaySignKey());
|
||||
para.put("sign", sign);
|
||||
para.put("sign", weixinSignature.sign(para));
|
||||
String param = XmlStream.map2xml(para);
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_REDPACKQUERY_URL,
|
||||
param);
|
||||
response = createSSLRequestExecutor(certificate).post(
|
||||
getRequestUri("redpack_query_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -130,7 +113,7 @@ public class CashApi {
|
||||
/**
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param mpPayment
|
||||
* 付款信息
|
||||
@ -141,27 +124,24 @@ public class CashApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentResult corpPayment(InputStream ca, CorpPayment payment)
|
||||
throws WeixinException {
|
||||
public CorpPaymentResult sendCorpPayment(InputStream certificate,
|
||||
CorpPayment payment) throws WeixinException {
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(payment);
|
||||
obj.put("nonce_str", RandomUtil.generateString(16));
|
||||
obj.put("mchid", weixinAccount.getMchId());
|
||||
obj.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
obj.put("mch_appid", weixinAccount.getId());
|
||||
obj.put("device_info", weixinAccount.getDeviceInfo());
|
||||
String sign = DigestUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
|
||||
obj.put("sign", sign);
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYMENT_URL,
|
||||
param);
|
||||
response = createSSLRequestExecutor(certificate).post(
|
||||
getRequestUri("corppayment_send_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -178,7 +158,7 @@ public class CashApi {
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
@ -188,26 +168,23 @@ public class CashApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentRecord queryCorpPayment(InputStream ca, String outTradeNo)
|
||||
throws WeixinException {
|
||||
public CorpPaymentRecord queryCorpPayment(InputStream certificate,
|
||||
String outTradeNo) throws WeixinException {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("nonce_str", RandomUtil.generateString(16));
|
||||
obj.put("mch_id", weixinAccount.getMchId());
|
||||
obj.put("appid", weixinAccount.getId());
|
||||
obj.put("partner_trade_no", outTradeNo);
|
||||
String sign = DigestUtil.paysignMd5(obj, weixinAccount.getPaySignKey());
|
||||
obj.put("sign", sign);
|
||||
obj.put("sign", weixinSignature.sign(obj));
|
||||
String param = XmlStream.map2xml(obj);
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_ENPAYQUERY_URL,
|
||||
param);
|
||||
response = createSSLRequestExecutor(certificate).post(
|
||||
getRequestUri("corppayment_query_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
|
||||
@ -2,21 +2,15 @@ package com.foxinmy.weixin4j.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
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.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
@ -29,21 +23,16 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @since JDK 1.6
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php">代金券文档</a>
|
||||
*/
|
||||
public class CouponApi {
|
||||
|
||||
private final WeixinRequestExecutor weixinExecutor;
|
||||
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
public class CouponApi extends MchApi {
|
||||
|
||||
public CouponApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinExecutor = new WeixinRequestExecutor();
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
@ -59,10 +48,10 @@ public class CouponApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponResult sendCoupon(InputStream ca, String couponStockId,
|
||||
String partnerTradeNo, String openId, String opUserId)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = baseMap();
|
||||
public CouponResult sendCoupon(InputStream certificate,
|
||||
String couponStockId, String partnerTradeNo, String openId,
|
||||
String opUserId) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("coupon_stock_id", couponStockId);
|
||||
map.put("partner_trade_no", partnerTradeNo);
|
||||
map.put("openid", openId);
|
||||
@ -75,19 +64,16 @@ public class CouponApi {
|
||||
map.put("op_user_id", opUserId);
|
||||
map.put("version", "1.0");
|
||||
map.put("type", "XML");
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_COUPONSEND_URL,
|
||||
param);
|
||||
response = createSSLRequestExecutor(certificate).post(
|
||||
getRequestUri("coupon_send_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -110,13 +96,12 @@ public class CouponApi {
|
||||
*/
|
||||
public CouponStock queryCouponStock(String couponStockId)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = baseMap();
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("coupon_stock_id", couponStockId);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_COUPONSTOCKQUERY_URL, param);
|
||||
getRequestUri("couponstock_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CouponStock>() {
|
||||
});
|
||||
}
|
||||
@ -134,33 +119,13 @@ public class CouponApi {
|
||||
*/
|
||||
public CouponDetail queryCouponDetail(String couponId)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = baseMap();
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("coupon_id", couponId);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_COUPONDETAILQUERY_URL, param);
|
||||
getRequestUri("coupondetail_query_uri"), param);
|
||||
return response.getAsObject(new TypeReference<CouponDetail>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口请求基本数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> baseMap() {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
|
||||
map.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.foxinmy.weixin4j.api;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 商户支付
|
||||
*
|
||||
* @className MchApi
|
||||
* @author jy
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see <a href="https://pay.weixin.qq.com/wiki/doc/api/index.html">商户支付平台</a>
|
||||
*/
|
||||
public class MchApi extends BaseApi {
|
||||
|
||||
private final static ResourceBundle WEIXIN_BUNDLE;
|
||||
|
||||
static {
|
||||
WEIXIN_BUNDLE = ResourceBundle
|
||||
.getBundle("com/foxinmy/weixin4j/payment/weixin");
|
||||
}
|
||||
|
||||
protected final WeixinPayAccount weixinAccount;
|
||||
protected final WeixinSignature weixinSignature;
|
||||
|
||||
public MchApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinSignature = new WeixinPaymentSignature(
|
||||
weixinAccount.getPaySignKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle weixinBundle() {
|
||||
return WEIXIN_BUNDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 SSL支付请求
|
||||
*
|
||||
* @param certificate
|
||||
* *.p12证书文件
|
||||
* @return
|
||||
* @throws WeixinException
|
||||
*/
|
||||
protected WeixinRequestExecutor createSSLRequestExecutor(
|
||||
InputStream certificate) throws WeixinException {
|
||||
return new WeixinSSLRequestExecutor(weixinAccount.getCertificateKey(),
|
||||
certificate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付接口请求基本数据
|
||||
*
|
||||
* @param idQuery
|
||||
* ID信息 可为空
|
||||
* @return 基础map
|
||||
*/
|
||||
protected Map<String, String> createBaseRequestMap(IdQuery idQuery) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubId())) {
|
||||
map.put("sub_appid", weixinAccount.getSubId());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
|
||||
map.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
}
|
||||
if (idQuery != null) {
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -19,14 +19,11 @@ 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.WeixinRequestExecutor;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
|
||||
import com.foxinmy.weixin4j.http.weixin.XmlResult;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
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.JSAPIPayRequest;
|
||||
@ -63,14 +60,10 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
* @since JDK 1.6
|
||||
* @see <a href="http://pay.weixin.qq.com/wiki/doc/api/index.html">商户平台API</a>
|
||||
*/
|
||||
public class PayApi {
|
||||
|
||||
private final WeixinRequestExecutor weixinExecutor;
|
||||
private final WeixinPayAccount weixinAccount;
|
||||
public class PayApi extends MchApi {
|
||||
|
||||
public PayApi(WeixinPayAccount weixinAccount) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.weixinExecutor = new WeixinRequestExecutor();
|
||||
super(weixinAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,12 +81,11 @@ public class PayApi {
|
||||
*/
|
||||
public PrePay createPrePay(MchPayPackage payPackage)
|
||||
throws WeixinPayException {
|
||||
payPackage.setSign(DigestUtil.paysignMd5(payPackage,
|
||||
weixinAccount.getPaySignKey()));
|
||||
payPackage.setSign(weixinSignature.sign(payPackage));
|
||||
String payJsRequestXml = XmlStream.toXML(payPackage);
|
||||
try {
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_UNIFIEDORDER_URL, payJsRequestXml);
|
||||
getRequestUri("order_create_uri"), payJsRequestXml);
|
||||
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
|
||||
});
|
||||
if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) {
|
||||
@ -250,8 +242,7 @@ public class PayApi {
|
||||
map.put("nonceStr", RandomUtil.generateString(16));
|
||||
map.put("url", url);
|
||||
map.put("accessToken", oauthToken);
|
||||
String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true,
|
||||
null));
|
||||
String sign = DigestUtil.SHA1(MapUtil.toJoinString(map, false, true));
|
||||
map.remove("url");
|
||||
map.remove("accessToken");
|
||||
map.put("scope", "jsapi_address");
|
||||
@ -279,8 +270,8 @@ public class PayApi {
|
||||
map.put("time_stamp", timestamp);
|
||||
map.put("nonce_str", noncestr);
|
||||
map.put("product_id", productId);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
return String.format(PayURLConsts.MCH_NATIVE_URL, sign,
|
||||
String sign = weixinSignature.sign(map);
|
||||
return String.format(getRequestUri("native_pay_uri"), sign,
|
||||
weixinAccount.getId(), weixinAccount.getMchId(), productId,
|
||||
timestamp, noncestr);
|
||||
}
|
||||
@ -438,14 +429,11 @@ public class PayApi {
|
||||
*/
|
||||
public Order createMicroPay(MicroPayPackage payPackage)
|
||||
throws WeixinException {
|
||||
String sign = DigestUtil.paysignMd5(payPackage,
|
||||
weixinAccount.getPaySignKey());
|
||||
payPackage.setSign(sign);
|
||||
payPackage.setSign(weixinSignature.sign(payPackage));
|
||||
String para = XmlStream.toXML(payPackage);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_MICROPAY_URL, para);
|
||||
return response
|
||||
.getAsObject(new TypeReference<com.foxinmy.weixin4j.payment.mch.Order>() {
|
||||
getRequestUri("micropay_uri"), para);
|
||||
return response.getAsObject(new TypeReference<Order>() {
|
||||
});
|
||||
}
|
||||
|
||||
@ -466,13 +454,12 @@ public class PayApi {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order orderQuery(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
public Order queryOrder(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_ORDERQUERY_URL, param);
|
||||
getRequestUri("order_query_uri"), param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
Order.class);
|
||||
}
|
||||
@ -489,7 +476,7 @@ public class PayApi {
|
||||
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
|
||||
* </p>
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -511,12 +498,12 @@ public class PayApi {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundResult refundApply(InputStream ca, IdQuery idQuery,
|
||||
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
CurrencyType refundFeeType, String opUserId) throws WeixinException {
|
||||
WeixinResponse response = null;
|
||||
try {
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("out_refund_no", outRefundNo);
|
||||
map.put("total_fee", DateUtil.formaFee2Fen(totalFee));
|
||||
map.put("refund_fee", DateUtil.formaFee2Fen(refundFee));
|
||||
@ -528,18 +515,14 @@ public class PayApi {
|
||||
refundFeeType = CurrencyType.CNY;
|
||||
}
|
||||
map.put("refund_fee_type", refundFeeType.name());
|
||||
String sign = DigestUtil.paysignMd5(map,
|
||||
weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
response = weixinExecutor.post(PayURLConsts.MCH_REFUNDAPPLY_URL,
|
||||
param);
|
||||
response = createSSLRequestExecutor(certificate).post(
|
||||
getRequestUri("refund_apply_uri"), param);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -552,7 +535,7 @@ public class PayApi {
|
||||
/**
|
||||
* 退款申请(全额退款)
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -561,12 +544,12 @@ public class PayApi {
|
||||
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* @param totalFee
|
||||
* 订单总金额,单位为元
|
||||
* @see {@link #refundApply(InputStream, IdQuery, String, double, double,CurrencyType, String)}
|
||||
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double,CurrencyType, String)}
|
||||
*/
|
||||
public RefundResult refundApply(InputStream ca, IdQuery idQuery,
|
||||
public RefundResult applyRefund(InputStream certificate, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee) throws WeixinException {
|
||||
return refundApply(ca, idQuery, outRefundNo, totalFee, totalFee, null,
|
||||
null);
|
||||
return applyRefund(certificate, idQuery, outRefundNo, totalFee,
|
||||
totalFee, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -575,7 +558,7 @@ public class PayApi {
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -584,24 +567,20 @@ public class PayApi {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public ApiResult reverseOrder(InputStream ca, IdQuery idQuery)
|
||||
public ApiResult reverseOrder(InputStream certificate, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
try {
|
||||
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
|
||||
weixinAccount.getCertificateKey(), ca);
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = DigestUtil.paysignMd5(map,
|
||||
weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_ORDERREVERSE_URL, param);
|
||||
WeixinResponse response = createSSLRequestExecutor(certificate)
|
||||
.post(getRequestUri("order_reverse_uri"), param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -621,17 +600,16 @@ public class PayApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_9">转换短链接API</a>
|
||||
*/
|
||||
public String getShorturl(String url) throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
try {
|
||||
map.put("long_url", URLEncoder.encode(url, Consts.UTF_8.name()));
|
||||
} catch (UnsupportedEncodingException ignore) {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
;
|
||||
}
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_SHORTURL_URL, param);
|
||||
getRequestUri("longurl_convert_uri"), param);
|
||||
map = XmlStream.xml2map(response.getAsString());
|
||||
return map.get("short_url");
|
||||
}
|
||||
@ -652,13 +630,12 @@ public class PayApi {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API</a>
|
||||
*/
|
||||
public ApiResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
Map<String, String> map = baseMap(new IdQuery(outTradeNo,
|
||||
Map<String, String> map = createBaseRequestMap(new IdQuery(outTradeNo,
|
||||
IdType.TRADENO));
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_CLOSEORDER_URL, param);
|
||||
getRequestUri("order_close_uri"), param);
|
||||
return response.getAsObject(new TypeReference<ApiResult>() {
|
||||
});
|
||||
}
|
||||
@ -700,14 +677,13 @@ public class PayApi {
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
Map<String, String> map = baseMap(null);
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("bill_date", formatBillDate);
|
||||
map.put("bill_type", billType.name());
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_DOWNLOADBILL_URL, param);
|
||||
getRequestUri("downloadbill_uri"), param);
|
||||
|
||||
BufferedReader reader = null;
|
||||
BufferedWriter writer = null;
|
||||
@ -757,13 +733,12 @@ public class PayApi {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundRecord refundQuery(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = baseMap(idQuery);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException {
|
||||
Map<String, String> map = createBaseRequestMap(idQuery);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_REFUNDQUERY_URL, param);
|
||||
getRequestUri("refund_query_uri"), param);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
RefundRecord.class);
|
||||
}
|
||||
@ -793,18 +768,17 @@ public class PayApi {
|
||||
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("interface_url", interfaceUrl);
|
||||
map.put("execute_time_", Integer.toString(executeTime));
|
||||
map.put("out_trade_no", outTradeNo);
|
||||
map.put("user_ip", ip);
|
||||
map.put("time", DateUtil.fortmat2yyyyMMddHHmmss(time));
|
||||
map.putAll((Map<String, String>) JSON.toJSON(returnXml));
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_PAYREPORT_URL, param);
|
||||
getRequestUri("interface_report_uri"), param);
|
||||
return response.getAsXmlResult();
|
||||
}
|
||||
|
||||
@ -820,39 +794,13 @@ public class PayApi {
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
Map<String, String> map = baseMap(null);
|
||||
Map<String, String> map = createBaseRequestMap(null);
|
||||
map.put("auth_code", authCode);
|
||||
String sign = DigestUtil.paysignMd5(map, weixinAccount.getPaySignKey());
|
||||
map.put("sign", sign);
|
||||
map.put("sign", weixinSignature.sign(map));
|
||||
String param = XmlStream.map2xml(map);
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
PayURLConsts.MCH_AUTHCODE_OPENID_URL, param);
|
||||
getRequestUri("authcode_openid_uri"), param);
|
||||
return response.getAsObject(new TypeReference<OpenIdResult>() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付接口请求基本数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> baseMap(IdQuery idQuery) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("mch_id", weixinAccount.getMchId());
|
||||
map.put("nonce_str", RandomUtil.generateString(16));
|
||||
if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
|
||||
map.put("device_info", weixinAccount.getDeviceInfo());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubId())) {
|
||||
map.put("sub_appid", weixinAccount.getSubId());
|
||||
}
|
||||
if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
|
||||
map.put("sub_mch_id", weixinAccount.getSubMchId());
|
||||
}
|
||||
if (idQuery != null) {
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
package com.foxinmy.weixin4j.payment;
|
||||
|
||||
|
||||
/**
|
||||
* 支付URL常量类
|
||||
*
|
||||
* @className PayURLConsts
|
||||
* @author jy
|
||||
* @date 2014年12月3日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public final class PayURLConsts {
|
||||
|
||||
private static final String MCH_BASE_URL = "https://api.mch.weixin.qq.com";
|
||||
|
||||
/**
|
||||
* 商户平台下统一订单生成的url
|
||||
*/
|
||||
public static final String MCH_UNIFIEDORDER_URL = MCH_BASE_URL
|
||||
+ "/pay/unifiedorder";
|
||||
/**
|
||||
* 订单查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_ORDERQUERY_URL = MCH_BASE_URL
|
||||
+ "/pay/orderquery";
|
||||
/**
|
||||
* 关闭订单(商户平台)
|
||||
*/
|
||||
public static final String MCH_CLOSEORDER_URL = MCH_BASE_URL
|
||||
+ "/pay/closeorder";
|
||||
/**
|
||||
* 对账单下载(商户平台)
|
||||
*/
|
||||
public static final String MCH_DOWNLOADBILL_URL = MCH_BASE_URL
|
||||
+ "/pay/downloadbill";
|
||||
/**
|
||||
* 退款查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_REFUNDQUERY_URL = MCH_BASE_URL
|
||||
+ "/pay/refundquery";
|
||||
/**
|
||||
* 退款申请(商户平台)
|
||||
*/
|
||||
public static final String MCH_REFUNDAPPLY_URL = MCH_BASE_URL
|
||||
+ "/secapi/pay/refund";
|
||||
/**
|
||||
* 冲正撤销(商户平台)
|
||||
*/
|
||||
public static final String MCH_ORDERREVERSE_URL = MCH_BASE_URL
|
||||
+ "/secapi/pay/reverse";
|
||||
/**
|
||||
* 被扫支付&刷卡支付(商户平台)
|
||||
*/
|
||||
public static final String MCH_MICROPAY_URL = MCH_BASE_URL
|
||||
+ "/pay/micropay";
|
||||
/**
|
||||
* 接口上报(商户平台)
|
||||
*/
|
||||
public static final String MCH_PAYREPORT_URL = MCH_BASE_URL
|
||||
+ "/payitil/report";
|
||||
/**
|
||||
* 发送现金红包-普通红包(商户平台)
|
||||
*/
|
||||
public static final String MCH_REDPACKSEND_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/sendredpack";
|
||||
/**
|
||||
* 发送现金红包-裂变红包(商户平台)
|
||||
*/
|
||||
public static final String MCH_REDPACK_GROUPSEND_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/sendgroupredpack";
|
||||
/**
|
||||
* 查询现金红包(商户平台)
|
||||
*/
|
||||
public static final String MCH_REDPACKQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/gethbinfo";
|
||||
/**
|
||||
* 企业向个人付款(商户平台)
|
||||
*/
|
||||
public static final String MCH_ENPAYMENT_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/promotion/transfers";
|
||||
/**
|
||||
* 企业付款查询(商户平台)
|
||||
*/
|
||||
public static final String MCH_ENPAYQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/gettransferinfo";
|
||||
/**
|
||||
* 发放代金券(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONSEND_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/send_coupon";
|
||||
/**
|
||||
* 查询代金券批次信息(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONSTOCKQUERY_URL = MCH_BASE_URL
|
||||
+ "/mmpaymkttransfers/query_coupon_stock";
|
||||
/**
|
||||
* 查询代金券详细信息(商户平台)
|
||||
*/
|
||||
public static final String MCH_COUPONDETAILQUERY_URL = MCH_BASE_URL
|
||||
+ "/promotion/query_coupon";
|
||||
/**
|
||||
* 长链接转换(商户平台)
|
||||
*/
|
||||
public static final String MCH_SHORTURL_URL = MCH_BASE_URL
|
||||
+ "/tools/shorturl";
|
||||
/**
|
||||
* 商户平台下native支付的url(模式1)
|
||||
*/
|
||||
public static final String MCH_NATIVE_URL = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";
|
||||
|
||||
/**
|
||||
* WAP支付
|
||||
*
|
||||
* @see <a
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1">WAP支付说明</a>
|
||||
*/
|
||||
public static final String MCH_WAP_URL = "weixin://wap/pay?%s";
|
||||
/**
|
||||
* 授权码查询OPENID接口
|
||||
*/
|
||||
public static final String MCH_AUTHCODE_OPENID_URL = MCH_BASE_URL
|
||||
+ "/tools/authcodetoopenid";
|
||||
}
|
||||
@ -30,6 +30,7 @@ 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.payment.mch.RefundResult;
|
||||
import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
@ -50,7 +51,7 @@ public class WeixinPayProxy {
|
||||
/**
|
||||
* 微信支付API:js支付、扫码支付等接口
|
||||
*/
|
||||
private final PayApi pay3Api;
|
||||
private final PayApi payApi;
|
||||
/**
|
||||
* 代金券API
|
||||
*/
|
||||
@ -79,7 +80,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public WeixinPayProxy(Weixin4jSettings settings) {
|
||||
this.settings = settings;
|
||||
this.pay3Api = new PayApi(settings.getWeixinPayAccount());
|
||||
this.payApi = new PayApi(settings.getWeixinPayAccount());
|
||||
this.couponApi = new CouponApi(settings.getWeixinPayAccount());
|
||||
this.cashApi = new CashApi(settings.getWeixinPayAccount());
|
||||
}
|
||||
@ -109,7 +110,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public PrePay createPrePay(MchPayPackage payPackage)
|
||||
throws WeixinPayException {
|
||||
return pay3Api.createPrePay(payPackage);
|
||||
return payApi.createPrePay(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +128,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public MchPayRequest createPayRequest(MchPayPackage payPackage)
|
||||
throws WeixinPayException {
|
||||
return pay3Api.createPayRequest(payPackage);
|
||||
return payApi.createPayRequest(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,7 +174,7 @@ public class WeixinPayProxy {
|
||||
double totalFee, String notifyUrl, String createIp, String attach,
|
||||
Date timeStart, Date timeExpire, String goodsTag, String limitPay)
|
||||
throws WeixinPayException {
|
||||
return pay3Api.createPayRequest(tradeType, openId, productId, body,
|
||||
return payApi.createPayRequest(tradeType, openId, productId, body,
|
||||
detail, outTradeNo, totalFee, notifyUrl, createIp, attach,
|
||||
timeStart, timeExpire, goodsTag, limitPay);
|
||||
}
|
||||
@ -201,7 +202,7 @@ public class WeixinPayProxy {
|
||||
public MchPayRequest createJSPayRequest(String openId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp) throws WeixinPayException {
|
||||
return pay3Api.createJSPayRequest(openId, body, outTradeNo, totalFee,
|
||||
return payApi.createJSPayRequest(openId, body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp);
|
||||
}
|
||||
|
||||
@ -226,7 +227,7 @@ public class WeixinPayProxy {
|
||||
* @return 编辑地址请求JSON串
|
||||
*/
|
||||
public String createAddressRequestJSON(String url, String oauthToken) {
|
||||
return pay3Api.createAddressRequestJSON(url, oauthToken);
|
||||
return payApi.createAddressRequestJSON(url, oauthToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +242,7 @@ public class WeixinPayProxy {
|
||||
* href="https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">模式一</a>
|
||||
*/
|
||||
public String createNativePayRequestURL(String productId) {
|
||||
return pay3Api.createNativePayRequestURL(productId);
|
||||
return payApi.createNativePayRequestURL(productId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,7 +271,7 @@ public class WeixinPayProxy {
|
||||
public NativePayResponse createNativePayResponse(String productId,
|
||||
String body, String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp) throws WeixinPayException {
|
||||
return pay3Api.createNativePayResponse(productId, body, outTradeNo,
|
||||
return payApi.createNativePayResponse(productId, body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp);
|
||||
}
|
||||
|
||||
@ -300,7 +301,7 @@ public class WeixinPayProxy {
|
||||
public MchPayRequest createNativePayRequest(String productId, String body,
|
||||
String outTradeNo, double totalFee, String notifyUrl,
|
||||
String createIp) throws WeixinPayException {
|
||||
return pay3Api.createNativePayRequest(productId, body, outTradeNo,
|
||||
return payApi.createNativePayRequest(productId, body, outTradeNo,
|
||||
totalFee, notifyUrl, createIp);
|
||||
}
|
||||
|
||||
@ -327,7 +328,7 @@ public class WeixinPayProxy {
|
||||
public MchPayRequest createAppPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp)
|
||||
throws WeixinPayException {
|
||||
return pay3Api.createAppPayRequest(body, outTradeNo, totalFee,
|
||||
return payApi.createAppPayRequest(body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp);
|
||||
}
|
||||
|
||||
@ -354,7 +355,7 @@ public class WeixinPayProxy {
|
||||
public MchPayRequest createWAPPayRequest(String body, String outTradeNo,
|
||||
double totalFee, String notifyUrl, String createIp)
|
||||
throws WeixinPayException {
|
||||
return pay3Api.createWAPPayRequest(body, outTradeNo, totalFee,
|
||||
return payApi.createWAPPayRequest(body, outTradeNo, totalFee,
|
||||
notifyUrl, createIp);
|
||||
}
|
||||
|
||||
@ -378,7 +379,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public Order createMicroPay(String authCode, String body, String orderNo,
|
||||
double orderFee, String createIp) throws WeixinException {
|
||||
return pay3Api.createMicroPay(authCode, body, orderNo, orderFee,
|
||||
return payApi.createMicroPay(authCode, body, orderNo, orderFee,
|
||||
createIp);
|
||||
}
|
||||
|
||||
@ -397,7 +398,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public Order createMicroPay(MicroPayPackage payPackage)
|
||||
throws WeixinException {
|
||||
return pay3Api.createMicroPay(payPackage);
|
||||
return payApi.createMicroPay(payPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,8 +419,8 @@ public class WeixinPayProxy {
|
||||
* @return 订单详情
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public Order orderQuery(IdQuery idQuery) throws WeixinException {
|
||||
return pay3Api.orderQuery(idQuery);
|
||||
public Order queryOrder(IdQuery idQuery) throws WeixinException {
|
||||
return payApi.queryOrder(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -434,7 +435,7 @@ public class WeixinPayProxy {
|
||||
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
|
||||
* </p>
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -458,11 +459,11 @@ public class WeixinPayProxy {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
|
||||
InputStream ca, IdQuery idQuery, String outRefundNo,
|
||||
public RefundResult applyRefund(
|
||||
InputStream certificate, IdQuery idQuery, String outRefundNo,
|
||||
double totalFee, double refundFee, CurrencyType refundFeeType,
|
||||
String opUserId) throws WeixinException {
|
||||
return pay3Api.refundApply(ca, idQuery, outRefundNo, totalFee,
|
||||
return payApi.applyRefund(certificate, idQuery, outRefundNo, totalFee,
|
||||
refundFee, refundFeeType, opUserId);
|
||||
}
|
||||
|
||||
@ -471,12 +472,12 @@ public class WeixinPayProxy {
|
||||
*
|
||||
* @throws IOException
|
||||
*
|
||||
* @see {@link #refundApply(InputStream, IdQuery, String, double, double, String,CurrencyType)}
|
||||
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String,CurrencyType)}
|
||||
*/
|
||||
public com.foxinmy.weixin4j.payment.mch.RefundResult refundApply(
|
||||
public RefundResult applyRefund(
|
||||
IdQuery idQuery, String outRefundNo, double totalFee)
|
||||
throws WeixinException, IOException {
|
||||
return pay3Api.refundApply(
|
||||
return payApi.applyRefund(
|
||||
new FileInputStream(settings.getCertificateFile0()), idQuery,
|
||||
outRefundNo, totalFee);
|
||||
}
|
||||
@ -499,8 +500,8 @@ public class WeixinPayProxy {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundRecord refundQuery(IdQuery idQuery) throws WeixinException {
|
||||
return pay3Api.refundQuery(idQuery);
|
||||
public RefundRecord queryRefund(IdQuery idQuery) throws WeixinException {
|
||||
return payApi.queryRefund(idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -524,7 +525,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public File downloadBill(Date billDate, BillType billType)
|
||||
throws WeixinException {
|
||||
return pay3Api.downloadBill(billDate, billType, settings.getTmpdir0());
|
||||
return payApi.downloadBill(billDate, billType, settings.getTmpdir0());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -533,7 +534,7 @@ public class WeixinPayProxy {
|
||||
* 如需实现相同功能请调用退款接口</font></br> <font
|
||||
* color="red">调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销</font></br>
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -543,9 +544,9 @@ public class WeixinPayProxy {
|
||||
* @since V3
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public ApiResult reverseOrder(InputStream ca, IdQuery idQuery)
|
||||
public ApiResult reverseOrder(InputStream certificate, IdQuery idQuery)
|
||||
throws WeixinException {
|
||||
return pay3Api.reverseOrder(ca, idQuery);
|
||||
return payApi.reverseOrder(certificate, idQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -560,7 +561,7 @@ public class WeixinPayProxy {
|
||||
*/
|
||||
public ApiResult reverseOrder(IdQuery idQuery) throws WeixinException,
|
||||
IOException {
|
||||
return pay3Api.reverseOrder(
|
||||
return payApi.reverseOrder(
|
||||
new FileInputStream(settings.getCertificateFile0()), idQuery);
|
||||
}
|
||||
|
||||
@ -581,7 +582,7 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3">关闭订单API</a>
|
||||
*/
|
||||
public ApiResult closeOrder(String outTradeNo) throws WeixinException {
|
||||
return pay3Api.closeOrder(outTradeNo);
|
||||
return payApi.closeOrder(outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -598,7 +599,7 @@ public class WeixinPayProxy {
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String getPayShorturl(String url) throws WeixinException {
|
||||
return pay3Api.getShorturl(url);
|
||||
return payApi.getShorturl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -626,14 +627,14 @@ public class WeixinPayProxy {
|
||||
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
|
||||
String outTradeNo, String ip, Date time, XmlResult returnXml)
|
||||
throws WeixinException {
|
||||
return pay3Api.interfaceReport(interfaceUrl, executeTime, outTradeNo,
|
||||
return payApi.interfaceReport(interfaceUrl, executeTime, outTradeNo,
|
||||
ip, time, returnXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放代金券(需要证书)
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param couponStockId
|
||||
* 代金券批次id
|
||||
@ -650,11 +651,11 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/sp_coupon.php?chapter=12_3">发放代金券接口</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CouponResult sendCoupon(InputStream ca, String couponStockId,
|
||||
String partnerTradeNo, String openId, String opUserId)
|
||||
throws WeixinException {
|
||||
return couponApi.sendCoupon(ca, couponStockId, partnerTradeNo, openId,
|
||||
opUserId);
|
||||
public CouponResult sendCoupon(InputStream certificate,
|
||||
String couponStockId, String partnerTradeNo, String openId,
|
||||
String opUserId) throws WeixinException {
|
||||
return couponApi.sendCoupon(certificate, couponStockId, partnerTradeNo,
|
||||
openId, opUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -706,7 +707,7 @@ public class WeixinPayProxy {
|
||||
/**
|
||||
* 发放红包 企业向微信用户个人发现金红包
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param redpacket
|
||||
* 红包信息
|
||||
@ -718,9 +719,9 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5">红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketSendResult sendRedpack(InputStream ca, Redpacket redpacket)
|
||||
throws WeixinException {
|
||||
return cashApi.sendRedpack(ca, redpacket);
|
||||
public RedpacketSendResult sendRedpack(InputStream certificate,
|
||||
Redpacket redpacket) throws WeixinException {
|
||||
return cashApi.sendRedpack(certificate, redpacket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -737,7 +738,7 @@ public class WeixinPayProxy {
|
||||
/**
|
||||
* 查询红包记录
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户发放红包的商户订单号
|
||||
@ -748,9 +749,9 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6">查询红包接口说明</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RedpacketRecord queryRedpack(InputStream ca, String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryRedpack(ca, outTradeNo);
|
||||
public RedpacketRecord queryRedpack(InputStream certificate,
|
||||
String outTradeNo) throws WeixinException {
|
||||
return cashApi.queryRedpack(certificate, outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -769,9 +770,9 @@ public class WeixinPayProxy {
|
||||
/**
|
||||
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param mpPayment
|
||||
* @param payment
|
||||
* 付款信息
|
||||
* @return 付款结果
|
||||
* @see com.foxinmy.weixin4j.api.CashApi
|
||||
@ -781,26 +782,26 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_1">企业付款</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentResult corpPayment(InputStream ca, CorpPayment payment)
|
||||
throws WeixinException {
|
||||
return cashApi.corpPayment(ca, payment);
|
||||
public CorpPaymentResult sendCorpPayment(InputStream certificate,
|
||||
CorpPayment payment) throws WeixinException {
|
||||
return cashApi.sendCorpPayment(certificate, payment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款
|
||||
*
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#corpPayment(InputStream, CorpPayment)}
|
||||
* @see {@link com.foxinmy.weixin4j.payment.WeixinPayProxy#senCorpPayment(InputStream, CorpPayment)}
|
||||
*/
|
||||
public CorpPaymentResult corpPayment(CorpPayment payment)
|
||||
public CorpPaymentResult sendCorpPayment(CorpPayment payment)
|
||||
throws WeixinException, IOException {
|
||||
return cashApi.corpPayment(
|
||||
return cashApi.sendCorpPayment(
|
||||
new FileInputStream(settings.getCertificateFile0()), payment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款查询 用于商户的企业付款操作进行结果查询,返回付款操作详细结果
|
||||
*
|
||||
* @param ca
|
||||
* @param certificate
|
||||
* 后缀为*.p12的证书文件
|
||||
* @param outTradeNo
|
||||
* 商户调用企业付款API时使用的商户订单号
|
||||
@ -811,9 +812,9 @@ public class WeixinPayProxy {
|
||||
* href="http://pay.weixin.qq.com/wiki/doc/api/mch_pay.php?chapter=14_3">企业付款查询</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public CorpPaymentRecord queryCorpPayment(InputStream ca, String outTradeNo)
|
||||
throws WeixinException {
|
||||
return cashApi.queryCorpPayment(ca, outTradeNo);
|
||||
public CorpPaymentRecord queryCorpPayment(InputStream certificate,
|
||||
String outTradeNo) throws WeixinException {
|
||||
return cashApi.queryCorpPayment(certificate, outTradeNo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -842,7 +843,7 @@ public class WeixinPayProxy {
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OpenIdResult authCode2openId(String authCode) throws WeixinException {
|
||||
return pay3Api.authCode2openId(authCode);
|
||||
return payApi.authCode2openId(authCode);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.6.7";
|
||||
|
||||
@ -44,7 +44,7 @@ public class APPPayRequest extends AbstractPayRequest {
|
||||
PayRequest payRequest = toRequestObject();
|
||||
String sign = DigestUtil.MD5(
|
||||
String.format("%s&key=%s",
|
||||
MapUtil.toJoinString(payRequest, false, true, null),
|
||||
MapUtil.toJoinString(payRequest, false, true),
|
||||
getPayAccount().getPaySignKey())).toUpperCase();
|
||||
StringBuilder content = new StringBuilder();
|
||||
content.append("<xml>");
|
||||
|
||||
@ -1,15 +1,19 @@
|
||||
package com.foxinmy.weixin4j.payment.mch;
|
||||
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
|
||||
public abstract class AbstractPayRequest implements MchPayRequest {
|
||||
|
||||
private final String prePayId;
|
||||
private final WeixinPayAccount payAccount;
|
||||
protected final WeixinSignature weixinSignature;
|
||||
|
||||
public AbstractPayRequest(String prePayId, WeixinPayAccount payAccount) {
|
||||
this.prePayId = prePayId;
|
||||
this.payAccount = payAccount;
|
||||
this.weixinSignature = new WeixinPaymentSignature(payAccount.getPaySignKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -5,7 +5,6 @@ import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.type.SignType;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
|
||||
/**
|
||||
* 公众号JS支付:get_brand_wcpay_request</br>
|
||||
@ -40,8 +39,7 @@ public class JSAPIPayRequest extends AbstractPayRequest {
|
||||
PayRequest payRequest = new PayRequest(getPayAccount().getId(),
|
||||
"prepay_id=" + getPrePayId());
|
||||
payRequest.setSignType(SignType.MD5);
|
||||
payRequest.setPaySign(DigestUtil.paysignMd5(payRequest, getPayAccount()
|
||||
.getPaySignKey()));
|
||||
payRequest.setPaySign(weixinSignature.sign(payRequest));
|
||||
return payRequest;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.exception.WeixinPayException;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.util.RandomUtil;
|
||||
|
||||
/**
|
||||
@ -67,7 +67,8 @@ public class NativePayResponse extends ApiResult {
|
||||
this.setAppId(weixinAccount.getId());
|
||||
this.setNonceStr(RandomUtil.generateString(16));
|
||||
this.prepayId = prepayId;
|
||||
this.setSign(DigestUtil.paysignMd5(this, weixinAccount.getPaySignKey()));
|
||||
this.setSign(new WeixinPaymentSignature(weixinAccount.getPaySignKey())
|
||||
.sign(this));
|
||||
}
|
||||
|
||||
public String getPrepayId() {
|
||||
|
||||
@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.payment.mch;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.payment.PayURLConsts;
|
||||
import com.foxinmy.weixin4j.type.TradeType;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
@ -46,12 +45,13 @@ public class WAPPayRequest extends AbstractPayRequest {
|
||||
@Override
|
||||
public String toRequestString() {
|
||||
PayRequest payRequest = toRequestObject();
|
||||
String original = MapUtil.toJoinString(payRequest, true, true, null);
|
||||
String original = MapUtil.toJoinString(payRequest, true, true);
|
||||
String sign = DigestUtil.MD5(
|
||||
String.format("%s&key=%s", original, getPayAccount()
|
||||
.getPaySignKey())).toUpperCase();
|
||||
return String.format(PayURLConsts.MCH_WAP_URL, URLEncodingUtil
|
||||
.encoding(String.format("%s&sign=%s", original, sign),
|
||||
return String.format("weixin://wap/pay?%s",
|
||||
URLEncodingUtil.encoding(
|
||||
String.format("%s&sign=%s", original, sign),
|
||||
Consts.UTF_8, true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
# \u5fae\u4fe1\u5546\u6237\u5e73\u53f0\u6587\u6863\u8bf4\u660e
|
||||
# https://pay.weixin.qq.com/
|
||||
# https://pay.weixin.qq.com/wiki/doc/api/index.php
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
mch_base_url=https://api.mch.weixin.qq.com
|
||||
|
||||
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
|
||||
# \u53d1\u9001\u73b0\u91d1\u88c2\u53d8\u7ea2\u5305
|
||||
groupredpack_send_uri={mch_base_url}/mmpaymkttransfers/sendgroupredpack
|
||||
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
|
||||
# \u7edf\u4e00\u8ba2\u5355\u751f\u6210
|
||||
order_create_uri={mch_base_url}/pay/unifiedorder
|
||||
# \u88ab\u626b\u652f\u4ed8
|
||||
micropay_uri={mch_base_url}/pay/micropay
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
order_query_uri={mch_base_url}/pay/orderquery
|
||||
# \u5173\u95ed\u8ba2\u5355
|
||||
order_close_uri={mch_base_url}/pay/closeorder
|
||||
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
downloadbill_uri={mch_base_url}/pay/downloadbill
|
||||
# \u9000\u6b3e\u67e5\u8be2
|
||||
refund_query_uri={mch_base_url}/pay/refundquery
|
||||
# \u9000\u6b3e\u7533\u8bf7
|
||||
refund_apply_uri={mch_base_url}/secapi/pay/refund
|
||||
# \u51b2\u6b63\u64a4\u9500
|
||||
order_reverse_uri={mch_base_url}/secapi/pay/reverse
|
||||
# \u957f\u94fe\u63a5\u8f6c\u6362
|
||||
longurl_convert_uri={mch_base_url}/tools/shorturl
|
||||
# \u53d1\u653e\u4ee3\u91d1\u5238
|
||||
coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f
|
||||
couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f
|
||||
coupondetail_query_uri={mch_base_url}/promotion/query_coupon
|
||||
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
|
||||
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
|
||||
# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e
|
||||
corppayment_send_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
|
||||
# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2
|
||||
corppayment_query_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo
|
||||
# \u63a5\u53e3\u4e0a\u62a5
|
||||
interface_report_uri={mch_base_url}/payitil/report
|
||||
# \u6388\u6743\u7801\u67e5\u8be2OPENID\u63a5\u53e3
|
||||
authcode_openid_uri={mch_base_url}/tools/authcodetoopenid
|
||||
# native\u652f\u4ed8url(\u6a21\u5f0f1)
|
||||
native_pay_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s
|
||||
@ -0,0 +1,43 @@
|
||||
package com.foxinmy.weixin4j.sign;
|
||||
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
|
||||
/**
|
||||
* 微信签名
|
||||
*
|
||||
* @className AbstractWeixinSignature
|
||||
* @author jy
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public abstract class AbstractWeixinSignature implements WeixinSignature {
|
||||
/**
|
||||
* 是否编码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean encoder() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否转换小写
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean lowerCase() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接字符串
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
protected StringBuilder join(Object obj) {
|
||||
return new StringBuilder(MapUtil.toJoinString(obj, encoder(),
|
||||
lowerCase()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.foxinmy.weixin4j.sign;
|
||||
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
|
||||
/**
|
||||
* 微信支付签名实现
|
||||
*
|
||||
* @className WeixinPaymentSignature
|
||||
* @author jy
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class WeixinPaymentSignature extends AbstractWeixinSignature {
|
||||
/**
|
||||
* 支付密钥
|
||||
*/
|
||||
private final String paySignKey;
|
||||
|
||||
public WeixinPaymentSignature(String paySignKey) {
|
||||
this.paySignKey = paySignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sign(Object obj) {
|
||||
StringBuilder sb = join(obj).append("&key=").append(paySignKey);
|
||||
return DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.foxinmy.weixin4j.sign;
|
||||
|
||||
|
||||
/**
|
||||
* 微信签名
|
||||
*
|
||||
* @className WeixinSignature
|
||||
* @author jy
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface WeixinSignature {
|
||||
/**
|
||||
* 是否编码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean encoder();
|
||||
|
||||
/**
|
||||
* 是否转换小写
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean lowerCase();
|
||||
|
||||
/**
|
||||
* 签名
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public String sign(Object obj);
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.type;
|
||||
|
||||
/**
|
||||
* 签名类型
|
||||
*
|
||||
* @className SignType
|
||||
* @author jy
|
||||
* @date 2014年11月5日
|
||||
@ -9,5 +10,5 @@ package com.foxinmy.weixin4j.type;
|
||||
* @see
|
||||
*/
|
||||
public enum SignType {
|
||||
SHA1,MD5
|
||||
SHA1, MD5, HMAC$SHA256
|
||||
}
|
||||
|
||||
@ -1,16 +1,9 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 签名工具类
|
||||
@ -66,81 +59,4 @@ public final class DigestUtil {
|
||||
byte[] data = StringUtil.getBytesUtf8(content);
|
||||
return HexUtil.encodeHexString(getDigest(Consts.MD5).digest(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* md5签名(一般用于V3.x支付接口)
|
||||
*
|
||||
* @param obj
|
||||
* 签名对象
|
||||
* @param paySignKey
|
||||
* 支付API的密钥
|
||||
* @return
|
||||
*/
|
||||
public static String paysignMd5(Object obj, String paySignKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a--->string1
|
||||
sb.append(MapUtil.toJoinString(obj, false, false, null));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=paternerKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(paySignKey);
|
||||
return MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* sha签名(一般用于V2.x支付接口)
|
||||
*
|
||||
* @param obj
|
||||
* 签名对象
|
||||
* @param paySignKey
|
||||
* 支付API的密钥<font color="red">请注意排序放进去的是put("appKey",
|
||||
* paySignKey)</font>
|
||||
* @return
|
||||
*/
|
||||
public static String paysignSha(Object obj, String paySignKey) {
|
||||
Map<String, String> extra = new HashMap<String, String>();
|
||||
if (StringUtil.isNotBlank(paySignKey)) {
|
||||
extra.put("appKey", paySignKey);
|
||||
}
|
||||
return SHA1(MapUtil.toJoinString(obj, false, true, extra));
|
||||
}
|
||||
|
||||
/**
|
||||
* package拼接签名(一般用于V2.x支付接口)
|
||||
*
|
||||
* @param signObj
|
||||
* 签名对象 如 PayPackageV2
|
||||
* @param signKey
|
||||
* 签名key
|
||||
* @return
|
||||
*/
|
||||
public static String packageSign(Object signObj, String signKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a.对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) 后,
|
||||
// 使用 URL 键值 对的格式(即 key1=value1&key2=value2...)拼接成字符串 string1
|
||||
// 注意:值为空的参数不参与签名
|
||||
sb.append(MapUtil.toJoinString(signObj, false, false, null));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=signKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(signKey);
|
||||
// c---> & d---->
|
||||
String sign = DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
sb.delete(0, sb.length());
|
||||
// c.对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2
|
||||
sb.append(MapUtil.toJoinString(signObj, true, false, null))
|
||||
.append("&sign=").append(sign);
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ public class MapUtil {
|
||||
* @return
|
||||
*/
|
||||
public static String toJoinString(Object object, boolean encoder,
|
||||
boolean lowerCase, Map<String, String> extra) {
|
||||
boolean lowerCase) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
JSONObject obj = null;
|
||||
if (object instanceof String) {
|
||||
@ -46,14 +46,11 @@ public class MapUtil {
|
||||
for (String key : obj.keySet()) {
|
||||
map.put(key, obj.getString(key));
|
||||
}
|
||||
if (extra != null && !extra.isEmpty()) {
|
||||
map.putAll(extra);
|
||||
}
|
||||
return toJoinString(map, encoder, lowerCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接字符串
|
||||
* 拼接字符串
|
||||
*
|
||||
* @param map
|
||||
* 对象
|
||||
|
||||
@ -43,17 +43,17 @@ public class CashTest extends PayTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mpPayment() throws WeixinException, IOException {
|
||||
public void sendCorpPayment() throws WeixinException, IOException {
|
||||
CorpPayment payment = new CorpPayment("MP001",
|
||||
"ofW1gwok9vZIyle0YbA-eQe83Uk8",
|
||||
MPPaymentCheckNameType.NO_CHECK, "企业付款测试", 1d, "127.0.0.1");
|
||||
CorpPaymentResult result = PAY.corpPayment(new FileInputStream(caFile),
|
||||
CorpPaymentResult result = PAY.sendCorpPayment(new FileInputStream(caFile),
|
||||
payment);
|
||||
System.err.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mchPaymentQuery() throws WeixinException, IOException {
|
||||
public void queryCorpPayment() throws WeixinException, IOException {
|
||||
System.err.println(PAY.queryCorpPayment(new FileInputStream(caFile),
|
||||
"MP001"));
|
||||
}
|
||||
|
||||
@ -18,10 +18,13 @@ 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.payment.mch.RefundRecord;
|
||||
import com.foxinmy.weixin4j.payment.mch.RefundResult;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
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.Weixin4jSettings;
|
||||
|
||||
/**
|
||||
@ -34,10 +37,13 @@ import com.foxinmy.weixin4j.util.Weixin4jSettings;
|
||||
* @see
|
||||
*/
|
||||
public class PayTest {
|
||||
protected final static WeixinPayProxy PAY;
|
||||
protected final static WeixinPayAccount ACCOUNT;
|
||||
protected final static WeixinSignature SIGNATURE;
|
||||
protected final static WeixinPayProxy PAY;
|
||||
|
||||
static {
|
||||
ACCOUNT = new WeixinPayAccount("appid", "paySignKey", "mchid");
|
||||
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
|
||||
PAY = new WeixinPayProxy(new Weixin4jSettings(ACCOUNT));
|
||||
}
|
||||
/**
|
||||
@ -46,35 +52,34 @@ public class PayTest {
|
||||
protected File caFile = new File("证书文件:*.p12");
|
||||
|
||||
@Test
|
||||
public void orderQueryV3() throws WeixinException {
|
||||
Order order = PAY.orderQuery(new IdQuery("BY2016010800025",
|
||||
public void queryOrder() throws WeixinException {
|
||||
Order order = PAY.queryOrder(new IdQuery("BY2016010800025",
|
||||
IdType.TRADENO));
|
||||
System.err.println(order);
|
||||
String sign = order.getSign();
|
||||
order.setSign(null);
|
||||
String valiSign = DigestUtil.paysignMd5(order, ACCOUNT.getPaySignKey());
|
||||
String valiSign = SIGNATURE.sign(order);
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundQueryV3() throws WeixinException {
|
||||
com.foxinmy.weixin4j.payment.mch.RefundRecord record = PAY
|
||||
.refundQuery(new IdQuery("TT_1427183696238", IdType.TRADENO));
|
||||
public void queryRefund() throws WeixinException {
|
||||
RefundRecord record = PAY.queryRefund(new IdQuery("TT_1427183696238",
|
||||
IdType.TRADENO));
|
||||
System.err.println(record);
|
||||
// 这里的验证签名需要把details循环拼接
|
||||
String sign = record.getSign();
|
||||
record.setSign(null);
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(record, ACCOUNT.getPaySignKey());
|
||||
String valiSign = SIGNATURE.sign(record);
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downbillV3() throws WeixinException {
|
||||
public void downbill() throws WeixinException {
|
||||
Calendar c = Calendar.getInstance();
|
||||
System.err.println(c.getTime());
|
||||
c.set(Calendar.YEAR, 2015);
|
||||
@ -86,24 +91,22 @@ public class PayTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundV3() throws WeixinException, IOException {
|
||||
public void refund() throws WeixinException, IOException {
|
||||
IdQuery idQuery = new IdQuery("TT_1427183696238", IdType.TRADENO);
|
||||
com.foxinmy.weixin4j.payment.mch.RefundResult result = PAY.refundApply(
|
||||
new FileInputStream(caFile), idQuery,
|
||||
"TT_R" + System.currentTimeMillis(), 0.01d, 0.01d, null,
|
||||
"10020674");
|
||||
RefundResult result = PAY.applyRefund(new FileInputStream(caFile),
|
||||
idQuery, "TT_R" + System.currentTimeMillis(), 0.01d, 0.01d,
|
||||
null, "10020674");
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(result, ACCOUNT.getPaySignKey());
|
||||
String valiSign = SIGNATURE.sign(result);
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeV3() throws WeixinException {
|
||||
public void nativePay() throws WeixinException {
|
||||
MchPayPackage payPackageV3 = new MchPayPackage(ACCOUNT,
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", "native测试", "T0001", 0.1d,
|
||||
"notify_url", "127.0.0.1", TradeType.NATIVE);
|
||||
@ -123,8 +126,7 @@ public class PayTest {
|
||||
System.err.println(result);
|
||||
String sign = result.getSign();
|
||||
result.setSign(null);
|
||||
String valiSign = DigestUtil
|
||||
.paysignMd5(result, ACCOUNT.getPaySignKey());
|
||||
String valiSign = SIGNATURE.sign(result);
|
||||
System.err
|
||||
.println(String.format("sign=%s,valiSign=%s", sign, valiSign));
|
||||
Assert.assertEquals(valiSign, sign);
|
||||
|
||||
@ -34,12 +34,15 @@ import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayOldAccount;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.OrderV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.OrderV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.PayPackageV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.RefundResultV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.WeixinOldPaymentSignature;
|
||||
import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
|
||||
import com.foxinmy.weixin4j.sign.WeixinSignature;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
@ -58,7 +61,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
/**
|
||||
* V2老支付API
|
||||
*
|
||||
* @className Pay2Api
|
||||
* @className PayOldApi
|
||||
* @author jy
|
||||
* @date 2014年10月28日
|
||||
* @since JDK 1.6
|
||||
@ -66,8 +69,10 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
*/
|
||||
public class PayOldApi extends MpApi {
|
||||
|
||||
private final WeixinPayOldAccount payAccount;
|
||||
private final WeixinPayOldAccount weixinAccount;
|
||||
private final TokenHolder tokenHolder;
|
||||
private final WeixinSignature weixinMD5Signature;
|
||||
private final WeixinOldPaymentSignature weixinOldSignature;
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置信息
|
||||
@ -90,14 +95,19 @@ public class PayOldApi extends MpApi {
|
||||
WeixinPayOldAccount.class), tokenStorager);
|
||||
}
|
||||
|
||||
public PayOldApi(WeixinPayOldAccount payAccount, TokenStorager tokenStorager) {
|
||||
this.payAccount = payAccount;
|
||||
public PayOldApi(WeixinPayOldAccount weixinAccount,
|
||||
TokenStorager tokenStorager) {
|
||||
this.weixinAccount = weixinAccount;
|
||||
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
payAccount.getId(), payAccount.getSecret()), tokenStorager);
|
||||
weixinAccount.getId(), weixinAccount.getSecret()),
|
||||
tokenStorager);
|
||||
this.weixinMD5Signature = new WeixinPaymentSignature(
|
||||
weixinAccount.getPartnerKey());
|
||||
this.weixinOldSignature = new WeixinOldPaymentSignature();
|
||||
}
|
||||
|
||||
public WeixinPayOldAccount getPayAccount() {
|
||||
return this.payAccount;
|
||||
return this.weixinAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,10 +172,10 @@ public class PayOldApi extends MpApi {
|
||||
payPackage.setProductFee(productFee);
|
||||
payPackage.setGoodsTag(goodsTag);
|
||||
PayRequest payRequest = new PayRequest(getPayAccount().getId(),
|
||||
DigestUtil.packageSign(payPackage, getPayAccount()
|
||||
weixinOldSignature.sign(payPackage, getPayAccount()
|
||||
.getPartnerKey()));
|
||||
payRequest.setPaySign(DigestUtil.paysignSha(payRequest, getPayAccount()
|
||||
.getPaySignKey()));
|
||||
payRequest.setPaySign(weixinOldSignature.sign(payRequest,
|
||||
getPayAccount().getPaySignKey()));
|
||||
payRequest.setSignType(SignType.SHA1);
|
||||
return JSON.toJSONString(payRequest);
|
||||
}
|
||||
@ -186,9 +196,9 @@ public class PayOldApi extends MpApi {
|
||||
map.put("noncestr", noncestr);
|
||||
map.put("productid", productId);
|
||||
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, getPayAccount().getId(),
|
||||
String sign = weixinOldSignature.sign(map);
|
||||
String nativepay_uri = getRequestUri("nativepay_old_uri");
|
||||
return String.format(nativepay_uri, sign, getPayAccount().getId(),
|
||||
productId, timestamp, noncestr);
|
||||
}
|
||||
|
||||
@ -198,12 +208,12 @@ public class PayOldApi extends MpApi {
|
||||
* @param idQuery
|
||||
* 订单号
|
||||
* @return 订单信息
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.OrderV2
|
||||
* @see com.foxinmy.weixin4j.mp.oldpayment.OrderV2
|
||||
* @since V2
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OrderV2 orderQuery(IdQuery idQuery) throws WeixinException {
|
||||
String orderquery_uri = getRequestUri("orderquery_v2_uri");
|
||||
public OrderV2 queryOrder(IdQuery idQuery) throws WeixinException {
|
||||
String orderquery_uri = getRequestUri("orderquery_old_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(idQuery.getType().getName()).append("=")
|
||||
@ -221,7 +231,7 @@ public class PayOldApi extends MpApi {
|
||||
obj.put("appkey", getPayAccount().getPaySignKey());
|
||||
obj.put("package", sb.toString());
|
||||
obj.put("timestamp", timestamp);
|
||||
String signature = DigestUtil.paysignSha(obj, null);
|
||||
String signature = weixinOldSignature.sign(obj);
|
||||
|
||||
obj.clear();
|
||||
obj.put("appid", getPayAccount().getId());
|
||||
@ -251,7 +261,7 @@ public class PayOldApi extends MpApi {
|
||||
* 败后重新提交,要采用原来的 out_refund_no。总退款金额不能超过用户实际支付金额。</br>
|
||||
* </p>
|
||||
*
|
||||
* @param caFile
|
||||
* @param certificate
|
||||
* 证书文件(V2版本后缀为*.pfx)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -268,18 +278,17 @@ public class PayOldApi extends MpApi {
|
||||
* 如 opUserPasswd
|
||||
*
|
||||
* @return 退款申请结果
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundResultV2
|
||||
* @see com.foxinmy.weixin4j.mp.oldpayment.RefundResultV2
|
||||
* @since V2
|
||||
* @throws WeixinException
|
||||
*/
|
||||
protected RefundResultV2 refundApply(File caFile, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, Map<String, String> mopara) throws WeixinException {
|
||||
String refund_uri = getRequestUri("refundapply_v2_uri");
|
||||
protected RefundResultV2 applyRefund(InputStream certificate,
|
||||
IdQuery idQuery, String outRefundNo, double totalFee,
|
||||
double refundFee, String opUserId, Map<String, String> mopara)
|
||||
throws WeixinException {
|
||||
String refund_uri = getRequestUri("refundapply_old_uri");
|
||||
WeixinResponse response = null;
|
||||
InputStream ca = null;
|
||||
try {
|
||||
ca = new FileInputStream(caFile);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("input_charset", Consts.UTF_8.name());
|
||||
// 版本号
|
||||
@ -298,24 +307,23 @@ public class PayOldApi extends MpApi {
|
||||
if (mopara != null && !mopara.isEmpty()) {
|
||||
map.putAll(mopara);
|
||||
}
|
||||
String sign = DigestUtil.paysignMd5(map, getPayAccount()
|
||||
.getPartnerKey());
|
||||
String sign = weixinMD5Signature.sign(map);
|
||||
map.put("sign", sign.toUpperCase());
|
||||
|
||||
SSLContext ctx = null;
|
||||
KeyStore ks = null;
|
||||
String jksPwd = "";
|
||||
File jksFile = new File(String.format("%s/tenpay_cacert.jks",
|
||||
caFile.getParent()));
|
||||
Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
|
||||
System.getProperty("java.io.tmpdir"))));
|
||||
// create jks ca
|
||||
if (!jksFile.exists()) {
|
||||
CertificateFactory cf = CertificateFactory
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.X509);
|
||||
.getInstance(Consts.X509);
|
||||
java.security.cert.Certificate cert = cf
|
||||
.generateCertificate(PayOldApi.class
|
||||
.getResourceAsStream("cacert.pem"));
|
||||
ks = KeyStore
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.JKS);
|
||||
ks = KeyStore.getInstance(Consts.JKS);
|
||||
ks.load(null, null);
|
||||
ks.setCertificateEntry("tenpay", cert);
|
||||
FileOutputStream os = new FileOutputStream(jksFile);
|
||||
@ -324,20 +332,20 @@ public class PayOldApi extends MpApi {
|
||||
}
|
||||
// load jks ca
|
||||
TrustManagerFactory tmf = TrustManagerFactory
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
|
||||
ks = KeyStore.getInstance(com.foxinmy.weixin4j.model.Consts.JKS);
|
||||
.getInstance(Consts.SunX509);
|
||||
ks = KeyStore.getInstance(Consts.JKS);
|
||||
FileInputStream is = new FileInputStream(jksFile);
|
||||
ks.load(is, jksPwd.toCharArray());
|
||||
tmf.init(ks);
|
||||
is.close();
|
||||
// load pfx ca
|
||||
KeyManagerFactory kmf = KeyManagerFactory
|
||||
.getInstance(com.foxinmy.weixin4j.model.Consts.SunX509);
|
||||
ks = KeyStore.getInstance(com.foxinmy.weixin4j.model.Consts.PKCS12);
|
||||
ks.load(ca, getPayAccount().getPartnerId().toCharArray());
|
||||
.getInstance(Consts.SunX509);
|
||||
ks = KeyStore.getInstance(Consts.PKCS12);
|
||||
ks.load(certificate, getPayAccount().getPartnerId().toCharArray());
|
||||
kmf.init(ks, getPayAccount().getPartnerId().toCharArray());
|
||||
|
||||
ctx = SSLContext.getInstance(com.foxinmy.weixin4j.model.Consts.TLS);
|
||||
ctx = SSLContext.getInstance(Consts.TLS);
|
||||
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
|
||||
new SecureRandom());
|
||||
|
||||
@ -349,9 +357,9 @@ public class PayOldApi extends MpApi {
|
||||
} catch (Exception e) {
|
||||
throw new WeixinException(e);
|
||||
} finally {
|
||||
if (ca != null) {
|
||||
if (certificate != null) {
|
||||
try {
|
||||
ca.close();
|
||||
certificate.close();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
@ -364,7 +372,7 @@ public class PayOldApi extends MpApi {
|
||||
/**
|
||||
* 退款申请
|
||||
*
|
||||
* @param caFile
|
||||
* @param certificate
|
||||
* 证书文件(V2版本后缀为*.pfx)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -379,21 +387,21 @@ public class PayOldApi extends MpApi {
|
||||
* 操作员帐号, 默认为商户号
|
||||
* @param opUserPasswd
|
||||
* 操作员密码,默认为商户后台登录密码
|
||||
* @see {@link #refundApply(File, IdQuery, String, double, double, String, Map)}
|
||||
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String, Map)}
|
||||
*/
|
||||
public RefundResultV2 refundApply(File caFile, IdQuery idQuery,
|
||||
public RefundResultV2 applyRefund(InputStream certificate, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, String opUserPasswd) throws WeixinException {
|
||||
Map<String, String> mopara = new HashMap<String, String>();
|
||||
mopara.put("op_user_passwd", DigestUtil.MD5(opUserPasswd));
|
||||
return refundApply(caFile, idQuery, outRefundNo, totalFee, refundFee,
|
||||
opUserId, mopara);
|
||||
return applyRefund(certificate, idQuery, outRefundNo, totalFee,
|
||||
refundFee, opUserId, mopara);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款申请
|
||||
*
|
||||
* @param caFile
|
||||
* @param certificate
|
||||
* 证书文件(V2版本后缀为*.pfx)
|
||||
* @param idQuery
|
||||
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
|
||||
@ -417,10 +425,10 @@ public class PayOldApi extends MpApi {
|
||||
* @param refundType
|
||||
* 为空或者填 1:商户号余额退款;2:现金帐号 退款;3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。使用 2 或
|
||||
* 3 时,需联系财 付通开通此功能
|
||||
* @see {@link #refundApply(File, IdQuery, String, double, double, String, Map)}
|
||||
* @see {@link #applyRefund(InputStream, IdQuery, String, double, double, String, Map)}
|
||||
* @return 退款结果
|
||||
*/
|
||||
public RefundResultV2 refundApply(File caFile, IdQuery idQuery,
|
||||
public RefundResultV2 applyRefund(InputStream certificate, IdQuery idQuery,
|
||||
String outRefundNo, double totalFee, double refundFee,
|
||||
String opUserId, String opUserPasswd, String recvUserId,
|
||||
String reccvUserName, RefundType refundType) throws WeixinException {
|
||||
@ -435,8 +443,8 @@ public class PayOldApi extends MpApi {
|
||||
if (refundType != null) {
|
||||
mopara.put("refund_type", Integer.toString(refundType.getVal()));
|
||||
}
|
||||
return refundApply(caFile, idQuery, outRefundNo, totalFee, refundFee,
|
||||
opUserId, mopara);
|
||||
return applyRefund(certificate, idQuery, outRefundNo, totalFee,
|
||||
refundFee, opUserId, mopara);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -474,7 +482,7 @@ public class PayOldApi extends MpApi {
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
String downloadbill_uri = getRequestUri("downloadbill_v2_uri");
|
||||
String downloadbill_uri = getRequestUri("downloadbill_old_uri");
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<String, String>();
|
||||
map.put("spid", getPayAccount().getPartnerId());
|
||||
@ -523,19 +531,18 @@ public class PayOldApi extends MpApi {
|
||||
* 四个参数必填一个,优先级为:
|
||||
* refund_id>out_refund_no>transaction_id>out_trade_no
|
||||
* @return 退款记录
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetailV2
|
||||
* @see com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2
|
||||
* @see com.foxinmy.weixin4j.mp.oldpayment.RefundDetailV2
|
||||
* @since V2
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public RefundRecordV2 refundQuery(IdQuery idQuery) throws WeixinException {
|
||||
String refundquery_uri = getRequestUri("refundquery_v2_uri");
|
||||
public RefundRecordV2 queryRefund(IdQuery idQuery) throws WeixinException {
|
||||
String refundquery_uri = getRequestUri("refundquery_old_uri");
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("input_charset", Consts.UTF_8.name());
|
||||
map.put("partner", getPayAccount().getPartnerId());
|
||||
map.put(idQuery.getType().getName(), idQuery.getId());
|
||||
String sign = DigestUtil.paysignMd5(map, getPayAccount()
|
||||
.getPartnerKey());
|
||||
String sign = weixinMD5Signature.sign(map);
|
||||
map.put("sign", sign.toLowerCase());
|
||||
WeixinResponse response = weixinExecutor.get(refundquery_uri, map);
|
||||
return ListsuffixResultDeserializer.deserialize(response.getAsString(),
|
||||
@ -561,7 +568,7 @@ public class PayOldApi extends MpApi {
|
||||
public JsonResult deliverNotify(String openId, String transid,
|
||||
String outTradeNo, boolean status, String statusMsg)
|
||||
throws WeixinException {
|
||||
String delivernotify_uri = getRequestUri("delivernotify_uri");
|
||||
String delivernotify_uri = getRequestUri("delivernotify_old_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
@ -573,7 +580,7 @@ public class PayOldApi extends MpApi {
|
||||
map.put("deliver_timestamp", DateUtil.timestamp2string());
|
||||
map.put("deliver_status", status ? "1" : "0");
|
||||
map.put("deliver_msg", statusMsg);
|
||||
map.put("app_signature", DigestUtil.paysignSha(map, null));
|
||||
map.put("app_signature", weixinOldSignature.sign(map));
|
||||
map.put("sign_method", SignType.SHA1.name().toLowerCase());
|
||||
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
@ -594,11 +601,10 @@ public class PayOldApi extends MpApi {
|
||||
*/
|
||||
public JsonResult updateFeedback(String openId, String feedbackId)
|
||||
throws WeixinException {
|
||||
String payfeedback_update_uri = getRequestUri("payfeedback_update_uri");
|
||||
String payfeedback_uri = getRequestUri("payfeedback_old_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinExecutor.get(String.format(
|
||||
payfeedback_update_uri, token.getAccessToken(), openId,
|
||||
feedbackId));
|
||||
payfeedback_uri, token.getAccessToken(), openId, feedbackId));
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,12 +6,10 @@
|
||||
api_base_url=https://api.weixin.qq.com
|
||||
api_cgi_url={api_base_url}/cgi-bin
|
||||
mp_base_url=https://mp.weixin.qq.com/cgi-bin
|
||||
mch_base_url=https://api.mch.weixin.qq.com
|
||||
tenpay_base_url=http://mch.tenpay.com
|
||||
tenpay_ssl_base_url=https://mch.tenpay.com
|
||||
tenpay_gw_base_url=https://gw.tenpay.com
|
||||
|
||||
|
||||
# \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f
|
||||
sns_user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
|
||||
#open_user_auth_uri=https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
|
||||
@ -107,7 +105,6 @@ kfsession_list_uri={api_base_url}/customservice/kfsession/getsessionlist?access_
|
||||
kfsession_wait_uri={api_base_url}/customservice/kfsession/getwaitcase?access_token=%s
|
||||
# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5
|
||||
shorturl_uri={api_cgi_url}/shorturl?access_token=%s
|
||||
p_shorturl_uri={mch_base_url}/tools/shorturl
|
||||
# \u8bbe\u7f6e\u5907\u6ce8\u540d
|
||||
updateremark_uri={api_cgi_url}/user/info/updateremark?access_token=%s
|
||||
# \u8bbe\u7f6e\u6a21\u677f\u6d88\u606f\u6240\u5904\u884c\u4e1a
|
||||
@ -126,48 +123,26 @@ template_send_uri={api_cgi_url}/message/template/send?access_token=%s
|
||||
semantic_uri={api_base_url}/semantic/semproxy/search?access_token=%s
|
||||
# \u5fae\u4fe1\u670d\u52a1\u5730\u5740
|
||||
getcallbackip_uri={api_cgi_url}/getcallbackip?access_token=%s
|
||||
|
||||
# v2\u8ba2\u5355\u67e5\u8be2
|
||||
orderquery_v2_uri={api_base_url}/pay/orderquery?access_token=%s
|
||||
# v2native\u652f\u4ed8
|
||||
ordernative_v2_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&nocestr=%s\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc53\udbff\udc53\udbff\udc53\udbff\udc53\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udce0\udbff\udc76\udbff\udc76\udbff\udc76\udbff\udc76\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcde\udbff\udcde\udbff\udcde\udbff\udcde\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udcdf\udbff\udcdf\udbff\udcdf\udbff\udcdf\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc69\udbff\udc77\udbff\udc77\udbff\udc77\udbff\udc77\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc57\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc71\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc54\udbff\udc68\udbff\udc68\udbff\udc68\udbff\udc68\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdc\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd\udbff\udcdd
|
||||
# \u53d1\u8d27\u901a\u77e5
|
||||
delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s
|
||||
# \u7ef4\u6743\u5904\u7406
|
||||
payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
|
||||
# v2\u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
downloadbill_v2_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi
|
||||
# v2\u9000\u6b3e\u67e5\u8be2
|
||||
refundquery_v2_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml
|
||||
# v2\u9000\u6b3e\u7533\u8bf7
|
||||
refundapply_v2_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml
|
||||
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
orderquery_v3_uri={mch_base_url}/pay/orderquery
|
||||
# \u5173\u95ed\u8ba2\u5355
|
||||
closeorder_uri={mch_base_url}/pay/closeorder
|
||||
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
downloadbill_v3_uri={mch_base_url}/pay/downloadbill
|
||||
# \u9000\u6b3e\u67e5\u8be2
|
||||
refundquery_v3_uri={mch_base_url}/pay/refundquery
|
||||
# \u9000\u6b3e\u7533\u8bf7
|
||||
refund_v3_uri={mch_base_url}/secapi/pay/refund
|
||||
# \u51b2\u6b63\u64a4\u9500
|
||||
reverse_uri={mch_base_url}/secapi/pay/reverse
|
||||
# \u88ab\u626b\u652f\u4ed8
|
||||
micropay_uri={mch_base_url}/pay/micropay
|
||||
# \u63a5\u53e3\u4e0a\u62a5
|
||||
pay_report_uri={mch_base_url}/payitil/report
|
||||
|
||||
# \u7edf\u4e00\u8ba2\u5355\u751f\u6210
|
||||
unifiedorder_uri={mch_base_url}/pay/unifiedorder
|
||||
# native\u652f\u4ed8\u94fe\u63a5
|
||||
nativepay_v2_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s
|
||||
nativepay_v3_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s
|
||||
|
||||
# \u6570\u636e\u7edf\u8ba1
|
||||
datacube_uri={api_base_url}/datacube/%s?access_token=%s
|
||||
|
||||
##########################\u8001\u7248\u672c\u652f\u4ed8~start
|
||||
# \u8ba2\u5355\u67e5\u8be2
|
||||
orderquery_old_uri={api_base_url}/pay/orderquery?access_token=%s
|
||||
# \u53d1\u8d27\u901a\u77e5
|
||||
delivernotify_old_uri={api_base_url}/pay/delivernotify?access_token=%s
|
||||
# \u7ef4\u6743\u5904\u7406
|
||||
payfeedback_old_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s
|
||||
# \u5bf9\u8d26\u5355\u4e0b\u8f7d
|
||||
downloadbill_old_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi
|
||||
# \u9000\u6b3e\u67e5\u8be2
|
||||
refundquery_old_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml
|
||||
# \u9000\u6b3e\u7533\u8bf7
|
||||
refundapply_old_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml
|
||||
# native\u652f\u4ed8
|
||||
nativepay_old_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s
|
||||
##########################\u8001\u7248\u672c\u652f\u4ed8~end
|
||||
|
||||
# \u4e0a\u4f20\u6c38\u4e45\u56fe\u6587\u7d20\u6750
|
||||
material_article_upload_uri={api_cgi_url}/material/add_news?access_token=%s
|
||||
# \u4e0a\u4f20\u6c38\u4e45\u5a92\u4f53\u7d20\u6750
|
||||
@ -184,18 +159,3 @@ material_media_count_uri={api_cgi_url}/material/get_materialcount?access_token=%
|
||||
material_media_list_uri={api_cgi_url}/material/batchget_material?access_token=%s
|
||||
# \u81ea\u52a8\u56de\u590d\u89c4\u5219
|
||||
autoreply_setting_get_uri={api_cgi_url}/get_current_autoreply_info?access_token=%s
|
||||
|
||||
# \u53d1\u653e\u4ee3\u91d1\u5238
|
||||
coupon_send_uri={mch_base_url}/mmpaymkttransfers/send_coupon
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u6279\u6b21\u4fe1\u606f
|
||||
couponstock_query_uri={mch_base_url}/mmpaymkttransfers/query_coupon_stock
|
||||
# \u67e5\u8be2\u4ee3\u91d1\u5238\u8be6\u7ec6\u4fe1\u606f
|
||||
coupondetail_query_uri={mch_base_url}/promotion/query_coupon
|
||||
# \u53d1\u9001\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_send_uri={mch_base_url}/mmpaymkttransfers/sendredpack
|
||||
# \u67e5\u8be2\u73b0\u91d1\u7ea2\u5305
|
||||
redpack_query_uri={mch_base_url}/mmpaymkttransfers/gethbinfo
|
||||
# \u4f01\u4e1a\u5411\u4e2a\u4eba\u4ed8\u6b3e
|
||||
mp_payment_uri={mch_base_url}/mmpaymkttransfers/promotion/transfers
|
||||
# \u4f01\u4e1a\u4ed8\u6b3e\u67e5\u8be2
|
||||
mp_payquery_uri={mch_base_url}/mmpaymkttransfers/gettransferinfo
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -11,7 +11,6 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.model.WeixinPayOldAccount;
|
||||
import com.foxinmy.weixin4j.payment.PayRequest;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
|
||||
/**
|
||||
* V2 Native支付时的回调响应
|
||||
@ -64,10 +63,12 @@ public class NativePayResponseV2 extends PayRequest {
|
||||
*/
|
||||
public NativePayResponseV2(WeixinPayOldAccount weixinAccount,
|
||||
PayPackageV2 payPackage) {
|
||||
super(weixinAccount.getId(), DigestUtil.packageSign(payPackage,
|
||||
weixinAccount.getPartnerKey()));
|
||||
super(weixinAccount.getId(), null);
|
||||
this.retCode = "0";
|
||||
this.retMsg = "OK";
|
||||
WeixinOldPaymentSignature weixinSignature = new WeixinOldPaymentSignature();
|
||||
setPackageInfo(weixinSignature.sign(payPackage,
|
||||
weixinAccount.getPartnerKey()));
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("appid", weixinAccount.getId());
|
||||
map.put("appkey", weixinAccount.getPaySignKey());
|
||||
@ -76,7 +77,7 @@ public class NativePayResponseV2 extends PayRequest {
|
||||
map.put("package", getPackageInfo());
|
||||
map.put("retcode", getRetCode());
|
||||
map.put("reterrmsg", getRetMsg());
|
||||
this.setPaySign(DigestUtil.paysignSha(map, null));
|
||||
this.setPaySign(weixinSignature.sign(map));
|
||||
}
|
||||
|
||||
public String getRetCode() {
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResult;
|
||||
* @author jy
|
||||
* @date 2014年11月1日
|
||||
* @since JDK 1.6
|
||||
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundDetailV2
|
||||
* @see com.foxinmy.weixin4j.mp.oldpayment.RefundDetailV2
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@ -1,4 +1,4 @@
|
||||
package com.foxinmy.weixin4j.mp.payment.v2;
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
@ -0,0 +1,70 @@
|
||||
package com.foxinmy.weixin4j.mp.oldpayment;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONPath;
|
||||
import com.foxinmy.weixin4j.sign.AbstractWeixinSignature;
|
||||
import com.foxinmy.weixin4j.util.DigestUtil;
|
||||
import com.foxinmy.weixin4j.util.MapUtil;
|
||||
|
||||
/**
|
||||
* 老版本支付签名
|
||||
*
|
||||
* @className WeixinOldPaymentSignature
|
||||
* @author jy
|
||||
* @date 2016年3月26日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class WeixinOldPaymentSignature extends AbstractWeixinSignature {
|
||||
|
||||
@Override
|
||||
public boolean lowerCase() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sign(Object obj) {
|
||||
return DigestUtil.SHA1(join(obj).toString());
|
||||
}
|
||||
|
||||
public String sign(Object obj, String paySignKey) {
|
||||
if (obj instanceof Map) {
|
||||
JSONPath.set(obj, "appKey", paySignKey);
|
||||
} else {
|
||||
((JSONObject) JSON.toJSON(obj)).put("appKey", paySignKey);
|
||||
}
|
||||
return DigestUtil.SHA1(join(obj).toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* package拼接签名
|
||||
*
|
||||
* @param packageInfo
|
||||
* package对象
|
||||
* @param partnerKey
|
||||
* 签名key
|
||||
* @return
|
||||
*/
|
||||
public String sign(PayPackageV2 packageInfo, String partnerKey) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// a.对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) 后,
|
||||
// 使用 URL 键值 对的格式(即 key1=value1&key2=value2...)拼接成字符串 string1
|
||||
// 注意:值为空的参数不参与签名
|
||||
sb.append(MapUtil.toJoinString(packageInfo, false, false));
|
||||
// b--->
|
||||
// 在 string1 最后拼接上 key=signKey 得到 stringSignTemp 字符串,并 对
|
||||
// stringSignTemp 进行 md5 运算
|
||||
// 再将得到的 字符串所有字符转换为大写 ,得到 sign 值 signValue。
|
||||
sb.append("&key=").append(partnerKey);
|
||||
// c---> & d---->
|
||||
String sign = DigestUtil.MD5(sb.toString()).toUpperCase();
|
||||
sb.delete(0, sb.length());
|
||||
// c.对传入参数中所有键值对的 value 进行 urlencode 转码后重新拼接成字符串 string2
|
||||
sb.append(MapUtil.toJoinString(packageInfo, true, false))
|
||||
.append("&sign=").append(sign);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
package com.foxinmy.weixin4j.mp.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -36,20 +38,21 @@ public class PayTest {
|
||||
|
||||
@Test
|
||||
public void orderQueryV2() throws WeixinException {
|
||||
System.err.println(PAY2.orderQuery(new IdQuery("D14110500021",
|
||||
System.err.println(PAY2.queryOrder(new IdQuery("D14110500021",
|
||||
IdType.REFUNDNO)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundV2() throws WeixinException {
|
||||
public void refundV2() throws WeixinException, IOException {
|
||||
IdQuery idQuery = new IdQuery("D15020300005", IdType.TRADENO);
|
||||
System.err.println(PAY2.refundApply(caFile, idQuery, "1422925555037",
|
||||
16d, 16d, "1221928801", "111111", null, null, null));
|
||||
System.err.println(PAY2.applyRefund(new FileInputStream(caFile),
|
||||
idQuery, "1422925555037", 16d, 16d, "1221928801", "111111",
|
||||
null, null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refundQueryV2() throws WeixinException {
|
||||
System.err.println(PAY2.refundQuery(new IdQuery("D14123000004",
|
||||
System.err.println(PAY2.queryRefund(new IdQuery("D14123000004",
|
||||
IdType.TRADENO)));
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.mp.oldpayment.RefundRecordV2;
|
||||
import com.foxinmy.weixin4j.payment.mch.Order;
|
||||
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
@ -14,10 +14,10 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
@ -88,7 +88,7 @@ public class WeixinMessageDispatcher {
|
||||
/**
|
||||
* 消息转换
|
||||
*/
|
||||
private ThreadLocal<Map<Class<? extends WeixinMessage>, Unmarshaller>> messageUnmarshaller;
|
||||
private Map<Class<? extends WeixinMessage>, Unmarshaller> messageUnmarshaller;
|
||||
/**
|
||||
* 是否总是响应请求,如未匹配到MessageHandler时回复空白消息
|
||||
*/
|
||||
@ -100,12 +100,7 @@ public class WeixinMessageDispatcher {
|
||||
|
||||
public WeixinMessageDispatcher(WeixinMessageMatcher messageMatcher) {
|
||||
this.messageMatcher = messageMatcher;
|
||||
this.messageUnmarshaller = new ThreadLocal<Map<Class<? extends WeixinMessage>, Unmarshaller>>() {
|
||||
@Override
|
||||
protected Map<Class<? extends WeixinMessage>, Unmarshaller> initialValue() {
|
||||
return new HashMap<Class<? extends WeixinMessage>, Unmarshaller>();
|
||||
}
|
||||
};
|
||||
this.messageUnmarshaller = new ConcurrentHashMap<Class<? extends WeixinMessage>, Unmarshaller>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +120,8 @@ public class WeixinMessageDispatcher {
|
||||
WeixinMessageKey messageKey = defineMessageKey(messageTransfer, request);
|
||||
Class<? extends WeixinMessage> targetClass = messageMatcher
|
||||
.match(messageKey);
|
||||
WeixinMessage message = messageRead(request.getOriginalContent(), targetClass);
|
||||
WeixinMessage message = messageRead(request.getOriginalContent(),
|
||||
targetClass);
|
||||
logger.info("define '{}' matched '{}'", messageKey, targetClass);
|
||||
MessageHandlerExecutor handlerExecutor = getHandlerExecutor(context,
|
||||
request, messageKey, message, messageTransfer.getNodeNames());
|
||||
@ -179,6 +175,7 @@ public class WeixinMessageDispatcher {
|
||||
*/
|
||||
protected void noHandlerFound(ChannelHandlerContext context,
|
||||
WeixinRequest request, Object message) {
|
||||
logger.warn("no handler found {}", request);
|
||||
if (alwaysResponse) {
|
||||
context.write(BlankResponse.global);
|
||||
} else {
|
||||
@ -209,13 +206,13 @@ public class WeixinMessageDispatcher {
|
||||
*/
|
||||
protected MessageHandlerExecutor getHandlerExecutor(
|
||||
ChannelHandlerContext context, WeixinRequest request,
|
||||
WeixinMessageKey messageKey, WeixinMessage message, Set<String> nodeNames)
|
||||
throws WeixinException {
|
||||
WeixinMessageKey messageKey, WeixinMessage message,
|
||||
Set<String> nodeNames) throws WeixinException {
|
||||
WeixinMessageHandler[] messageHandlers = getMessageHandlers();
|
||||
if (messageHandlers == null) {
|
||||
return null;
|
||||
}
|
||||
logger.info("resolve handlers '{}'", this.messageHandlerList);
|
||||
logger.info("resolve message handlers '{}'", this.messageHandlerList);
|
||||
List<WeixinMessageHandler> matchedMessageHandlers = new ArrayList<WeixinMessageHandler>();
|
||||
for (WeixinMessageHandler handler : messageHandlers) {
|
||||
if (handler.canHandle(request, message, nodeNames)) {
|
||||
@ -233,7 +230,7 @@ public class WeixinMessageDispatcher {
|
||||
return m2.weight() - m1.weight();
|
||||
}
|
||||
});
|
||||
logger.info("matched message handlers '{}'", matchedMessageHandlers);
|
||||
logger.info("matched message handler '{}'", matchedMessageHandlers);
|
||||
return new MessageHandlerExecutor(context,
|
||||
matchedMessageHandlers.get(0), getMessageInterceptors());
|
||||
}
|
||||
@ -367,6 +364,8 @@ public class WeixinMessageDispatcher {
|
||||
.size()]);
|
||||
}
|
||||
}
|
||||
logger.info("resolve message interceptors '{}'",
|
||||
this.messageInterceptorList);
|
||||
return this.messageInterceptors;
|
||||
}
|
||||
|
||||
@ -406,12 +405,12 @@ public class WeixinMessageDispatcher {
|
||||
*/
|
||||
protected Unmarshaller getUnmarshaller(Class<? extends WeixinMessage> clazz)
|
||||
throws WeixinException {
|
||||
Unmarshaller unmarshaller = messageUnmarshaller.get().get(clazz);
|
||||
Unmarshaller unmarshaller = messageUnmarshaller.get(clazz);
|
||||
if (unmarshaller == null) {
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
|
||||
unmarshaller = jaxbContext.createUnmarshaller();
|
||||
messageUnmarshaller.get().put(clazz, unmarshaller);
|
||||
messageUnmarshaller.put(clazz, unmarshaller);
|
||||
} catch (JAXBException e) {
|
||||
throw new WeixinException(e);
|
||||
}
|
||||
|
||||
@ -87,6 +87,7 @@ public class WeixinMessageDecoder extends
|
||||
messageContent = MessageUtil.aesDecrypt(aesToken.getWeixinId(),
|
||||
aesToken.getAesKey(), encryptContent);
|
||||
}
|
||||
logger.info("read original message {}", messageContent);
|
||||
WeixinRequest request = new WeixinRequest(req.headers(), method,
|
||||
req.getUri(), encryptType, echoStr, timeStamp, nonce,
|
||||
signature, msgSignature, messageContent, encryptContent,
|
||||
|
||||
@ -233,6 +233,9 @@ public final class WeixinServerBootstrap {
|
||||
*/
|
||||
public WeixinServerBootstrap addHandler(
|
||||
WeixinMessageHandler... messageHandler) {
|
||||
if (messageHandler == null) {
|
||||
throw new IllegalArgumentException("messageHandler not be null");
|
||||
}
|
||||
messageHandlerList.addAll(Arrays.asList(messageHandler));
|
||||
return this;
|
||||
}
|
||||
@ -246,6 +249,9 @@ public final class WeixinServerBootstrap {
|
||||
*/
|
||||
public WeixinServerBootstrap addInterceptor(
|
||||
WeixinMessageInterceptor... messageInterceptor) {
|
||||
if (messageInterceptor == null) {
|
||||
throw new IllegalArgumentException("messageInterceptor not be null");
|
||||
}
|
||||
messageInterceptorList.addAll(Arrays.asList(messageInterceptor));
|
||||
return this;
|
||||
}
|
||||
@ -259,6 +265,10 @@ public final class WeixinServerBootstrap {
|
||||
*/
|
||||
public WeixinServerBootstrap handlerPackagesToScan(
|
||||
String... messageHandlerPackages) {
|
||||
if (messageHandlerPackages == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"messageHandlerPackages not be null");
|
||||
}
|
||||
messageDispatcher.setMessageHandlerPackages(messageHandlerPackages);
|
||||
return this;
|
||||
}
|
||||
@ -272,6 +282,10 @@ public final class WeixinServerBootstrap {
|
||||
*/
|
||||
public WeixinServerBootstrap interceptorPackagesToScan(
|
||||
String... messageInterceptorPackages) {
|
||||
if (messageInterceptorPackages == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"messageInterceptorPackages not be null");
|
||||
}
|
||||
messageDispatcher
|
||||
.setMessageInterceptorPackages(messageInterceptorPackages);
|
||||
return this;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user