Commit 354b2487 authored by shiyu's avatar shiyu

保证金缴纳2

parent 5292fa19
package com.wwdz.ch.core.api.lianpay;
import com.wwdz.ch.core.api.lianpay.bean.ConfirmPaymentRequestBean;
import com.wwdz.ch.core.api.lianpay.bean.ConfirmPaymentResponseBean;
import com.wwdz.ch.core.api.lianpay.bean.QueryPaymentRequestBean;
import com.wwdz.ch.core.api.lianpay.bean.QueryPaymentResponseBean;
import com.wwdz.ch.core.api.lianpay.constant.PaymentConstant;
import com.wwdz.ch.core.api.lianpay.constant.PaymentStatusEnum;
import com.wwdz.ch.core.api.lianpay.constant.RetCodeEnum;
import com.wwdz.ch.core.api.lianpay.security.LianLianPaySecurity;
import com.wwdz.ch.core.api.lianpay.security.TraderRSAUtil;
import com.wwdz.ch.core.api.lianpay.util.HttpUtil;
import com.wwdz.ch.core.api.lianpay.util.SignUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* DEMO仅提供商户参考方便对接实时付款,具体对接看先细看实时付款API商户接口说明书
* 确认付款接口不是必须的,只用于当付款交易接口返回4002,4003,4004时
* 对于返回码4002和4004的疑似订单(文档中有说明),不能系统直接调用确认接口,要人工审核后才能调用
*/
public class ConfirmPaymentApiTest {
private static final Logger logger = LoggerFactory.getLogger(ConfirmPaymentApiTest.class);
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 连连内部测试环境数据(商户测试期间需要用正式的数据测试,测试时默认单笔单日单月额度50,等测试OK,和连连技术核对过业务对接逻辑后,申请走上线流程打开额度)
ConfirmPaymentRequestBean paymentRequestBean = new ConfirmPaymentRequestBean();
paymentRequestBean.setNo_order("20170208165924");
// 当调用付款接口返回4002,4003,4004时,会返回验证码信息
paymentRequestBean.setConfirm_code("137007");
// 填写商户自己的接收付款结果回调异步通知 长度
paymentRequestBean.setNotify_url("http://192.168.110.13:8080/test/tradepayapi/receiveNotify.htm");
paymentRequestBean.setOid_partner(PaymentConstant.OID_PARTNER);
// paymentRequestBean.setPlatform("test.com");
paymentRequestBean.setApi_version(PaymentConstant.API_VERSION);
paymentRequestBean.setSign_type(PaymentConstant.SIGN_TYPE);
// 用商户自己的私钥加签
paymentRequestBean.setSign(SignUtil.genRSASign(JSON.parseObject(JSON.toJSONString(paymentRequestBean))));
String jsonStr = JSON.toJSONString(paymentRequestBean);
// 用银通公钥对请求参数json字符串加密
// 报Illegal key
// size异常时,可参考这个网页解决问题http://www.wxdl.cn/java/security-invalidkey-exception.html
String encryptStr = LianLianPaySecurity.encrypt(jsonStr, PaymentConstant.PUBLIC_KEY_ONLINE);
if (StringUtils.isEmpty(encryptStr)) {
// 加密异常
logger.error("加密异常:");
return;
}
JSONObject json = new JSONObject();
json.put("oid_partner", PaymentConstant.OID_PARTNER);
json.put("pay_load", encryptStr);
String response = HttpUtil.doPost("https://instantpay.lianlianpay.com/paymentapi/confirmPayment.htm", json,
"UTF-8");
System.out.print("确认付款接口返回响应报文:" + response);
logger.info("确认付款接口返回响应报文:" + response);
if (StringUtils.isEmpty(response)) {
// 出现异常时调用订单查询,明确订单状态,不能私自设置订单为失败状态,以免造成这笔订单在连连付款成功了,而商户设置为失败
queryPaymentAndDealBusiness(paymentRequestBean.getNo_order());
} else {
ConfirmPaymentResponseBean confirmaymentResponseBean = JSONObject.parseObject(response,
ConfirmPaymentResponseBean.class);
// 对返回0000时验证签名
if (confirmaymentResponseBean.getRet_code().equals("0000")) {
// 先对结果验签
boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
SignUtil.genSignData(JSONObject.parseObject(response)), confirmaymentResponseBean.getSign());
if (!signCheck) {
// 传送数据被篡改,可抛出异常,再人为介入检查原因
logger.error("返回结果验签异常,可能数据被篡改");
return;
}
logger.info(paymentRequestBean.getNo_order() + "订单处于付款处理中");
// 已生成连连支付单,付款处理中(交易成功,不是指付款成功,是指跟连连流程正常),商户可以在这里处理自已的业务逻辑(或者不处理,在异步回调里处理逻辑),最终的付款状态由异步通知回调告知
} else if (RetCodeEnum.isNeedQuery(confirmaymentResponseBean.getRet_code())) {
// 出现1002,2005,4006,4007,4009,9999这6个返回码时(或者对除了0000之后的code都查询一遍查询接口)调用订单查询,明确订单状态,不能私自设置订单为失败状态,以免造成这笔订单在连连付款成功了,而商户设置为失败
// 第一次测试对接时,返回{"ret_code":"4007","ret_msg":"敏感信息解密异常"},可能原因报文加密用的公钥改动了,demo中的公钥是连连公钥,商户生成的公钥用于上传连连商户站用于连连验签,生成的私钥用于加签
queryPaymentAndDealBusiness(paymentRequestBean.getNo_order());
} else {
// 返回其他code时,可将订单置为失败
// TODO
System.out.println("failure");
}
}
}
// 异常时,先查询订单状态,再根据订单状态处理业务逻辑
public static void queryPaymentAndDealBusiness(String orderNo) {
// 连连内部测试环境数据
QueryPaymentRequestBean queryRequestBean = new QueryPaymentRequestBean();
queryRequestBean.setNo_order(orderNo);
queryRequestBean.setOid_partner(PaymentConstant.OID_PARTNER);
// queryRequestBean.setPlatform("test.com");
queryRequestBean.setApi_version(PaymentConstant.API_VERSION);
queryRequestBean.setSign_type(PaymentConstant.SIGN_TYPE);
queryRequestBean.setSign(SignUtil.genRSASign(JSON.parseObject(JSON.toJSONString(queryRequestBean))));
String queryResult = HttpUtil.doPost("https://instantpay.lianlianpay.com/paymentapi/queryPayment.htm",
JSON.parseObject(JSON.toJSONString(queryRequestBean)), "UTF-8");
logger.info("实时付款查询接口响应报文:" + queryResult);
if (StringUtils.isEmpty(queryResult)) {
// 可抛异常,查看原因
logger.error("实时付款查询接口响应异常");
return;
}
QueryPaymentResponseBean queryPaymentResponseBean = JSONObject.parseObject(queryResult,
QueryPaymentResponseBean.class);
// 先对结果验签
boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
SignUtil.genSignData(JSONObject.parseObject(queryResult)), queryPaymentResponseBean.getSign());
if (!signCheck) {
// 传送数据被篡改,可抛出异常,再人为介入检查原因
logger.error("返回结果验签异常,可能数据被篡改");
return;
}
if (queryPaymentResponseBean.getRet_code().equals("0000")) {
PaymentStatusEnum paymentStatusEnum = PaymentStatusEnum
.getPaymentStatusEnumByValue(queryPaymentResponseBean.getResult_pay());
// TODO商户根据订单状态处理自已的业务逻辑
switch (paymentStatusEnum) {
case PAYMENT_APPLY:
// 付款申请,这种情况一般不会发生,如出现,请直接找连连技术处理
break;
case PAYMENT_CHECK:
// 复核状态 TODO
// 返回4002,4003,4004时,订单会处于复核状态,这时还未创建连连支付单,没提交到银行处理,如需对该订单继续处理,需商户先人工审核这笔订单是否是正常的付款请求,没问题后再调用确认付款接口
// 如果对于复核状态的订单不做处理,可当做失败订单
break;
case PAYMENT_SUCCESS:
// 成功 TODO
break;
case PAYMENT_FAILURE:
// 失败 TODO
break;
case PAYMENT_DEALING:
// 处理中 TODO
break;
case PAYMENT_RETURN:
// 退款 TODO
// 可当做失败(退款情况
// 极小概率下会发生,个别银行处理机制是先扣款后打款给用户时再检验卡号信息是否正常,异常时会退款到连连商户账上)
break;
case PAYMENT_CLOSED:
// 关闭 TODO 可当做失败 ,对于复核状态的订单不做处理会将订单关闭
break;
default:
break;
}
} else if (queryPaymentResponseBean.getRet_code().equals("8901")) {
// 订单不存在,这种情况可以用原单号付款,最好不要换单号,如换单号,在连连商户站确认下改订单是否存在,避免系统并发时返回8901,实际有一笔订单
} else {
// 查询异常(极端情况下才发生,对于这种情况,可人工介入查询,在连连商户站查询或者联系连连客服,查询订单状态)
logger.error("查询异常");
}
}
}
package com.wwdz.ch.core.api.lianpay;
import com.wwdz.ch.core.api.lianpay.bean.BusinessNoticeBean;
import com.wwdz.ch.core.api.lianpay.bean.NotifyResponseBean;
import com.wwdz.ch.core.api.lianpay.constant.PaymentConstant;
import com.wwdz.ch.core.api.lianpay.constant.PaymentStatusEnum;
import com.wwdz.ch.core.api.lianpay.security.TraderRSAUtil;
import com.wwdz.ch.core.api.lianpay.util.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
/**
* 这个Controller需放到服务器上运行调试 异步回调接口
* 用于接收连连付款状态 只有生成连连支付单的订单才会有异步回调通知,
* 没生成连连支付单的订单连连是不会提交到银行渠道走付款流程
*
* 用spring mvc获取需要配置下面 或者参考另一个文件夹的异步回调demo从http request 数据流中获取
* <mvc:annotation-driven> <mvc:message-converters register-defaults="false">
* <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="fastJsonHttpMessageConverter"
* class=
* "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter "
* > <property name="supportedMediaTypes"> <list>
* <value>text/html;charset=UTF-8</value>
* <value>application/json;charset=UTF-8</value>
* <value>text/json;charset=UTF-8</value> </list> </property> </bean>
* </mvc:message-converters> </mvc:annotation-driven>
*
* @author lihp
* @date 2017-3-17 上午09:55:30
*/
@Controller
public class ImmediatePayNotifyController {
private static final Logger logger = LoggerFactory.getLogger(ImmediatePayNotifyController.class);
/**
* 支付平台异步通知更新 用这个demo需要xml配置json转化格式,不然回调接收异常,具体配置参考类注释
*
* @param request
* @return
*/
@RequestMapping(value = "/tradepayapi/receiveNotify", method = RequestMethod.POST)
@ResponseBody
public NotifyResponseBean receiveNotify(@RequestBody BusinessNoticeBean businessNoticeBean) {
logger.info("notify request:" + businessNoticeBean.toString());
NotifyResponseBean responseBean = new NotifyResponseBean();
boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
SignUtil.genSignData(JSONObject.parseObject(JSONObject.toJSONString(businessNoticeBean))),
businessNoticeBean.getSign());
if (!signCheck) {
// 传送数据被篡改,可抛出异常,再人为介入检查原因
logger.error("返回结果验签异常,可能数据被篡改");
// 回调内容先验签,再处理相应逻辑
responseBean.setRet_code("9999");
responseBean.setRet_msg("未知异常");
}
if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_SUCCESS.getValue())) {
// TODO 商户更新订单为成功,处理自己的业务逻辑
} else if (businessNoticeBean.getResult_pay().equals(PaymentStatusEnum.PAYMENT_FAILURE.getValue())) {
// TODO 商户更新订单为失败,处理自己的业务逻辑
} else {
// TODO 返回订单为退款状态 ,商户可以更新订单为失败或者退款
// 退款这种情况是极小概率情况下才会发生的,个别银行处理机制是先扣款后再打款给用户时,
// 才检验卡号姓名信息的有效性,当卡号姓名信息有误发生退款,实际上钱没打款到商户。
// 这种情况商户代码上也可不做考虑,如发生用户投诉未收到钱,可直接联系连连客服,连连会跟银行核对
// 退款情况,异步通知会通知两次,先通知成功,后通知退款(极小概率情况下才会发生的)
}
//回调内容先验签,再处理相应逻辑
responseBean.setRet_code("0000");
responseBean.setRet_msg("交易成功");
return responseBean;
}
}
package com.wwdz.ch.core.api.lianpay;
import com.wwdz.ch.core.api.lianpay.bean.QueryPaymentRequestBean;
import com.wwdz.ch.core.api.lianpay.bean.QueryPaymentResponseBean;
import com.wwdz.ch.core.api.lianpay.constant.PaymentConstant;
import com.wwdz.ch.core.api.lianpay.constant.PaymentStatusEnum;
import com.wwdz.ch.core.api.lianpay.security.TraderRSAUtil;
import com.wwdz.ch.core.api.lianpay.util.HttpUtil;
import com.wwdz.ch.core.api.lianpay.util.SignUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* DEMO仅提供商户参考方便对接实时付款,具体对接看先细看实时付款API商户接口说明书
*
*/
public class QueryApiTest {
String test = "{\"busi_partner\":\"101001\",\"sign\":\"Smky7Cb8xmgCb8s4DdfwBw77m+gZZ+clTwzoMWRhGUWs4xHb\\/HkUsLaWrwKB+CuKk9dky8SULxl1A6ZQlZlKpB1nhX8\\/p+7I8SLrOG\\/q8vEJGEA4jH2uM\\/Jk3Qh3ix9DEPXwUsscfSLRATcf5v6rsdlQFrIqaDXyc0Mw0dzDSzY=\",\"acct_name\":\"苏亮\",\"oid_partner\":\"201408071000001543\",\"risk_item\":\"{\\\"user_info_bind_phone\\\":\\\"15853239182\\\",\\\"user_info_identify_type\\\":\\\"4\\\",\\\"user_info_id_type\\\":\\\"0\\\",\\\"user_info_mercht_userlogin\\\":\\\"15853239182\\\",\\\"user_info_id_no\\\":\\\"370211199004212014\\\",\\\"user_info_mercht_userno\\\":\\\"70\\\"}\",\"no_order\":\"liang_t_20171228\",\"name_goods\":\"苏亮测试订单_2\",\"flag_modify\":\"1\",\"money_order\":\"0.01\",\"valid_order\":\"10080\",\"notify_url\":\"http:\\/\\/test.yintong.com.cn:80\\/apidemo\\/API_DEMO\\/notifyUrl.htm\",\"id_type\":\"0\",\"info_order\":\"test\",\"user_id\":\"\\nliang_test\",\"id_no\":\"141031199307290012\",\"sign_type\":\"RSA\",\"dt_order\":\"20171228142303\"}";
private static final Logger logger = LoggerFactory.getLogger(QueryApiTest.class);
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 连连内部测试环境数据
QueryPaymentRequestBean queryRequestBean = new QueryPaymentRequestBean();
queryRequestBean.setNo_order("20170208165923");
queryRequestBean.setOid_partner(PaymentConstant.OID_PARTNER);
queryRequestBean.setApi_version(PaymentConstant.API_VERSION);
queryRequestBean.setSign_type(PaymentConstant.SIGN_TYPE);
queryRequestBean.setSign(SignUtil.genRSASign(JSON.parseObject(JSON.toJSONString(queryRequestBean))));
System.out.println(SignUtil.genRSASign(JSON.parseObject(JSON.toJSONString(queryRequestBean))));
JSONObject json = JSON.parseObject(JSON.toJSONString(queryRequestBean));
String queryResult = HttpUtil.doPost("https://instantpay.lianlianpay.com/paymentapi/queryPayment.htm", json,
"UTF-8");
System.out.print("实时付款查询接口返回响应报文:" + queryResult);
logger.info("实时付款查询接口响应报文:" + queryResult);
if (StringUtils.isEmpty(queryResult)) {
// 可抛异常,查看原因
logger.error("实时付款查询接口响应异常");
return;
}
QueryPaymentResponseBean queryPaymentResponseBean = JSONObject.parseObject(queryResult,
QueryPaymentResponseBean.class);
// 先对结果验签
boolean signCheck = TraderRSAUtil.checksign(PaymentConstant.PUBLIC_KEY_ONLINE,
SignUtil.genSignData(JSONObject.parseObject(queryResult)), queryPaymentResponseBean.getSign());
if (!signCheck) {
// 传送数据被篡改,可抛出异常,再人为介入检查原因
logger.error("返回结果验签异常,可能数据被篡改");
return;
}
if (queryPaymentResponseBean.getRet_code().equals("0000")) {
PaymentStatusEnum paymentStatusEnum = PaymentStatusEnum
.getPaymentStatusEnumByValue(queryPaymentResponseBean.getResult_pay());
// TODO商户根据订单状态处理自已的业务逻辑
switch (paymentStatusEnum) {
case PAYMENT_APPLY:
// 付款申请,这种情况一般不会发生,如出现,请直接找连连技术处理
break;
case PAYMENT_CHECK:
// 复核状态 TODO
// 返回4002,4003,4004时,订单会处于复核状态,这时还未创建连连支付单,没提交到银行处理,如需对该订单继续处理,需商户先人工审核这笔订单是否是正常的付款请求,没问题后再调用确认付款接口
// 如果对于复核状态的订单不做处理,可当做失败订单
break;
case PAYMENT_SUCCESS:
// 成功 TODO
break;
case PAYMENT_FAILURE:
// 失败 TODO
break;
case PAYMENT_DEALING:
// 处理中 TODO
break;
case PAYMENT_RETURN:
// 退款 TODO
// 可当做失败(退款情况
// 极小概率下会发生,个别银行处理机制是先扣款后打款给用户时再检验卡号信息是否正常,异常时会退款到连连商户账上)
break;
case PAYMENT_CLOSED:
// 关闭 TODO 可当做失败 ,对于复核状态的订单不做处理会将订单关闭
break;
default:
break;
}
} else if (queryPaymentResponseBean.getRet_code().equals("8901")) {
// 订单不存在,这种情况可以用原单号付款,最好不要换单号,如换单号,在连连商户站确认下改订单是否存在,避免系统并发时返回8901,实际有一笔订单
} else {
// 查询异常(极端情况下才发生,对于这种情况,可人工介入查询,在连连商户站查询或者联系连连客服,查询订单状态)
logger.error("查询异常");
}
}
}
package com.wwdz.ch.core.api.lianpay.bean;
import java.io.Serializable;
/**
* 基础reponse bean
*
*/
public class BaseResponseBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1245259120617909449L;
/** 交易结果code . */
public String ret_code;
/** 交易结果描述 . */
public String ret_msg;
/** 签名方式 . */
public String sign_type;
/** 签名 . */
public String sign;
/** 商户编号 . */
public String oid_partner;
public String getRet_code() {
return ret_code;
}
public void setRet_code(String ret_code) {
this.ret_code = ret_code;
}
public String getRet_msg() {
return ret_msg;
}
public void setRet_msg(String ret_msg) {
this.ret_msg = ret_msg;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
}
package com.wwdz.ch.core.api.lianpay.bean;
import java.io.Serializable;
/**
* 异步
*
* @author lihp
* @date 2017-3-17 上午10:07:06
*/
public class BusinessNoticeBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = -821204118733047614L;
/** 商户编号 . */
private String oid_partner;
/** 签名方式 . */
private String sign_type;
/** 签名串 . */
private String sign;
/** 商户付款流水号即订单号. */
private String no_order;
/** 商户付款请求时间. */
private String dt_order;
/** 金额. */
private String money_order;
/** 连连支付单. */
private String oid_paybill;
/** 商户付款请求时间. */
private String info_order;
/** 订单状态,付款结果以订单状态为判断依据. */
private String result_pay;
/** 清算时间. */
private String settle_date;
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getDt_order() {
return dt_order;
}
public void setDt_order(String dt_order) {
this.dt_order = dt_order;
}
public String getMoney_order() {
return money_order;
}
public void setMoney_order(String money_order) {
this.money_order = money_order;
}
public String getOid_paybill() {
return oid_paybill;
}
public void setOid_paybill(String oid_paybill) {
this.oid_paybill = oid_paybill;
}
public String getInfo_order() {
return info_order;
}
public void setInfo_order(String info_order) {
this.info_order = info_order;
}
public String getResult_pay() {
return result_pay;
}
public void setResult_pay(String result_pay) {
this.result_pay = result_pay;
}
public String getSettle_date() {
return settle_date;
}
public void setSettle_date(String settle_date) {
this.settle_date = settle_date;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BusinessNoticeBean [oid_partner=");
builder.append(oid_partner);
builder.append(", sign_type=");
builder.append(sign_type);
builder.append(", sign=");
builder.append(sign);
builder.append(", no_order=");
builder.append(no_order);
builder.append(", dt_order=");
builder.append(dt_order);
builder.append(", money_order=");
builder.append(money_order);
builder.append(", oid_paybill=");
builder.append(oid_paybill);
builder.append(", info_order=");
builder.append(info_order);
builder.append(", result_pay=");
builder.append(result_pay);
builder.append(", settle_date=");
builder.append(settle_date);
builder.append("]");
return builder.toString();
}
}
package com.wwdz.ch.core.api.lianpay.bean;
/**
* 确认付款Bean
*
*/
public class ConfirmPaymentRequestBean {
/**
*
*/
private static final long serialVersionUID = -5151860453021854789L;
/** 商户付款流水号 . */
private String no_order;
/** 服务器异步通知地址 . */
private String notify_url;
/** 验证码 . */
private String confirm_code;
/** 商户编号 . */
private String oid_partner;
/** 用户来源 . */
private String platform;
/** api当前版本号 . */
private String api_version;
/** 签名方式 . */
private String sign_type;
/** 签名方 . */
private String sign;
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getConfirm_code() {
return confirm_code;
}
public void setConfirm_code(String confirm_code) {
this.confirm_code = confirm_code;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getApi_version() {
return api_version;
}
public void setApi_version(String api_version) {
this.api_version = api_version;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}
package com.wwdz.ch.core.api.lianpay.bean;
/**
* 确认付款response bean
*
*/
public class ConfirmPaymentResponseBean extends BaseResponseBean {
/**
*
*/
private static final long serialVersionUID = -4781024640608623981L;
/** 连连银通付款流水号 . */
public String oid_paybill;
/** 商户付款流水号 . */
private String no_order;
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getOid_paybill() {
return oid_paybill;
}
public void setOid_paybill(String oid_paybill) {
this.oid_paybill = oid_paybill;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ConfirmPaymentResponseBean [oid_paybill=");
builder.append(oid_paybill);
builder.append(", no_order=");
builder.append(no_order);
builder.append(", ret_code=");
builder.append(ret_code);
builder.append(", ret_msg=");
builder.append(ret_msg);
builder.append(", sign_type=");
builder.append(sign_type);
builder.append(", sign=");
builder.append(sign);
builder.append(", oid_partner=");
builder.append(oid_partner);
builder.append("]");
return builder.toString();
}
}
package com.wwdz.ch.core.api.lianpay.bean;
import java.io.Serializable;
/**
*
* 异步回调reponse
*
* @author lihp
* @date 2017-3-17 上午10:04:52
*/
public class NotifyResponseBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1243721631785017233L;
/** 交易结果code . */
public String ret_code;
/** 交易结果描述 . */
public String ret_msg;
public String getRet_code() {
return ret_code;
}
public void setRet_code(String ret_code) {
this.ret_code = ret_code;
}
public String getRet_msg() {
return ret_msg;
}
public void setRet_msg(String ret_msg) {
this.ret_msg = ret_msg;
}
}
package com.wwdz.ch.core.api.lianpay.bean;
public class PaymentRequestBean {
/**
*
*/
private static final long serialVersionUID = -7682226991855956344L;
/** 商户付款流水号 . */
private String no_order;
/** 商户付款时间 . */
private String dt_order;
/** 付款金额 . */
private String money_order;
/** 银行账号 . */
private String card_no;
/** 收款人姓名 . */
private String acct_name;
/** 收款人银行名称 . */
private String bank_name;
/** 付款用途. */
private String info_order;
/** 收款备注 用于给用户显示 . */
private String memo;
/** 对公对私标志 0-对私 1-对公 . */
private String flag_card;
/** 服务器异步通知地址 . */
private String notify_url;
/** 商户编号 . */
private String oid_partner;
/** 用户来源 . */
private String platform;
/** api当前版本号 . */
private String api_version;
/** 签名方式 . */
private String sign_type;
/** 签名方 . */
private String sign;
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getDt_order() {
return dt_order;
}
public void setDt_order(String dt_order) {
this.dt_order = dt_order;
}
public String getMoney_order() {
return money_order;
}
public void setMoney_order(String money_order) {
this.money_order = money_order;
}
public String getCard_no() {
return card_no;
}
public void setCard_no(String card_no) {
this.card_no = card_no;
}
public String getAcct_name() {
return acct_name;
}
public void setAcct_name(String acct_name) {
this.acct_name = acct_name;
}
public String getBank_name() {
return bank_name;
}
public void setBank_name(String bank_name) {
this.bank_name = bank_name;
}
public String getInfo_order() {
return info_order;
}
public void setInfo_order(String info_order) {
this.info_order = info_order;
}
public String getFlag_card() {
return flag_card;
}
public void setFlag_card(String flag_card) {
this.flag_card = flag_card;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getApi_version() {
return api_version;
}
public void setApi_version(String api_version) {
this.api_version = api_version;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
}
package com.wwdz.ch.core.api.lianpay.bean;
/**
* 付款 response bean
*
*/
public class PaymentResponseBean extends BaseResponseBean {
/**
*
*/
private static final long serialVersionUID = -1198276503805567647L;
/** 连连支付支付单号 . */
public String oid_paybill;
/** 商户付款流水号 . */
public String no_order;
/** 验证码. */
public String confirm_code;
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getConfirm_code() {
return confirm_code;
}
public void setConfirm_code(String confirm_code) {
this.confirm_code = confirm_code;
}
public String getOid_paybill() {
return oid_paybill;
}
public void setOid_paybill(String oid_paybill) {
this.oid_paybill = oid_paybill;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("PaymentResponseBean [oid_paybill=");
builder.append(oid_paybill);
builder.append(", no_order=");
builder.append(no_order);
builder.append(", confirm_code=");
builder.append(confirm_code);
builder.append(", ret_code=");
builder.append(ret_code);
builder.append(", ret_msg=");
builder.append(ret_msg);
builder.append(", sign_type=");
builder.append(sign_type);
builder.append(", sign=");
builder.append(sign);
builder.append(", oid_partner=");
builder.append(oid_partner);
builder.append("]");
return builder.toString();
}
}
package com.wwdz.ch.core.api.lianpay.bean;
/**
* 实时付款交易结果查询request bean
*
*/
public class QueryPaymentRequestBean {
/**
*
*/
private static final long serialVersionUID = -5466252690879093697L;
/** 商户付款流水号 . */
private String no_order;
/** 连连银通付款流水号 . */
public String oid_paybill;
/** 商户编号 . */
private String oid_partner;
/** 用户来源 . */
private String platform;
/** api当前版本号 . */
private String api_version;
/** 签名方式 . */
private String sign_type;
/** 签名方 . */
private String sign;
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getOid_paybill() {
return oid_paybill;
}
public void setOid_paybill(String oid_paybill) {
this.oid_paybill = oid_paybill;
}
public String getOid_partner() {
return oid_partner;
}
public void setOid_partner(String oid_partner) {
this.oid_partner = oid_partner;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getApi_version() {
return api_version;
}
public void setApi_version(String api_version) {
this.api_version = api_version;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}
package com.wwdz.ch.core.api.lianpay.bean;
/**
* 实时付款交易结果查询response bean
*
*/
public class QueryPaymentResponseBean extends BaseResponseBean {
/**
*
*/
private static final long serialVersionUID = 1405281788989159722L;
/** 商户付款流水号 . */
public String no_order;
/** 商户下单时间 . */
public String dt_order;
/** 付款金额 . */
public String money_order;
/** 付款状态 . */
public String result_pay;
/** 连连银通付款流水号 . */
public String oid_paybill;
/** 订单描述. */
public String info_order;
/** 清算日期 . */
public String settle_date;
/** 支付备注. */
public String memo;
public String getNo_order() {
return no_order;
}
public void setNo_order(String no_order) {
this.no_order = no_order;
}
public String getMoney_order() {
return money_order;
}
public void setMoney_order(String money_order) {
this.money_order = money_order;
}
public String getResult_pay() {
return result_pay;
}
public void setResult_pay(String result_pay) {
this.result_pay = result_pay;
}
public String getOid_paybill() {
return oid_paybill;
}
public void setOid_paybill(String oid_paybill) {
this.oid_paybill = oid_paybill;
}
public String getInfo_order() {
return info_order;
}
public void setInfo_order(String info_order) {
this.info_order = info_order;
}
public String getSettle_date() {
return settle_date;
}
public void setSettle_date(String settle_date) {
this.settle_date = settle_date;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public String getDt_order() {
return dt_order;
}
public void setDt_order(String dt_order) {
this.dt_order = dt_order;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("QueryPaymentResponseBean [no_order=");
builder.append(no_order);
builder.append(", dt_order=");
builder.append(dt_order);
builder.append(", money_order=");
builder.append(money_order);
builder.append(", result_pay=");
builder.append(result_pay);
builder.append(", oid_paybill=");
builder.append(oid_paybill);
builder.append(", info_order=");
builder.append(info_order);
builder.append(", settle_date=");
builder.append(settle_date);
builder.append(", memo=");
builder.append(memo);
builder.append(", ret_code=");
builder.append(ret_code);
builder.append(", ret_msg=");
builder.append(ret_msg);
builder.append(", sign_type=");
builder.append(sign_type);
builder.append(", sign=");
builder.append(sign);
builder.append(", oid_partner=");
builder.append(oid_partner);
builder.append("]");
return builder.toString();
}
}
package com.wwdz.ch.core.api.lianpay.constant;
public class PaymentConstant {
/** 连连银通公钥(不需替换,这是连连公钥,用于报文加密和连连返回响应报文时验签,不是商户生成的公钥. */
public static final String PUBLIC_KEY_ONLINE = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCSS/DiwdCf/aZsxxcacDnooGph3d2JOj5GXWi+q3gznZauZjkNP8SKl3J2liP0O6rU/Y/29+IUe+GTMhMOFJuZm1htAtKiu5ekW0GlBMWxf4FPkYlQkPE0FtaoMP3gYfh+OwI+fIRrpW3ySn3mScnc6Z700nU/VYrRkfcSCbSnRwIDAQAB";
/** 商户私钥 商户通过openssl工具生成公私钥,公钥通过商户站上传,私钥用于加签,替换下面的值 . */
public static final String BUSINESS_PRIVATE_KEY = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAK5oCtldgp6A0cdjiRjYTJ3fFxBZ55bmFqNxCSICEMp4loS2a0Qm42bov5V3zmmgbhnOJh13dEZU8a1SEeoiYiiKE0F5Pan+RPt329F5YXLfT0h87N3YPmzfx2xiSJa3snmLy0gQHyo/+TfrO59HnY3DuB7aX0U5MkSMQauBiORLAgMBAAECgYEArQiCgwe4eQN7nePN+D1ZPmRA4LMiBt9+5GdYVUpRWF/tjfviTnp6sPYIZgW4X6mQsr+Jp0CFtuW95WSAa5fzY3ulxchf34Hxt1j4h/9IcMAc0qPdB0HTF7M06eEpVLZ5GnbpepStB18HBaGO66kqnwUZ38Hub2EZ8vwN8O8+q1ECQQDaATZ7W9TmPovPhUlerbYEzM2v2IpkhIaziDpwV152bta215fql1iwKINibCta/PYU7spZSLcNpJumHz93OUYJAkEAzM2W2hgujCnZm8trR+c7aY6tlo/8GSRRvFVxnfUOGKYdALXGGYoWE5donH5/2Yfkzzivqar/e/kc+qbFTLCMswJBAL2WRG0vRY0eY7QLM+1UoHC4M0Bzzpbv8bz8AeZk9M+GQNAt2f23tPctpGTZsTKlvtQhfnP7GsaQmpPzpNvoQRECQQCeGmRHT323pKMiG2Jhase50HR/k/345snWi1ufpktQigQ/xRP+KVSroSoYDavjIX5o3oj1gVWjvgc6FL6hWnXzAkEAlyzQsNoFu65uN8Cdc3bHm01H6UHsCdjR5p3KGK3RbAydAbbXInE3003duU/JxWh8P7fVpJohXQc4eh4bIBEhuw==";
/** 商户号(商户需要替换自己的商户号). */
public static final String OID_PARTNER = "201609130000219023";
/** 实时付款api版本. */
public static final String API_VERSION = "1.0";
/** 实时付款签名方式. */
public static final String SIGN_TYPE = "RSA";
}
package com.wwdz.ch.core.api.lianpay.constant;
public enum PaymentStatusEnum {
PAYMENT_APPLY("APPLY", "付款申请"), PAYMENT_CHECK("CHECK", "复核申请"), PAYMENT_DEALING("PROCESSING", "付款处理中"), PAYMENT_SUCCESS(
"SUCCESS", "付款成功"), PAYMENT_FAILURE("FAILURE", "付款失败"), PAYMENT_RETURN("CANCEL", "退款"), PAYMENT_CLOSED(
"CLOSED", "订单关闭");
private String value;
private String desc;
private PaymentStatusEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public static PaymentStatusEnum getPaymentStatusEnumByValue(String value) {
for (PaymentStatusEnum statusEnum : PaymentStatusEnum.values()) {
if (statusEnum.getValue().equals(value)) {
return statusEnum;
}
}
return null;
}
}
package com.wwdz.ch.core.api.lianpay.constant;
/**
* 实时付款返回码
*
*/
public enum RetCodeEnum {
SUCC("0000", "交易成功", "请求成功"),
SIGN_ERROR("1001", "商户请求签名未通过", "请求直接拦截,连连数据未落地,订单失败"),
ORDER_REPEAT_ERROR("1002","商户单号重复", "已有相同订单号,需查询订单状态"),
PARAM_ERROR("1004", "商户请求参数校验错误", "请求拦截,连连数据未落地,订单失败"),
BANK_UNSUPPORT_ERROR("1005", "不支持该银行账户类型", "请求拦截,连连数据未落地,订单失败"),
IP_ERROR("1008", "商户请求IP错误", "请求拦截,连连数据未落地,订单失败"),
ORDER_REPEAT_SUBMIT("2005", "原交易已在进行处理,请勿重复提交", "已有相同订单号,需查询订单状态"),
TRADER_INVALID("3001", "非法的商户", "请求拦截,连连数据未落地,订单失败"),
ORDER_CONFIRM_ERROR("4001", "该订单不存在或非复核状态", "调用确认付款接口返回,原先复核订单关闭了,或者不存在该订单"),
ORDER_SUSPECT("4002", "疑似重复提交订单","当天不同订单号,付款相同金额到相同卡号,第二笔起当作疑似订单,这是连连支付单未创建,不调用确认付款接口的话可置为失败"),
BANK_SUSPECT("4003", "收款银行卡和姓名不一致", "连连校验已在连连有用户信息的卡号和姓名,最终提交到银行处理时,银行会再校验卡号信息"),
BOTH_SUSPECT("4004", "疑似重复提交订单且收款银行卡和姓名不一致", "结合4002和4003的解释描述"),
PAY_AUTH_ERROR("4005", "商户未开通权限", "请求直接拦截,订单失败,连连数据未落地"),
ENCRYPT_ERROR("4006", "敏感信息加密异常", "异常码,需查询订单状态"),
DESCRYPT_ERROR("4007", "敏感信息解密异常","异常码,需查询订单状态"),
CODE_BEYOND_ERROR("4008", "验证码次数超限","验证码错误次数超6次"),
CONFIRM_CODE_ERROR("4009", "验证码异常", "异常码,需查询订单状态"),
CODE_EXPIRE_ERROR("4010", "验证码失效", "订单失败,订单将关闭"),
CODE_NOTMATCH_ERROR("4011", "验证码不匹配", "传入不匹配的验证码"),
BANK_QUERY_ERROR("4012", "银行卡查询异常", "一般是卡号信息不存在,请求拦截,连连数据未落地,订单失败"),
ACCOUNT_ERROR("4103", "账户异常", "订单失败,可用原订单号重新提交,请求参数需一样"),
ORDER_CREATE_ERROR("4104", "付款订单创建失败", "订单失败,可用原订单号重新提交,请求参数需一样"),
PRCPTCD_QUERY_ERROR("4105", "大额行号查询失败", "请求拦截,连连数据未落地,订单失败"),
NO_RECORD("8901", "没有记录", "订单不存在,查询接口返回"),
ACCOUNT_MENOY_LACK("9104", "账户余额不足", "订单失败,可用原订单号重新提交,请求参数需一样"),
RISK_ERROR( "9910", "风险等级过高", "请求拦截,连连数据未落地,订单失败"),
BEYOND_SINGLE_LIMIT("9911", "超过单笔限额", "请求拦截,连连数据未落地,订单失败"),
BEYOND_DAY_LIMIT("9912", "超过单日限额", "请求拦截,连连数据未落地,订单失败"),
BEYOND_MONDY_LIMIT("9913", "超过单月限额", "请求拦截,连连数据未落地,订单失败"),
SYSTEM_ERROR("9999", "系统错误","未知异常,异常码,需查询订单状态");
public final String code;
public final String msg;
public final String desc;
RetCodeEnum(String code, String msg, String desc) {
this.code = code;
this.msg = msg;
this.desc = desc;
}
public static RetCodeEnum getRetCodeEnumByValue(String value) {
for (RetCodeEnum retCodeEnum : RetCodeEnum.values()) {
if (retCodeEnum.getCode().equals(value)) {
return retCodeEnum;
}
}
return null;
}
/**
* 判断返回code是否需要调用付款查询结果
*
* @param trade_code
* @return
*/
public static boolean isNeedQuery(String trade_code) {
if (trade_code.equals(ORDER_REPEAT_ERROR.code) || trade_code.equals(ORDER_REPEAT_SUBMIT.code)
|| trade_code.equals(ENCRYPT_ERROR.code) || trade_code.equals(DESCRYPT_ERROR.code)
|| trade_code.equals(CONFIRM_CODE_ERROR.code)||trade_code.equals(SYSTEM_ERROR.code)) {
return true;
}
return false;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
package com.wwdz.ch.core.api.lianpay.security;
import org.apache.commons.codec.binary.Base64;
public class Base64Utils {
private static Base64 base64 = new Base64();
public static String getBASE64(String s)
{
if (s == null)
return null;
try
{
return base64.encode(s.getBytes()).toString();
} catch (Exception e){
e.printStackTrace();
}
return null;
}
public static String getBASE64(byte[] b)
{
return base64.encode(b).toString();
}
// �?BASE64 编码的字符串 s 进行解码
public static String getFromBASE64(String s)
{
if (s == null)
return null;
try
{
byte[] b = base64.decode(s).toString().getBytes();
return new String(b, "UTF-8");
} catch (Exception e)
{
return null;
}
}
// �?BASE64 编码的字符串 s 进行解码
public static byte[] getBytesBASE64(String s)
{
if (s == null)
return null;
try
{
byte[] b = base64.decode(s).toString().getBytes();
return b;
} catch (Exception e)
{
return null;
}
}
}
package com.wwdz.ch.core.api.lianpay.security;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 32位MD5摘要算法
* @author shmily
* @date 2012-6-28 下午02:34:45
*/
public class Md5Algorithm {
private static Md5Algorithm instance;
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
private Md5Algorithm(){
}
public static Md5Algorithm getInstance(){
if(null == instance)
return new Md5Algorithm();
return instance;
}
/**
* 转换字节数组�?6进制字串
* @param b 字节数组
* @return 16进制字串
*/
private String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
/**
* 转换字节数组为高位字符串
* @param b 字节数组
* @return
*/
private String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* MD5 摘要计算(byte[]).
* @param src byte[]
* @throws Exception
* @return String
*/
public String md5Digest(byte[] src) {
MessageDigest alg;
try {
// MD5 is 32 bit message digest
alg = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
return null;
}
return byteArrayToHexString(alg.digest(src));
}
}
package com.wwdz.ch.core.api.lianpay.security;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA签名公共类
* @author shmily
*/
public class TraderRSAUtil{
private static TraderRSAUtil instance;
private TraderRSAUtil()
{
}
public static TraderRSAUtil getInstance()
{
if (null == instance)
return new TraderRSAUtil();
return instance;
}
/**
* 签名处理
* @param prikeyvalue:私钥
* @param sign_str:签名源内容
* @return
*/
public static String sign(String prikeyvalue, String sign_str)
{
try
{
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
Base64Utils.getBytesBASE64(prikeyvalue));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey myprikey = keyf.generatePrivate(priPKCS8);
// 用私钥对信息生成数字签名
java.security.Signature signet = java.security.Signature
.getInstance("MD5withRSA");
signet.initSign(myprikey);
signet.update(sign_str.getBytes("UTF-8"));
byte[] signed = signet.sign(); // 对信息的数字签名
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(signed));
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* 签名验证
* @param pubkeyvalue:公�?
* @param oid_str:源�?
* @param signed_str:签名结果串
* @return
*/
public static boolean checksign(String pubkeyvalue, String oid_str,
String signed_str)
{
try
{
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(
Base64Utils.getBytesBASE64(pubkeyvalue));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(bobPubKeySpec);
byte[] signed = Base64Utils.getBytesBASE64(signed_str);// 这是SignatureData输出的数字签�?
java.security.Signature signetcheck = java.security.Signature
.getInstance("MD5withRSA");
signetcheck.initVerify(pubKey);
signetcheck.update(oid_str.getBytes("UTF-8"));
return signetcheck.verify(signed);
} catch (Exception e)
{
e.printStackTrace();
}
return false;
}
}
package com.wwdz.ch.core.api.lianpay.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
public class HttpUtil {
private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
public static String doPost(String url, JSONObject json, String charset) {
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try {
httpClient = new SSLClient();
httpPost = new HttpPost(url);
// 设置参数
StringEntity s = new StringEntity(json.toString());
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
httpPost.setEntity(s);
HttpResponse response = httpClient.execute(httpPost);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, charset);
}
}
} catch (Exception ex) {
logger.error("https 请求实时代付API异常", ex);
}
return result;
}
}
package com.wwdz.ch.core.api.lianpay.util;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
//用于进行Https请求的HttpClient
public class SSLClient extends DefaultHttpClient {
public SSLClient() throws Exception {
super();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] ax509certificate, String s)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] ax509certificate, String s)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
}
}
\ No newline at end of file
package com.wwdz.ch.core.api.lianpay.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.wwdz.ch.core.api.lianpay.constant.PaymentConstant;
import com.wwdz.ch.core.api.lianpay.security.TraderRSAUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
public class SignUtil {
private static Logger logger = LoggerFactory.getLogger(SignUtil.class);
public static String genRSASign(JSONObject reqObj) {
// 生成待签名串
String sign_src = genSignData(reqObj);
logger.info("商户[" + reqObj.getString("oid_partner") + "]待签名原串" + sign_src);
return TraderRSAUtil.sign(PaymentConstant.BUSINESS_PRIVATE_KEY, sign_src);
}
/**
* 生成待签名串
*
* @param paramMap
* @return
*/
public static String genSignData(JSONObject jsonObject) {
StringBuffer content = new StringBuffer();
// 按照key做首字母升序排列
List<String> keys = new ArrayList<String>(jsonObject.keySet());
Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < keys.size(); i++) {
String key = (String) keys.get(i);
// sign 和ip_client 不参与签名
if ("sign".equals(key)) {
continue;
}
String value = (String) jsonObject.getString(key);
// 空串不参与签名
if (StringUtils.isEmpty(value)) {
continue;
}
content.append((i == 0 ? "" : "&") + key + "=" + value);
}
String signSrc = content.toString();
if (signSrc.startsWith("&")) {
signSrc = signSrc.replaceFirst("&", "");
}
return signSrc;
}
}
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