Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Q
qk_backend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
quanku
qk_backend
Commits
354b2487
Commit
354b2487
authored
Nov 07, 2024
by
shiyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
保证金缴纳2
parent
5292fa19
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1975 additions
and
0 deletions
+1975
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/ConfirmPaymentApiTest.java
...a/com/wwdz/ch/core/api/lianpay/ConfirmPaymentApiTest.java
+169
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/ImmediatePayNotifyController.java
...wdz/ch/core/api/lianpay/ImmediatePayNotifyController.java
+81
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/PaymentApiTest.java
...ain/java/com/wwdz/ch/core/api/lianpay/PaymentApiTest.java
+192
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/QueryApiTest.java
.../main/java/com/wwdz/ch/core/api/lianpay/QueryApiTest.java
+107
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/BaseResponseBean.java
...a/com/wwdz/ch/core/api/lianpay/bean/BaseResponseBean.java
+70
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/BusinessNoticeBean.java
...com/wwdz/ch/core/api/lianpay/bean/BusinessNoticeBean.java
+155
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/ConfirmPaymentRequestBean.java
...z/ch/core/api/lianpay/bean/ConfirmPaymentRequestBean.java
+102
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/ConfirmPaymentResponseBean.java
.../ch/core/api/lianpay/bean/ConfirmPaymentResponseBean.java
+65
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/NotifyResponseBean.java
...com/wwdz/ch/core/api/lianpay/bean/NotifyResponseBean.java
+42
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/PaymentRequestBean.java
...com/wwdz/ch/core/api/lianpay/bean/PaymentRequestBean.java
+175
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/PaymentResponseBean.java
...om/wwdz/ch/core/api/lianpay/bean/PaymentResponseBean.java
+78
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/QueryPaymentRequestBean.java
...wdz/ch/core/api/lianpay/bean/QueryPaymentRequestBean.java
+91
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/QueryPaymentResponseBean.java
...dz/ch/core/api/lianpay/bean/QueryPaymentResponseBean.java
+135
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/PaymentConstant.java
...om/wwdz/ch/core/api/lianpay/constant/PaymentConstant.java
+20
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/PaymentStatusEnum.java
.../wwdz/ch/core/api/lianpay/constant/PaymentStatusEnum.java
+45
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/RetCodeEnum.java
...va/com/wwdz/ch/core/api/lianpay/constant/RetCodeEnum.java
+87
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/Base64Utils.java
...va/com/wwdz/ch/core/api/lianpay/security/Base64Utils.java
+56
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/Md5Algorithm.java
...a/com/wwdz/ch/core/api/lianpay/security/Md5Algorithm.java
+71
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/TraderRSAUtil.java
.../com/wwdz/ch/core/api/lianpay/security/TraderRSAUtil.java
+84
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/HttpUtil.java
...main/java/com/wwdz/ch/core/api/lianpay/util/HttpUtil.java
+43
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/SSLClient.java
...ain/java/com/wwdz/ch/core/api/lianpay/util/SSLClient.java
+48
-0
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/SignUtil.java
...main/java/com/wwdz/ch/core/api/lianpay/util/SignUtil.java
+59
-0
No files found.
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/ConfirmPaymentApiTest.java
0 → 100644
View file @
354b2487
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
(
"查询异常"
);
}
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/ImmediatePayNotifyController.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/PaymentApiTest.java
0 → 100644
View file @
354b2487
package
com.wwdz.ch.core.api.lianpay
;
import
com.wwdz.ch.core.api.lianpay.bean.PaymentRequestBean
;
import
com.wwdz.ch.core.api.lianpay.bean.PaymentResponseBean
;
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商户接口说明书
* 实时付款对接流程:开通商户号,登录商户站上传商户生成的公钥,商户服务器IP需要向连连报备(群里咨询,会发报备申请表),
* 代码对接好了后,如在连连商户账户没钱,需先在连连商户站充值(可采用线下加款方式),用正式商户号和真实数据测试
*
*/
public
class
PaymentApiTest
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
PaymentApiTest
.
class
);
/**
* 实时付款正常流程只需要调用付款申请接口,同步返回0000时指创建连连支付单成功,订单处于付款处理中,等待连连付款结果通知告知付款状态
*
* @param args
* @throws Exception
*/
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// 连连内部测试环境数据(商户测试期间需要用正式的数据测试,测试时默认单笔单日单月额度50,等测试OK,申请走上线流程打开额度)
PaymentRequestBean
paymentRequestBean
=
new
PaymentRequestBean
();
paymentRequestBean
.
setNo_order
(
"20170413165934"
);
paymentRequestBean
.
setDt_order
(
"20170317165929"
);
paymentRequestBean
.
setMoney_order
(
"0.02"
);
paymentRequestBean
.
setCard_no
(
"6216261000000000000"
);
paymentRequestBean
.
setAcct_name
(
"张三"
);
// paymentRequestBean.setBank_name("中国平安银行");
paymentRequestBean
.
setInfo_order
(
"test测试10.00?"
);
paymentRequestBean
.
setFlag_card
(
"0"
);
paymentRequestBean
.
setMemo
(
"代付"
);
// 填写商户自己的接收付款结果回调异步通知
paymentRequestBean
.
setNotify_url
(
"http://10.20.41.35:8080/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
);
logger
.
info
(
"实时付款请求报文:"
+
jsonStr
);
System
.
out
.
println
(
jsonStr
);
// 用银通公钥对请求参数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
;
}
System
.
out
.
println
(
"pay_load: "
+
encryptStr
);
JSONObject
json
=
new
JSONObject
();
// json.put("oid_partner", PaymentConstant.OID_PARTNER);
json
.
put
(
"oid_partner"
,
"201712210001304164"
);
json
.
put
(
"pay_load"
,
encryptStr
);
System
.
out
.
println
(
"final request: "
+
json
.
toString
());
String
response
=
HttpUtil
.
doPost
(
"https://instantpay.lianlianpay.com/paymentapi/payment.htm"
,
json
,
"UTF-8"
);
System
.
out
.
println
(
"付款接口返回响应报文:"
+
response
.
toString
());
logger
.
info
(
"付款接口返回响应报文:"
+
response
);
if
(
StringUtils
.
isEmpty
(
response
))
{
// 出现异常时调用订单查询,明确订单状态,不能私自设置订单为失败状态,以免造成这笔订单在连连付款成功了,而商户设置为失败
queryPaymentAndDealBusiness
(
paymentRequestBean
.
getNo_order
());
}
else
{
PaymentResponseBean
paymentResponseBean
=
JSONObject
.
parseObject
(
response
,
PaymentResponseBean
.
class
);
// 对返回0000时验证签名
if
(
paymentResponseBean
.
getRet_code
().
equals
(
"0000"
))
{
// 先对结果验签
boolean
signCheck
=
TraderRSAUtil
.
checksign
(
PaymentConstant
.
PUBLIC_KEY_ONLINE
,
SignUtil
.
genSignData
(
JSONObject
.
parseObject
(
response
)),
paymentResponseBean
.
getSign
());
if
(!
signCheck
)
{
// 传送数据被篡改,可抛出异常,再人为介入检查原因
logger
.
error
(
"返回结果验签异常,可能数据被篡改"
);
return
;
}
logger
.
info
(
paymentRequestBean
.
getNo_order
()
+
"订单处于付款处理中"
);
// 已生成连连支付单,付款处理中(交易成功,不是指付款成功,是指跟连连流程正常),商户可以在这里处理自已的业务逻辑(或者不处理,在异步回调里处理逻辑),最终的付款状态由异步通知回调告知
}
else
if
(
paymentResponseBean
.
getRet_code
().
equals
(
"4002"
)
||
paymentResponseBean
.
getRet_code
().
equals
(
"4004"
))
{
// 当调用付款申请接口返回4002,4003,4004,会同时返回验证码,用于确认付款接口
// 对于疑似重复订单,需先人工审核这笔订单是否正常的付款请求,而不是系统产生的重复订单,确认后再调用确认付款接口或者在连连商户站后台操作疑似订单,api不调用确认付款接口
// 对于疑似重复订单,也可不做处理,
// TODO
}
else
if
(
RetCodeEnum
.
isNeedQuery
(
paymentResponseBean
.
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
(
"http://test.yintong.com.cn/paymentapi/queryPayment.htm"
,
JSON
.
parseObject
(
JSON
.
toJSONString
(
queryRequestBean
)),
"UTF-8"
);
System
.
out
.
println
(
"实时付款查询接口响应报文: "
+
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
(
"查询异常"
);
}
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/QueryApiTest.java
0 → 100644
View file @
354b2487
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
(
"查询异常"
);
}
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/BaseResponseBean.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/BusinessNoticeBean.java
0 → 100644
View file @
354b2487
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
();
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/ConfirmPaymentRequestBean.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/ConfirmPaymentResponseBean.java
0 → 100644
View file @
354b2487
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
();
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/NotifyResponseBean.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/PaymentRequestBean.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/PaymentResponseBean.java
0 → 100644
View file @
354b2487
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
();
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/QueryPaymentRequestBean.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/bean/QueryPaymentResponseBean.java
0 → 100644
View file @
354b2487
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
();
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/PaymentConstant.java
0 → 100644
View file @
354b2487
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"
;
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/PaymentStatusEnum.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/constant/RetCodeEnum.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/Base64Utils.java
0 → 100644
View file @
354b2487
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
;
}
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/Md5Algorithm.java
0 → 100644
View file @
354b2487
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
));
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/security/TraderRSAUtil.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/HttpUtil.java
0 → 100644
View file @
354b2487
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
;
}
}
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/SSLClient.java
0 → 100644
View file @
354b2487
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
ch-core/src/main/java/com/wwdz/ch/core/api/lianpay/util/SignUtil.java
0 → 100644
View file @
354b2487
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
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment