本文共 11700 字,大约阅读时间需要 39 分钟。
本文本打算接入微信支付和支付宝支付作为讲解,但是没有弄到微信和支付宝的商户账户.所以支付将只会讲解扣除账户余额的方式.
com.ccm assembly-mysql 1.0.0 org.springframework.cloud spring-cloud-starter-openfeign
package com.ccm.server.pay;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Import;import springfox.documentation.swagger2.annotations.EnableSwagger2;/** * @Description server-pay服务启动类 * @Author ccm * @CreateTime 2020/8/19 14:18 */@EnableFeignClients@EnableDiscoveryClient //注册中心客户端@ComponentScan(basePackages = "com.ccm")@EnableSwagger2@MapperScan(basePackages = "com.ccm.server.pay.dao.mysql.mapper")@SpringBootApplication //声明为一个启动类@Import(value = { PaginationInterceptor.class})public class ServerPayApplication { public static void main(String[] args) { SpringApplication.run(ServerPayApplication.class,args); }}
server: port: 5000 #服务端口spring: application: name: server-pay #服务名称 cloud: nacos: discovery: server-addr: 47.96.131.185:8849 config: server-addr: 47.96.131.185:8849 #nacos config配置中心ip和端口 file-extension: yaml #文件扩展名格式,针对于默认的{spring.application.name}-${profile}.${file-extension:properties}配置 enabled: true #开启或关闭配置中心 datasource: username: root password: Test2016@ url: jdbc:mysql://47.96.131.185:3306/pay?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true type: com.alibaba.druid.pool.DruidDataSourcemybatis-plus: typeAliasesPackage: com.ccm.server.pay.dao.mysql.domain #数据库实体类包 mapper-locations: classpath:mappering/*.xml #xml文件扫描#自定义配置server-order: serverNumber: 1 #机器服务号
package com.ccm.server.pay.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.ParameterBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.schema.ModelRef;import springfox.documentation.service.ApiInfo;import springfox.documentation.service.Parameter;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import java.util.ArrayList;import java.util.List;/** * @Description swagger配置 * @Author ccm * @CreateTime 2020/7/8 17:38 */@Configurationpublic class SwaggerConfig { @Bean public Docket createRestApi() { Listpars = new ArrayList (); ParameterBuilder ticketPar = new ParameterBuilder(); ticketPar.name("ccm-token").description("必要参数(白名单接口无需传递)") .modelRef(new ModelRef("string")).parameterType("header") .required(false).build(); //header中的ticket参数非必填,传空也可以 pars.add(ticketPar.build()); return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.ccm.server.pay.controller")) //swagger接口扫描包 .paths(PathSelectors.any()).build().globalOperationParameters(pars); } private ApiInfo apiInfo() { return new ApiInfoBuilder().version("1.0.0") .title("欢迎") .description("光临") .termsOfServiceUrl("www.baidu.com") .build(); }}
package com.ccm.server.pay.constants;import com.alibaba.fastjson.JSONObject;import lombok.Data;import lombok.extern.slf4j.Slf4j;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;/** * @Description 自定义配置映射实体 * @Author ccm * @CreateTime 2020/08/18 15:01 */@Slf4j@Data@Component@ConfigurationProperties(prefix = "server-pay")public class ServerPayProperties { private String serverNumber; @PostConstruct public void init() { log.info("ServerPayProperties初始化完成......{}", JSONObject.toJSONString(this)); }}
spring: cloud: #gateway组件相关配置 gateway: routes: #路由配置 - id: server-pay #路由名称,不配默认为UUID uri: lb://server-pay #满足断言的路由到此服务 predicates: #为一个数组,每个规则为并且的关系 - Path=/api-pay/** #断言表达式,如果args不写key的,会自动生成一个id,如下会生成一个xxx0的key,值为/foo/* filters: #请求路由转发前执行的filter,为数组 - StripPrefix=1 #缩写,和name=StripPrefix,args,参数=1是一个意思,该过滤器为路由转发过滤去 - name: AuthFilter
package com.ccm.server.pay.controller;import com.ccm.common.exception.result.ResultSet;import com.ccm.server.pay.controller.service.PayService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.annotations.ApiParam;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.*;import java.util.List;/** * @Description 支付控制层 * @Author ccm * @CreateTime 2020/08/19 14:38 */@Api(tags = "支付")@RestController@RequestMapping(value = "pay")@Validatedpublic class PayController { @Autowired private PayService payService; @ApiOperation(value = "支付") @PostMapping(value = "pay") public ResultSetpay(@ApiParam(hidden = true) @RequestHeader(name = "ccm-userId") Long userId, @ApiParam(value = "支付金额")@RequestParam BigDecimal payMoney) { String flowingWaterId = payService.pay(userId,payMoney); return ResultSet.success(flowingWaterId); }}
package com.ccm.server.pay.controller.service;/** * @Description 支付业务层 * @Author ccm * @CreateTime 2020/08/19 15:13 */public interface PayService { /** * @Description 支付 * @Author ccm * @CreateTime 2020/8/19 16:06 * @Params [userId, payMoney] * @Return java.lang.String */ String pay(Long userId, BigDecimal payMoney);}
package com.ccm.server.pay.controller.service.impl;import com.ccm.common.exception.result.ResultSet;import com.ccm.server.pay.config.FlowingWaterIdGenerator;import com.ccm.server.pay.controller.service.PayService;import com.ccm.server.pay.dao.mysql.domain.PayFlowingWater;import com.ccm.server.pay.dao.mysql.mapper.PayFlowingWaterMapper;import com.ccm.server.pay.feign.ServerUserFeign;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** * @Description 支付业务层实现 * @Author ccm * @CreateTime 2020/08/19 15:14 */@Servicepublic class PayServiceImpl implements PayService { @Autowired private FlowingWaterIdGenerator flowingWaterIdGenerator; @Autowired private ServerUserFeign serverUserFeign; @Autowired private PayFlowingWaterMapper flowingWaterMapper; @Override public String pay(Long userId, BigDecimal payMoney) { //生成支付流水号 String flowingWaterId = flowingWaterIdGenerator.nextFlowingWaterId(); //调用server-user的账户扣除余额接口 ResultSet.getFeignData(serverUserFeign.deduction(userId,payMoney)); //pay_flowing_water表插入数据 PayFlowingWater payFlowingWater = new PayFlowingWater(); payFlowingWater.setUserId(userId); payFlowingWater.setFlowingWaterId(flowingWaterId); payFlowingWater.setPayMoney(payMoney); flowingWaterMapper.insert(payFlowingWater); return flowingWaterId; }}
package com.ccm.server.pay.config;import com.ccm.server.pay.constants.ServerPayProperties;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.Date;import java.util.UUID;/** * @Description 支付流水号id生成器 * @Author ccm * @CreateTime 2020/02/16 15:17 */@Componentpublic class FlowingWaterIdGenerator { private Long lastTimeStamp = 0L; //上次生成订单id的时间戳 @Autowired private ServerPayProperties serverPayProperties; /** * @Description 生成支付流水号 * @Author ccm * @CreateTime 2020/2/16 15:17 * @Params [] * @Return java.lang.String */ public String nextFlowingWaterId() { Long timeStamp; synchronized (this.getClass()) { while(true) { Long nowTimeStamp = System.currentTimeMillis(); if(!nowTimeStamp.equals(lastTimeStamp)) { timeStamp = nowTimeStamp; lastTimeStamp = nowTimeStamp; break; } } } String timeStampStr = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date(timeStamp)); StringBuffer idStringBuffer = new StringBuffer(); idStringBuffer.append(timeStampStr) .append(UUID.randomUUID().toString().replace("-","")) .append(serverPayProperties.getServerNumber()); return idStringBuffer.substring(0,32); }}
package com.ccm.server.pay.feign;import com.ccm.common.exception.result.ResultSet;import io.swagger.annotations.ApiParam;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.PutMapping;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestParam;/** * @Description 调用server-user服务的feign层 * @Author ccm * @CreateTime 2020/08/19 16:21 */@FeignClient(name = "server-user")public interface ServerUserFeign { @PutMapping(value = "account/deduction") ResultSet deduction(@ApiParam(hidden = true) @RequestHeader(name = "ccm-userId") Long userId, @ApiParam(value = "金额") @RequestParam BigDecimal amountOfMoney);}
package com.ccm.server.pay.dao.mysql.mapper;import com.ccm.server.pay.dao.mysql.domain.PayFlowingWater;/** * @Description pay_flowing_water表操作持久层 * @Author ccm * @CreateTime 2020/08/19 15:20 */public interface PayFlowingWaterMapper { int insert(PayFlowingWater payFlowingWater);}
insert into pay_flowing_water ( flowing_water_id, pay_money, user_id, create_time ) values ( #{flowingWaterId}, #{payMoney}, #{userId}, now() )
package com.ccm.server.pay.dao.mysql.domain;import lombok.Data;import java.util.Date;/** * @Description pay_flowing_water表映射实体类 * @Author ccm * @CreateTime 2020/08/19 15:17 */@Datapublic class PayFlowingWater { private String flowingWaterId; private BigDecimal payMoney; private Long userId; private Date createTime;}
账户余额成功扣款1元
生成了支付流水 至此,完事!您的点赞、收藏、转发和关注是我持续创作的动力!
源码地址:
转载地址:http://zutli.baihongyu.com/