Commit e2bc25cd authored by hezhen's avatar hezhen

添加微信支付

parent a5e1f87f
...@@ -29,5 +29,34 @@ public class SystemConfig { ...@@ -29,5 +29,34 @@ public class SystemConfig {
public static String getCongif(String key) { public static String getCongif(String key) {
return SystemProperty.getConfig(key); return SystemProperty.getConfig(key);
} }
// 微信公众号的配置
public static final String WINXIN_AppID = SystemProperty.getConfig("WINXIN_AppID");
public static final String WINXIN_AppSecret = SystemProperty.getConfig("WINXIN_AppSecret");
public static final String WINXIN_PARTNER_KEY = SystemProperty.getConfig("WINXIN_PARTNER_KEY");
public static final String WINXIN_PARTNER = SystemProperty.getConfig("WINXIN_PARTNER");
// 移动端app微信支付配置参数
/**
* appStore配置
*/
// 微信开发平台应用id(OK)
public static String APP_ID = SystemProperty.getConfig("APP_ID");
// 财付通商户号(OK)
public static String APP_PARTNER = SystemProperty.getConfig("APP_PARTNER");
// 商户号对应的密钥//(OK)
public static String APP_PARTNER_KEY = SystemProperty.getConfig("APP_PARTNER_KEY");
public static String APP_TRADE_TYPE = SystemProperty.getConfig("APP_TRADE_TYPE");
/**
* (IOS)企业版配置
*/
public static String APP_ID_IOS = SystemProperty.getConfig("APP_ID_IOS");
// 微信开发平台应用id(OK)
public static String APP_PARTNER_IOS = SystemProperty.getConfig("APP_PARTNER_IOS");
// 财付通商户号(OK)
public static String APP_PARTNER_KEY_IOS = SystemProperty.getConfig("APP_PARTNER_KEY_IOS");
// 商户号对应的密钥//(OK)
public static String APP_TRADE_TYPE_IOS = SystemProperty.getConfig("APP_TRADE_TYPE");
// 平台所有微信的回调地址的域名
public static final String weixinHost = SystemProperty.getConfig("weixinHost");
} }
...@@ -17,3 +17,20 @@ ACCESSKEYID=LTAIlXrgxOBAj2Ny ...@@ -17,3 +17,20 @@ ACCESSKEYID=LTAIlXrgxOBAj2Ny
ACCESSKEYSECRET=zo8OkOCF4iygqOjYYoxRKfVRxDvgTI ACCESSKEYSECRET=zo8OkOCF4iygqOjYYoxRKfVRxDvgTI
TEMPLATECODE=SMS_166480010 TEMPLATECODE=SMS_166480010
SIGNNAME=升云 SIGNNAME=升云
#微信支付配置
WINXIN_AppID=wxcc2c9b7c87439a6d
WINXIN_AppSecret=279796e8c2963c8a5ddc8270ef642b29
WINXIN_PARTNER_KEY=CNITR89201000CNITR89201000FUWUSH
WINXIN_PARTNER=1512136241
#ios
APP_ID_IOS=wx3f51779d49171d63
APP_PARTNER_IOS=1492557632
APP_PARTNER_KEY_IOS=89201002892010008920100quanzinet
APP_TRADE_TYPE_IOS=APP
#andoir
APP_ID=wxa9805823769294b6
APP_PARTNER=1327473801
APP_PARTNER_KEY=cnitr89201000QZNWcnitr89201000QZ
APP_TRADE_TYPE=APP
#支付回调
weixinHost=xxfcmgmt.upyuns.com
...@@ -10,7 +10,7 @@ spring: ...@@ -10,7 +10,7 @@ spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://10.5.52.3:3306/vehicle?useUnicode=true&characterEncoding=UTF-8 url: jdbc:mysql://10.5.52.3:3306/xxfc_third_platform?useUnicode=true&characterEncoding=UTF-8
username: root username: root
password: sslcloud123*() password: sslcloud123*()
jackson: jackson:
......
#代码生成器,配置信息 #代码生成器,配置信息
#包名 #包名
package=com.xxfc.platform.vehicle package=com.xxfc.platform.universal
#作者 #作者
author=zjw author=zjw
#Email #Email
......
...@@ -11,5 +11,37 @@ ...@@ -11,5 +11,37 @@
<groupId>com.xxfc.platform</groupId> <groupId>com.xxfc.platform</groupId>
<artifactId>xx-universal-api</artifactId> <artifactId>xx-universal-api</artifactId>
<dependencies>
<!-- xstream XML工具-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.5</version>
</dependency>
<!-- XML解析包 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- 微信支付需要的jar -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
</dependencies>
</project> </project>
\ No newline at end of file
package com.xxfc.platform.universal.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单支付
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
@Data
@Table(name = "order_pay")
public class OrderPay implements Serializable {
private static final long serialVersionUID = 1L;
//
@Id
@GeneratedValue(generator = "JDBC")
@ApiModelProperty("")
private Integer id;
//支付订单号
@Column(name = "trade_no")
@ApiModelProperty(value = "支付订单号")
private String tradeNo;
//订单号
@Column(name = "order_no")
@ApiModelProperty(value = "订单号")
private String orderNo;
//用户id
@Column(name = "user_id")
@ApiModelProperty(value = "用户id")
private Integer userId;
//1:微信公众号支付 2.支付宝即时到账,3,银联
@Column(name = "pay_way")
@ApiModelProperty(value = "1:微信公众号支付 2.支付宝即时到账,3,银联")
private Integer payWay;
//渠道:1-租车;2-旅游
@Column(name = "channel")
@ApiModelProperty(value = "渠道:1-租车;2-旅游")
private Integer channel;
//来源:1-app;2-小程序
@Column(name = "type")
@ApiModelProperty(value = "来源:1-app;2-小程序")
private Integer type;
//买家IP地址
@Column(name = "buyer_ip")
@ApiModelProperty(value = "买家IP地址")
private String buyerIp;
//商品标题
@Column(name = "subject")
@ApiModelProperty(value = "商品标题")
private String subject;
//商品描述信息
@Column(name = "body")
@ApiModelProperty(value = "商品描述信息")
private String body;
//回调地址
@Column(name = "notify_url")
@ApiModelProperty(value = "回调地址")
private String notifyUrl;
//支付状态0:未支付 1:已支付
@Column(name = "status")
@ApiModelProperty(value = "支付状态0:未支付 1:已支付")
private Integer status;
//支付金额
@Column(name = "amount")
@ApiModelProperty(value = "支付金额")
private Integer amount;
//是否删除
@Column(name = "is_del")
@ApiModelProperty(value = "是否删除")
private Integer isDel;
//支付接口返回的流水号
@Column(name = "serial_number")
@ApiModelProperty(value = "支付接口返回的流水号")
private String serialNumber;
//买家第三方付款账号
@Column(name = "buyer_account")
@ApiModelProperty(value = "买家第三方付款账号")
private String buyerAccount;
//卖家第三方收款账号
@Column(name = "seller_account")
@ApiModelProperty(value = "卖家第三方收款账号")
private String sellerAccount;
//创建时间
@Column(name = "crt_time")
@ApiModelProperty(value = "创建时间", hidden = true )
private Long crtTime;
//更新时间
@Column(name = "upd_time")
@ApiModelProperty(value = "更新时间", hidden = true )
private Long updTime;
//支付完成时间
@Column(name = "finish_time")
@ApiModelProperty(value = "支付完成时间")
private Long finishTime;
}
package com.xxfc.platform.universal.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单支付退款表
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
@Data
@Table(name = "order_refund")
public class OrderRefund implements Serializable {
private static final long serialVersionUID = 1L;
//
@Id
@GeneratedValue(generator = "JDBC")
@ApiModelProperty("")
private Integer id;
//退款订单号
@Column(name = "refund_trade_no")
@ApiModelProperty(value = "退款订单号")
private String refundTradeNo;
//订单号
@Column(name = "order_no")
@ApiModelProperty(value = "订单号")
private String orderNo;
//用户id
@Column(name = "user_id")
@ApiModelProperty(value = "用户id")
private Integer userId;
//0-订单生成,1-退款中,2-退款成功,3-退款失败
@Column(name = "status")
@ApiModelProperty(value = "0-订单生成,1-退款中,2-退款成功,3-退款失败")
private Integer status;
//支付金额
@Column(name = "amount")
@ApiModelProperty(value = "支付金额")
private Integer amount;
//退款金额
@Column(name = "refund_amount")
@ApiModelProperty(value = "退款金额")
private Integer refundAmount;
//是否删除
@Column(name = "is_del")
@ApiModelProperty(value = "是否删除")
private Integer isDel;
//商户退款单号
@Column(name = "out_refund_no")
@ApiModelProperty(value = "商户退款单号")
private String outRefundNo;
//支付接口返回的流水号
@Column(name = "serial_number")
@ApiModelProperty(value = "支付接口返回的流水号")
private String serialNumber;
//创建时间
@Column(name = "crt_time")
@ApiModelProperty(value = "创建时间", hidden = true )
private Long crtTime;
//更新时间
@Column(name = "upd_time")
@ApiModelProperty(value = "更新时间", hidden = true )
private Long updTime;
//退款完成时间
@Column(name = "finish_time")
@ApiModelProperty(value = "退款完成时间")
private Long finishTime;
}
package com.xxfc.platform.universal.feign; package com.xxfc.platform.universal.feign;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.xxfc.platform.universal.vo.OrderPayVo;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
...@@ -20,4 +22,7 @@ public interface ThirdFeign { ...@@ -20,4 +22,7 @@ public interface ThirdFeign {
public JSONObject send(@RequestParam(value = "phone") String phone); public JSONObject send(@RequestParam(value = "phone") String phone);
@RequestMapping(value = "/file/app/unauth/uploadFiles", method = RequestMethod.POST) @RequestMapping(value = "/file/app/unauth/uploadFiles", method = RequestMethod.POST)
public JSONObject uploadFiles(@RequestParam("files") MultipartFile[] files); public JSONObject uploadFiles(@RequestParam("files") MultipartFile[] files);
@RequestMapping(value = "/pay/app/wx", method = RequestMethod.POST)
public JSONObject wx(@RequestBody OrderPayVo orderPayVo);
} }
package com.xxfc.platform.universal.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
/**
* 下单
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
@Data
public class OrderPayVo{
//订单号
private String orderNo;
//用户id
private Integer userId;
//1:微信公众号支付 2.支付宝即时到账,3,银联
private Integer payWay;
//渠道:1-租车;2-旅游
private Integer channel;
//来源:1-app;2-小程序
private Integer type;
//买家IP地址
private String buyerIp;
//商品标题
private String subject;
//商品描述信息
private String body;
//回调地址
private String notifyUrl;
//支付金额
private Integer amount;
//买家第三方付款账号
private String buyerAccount;
}
package com.xxfc.platform.universal.weixin.api;
import java.util.Map.Entry;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import com.github.wxiaoqi.security.common.util.process.SystemConfig;
import com.xxfc.platform.universal.weixin.util.HTTPUtils;
import com.xxfc.platform.universal.weixin.util.MD5;
import com.xxfc.platform.universal.weixin.util.MD5Util;
import com.xxfc.platform.universal.weixin.util.OrderUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* 微信调起支付类
*
* @author Sunlight
*
*/
@Slf4j
public class WXPay {
/**
* 公众号支付
* @param total_fee
* @param body
* @param notify_url
* @param orderNo
* @param spbill_create_ip
* @param openid
* @return
*/
public static String webPay(String total_fee,String body,String notify_url,String orderNo,String spbill_create_ip,String openid){
WXPrepay prePay = new WXPrepay();
prePay.setAppid(SystemConfig.WINXIN_AppID);//pay.getAppId()
prePay.setBody(body);
prePay.setPartnerKey(SystemConfig.WINXIN_PARTNER_KEY);//pay.getPartnerKey()
prePay.setMch_id(SystemConfig.WINXIN_PARTNER);//pay.getPartnerId()
prePay.setNotify_url(notify_url);
prePay.setOut_trade_no(orderNo);
prePay.setSpbill_create_ip(spbill_create_ip);//"123.12.12.123"
prePay.setTotal_fee(total_fee);
prePay.setTrade_type("JSAPI");
prePay.setOpenid(openid);
//此处添加获取openid的方法,获取预支付订单需要此参数!!!!!!!!!!!
// 获取预支付订单号
String prepayid = prePay.submitXmlGetPrepayId(1);
System.out.println("获取的预支付订单是:" + prepayid);
//PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类
//logger.info("预支付签名:"+prepayReqHandler.createSHA1Sign());
String jsParam = "";
if (prepayid != null && prepayid.length() > 10) {
// 生成微信支付参数,此处拼接为完整的JSON格式,符合支付调起传入格式
jsParam = WXPay.createPackageValueWeb(SystemConfig.WINXIN_AppID, SystemConfig.WINXIN_PARTNER_KEY, prepayid);
}
return jsParam;
}
/**
* 公众号生成签名
* @param appid
* @param appKey
* @param prepay_id
* @return
*/
public static String createPackageValueWeb(String appid, String appKey, String prepay_id) {
JSONObject res = new JSONObject();
res.put("appId", appid);
String timeStamp = OrderUtil.GetTimestamp();
res.put("timeStamp", timeStamp);
Random random = new Random();
String randomStr = MD5.GetMD5String(String.valueOf(random.nextInt(10000)));
res.put("nonceStr", MD5Util.MD5Encode(randomStr, "utf-8").toLowerCase());//
res.put("package", "prepay_id=" + prepay_id);//
res.put("signType", "MD5");
SortedMap<String, String> nativeObj = new TreeMap<String, String>();
nativeObj.put("appId", appid);
nativeObj.put("nonceStr", MD5Util.MD5Encode(randomStr, "utf-8").toLowerCase());
nativeObj.put("package", "prepay_id=" + prepay_id);
nativeObj.put("signType", "MD5");
nativeObj.put("timeStamp", timeStamp);
res.put("paySign", createSignWeb(nativeObj, appKey));
return res.toJSONString();
}
/**
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。公众号生成加密的方式
*/
public static String createSignWeb(SortedMap<String, String> packageParams, String AppKey) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + AppKey);
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
/**
* app支付
* @param body 商品详情
* @param notify_url 回调地址
* @param orderNo 订单号
* @param spbill_create_ip 移动端的IP
* @return
*/
public static String apppay(String total_fee,String body,String notify_url,String orderNo,String spbill_create_ip, int version)
{
boolean isWeixinPayConfigedForAppStore = (0 == version);
WXPrepay prePay = new WXPrepay();
prePay.setBody(body);
if (isWeixinPayConfigedForAppStore) {
prePay.setAppid(SystemConfig.APP_ID);//pay.getAppId()
prePay.setPartnerKey(SystemConfig.APP_PARTNER_KEY);//pay.getPartnerKey()
prePay.setMch_id(SystemConfig.APP_PARTNER);//pay.getPartnerId()
prePay.setTrade_type(SystemConfig.APP_TRADE_TYPE);
} else {
prePay.setAppid(SystemConfig.APP_ID_IOS);//pay.getAppId()
prePay.setPartnerKey(SystemConfig.APP_PARTNER_KEY_IOS);//pay.getPartnerKey()
prePay.setMch_id(SystemConfig.APP_PARTNER_IOS);//pay.getPartnerId()
prePay.setTrade_type(SystemConfig.APP_TRADE_TYPE_IOS);
}
prePay.setNotify_url(notify_url);
prePay.setOut_trade_no(orderNo);
prePay.setSpbill_create_ip(spbill_create_ip);//"123.12.12.123"
prePay.setTotal_fee(total_fee);
//此处添加获取openid的方法,获取预支付订单需要此参数!!!!!!!!!!!
// 获取预支付订单号
String prepayid = prePay.submitXmlGetPrepayId(0);
String jsParam = "";
if (prepayid != null && prepayid.length() > 10) {
// 生成微信支付参数,此处拼接为完整的JSON格式,符合支付调起传入格式
log.error("微信支付>>>>>>>>>:\n isWeixinPayConfigedForAppStore=" + isWeixinPayConfigedForAppStore);
log.error("prepayid=" + prepayid);
log.error("SystemConfig.APP_PARTNER_IOS=" + SystemConfig.APP_PARTNER_IOS);
log.error("SystemConfig.APP_ID_IOS=" + SystemConfig.APP_ID_IOS);
log.error("SystemConfig.APP_PARTNER_KEY_IOS=" + SystemConfig.APP_PARTNER_KEY_IOS);
log.error("SystemConfig.APP_TRADE_TYPE_IOS=" + SystemConfig.APP_TRADE_TYPE_IOS);
if (isWeixinPayConfigedForAppStore) {
jsParam = createPackageValue(SystemConfig.APP_ID, SystemConfig.APP_PARTNER, prepayid, version);
} else {
jsParam = createPackageValue(SystemConfig.APP_ID_IOS, SystemConfig.APP_PARTNER_IOS, prepayid, version);
}
}
return jsParam;
}
/**
* app 生成签名
* @param appid
* @param appKey
* @param prepay_id
* @return
*/
public static String createPackageValue(String appid, String appKey, String prepay_id, int version) {
JSONObject res = new JSONObject();
res.put("appid", appid);
Random random = new Random();
String randomStr = MD5.GetMD5String(String.valueOf(random.nextInt(10000)));
res.put("noncestr", MD5Util.MD5Encode(randomStr, "utf-8").toLowerCase());//
res.put("package", "Sign=WXPay");//"prepay_id=" + prepay_id
res.put("partnerid", appKey);
res.put("prepayid", prepay_id);
String timeStamp = OrderUtil.GetTimestamp();
res.put("timestamp", timeStamp);
//参考以下两个方法
//https://pay.weixin.qq.com/wiki/tools/signverify/
//https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
SortedMap<Object,Object> nativeObj = new TreeMap<Object,Object>();
nativeObj.put("appid", appid);
nativeObj.put("package", "Sign=WXPay");
nativeObj.put("partnerid", appKey);
nativeObj.put("prepayid", prepay_id);
nativeObj.put("noncestr", MD5Util.MD5Encode(randomStr, "utf-8").toLowerCase());//MD5Util.MD5Encode(randomStr, "utf-8").toLowerCase()
nativeObj.put("timestamp", timeStamp);
res.put("sign", createSign("UTF-8",nativeObj, version));
return res.toString();
}
/**
* app微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters, int version){
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
// app store 微信支付
if (0 == version) {
sb.append("key=" + SystemConfig.APP_PARTNER_KEY);
} else {
sb.append("key=" + SystemConfig.APP_PARTNER_KEY_IOS);
}
log.error("version:" + version);
log.error("SystemConfig.APP_PARTNER_KEY_IOS=" + SystemConfig.APP_PARTNER_KEY_IOS);
log.error("签名前是:" + sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
/*public static void main(String[] args) {
String Key = "cnitr89201000cnitr89201000CNITR5";
System.out.println(">>>模拟微信支付<<<");
System.out.println("==========华丽的分隔符==========");
jsParam={
"appId": "wxbd892cbfd413fe5d",
"nonceStr": "31547a539dc23628bfbee986b27c9fe0",
"package": "prepay_id=wx201604151714339c6dbe5f130465780715",
"paySign": "790DD69BD895C7651773A528B34F93DA",
"signType": "MD5",
"timeStamp": "1460711673"
}
//微信api提供的参数
String appid = "wxbd892cbfd413fe5d";
String mch_id = "1311800701";
String device_info = "1000";
String body = "test";
String nonce_str = "ibuaiVcKdpRxkhJA";
SortedMap<String,String> parameters = new TreeMap<String,String>();
parameters.put("appId", "wxbd892cbfd413fe5d");
parameters.put("nonceStr", "31547a539dc23628bfbee986b27c9fe0");
parameters.put("signType", "MD5");
parameters.put("timeStamp", "1460711673");
parameters.put("package", "prepay_id=wx201604151714339c6dbe5f130465780715");
// String characterEncoding = "UTF-8";
String weixinApiSign = "3E3AECED3FD250CBB22EBAC64E4913C1";
System.out.println("微信的签名是:" + weixinApiSign);
String mySign = createSignWeb(parameters,Key);
System.out.println("我 的签名是:"+mySign);
if(weixinApiSign.equals(mySign)){
System.out.println("恭喜你成功了~");
}else{
System.out.println("注定了你是个失败者~");
}
String userAgent = "Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X) AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206 MicroMessenger/5.0";
char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);
System.out.println("微信的版本号:"+new String(new char[]{agent}));
}
*/
/**
*获取h5支付支付参数并返回中间页链接
* @param amount
* @param spbill_create_ip
* @param orderNo
* @param activityId
* @param token
* @param body
* @param notify_url
* @return
*/
public static String getH5PayParam(String amount,String spbill_create_ip, String orderNo, String activityId, String token, String body,String notify_url) {
WXPrepay prePay = new WXPrepay();
prePay.setAppid(SystemConfig.WINXIN_AppID);//pay.getAppId()
prePay.setBody(body);
prePay.setPartnerKey(SystemConfig.WINXIN_PARTNER_KEY);//pay.getPartnerKey()
prePay.setMch_id(SystemConfig.WINXIN_PARTNER);//pay.getPartnerId()
prePay.setNotify_url("https://"+SystemConfig.weixinHost+"/icircle/activity/notice.do");
prePay.setOut_trade_no(orderNo);
prePay.setSpbill_create_ip(spbill_create_ip);//"123.12.12.123"
prePay.setTotal_fee(amount);
prePay.setTrade_type("MWEB");
log.error("getH5PayParam->payOrderDto:{},appId:{},mchId:{},partnerKey:{},subMchId:{}",
prePay.getAppid(), prePay.getMch_id(), prePay, SystemConfig.WINXIN_AppID);
String xmlStr = prePay.getPackage();
log.error("xmlStr====="+xmlStr);
String response_body = HTTPUtils.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlStr,
"text/xml; charset=UTF-8", "UTF-8", null, null);
log.error("response_body====="+response_body);
String mweb_url = analysisXML(response_body, "mweb_url");
log.error("before->append mweb_url:{},,response_body:{}", mweb_url, response_body);
try {
mweb_url += "&redirect_url="
+ URLEncoder.encode(notify_url + "&token=" + token + "&payed=1", "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
log.error("after->append mweb_url:{},isIos:{}", mweb_url);
return mweb_url;
}
/**
* 解析指定xml字符串,获取指定节点名称的文本信息
*/
private static String analysisXML(String xmlStr, String nodeName) {
Document document;
try {
document = DocumentHelper.parseText(xmlStr);
Element rootElement = document.getRootElement();
Node node = rootElement.selectSingleNode("//" + nodeName);
if (node == null)
return null;
return node.getText();
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String xmlStr="<xml><appid>wx81470220f10b266e</appid>"+
"<body><![CDATA[参加活动 【活动名称】的报名费]]></body>"+
"<mch_id>1423414902</mch_id>"+
"<nonce_str>0DBCF39D413231953D442F2F17F80CD5</nonce_str>"+
"<notify_url>http://kcscl.qzlife.net/icircle/activity/notice.do</notify_url>"+
"<out_trade_no>20180821180143000001</out_trade_no>"+
"<sign><![CDATA[C948A38E3875E7B5D2F003E73D129391]]></sign>"+
"<spbill_create_ip>119.145.105.2</spbill_create_ip>"+
"<sub_mch_id>1511773781</sub_mch_id>"+
"<total_fee>1</total_fee>"+
"<trade_type>MWEB</trade_type>"+
"</xml>";
System.out.println(1);
String response_body = HTTPUtils.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlStr,
"text/xml; charset=UTF-8", "UTF-8", null, null);
System.out.println(response_body);
}
}
\ No newline at end of file
package com.xxfc.platform.universal.weixin.api;
import com.xxfc.platform.universal.weixin.util.MD5Util;
import com.xxfc.platform.universal.weixin.util.OrderUtil;
import com.xxfc.platform.universal.weixin.util.XMLUtil;
import java.util.Map;
import java.util.TreeMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.jdom.JDOMException;
import org.jsoup.Jsoup;
@Slf4j
public class WXPrepay {
private static String unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //预支付单接口
private static String orderquery = "https://api.mch.weixin.qq.com/pay/orderquery"; //查询订单接口
private static String refund = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //申请退款接口
private String appid;
private String mch_id;
private String nonce_str = OrderUtil.CreateNoncestr();
private String body;
private String out_trade_no;
private String total_fee;
private String spbill_create_ip;
private String trade_type;
private String notify_url;
private String sign;
private String partnerKey;
// 预支付订单号
private String prepay_id;
//微信订单号
private String transaction_id ;
//退款单号
private String out_refund_no;
//退款金额
private String refund_fee;
//操作者ID(商家号)
private String op_user_id;
private String openid;
/**
* 生成预支付订单
*
* @return
*/
public String submitXmlGetPrepayId(int type) {
// 创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// HttpClient
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
HttpPost httpPost = new HttpPost(unifiedorder);
System.out.println("生成预支付订单请求URL:"+unifiedorder);
String xml = (type==0 ? getPackage() : getPackageWithOpenId());
StringEntity entity;
try {
entity = new StringEntity(xml, "utf-8");
httpPost.setEntity(entity);
HttpResponse httpResponse;
// post请求
httpResponse = closeableHttpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
// 打印响应内容
String result = EntityUtils.toString(httpEntity, "UTF-8");
// System.out.println(result);
// 过滤
result = result.replaceAll("<![CDATA[|]]>", "");
String prepay_id = Jsoup.parse(result).select("prepay_id").html();
this.prepay_id = prepay_id;
if (prepay_id != null)
return prepay_id;
}
// 释放资源
closeableHttpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return prepay_id;
}
/**
* 请求订单查询接口
*/
@SuppressWarnings("unchecked")
public Map<String, String> reqOrderquery() {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
HttpPost httpPost = new HttpPost(orderquery);
String xml = getPackage();
StringEntity entity;
Map<String, String> map = null;
try {
entity = new StringEntity(xml, "utf-8");
httpPost.setEntity(entity);
HttpResponse httpResponse;
// post请求
httpResponse = closeableHttpClient.execute(httpPost);
// getEntity()
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
// 打印响应内容
String result = EntityUtils.toString(httpEntity, "UTF-8");
// 过滤
result = result.replaceAll("<![CDATA[|]]>", "");
try {
map = XMLUtil.doXMLParse(result);
} catch (JDOMException e) {
e.printStackTrace();
}
}
// 释放资源
closeableHttpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/*public static void main(String[] args) {
WXPrepay prePay = new WXPrepay();
prePay.setAppid(SystemConfig.WINXIN_AppID);//pay.getAppId()
prePay.setMch_id(SystemConfig.WINXIN_PARTNER);//pay.getPartnerId()
prePay.setTransaction_id("4000782001201604154870082793");
prePay.setTotal_fee("1");
prePay.setRefund_fee("1");
prePay.setOut_refund_no(OrderUtil.GetOrderNumber("T"));
prePay.setOp_user_id(SystemConfig.WINXIN_PARTNER);
prePay.setPartnerKey(SystemConfig.WINXIN_PARTNER_KEY);//pay.getPartnerKey()
System.out.println(prePay.getXMLTuiKuan());
}*/
public String getXMLTuiKuan(){
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("appid", this.appid);
treeMap.put("mch_id", this.mch_id);
treeMap.put("nonce_str", this.nonce_str);
treeMap.put("transaction_id", this.transaction_id);
treeMap.put("out_refund_no", this.out_refund_no);
treeMap.put("total_fee", this.total_fee);
treeMap.put("refund_fee", this.refund_fee);
treeMap.put("op_user_id", this.op_user_id);
StringBuilder sb = new StringBuilder();
for (String key : treeMap.keySet()) {
sb.append(key).append("=").append(treeMap.get(key)).append("&");
}
sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
treeMap.put("sign", sign);
StringBuilder xml = new StringBuilder();
xml.append("<xml>\n");
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
} else {
xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
}
}
xml.append("</xml>");
log.info(xml.toString());
return xml.toString();
}
public String getPackage() {
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("appid",this.appid);
treeMap.put("mch_id", this.mch_id);
treeMap.put("nonce_str", this.nonce_str);
treeMap.put("body", this.body);
treeMap.put("out_trade_no", this.out_trade_no);
treeMap.put("total_fee", this.total_fee);
treeMap.put("spbill_create_ip", this.spbill_create_ip);
treeMap.put("trade_type", this.trade_type);
treeMap.put("notify_url", this.notify_url);
StringBuilder sb = new StringBuilder();
for (String key : treeMap.keySet()) {
sb.append(key).append("=").append(treeMap.get(key)).append("&");
}
sb.append("key=" + partnerKey);
sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
treeMap.put("sign", sign);
StringBuilder xml = new StringBuilder();
xml.append("<xml>\n");
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
} else {
xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
}
}
xml.append("</xml>");
log.info(xml.toString());
return xml.toString();
}
public String getPackageWithOpenId() {
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("appid",this.appid);
treeMap.put("mch_id", this.mch_id);
treeMap.put("nonce_str", this.nonce_str);
treeMap.put("body", this.body);
treeMap.put("out_trade_no", this.out_trade_no);
treeMap.put("total_fee", this.total_fee);
treeMap.put("spbill_create_ip", this.spbill_create_ip);
treeMap.put("trade_type", this.trade_type);
treeMap.put("sub_openid", this.openid);
treeMap.put("notify_url", this.notify_url);
StringBuilder sb = new StringBuilder();
for (String key : treeMap.keySet()) {
sb.append(key).append("=").append(treeMap.get(key)).append("&");
}
sb.append("key=" + partnerKey);
sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
treeMap.put("sign", sign);
StringBuilder xml = new StringBuilder();
xml.append("<xml>\n");
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
} else {
xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
}
}
xml.append("</xml>");
log.info(xml.toString());
return xml.toString();
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getTotal_fee() {
return total_fee;
}
public void setTotal_fee(String total_fee) {
this.total_fee = total_fee;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getPartnerKey() {
return partnerKey;
}
public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getOut_refund_no() {
return out_refund_no;
}
public void setOut_refund_no(String out_refund_no) {
this.out_refund_no = out_refund_no;
}
public String getRefund_fee() {
return refund_fee;
}
public void setRefund_fee(String refund_fee) {
this.refund_fee = refund_fee;
}
public String getOp_user_id() {
return op_user_id;
}
public void setOp_user_id(String op_user_id) {
this.op_user_id = op_user_id;
}
public String getTransaction_id() {
return transaction_id;
}
public void setTransaction_id(String transaction_id) {
this.transaction_id = transaction_id;
}
}
package com.xxfc.platform.universal.weixin.api;
import com.github.wxiaoqi.security.common.util.process.SystemConfig;
import com.xxfc.platform.universal.weixin.util.MD5Util;
import com.xxfc.platform.universal.weixin.util.OrderUtil;
import com.xxfc.platform.universal.weixin.util.XMLUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.jdom.JDOMException;
/**
* 商家向用户转账,实现提现功能
* @author SunnyShang
*
*/
@Slf4j
public class WXSuppToUserPay {
private static String suppTouser = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";//商家向用户付款
private String mch_appid; //公众账号appid
private String mchid; //商户号
private String nonce_str;//随机字符串
private String sign;//签名
private String partner_trade_no;//商户订单号
private String openid;//用户openid
private String check_name;//校验用户姓名选项
private String re_user_name;//收款用户姓名(可选)
private String amount;//金额
private String desc;//企业付款描述信息
private String spbill_create_ip;//Ip地址
private String key;
public static void main(String[] args) throws Exception, IOException {
Map<String, String> map = WXSuppToUserPay.WeiXinTiXian("oRhMfwKwjNq2Ce-TxlqfoAqsYfww", "NO_CHECK", 500+"", "活动提现", "192.168.8.109");
if("SUCCESS".equals(map.get("return_code")))
{
if(!StringUtils.isBlank(map.get("payment_no")) && !StringUtils.isBlank(map.get("partner_trade_no")) )
{
System.out.println(map.get("partner_trade_no"));
System.out.println(map.get("payment_no"));
System.out.println(Integer.parseInt(System.currentTimeMillis()/1000+""));
}
System.out.println(map.get("return_code"));
}
// WXSuppToUserPay prePay = new WXSuppToUserPay();
/* prePay.setMch_appid(SystemConfig.WINXIN_AppID);
prePay.setMchid(SystemConfig.WINXIN_PARTNER);*/
// prePay.setMch_appid(SystemConfig.APP_ID);
// prePay.setMchid(SystemConfig.APP_PARTNER);
// prePay.setNonce_str( OrderUtil.CreateNoncestr());
// prePay.setPartner_trade_no(OrderUtil.GetOrderNumber("TX"));
// prePay.setOpenid("oRhMfwBQ-Ouqhff4AeFOqovgJOAs");
// prePay.setCheck_name("NO_CHECK");
// prePay.setAmount("100");
// prePay.setDesc("活动提现");
// prePay.setSpbill_create_ip("192.168.8.109");
// //prePay.setKey(SystemConfig.WINXIN_PARTNER_KEY);
// String result =postXML(suppTouser,prePay.getXMLTuiKuan());
// String result = "<xml>"+
// "<return_code><![CDATA[SUCCESS]]></return_code>"+
// "<return_msg><![CDATA[]]></return_msg>"+
// "<mch_appid><![CDATA[wxa9805823769294b6]]></mch_appid>"+
// "<mchid><![CDATA[1327473801]]></mchid>"+
// "<device_info><![CDATA[]]></device_info>"+
// "<nonce_str><![CDATA[FD45EBC1E1D76BC1FE0BA933E60E9957]]></nonce_str>"+
// "<result_code><![CDATA[SUCCESS]]></result_code>"+
// "<partner_trade_no><![CDATA[TX20160504120550000001]]></partner_trade_no>"+
// "<payment_no><![CDATA[1000018301201605040163328553]]></payment_no>"+
// "<payment_time><![CDATA[2016-05-04 12:05:51]]></payment_time>"+
// "</xml>";
//
//
// result = result.replaceAll("<![CDATA[|]]>", "");
//
// Map<String, String> map = XMLUtil.doXMLParse(result);
//
// System.out.println(map.get("return_code"));
// System.out.println(map.get("mchid"));
// System.out.println(map.get("payment_no"));
// System.out.println(map.get("partner_trade_no"));
// System.out.println(map.get("payment_time"));
}
public static Map<String,String> WeiXinTiXian(String openid,String check_name,String amount,String desc,String spbill_create_ip) throws Exception
{
WXSuppToUserPay prePay = new WXSuppToUserPay();
prePay.setMch_appid(SystemConfig.WINXIN_AppID);
prePay.setMchid(SystemConfig.WINXIN_PARTNER);
prePay.setNonce_str( OrderUtil.CreateNoncestr());
prePay.setPartner_trade_no(OrderUtil.GetOrderNumber("TX"));
prePay.setOpenid(openid);
prePay.setCheck_name(check_name);
prePay.setAmount(amount);
prePay.setDesc(desc);
prePay.setSpbill_create_ip(spbill_create_ip);
String result =postXML(suppTouser,prePay.getXMLTuiKuan());
result = result.replaceAll("<![CDATA[|]]>", "").replaceAll("支付成功", "pay sucess");
Map<String, String> map = XMLUtil.doXMLParse(result);
return map;
}
public static String postXML(String uri, String xml) {
CloseableHttpClient httpclient = null;
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//FileInputStream instream = new FileInputStream(new File("E:/apiclient_cert.p12"));
String path = Thread.currentThread().getContextClassLoader().getResource("/").getPath();
FileInputStream instream = new FileInputStream(new File(path+"/apiclient_cert.p12"));
try {
keyStore.load(instream, SystemConfig.WINXIN_PARTNER.toCharArray());
} finally {
if (instream != null)
instream.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, SystemConfig.APP_PARTNER.toCharArray()).build();
@SuppressWarnings("deprecation")
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return post(httpclient, uri, xml, "text/xml; charset=UTF-8", "UTF-8", null, null);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (httpclient != null) {
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static String post(CloseableHttpClient httpclient, String uri, String data, String miniType, String charset,
String cookie, String refer) {
HttpPost httpPost = new HttpPost(uri);
if (miniType != null) {
httpPost.setHeader("Content-Type", miniType);
}
if (data != null) {
StringEntity stringEntity = null;
try {
if (charset != null) {
stringEntity = new StringEntity(data, charset);
} else {
stringEntity = new StringEntity(data);
}
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
httpPost.setEntity(stringEntity);
}
if (cookie != null) {
httpPost.setHeader("Cookie", cookie);
}
if (refer != null) {
httpPost.setHeader("Refer", refer);
}
CloseableHttpResponse httpResponse = null;
HttpContext httContext = HttpClientContext.create();
try {
httpResponse = httpclient.execute(httpPost, httContext);
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
HttpEntity httpEntity = null;
try {
httpEntity = httpResponse.getEntity();
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
String response_body = null;
try {
response_body = EntityUtils.toString(httpEntity);
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
try {
httpResponse.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
httpclient.close();
} catch (Exception e) {
e.printStackTrace();
}
return response_body;
}
public String getXMLTuiKuan(){
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("mch_appid", this.mch_appid);
treeMap.put("mchid", this.mchid);
treeMap.put("nonce_str", this.nonce_str);
treeMap.put("partner_trade_no", this.partner_trade_no);
treeMap.put("openid", this.openid);
treeMap.put("check_name", this.check_name);
//treeMap.put("re_user_name", this.re_user_name);
treeMap.put("amount", this.amount);
treeMap.put("desc", this.desc);
treeMap.put("spbill_create_ip", this.spbill_create_ip);
//treeMap.put("key", this.key);
//treeMap.put("sign", this.sign);
StringBuilder sb = new StringBuilder();
for (String key : treeMap.keySet()) {
sb.append(key).append("=").append(treeMap.get(key)).append("&");
}
sb.append("key=" + SystemConfig.WINXIN_PARTNER_KEY);
sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
treeMap.put("sign", sign);
StringBuilder xml = new StringBuilder();
xml.append("<xml>\n");
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
} else {
xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
}
}
xml.append("</xml>");
return xml.toString();
}
public String getMch_appid() {
return mch_appid;
}
public void setMch_appid(String mch_appid) {
this.mch_appid = mch_appid;
}
public String getMchid() {
return mchid;
}
public void setMchid(String mchid) {
this.mchid = mchid;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getPartner_trade_no() {
return partner_trade_no;
}
public void setPartner_trade_no(String partner_trade_no) {
this.partner_trade_no = partner_trade_no;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getCheck_name() {
return check_name;
}
public void setCheck_name(String check_name) {
this.check_name = check_name;
}
public String getRe_user_name() {
return re_user_name;
}
public void setRe_user_name(String re_user_name) {
this.re_user_name = re_user_name;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
package com.xxfc.platform.universal.weixin.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.protocol.HttpContext;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
@Slf4j
public class HTTPUtils{
private static PoolingHttpClientConnectionManager connManager;
private static RequestConfig requestConfig;
private static final int MAX_TIMEOUT = 10 * 1000;
static {
// 设置连接池
connManager = new PoolingHttpClientConnectionManager();
// 设置连接池大小
connManager.setMaxTotal(100);
connManager.setDefaultMaxPerRoute(connManager.getMaxTotal());
// 在提交请求之前 测试连接是否可用
connManager.setValidateAfterInactivity(3600);
RequestConfig.Builder configBuilder = RequestConfig.custom();
// 设置连接超时
configBuilder.setConnectTimeout(MAX_TIMEOUT);
// 设置读取超时
configBuilder.setSocketTimeout(MAX_TIMEOUT);
// 设置从连接池获取连接实例的超时
configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
requestConfig = configBuilder.build();
}
/**
* 发送 GET 请求(HTTP),不带输入数据
* @param url
* @return
*/
public static String doGet(String url) {
return doGet(url, new LinkedHashMap<String, Object>());
}
public static String getParams(String url,Map<String,Object> params)
{
if(StringUtils.isBlank(url)) return null;
StringBuilder param = new StringBuilder();
int i = 0;
for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}
url += param;
return url;
}
/**
* 发送 GET 请求(HTTP),K-V形式
* @param url
* @param params
* @return
*/
public static String doGet(String url, Map<String, Object> params) {
if(StringUtils.isBlank(url)) return null;
StringBuilder param = new StringBuilder();
int i = 0;
/* for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}*/
for (Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if(value==null)
continue;
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(value);
i++;
}
url += param;
String result = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet httpPost = new HttpGet(url);
HttpResponse response = httpclient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
// System.out.println("执行状态码 : " + statusCode);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, "UTF-8");
}
} catch (Exception e) {
log.error(e.getMessage());
}
return result;
}
private static HttpGet setJsonHeader(HttpGet httpGet){
httpGet.setHeader("Content-Type", "application/json");
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("charset", "utf-8");
return httpGet;
}
public static String doGetJson(String url, Map<String, Object> params) {
if(StringUtils.isBlank(url)) return null;
StringBuilder param = new StringBuilder();
int i = 0;
if(params != null){
for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}
url += param;
}
String result = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet(url);
//httpGet = setJsonHeader(httpGet);
HttpResponse response = httpclient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
// System.out.println("执行状态码 : " + statusCode);
File file = new File("D:\\t.txt");
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
FileOutputStream fips = new FileOutputStream(file);
result = IOUtils.toString(instream, "UTF-8");
fips.write(result.getBytes());
}
} catch (Exception e) {
log.error(e.getMessage());
}
return result;
}
/**
* 发送 POST 请求(HTTP),不带输入数据
* @param url
* @return
*/
public static String doPost(String url) {
return doPost(url, new LinkedHashMap<String, Object>());
}
/**
* 发送 POST 请求(HTTP),K-V形式
* @param url
* @param params
* @return
*/
public static String doPost(String url, Map<String, Object> params) {
if(StringUtils.isBlank(url)) return null;
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = null;
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
httpPost.setConfig(requestConfig);
List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());
for (Entry<String, Object> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
pairList.add(pair);
}
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
return result;
}
/**
* 发送 POST 请求(HTTP),K-V形式
* @param url
* @param data
* @return
*/
public static String doPost(String url, String data) {
if(StringUtils.isBlank(url)) return null;
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = null;
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
httpPost.setConfig(requestConfig);
StringEntity entiry = new StringEntity(data, "UTF-8");
httpPost.setEntity(entiry);
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
return result;
}
/**
*
* @Description: get方法获取字节流
* @param url
* @return
* @throws Exception
* @throws
*/
public static ByteBuffer getImageFromUrl(String url) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
ByteBuffer buffer = null;
try {
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
HttpEntity entity = response.getEntity();
InputStream inStream = entity.getContent();
buffer = ByteBuffer.allocate(inStream.available());
int b = inStream.read();
while (b != -1) {
buffer.put((byte)b);
b = inStream.read();
}
System.out.println("length="+buffer.array().length);
EntityUtils.consume(entity);
} finally {
response.close();
}
}finally {
httpclient.close();
}
return buffer;
}
public static ByteBuffer download(String _url) throws Exception{
ByteBuffer buffer = null;
try {
// 构造URL
URL url = new URL(_url);
// 打开连接
URLConnection con = url.openConnection();
//设置请求超时为5s
con.setConnectTimeout(5*1000);
// 输入流
InputStream inStream = con.getInputStream();
buffer = ByteBuffer.allocate(inStream.available());
int b = inStream.read();
String tempStr = "";
int ii = 0;
while (b != -1) {
buffer.put((byte)b);
b = inStream.read();
tempStr += b;
ii++;
}
inStream.close();
System.out.println("tempStr="+ii);
} catch (IOException e) {
}
return buffer;
}
/**
* post请求提交数据, 例如xml, json
* @param uri
* @param data
* @param miniType
* @param charset
* @param cookie
* @param refer
* @return
*/
public static String post(String uri, String data, String miniType, String charset, String cookie, String refer) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(uri);
if (charset!=null&&!"".equals(charset)) {
httpPost.setHeader("Content-Type", miniType);
}
if (data!=null&&!"".equals(data)) {
StringEntity stringEntity = null;
try {
if (charset != null) {
stringEntity = new StringEntity(data, charset);
} else {
stringEntity = new StringEntity(data);
}
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
httpPost.setEntity(stringEntity);
}
if (cookie!=null&&!"".equals(cookie)) {
httpPost.setHeader("Cookie", cookie);
}
if (refer!=null&&!"".equals(refer)) {
httpPost.setHeader("Refer", refer);
}
CloseableHttpResponse httpResponse = null;
HttpContext httContext = HttpClientContext.create();
try {
httpResponse = httpClient.execute(httpPost, httContext);
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
HttpEntity httpEntity = null;
try {
httpEntity = httpResponse.getEntity();
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
String response_body = null;
try {
response_body = EntityUtils.toString(httpEntity, "utf-8");
} catch (Exception e) {
e.printStackTrace();
return "failure";
}
try {
httpResponse.close();
} catch (Exception e) {
e.printStackTrace();
}
return response_body;
}
}
package com.xxfc.platform.universal.weixin.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
/**
* Http客户端工具类<br/>
* 这是内部调用类,请不要在外部调用。
* @author miklchen
*
*/
public class HttpClientUtil {
public static final String SunX509 = "SunX509";
public static final String JKS = "JKS";
public static final String PKCS12 = "PKCS12";
public static final String TLS = "TLS";
/**
* get HttpURLConnection
* @param strUrl url地址
* @return HttpURLConnection
* @throws IOException
*/
public static HttpURLConnection getHttpURLConnection(String strUrl)
throws IOException {
URL url = new URL(strUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
return httpURLConnection;
}
/**
* get HttpsURLConnection
* @param strUrl url地址
* @return HttpsURLConnection
* @throws IOException
*/
public static HttpsURLConnection getHttpsURLConnection(String strUrl)
throws IOException {
URL url = new URL(strUrl);
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url
.openConnection();
return httpsURLConnection;
}
/**
* 获取不带查询串的url
* @param strUrl
* @return String
*/
public static String getURL(String strUrl) {
if(null != strUrl) {
int indexOf = strUrl.indexOf("?");
if(-1 != indexOf) {
return strUrl.substring(0, indexOf);
}
return strUrl;
}
return strUrl;
}
/**
* 获取查询串
* @param strUrl
* @return String
*/
public static String getQueryString(String strUrl) {
if(null != strUrl) {
int indexOf = strUrl.indexOf("?");
if(-1 != indexOf) {
return strUrl.substring(indexOf+1, strUrl.length());
}
return "";
}
return strUrl;
}
/**
* 查询字符串转换成Map<br/>
* name1=key1&name2=key2&...
* @param queryString
* @return
*/
public static Map queryString2Map(String queryString) {
if(null == queryString || "".equals(queryString)) {
return null;
}
Map m = new HashMap();
String[] strArray = queryString.split("&");
for(int index = 0; index < strArray.length; index++) {
String pair = strArray[index];
HttpClientUtil.putMapByPair(pair, m);
}
return m;
}
/**
* 把键值添加至Map<br/>
* pair:name=value
* @param pair name=value
* @param m
*/
public static void putMapByPair(String pair, Map m) {
if(null == pair || "".equals(pair)) {
return;
}
int indexOf = pair.indexOf("=");
if(-1 != indexOf) {
String k = pair.substring(0, indexOf);
String v = pair.substring(indexOf+1, pair.length());
if(null != k && !"".equals(k)) {
m.put(k, v);
}
} else {
m.put(pair, "");
}
}
/**
* BufferedReader转换成String<br/>
* 注意:流关闭需要自行处理
* @param reader
* @return String
* @throws IOException
*/
public static String bufferedReader2String(BufferedReader reader) throws IOException {
StringBuffer buf = new StringBuffer();
String line = null;
while( (line = reader.readLine()) != null) {
buf.append(line);
buf.append("\r\n");
}
return buf.toString();
}
/**
* 处理输出<br/>
* 注意:流关闭需要自行处理
* @param out
* @param data
* @param len
* @throws IOException
*/
public static void doOutput(OutputStream out, byte[] data, int len)
throws IOException {
int dataLen = data.length;
int off = 0;
while(off < dataLen) {
if(len >= dataLen) {
out.write(data, off, dataLen);
} else {
out.write(data, off, len);
}
//刷新缓冲区
out.flush();
off += len;
dataLen -= len;
}
}
/**
* 获取SSLContext
* @param trustPasswd
* @param keyPasswd
* @return
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws IOException
* @throws CertificateException
* @throws UnrecoverableKeyException
* @throws KeyManagementException
*/
public static SSLContext getSSLContext(
FileInputStream trustFileInputStream, String trustPasswd,
FileInputStream keyFileInputStream, String keyPasswd)
throws NoSuchAlgorithmException, KeyStoreException,
CertificateException, IOException, UnrecoverableKeyException,
KeyManagementException {
// ca
TrustManagerFactory tmf = TrustManagerFactory.getInstance(HttpClientUtil.SunX509);
KeyStore trustKeyStore = KeyStore.getInstance(HttpClientUtil.JKS);
trustKeyStore.load(trustFileInputStream, HttpClientUtil
.str2CharArray(trustPasswd));
tmf.init(trustKeyStore);
final char[] kp = HttpClientUtil.str2CharArray(keyPasswd);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(HttpClientUtil.SunX509);
KeyStore ks = KeyStore.getInstance(HttpClientUtil.PKCS12);
ks.load(keyFileInputStream, kp);
kmf.init(ks, kp);
SecureRandom rand = new SecureRandom();
SSLContext ctx = SSLContext.getInstance(HttpClientUtil.TLS);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), rand);
return ctx;
}
/**
* 获取CA证书信息
* @param cafile CA证书文件
* @return Certificate
* @throws CertificateException
* @throws IOException
*/
public static Certificate getCertificate(File cafile)
throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream(cafile);
Certificate cert = cf.generateCertificate(in);
in.close();
return cert;
}
/**
* 字符串转换成char数组
* @param str
* @return char[]
*/
public static char[] str2CharArray(String str) {
if(null == str) return null;
return str.toCharArray();
}
/**
* 存储ca证书成JKS格式
* @param cert
* @param alias
* @param password
* @param out
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws CertificateException
* @throws IOException
*/
public static void storeCACert(Certificate cert, String alias,
String password, OutputStream out) throws KeyStoreException,
NoSuchAlgorithmException, CertificateException, IOException {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
ks.setCertificateEntry(alias, cert);
// store keystore
ks.store(out, HttpClientUtil.str2CharArray(password));
}
public static InputStream String2Inputstream(String str) {
return new ByteArrayInputStream(str.getBytes());
}
}
package com.xxfc.platform.universal.weixin.util;
public class MD5 {
static MD5 instance = new MD5();
/**
* MD5加密
* @param data
* @return
*/
public static String GetMD5String(String data) {
return MD5Util.MD5Encode(data, "utf-8").toUpperCase();
}
/**
* MD5加密
* @param data
* @param charsetname 字符编码,UTF-8, GB2312
* @return
*/
public static String GetMD5String(String data, String charsetname) {
return MD5Util.MD5Encode(data, charsetname);
}
/*
* 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static
* final是表示了只读,切能在同一个进程空间内的多个 Instance间共享
*/
static final int S11 = 7;
static final int S12 = 12;
static final int S13 = 17;
static final int S14 = 22;
static final int S21 = 5;
static final int S22 = 9;
static final int S23 = 14;
static final int S24 = 20;
static final int S31 = 4;
static final int S32 = 11;
static final int S33 = 16;
static final int S34 = 23;
static final int S41 = 6;
static final int S42 = 10;
static final int S43 = 15;
static final int S44 = 21;
static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0 };
/*
* 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中 被定义到MD5_CTX结构中
*/
private long[] state = new long[4]; // state (ABCD)
private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb
// first)
private byte[] buffer = new byte[64]; // input buffer
/*
* digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的   16进制ASCII表示.
*/
public String digestHexStr;
/*
* digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.
*/
private byte[] digest = new byte[16];
/*
* getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串
* 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
*/
public String getMD5String(String data) {
md5Init();
md5Update(data.getBytes(), data.length());
md5Final();
digestHexStr = "";
for (int i = 0; i < 16; i++) {
digestHexStr += byteHEX(digest[i]);
}
return digestHexStr;
}
// 这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
public MD5() {
md5Init();
return;
}
/* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */
private void md5Init() {
count[0] = 0L;
count[1] = 0L;
// /* Load magic initialization constants.
state[0] = 0x67452301L;
state[1] = 0xefcdab89L;
state[2] = 0x98badcfeL;
state[3] = 0x10325476L;
return;
}
/*
* F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是
* 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们   实现成了private方法,名字保持了原来C中的。
*/
private long F(long x, long y, long z) {
return (x & y) | ((~x) & z);
}
private long G(long x, long y, long z) {
return (x & z) | (y & (~z));
}
private long H(long x, long y, long z) {
return x ^ y ^ z;
}
private long I(long x, long y, long z) {
return y ^ (x | (~z));
}
/*
* FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for
* rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent
* recomputation.
*/
private long FF(long a, long b, long c, long d, long x, long s, long ac) {
a += F(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}
private long GG(long a, long b, long c, long d, long x, long s, long ac) {
a += G(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}
private long HH(long a, long b, long c, long d, long x, long s, long ac) {
a += H(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}
private long II(long a, long b, long c, long d, long x, long s, long ac) {
a += I(b, c, d) + x + ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a += b;
return a;
}
/*
* md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
* 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的
*/
private void md5Update(byte[] inbuf, int inputLen) {
int i, index, partLen;
byte[] block = new byte[64];
index = (int) (count[0] >>> 3) & 0x3F;
// /* Update number of bits */
if ((count[0] += (inputLen << 3)) < (inputLen << 3))
count[1]++;
count[1] += (inputLen >>> 29);
partLen = 64 - index;
// Transform as many times as possible.
if (inputLen >= partLen) {
md5Memcpy(buffer, inbuf, index, 0, partLen);
md5Transform(buffer);
for (i = partLen; i + 63 < inputLen; i += 64) {
md5Memcpy(block, inbuf, 0, i, 64);
md5Transform(block);
}
index = 0;
} else
i = 0;
// /* Buffer remaining input */
md5Memcpy(buffer, inbuf, index, i, inputLen - i);
}
/*
* md5Final整理和填写输出结果
*/
private void md5Final() {
byte[] bits = new byte[8];
int index, padLen;
// /* Save number of bits */
Encode(bits, count, 8);
// /* Pad out to 56 mod 64.
index = (int) (count[0] >>> 3) & 0x3f;
padLen = (index < 56) ? (56 - index) : (120 - index);
md5Update(PADDING, padLen);
// /* Append length (before padding) */
md5Update(bits, 8);
// /* Store state in digest */
Encode(digest, state, 16);
}
/*
* md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的      
* 字节拷贝到output的outpos位置开始
*/
private void md5Memcpy(byte[] output, byte[] input, int outpos, int inpos,
int len) {
int i;
for (i = 0; i < len; i++)
output[outpos + i] = input[inpos + i];
}
/*
* md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节
*/
private void md5Transform(byte block[]) {
long a = state[0], b = state[1], c = state[2], d = state[3];
long[] x = new long[16];
Decode(x, block, 64);
/* Round 1 */
a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
/* Round 2 */
a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
/* Round 3 */
a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
/* Round 4 */
a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
/*
* Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途
*/
private void Encode(byte[] output, long[] input, int len) {
int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (byte) (input[i] & 0xffL);
output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
}
}
/*
* Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的,
* 只合成低32bit,高32bit清零,以适应原始C实现的用途
*/
private void Decode(long[] output, byte[] input, int len) {
int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8)
| (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24);
return;
}
/*
* b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
*/
public static long b2iu(byte b) {
return b < 0 ? b & 0x7F + 128 : b;
}
/*
* byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示,
*  因为java中的byte的toString无法实现这一点,我们又没有C语言中的 sprintf(outbuf,"%02X",ib)
*/
public static String byteHEX(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}
}
\ No newline at end of file
package com.xxfc.platform.universal.weixin.util;
import java.security.MessageDigest;
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
//Sha1签名
public static String getSha1(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("GBK"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
}
package com.xxfc.platform.universal.weixin.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class OrderUtil {
static Date today = new Date();
static int orderIndex = 0;
@SuppressWarnings("deprecation")
private static String getIndex() {
Date n = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String currTime = outFormat.format(n);
if (orderIndex > 0) {
if (n.getYear() == today.getYear() && n.getMonth() == today.getMonth() && n.getDay() == today.getDay()) {
orderIndex += 1;
} else {
today = n;
orderIndex = 1;
}
} else {
today = n;
orderIndex = 1;
}
if (orderIndex > 999999) {
orderIndex = 1;
}
String indexString = String.format("%s%06d", currTime, orderIndex);
return indexString;
}
/**
* 生成订单号
*
* @param preFixString
* @return
*/
public static String GetOrderNumber(String preFixString) {
String orderNumberString = preFixString + getIndex();
return orderNumberString;
}
/**
* 获取时间戳
*
* @return
*/
public static String GetTimestamp() {
return Long.toString(new Date().getTime() / 1000);
}
/**
* 生成随机数
*
* @return
*/
public static String CreateNoncestr() {
Random random = new Random();
return MD5.GetMD5String(String.valueOf(random.nextInt(10000)));
}
}
package com.xxfc.platform.universal.weixin.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
/**
* xml工具类
* @author miklchen
*
*/
@Slf4j
public class XMLUtil {
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
if(null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = HttpClientUtil.String2Inputstream(strxml);
// 2018-12-19注释原代码
// SAXBuilder builder = new SAXBuilder();
// Document doc = builder.build(in);
// Element root = doc.getRootElement();
// 2018-12-19,添加XXE漏洞代码(下6行代码)
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = builder.build(in);
Element root = doc.getRootElement();
log.error("==== XMLUtil.doXMLParse ===== ");
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
* @param children
* @return String
*/
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
}
/**
* 获取xml编码字符集
* @param strxml
* @return
* @throws IOException
* @throws JDOMException
*/
public static String getXMLEncoding(String strxml) throws JDOMException, IOException {
InputStream in = HttpClientUtil.String2Inputstream(strxml);
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
in.close();
return (String)doc.getProperty("encoding");
}
}
package com.xxfc.platform.universal.biz;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.util.process.SystemConfig;
import com.github.wxiaoqi.security.common.util.result.JsonResultUtil;
import com.xxfc.platform.universal.vo.OrderPayVo;
import com.xxfc.platform.universal.weixin.api.WXPay;
import com.xxfc.platform.universal.weixin.util.OrderUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.xxfc.platform.universal.entity.OrderPay;
import com.xxfc.platform.universal.mapper.OrderPayMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
/**
* 订单支付
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
@Service
@Slf4j
public class OrderPayBiz extends BaseBiz<OrderPayMapper,OrderPay> {
public JSONObject preparepay( OrderPayVo orderPayVo) {
if(null == orderPayVo) {
log.error("-----参数为空-----------");
return JsonResultUtil.createFailedResult(ResultCode.NULL_CODE, "参数为空");
}
if(orderPayVo.getAmount()==null||orderPayVo.getAmount()==0) {
log.error("-----金额不为为0-----------");
return JsonResultUtil.createFailedResult(ResultCode.NULL_CODE, "金额不为为0");
}
if(StringUtils.isBlank(orderPayVo.getOrderNo())) {
log.error("-----订单不能为空-----------");
return JsonResultUtil.createFailedResult(ResultCode.NULL_CODE, "订单不能为空");
}
String trade_no = OrderUtil.GetOrderNumber("");
String order_no=orderPayVo.getOrderNo();
Integer amount=orderPayVo.getAmount();
log.error("---下单---order_no====="+order_no+"--支付订单号--trade_no===="+trade_no+"--金额---amount===="+amount);
//报名费回调路径
String jsParam = WXPay.apppay(amount+"",orderPayVo.getBody(),"https://"+ SystemConfig.weixinHost+"/icircle/activity/notice.do" ,order_no,orderPayVo.getBuyerIp(),0);
log.info("报名费回调路径jsParam:"+jsParam);
if(!StringUtils.isBlank(jsParam))
{
try {
OrderPay orderPay= new OrderPay();
BeanUtils.copyProperties(orderPay,orderPayVo);
orderPay.setTradeNo(trade_no);
orderPay.setSellerAccount(SystemConfig.APP_PARTNER);
insertSelective(orderPay);
log.error("---下单---order_no====="+order_no+"----成功");
} catch (Exception e) {
e.printStackTrace();
log.error("---下单---order_no====="+order_no+"----异常---msg==="+ e.getMessage());
return JsonResultUtil.createFailedResult(ResultCode.EXCEPTION_CODE, "出现异常");
}
JSONObject temp = JSON.parseObject(jsParam);
return JsonResultUtil.createSuccessResultWithObj(temp);
}else{
return JsonResultUtil.createDefaultFail();
}
}
//支付回调
public void notice(String orderNo,String serialNumber){
log.error("---支付回调---order_no====="+orderNo+"----开始处理");
Example example =new Example(OrderPay.class);
example.createCriteria().andEqualTo("order_no",orderNo).andEqualTo("is_del",0).andEqualTo("status",0);
List<OrderPay> list=mapper.selectByExample(example);
if(list.size()==0){
log.error("---支付回调---order_no====="+orderNo+"----订单不存在或已处理");
return;
}
example.clear();
example.createCriteria().andEqualTo("order_no",orderNo);
OrderPay orderPay=new OrderPay();
orderPay.setFinishTime(System.currentTimeMillis());
orderPay.setStatus(1);
orderPay.setSerialNumber(serialNumber);
mapper.updateByExampleSelective(orderPay,example);
}
}
\ No newline at end of file
package com.xxfc.platform.universal.biz;
import org.springframework.stereotype.Service;
import com.xxfc.platform.universal.entity.OrderRefund;
import com.xxfc.platform.universal.mapper.OrderRefundMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
/**
* 订单支付退款表
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
@Service
public class OrderRefundBiz extends BaseBiz<OrderRefundMapper,OrderRefund> {
}
\ No newline at end of file
package com.xxfc.platform.universal.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.rest.BaseController;
import com.xxfc.platform.universal.biz.OrderPayBiz;
import com.xxfc.platform.universal.entity.OrderPay;
import com.xxfc.platform.universal.vo.OrderPayVo;
import com.xxfc.platform.universal.weixin.util.XMLUtil;
import org.jdom.JDOMException;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;
@RestController
@RequestMapping("pay")
public class OrderPayController extends BaseController<OrderPayBiz,OrderPay> {
/**
* APP支付
*
* @param orderPayVo
* @return
* @throws Exception
*/
@RequestMapping(value = "/app/wx", method = RequestMethod.POST) //匹配的是href中的download请求
public JSONObject wx(@RequestBody OrderPayVo orderPayVo) {
return baseBiz.preparepay(orderPayVo);
}
/**
* 支付回调
*
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(value = "/app/unauth/notify", method = RequestMethod.POST) //匹配的是href中的download请求
@IgnoreUserToken
public void notice(HttpServletRequest request, HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), "utf-8");
Map<String, String> map = null;
try {
map = XMLUtil.doXMLParse(result);
} catch (JDOMException e) {
e.printStackTrace();
}
if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
try {
String orderno = map.get("out_trade_no");
String serialNumber = map.get("transaction_id");
baseBiz.notice(orderno, serialNumber);
} catch (Exception e) {
e.printStackTrace();
}
out.print("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
} else
out.print("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[]]></return_msg></xml>");
}
}
\ No newline at end of file
package com.xxfc.platform.universal.controller;
import com.github.wxiaoqi.security.common.rest.BaseController;
import com.xxfc.platform.universal.biz.OrderRefundBiz;
import com.xxfc.platform.universal.entity.OrderRefund;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("orderRefund")
public class OrderRefundController extends BaseController<OrderRefundBiz,OrderRefund> {
}
\ No newline at end of file
package com.xxfc.platform.universal.mapper;
import com.xxfc.platform.universal.entity.OrderPay;
import tk.mybatis.mapper.common.Mapper;
/**
* 订单支付
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
public interface OrderPayMapper extends Mapper<OrderPay> {
}
package com.xxfc.platform.universal.mapper;
import com.xxfc.platform.universal.entity.OrderRefund;
import tk.mybatis.mapper.common.Mapper;
/**
* 订单支付退款表
*
* @author zjw
* @email nishijjo@qq.com
* @date 2019-05-28 16:17:42
*/
public interface OrderRefundMapper extends Mapper<OrderRefund> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxfc.platform.universal.mapper.OrderPayMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.xxfc.platform.universal.entity.OrderPay" id="orderPayMap">
<result property="id" column="id"/>
<result property="tradeNo" column="trade_no"/>
<result property="orderNo" column="order_no"/>
<result property="userId" column="user_id"/>
<result property="payWay" column="pay_way"/>
<result property="channel" column="channel"/>
<result property="type" column="type"/>
<result property="buyerIp" column="buyer_ip"/>
<result property="subject" column="subject"/>
<result property="body" column="body"/>
<result property="notifyUrl" column="notify_url"/>
<result property="status" column="status"/>
<result property="amount" column="amount"/>
<result property="isDel" column="is_del"/>
<result property="serialNumber" column="serial_number"/>
<result property="buyerAccount" column="buyer_account"/>
<result property="sellerAccount" column="seller_account"/>
<result property="crtTime" column="crt_time"/>
<result property="updTime" column="upd_time"/>
<result property="finishTime" column="finish_time"/>
</resultMap>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxfc.platform.universal.mapper.OrderRefundMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.xxfc.platform.universal.entity.OrderRefund" id="orderRefundMap">
<result property="id" column="id"/>
<result property="refundTradeNo" column="refund_trade_no"/>
<result property="orderNo" column="order_no"/>
<result property="userId" column="user_id"/>
<result property="status" column="status"/>
<result property="amount" column="amount"/>
<result property="refundAmount" column="refund_amount"/>
<result property="isDel" column="is_del"/>
<result property="outRefundNo" column="out_refund_no"/>
<result property="serialNumber" column="serial_number"/>
<result property="crtTime" column="crt_time"/>
<result property="updTime" column="upd_time"/>
<result property="finishTime" column="finish_time"/>
</resultMap>
</mapper>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment