轻量级支付模块集成(微信支付,友店扫码,支付宝)支付整合
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(); }
交流
很希望更多志同道合友友一起扩展新的的支付接口。相关文章推荐
- 【iOS】集成支付宝支付/银联支付/微信支付
- Android 支付宝支付、微信支付、银联支付 整合第三方支付接入方法(后台订单支付API设计)
- java实现沙箱测试环境支付宝支付(demo)和整合微信支付和支付宝支付到SSM环境全过程(附源码)
- IOS集成微信支付或者支付宝支付功能小结
- 【Java】快速集成微信支付和支付宝支付
- 微信支付,支付宝支付的集成和注意部分
- 快速集成微信支付和支付宝支付
- java实现沙箱测试环境支付宝支付(demo)和整合微信支付和支付宝支付到ssm
- Android怎么集成支付宝支付和微信支付功能(上)
- 支付宝支付与微信支付的集成
- iOS-集成支付宝支付、微信支付简单总结
- 微信支付及支付宝支付集成
- android app 集成 支付宝支付 微信支付
- iOS-集成支付宝支付、微信支付简单总结
- Android 支付宝支付、微信支付、银联支付 整合第三方支付接入方法
- 【Java】快速集成微信支付和支付宝支付
- iOS-集成支付宝支付、微信支付简单总结
- iOS----支付(微信支付、支付宝支付、银联支付控件集成支付)(转)
- Android怎么集成支付宝支付和微信支付功能(下)
- 整合Hbuilder,实现app的微信支付与支付宝支付