优化非核心类代码以及V3版本JSAPI接口支付签名错误bug

This commit is contained in:
jy.hu 2014-12-15 00:11:00 +08:00
parent 746697a358
commit 641d6c62ac
32 changed files with 266 additions and 263 deletions

View File

@ -174,6 +174,16 @@ netty的代码没有放到maven中心仓库,也没什么意义,因为最终需
+ **weixin4j-mp**: 新增设置`模板消息所处行业``获取模板消息ID`接口
* 2014-12-15
+ 修改某些函数在注释上的参数描述错误
+ 调整PayUtil类中`createPayJsRequestJsonV3`的形参位置,`notify_url``spbill_create_ip`对换与V2保持一致
+ 在PayUtil类中新增paySign重载版本函数,避免在某些地方产生歧义造成签名错误(appid,appKey)
+ 修正V3版本JSAPI接口支付签名错误bug(坑)
接下来
------
* 微信小店

View File

@ -85,8 +85,8 @@ public class XmlResult implements Serializable {
@Override
public String toString() {
return "XmlResult [returnCode=" + returnCode + ", returnMsg="
+ returnMsg + ", resultCode=" + resultCode + ", errCode="
+ errCode + ", errCodeDes=" + errCodeDes + "]";
return "returnCode=" + returnCode + ", returnMsg=" + returnMsg
+ ", resultCode=" + resultCode + ", errCode=" + errCode
+ ", errCodeDes=" + errCodeDes;
}
}

View File

@ -9,7 +9,9 @@ import org.apache.commons.lang3.StringUtils;
* @author jy
* @date 2014年8月17日
* @since JDK 1.7
* @see
* @see<a href=
* "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=836970804&lang=zh_CN"
* >开发者模式</a>
*/
public class WeixinMpAccount extends WeixinAccount {
private static final long serialVersionUID = 3689999353867189585L;
@ -29,13 +31,6 @@ public class WeixinMpAccount extends WeixinAccount {
// 微信支付版本号(如果无则按照mchId来做判断)
private int version;
// 是否已经认证
private boolean isAlive;
// 是否是服务号
private boolean isService;
// 是否是订阅号
private boolean isSubscribe;
@Override
public String getTokenUrl() {
return String.format(Consts.MP_ASSESS_TOKEN_URL, getId(), getSecret());
@ -89,30 +84,6 @@ public class WeixinMpAccount extends WeixinAccount {
this.deviceInfo = deviceInfo;
}
public boolean getIsAlive() {
return isAlive;
}
public void setIsAlive(Boolean isAlive) {
this.isAlive = isAlive;
}
public boolean getIsService() {
return isService;
}
public void setIsService(Boolean isService) {
this.isService = isService;
}
public boolean getIsSubscribe() {
return isSubscribe;
}
public void setIsSubscribe(Boolean isSubscribe) {
this.isSubscribe = isSubscribe;
}
public int getVersion() {
if (version == 0) {
return StringUtils.isNotBlank(mchId) ? 3 : 2;
@ -169,8 +140,7 @@ public class WeixinMpAccount extends WeixinAccount {
return "WeixinMpAccount [openId=" + openId + ", paySignKey="
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
+ deviceInfo + ", version=" + version + ", isAlive=" + isAlive
+ ", isService=" + isService + ", isSubscribe=" + isSubscribe
+ ", " + super.toString() + "]";
+ deviceInfo + ", version=" + version + ", " + super.toString()
+ "]";
}
}

View File

@ -7,7 +7,9 @@ package com.foxinmy.weixin4j.model;
* @author jy
* @date 2014年11月18日
* @since JDK 1.7
* @see
* @see <a href=
* "https://qy.weixin.qq.com/cgi-bin/home?lang=zh_CN&token=685923034#setting"
* >企业号设置</a>
*/
public class WeixinQyAccount extends WeixinAccount {
private static final long serialVersionUID = 3689999353867189585L;

View File

@ -92,7 +92,7 @@ public class WeixinProxy {
/**
* WeixinAccount对象
*
* @param weixinAccount
* @param weixinAccount 微信账户
*/
public WeixinProxy(WeixinMpAccount weixinAccount) {
this(new FileTokenHolder(weixinAccount));
@ -158,7 +158,7 @@ public class WeixinProxy {
*
* @param fileName
* 文件名
* @param bytes
* @param data
* 媒体数据包
* @param mediaType
* 媒体类型
@ -341,8 +341,8 @@ public class WeixinProxy {
*
* @param articles
* 图文列表
* @param openIds
* openId列表
* @param groupId
* 分组ID
* @return 群发后的消息ID
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroupId(Base,int)}
* @throws WeixinException
@ -405,7 +405,8 @@ public class WeixinProxy {
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E9%AB%98%E7%BA%A7%E7%BE%A4%E5%8F%91%E6%8E%A5%E5%8F%A3#.E5.88.A0.E9.99.A4.E7.BE.A4.E5.8F.91">删除群发</a>
* @see com.foxinmy.weixin4j.mp.api.MassApi
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroupId(Base, int)}
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(Base, String...)
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(Base, String...)
*/
public JsonResult deleteMassNews(String msgid) throws WeixinException {
return massApi.deleteMassNews(msgid);
@ -439,7 +440,6 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.mp.model.User
* @see com.foxinmy.weixin4j.mp.model.OauthToken
* @see com.foxinmy.weixin4j.mp.api.UserApi
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#getAccessToken(String)}
*/
public User getUser(OauthToken token) throws WeixinException {
return userApi.getUser(token);
@ -650,7 +650,6 @@ public class WeixinProxy {
* @return byte数据包
* @throws WeixinException
* @see com.foxinmy.weixin4j.mp.api.QrApi
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy.QrApi#getQR(QRParameter)}
*/
public byte[] getQRData(QRParameter parameter) throws WeixinException {
return qrApi.getQRData(parameter);
@ -666,7 +665,7 @@ public class WeixinProxy {
* @return byte数据包
* @throws WeixinException
* @see com.foxinmy.weixin4j.mp.api.QrApi
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy.QrApi#getQR(QRParameter)}
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#getQR(QRParameter)}
*/
public byte[] getQRData(int sceneId, int expireSeconds)
throws WeixinException {
@ -731,7 +730,7 @@ public class WeixinProxy {
/**
* 发送模板消息
*
* @param message
* @param tplMessage 模板消息主体
* @return 发送结果
* @throws WeixinException
* @see <a

View File

@ -143,8 +143,8 @@ public class MassApi extends MpApi {
*
* @param articles
* 图文列表
* @param openIds
* openId列表
* @param groupId
* 分组ID
* @return 群发后的消息ID
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByGroupId(Base,int)}
* @throws WeixinException
@ -229,8 +229,9 @@ public class MassApi extends MpApi {
* @throws WeixinException
* @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E9%AB%98%E7%BA%A7%E7%BE%A4%E5%8F%91%E6%8E%A5%E5%8F%A3#.E5.88.A0.E9.99.A4.E7.BE.A4.E5.8F.91">删除群发</a>
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByGroup(Base, int)}
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByOpenIds(Base, String...)
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByGroupId(Base, int)}
* @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massByOpenIds(Base, String...)
*/
public JsonResult deleteMassNews(String msgid) throws WeixinException {
JSONObject obj = new JSONObject();

View File

@ -100,21 +100,21 @@ public class PayApi extends MpApi {
String delivernotify_uri = getRequestUri("delivernotify_uri");
Token token = tokenHolder.getToken();
Map<String, String> param = new HashMap<String, String>();
param.put("appid", weixinAccount.getId());
param.put("appkey", weixinAccount.getPaySignKey());
param.put("openid", openId);
param.put("transid", transid);
param.put("out_trade_no", outTradeNo);
param.put("deliver_timestamp", DateUtil.timestamp2string());
param.put("deliver_status", status ? "1" : "0");
param.put("deliver_msg", statusMsg);
param.put("app_signature", PayUtil.paysignSha(param, null));
param.put("sign_method", SignType.SHA1.name().toLowerCase());
Map<String, String> map = new HashMap<String, String>();
map.put("appid", weixinAccount.getId());
map.put("appkey", weixinAccount.getPaySignKey());
map.put("openid", openId);
map.put("transid", transid);
map.put("out_trade_no", outTradeNo);
map.put("deliver_timestamp", DateUtil.timestamp2string());
map.put("deliver_status", status ? "1" : "0");
map.put("deliver_msg", statusMsg);
map.put("app_signature", PayUtil.paysignSha(map));
map.put("sign_method", SignType.SHA1.name().toLowerCase());
Response response = request.post(
String.format(delivernotify_uri, token.getAccessToken()),
JSON.toJSONString(param));
JSON.toJSONString(map));
return response.getAsJsonResult();
}
@ -146,7 +146,7 @@ public class PayApi extends MpApi {
obj.put("appkey", weixinAccount.getPaySignKey());
obj.put("package", sb.toString());
obj.put("timestamp", timestamp);
String signature = PayUtil.paysignSha(obj, null);
String signature = PayUtil.paysignSha(obj);
obj.clear();
obj.put("appid", weixinAccount.getId());

View File

@ -79,7 +79,7 @@ public class TmplApi extends MpApi {
/**
* 发送模板消息
*
* @param message
* @param tplMessage
* 消息对象
* @return 发送结果
* @throws WeixinException

View File

@ -95,8 +95,8 @@ public class ApiResult extends XmlResult {
@Override
public String toString() {
return "ApiResult [appId=" + appId + ", mchId=" + mchId + ", subMchId="
+ subMchId + ", nonceStr=" + nonceStr + ", sign=" + sign
+ ", deviceInfo=" + deviceInfo + ", recall=" + recall + "]";
return "appId=" + appId + ", mchId=" + mchId + ", subMchId=" + subMchId
+ ", nonceStr=" + nonceStr + ", sign=" + sign + ", deviceInfo="
+ deviceInfo + ", recall=" + recall + ", " + super.toString();
}
}

View File

@ -39,10 +39,7 @@ public class JsPayNotify extends PayBaseInfo {
@Override
public String toString() {
return "JsPayNotify [openid=" + openid + ", issubscribe=" + issubscribe
+ ", getAppId()=" + getAppId() + ", getTimeStamp()="
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
+ ", getPaySign()=" + getPaySign() + ", getSignType()="
+ getSignType() + "]";
return "openid=" + openid + ", issubscribe=" + issubscribe
+ ", " + super.toString();
}
}

View File

@ -87,8 +87,8 @@ public class PayBaseInfo implements Serializable {
@Override
public String toString() {
return "PayBaseInfo [appId=" + appId + ", timeStamp=" + timeStamp
return "appId=" + appId + ", timeStamp=" + timeStamp
+ ", nonceStr=" + nonceStr + ", paySign=" + paySign
+ ", signType=" + signType + "]";
+ ", signType=" + signType;
}
}

View File

@ -15,12 +15,11 @@ public class PayRequest extends PayBaseInfo {
private String packageInfo;
public PayRequest() {
this(null, null);
super(null, DateUtil.timestamp2string(), RandomUtil.generateString(16));
}
public PayRequest(String appId, String packageInfo) {
super(appId, DateUtil.timestamp2string(), RandomUtil
.generateString(16));
super(appId, DateUtil.timestamp2string(), RandomUtil.generateString(16));
this.packageInfo = packageInfo;
}
@ -31,4 +30,9 @@ public class PayRequest extends PayBaseInfo {
public void setPackageInfo(String packageInfo) {
this.packageInfo = packageInfo;
}
@Override
public String toString() {
return "package" + packageInfo + ", " + super.toString();
}
}

View File

@ -22,13 +22,14 @@ import com.foxinmy.weixin4j.mp.payment.v3.PayRequestV3;
import com.foxinmy.weixin4j.mp.payment.v3.PrePay;
import com.foxinmy.weixin4j.mp.type.SignType;
import com.foxinmy.weixin4j.mp.type.TradeType;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.MapUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
import com.foxinmy.weixin4j.xml.XStream;
/**
* 支付工具类
* 支付工具类(JSAPI,NATIVE,MicroPay)
*
* @className PayUtil
* @author jy
@ -42,9 +43,9 @@ public class PayUtil {
*
* @param payPackage
* 订单信息
* @param weixinConfig
* appid等信息
* @return
* @param WeixinMpAccount
* 商户信息
* @return 支付json串
* @throws PayException
*/
public static String createPayJsRequestJson(PayPackage payPackage,
@ -64,9 +65,9 @@ public class PayUtil {
*
* @param payPackage
* 订单信息
* @param weixinConfig
* appid等信息
* @return
* @param weixinAccount
* 商户信息
* @return 支付json串
*/
public static String createPayJsRequestJsonV2(PayPackageV2 payPackage,
WeixinMpAccount weixinAccount) {
@ -89,34 +90,46 @@ public class PayUtil {
* @param orderNo
* 订单号
* @param orderFee
* 订单总额
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* @param ip
* @param weixinConfig
* appid等信息
* @return
* @param weixinAccount
* 商户信息
* @return 支付json串
*/
public static String createPayJsRequestJsonV2(String body, String orderNo,
double orderFee, String ip, WeixinMpAccount weixinAccount) {
PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee, ip);
double orderFee, String notify_url, String ip,
WeixinMpAccount weixinAccount) {
PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee,
notify_url, ip);
payPackage.setPartner(weixinAccount.getPartnerId());
return createPayJsRequestJsonV2(payPackage, weixinAccount);
}
/**
* sha签名(一般用于V2.x支付接口)
*
* @param obj
* 签名对象
* @return
*/
public static String paysignSha(Object obj) {
return DigestUtils
.sha1Hex(MapUtil.toJoinString(obj, false, true, null));
}
/**
* sha签名(一般用于V2.x支付接口)
*
* @param obj
* 签名对象
* @param paySignKey
* 支付API的密钥
* 支付API的密钥<font color="red">请注意排序放进去的是put("appKey",
* paySignKey)</font>
* @return
*/
public static String paysignSha(Object obj, String paySignKey) {
Map<String, String> extra = null;
if (StringUtils.isNotBlank(paySignKey)) {
extra = new HashMap<String, String>();
extra.put("appKey", paySignKey);
}
Map<String, String> extra = new HashMap<String, String>();
extra.put("appKey", paySignKey);
return DigestUtils.sha1Hex(MapUtil
.toJoinString(obj, false, true, extra));
}
@ -152,8 +165,9 @@ public class PayUtil {
* @param orderNo
* 订单号
* @param orderFee
* 订单总额
* 订单总额 按实际金额传入即可() 构造函数会转换为分
* @param ip
* ip地址
* @param notifyUrl
* 支付通知地址
* @param weixinAccount
@ -162,7 +176,7 @@ public class PayUtil {
* @throws PayException
*/
public static String createPayJsRequestJsonV3(String openId, String body,
String orderNo, double orderFee, String ip, String notifyUrl,
String orderNo, double orderFee, String notifyUrl, String ip,
WeixinMpAccount weixinAccount) throws PayException {
PayPackageV3 payPackage = new PayPackageV3(weixinAccount, openId, body,
orderNo, orderFee, ip, TradeType.JSAPI);
@ -175,43 +189,54 @@ public class PayUtil {
*
* @param payPackage
* 订单信息
* @param weixinConfig
* appid等信息
* @return
* @param weixinAccount
* 商户信息
* @return 支付json串
* @throws PayException
*/
public static String createPayJsRequestJsonV3(PayPackageV3 payPackage,
WeixinMpAccount weixinAccount) throws PayException {
String paySignKey = weixinAccount.getPaySignKey();
payPackage.setSign(paysignMd5(payPackage, paySignKey));
PrePay prePay = createPrePay(payPackage);
PrePay prePay = createPrePay(payPackage, paySignKey);
PayRequestV3 jsPayRequest = new PayRequestV3(prePay);
jsPayRequest.setPaySign(paysignMd5(jsPayRequest, paySignKey));
jsPayRequest.setSignType(SignType.MD5);
jsPayRequest.setPaySign(paysignMd5(jsPayRequest, paySignKey));
return JSON.toJSONString(jsPayRequest);
}
/**
* 创建预支付对象</br> <font color="red">此方法并不包含签名,需要自己传入一个完整并且合法的PayPackage</font>
* 创建预支付对象</br>
*
* @param payPackage
* 包含订单信息的对象
* @param paySignKey
* <font color="red">如果sign为空 则拿paysignkey进行签名</font>
* @see com.foxinmy.weixin4j.mp.payment.v3.PayPackageV3
* @see com.foxinmy.weixin4j.mp.payment.v3.PrePay
* @return 预支付对象
*/
public static PrePay createPrePay(PayPackageV3 payPackage)
public static PrePay createPrePay(PayPackageV3 payPackage, String paySignKey)
throws PayException {
if (StringUtils.isBlank(payPackage.getSign())) {
// String paySignKey = weixinAccount.getPaySignKey();
// payPackage.setSign(paysignMd5(payPackage, paySignKey));
payPackage.setSign(paysignMd5(payPackage, paySignKey));
}
String payJsRequestXml = XStream.to(payPackage).replaceAll("__", "_");
HttpRequest request = new HttpRequest();
try {
Response response = request.post(Consts.UNIFIEDORDER, payJsRequestXml);
return response.getAsObject(new TypeReference<PrePay>() {
Response response = request.post(Consts.UNIFIEDORDER,
payJsRequestXml);
PrePay prePay = response.getAsObject(new TypeReference<PrePay>() {
});
if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getReturnMsg(),
prePay.getReturnCode());
}
if (!prePay.getResultCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getResultCode(),
prePay.getErrCodeDes());
}
return prePay;
} catch (WeixinException e) {
throw new PayException(e.getErrorCode(), e.getErrorMsg());
}
@ -238,33 +263,33 @@ public class PayUtil {
*/
public static String createAddressRequestJson(String appId, String url,
String accessToken) {
Map<String, String> obj = new HashMap<String, String>();
obj.put("appId", appId);
obj.put("timeStamp", DateUtil.timestamp2string());
obj.put("nonceStr", RandomUtil.generateString(16));
obj.put("url", url);
obj.put("accessToken", accessToken);
String sign = paysignSha(obj, null);
obj.remove("url");
obj.remove("accessToken");
obj.put("scope", "jsapi_address");
obj.put("signType", SignType.SHA1.name().toLowerCase());
obj.put("addrSign", sign);
Map<String, String> map = new HashMap<String, String>();
map.put("appId", appId);
map.put("timeStamp", DateUtil.timestamp2string());
map.put("nonceStr", RandomUtil.generateString(16));
map.put("url", url);
map.put("accessToken", accessToken);
String sign = paysignSha(map);
map.remove("url");
map.remove("accessToken");
map.put("scope", "jsapi_address");
map.put("signType", SignType.SHA1.name().toLowerCase());
map.put("addrSign", sign);
return JSON.toJSONString(obj);
return JSON.toJSONString(map);
}
/**
* 创建V2.x NativePay支付链接
*
* @param weixinConfig
* 支付配置信息
* @param weixinAccount
* 商户信息
* @param productId
* 与订单ID等价
* @return
*/
public String createNativePayRequestURLV2(WeixinMpAccount weixinAccount,
String productId) {
public static String createNativePayRequestURLV2(
WeixinMpAccount weixinAccount, String productId) {
Map<String, String> map = new HashMap<String, String>();
String timestamp = DateUtil.timestamp2string();
String noncestr = RandomUtil.generateString(16);
@ -272,7 +297,8 @@ public class PayUtil {
map.put("timestamp", timestamp);
map.put("noncestr", noncestr);
map.put("productid", productId);
String sign = paysignSha(map, weixinAccount.getPaySignKey());
map.put("appkey", weixinAccount.getPaySignKey());
String sign = paysignSha(map);
return String.format(Consts.NATIVEURLV2, sign, weixinAccount.getId(),
productId, timestamp, noncestr);
}
@ -286,8 +312,8 @@ public class PayUtil {
* 与订单ID等价
* @return
*/
public String createNativePayRequestURLV3(WeixinMpAccount weixinAccount,
String productId) {
public static String createNativePayRequestURLV3(
WeixinMpAccount weixinAccount, String productId) {
Map<String, String> map = new HashMap<String, String>();
String timestamp = DateUtil.timestamp2string();
String noncestr = RandomUtil.generateString(16);
@ -301,7 +327,16 @@ public class PayUtil {
weixinAccount.getMchId(), productId, timestamp, noncestr);
}
public static String createNativePayRequestV2(
/**
* NATIVE回调时的响应
*
* @param weixinAccount
* 商户信息
* @param payPackage
* 订单信息
* @return
*/
public static String createNativePayResponseV2(
WeixinMpAccount weixinAccount, PayPackageV2 payPackage) {
NativePayResponseV2 payRequest = new NativePayResponseV2(weixinAccount,
payPackage);
@ -309,12 +344,13 @@ public class PayUtil {
String timestamp = DateUtil.timestamp2string();
String noncestr = RandomUtil.generateString(16);
map.put("appid", weixinAccount.getId());
map.put("appkey", weixinAccount.getPaySignKey());
map.put("timestamp", timestamp);
map.put("noncestr", noncestr);
map.put("package", payRequest.getPackageInfo());
map.put("retcode", payRequest.getRetCode());
map.put("reterrmsg", payRequest.getRetMsg());
payRequest.setPaySign(paysignSha(map, weixinAccount.getPaySignKey()));
payRequest.setPaySign(paysignSha(map));
return XStream.to(payRequest);
}
@ -370,4 +406,38 @@ public class PayUtil {
.getAsObject(new TypeReference<com.foxinmy.weixin4j.mp.payment.v3.Order>() {
});
}
private static String JSAPIV2() {
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
return createPayJsRequestJsonV2("支付测试", "JSAPI01", 0.01d, "127.0.0.0",
"http://127.0.0.1/jsapi/notify", weixinAccount);
}
private static String NATIVEV2() {
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
return createNativePayRequestURLV2(weixinAccount, "P1");
}
private static String JSAPIV3() throws PayException {
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
return createPayJsRequestJsonV3("oyFLst1bqtuTcxK-ojF8hOGtLQao", "支付测试",
"JSAPI01", 0.01d, "http://127.0.0.1/jsapi/notify", "127.0.0.0",
weixinAccount);
}
private static String NATIVEV3() {
WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount();
return createNativePayRequestURLV3(weixinAccount, "P1");
}
public static void main(String[] args) throws PayException {
// V2版本下的JS支付
System.out.println(JSAPIV2());
// V2版本下的原生支付
System.out.println(NATIVEV2());
// V3版本下的JS支付
System.out.println(JSAPIV3());
// V3版本下的原生支付
System.out.println(NATIVEV3());
}
}

View File

@ -62,12 +62,6 @@ public class Refund extends ApiResult {
return "Refund [transactionId=" + transactionId + ", orderNo="
+ orderNo + ", subMchId=" + subMchId + ", count=" + count
+ ", partner=" + partner + ", details=" + details
+ ", getAppId()=" + getAppId() + ", getMchId()=" + getMchId()
+ ", getNonceStr()=" + getNonceStr() + ", getSign()="
+ getSign() + ", getDeviceInfo()=" + getDeviceInfo()
+ ", getReturnCode()=" + getReturnCode() + ", getReturnMsg()="
+ getReturnMsg() + ", getResultCode()=" + getResultCode()
+ ", getErrCode()=" + getErrCode() + ", getErrCodeDes()="
+ getErrCodeDes() + "]";
+ ", " + super.toString() + "]";
}
}

View File

@ -112,13 +112,7 @@ public class RefundResult extends ApiResult {
+ ", refundFee=" + refundFee + ", couponRefundFee="
+ couponRefundFee + ", recvUserId=" + recvUserId
+ ", reccvUserName=" + reccvUserName + ", signKeyIndex="
+ signKeyIndex + ", signType=" + signType + ", getAppId()="
+ getAppId() + ", getMchId()=" + getMchId()
+ ", getSubMchId()=" + getSubMchId() + ", getNonceStr()="
+ getNonceStr() + ", getSign()=" + getSign()
+ ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()="
+ getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
+ ", getResultCode()=" + getResultCode() + ", getErrCode()="
+ getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]";
+ signKeyIndex + ", signType=" + signType + ", "
+ super.toString() + "]";
}
}

View File

@ -59,10 +59,6 @@ public class JsPayRequestV2 extends PayRequest {
@Override
public String toString() {
return "JsPayRequestV2 [getPackageInfo()=" + getPackageInfo()
+ ", getAppId()=" + getAppId() + ", getTimeStamp()="
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
+ ", getPaySign()=" + getPaySign() + ", getSignType()="
+ getSignType() + "]";
return "JsPayRequestV2 [" + super.toString() + "]";
}
}

View File

@ -28,11 +28,7 @@ public class NativePayNotifyV2 extends JsPayNotify {
@Override
public String toString() {
return "NativePayNotifyV2 [productId=" + productId + ", getOpenid()="
+ getOpenid() + ", getIssubscribe()=" + getIssubscribe()
+ ", getAppId()=" + getAppId() + ", getTimeStamp()="
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
+ ", getPaySign()=" + getPaySign() + ", getSignType()="
+ getSignType() + "]";
return "NativePayNotifyV2 [productId=" + productId + ", "
+ super.toString() + "]";
}
}

View File

@ -47,9 +47,6 @@ public class NativePayResponseV2 extends JsPayRequestV2 {
@Override
public String toString() {
return "NativePayResponseV2 [retCode=" + retCode + ", retMsg=" + retMsg
+ ", getPackageInfo()=" + getPackageInfo() + ", getAppId()="
+ getAppId() + ", getTimeStamp()=" + getTimeStamp()
+ ", getNonceStr()=" + getNonceStr() + ", getPaySign()="
+ getPaySign() + ", getSignType()=" + getSignType() + "]";
+ ", " + super.toString() + "]";
}
}

View File

@ -71,9 +71,7 @@ public class PayFeedback extends PayBaseInfo {
return "PayFeedback [feedbackId=" + feedbackId + ", openId=" + openId
+ ", transId=" + transId + ", reason=" + reason + ", solution="
+ solution + ", extInfo=" + extInfo + ", picInfo=" + picInfo
+ ", status=" + status + ", getAppId()=" + getAppId()
+ ", getTimeStamp()=" + getTimeStamp() + ", getNonceStr()="
+ getNonceStr() + ", getPaySign()=" + getPaySign()
+ ", getSignType()=" + getSignType() + "]";
+ ", status=" + status + ", " + super.toString()
+ "]";
}
}

View File

@ -104,9 +104,9 @@ public class PayPackageV2 extends PayPackage {
}
public PayPackageV2(String body, String out_trade_no, double total_fee,
String spbill_create_ip) {
this(body, null, null, out_trade_no, total_fee, null, spbill_create_ip,
null, null, 0d, 0d, null);
String notify_url, String spbill_create_ip) {
this(body, null, null, out_trade_no, total_fee, notify_url,
spbill_create_ip, null, null, 0d, 0d, null);
}
public PayPackageV2(String body, String partner, String out_trade_no,

View File

@ -32,10 +32,7 @@ public class PayWarn extends PayBaseInfo {
@Override
public String toString() {
return "PayWarn [errortype=" + errortype + ", description="
+ description + ", alarmcontent=" + alarmcontent
+ ", getAppId()=" + getAppId() + ", getTimeStamp()="
+ getTimeStamp() + ", getNonceStr()=" + getNonceStr()
+ ", getPaySign()=" + getPaySign() + ", getSignType()="
+ getSignType() + "]";
+ description + ", alarmcontent=" + alarmcontent + ", "
+ super.toString() + "]";
}
}

View File

@ -30,12 +30,7 @@ public class NativePayNotifyV3 extends ApiResult {
@Override
public String toString() {
return "NativePayNotifyV3 [mchId=" + getMchId() + ", productId="
+ productId + ", getAppId()=" + getAppId() + ", getNonceStr()="
+ getNonceStr() + ", getSign()=" + getSign()
+ ", getDeviceInfo()=" + getDeviceInfo() + ", getReturnCode()="
+ getReturnCode() + ", getReturnMsg()=" + getReturnMsg()
+ ", getResultCode()=" + getResultCode() + ", getErrCode()="
+ getErrCode() + ", getErrCodeDes()=" + getErrCodeDes() + "]";
return "NativePayNotifyV3 [productId=" + productId + ", "
+ super.toString() + "]";
}
}

View File

@ -1,13 +1,13 @@
package com.foxinmy.weixin4j.mp.payment.v3;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.exception.PayException;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.payment.ApiResult;
import com.foxinmy.weixin4j.mp.payment.PayUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* Native支付时的回调响应
@ -23,20 +23,44 @@ public class NativePayResponseV3 extends ApiResult {
private static final long serialVersionUID = 6119895998783333012L;
@XStreamOmitField
@JSONField(serialize = false)
private PrePay prePay;
private String prepay_id;
public NativePayResponseV3(PayPackageV3 payPackage, String returnMsg,
String resultMsg) throws PayException {
/**
* 一般作为校验失败时返回
*
* @param returnMsg
* 失败消息
* @param resultMsg
* 结果消息
* @throws PayException
*/
public NativePayResponseV3(String returnMsg, String resultMsg) {
super.setReturnMsg(returnMsg);
super.setReturnCode(StringUtils.isNotBlank(returnMsg) ? Consts.FAIL
: Consts.SUCCESS);
this.setErrCodeDes(resultMsg);
this.setResultCode(StringUtils.isNotBlank(resultMsg) ? Consts.FAIL
: Consts.SUCCESS);
super.setReturnCode(Consts.FAIL);
super.setErrCodeDes(resultMsg);
super.setResultCode(Consts.FAIL);
}
/**
* 作为return_code SUCCESS 的时候返回
*
* @param payPackage
* 订单信息
* @throws PayException
*/
public NativePayResponseV3(PayPackageV3 payPackage, String paysignKey)
throws PayException {
super.setReturnCode(Consts.SUCCESS);
this.setResultCode(Consts.SUCCESS);
this.setMchId(payPackage.getMch_id());
this.setAppId(payPackage.getAppid());
this.setNonceStr(RandomUtil.generateString(16));
this.prepay_id = PayUtil.createPrePay(payPackage).getPrepayId();
this.prePay = PayUtil.createPrePay(payPackage, paysignKey);
this.prepay_id = prePay.getPrepayId();
}
public String getPrepay_id() {
@ -49,13 +73,8 @@ public class NativePayResponseV3 extends ApiResult {
@Override
public String toString() {
return "NativePayResponseV3 [prepay_id=" + prepay_id + ", getAppId()="
+ getAppId() + ", getMchId()=" + getMchId()
+ ", getNonceStr()=" + getNonceStr() + ", getSign()="
+ getSign() + ", getDeviceInfo()=" + getDeviceInfo()
+ ", getReturnCode()=" + getReturnCode() + ", getReturnMsg()="
+ getReturnMsg() + ", getResultCode()=" + getResultCode()
+ ", getErrCode()=" + getErrCode() + ", getErrCodeDes()="
+ getErrCodeDes() + "]";
return "NativePayResponseV3 [prePay=" + prePay + ", prepay_id="
+ prepay_id + ", " + super.toString() + "]";
}
}

View File

@ -125,12 +125,6 @@ public class Order extends ApiResult {
+ ", couponFee=" + couponFee + ", feeType=" + feeType
+ ", transactionId=" + transactionId + ", outTradeNo="
+ outTradeNo + ", attach=" + attach + ", timeEnd=" + timeEnd
+ ", getAppId()=" + getAppId() + ", getMchId()=" + getMchId()
+ ", getNonceStr()=" + getNonceStr() + ", getSign()="
+ getSign() + ", getDeviceInfo()=" + getDeviceInfo()
+ ", getReturnCode()=" + getReturnCode() + ", getReturnMsg()="
+ getReturnMsg() + ", getResultCode()=" + getResultCode()
+ ", getErrCode()=" + getErrCode() + ", getErrCodeDes()="
+ getErrCodeDes() + "]";
+ ", " + super.toString() + "]";
}
}

View File

@ -11,8 +11,7 @@ import com.foxinmy.weixin4j.util.RandomUtil;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* V3支付的订单详情</br>
* 注意: <font color="red">total_fee字段传入时单位为元,创建支付时会转换为分</font>
* V3支付的订单详情</br> 注意: <font color="red">total_fee字段传入时单位为元,创建支付时会转换为分</font>
*
* @className PayPackageV3
* @author jy
@ -41,13 +40,13 @@ public class PayPackageV3 extends PayPackage {
public PayPackageV3(WeixinMpAccount weixinAccount, String openId,
String body, String out_trade_no, double total_fee,
String spbill_create_ip, TradeType tradeType) {
this(weixinAccount, openId, body, null, out_trade_no, total_fee,
spbill_create_ip, null, tradeType);
this(weixinAccount, openId, body, null, out_trade_no, total_fee, null,
spbill_create_ip, tradeType);
}
public PayPackageV3(WeixinMpAccount weixinAccount, String openId,
String body, String attach, String out_trade_no, double total_fee,
String spbill_create_ip, String notify_url, TradeType tradeType) {
String notify_url, String spbill_create_ip, TradeType tradeType) {
this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount
.getDeviceInfo(), RandomUtil.generateString(16), body, attach,
out_trade_no, total_fee, spbill_create_ip, null, null, null,

View File

@ -1,10 +1,7 @@
package com.foxinmy.weixin4j.mp.payment.v3;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.exception.PayException;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.mp.payment.PayRequest;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* JS支付:get_brand_wcpay_request</br>
@ -26,35 +23,13 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField;
public class PayRequestV3 extends PayRequest {
private static final long serialVersionUID = -5972173459255255197L;
@XStreamOmitField
@JSONField(serialize = false)
private PrePay prePay;
public PayRequestV3(PrePay prePay) throws PayException {
if (!prePay.getReturnCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getReturnMsg(),
prePay.getReturnCode());
}
if (!prePay.getResultCode().equalsIgnoreCase(Consts.SUCCESS)) {
throw new PayException(prePay.getResultCode(),
prePay.getErrCodeDes());
}
this.prePay = prePay;
this.setAppId(prePay.getAppId());
this.setPackageInfo("prepay_id=" + prePay.getPrepayId());
}
public PrePay getPrePay() {
return prePay;
}
@Override
public String toString() {
return "PayRequestV3 [prePay=" + prePay + ", getPackageInfo()="
+ getPackageInfo() + ", getAppId()=" + getAppId()
+ ", getTimeStamp()=" + getTimeStamp() + ", getNonceStr()="
+ getNonceStr() + ", getPaySign()=" + getPaySign()
+ ", getSignType()=" + getSignType() + "]";
return "JsPayRequestV3 [" + super.toString() + "]";
}
}

View File

@ -25,6 +25,7 @@ public class PrePay extends ApiResult {
@XStreamAlias("code_url")
private String codeUrl;// trade_type NATIVE 是有 返回,此参数可直接生成二 维码展示出来进行扫码支付
// 可能为空
public PrePay() {
}
@ -60,13 +61,6 @@ public class PrePay extends ApiResult {
@Override
public String toString() {
return "PrePay [tradeType=" + tradeType + ", prepayId=" + prepayId
+ ", codeUrl=" + codeUrl + ", getAppId()=" + getAppId()
+ ", getMchId()=" + getMchId() + ", getNonceStr()="
+ getNonceStr() + ", getSign()=" + getSign()
+ ", getDeviceInfo()=" + getDeviceInfo() + ", toString()="
+ super.toString() + ", getReturnCode()=" + getReturnCode()
+ ", getReturnMsg()=" + getReturnMsg() + ", getResultCode()="
+ getResultCode() + ", getErrCode()=" + getErrCode()
+ ", getErrCodeDes()=" + getErrCodeDes() + "]";
+ ", codeUrl=" + codeUrl + ", " + super.toString() + "]";
}
}

View File

@ -1,10 +1,11 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.foxinmy</groupId>
<artifactId>weixin4j-mp</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0</version>
</parent>
<artifactId>weixin4j-mp-server</artifactId>
<name>weixin4j-mp-server</name>
@ -53,6 +54,10 @@
<artifactId>logback-core</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@ -236,15 +236,17 @@ public class PayAction {
"商品描述", "系统内部订单号", 1d, "IP地址", TradeType.NATIVE);
payPackage.setProduct_id(payNotify.getProductId());
if (!sign.equals(valid_sign)) {
NativePayResponseV3 payReponse = new NativePayResponseV3(
payPackage, "签名失败", null);
// 校验失败
NativePayResponseV3 payReponse = new NativePayResponseV3("签名失败",
null);
payReponse.setSign(PayUtil.paysignMd5(payReponse,
weixinAccount.getPaySignKey()));
return XStream.to(payReponse);
}
// 成功返回
NativePayResponseV3 payReponse = new NativePayResponseV3(payPackage,
null, null);
weixinAccount.getPaySignKey());
payReponse.setSign(PayUtil.paysignMd5(payReponse,
weixinAccount.getPaySignKey()));
return XStream.to(payReponse);
@ -298,7 +300,8 @@ public class PayAction {
obj.put("openid", feedback.getOpenId());
obj.put("appid", feedback.getAppId());
obj.put("timestamp", feedback.getTimeStamp());
String sign = PayUtil.paysignSha(obj, weixinAccount.getPaySignKey());
obj.put("appkey", weixinAccount.getPaySignKey());
String sign = PayUtil.paysignSha(obj);
log.info("微信签名----->sign={},vaild_sign={}", sign, feedback.getPaySign());
return "success";
}

View File

@ -40,8 +40,8 @@ public class WeixinProxy {
/**
* appid,appsecret
*
* @param appid
* @param appsecret
* @param corpid
* @param corpsecret
*/
public WeixinProxy(String corpid, String corpsecret) {
this(new WeixinQyAccount(corpid, corpsecret));
@ -244,10 +244,7 @@ public class WeixinProxy {
/**
* 更新标签(管理组必须是指定标签的创建者)
*
* @param tagId
* 标签ID
* @param tagName
* 标签名称
* @param tag 标签信息
* @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E6.9B.B4.E6.96.B0.E6.A0.87.E7.AD.BE.E5.90.8D.E5.AD.97"
* >更新标签说明</a>

View File

@ -67,7 +67,7 @@ public class MediaApi extends QyApi {
* @throws WeixinException
* @throws IOException
* @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(File, byte[],String)}
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(String, byte[],String)}
*/
public String uploadMedia(File file, MediaType mediaType)
throws WeixinException, IOException {

View File

@ -51,10 +51,7 @@ public class TagApi extends QyApi {
/**
* 更新标签(管理组必须是指定标签的创建者)
*
* @param tagId
* 标签ID
* @param tagName
* 标签名称
* @param tag 标签信息
* @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%A0%87%E7%AD%BE#.E6.9B.B4.E6.96.B0.E6.A0.87.E7.AD.BE.E5.90.8D.E5.AD.97"
* >更新标签说明</a>