您的位置:首页 > 移动开发 > 微信开发

轻量级支付模块集成(微信支付,友店扫码,支付宝)支付整合

2017-02-18 10:51 405 查看


zzs
最后提交于
16小时前 .
初始版本

pay-java-ali

16小时前



zzs

初始版本

删除重命名

保存

取消

pay-java-common

16小时前



zzs

初始版本

删除重命名

保存

取消

pay-java-demo

16小时前



zzs

初始版本

删除重命名

保存

取消

pay-java-wx-youdian

16小时前



zzs

初始版本

删除重命名

保存

取消

pay-java-wx

16小时前



zzs

初始版本

删除重命名

保存

取消

ISSUE_TEMPLATE.zh-CN.md

17小时前



egan

Initial commit

删除重命名

保存

取消

LICENSE

17小时前



egan

Initial commit

删除重命名

保存

取消

PULL_REQUEST_TEMPLATE.zh-CN.md

17小时前



egan

Initial commit

删除重命名

保存

取消

README.md

16小时前



zzs

初始版本

删除重命名

保存

取消

pom.xml

16小时前



zzs

初始版本

删除重命名

保存

取消

Loading...

README.md 12.58 KB

pay-java-parent

整合支付模块(微信支付,支付宝)

特性

1.支付请求调用支持HTTP和异步
2.控制层统一异常处理
3.LogBack日志记录
4.简单快速完成支付模块的开发
5.支持多种支付类型多支付账户扩展(目前已支持微信支付,支付宝支付,友店支付)
6.支持http代理


使用

这里不多说直接上代码 集群的话,友店可能会有bug。

测试链接 : http://pay.egan.in/index.html

快速入门

1.支付整合配置

/**
* 支付类型
* @author egan
* @email egzosn@gmail.com
* @date 2016/11/20 0:30
*/
public enum PayType implements BasePayType{
aliPay{
@Override
public PayService getPayService(ApyAccount apyAccount) {
AliPayConfigStorage aliPayConfigStorage = new AliPayConfigStorage();
aliPayConfigStorage.setPartner(apyAccount.getPartner());
aliPayConfigStorage.setAliPublicKey(apyAccount.getPublicKey());
aliPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
aliPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
aliPayConfigStorage.setReturnUrl(apyAccount.getReturnUrl());
aliPayConfigStorage.setSignType(apyAccount.getSignType());
aliPayConfigStorage.setSeller(apyAccount.getSeller());
aliPayConfigStorage.setPayType(apyAccount.getPayType().toString());
aliPayConfigStorage.setMsgType(apyAccount.getMsgType());
aliPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
return new AliPayService(aliPayConfigStorage);
}

@Override
public TransactionType getTransactionType(String transactionType) {
return AliTransactionType.valueOf(transactionType);
}

},wxPay {
@Override
public PayService getPayService(ApyAccount apyAccount) {
WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
wxPayConfigStorage.setMchId(apyAccount.getPartner());
wxPayConfigStorage.setAppSecret(apyAccount.getPublicKey());
wxPayConfigStorage.setKeyPublic(apyAccount.getPublicKey());
wxPayConfigStorage.setAppid(apyAccount.getAppid());
wxPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
wxPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
wxPayConfigStorage.setSignType(apyAccount.getSignType());
wxPayConfigStorage.setPayType(apyAccount.getPayType().toString());
wxPayConfigStorage.setMsgType(apyAccount.getMsgType());
wxPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
return  new WxPayService(wxPayConfigStorage);
}

/**
* 根据支付类型获取交易类型
* @param transactionType 类型值
* @see WxTransactionType
* @return
*/
@Override
public TransactionType getTransactionType(String transactionType) {

return WxTransactionType.valueOf(transactionType);
}
},youdianPay {
@Override
public PayService getPayService(ApyAccount apyAccount) {
// TODO 2017/1/23 14:12 author: egan  集群的话,友店可能会有bug。暂未测试集群环境
WxYouDianPayConfigStorage wxPayConfigStorage = new WxYouDianPayConfigStorage();
wxPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey());
wxPayConfigStorage.setKeyPublic(apyAccount.getPublicKey());
//            wxPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl());
//            wxPayConfigStorage.setReturnUrl(apyAccount.getReturnUrl());
wxPayConfigStorage.setSignType(apyAccount.getSignType());
wxPayConfigStorage.setPayType(apyAccount.getPayType().toString());
wxPayConfigStorage.setMsgType(apyAccount.getMsgType());
wxPayConfigStorage.setSeller(apyAccount.getSeller());
wxPayConfigStorage.setInputCharset(apyAccount.getInputCharset());
return  new WxYouDianPayService(wxPayConfigStorage);
}

/**
* 根据支付类型获取交易类型
* @param transactionType 类型值
* @see YoudianTransactionType
* @return
*/
@Override
public TransactionType getTransactionType(String transactionType) {

return YoudianTransactionType.valueOf(transactionType);
}
};

public abstract PayService getPayService(ApyAccount apyAccount);

}

