From be5ebbf9bb1442509b100557764099778ba354b6 Mon Sep 17 00:00:00 2001 From: chenwei Date: Wed, 4 Sep 2024 18:20:07 +0800 Subject: [PATCH] 微信h5支付 --- backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java | 455 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java | 6 ++++++ backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java | 35 ++++++++++++++++++++++++++++++----- backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- backend/lpg-user/src/main/java/com/hotent/lpg/user/dao/CzzfpzDao.java | 14 ++++++++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/dto/DdDto.java | 18 ++++++++++++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/CzzfpzManager.java | 25 +++++++++++++++++++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/DdManager.java | 8 ++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java | 8 +++++++- backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------- backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WCzzfpzManagerImpl.java | 33 +++++++++++++++++++++++++++++++++ backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java | 54 +++++++----------------------------------------------- 14 files changed, 874 insertions(+), 363 deletions(-) create mode 100644 backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java create mode 100644 backend/lpg-user/src/main/java/com/hotent/lpg/user/dao/CzzfpzDao.java create mode 100644 backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/CzzfpzManager.java create mode 100644 backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WCzzfpzManagerImpl.java diff --git a/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java b/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java index 15be43d..312f62d 100644 --- a/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java +++ b/backend/base/src/main/java/com/hotent/base/conf/WebSecurityConfig.java @@ -39,239 +39,241 @@ import java.util.List; @EnableWebSecurity @Configuration -public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ - private static final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); - @Resource - UserDetailsService userDetailsService; - @Resource - JwtTokenHandler jwtTokenHandler; - @Resource - JwtConfig jwtConfig; - @Value("${feign.encry.key:feignCallEncry}") +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + private static final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); + @Resource + UserDetailsService userDetailsService; + @Resource + JwtTokenHandler jwtTokenHandler; + @Resource + JwtConfig jwtConfig; + @Value("${feign.encry.key:feignCallEncry}") private String encryKey; - @Value("${hotent.security.ignore.httpUrls:''}") - String permitAll; - @Value("${hotent.security.deny.httpUrls:''}") - String denyAll; - @Value("${hotent.security.pswd.encoder:}") - String passwordEncoder; + @Value("${hotent.security.ignore.httpUrls:''}") + String permitAll; + @Value("${hotent.security.deny.httpUrls:''}") + String denyAll; + @Value("${hotent.security.pswd.encoder:}") + String passwordEncoder; @Value("${cors.enable:true}") Boolean corsEnable; - @Resource - JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; - @Resource - HtFilterSecurityInterceptor htFilterSecurityInterceptor; - @Resource - CustomAccessDeniedHandler customAccessDeniedHandler; - @Resource - EipYmlConfig eipYmlConfig; - @Value("${webjar.context:mvue,front,mobile}") - private List resourceContext; - @Autowired - PortalFeignService portalFeignService; - @Value("${openApi.prefix:'openApi'}") - String openApiPre; + @Resource + JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + @Resource + HtFilterSecurityInterceptor htFilterSecurityInterceptor; + @Resource + CustomAccessDeniedHandler customAccessDeniedHandler; + @Resource + EipYmlConfig eipYmlConfig; + @Value("${webjar.context:mvue,front,mobile}") + private List resourceContext; + @Autowired + PortalFeignService portalFeignService; + @Value("${openApi.prefix:'openApi'}") + String openApiPre; // @Resource // List webExtends; - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService) - .passwordEncoder(getCustomPasswordEncoder()); - } + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService) + .passwordEncoder(getCustomPasswordEncoder()); + } - /** - * 获取配置的自定义密码加密类 - * @return - */ - public PasswordEncoder getCustomPasswordEncoder() { - CustomPwdEncoder encoder = (CustomPwdEncoder) defaultPasswordEncoderBean(); - if (StringUtil.isNotEmpty(passwordEncoder)) { - try { - logger.info("Use config password encoder : " + passwordEncoder); - PasswordEncoder delegate = (PasswordEncoder) Class.forName(passwordEncoder).newInstance(); - encoder.setDelegateEncoder(delegate); - } catch (Exception e) { - logger.error("Create custom password encoder config class["+passwordEncoder+"] failed."); - } - } - return encoder; - } + /** + * 获取配置的自定义密码加密类 + * + * @return + */ + public PasswordEncoder getCustomPasswordEncoder() { + CustomPwdEncoder encoder = (CustomPwdEncoder) defaultPasswordEncoderBean(); + if (StringUtil.isNotEmpty(passwordEncoder)) { + try { + logger.info("Use config password encoder : " + passwordEncoder); + PasswordEncoder delegate = (PasswordEncoder) Class.forName(passwordEncoder).newInstance(); + encoder.setDelegateEncoder(delegate); + } catch (Exception e) { + logger.error("Create custom password encoder config class[" + passwordEncoder + "] failed."); + } + } + return encoder; + } - @Bean - public WebSecurityExtend emptyExtend() { - return new WebSecurityEmptyExtend(); - } + @Bean + public WebSecurityExtend emptyExtend() { + return new WebSecurityEmptyExtend(); + } - @Bean - public PasswordEncoder defaultPasswordEncoderBean() { - return new CustomPwdEncoder(); - } + @Bean + public PasswordEncoder defaultPasswordEncoderBean() { + return new CustomPwdEncoder(); + } - // 注册后台权限控制器 - @Bean - public AccessDecisionManager accessDecisionManager() { - return new HtDecisionManager(); - } + // 注册后台权限控制器 + @Bean + public AccessDecisionManager accessDecisionManager() { + return new HtDecisionManager(); + } - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - String[] permitAlls = new String[]{}; - String[] denyAlls = new String[]{}; - if(StringUtil.isNotEmpty(permitAll)){ - permitAlls = permitAll.split(","); - } + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + String[] permitAlls = new String[]{}; + String[] denyAlls = new String[]{}; + if (StringUtil.isNotEmpty(permitAll)) { + permitAlls = permitAll.split(","); + } - // 将webjar中的resource资源添加到可匿名访问中 - for(String rc : resourceContext) { - permitAlls = (String[]) ArrayUtils.add(permitAlls, String.format("/%s/**", rc)); - } + // 将webjar中的resource资源添加到可匿名访问中 + for (String rc : resourceContext) { + permitAlls = (String[]) ArrayUtils.add(permitAlls, String.format("/%s/**", rc)); + } - if(StringUtil.isNotEmpty(denyAll)){ - denyAlls = denyAll.split(","); - } - httpSecurity - // we don't need CSRF because our token is invulnerable - .csrf().disable() - .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and() - .exceptionHandling().accessDeniedHandler(customAccessDeniedHandler).and() - // don't create session - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() - .authorizeRequests() - .antMatchers(permitAlls).permitAll() - .antMatchers(denyAlls).denyAll() - .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() - .antMatchers("/auth/**").permitAll() - .antMatchers("/lpg/auth/**").permitAll() - .antMatchers("/enterprise/largeScreen/v1/**").permitAll()//企业大屏接口 - // 文件预览相关 - .antMatchers("/index").permitAll() - .antMatchers("/mobile/v1/**").permitAll() - .antMatchers("/apiMobile/v1/**").permitAll() - .antMatchers("/images/**").permitAll() - .antMatchers("/listFiles").permitAll() - .antMatchers("/fileUpload").permitAll() - .antMatchers("/deleteFile").permitAll() - .antMatchers("/ueditor/**","/apiManager/getToken").permitAll() - .anyRequest().authenticated() - .accessDecisionManager(accessDecisionManager()); + if (StringUtil.isNotEmpty(denyAll)) { + denyAlls = denyAll.split(","); + } + httpSecurity + // we don't need CSRF because our token is invulnerable + .csrf().disable() + .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and() + .exceptionHandling().accessDeniedHandler(customAccessDeniedHandler).and() + // don't create session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + .authorizeRequests() + .antMatchers(permitAlls).permitAll() + .antMatchers(denyAlls).denyAll() + .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() + .antMatchers("/auth/**").permitAll() + .antMatchers("/lpg/auth/**").permitAll() + .antMatchers("/enterprise/largeScreen/v1/**").permitAll()//企业大屏接口 + // 文件预览相关 + .antMatchers("/index").permitAll() + .antMatchers("/mobile/v1/**").permitAll() + .antMatchers("/apiMobile/v1/**").permitAll() + .antMatchers("/images/**").permitAll() + .antMatchers("/listFiles").permitAll() + .antMatchers("/fileUpload").permitAll() + .antMatchers("/deleteFile").permitAll() + .antMatchers("/ueditor/**", "/apiManager/getToken").permitAll() + .antMatchers("/user/order/payment/notifyOrder").permitAll() + .anyRequest().authenticated() + .accessDecisionManager(accessDecisionManager()); - // Custom JWT based security filter - JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenHandler, jwtConfig.getHeader(),portalFeignService,openApiPre); - authenticationTokenFilter.setEncryKey(encryKey); - authenticationTokenFilter.setEipYmlConfig(eipYmlConfig); - httpSecurity - .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); - httpSecurity - .addFilterBefore(htFilterSecurityInterceptor, FilterSecurityInterceptor.class); - httpSecurity - .addFilterBefore(corsFilter(), ChannelProcessingFilter.class); + // Custom JWT based security filter + JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenHandler, jwtConfig.getHeader(), portalFeignService, openApiPre); + authenticationTokenFilter.setEncryKey(encryKey); + authenticationTokenFilter.setEipYmlConfig(eipYmlConfig); + httpSecurity + .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + httpSecurity + .addFilterBefore(htFilterSecurityInterceptor, FilterSecurityInterceptor.class); + httpSecurity + .addFilterBefore(corsFilter(), ChannelProcessingFilter.class); - // add custom filter + // add custom filter // for (WebSecurityExtend extend : webExtends) { // for (Map.Entry, Filter> entry : extend.getCustomBeforeFilter().entrySet()) { // httpSecurity.addFilterBefore(entry.getValue(), entry.getKey()); // } // } - // disable page caching - httpSecurity - .headers() - .frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank. - .cacheControl(); - } + // disable page caching + httpSecurity + .headers() + .frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank. + .cacheControl(); + } - @Override - public void configure(WebSecurity web) throws Exception { - // AuthenticationTokenFilter will ignore the below paths - web - .ignoring() - .antMatchers( - HttpMethod.POST, - "/auth", - "/error", - "/sys/sysLogs/v1/loginLogs", - "/sys/sysLogs/v1/saveLogs", - "/api/user/v1/user/loadUserByUsername", - "/actuator/cert", - "/form/formServiceController/v1/getFormAndBoExportXml", - "/api/twoVerify/v1/twoStepVerify", - "/api/twoVerify/v1/twoStepVerifyAndBind", - "/i18n/custom/i18nMessageType/v1/all", - "/**/bpmRuntimeStartUp" - ) - .antMatchers( - HttpMethod.GET, - "/sso/**", - "/sys/sysLogsSettings/v1/getSysLogsSettingStatusMap", - "/sys/sysRoleAuth/v1/getMethodRoleAuth", - "/system/file/v1/getLogoFile", - "/system/file/v1/getImage", - /*"/flow/bpmTaskReminder/v1/executeTaskReminderJob",*/ - "/flow/def/v1/bpmnXml", - "/file/onlinePreviewController/v1/getFileByPathAndId**", - "/file/onlinePreviewController/v1/getFileById**", - "/portal/main/v1/appProperties", - "/uc/tenantManage/v1/getTenantByCode", - "/sys/sysProperties/v1/getDecryptBySysSetting", - "/portal/shorturlManage/v1/getLongUrlByShortUrl", - "/system/file/v1/downloadFile", - "/portal/sysExternalUnite/v1/getQrCodeInfo", - "/portal/sysExternalUnite/v1/getDingtalkIdFromScanCode", - "/portal/sysExternalUnite/v1/getWxWorkIdFromScanCode", - "/base/tools/v1/getPublicKey", - "/portalBizSystem/v1/checkSysCodeAndUri", - "/instance/client/v1/get", - "/i18n/custom/i18nMessage/v1/getLangPackage", - "/task/check", - "/base/tools/v1/getPinyin" - ) - // allow anonymous resource requests - .and() - .ignoring() - .antMatchers( - HttpMethod.GET, - "/", - "/error", - "/*.html", - "/favicon.ico", - "/**/*.html", - "/getPreviewFile/*_*_*", // 附件预览 静态资源 - "/**/*.css", - "/**/*.js", - "/**/*.css", - "/**/*.woff2", - "/**/*.woff", - "/**/*.ttf", - "/**/image" - ) - .and() - .ignoring() - .antMatchers("/v2/api-docs", - "/swagger-resources/configuration/ui", - "/swagger-resources", - "/swagger-resources/configuration/security", - "/swagger-ui.html", - "/proxy.stream", - "/hystrix.stream", - "/druid/**", - "/hystrix/**", - "/actuator/**", - "/static/**", - "/public/**", - "/pdfjs/**", - "/css/**", - "/service/**") - .and().ignoring().antMatchers(eipYmlConfig.getAnonymousUrl().toArray(new String[eipYmlConfig.getAnonymousUrl().size()])); - ; + @Override + public void configure(WebSecurity web) throws Exception { + // AuthenticationTokenFilter will ignore the below paths + web + .ignoring() + .antMatchers( + HttpMethod.POST, + "/auth", + "/error", + "/sys/sysLogs/v1/loginLogs", + "/sys/sysLogs/v1/saveLogs", + "/api/user/v1/user/loadUserByUsername", + "/actuator/cert", + "/form/formServiceController/v1/getFormAndBoExportXml", + "/api/twoVerify/v1/twoStepVerify", + "/api/twoVerify/v1/twoStepVerifyAndBind", + "/i18n/custom/i18nMessageType/v1/all", + "/**/bpmRuntimeStartUp" + ) + .antMatchers( + HttpMethod.GET, + "/sso/**", + "/sys/sysLogsSettings/v1/getSysLogsSettingStatusMap", + "/sys/sysRoleAuth/v1/getMethodRoleAuth", + "/system/file/v1/getLogoFile", + "/system/file/v1/getImage", + /*"/flow/bpmTaskReminder/v1/executeTaskReminderJob",*/ + "/flow/def/v1/bpmnXml", + "/file/onlinePreviewController/v1/getFileByPathAndId**", + "/file/onlinePreviewController/v1/getFileById**", + "/portal/main/v1/appProperties", + "/uc/tenantManage/v1/getTenantByCode", + "/sys/sysProperties/v1/getDecryptBySysSetting", + "/portal/shorturlManage/v1/getLongUrlByShortUrl", + "/system/file/v1/downloadFile", + "/portal/sysExternalUnite/v1/getQrCodeInfo", + "/portal/sysExternalUnite/v1/getDingtalkIdFromScanCode", + "/portal/sysExternalUnite/v1/getWxWorkIdFromScanCode", + "/base/tools/v1/getPublicKey", + "/portalBizSystem/v1/checkSysCodeAndUri", + "/instance/client/v1/get", + "/i18n/custom/i18nMessage/v1/getLangPackage", + "/task/check", + "/base/tools/v1/getPinyin" + ) + // allow anonymous resource requests + .and() + .ignoring() + .antMatchers( + HttpMethod.GET, + "/", + "/error", + "/*.html", + "/favicon.ico", + "/**/*.html", + "/getPreviewFile/*_*_*", // 附件预览 静态资源 + "/**/*.css", + "/**/*.js", + "/**/*.css", + "/**/*.woff2", + "/**/*.woff", + "/**/*.ttf", + "/**/image" + ) + .and() + .ignoring() + .antMatchers("/v2/api-docs", + "/swagger-resources/configuration/ui", + "/swagger-resources", + "/swagger-resources/configuration/security", + "/swagger-ui.html", + "/proxy.stream", + "/hystrix.stream", + "/druid/**", + "/hystrix/**", + "/actuator/**", + "/static/**", + "/public/**", + "/pdfjs/**", + "/css/**", + "/service/**") + .and().ignoring().antMatchers(eipYmlConfig.getAnonymousUrl().toArray(new String[eipYmlConfig.getAnonymousUrl().size()])); + ; - // 添加扩展的路径过滤 + // 添加扩展的路径过滤 // for (WebSecurityExtend extend : webExtends) { // web // .ignoring() @@ -283,29 +285,30 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ // .ignoring() // .antMatchers(extend.getIgnoringUrl()); // } - } + } - /** - * 允许跨域访问的源 - * @return - */ - @Bean - public CorsFilter corsFilter() { - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - if(corsEnable){ + /** + * 允许跨域访问的源 + * + * @return + */ + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + if (corsEnable) { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); source.registerCorsConfiguration("/**", corsConfiguration); } - return new CorsFilter(source); - } + return new CorsFilter(source); + } - @Bean - public HtFilterSecurityInterceptor htFilterSecurityInterceptor(AccessDecisionManager accessDecisionManager) throws Exception{ - HtFilterSecurityInterceptor htFilterSecurityInterceptor = new HtFilterSecurityInterceptor(); - htFilterSecurityInterceptor.setAccessDecisionManager(accessDecisionManager); - return htFilterSecurityInterceptor; - } + @Bean + public HtFilterSecurityInterceptor htFilterSecurityInterceptor(AccessDecisionManager accessDecisionManager) throws Exception { + HtFilterSecurityInterceptor htFilterSecurityInterceptor = new HtFilterSecurityInterceptor(); + htFilterSecurityInterceptor.setAccessDecisionManager(accessDecisionManager); + return htFilterSecurityInterceptor; + } } diff --git a/backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java b/backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java index 76c25ba..6a8fc20 100644 --- a/backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java +++ b/backend/lpg-common/src/main/java/com/hotent/lpg/common/enums/DdztEnum.java @@ -10,6 +10,12 @@ import lombok.Getter; @Getter public enum DdztEnum { + + /** + * 待支付 + */ + dzf("dzf", "待支付"), + /** * 待配送 */ diff --git a/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java b/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java new file mode 100644 index 0000000..9cd33bd --- /dev/null +++ b/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WCzzfpz.java @@ -0,0 +1,203 @@ +package com.hotent.lpg.common.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.hotent.base.entity.BaseModel; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.fasterxml.jackson.annotation.JsonProperty; +/** + * 厂站支付配置 + * + * @author cw + * @since 2024-09-04 + */ +@ApiModel(value="WCzzfpz对象", description="厂站支付配置") +public class WCzzfpz extends BaseModel { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "主键") + @TableId(value = "ID_", type = IdType.ASSIGN_ID) + @JsonProperty("id") + private String id; + + @ApiModelProperty(value = "外键") + @TableField("REF_ID_") + @JsonProperty("refId") + private String refId; + + @ApiModelProperty(value = "企业ID") + @TableField("F_qyID") + @JsonProperty("fQyid") + private String fQyid; + + @ApiModelProperty(value = "厂站ID") + @TableField("F_czID") + @JsonProperty("fCzid") + private String fCzid; + + @ApiModelProperty(value = "企业名称") + @TableField("F_qymc") + @JsonProperty("fQymc") + private String fQymc; + + @ApiModelProperty(value = "厂站名称") + @TableField("F_czmc") + @JsonProperty("fCzmc") + private String fCzmc; + + @ApiModelProperty(value = "支付类型") + @TableField("F_zflx") + @JsonProperty("fZflx") + private String fZflx; + + @ApiModelProperty(value = "应用id") + @TableField("F_appId") + @JsonProperty("fAppid") + private String fAppid; + + @ApiModelProperty(value = "商户id") + @TableField("F_mchId") + @JsonProperty("fMchid") + private String fMchid; + + @ApiModelProperty(value = "商户密钥") + @TableField("F_mchKey") + @JsonProperty("fMchkey") + private String fMchkey; + + @ApiModelProperty(value = "商户证书序列号") + @TableField("F_certSerialNo") + @JsonProperty("fCertserialno") + private String fCertserialno; + + @ApiModelProperty(value = "APIv3密钥") + @TableField("F_apiV3Key") + @JsonProperty("fApiv3key") + private String fApiv3key; + + @ApiModelProperty(value = "表单数据版本") + @TableField("F_form_data_rev_") + @JsonProperty("fFormDataRev") + private Long fFormDataRev; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + public String getRefId() { + return refId; + } + + public void setRefId(String refId) { + this.refId = refId; + } + public String getFQyid() { + return fQyid; + } + + public void setFQyid(String fQyid) { + this.fQyid = fQyid; + } + public String getFCzid() { + return fCzid; + } + + public void setFCzid(String fCzid) { + this.fCzid = fCzid; + } + public String getFQymc() { + return fQymc; + } + + public void setFQymc(String fQymc) { + this.fQymc = fQymc; + } + public String getFCzmc() { + return fCzmc; + } + + public void setFCzmc(String fCzmc) { + this.fCzmc = fCzmc; + } + public String getFZflx() { + return fZflx; + } + + public void setFZflx(String fZflx) { + this.fZflx = fZflx; + } + public String getFAppid() { + return fAppid; + } + + public void setFAppid(String fAppid) { + this.fAppid = fAppid; + } + public String getFMchid() { + return fMchid; + } + + public void setFMchid(String fMchid) { + this.fMchid = fMchid; + } + public String getFMchkey() { + return fMchkey; + } + + public void setFMchkey(String fMchkey) { + this.fMchkey = fMchkey; + } + public String getFCertserialno() { + return fCertserialno; + } + + public void setFCertserialno(String fCertserialno) { + this.fCertserialno = fCertserialno; + } + public String getFApiv3key() { + return fApiv3key; + } + + public void setFApiv3key(String fApiv3key) { + this.fApiv3key = fApiv3key; + } + public Long getFFormDataRev() { + return fFormDataRev; + } + + public void setFFormDataRev(Long fFormDataRev) { + this.fFormDataRev = fFormDataRev; + } + + + @Override + protected Serializable pkVal() { + return this.id; + } + + @Override + public String toString() { + return "WCzzfpz{" + + "id=" + id + + ", refId=" + refId + + ", fQyid=" + fQyid + + ", fCzid=" + fCzid + + ", fQymc=" + fQymc + + ", fCzmc=" + fCzmc + + ", fZflx=" + fZflx + + ", fAppid=" + fAppid + + ", fMchid=" + fMchid + + ", fMchkey=" + fMchkey + + ", fCertserialno=" + fCertserialno + + ", fApiv3key=" + fApiv3key + + ", fFormDataRev=" + fFormDataRev + + "}"; + } +} diff --git a/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java b/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java index 421ff22..b984570 100644 --- a/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java +++ b/backend/lpg-common/src/main/java/com/hotent/lpg/common/model/WDd.java @@ -53,11 +53,6 @@ public class WDd extends BaseModel { @JsonProperty("fDdly") private String fDdly; - @ApiModelProperty(value = "支付方式") - @TableField("F_zffs") - @JsonProperty("fZffs") - private String fZffs; - @ApiModelProperty(value = "配送方式") @TableField("F_psfs") @JsonProperty("fPsfs") @@ -244,6 +239,36 @@ public class WDd extends BaseModel { @JsonProperty("fShdzwd") private String fShdzwd; +// 微信,现金,支付宝 + @ApiModelProperty(value = "支付方式") + @TableField("F_zffs") + @JsonProperty("fZffs") + private String fZffs; + + + // 是,否 + @ApiModelProperty(value = "是否支付") + @TableField("F_sfzf") + @JsonProperty("fSfzf") + private String fSfzf; + + @ApiModelProperty(value = "付款时间") + @TableField("F_fksj") + @JsonProperty("fFksj") + private LocalDateTime fFksj; + +// APP,NATIVE,JSAPI,MWEB + @ApiModelProperty(value = "支付类型") + @TableField("F_zflx") + @JsonProperty("fZflx") + private String fZflx; + + @ApiModelProperty(value = "支付单号(微信返回)") + @TableField("F_zfdh") + @JsonProperty("fZfdh") + private String fZfdh; + + /** * 订单详情 */ diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java index b3d3140..38276ab 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/controller/PaymentController.java @@ -1,41 +1,110 @@ package com.hotent.lpg.user.controller; +import cn.hutool.core.bean.BeanUtil; +import com.hotent.base.model.CommonResult; +import com.hotent.lpg.common.enums.DdlyEnum; +import com.hotent.lpg.common.enums.DdztEnum; +import com.hotent.lpg.common.enums.UserlxEnum; +import com.hotent.lpg.common.model.WDd; +import com.hotent.lpg.common.model.WHydz; +import com.hotent.lpg.common.model.WHyxx; +import com.hotent.lpg.user.dao.HydzDao; +import com.hotent.lpg.user.dto.DdDto; import com.hotent.lpg.user.enums.PayTypeEnum; +import com.hotent.lpg.user.manager.DdManager; +import com.hotent.lpg.user.manager.HyxxManager; import com.hotent.lpg.user.manager.PaymentManage; import com.hotent.lpg.user.vo.ResultData; +import com.hotent.uc.util.ContextUtil; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import java.util.HashMap; + @RestController -@RequestMapping("/payment/v1/") +@RequestMapping("/user/order/payment/") @AllArgsConstructor @Validated @Slf4j public class PaymentController { private final PaymentManage paymentManage; - /** - * 预支付 - * @param ddid - * @return - */ - @PostMapping("/{ddid}") - public ResultData pay(@PathVariable("ddid") String ddid) { - String payType = PayTypeEnum.WX.getName(); // 默认微信 - return paymentManage.pay(ddid, payType); + private final DdManager wDdManager; + private final HydzDao hydzDao; + private final HyxxManager wHyxxManager; +// /** +// * 预支付 +// * @param ddid +// * @return +// */ +// @PostMapping("/{ddid}") +// public ResultData pay(@PathVariable("ddid") String ddid) { +// String payType = PayTypeEnum.WX.getName(); // 默认微信 +// return paymentManage.pay(ddid, payType); +// } + + + @PostMapping(value = "/add") + @ApiOperation(value = "创建订单", httpMethod = "POST", notes = "创建订单") + public CommonResult createOrder(@ApiParam(name = "CreateOrderRequest", value = "创建订单请求对象", required = true) @RequestBody DdDto ddDto) throws Exception { + log.warn("创建订单1:{}", ddDto); + WHydz hydz = hydzDao.selectOneByHyIdAndDzId(ContextUtil.getCurrentUserId(), ddDto.getHydzId()); + if (BeanUtil.isEmpty(hydz)){ + throw new RuntimeException("未查询到地址信息。"); + } + WHyxx hyxx = wHyxxManager.getUseridByInfo(ContextUtil.getCurrentUserId()); + if (BeanUtil.isEmpty(hyxx)){ + throw new RuntimeException("未查询会员信息。"); + } + ddDto.setShlxr(hydz.getFLxr()); + ddDto.setShlxrdh(hydz.getFLxrdh()); + ddDto.setShsf(hydz.getFLxrsf()); + ddDto.setShs(hydz.getFLxrs()); + ddDto.setShq(hydz.getFLxrq()); + ddDto.setShjd(hydz.getFLxrjd()); + ddDto.setShxxdz(hydz.getFLxrxxdz()); + ddDto.setJd(hydz.getFJd()); + ddDto.setWd(hydz.getFWd()); + + ddDto.setSfhy("是"); + ddDto.setHydh(hyxx.getFSjh()); //账号就是电话 + ddDto.setHyid(hyxx.getFUserid()); + ddDto.setHymc(hyxx.getFXm()); + ddDto.setHylx(hyxx.getFHylx()); + ddDto.setSfzh(hyxx.getFSfzh()); + ddDto.setShtysbm(hyxx.getFShtysbm()); + + ddDto.setXdrlx(UserlxEnum.hy.getInfo()); + ddDto.setXdrid(ContextUtil.getCurrentUserId()); + ddDto.setXdrmc(ContextUtil.getCurrentUser().getFullname()); + ddDto.setDdly(DdlyEnum.xsxd.getInfo()); + ddDto.setDdzt(DdztEnum.dzf.getInfo()); + WDd order = wDdManager.addOrder(ddDto); + log.warn("创建订单2:{}", order); + HashMap resultData = paymentManage.wxPay(order); + log.warn("创建订单3:{}", resultData); + return CommonResult.ok().value(resultData); } + + + + /** * 支付回调 * @return */ - @PostMapping("/notify-order") + @PostMapping("/notifyOrder") public String notifyOrder(@RequestBody String xmlData) { log.warn("支付回调:{}", xmlData); String res = paymentManage.notifyOrder(xmlData); - log.warn("处理状态:{}", res); - return res; + log.warn("处理状态:{}", xmlData); + return xmlData; } } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/dao/CzzfpzDao.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/dao/CzzfpzDao.java new file mode 100644 index 0000000..8eefc37 --- /dev/null +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/dao/CzzfpzDao.java @@ -0,0 +1,14 @@ +package com.hotent.lpg.user.dao; + +import com.hotent.lpg.common.model.WCzzfpz; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 厂站支付配置 Mapper 接口 + * + * @author cw + * @since 2024-09-04 + */ +public interface CzzfpzDao extends BaseMapper { + +} diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/dto/DdDto.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/dto/DdDto.java index dbc2cf1..a5dad13 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/dto/DdDto.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/dto/DdDto.java @@ -124,6 +124,21 @@ public class DdDto { */ private String wd; + /** + * 维度 + */ + private String ddzt; + + + /** + * 支付方式(微信,现金,支付宝) + */ + private String zffs; + + /** + * 支付类型(APP,NATIVE,JSAPI,MWEB) + */ + private String zflx; /** @@ -146,5 +161,8 @@ public class DdDto { @NotNull(message = "数量不能为空") private Integer sl; } + + + } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/CzzfpzManager.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/CzzfpzManager.java new file mode 100644 index 0000000..ba578a3 --- /dev/null +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/CzzfpzManager.java @@ -0,0 +1,25 @@ +package com.hotent.lpg.user.manager; + +import com.hotent.lpg.common.model.WCzzfpz; +import com.hotent.base.manager.BaseManager; + +/** + * 厂站支付配置 服务类 + * + * @author cw + * @since 2024-09-04 + */ +public interface CzzfpzManager extends BaseManager { + /** + * 根据主键获取详情 + * @param id + * @return + */ + WCzzfpz getDetail(String id); + /** + * 新建、更新厂站支付配置 + * @param wCzzfpz + * @return + */ + void createOrUpdate(WCzzfpz wCzzfpz); +} diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/DdManager.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/DdManager.java index 21fff6d..2a7e5a7 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/DdManager.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/DdManager.java @@ -52,4 +52,12 @@ public interface DdManager extends BaseManager { DdxxVo getOrderByid(String oracleId); + /** + * 创建订单 + * @param ddDto + * @return + */ + WDd addOrder(DdDto ddDto); + + } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java index 1ca6e56..0c9ba75 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/PaymentManage.java @@ -1,10 +1,16 @@ package com.hotent.lpg.user.manager; +import com.hotent.lpg.common.model.WDd; import com.hotent.lpg.user.vo.ResultData; +import java.util.HashMap; + public interface PaymentManage { - ResultData pay(String ddid, String payType); +// ResultData pay(String ddid, String payType); String notifyOrder(String xmlData); + + HashMap wxPay(WDd order); + } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java index e256831..f78910f 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/DdManagerImpl.java @@ -196,4 +196,72 @@ public class DdManagerImpl extends BaseManagerImpl implements DdMana ddxxVo.setMcazsj(BeanUtil.isEmpty(wHyyqjl) ? null : wHyyqjl.getFCjsj()); return ddxxVo; } + + @Override + public WDd addOrder(DdDto ddDto) { + WQplx qplx = qplxDao.selectById(ddDto.getXqList().get(0).getQplxId()); + WDd dd = new WDd(); + dd.setId(idGenerator.getSuid()); + dd.setFSfhy(ddDto.getSfhy()); + dd.setFHyyhid(ddDto.getHyid()); + dd.setFHymc(ddDto.getHymc()); + dd.setFHylx(ddDto.getHylx()); + dd.setFHydh(ddDto.getHydh()); + dd.setFShtysbm(ddDto.getShtysbm()); + dd.setFSfzh(ddDto.getSfzh()); + dd.setFDdlx(null); + dd.setFDddh(idGenerator.getSuid()); + dd.setFDdly(ddDto.getDdly()); + dd.setFZffs(ddDto.getZffs()); + dd.setFZflx(ddDto.getZflx()); + dd.setFSfzf("否"); + dd.setFPsfs(ddDto.getPsfs()); + dd.setFDdzt(StringUtil.isEmail(ddDto.getDdzt())?DdztEnum.dps.getInfo():ddDto.getDdzt()); + dd.setFMjly(ddDto.getMjly()); + dd.setFBz(ddDto.getBz()); + dd.setFCzid(qplx.getfSsczid()); + dd.setFCzmc(qplx.getfSsczmc()); + dd.setFQyid(qplx.getfSsqyid()); + dd.setFXdrlx(ddDto.getXdrlx()); + dd.setFXdrid(ddDto.getXdrid()); + dd.setFXdrmc(ddDto.getXdrmc()); + dd.setFShlxr(ddDto.getShlxr()); + dd.setFShlxrdh(ddDto.getShlxrdh()); + dd.setFShsf(ddDto.getShsf()); + dd.setFShs(ddDto.getShs()); + dd.setFShq(ddDto.getShq()); + dd.setFShjd(ddDto.getShjd()); + dd.setFShxxdz(ddDto.getShxxdz()); + dd.setFCjr(ContextUtil.getCurrentUser().getFullname()); + dd.setFCjsj(LocalDateTime.now()); + dd.setFGxr(ContextUtil.getCurrentUser().getFullname()); + dd.setFGxsj(LocalDateTime.now()); + dd.setFShdzjd(ddDto.getJd()); + dd.setFShdzwd(ddDto.getWd()); + BigDecimal ddje = new BigDecimal(0); + List ddxqList = new ArrayList(); + for (DdDto.XqVO xqVO : ddDto.getXqList()) { + WQplx wQplx = qplxDao.selectById(xqVO.getQplxId()); + if (ObjectUtil.isNull(wQplx)) { + throw new RuntimeException("商品信息不存在"); + } + ddje = NumberUtil.add(ddje, NumberUtil.mul(wQplx.getfJg(), xqVO.getSl())); + WDdxq ddxq = new WDdxq(); + ddxq.setfDdid(dd.getId()); + ddxq.setfQplxid(wQplx.getId()); + ddxq.setfSpmc(wQplx.getfMc()); + ddxq.setfTp(wQplx.getfTp()); + ddxq.setfSl(BigDecimal.valueOf(xqVO.getSl())); + ddxq.setfDj(wQplx.getfJg()); + ddxq.setfMs(wQplx.getfMs()); + ddxqDao.insert(ddxq); + ddxqList.add(ddxq); + } + dd.setFDdje(ddje); + dd.setDdxqList(ddxqList); + baseMapper.insert(dd); + //添加服务日志 + wDdfwrzManager.insertDdfwrz(DdfwlxEnum.cjdd.getCode(), dd.getId()); + return dd; + } } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java index 0773d5b..05baef0 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/PaymentManageImpl.java @@ -3,14 +3,20 @@ package com.hotent.lpg.user.manager.impl; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.hotent.base.util.BeanUtils; +import com.hotent.lpg.common.model.WCzzfpz; import com.hotent.lpg.common.model.WDd; +import com.hotent.lpg.common.model.WQpxx; +import com.hotent.lpg.user.dao.CzzfpzDao; import com.hotent.lpg.user.dao.DdDao; import com.hotent.lpg.user.enums.PayTypeEnum; import com.hotent.lpg.user.manager.PaymentManage; @@ -21,9 +27,23 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.StringReader; +import java.io.StringWriter; import java.math.BigDecimal; +import java.sql.Wrapper; import java.time.LocalDateTime; +import java.util.HashMap; @Service @Transactional @@ -31,110 +51,163 @@ import java.time.LocalDateTime; @Slf4j public class PaymentManageImpl implements PaymentManage { private final DdDao ddDao; - + private final CzzfpzDao czzfpzDao; @Override - public ResultData pay(String ddid, String payType) { + public String notifyOrder(String xmlData) { + // 从 XML 数据中提取支付单号 + String outTradeNo = extractValueFromXML(xmlData, "out_trade_no"); + //先用订单号找到订单 + WDd wDd = ddDao.selectOne(new LambdaQueryWrapper().eq(WDd::getFDddh, outTradeNo)); + //在用 场站信息 拿到场站对应得支付配置 + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); + //下面依旧是走微信sdk,查询订单和验证订单,为了保证数据得安全性,还是重复验证一次 + String dddh = null; + try { + WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData); + // 获取订单编号 + dddh = notifyResult.getOutTradeNo(); + // 获取微信支付单号 + String transactionId = notifyResult.getTransactionId(); + wDd = ddDao.selectOne(new LambdaQueryWrapper().eq(WDd::getFDddh, dddh)); + if (wDd == null) { + log.warn("订单不存在: {}", dddh); + return generateXmlResponse("FAIL", "订单不存在", dddh); + } + // 检查订单状态是否已支付 + if ("已支付".equals(wDd.getFDdzt())) { + log.warn("订单 {} 已经处理过,忽略本次通知", dddh); + return generateXmlResponse("SUCCESS", "已处理过", dddh); + } + BigDecimal payPrice = wDd.getFDdje(); + if (payPrice.multiply(new BigDecimal(100)).intValue() != notifyResult.getTotalFee()) { + log.warn("付款金额与订单金额不等: {}", dddh); + return generateXmlResponse("FAIL", "付款金额与订单金额不等", dddh); + } + + String timeEnd = notifyResult.getTimeEnd(); + LocalDateTime paymentTime = LocalDateTimeUtils.parse(timeEnd); + wDd.setFFksj(paymentTime); + wDd.setFSfzf("是"); + wDd.setFDdzt("待配送"); + wDd.setFZfdh(transactionId); + ddDao.updateById(wDd); - WDd wDd = ddDao.selectById(ddid); - if (BeanUtils.isEmpty(wDd)) { - return ResultData.error("订单不存在"); + log.info("订单支付成功: {}", dddh); + return generateXmlResponse("SUCCESS", "成功", dddh); + } catch (WxPayException e) { + log.error("支付回调处理失败: {}", e.getErrCodeDes(), e); + return generateXmlResponse("FAIL", e.getErrCodeDes(), dddh); } - if (payType.equals(PayTypeEnum.WX.getName())) { - wDd.setFZffs(PayTypeEnum.WX.getName()); - return wxPay(wDd); + } + + + private String extractValueFromXML(String xmlData, String paramName) { + // 解析 XML 数据以提取指定参数的值 + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(xmlData)); + Document doc = dBuilder.parse(is); + + Element element = doc.getDocumentElement(); + Node paramNode = element.getElementsByTagName(paramName).item(0).getFirstChild(); + return paramNode != null ? paramNode.getNodeValue() : null; + } catch (Exception e) { + log.error("解析 XML 数据失败: {}", e.getMessage(), e); + return null; } - return ResultData.error("支付方式错误"); } - private ResultData wxPay(WDd wDd) { + private String generateXmlResponse(String returnCode, String returnMsg, String outTradeNo) { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder; try { - String tradeType = wDd.getFZffs(); - if (StrUtil.isBlank(tradeType)) { - return ResultData.error("支付方式错误"); - } + dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.newDocument(); + + Element rootElement = doc.createElement("xml"); + doc.appendChild(rootElement); + + Element returnCodeElement = doc.createElement("return_code"); + returnCodeElement.appendChild(doc.createTextNode(returnCode)); + rootElement.appendChild(returnCodeElement); - // 防止重新启动支付时报“商户订单号重复”,前面增加8位随机数,product_id最大32位 - String outTradeNo = RandomUtil.randomString(8) + "_" + wDd.getId(); - String body = wDd.getFDddh(); - body = body.length() > 40 ? body.substring(0,39) : body; + Element returnMsgElement = doc.createElement("return_msg"); + returnMsgElement.appendChild(doc.createTextNode(returnMsg)); + rootElement.appendChild(returnMsgElement); + Element outTradeNoElement = doc.createElement("out_trade_no"); + outTradeNoElement.appendChild(doc.createTextNode(outTradeNo)); + rootElement.appendChild(outTradeNoElement); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + return writer.toString(); + } catch (Exception e) { + log.error("构建 XML 响应失败", e); + return "FAIL处理失败"; + } + } + + @Override + public HashMap wxPay(WDd wDd) { + try { + WCzzfpz wCzzfpz = czzfpzDao.selectOne(Wrappers.lambdaQuery().eq(WCzzfpz::getFCzid, wDd.getFCzid()).eq(WCzzfpz::getFZflx, wDd.getFZffs())); + if (BeanUtils.isEmpty(wCzzfpz) || wCzzfpz == null) { + throw new RuntimeException("支付配置不存在"); + } + String tradeType = wDd.getFZflx(); + if (StrUtil.isBlank(tradeType)) { + throw new RuntimeException("支付方式错误"); + } WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest(); - wxPayUnifiedOrderRequest.setAppid(WxPayConfiguration.appId); + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); wxPayUnifiedOrderRequest.setOpenid(null); - wxPayUnifiedOrderRequest.setBody(body); - wxPayUnifiedOrderRequest.setOutTradeNo(outTradeNo); + wxPayUnifiedOrderRequest.setBody(wDd.getFDddh()); + wxPayUnifiedOrderRequest.setOutTradeNo(wDd.getFDddh()); wxPayUnifiedOrderRequest.setTotalFee(wDd.getFDdje().multiply(new BigDecimal(100)).intValue()); wxPayUnifiedOrderRequest.setTradeType(tradeType); - + log.warn("创建订单5:{}", wxPayUnifiedOrderRequest); JSONObject scene_info = new JSONObject(); scene_info.put("id", "LPG"); scene_info.put("name", "燃气"); wxPayUnifiedOrderRequest.setSceneInfo(scene_info.toString()); - wxPayUnifiedOrderRequest.setNotifyUrl("https://zaoyin.peony.cn/server/hzys/payment/v1/notify-order"); // 支付回调地址,开放不用登录 + wxPayUnifiedOrderRequest.setNotifyUrl("http://i42mtc.natappfree.cc/api/user/order/payment/notifyOrder"); // 支付回调地址,开放不用登录 wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1"); - // trade_type=APP时 移动应用内的支付场景 - if("APP".equals(wxPayUnifiedOrderRequest.getTradeType())){ - wxPayUnifiedOrderRequest.setAppid(WxPayConfiguration.appId); + if ("APP".equals(wxPayUnifiedOrderRequest.getTradeType())) { + wxPayUnifiedOrderRequest.setAppid(wCzzfpz.getFAppid()); } // trade_type=NATIVE时 线下消费场景 - if("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())){ + if ("NATIVE".equals(wxPayUnifiedOrderRequest.getTradeType())) { wxPayUnifiedOrderRequest.setProductId(wxPayUnifiedOrderRequest.getOutTradeNo()); } // 公众号内或者微信内的网页支付 if ("JSAPI".equals(wxPayUnifiedOrderRequest.getTradeType())) { - wxPayUnifiedOrderRequest.setOpenid(null); + wxPayUnifiedOrderRequest.setOpenid("oH7LG54_Y49mVunw2FLXzUCxHWlM"); } // 手机浏览器中的支付场景 if ("MWEB".equals(wxPayUnifiedOrderRequest.getTradeType())) { wxPayUnifiedOrderRequest.setSceneInfo(null); } - WxPayService wxPayService = WxPayConfiguration.getPayService(); - ddDao.updateById(wDd); - return ResultData.success(wxPayService.createOrder(wxPayUnifiedOrderRequest)); + WxPayService wxPayService = WxPayConfiguration.getPayService(wCzzfpz); + Object payment = wxPayService.createOrder(wxPayUnifiedOrderRequest); + HashMap resultData = new HashMap(); + resultData.put("payment", payment); + resultData.put("ddid", wDd.getId()); + resultData.put("dddh", wDd.getFDddh()); + return resultData; } catch (WxPayException e) { - if("INVALID_REQUEST".equals(e.getErrCode())){ - return ResultData.error("订单号重复,请重新下单"); + if ("INVALID_REQUEST".equals(e.getErrCode())) { + throw new RuntimeException("订单号重复,请重新下单"); } - e.printStackTrace(); - return ResultData.error(e.getReturnMsg() + "" + e.getCustomErrorMsg() + "" + e.getErrCodeDes()); - } - } - - - @Override - public String notifyOrder(String xmlData) { - WxPayService wxPayService = WxPayConfiguration.getPayService(); - try { - WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData); - String ddid = notifyResult.getOutTradeNo().split("_")[1]; - WDd wDd = ddDao.selectById(ddid); - if (null == wDd) { - return WxPayNotifyResponse.fail("订单不存在"); - } - BigDecimal payPrice = wDd.getFDdje(); - if (payPrice.multiply(new BigDecimal(100)).intValue() != notifyResult.getTotalFee()) { - return WxPayNotifyResponse.fail("付款金额与订单金额不等"); - } - - String timeEnd = notifyResult.getTimeEnd(); - LocalDateTime paymentTime = LocalDateTimeUtils.parse(timeEnd); -// wDdb.setfFksj(paymentTime); -// wDdb.setfZfdh(notifyResult.getTransactionId()); -// wDdb.setfSffk("是"); -// wDdb.setfDdzt("已付款"); -// wDdb.setfPtddzt("待审批"); -// wDdbDao.updateById(wDdb); -// -// if (StrUtil.isNotBlank(wDdb.getfZpid())) { -// WZp wZp = wZpDao.selectById(wDdb.getfZpid()); -// wZp.setfZt("定制中"); -// wZpDao.updateById(wZp); -// } - return WxPayNotifyResponse.success("成功"); - } catch (WxPayException e) { - return WxPayNotifyResponse.fail(e.getErrCodeDes()); + throw new RuntimeException(e.getMessage()); } } } diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WCzzfpzManagerImpl.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WCzzfpzManagerImpl.java new file mode 100644 index 0000000..4a8439e --- /dev/null +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/manager/impl/WCzzfpzManagerImpl.java @@ -0,0 +1,33 @@ +package com.hotent.lpg.user.manager.impl; + +import com.hotent.lpg.common.model.WCzzfpz; +import com.hotent.lpg.user.dao.CzzfpzDao; +import com.hotent.lpg.user.manager.CzzfpzManager; +import com.hotent.base.manager.impl.BaseManagerImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +/** + * 厂站支付配置 服务实现类 + * + * @author cw + * @since 2024-09-04 + */ +@Service +public class WCzzfpzManagerImpl extends BaseManagerImpl implements CzzfpzManager { + + @Override + public WCzzfpz getDetail(String id) { + WCzzfpz wCzzfpz = this.get(id); + + + return wCzzfpz; + } + @Override + @Transactional + public void createOrUpdate(WCzzfpz wCzzfpz) { + //新建或更新 + this.saveOrUpdate(wCzzfpz); + } +} diff --git a/backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java b/backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java index 6c9f220..27799d8 100644 --- a/backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java +++ b/backend/lpg-user/src/main/java/com/hotent/lpg/user/util/WxPayConfiguration.java @@ -3,57 +3,17 @@ package com.hotent.lpg.user.util; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import com.hotent.lpg.common.model.WCzzfpz; public class WxPayConfiguration { -// public static final String appId = "wxf41ff374261f39cc"; // 该配置用的是景易游的微信支付信息 - public static final String appId = "wxde6f31c15afb357d"; - - public static WxPayService getPayService() { - // 该配置用的是景易游的微信支付信息 -// WxPayConfig wxPayConfig = new WxPayConfig(); -// wxPayConfig.setAppId("wxf41ff374261f39cc"); -// wxPayConfig.setMchId("1634368190"); -// wxPayConfig.setMchKey("Peony8228Peony8228Peony8228Peony"); -//// wxPayConfig.setKeyPath("/mnt/install/joolun-file/cert/1/apiclient_cert8e55f27b-6d67-4b91-a16e-e9f6ef96ca5b11027923844080776299.p12"); -//// wxPayConfig.setPrivateKeyPath("/mnt/install/joolun-file/cert/1/apiclient_key571e2a52-a9f8-46c5-9d4d-ed4b08d0749c4331609001879503591.pem"); -//// wxPayConfig.setPrivateCertPath("/mnt/install/joolun-file/cert/1/apiclient_cert13b610c6-4005-4189-8a61-85fab73fa42017841178972810569411.pem"); -// wxPayConfig.setCertSerialNo("55ED43DE3CC79DD045B92577A8FB2E95AACE8BEF"); -// wxPayConfig.setApiV3Key("Peony8228Peony8228Peony8228Peony"); -// // 可以指定是否使用沙箱环境 -// wxPayConfig.setUseSandboxEnv(false); - - - /** - * 商户简称: - * 牡丹集团宁安智慧工程中心 - * 企业名称: - * 北京牡丹电子集团有限责任公司宁安智慧工程中心 - * 登录账号 - * 1556251121 (本账号) - * - * 账号角色 - * Administrator - * 创建时间 - * 2019年9月19日 09:29:32 - * 绑定微信号 - * c*****21更换绑定 - * 姓 名 - * *际 - * 联系手机 - * 158******80 - * 联系邮箱 - * b*********n - */ + public static WxPayService getPayService(WCzzfpz wCzzfpz) { WxPayConfig wxPayConfig = new WxPayConfig(); - wxPayConfig.setAppId("wxde6f31c15afb357d"); // appId(应用id)(微信支付商户平台获取) - wxPayConfig.setMchId("1556251121"); // 商户号(微信支付商户平台获取) + wxPayConfig.setAppId(wCzzfpz.getFAppid()); // appId(应用id)(微信支付商户平台获取) + wxPayConfig.setMchId(wCzzfpz.getFMchid()); // 商户号(微信支付商户平台获取) // 这里的密钥应该使用APIv2密码,v3密钥此jar包不支持签名方式 - wxPayConfig.setMchKey("Peony8228Peony8228Peony8228Peony"); // 商户密钥(APIv2密钥)(微信支付商户平台-》账户中心-》API安全中获取APIv3密钥) -// wxPayConfig.setKeyPath("/mnt/install/joolun-file/cert/1/apiclient_cert8e55f27b-6d67-4b91-a16e-e9f6ef96ca5b11027923844080776299.p12"); -// wxPayConfig.setPrivateKeyPath("/mnt/install/joolun-file/cert/1/apiclient_key571e2a52-a9f8-46c5-9d4d-ed4b08d0749c4331609001879503591.pem"); -// wxPayConfig.setPrivateCertPath("/mnt/install/joolun-file/cert/1/apiclient_cert13b610c6-4005-4189-8a61-85fab73fa42017841178972810569411.pem"); - wxPayConfig.setCertSerialNo("736846A3CE4CBAC36DD5E81EB08F89240E4A05E1"); // 商户证书序列号(微信支付商户平台-》账户中心-》API安全中申请API证书) - wxPayConfig.setApiV3Key("Peony8228Peony8228Peony8228Peony"); // 商户密钥(APIv2密钥)(微信支付商户平台-》账户中心-》API安全中获取APIv3密钥) + wxPayConfig.setMchKey(wCzzfpz.getFMchkey()); // 商户密钥(APIv2密钥)(微信支付商户平台-》账户中心-》API安全中获取APIv3密钥) + wxPayConfig.setCertSerialNo(wCzzfpz.getFCertserialno()); // 商户证书序列号(微信支付商户平台-》账户中心-》API安全中申请API证书) + wxPayConfig.setApiV3Key(wCzzfpz.getFApiv3key()); // 商户密钥(APIv2密钥)(微信支付商户平台-》账户中心-》API安全中获取APIv3密钥) // 可以指定是否使用沙箱环境 wxPayConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); -- libgit2 0.21.2