Java 实现微信和支付宝支付功能
一、前期准备
1、申请好微信商户号appid,拿到商户id和商户秘钥,退款的话需要商户证书
2、申请好支付宝商户号appid,商户公钥和秘钥(需要用支付宝工具自己生成),支付宝退款不需要证书
二、数据库表设计
1、微信支付配置表
CREATETABLE`py_wx_config`( `wx_config_id`varchar(18)NOTNULLCOMMENT'微信支付配置ID', `appid`varchar(128)DEFAULTNULLCOMMENT'微信公众号ID', `mch_id`varchar(128)DEFAULTNULLCOMMENT'商户号ID', `mch_key_secret`varchar(2200)DEFAULTNULLCOMMENT'商户安全密钥', `crt_path`varchar(200)DEFAULTNULLCOMMENT'商户证书存放路径', `app_secret`varchar(2200)DEFAULTNULLCOMMENT'公众号安全密钥', `create_id`varchar(18)DEFAULTNULLCOMMENT'创建人', `create_time`datetimeDEFAULTNULLCOMMENT'创建时间', `upd_id`varchar(18)DEFAULTNULLCOMMENT'修改人', `upd_time`datetimeDEFAULTNULLCOMMENT'修改时间', `delete_flag`tinyint(1)NOTNULLDEFAULT'0'COMMENT'删除标志', `app_code`varchar(18)NOTNULLCOMMENT'商家编码', `bm_code`varchar(20)DEFAULTNULLCOMMENT'部门编码', PRIMARYKEY(`wx_config_id`)USINGBTREE )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4ROW_FORMAT=COMPACTCOMMENT='微信支付配置';
2、微信小程序支付配置表
CREATETABLE`py_wx_min_config`( `wx_min_config_id`varchar(18)NOTNULLCOMMENT'微信支付配置ID', `appid`varchar(128)DEFAULTNULLCOMMENT'微信公众号ID', `mch_id`varchar(128)DEFAULTNULLCOMMENT'商户号ID', `mch_key_secret`varchar(2200)DEFAULTNULLCOMMENT'商户安全密钥', `crt_path`varchar(200)DEFAULTNULLCOMMENT'商户证书存放路径', `app_secret`varchar(2200)DEFAULTNULLCOMMENT'公众号安全密钥', `create_id`varchar(18)DEFAULTNULLCOMMENT'创建人', `create_time`datetimeDEFAULTNULLCOMMENT'创建时间', `upd_id`varchar(18)DEFAULTNULLCOMMENT'修改人', `upd_time`datetimeDEFAULTNULLCOMMENT'修改时间', `delete_flag`tinyint(1)NOTNULLDEFAULT'0'COMMENT'删除标志', `app_code`varchar(18)NOTNULLCOMMENT'商家编码', `sys_software_code`varchar(18)DEFAULTNULLCOMMENT'系统编码', PRIMARYKEY(`wx_min_config_id`)USINGBTREE )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4ROW_FORMAT=COMPACTCOMMENT='微信支付配置';
3、支付宝支付配置表
CREATETABLE`py_alipay_config`( `alipay_config_id`varchar(18)NOTNULLCOMMENT'支付宝支付配置ID', `ali_private_key`varchar(2200)DEFAULTNULLCOMMENT'支付宝密钥', `ali_public_key`varchar(2200)DEFAULTNULLCOMMENT'支付宝公钥', `ali_appid`varchar(128)DEFAULTNULLCOMMENT'支付宝appid', `create_id`varchar(18)DEFAULTNULLCOMMENT'创建人', `create_time`datetimeDEFAULTNULLCOMMENT'创建时间', `upd_id`varchar(18)DEFAULTNULLCOMMENT'修改人', `upd_time`datetimeDEFAULTNULLCOMMENT'修改时间', `delete_flag`tinyint(1)NOTNULLDEFAULT'0'COMMENT'删除标志', `app_code`varchar(18)NOTNULLCOMMENT'商家编码', PRIMARYKEY(`alipay_config_id`)USINGBTREE )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4ROW_FORMAT=COMPACTCOMMENT='支付宝支付配置';
4、支付流水记录表
CREATETABLE`py_pay_log`( `pay_log_id`varchar(18)NOTNULLCOMMENT'支付流水ID', `pay_no`varchar(20)DEFAULTNULLCOMMENT'支付订单号', `third_id`varchar(64)DEFAULTNULLCOMMENT'微信支付宝订单ID', `money_type`varchar(20)DEFAULTNULLCOMMENT'支付类型0-微信1-支付宝2-会员卡3-银联', `mq_topic`varchar(100)DEFAULTNULLCOMMENT'MQ主题', `mq_status`tinyint(3)DEFAULTNULLCOMMENT'MQ发送状态0-待发送1-已发送2-发送失败', `mq_remark`varchar(100)DEFAULTNULLCOMMENT'MQ发送备注', `request`textCOMMENT'发送数据', `response`textCOMMENT'返回数据', `fee`decimal(14,2)DEFAULTNULLCOMMENT'订单金额', `create_id`varchar(18)DEFAULTNULLCOMMENT'创建人', `create_time`datetimeDEFAULTNULLCOMMENT'创建时间', `upd_id`varchar(18)DEFAULTNULLCOMMENT'修改人', `upd_time`datetimeDEFAULTNULLCOMMENT'修改时间', `delete_flag`tinyint(1)NOTNULLDEFAULT'0'COMMENT'删除标志', `app_code`varchar(18)NOTNULLCOMMENT'商家编码', `pay_config_json_str`longtextCOMMENT'支付配置', PRIMARYKEY(`pay_log_id`)USINGBTREE )ENGINE=MyISAMDEFAULTCHARSET=utf8mb4ROW_FORMAT=DYNAMICCOMMENT='支付流水';
5、支付失败记录表
CREATETABLE`pay_fail_log`( `pay_id`varchar(18)NOTNULL, `json_date`varchar(500)DEFAULTNULL, `create_id`varchar(18)DEFAULTNULL, `create_time`datetimeDEFAULTNULL, `update_id`varchar(18)DEFAULTNULL, `update_time`datetimeDEFAULTNULL, `app_code`varchar(18)NOTNULL, `delete_flag`tinyint(1)DEFAULT'0'COMMENT'是否删除:0-否;1-是', PRIMARYKEY(`pay_id`)USINGBTREE )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4ROW_FORMAT=COMPACT;
三、依赖引入
org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 4.0.0 com.pay qc-payment 2.3 qc-payment http://www.example.com UTF-8 1.7 1.7 Greenwich.SR1 org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-zuul com.alipay.sdk alipay-sdk-java 3.3.4.ALL org.springframework.boot spring-boot-starter-test test org.springframework.retry spring-retry org.springframework.cloud spring-cloud-starter-netflix-hystrix com.auth0 java-jwt 3.4.1 org.apache.commons commons-lang3 3.3.2 com.alibaba druid 1.1.12 org.mybatis.spring.boot mybatis-spring-boot-starter 2.0.0 mysql mysql-connector-java javax.persistence persistence-api 1.0.2 tk.mybatis mapper 4.0.3 org.projectlombok lombok provided commons-io commons-io 2.4 com.pay easyqinyu-tools 0.0.1-SNAPSHOT com.github.pagehelper pagehelper 5.1.2 com.github.pagehelper pagehelper-spring-boot-autoconfigure 1.2.3 com.github.pagehelper pagehelper-spring-boot-starter 1.2.3 com.qcsoft qc-swagger-ui 0.0.1-SNAPSHOT compile com.google.zxing core 3.3.0 com.alibaba fastjson RELEASE compile org.apache.httpcomponents httpclient ${httpclient.version} com.google.code.gson gson 2.8.2 com.aliyun aliyun-java-sdk-core 3.3.1 com.github.1991wangliang aliyun-java-sdk-dysmsapi 1.0.0 org.springframework.kafka spring-kafka com.thoughtworks.xstream xstream 1.4.10 org.dom4j dom4j 2.1.1 com.github.binarywang weixin-java-common 3.3.4.B org.jodd jodd-http compile org.apache.commons commons-lang3 commons-beanutils commons-beanutils 1.9.3 jdom jdom 1.0 org.bouncycastle bcpkix-jdk15on 1.59 org.jodd jodd-http 3.7.1 com.google.zxing core 3.2.1 com.qcsoft qc-commonbean 0.0.1-SNAPSHOT org.springframework.cloud spring-cloud-starter-openfeign com.xuxueli xxl-job-core 2.0.1 org.springframework.cloud spring-cloud-starter-netflix-hystrix-dashboard org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import qc-payment org.springframework.boot spring-boot-maven-plugin org.apache.maven.plugins maven-compiler-plugin 8 8
四、程序实现
1、Controller
packagecom.qcsoft.payment.controller; importcom.alibaba.fastjson.JSON; importcom.qcsoft.commonbean.bean.common.SwaggerConstant; importcom.qcsoft.commonbean.bean.payment.common.PrePayResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.commonbean.bean.payment.wx.exception.WxPayException; importcom.qcsoft.commonbean.bean.payment.wx.util.QrcodeUtils; importcom.qcsoft.easyqinyutools.message.ReturnMsg; importcom.qcsoft.payment.controller.commom.BaseController; importcom.qcsoft.payment.service.PayService; importcom.qcsoft.swaggerui.anno.ApiTag; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.*; importjavax.imageio.ImageIO; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.awt.image.BufferedImage; importjava.io.IOException; /** *@Description:支付控制中心 *@Author: *@Date: */ @RestController @RequestMapping("/v2") publicclassPayControllerextendsBaseController{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(PayController.class); @Autowired privatePayServicepayService; //privatefinalAtomicIntegertick=newAtomicInteger(); /** *统一预支付接口(统一下单) * *@paramorderParam{dh:订单号,payType:支付方式(WXPAY、ALIPAY、MEMBER_CARD、ACCOUNT),appCode:商家编码, *tradeType:支付方式类型(NATIVE、JSAPI、APP、MWEB),openId:支付方式为JSAPI必传,reqId:请求的真实IP地址 *,redirectUrl:支付成功返回地址,appCode:商家编码,outTradeNo:商务订单号,timeExpire,订单到期时间 *,totalAmount:订单金额,body:商品简单描述,subject:订单标题,quitUrl:中途退出} *@paramtokentoken *@return(微信公众号/小程序返回一串json字符串:{appId:,timeStamp:,nonceStr:,info_package:,paySign:,signType:},前端使用微信sdk调用微信支付) *(微信扫码支付返回一个连接,前端需要把连接生成一个二维码使用,连接如:weixin://123.123.com/***) *(微信H5--返回一个连接,前端需要把连接生成一个连接前端直接跳转该连接使用,使用如:location.href='weixin://123.123.com/***') *(支付宝扫码支付--返回一个连接,前端直接跳转到该连接使用,使用如:location.href='weixin://123.123.com/***') *(支付宝扫码H5--返回一个页面form表单,前端需要把这个form表单渲染到h5页面上,使用如:$("#view).html(alipayForm)') *(支付宝app支付--返回一个参数包,如sdk-version=**&service=**&&service=**&&body=**&&out_trade_no=**&,前端使用支付宝sdk调用app支付') *{ *wxNativeUrl:微信扫码地址 *wxAppPackage:app支付sdk参数包 *wxJsapiPackage:公众号支付包 *wxH5Url:h5支付url *wxScanUrl:wxScanUrl *alipayScanUrl:支付宝扫码支付url *alipayH5Form:支付宝h5支付表单 *alipayAppParamStr:支付宝app支付参数支付串 *} *@throwsWxPayException */ @RequestMapping(value="/prePayOrder") @ApiTag(SwaggerConstant.PAYMENT_001) publicReturnMsgprePayOrder(@RequestBodyPreOrderParamorderParam){ Stringmetadata=JSON.toJSONString(orderParam); logger.info("PayController.prePayOrder----\n正在请求支付....,参数为>>>>{}",metadata); ReturnMsgret=newReturnMsg(); //预下单 PrePayResultprePayResult=this.payService.payPreOrder(orderParam); ret.setData(prePayResult); returnret.success("下单成功,订单有效期为"+orderParam.getTimeExpire()); } /** *生成支付二维码 * *@paramurl二维码地址 *@throwsIOException */ @RequestMapping(value="/createQrCode/url") @ApiTag(SwaggerConstant.PAYMENT_001) publicvoidcreateQrCode(@PathVariableStringurl,HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{ StringqueryString=request.getQueryString(); BufferedImagebufferedImage=QrcodeUtils.encode(url+queryString,500,500,null,null); BufferedImagegrayImage=QrcodeUtils.grayImage(bufferedImage); ImageIO.write(grayImage,"png",response.getOutputStream()); } }
2、PayService
packagecom.qcsoft.payment.service.impl; importcom.alibaba.fastjson.JSON; importcom.alipay.api.AlipayClient; importcom.qcsoft.commonbean.bean.common.KafkaConstant; importcom.qcsoft.commonbean.bean.payment.ChinaumsConfig; importcom.qcsoft.commonbean.bean.payment.PayLog; importcom.qcsoft.commonbean.bean.payment.common.PayConstant; importcom.qcsoft.commonbean.bean.payment.common.PrePayResult; importcom.qcsoft.commonbean.bean.payment.common.WxPrePayResultPackage; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.commonbean.bean.payment.wx.bean.request.WxPayUnifiedOrderRequest; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.WxPayUnifiedOrderResult; importcom.qcsoft.commonbean.bean.payment.wx.config.WxPayConfig; importcom.qcsoft.easyqinyutools.utils.JsonUtil; importcom.qcsoft.payment.commns.exception.BaseException; importcom.qcsoft.payment.commns.exception.QYError; importcom.qcsoft.payment.commns.utils.UserUtil; importcom.qcsoft.payment.commns.utils.weixin.PackageUtil; importcom.qcsoft.payment.service.*; importorg.apache.commons.lang3.StringUtils; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Service; importjava.util.SortedMap; importjava.util.TreeMap; @Service publicclassPayServiceImplimplementsPayService{ publicLoggerlogger=LoggerFactory.getLogger(getClass()); @Autowired privateAliPayServicealiPayService; @Autowired privateWxPayServicewxPayService; @Autowired privateChinaumsPayServicechinaumsPayService; @Autowired privateUserUtiluserUtil; @Autowired privatePayLogServicepayLogService; @Override publicPrePayResultpayPreOrder(PreOrderParamorderParam)throwsBaseException{ logger.info("PayServiceImpl.payPreOrder---->>>>\n准备下单.....,当前用户订单号[{}]",orderParam.getDh()); Stringtemp=""; PrePayResultpayResult=newPrePayResult(); //校验支付方式 StringpayType=orderParam.getPayType(); if(!StringUtils.isNotBlank(payType)) thrownewBaseException(QYError.msg("请选择支付方式!")); if(PayConstant.WXPAY.toString().equals(payType)){ //查询商家配置信息 WxPayConfigconfig; if(orderParam.getTradeType().equals(PayConstant.WECHATAPP.toString())){ config=wxPayService.getWxMinPayConfigByAppCode(orderParam.getAppCode(),orderParam.getSysSoftwareCode()); }else{ config=wxPayService.getWxPayConfigByAppCode(orderParam.getAppCode(),orderParam.getBmCode()); } //设置预支付请求参数 if(orderParam.getTradeType().equals(PayConstant.WECHATAPP.toString())){ orderParam.setTradeType(PayConstant.JSAPI.toString()); } WxPayUnifiedOrderRequestrequestParam=wxPayService.packRequestParam(orderParam); //开始请求预支付接口 WxPayUnifiedOrderResultresult=wxPayService.wxPrePay(config,requestParam); //根据支付类型设置值 WxPrePayResultPackageresultPackage=null; if(orderParam.getTradeType().equals(PayConstant.APP.toString())||orderParam.getTradeType().equals(PayConstant.JSAPI.toString())||orderParam.getTradeType().equals(PayConstant.WECHATAPP.toString())){ resultPackage=newWxPrePayResultPackage(); StringtimeMillis=PackageUtil.getTimeStamp(); StringnonceString=PackageUtil.getNonceStr(); resultPackage.setAppId(result.getAppid()); resultPackage.setNonceStr(nonceString); resultPackage.setTimeStamp(timeMillis); resultPackage.setPrePayId(result.getPrepayId()); resultPackage.setInfoPackage("prepay_id="+result.getPrepayId()); resultPackage.setSignType(requestParam.getSignType()); if(orderParam.getTradeType().equals(PayConstant.APP.toString())){ SortedMapreturnData=PackageUtil.getReturnData(resultPackage,config.getMchId()); Stringpaysign=PackageUtil.createSign(returnData,config.getMchKey()); resultPackage.setPaySign(paysign); resultPackage.setInfoPackage(returnData.get("package")); payResult.setWxAppPackage(resultPackage); }else{ SortedMap paypackageParams=newTreeMap (); paypackageParams.put("appId",result.getAppid());//appid paypackageParams.put("timeStamp",timeMillis);// paypackageParams.put("nonceStr",nonceString);// paypackageParams.put("package",resultPackage.getInfoPackage());// paypackageParams.put("signType",resultPackage.getSignType()); Stringpaysign=PackageUtil.createSign(paypackageParams,config.getMchKey()); resultPackage.setPaySign(paysign); payResult.setWxJsapiPackage(resultPackage); } }elseif(orderParam.getTradeType().equals(PayConstant.MWEB.toString())){ payResult.setWxH5Url(result.getMwebUrl()+"&redirect_url="+orderParam.getRedirectUrl()); }elseif(orderParam.getTradeType().equals(PayConstant.NATIVE.toString())){ payResult.setWxNativeUrl(result.getCodeURL()); } //添加支付日志 insertPayLog(orderParam,KafkaConstant.PAYMENT_NOTIFY_001.getTopic(),"0",resultPackage,JSON.toJSONString(config)); returnpayResult; }elseif(PayConstant.ALIPAY.toString().equals(payType)){ AlipayClientclient=aliPayService.getAlipayClientByAppCode(orderParam.getAppCode()); if(orderParam.getTradeType().equals(PayConstant.APP.toString())){ temp=aliPayService.aliAppPay(client,orderParam); payResult.setAlipayAppParamStr(temp); }elseif(orderParam.getTradeType().equals(PayConstant.MWEB.toString())){ temp=aliPayService.aliH5Pay(client,orderParam); payResult.setAlipayH5Form(temp); }elseif(orderParam.getTradeType().equals(PayConstant.NATIVE.toString())){ temp=aliPayService.aliScanPay(client,orderParam); payResult.setAlipayScanUrl(temp); } //添加支付日志 insertPayLog(orderParam,KafkaConstant.PAYMENT_NOTIFY_001.getTopic(),"1",orderParam,JSON.toJSONString(aliPayService.getConfigByAppCode(orderParam.getAppCode()))); returnpayResult; }elseif(PayConstant.WECHATAPP.toString().equals(payType)){ }elseif(PayConstant.CHINAUMS.toString().equals(payType)){//银联pos支付 //查询商家配置信息 ChinaumsConfigconfig; config=chinaumsPayService.getPayConfigByAppCode(orderParam.getAppCode(),orderParam.getBmCode()); if(orderParam.getTradeType().equals(PayConstant.CODE_SCAN.toString())){ chinaumsPayService.codeScanPay(config,orderParam); } //添加支付日志 insertPayLog(orderParam,KafkaConstant.PAYMENT_NOTIFY_001.getTopic(),"3",orderParam,JSON.toJSONString(config)); returnpayResult; } logger.warn("用户未选择正确的支付方式"); thrownewBaseException(QYError.msg("请选择正确的支付方式!")); } publicvoidinsertPayLog(PreOrderParamorderParam,Stringtopic,StringmoneyType,Objectobj,StringpayConfigJsonStr){ PayLogpayLog=newPayLog(); payLog.setAppCode(orderParam.getAppCode()); payLog.setPayLogId(orderParam.getDh()); payLog.setMoneyType(moneyType); payLog.setMqTopic(topic); payLog.setMqStatus(0); payLog.setPayNo(orderParam.getDh()); payLog.setRequest(JsonUtil.toJSon(obj)); payLog.setFee(orderParam.getTotalAmount()); payLog.setPayConfigJsonStr(payConfigJsonStr); payLogService.saveOrUpdate(payLog); } }
3、AliPayService
packagecom.qcsoft.payment.service; importcom.alipay.api.AlipayClient; importcom.alipay.api.request.AlipayTradeRefundRequest; importcom.alipay.api.response.AlipayTradeQueryResponse; importcom.alipay.api.response.AlipayTradeRefundResponse; importcom.qcsoft.commonbean.bean.payment.AlipayConfig; importcom.qcsoft.commonbean.bean.payment.alipay.AliPayRefundParam; importcom.qcsoft.commonbean.bean.payment.common.PayNotify; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.easyqinyutools.message.ReturnMsg; importjavax.servlet.http.HttpServletRequest; importjava.util.Map; publicinterfaceAliPayService{ /** * *@paramalipayClient *@paramorderParam *@param *@return */ StringaliAppPay(AlipayClientalipayClient,PreOrderParamorderParam); StringaliScanPay(AlipayClientalipayClient,PreOrderParamorderParam); StringaliH5Pay(AlipayClientalipayClient,PreOrderParamorderParam); voidaliPayNotify(PayNotifyparams); booleanrsaCheckV1(HttpServletRequestrequest,StringappCode); AlipayTradeQueryResponsealiPayOrderQuery(AlipayClientalipayClient,Stringout_trade_no); AlipayClientgetAlipayClientByAppCode(StringappCode); AlipayConfiggetConfigByAppCode(StringappCode); /** *支付宝退款接口 *@paramaliPayRefundParam *@return */ ReturnMsgaliPayRefund(AliPayRefundParamaliPayRefundParam); }
AliPayServiceImpl
packagecom.qcsoft.payment.service.impl; importcom.alibaba.fastjson.JSON; importcom.alipay.api.AlipayApiException; importcom.alipay.api.AlipayClient; importcom.alipay.api.DefaultAlipayClient; importcom.alipay.api.domain.AlipayTradeAppPayModel; importcom.alipay.api.domain.AlipayTradePrecreateModel; importcom.alipay.api.domain.AlipayTradeRefundModel; importcom.alipay.api.domain.AlipayTradeWapPayModel; importcom.alipay.api.internal.util.AlipaySignature; importcom.alipay.api.request.*; importcom.alipay.api.response.*; importcom.qcsoft.commonbean.bean.payment.AlipayConfig; importcom.qcsoft.commonbean.bean.payment.alipay.AliPayRefundParam; importcom.qcsoft.commonbean.bean.payment.common.PayConstant; importcom.qcsoft.commonbean.bean.payment.common.PayNotify; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.easyqinyutools.message.ReturnMsg; importcom.qcsoft.payment.commns.exception.BaseException; importcom.qcsoft.payment.commns.exception.QYError; importcom.qcsoft.payment.commns.utils.DateUtils; importcom.qcsoft.payment.commns.utils.RedisUtil; importcom.qcsoft.payment.service.AliPayService; importcom.qcsoft.payment.service.AlipayConfigService; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Value; importorg.springframework.stereotype.Service; importjavax.servlet.http.HttpServletRequest; importjava.net.URLEncoder; importjava.util.Date; importjava.util.HashMap; importjava.util.Iterator; importjava.util.Map; /** *支付宝相关业务实现类 */ @Service publicclassAliPayServiceImplimplementsAliPayService{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(AliPayServiceImpl.class); @Autowired privateAlipayConfigServicealipayConfigService; @Autowired privateRedisUtilredisUtil; @Value("${payNotifyUrl}") privateStringnotifyUrl; /** *APP支付 *参数加签 */ @Override publicStringaliAppPay(AlipayClientalipayClient,PreOrderParamorderParam){ logger.info("AliPayServiceImpl.aliAppPay--->>>\n支付宝预支付开始,\n支付类型为:APP支付,\n订单号为:{}",orderParam.getDh()); Datedate=newDate(); AlipayTradeAppPayResponseresponse=null; //发起App支付请求 AlipayTradeAppPayModelmodel=newAlipayTradeAppPayModel(); //订单描述 model.setBody(orderParam.getBody()); //订单标题 model.setSubject(orderParam.getSubject()); //商户订单号就是商户后台生成的订单号 model.setOutTradeNo(orderParam.getOutTradeNo()); //该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(屁股后面的字母一定要带,不然报错) model.setTimeoutExpress(DateUtils.toString(date,orderParam.getTimeExpire())); //订单总金额,默认单位为元,精确到小数点后两位,取值范围[0.01,100000000] model.setTotalAmount(orderParam.getTotalAmount().toString()); //销售产品码 model.setProductCode(PayConstant.ALIPAY_QUICK_WAP_WAY.getKey()); AlipayTradeAppPayRequestrequest=newAlipayTradeAppPayRequest(); request.setBizModel(model); //request.setNotifyUrl("商户外网可以访问的异步地址,不写就是不回调"); request.setNotifyUrl(notifyUrl+PayConstant.ALIPAY_05.getKey()+"/"+orderParam.getAppCode()+"/"+orderParam.getDh()); //支付成功返回地址 request.setReturnUrl(orderParam.getRedirectUrl()); //通过api的方法请求阿里接口获得反馈 logger.info("AliPayServiceImpl.aliAppPay----->\n支付宝预支付接口请求信息:{}",JSON.toJSONString(request)); try{ response=alipayClient.sdkExecute(request); }catch(AlipayApiExceptione){ logger.info("AliPayServiceImpl.aliAppPay----->\n支付宝预下单失败,\n本次下单的订单号为:{},\n相关报错信息为:{}",orderParam.getDh(),response,e); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+e.getMessage()+"]")); } logger.info("AliPayServiceImpl.aliAppPay----->\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); if(response.isSuccess()){ logger.info("AliPayServiceImpl.aliAppPay----->\n支付宝预下单成功,\n本次下单的订单号为:{},商户订单号为:{}",orderParam.getDh(),orderParam.getOutTradeNo()); }else{ logger.error("AliPayServiceImpl.aliAppPay----->\n调用支付宝预下单接口失败!\n具体信息为:\n{}",response.getBody()); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+response.getMsg()+"]")); } returnresponse.getBody(); } /** *扫码支付 *参数加签 */ @Override publicStringaliScanPay(AlipayClientalipayClient,PreOrderParamorderParam){ logger.info("AliPayServiceImpl.aliScanPay--->>>\n支付宝预支付开始,\n支付类型为:扫码支付,\n订单号:{}",orderParam.getDh()); /*AlipayTradePagePayResponseresponse=null;*/ AlipayTradePrecreateResponseresponse=null; Datedate=newDate(); /** *设置请求model参数(body、subject、outTradeNo、totalAmount、timeoutExpress;必传) */ AlipayTradePrecreateModelmodel=newAlipayTradePrecreateModel(); //订单描述 model.setBody(orderParam.getBody()); //订单标题 model.setSubject(orderParam.getBody()); //商户订单号就是商户后台生成的订单号 model.setOutTradeNo(orderParam.getOutTradeNo()); //该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(屁股后面的字母一定要带,不然报错) model.setTimeoutExpress(orderParam.getTimeExpire()); //model.setSellerId(DateUtils.toString(date,"yyyyMMddHHmmssSSS")); //订单总金额,默认单位为元,精确到小数点后两位,取值范围[0.01,100000000] model.setTotalAmount(orderParam.getTotalAmount().toString()); //model.setProductCode(PayConstant.ALIPAY_FAST_INSTANT_TRADE_PAY.getKey()); //选填 /** *创建支付宝扫码支付请求接口类,设置相关请求处理信息,准备请求下单 */ AlipayTradePrecreateRequestrequest=newAlipayTradePrecreateRequest(); request.setBizModel(model); //request.setNotifyUrl("商户外网可以访问的异步地址,不写就是不回调"); request.setNotifyUrl(notifyUrl+PayConstant.ALIPAY_05.getKey()+"/"+orderParam.getAppCode()+"/"+orderParam.getDh()); //支付成功返回地址 request.setReturnUrl(orderParam.getRedirectUrl()); //通过api的方法请求阿里接口获得反馈alipayClient.pageExecute(request) try{ logger.info("支付宝扫码付请求报文:{}",JSON.toJSONString(request)); response=alipayClient.execute(request)/**/; }catch(AlipayApiExceptione){ logger.info("AliPayServiceImpl.aliScanPay----->\n支付宝预下单失败,\n本次下单的订单号:{},\n相关报错信息为:{}",orderParam.getDh(),response,e); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+e.getMessage()+"]")); }catch(Exceptione){ e.printStackTrace(); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+e.getMessage()+"]")); } //打印返回信息 logger.info("AliPayServiceImpl.aliScanPay----->\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); //判断预下单返回状态 if(response.isSuccess()){ logger.info("AliPayServiceImpl.aliScanPay----->\n支付宝预下单成功,\n本次下单的订单号:{},商务订单号为",orderParam.getDh(),orderParam.getOutTradeNo()); }else{ logger.error("AliPayServiceImpl.aliScanPay----->\n调用支付宝预下单接口失败!\n具体信息:\n{}",response.getBody()); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+response.getMsg()+"]")); } returnresponse.getQrCode(); } /** *H5支付 *参数加签 */ @Override publicStringaliH5Pay(AlipayClientalipayClient,PreOrderParamorderParam){ logger.info("AliPayServiceImpl.aliH5Pay--->>>\n支付宝预支付开始,\n支付类型为:H5支付,\n订单号:{}",orderParam.getDh()); Stringform=""; AlipayTradeWapPayResponseresponse=null; /** *封装请求支付信息 */ AlipayTradeWapPayModelpayModel=newAlipayTradeWapPayModel(); payModel.setOutTradeNo(orderParam.getOutTradeNo()); payModel.setSubject(orderParam.getBody()); payModel.setTotalAmount(orderParam.getTotalAmount().toString()); payModel.setBody(orderParam.getBody()); payModel.setTimeoutExpress(orderParam.getTimeExpire()); payModel.setProductCode(PayConstant.ALIPAY_QUICK_WAP_WAY.getKey()); payModel.setQuitUrl(URLEncoder.encode(orderParam.getQuitUrl())); /** *创建支付宝H5支付请求接口类,设置相关请求处理信息,准备请求下单 */ AlipayTradeWapPayRequestalipay_request=newAlipayTradeWapPayRequest(); alipay_request.setBizModel(payModel); //设置异步通知地址 logger.info("通知地址{}",notifyUrl+PayConstant.ALIPAY_05.getKey()+"/"+orderParam.getAppCode()+"/"+orderParam.getDh()); alipay_request.setNotifyUrl(notifyUrl+PayConstant.ALIPAY_05.getKey()+"/"+orderParam.getAppCode()+"/"+orderParam.getDh()); //设置同步地址 alipay_request.setReturnUrl(URLEncoder.encode(orderParam.getRedirectUrl())); //调用SDK生成表单 try{ response=alipayClient.pageExecute(alipay_request); if(response.isSuccess()){ form=response.getBody(); logger.info("AliPayServiceImpl.aliH5Pay----->>>>\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); }else{ logger.info("AliPayServiceImpl.aliH5Pay----->>>>\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); thrownewBaseException(QYError.msg("支付宝")); } }catch(AlipayApiExceptione){ logger.info("AliPayServiceImpl.aliH5Pay----->>>>\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); thrownewBaseException(QYError.msg("调用支付宝预下单接口失败!["+e.getMessage()+"]")); } logger.info("AliPayServiceImpl.aliH5Pay----->>>>\n支付宝预支付接口返回信息:{}",JSON.toJSONString(response)); /** *打印日志,并返回链接 */ returnform; } /** *支付宝通知 * *@paramparams */ @Override publicvoidaliPayNotify(PayNotifyparams){ logger.info("AliPayServiceImpl.appAliPayNotify-\n阿里服务器消费手机回调参数获取和参数判断-------》》》"); /** *打印信息 */ //校验支付金额 /*ReturnMsgreturnMsg=restTemplate.postForEntity(params.getNoOrderAmountUrl(),params,ReturnMsg.class).getBody(); if(!returnMsg.isSuccess()){ logger.info("WxPayController.wxPayNotify-->\n校验订单金额失败,请核实商务订单号:{}",params); thrownewBaseException(QYError.msg("校验订单金额失败!商务订单号["+params.getOutTradeNo()+"]")); }*/ /** *判断支付状态 */ if(params.getTradeStatus().equals("TRADE_SUCCESS")){ logger.info("AliPayServiceImpl.appAliPayNotify----\n支付宝支付成功!商务订单号[{}]----->>",params.getOutTradeNo(),JSON.toJSONString(params)); }else{ logger.error("AliPayServiceImpl.appAliPayNotify---\n支付宝支付失败!商务订单号[{}]---->>",params.getOutTradeNo()); thrownewBaseException(QYError.msg("支付宝支付失败!商务订单号["+params.getOutTradeNo()+"]")); } } @Override publicbooleanrsaCheckV1(HttpServletRequestrequest,StringappCode){ //获取支付宝GET过来反馈信息 Mapparams=newHashMap (); //签名验证(对支付宝返回的数据验证,确定是支付宝返回的) booleanresult=false; try{ //从支付宝回调的request域中取值 Map requestParams=request.getParameterMap(); for(Iterator iter=requestParams.keySet().iterator();iter.hasNext();){ Stringname=iter.next(); String[]values=(String[])requestParams.get(name); StringvalueStr=""; for(inti=0;i >>>>>>>>>>>>>>{}",JSON.toJSONString(params)); //商家编码 AlipayConfigalipayConfig=getConfigByAppCode(appCode); result=AlipaySignature.rsaCheckV1(params,alipayConfig.getAliPublicKey(), PayConstant.ALIPAY_CHARSET.getKey(),PayConstant.ALIPAY_SIGN_TYPE_RSA2.getKey()); }catch(Exceptione){ logger.error("AliPayServiceImpl.appAliPayNotify---\n校验签名失败!商务订单号[{}]---->>",JSON.toJSONString(request),e); thrownewBaseException(QYError.msg("支付宝支付校验签名失败!")); } returnresult; } /** *根据商务订单号查询查询支付信息 * *@paramalipayClient *@paramout_trade_no *@return */ @Override publicAlipayTradeQueryResponsealiPayOrderQuery(AlipayClientalipayClient,Stringout_trade_no){ logger.info("AliPayServiceImpl.aliPayOrderQuery----\n根据商务订单号查询支付宝订单信息,\n商务订单号:[{}]----》》》",out_trade_no); AlipayTradeQueryResponseresponse=null; AlipayTradeQueryRequestrequest=newAlipayTradeQueryRequest(); //设置查询参数 Map bizModel=newHashMap<>(); bizModel.put("out_trade_no",out_trade_no); request.setBizContent(JSON.toJSONString(bizModel)); //开始查询 try{ response=alipayClient.execute(request); }catch(AlipayApiExceptione){ logger.error("AliPayServiceImpl.aliPayOrderQuery--->>\n支付宝订单查询失败,\n商务订单号:[{}]",out_trade_no); thrownewBaseException(QYError.msg("订单号["+out_trade_no+"],订单支付失败,状态码为["+response.getTradeStatus()+"]")); } logger.info("AliPayServiceImpl.aliPayOrderQuery---->>\n查询支付宝订单信息,\n商务订单号:[{}],\n返回信息:{}",out_trade_no,JSON.toJSONString(response)); //查询状态处理 if(response.isSuccess()){ logger.info("AliPayServiceImpl.aliPayOrderQuery--->>\n支付宝订单查询成功,\n商务订单号:[{}]",out_trade_no); }else{ logger.error("AliPayServiceImpl.aliPayOrderQuery--->>\n支付宝订单查询失败,\n商务订单号:[{}]",out_trade_no); thrownewBaseException(QYError.msg("订单号["+out_trade_no+"],订单支付失败,状态码为["+response.getTradeStatus()+"]")); } returnresponse; } /** *根据商家编码设置alipay配置信息 * *@paramappCode商家编码 *@return */ @Override publicAlipayClientgetAlipayClientByAppCode(StringappCode){ logger.info("AliPayServiceImpl.getAlipayClientByAppCode--->>\n获取支付宝配置信息:[{}]",appCode); AlipayConfigalipayConfig=null; /** *获取商家支付宝配置信息(优先级:1-redis,2-mysql,3-用户系统) */ try{ alipayConfig=getConfigByAppCode(appCode); if(alipayConfig==null){ logger.info("AliPayServiceImpl.getAlipayClientByAppCode--->>\n获取支付宝支付配置信息失败:[{}]",appCode); logger.info("AliPayServiceImpl.getAlipayClientByAppCode--->>\n获取支付宝支付配置信息失败:[{}{}]",appCode,alipayConfig); thrownewBaseException(QYError.msg("获取支付宝支付配置信息失败!")); } }catch(Exceptione){ logger.error("AliPayServiceImpl.getAlipayClientByAppCode--->>\n获取支付宝配置信息失败:[{}]",e); thrownewBaseException(QYError.msg("获取支付宝配置信息失败!")); } AlipayClientalipayClient=newDefaultAlipayClient( PayConstant.ALIPAY_01.getKey(), alipayConfig.getAliAppid(), alipayConfig.getAliPrivateKey(), PayConstant.ALIPAY_FORMAT.getKey(), PayConstant.ALIPAY_CHARSET.getKey(), alipayConfig.getAliPublicKey(), PayConstant.ALIPAY_SIGN_TYPE_RSA2.getKey()); returnalipayClient; } //获取商家支付宝的配置信息 publicAlipayConfiggetConfigByAppCode(StringappCode){ AlipayConfigalipayConfig=alipayConfigService.selectByAppCode(appCode); returnalipayConfig; } /** *支付宝退款接口 *@paramaliPayRefundParam *@return */ publicReturnMsgaliPayRefund(AliPayRefundParamaliPayRefundParam){ ReturnMsgreturnMsg=newReturnMsg(); StringappCode=aliPayRefundParam.getAppCode(); AlipayClientalipayClient=getAlipayClientByAppCode(appCode); AlipayTradeRefundResponseresponse=null; AlipayTradeRefundModelmodel=newAlipayTradeRefundModel(); //订单支付时传入的商户订单号,不能和trade_no同时为空。 model.setOutTradeNo(aliPayRefundParam.getOutTradeNo()); //支付宝交易号,和商户订单号不能同时为空 //model.setTradeNo(aliPayRefundParam.getTradeNo()); //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。 model.setOutRequestNo(aliPayRefundParam.getOutRequestNo()); // 需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数 model.setRefundAmount(aliPayRefundParam.getRefundAmount()); //退款的原因说明 model.setRefundReason(aliPayRefundParam.getRefundReason()); /** *创建支付宝扫码支付请求接口类,设置相关请求处理信息,准备请求下单 */ AlipayTradeRefundRequestrequest=newAlipayTradeRefundRequest(); request.setBizModel(model); //商户外网可以访问的异步地址,不写就是不回调 request.setNotifyUrl(notifyUrl+PayConstant.ALIPAY_05.getKey()+"/"+aliPayRefundParam.getAppCode()+"/"+aliPayRefundParam.getDh()); //支付成功返回地址 request.setReturnUrl(aliPayRefundParam.getRedirectUrl()); //通过api的方法请求阿里接口获得反馈alipayClient.pageExecute(request) try{ logger.info("支付宝退款请求完整报文:{}",JSON.toJSONString(request)); response=alipayClient.execute(request)/**/; }catch(AlipayApiExceptione){ logger.info("支付宝退款失败,\n本次下单的订单号:{},\n相关报错信息为:{}",aliPayRefundParam.getDh(),response,e); thrownewBaseException(QYError.msg("调用支付宝预退款失败!["+e.getMessage()+"]")); }catch(Exceptione){ e.printStackTrace(); thrownewBaseException(QYError.msg("支付宝预退款失败!["+e.getMessage()+"]")); } //打印返回信息 logger.info("支付宝退款失败:{}",JSON.toJSONString(response)); //判断预下单返回状态 if(response.isSuccess()&&"Y".equals(response.getFundChange())){ logger.info("AliPayServiceImpl.aliScanPay----->\n支付宝退款成功,\n本次下单的订单号:{},商务订单号为,{}",aliPayRefundParam.getDh(),aliPayRefundParam.getOutTradeNo()); returnreturnMsg.setData("退款成功"); }else{ logger.error("AliPayServiceImpl.aliScanPay----->\n调用支付宝退款接口失败!\n具体信息:\n{}",response.getBody()); thrownewBaseException(QYError.msg("调用支付宝退款接口失败!["+response.getBody()+"]")); } } }
4、WxPayService
packagecom.qcsoft.payment.service; importcom.qcsoft.commonbean.bean.payment.WxMinConfig; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.commonbean.bean.payment.wx.bean.WxRefund; importcom.qcsoft.commonbean.bean.payment.wx.bean.entpay.EntPayParam; importcom.qcsoft.commonbean.bean.payment.wx.bean.entpay.EntPayResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.request.WxPayUnifiedOrderRequest; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.BaseWxPayResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.WxPayOrderQueryResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.WxPayUnifiedOrderResult; importcom.qcsoft.commonbean.bean.payment.wx.config.WxPayConfig; importcom.qcsoft.commonbean.bean.payment.wx.exception.WxPayException; /** *微信预支付 *@paramappId应用ID(微信公众号) *@parammchId商务号ID *@parammchKey商务号密钥 *@paramnotifyUrl异步通知地址 *@paramsignType签名类型 *@parambody描述 *@paramtotalFee金额 *@paramspbillCreateIpapp和h5支付需要用户的真实请求地址 *@paramtradeType *@paramoutTradeNo *@return */ publicinterfaceWxPayService{ /** * *@paramconfig{appId:应用ID,mchId:商务号ID,mchKey:商务号密钥,notifyUrl:异步通知地址,signType:签名类型} *@paramrequest{body:订单描述,totalFee:金额, *spbillCreateIp:app和h5支付需要用户的真实请求地址Native支付填调用微信支付API的机器IP, *tradeType:SAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里, *outTradeNo:商户订单号,productId:商品Id(扫码支付必传,其他选填),openid:公众号openId} *@return */ WxPayUnifiedOrderResultwxPrePay(WxPayConfigconfig,WxPayUnifiedOrderRequestrequest); /** *根据appCode获取商家微信支付配置 *@paramappCode *@return */ WxPayConfiggetWxPayConfigByAppCode(StringappCode,StringbmCode); WxPayConfiggetWxMinPayConfigByAppCode(StringappCode,StringsysSoftwareCode); /** *封装预下单参数实体 *@paramorderParam预支付接口参数实体 *@paramorder点单 *@return */ WxPayUnifiedOrderRequestpackRequestParam(PreOrderParamorderParam); /** *查询订单 *@paramappCode商家编码 *@paramdh订单号 *@paramsysSoftwareCode */ WxPayOrderQueryResultwxPayOrderQuery(StringappCode,StringbmCode,Stringdh,Integertype,StringsysSoftwareCode); /** *企业支付 *@paramparams *@return: *@Author: *@date: */ BaseWxPayResultentPay(EntPayParamparams)throwsWxPayException; }
WxPayServiceImpl
packagecom.qcsoft.payment.service.impl; importcom.alibaba.fastjson.JSON; importcom.qcsoft.commonbean.bean.payment.PayLog; importcom.qcsoft.commonbean.bean.payment.WxConfig; importcom.qcsoft.commonbean.bean.payment.WxMinConfig; importcom.qcsoft.commonbean.bean.payment.common.PayConstant; importcom.qcsoft.commonbean.bean.payment.common.PayNotify; importcom.qcsoft.commonbean.bean.payment.wx.bean.PreOrderParam; importcom.qcsoft.commonbean.bean.payment.wx.bean.entpay.*; importcom.qcsoft.commonbean.bean.payment.wx.bean.request.WxPayOrderQueryRequest; importcom.qcsoft.commonbean.bean.payment.wx.bean.request.WxPayUnifiedOrderRequest; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.BaseWxPayResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.WxPayOrderQueryResult; importcom.qcsoft.commonbean.bean.payment.wx.bean.result.WxPayUnifiedOrderResult; importcom.qcsoft.commonbean.bean.payment.wx.config.WxPayConfig; importcom.qcsoft.commonbean.bean.payment.wx.exception.WxPayException; importcom.qcsoft.commonbean.bean.payment.wx.handler.EntPayHandler; importcom.qcsoft.commonbean.bean.payment.wx.handler.WxPayHandler; importcom.qcsoft.commonbean.bean.payment.wx.handler.impl.EntPayHandlerImpl; importcom.qcsoft.commonbean.bean.payment.wx.handler.impl.WxPayHandlerApacheHttpImpl; importcom.qcsoft.payment.commns.exception.BaseException; importcom.qcsoft.payment.commns.exception.QYError; importcom.qcsoft.payment.commns.utils.DateUtils; importcom.qcsoft.payment.commns.utils.RedisUtil; importcom.qcsoft.payment.service.PayLogService; importcom.qcsoft.payment.service.WxConfigService; importcom.qcsoft.payment.service.WxMinConfigService; importcom.qcsoft.payment.service.WxPayService; importlombok.extern.slf4j.Slf4j; importorg.apache.commons.lang3.StringUtils; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Value; importorg.springframework.stereotype.Service; importjava.math.BigDecimal; importjava.util.Date; @Service @Slf4j publicclassWxPayServiceImplimplementsWxPayService{ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(WxPayServiceImpl.class); @Value("${payNotifyUrl}") privateStringnotifyUrl; @Autowired privateRedisUtilredisUtil; @Autowired privateWxConfigServicewxConfigService; @Autowired privateWxMinConfigServicewxMinConfigService; @Autowired privatePayLogServicepayLogService; /** *@paramconfig{appId:应用ID,mchId:商务号ID,mchKey:商务号密钥,notifyUrl:异步通知地址,signType:签名类型} *@paramrequest{body:订单描述,totalFee:金额, *spbillCreateIp:app和h5支付需要用户的真实请求地址Native支付填调用微信支付API的机器IP, *tradeType:SAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里, *outTradeNo:商户订单号,productId:商品Id(扫码支付必传,其他选填),openid:公众号openId}还有很多参数选填 *@return *@throwsWxPayException */ @Override publicWxPayUnifiedOrderResultwxPrePay(WxPayConfigconfig,WxPayUnifiedOrderRequestrequest){ logger.info("WxPayServiceImpl.wxPrePay--->>\n微信预支付,\n商务订单号:[{}]",request.getOutTradeNo()); WxPayHandlerwx=newWxPayHandlerApacheHttpImpl(); WxPayUnifiedOrderResultorderResult=null; wx.setConfig(config); log.info("WxPayUnifiedOrderResult={}",config.getNotifyUrl()); try{ orderResult=wx.unifiedOrder(request); }catch(WxPayExceptione){ logger.error("WxPayServiceImpl.wxPrePay--->>\n微信预支付失败,\n商务订单号:[{}]",request.getOutTradeNo(),orderResult); logger.error("异常信息{}",e.getMessage()); thrownewBaseException(QYError.msg("订单号["+request.getOutTradeNo()+"]预支付失败!")); } returnorderResult; } /** *根据商家编码获取微信商户配置信息 * *@paramappCode *@return */ @Override publicWxPayConfiggetWxPayConfigByAppCode(StringappCode,StringbmCode){ logger.info("WxPayServiceImpl.getWxPayConfigByAppCode--->>\n获取微信支付配置信息:appCode[{}],bmCode[{}]",appCode,bmCode); WxConfigconfig=null; WxPayConfigwxPayConfig=newWxPayConfig(); /** *获取商家支付宝配置信息(优先级:1-redis,2-mysql,3-用户系统) */ try{ //2、mysql if(config==null){ if(StringUtils.isNotBlank(bmCode)){ config=wxConfigService.selectByBmCode(bmCode,appCode); //如果部门取不到,则去商家的配置 if(config==null) config=wxConfigService.selectByAppCode(appCode); }else{ config=wxConfigService.selectByAppCode(appCode); } } if(config==null){ logger.warn("WxPayServiceImpl.getWxPayConfigByAppCode--->>\n获取微信支付配置信息失败:[{}]",appCode); thrownewBaseException(QYError.msg("获取微信支付配置信息失败!")); } }catch(Exceptione){ logger.error("WxPayServiceImpl.getWxPayConfigByAppCode--->>\n获取微信支付配置信息失败:[{}]",e); thrownewBaseException(QYError.msg("获取微信支付配置信息失败!")); } //根据appCode查询商家微信配置信息 wxPayConfig.setAppId(config.getAppid()); wxPayConfig.setMchId(config.getMchId()); wxPayConfig.setMchKey(config.getMchKeySecret()); wxPayConfig.setSignType(PayConstant.WXPAY_SIGNTYPE_MD5.getKey()); wxPayConfig.setKeyUrl(config.getCrtPath()); wxPayConfig.setKeyPath(config.getCrtPath()); log.info("获取微信公众号配置为[{}],转为微信支付实体为[{}]",config,wxPayConfig); returnwxPayConfig; } @Override publicWxPayConfiggetWxMinPayConfigByAppCode(StringappCode,StringsysSoftwareCode){ logger.error("WxPayServiceImpl.getWxMinPayConfigByAppCode--->>\n获取微信小程序支付配置信息:[{}]",appCode); if(StringUtils.isBlank(sysSoftwareCode)){ sysSoftwareCode="store-service"; } WxMinConfigconfig=null; WxPayConfigwxPayConfig=newWxPayConfig(); /** *获取商家支付宝配置信息(优先级:1-redis,2-mysql,3-用户系统) */ try{ if(config==null){ //config=wxMinConfigService.selectByAppCode(appCode); config=wxMinConfigService.selectBySysSoftwareCode(appCode,sysSoftwareCode); } if(config==null){ logger.warn("WxPayServiceImpl.getWxMinPayConfigByAppCode--->>\n获取微信小程序支付配置信息失败:[{}]",appCode); thrownewBaseException(QYError.msg("获取微信支付配置信息失败!")); } }catch(Exceptione){ logger.error("WxPayServiceImpl.getWxMinPayConfigByAppCode--->>\n获取微信小程序支付配置信息失败:[{}]",e); thrownewBaseException(QYError.msg("获取微信小程序支付配置信息失败!")); } //根据appCode查询商家微信配置信息 wxPayConfig.setAppId(config.getAppid()); wxPayConfig.setMchId(config.getMchId()); wxPayConfig.setMchKey(config.getMchKeySecret()); wxPayConfig.setSignType(PayConstant.WXPAY_SIGNTYPE_MD5.getKey()); wxPayConfig.setKeyUrl(config.getCrtPath()); wxPayConfig.setKeyPath(config.getCrtPath()); log.info("获取微信小程序退款配置为[{}],转为微信支付实体为[{}]",config,wxPayConfig); returnwxPayConfig; } /** *封装预下单参数实体 * *@paramorderParam预支付接口参数实体 *@paramorder点单 *@return */ @Override publicWxPayUnifiedOrderRequestpackRequestParam(PreOrderParamorderParam){ Datedate=newDate(); BigDecimalparamAmount=newBigDecimal(orderParam.getTotalAmount().toString()); BigDecimalmultiplyNum=newBigDecimal("100"); WxPayUnifiedOrderRequestrequest=WxPayUnifiedOrderRequest.newBuilder() .body(orderParam.getBody()) .totalFee(paramAmount.multiply(multiplyNum).intValue()) .spbillCreateIp(orderParam.getReqId()) .notifyUrl(notifyUrl+PayConstant.WXPAY_09.getKey()) .tradeType(orderParam.getTradeType()) .outTradeNo(orderParam.getOutTradeNo()) .build(); log.info("WxPayUnifiedOrderRequest={}",PayConstant.WXPAY_09.getKey()); request.setProductId(orderParam.getDh()); request.setDetail(orderParam.getSubject()); PayNotifypayNotify=newPayNotify(); payNotify.setAppCode(orderParam.getAppCode()); payNotify.setCode(orderParam.getBmCode()); payNotify.setDh(orderParam.getDh()); request.setAttach(JSON.toJSONString(payNotify)); if(orderParam.getTradeType().equals(PayConstant.JSAPI.toString())){ request.setOpenid(orderParam.getOpenId()); } //开始时间 request.setTimeStart(DateUtils.getLastMinute(date,0)); //有效期 request.setTimeExpire(orderParam.getTimeExpire()); returnrequest; } /** *订单查询 * *@paramappCode商家编码 *@paramdh订单号 *@paramsysSoftwareCode *@return */ @Override publicWxPayOrderQueryResultwxPayOrderQuery(StringappCode,StringbmCode,Stringdh,Integertype,StringsysSoftwareCode){ logger.info("WxPayServiceImpl.wxPayOrderQuery--->>\n微信订单查询,\n本次查询的商家编码为:[{}],商务订单号:[{}]",appCode,dh); WxPayHandlerhandler=newWxPayHandlerApacheHttpImpl(); WxPayOrderQueryRequestrequest=newWxPayOrderQueryRequest(); WxPayOrderQueryResultqueryResult=null; WxPayConfigconfig=null; try{ PayLogpayLog=payLogService.selectByDh(dh); if(payLog==null){ //商家的微信支付 if(type==null||type==1){ bmCode=null; config=this.getWxPayConfigByAppCode(appCode,bmCode); //部门的微信支付支付 }elseif(type==2){ config=this.getWxPayConfigByAppCode(appCode,bmCode); //商家小程序支付 }elseif(type==3){ config=this.getWxMinPayConfigByAppCode(appCode,sysSoftwareCode); } }else{ config=JSON.parseObject(payLog.getPayConfigJsonStr(),WxPayConfig.class); } request.setOutTradeNo(dh); handler.setConfig(config); queryResult=handler.queryOrder(request); logger.info("WxPayServiceImpl.wxPayOrderQuery--->>\n微信订单查询成功,\n返回包信息:[{}]",JSON.toJSONString(queryResult)); }catch(WxPayExceptione){ logger.error("WxPayServiceImpl.wxPayOrderQuery--->>\n微信订单查询失败,\n商务订单号:[{}]",dh); thrownewBaseException(QYError.msg("微信订单查询失败,商务订单号:[{}]"+dh+"")); } returnqueryResult; } /** *企业支付 *@paramparams *@return:com.qcsoft.commonbean.bean.payment.wx.bean.result.BaseWxPayResult *@Author: *@date: */ @Override publicBaseWxPayResultentPay(EntPayParamparams)throwsWxPayException{ WxPayHandlerwxPayHandler=newWxPayHandlerApacheHttpImpl(); WxPayConfigconfig=null; EntPayResultresult=null; EntPayBankResultbankResult=null; if(params.getTradeType()!=null&¶ms.getTradeType()==3){ config=this.getWxMinPayConfigByAppCode(params.getAppCode(),params.getSysSoftwareCode()); }else{ config=this.getWxPayConfigByAppCode(params.getAppCode(),params.getBmCode()); } config.setUseKey(true); wxPayHandler.setConfig(config); if(params.getTradeType()==1){ EntPayRequestrequest=packEntPayRequest(params,config); EntPayHandlerentPayHandler=newEntPayHandlerImpl(wxPayHandler); result=entPayHandler.entPay(request); returnresult; }else{ EntPayBankRequestrequest=packEntPayBankRequest(params); EntPayHandlerentPayHandler=newEntPayHandlerImpl(wxPayHandler); bankResult=entPayHandler.payBank(request); returnbankResult; } } /** *封装微信企业支付请求参数 *@paramparams *@return:com.qcsoft.commonbean.bean.payment.wx.bean.entpay.EntPayRequest *@Author: *@date: */ publicEntPayRequestpackEntPayRequest(EntPayParamparams,WxPayConfigconfig){ EntPayRequestrequest=newEntPayRequest(); request.setAmount