/**
* 支付响应对象
* @author: egan
* @email egzosn@gmail.com
* @date 2016/11/18 0:34
*/
public class PayResponse {
@Resource
private AutowireCapableBeanFactory spring;

private PayConfigStorage storage;

private PayService service;

private PayMessageRouter router;

public PayResponse() {

}

/**
* 初始化支付配置
* @param apyAccount 账户信息
* @see ApyAccount 对应表结构详情--》 pay-java-demo/resources/apy_account.sql
*/
public void init(ApyAccount apyAccount) {

//根据不同的账户类型 初始化支付配置
this.service = apyAccount.getPayType().getPayService(apyAccount);
this.storage = service.getPayConfigStorage();

buildRouter(apyAccount.getPayId());
}

/**
* 配置路由
* @param payId 指定账户id,用户多微信支付多支付宝支付
*/
private void buildRouter(Integer payId) {
router = new PayMessageRouter(this.service);
router
.rule()
.async(false)
.msgType(MsgType.text.name()) //消息类型
.event(PayType.aliPay.name()) //支付账户事件类型
.interceptor(new AliPayMessageInterceptor()) //拦截器
.handler(autowire(new AliPayMessageHandler(payId))) //处理器
.end()
.rule()
.async(false)
.msgType(MsgType.xml.name())
.event(PayType.wxPay.name())
.handler(autowire(new WxPayMessageHandler(payId)))
.end()
;
}

private PayMessageHandler autowire(PayMessageHandler handler) {
spring.autowireBean(handler);
return handler;
}

public PayConfigStorage getStorage() {
return storage;
}

public PayService getService() {
return service;
}

public PayMessageRouter getRouter() {
return router;
}
}


2.支付处理器与拦截器简单实现

/**
* 微信支付回调处理器
* Created by ZaoSheng on 2016/6/1.
*/
public class WxPayMessageHandler extends BasePayMessageHandler {
public WxPayMessageHandler(Integer payId) {
super(payId);
}
@Override
public PayOutMessage handle(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
//交易状态
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){
/////这里进行成功的处理

return  payService.getPayOutMessage("SUCCESS", "OK");
}

return  payService.getPayOutMessage("FAIL", "失败");
}
}

/**
* 支付宝回调信息拦截器
* @author: egan
* @email egzosn@gmail.com
* @date 2017/1/18 19:28
*/
public class AliPayMessageInterceptor implements PayMessageInterceptor {
/**
* 拦截支付消息
*
* @param payMessage     支付回调消息
* @param context        上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param payService
* @return true代表OK,false代表不OK并直接中断对应的支付处理器
* @see PayMessageHandler 支付处理器
*/
@Override
public boolean intercept(PayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {

//这里进行拦截器处理,自行实现
return true;
}
}


3.支付响应PayResponse的获取

public class ApyAccountService {

@Inject
private ApyAccountDao dao;

@Inject
private AutowireCapableBeanFactory spring;

private final static Map<Integer, PayResponse> payResponses = new HashMap<Integer, PayResponse>();

/**
*  获取支付响应
* @param id 账户id
* @return
*/
public PayResponse getPayResponse(Integer id) {

PayResponse payResponse = payResponses.get(id);
if (payResponse  == null) {
ApyAccount apyAccount = dao.get(id);
if (apyAccount == null) {
throw new IllegalArgumentException ("无法查询");
}
payResponse = new PayResponse();
spring.autowireBean(payResponse);
payResponse.init(apyAccount);
payResponses.put(id, payResponse);
// 查询
}
return payResponse;
}

}


4.根据账户id与业务id,组拼订单信息(支付宝、微信支付订单)获取支付信息所需的数据

/**
* 跳到支付页面
* 针对实时支付,即时付款
*
* @param payId 账户id
* @param transactionType 交易类型, 这个针对于每一个 支付类型的对应的几种交易方式
* @param bankType 针对刷卡支付,卡的类型,类型值
* @return
*/
@RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8")
public String toPay( Integer payId, String transactionType, String bankType, BigDecimal price) {
//获取对应的支付账户操作工具(可根据账户id)
PayResponse payResponse =  service.getPayResponse(payId);

PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));

//此处只有刷卡支付(银行卡支付)时需要
if (StringUtils.isNotEmpty(bankType)){
order.setBankType(bankType);
}
Map orderInfo = payResponse.getService().orderInfo(order);
return  payResponse.getService().buildRequest(orderInfo, MethodType.POST);
}

/**
* 获取二维码图像
* 二维码支付
* @return
*/
@RequestMapping(value = "toQrPay.jpg", produces = "image/jpeg;charset=UTF-8")
public byte[] toWxQrPay(Integer payId, String transactionType, BigDecimal price) throws IOException {
//获取对应的支付账户操作工具(可根据账户id)
PayResponse payResponse =  service.getPayResponse(payId);
//获取订单信息
Map<String, Object> orderInfo = payResponse.getService().orderInfo(new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType)));

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(payResponse.getService().genQrPay(orderInfo), "JPEG", baos);
return baos.toByteArray();
}

/**
*
*  获取支付预订单信息
* @param payId 支付账户id
* @param transactionType 交易类型
* @return
*/
@RequestMapping("getOrderInfo")
public Map<String, Object> getOrderInfo(Integer payId, String transactionType, BigDecimal price){
//获取对应的支付账户操作工具(可根据账户id)
PayResponse payResponse =  service.getPayResponse(payId);
Map<String, Object> data = new HashMap<>();
data.put("code", 0);
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
data.put("orderInfo",  payResponse.getService().orderInfo(order));
return data;
}


5.支付回调

/**
* 支付回调地址
* @param request
* @return
*/
@RequestMapping(value = "payBack{payId}.json")
public String payBack(HttpServletRequest request, @PathVariable Integer payId) throws IOException {
//根据账户id,获取对应的支付账户操作工具
PayResponse payResponse = service.getPayResponse(payId);
PayConfigStorage storage = payResponse.getStorage();
//获取支付方返回的对应参数
Map<String, String> params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream());
if (null == params){
return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
}

//校验
if (payResponse.getService().verify(params)){
PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
PayOutMessage outMessage = payResponse.getRouter().route(message);
return outMessage.toMessage();
}

return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
}


交流

很希望更多志同道合友友一起扩展新的的支付接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: