预见猿份
主题
首页面试题在线工具关于我们老苗一对一私教学员评价
实战项目
项目前置基础创新WMS项目Java微服务框架与实战云岚到家项目闪聚支付项目学成在线项目青橙电商项目JVM原理与实战调优分布式事务专题Java高频面试题MySQL从入门到精通Java数据结构与算法老苗一对一私教学员评价blog
blog
  • 闪聚支付项目

    • 项目介绍
    • 项目安装配置
    • 第一章商户注册&资质申请
    • 验证码服务使用指南
    • 第二章支付参数配置
    • 第二章对接SaaS
    • 七牛云对象存储使用指南
    • 第三章C扫B支付
    • 支付宝接入指南
    • 微信支付接入指南
    • 第四章闪聚支付项目总结&就业指导







----- 到底线了 -----

×

欢迎来到预见猿份,本站项目均为站长原创,学习中有问题可直接提交给站长老苗解决(微信:mrt_0607)。

苗润土老师,20余年一线项目经验,2014年加入黑马,星辰wms、云岚到家、学成在线项目作者,历任高级讲师、教学主管及课程研究员。 b站老苗

闪聚支付 第2章 讲义-支付参数配置 ​

1 需求概述 ​

1.1 基础概念 ​

1.1.1 理解应用 ​

​ 商户资质审核通过后就可以使用闪聚支付平台提供的服务,闪聚支付平台所提供的基础服务正是聚合支付。聚合支付就是将微信、支付宝等支付渠道汇聚为一个支付通道供商户使用,如下图:

闪聚支付平台提供线上支付和线下支付两个方式,线上支付可通过手机和PC完成,线下支付可通过扫码完成。

1576119989544

1、闪聚支付平台对接微信、支付宝等众多支付渠道。

2、商户创建自己的应用

3、用户在使用商户某个应用时发起支付到闪聚支付平台

4、闪聚支付平台根据用户的支付请求使用具体的支付渠道完成支付。

支付渠道是什么?

是指微信、支付宝等第三方支付机构提供的支付渠道。闪聚支付平台是要聚合这些支付渠道,为用户提供一个支付通道。

应用是什么?

应用是商户在闪聚支付平台创建的业务标识,比如:商户在自己的XX电商网站使用闪聚支付则会创建“XX电商网站应用”,商户在自己经营的餐厅使用闪聚支付则会创建“XX餐厅应用”。

应用有什么用?

用户是基于某个应用完成的支付,用户在商户的餐厅支付则支付订单会隶属于“XX餐厅应用”下,用户在XX电商网站支付则支付订单会隶属于“XX电商网站应用”下。

闪聚支付平台通过应用来管理商户的支付订单,实现按业务进行订单管理、财务数据统计等功能。比如:可以统计“XX餐厅应用”下的支付订单,统计“XX电商网站应用”下的订单信息。

1.1.2 理解支付渠道参数配置 ​

​ 闪聚支付平台作为一个中介,为了给用户提供更便利的支付体验而聚合了微信、支付宝等第三方支付渠道为一个支付通道,用户通过闪聚支付平台完成支付,闪聚支付平台最终会请求第三方支付渠道完成支付。

​ 所以, 商户不仅是闪聚平台的商户,还是第三方支付机构的商户,商户要使用闪聚支付平台就需要开通微信、支付宝等支付渠道,然后在闪聚支付平台配置支付渠道参数,如下图:

1576122656489

一、整体流程如下:

1、商户在支付宝、微信开通支付

下图是商户在支付宝开通支付后的配置参数,包括Appid、密钥等。(在支付章节详细介绍这些参数)

1576132433450

2、商户在闪聚支付平台配置支付渠道参数

商户把支付宝、微信等支付渠道的参数配置在闪聚支付平台。

第一步在第三方支付渠道开通支付,商户将第三支付渠道的APPID、密钥等信息配置在闪聚支付平台。

3、闪聚支付平台为商户生成一个支付二维码

如果不使用闪聚支付平台商户要分别在支付宝、微信生成不同的二维码

4、用户扫二维码完成支付

当用户用支付宝扫描二维码则自动用支付宝完成支付,当使用微信扫描二维码则自动打开微信进行支付。

二、商户应该配置哪些第三方支付渠道的参数呢?

1、首先理解服务类型

服务类型是闪聚支付平台为商户提供的聚合支付服务通道,共分为线上和线下两大类:

线上支付服务通道:

1)手机APP支付

2)PC网页支付

3)手机网页支付

4)小程序支付

等

线下支付服务通道:

1)收款码支付(C扫B)

商户出示收款码,用户扫收款码完成支付。

1576134393245

2)B扫C,顾客出示付款码,商户扫描付款码

1576135310468

2、商户为应用绑定服务类型

前边学习了“应用”的概念,用户是基于某个应用进行支付,商户为应用绑定服务类型。比如:商户为”XX餐厅应用“绑定服务类型为收款码支付,则用户可以C扫B支付;商户为“XX电商网站应用”指定服务类型为“手机网页支付”,则用户可以通过 手机端在 XX电商网站完成支付。一个应用可以指定多个服务类型。

C扫B支付:顾客扫商户出示的二维码完成支付。

3、配置支付渠道参数

第三方支付渠道提供多种支付方式,比如:微信提供如下支付方式和支付宝提供的支付方式。

微信支付方式:

1576136909472

支付宝支付方式:

1576137351543

商户需要根据应用所绑定的服务类型来配置支付渠道的参数,比如:应用绑定的服务类型是“收款码支付(c扫b)”则需要配置微信的“JSAPI支付”和支付宝的“手机网站支付”参数,如果闪聚支付还聚合了百度、京东等第三方支付渠道,且商户还希望顾客可以用百度、京东的App完成支付,此时商户就需要配置百度、京东所提供的“手机网页支付”参数。

微信JSAPI支付:微信提供的内嵌于微信App内的网页支付,可用于微信公众号支付。

支付宝手机网站支付:支付宝提供的用于手机网页支付方式。

三、总结

下图展示了闪聚支付平台下应用及支付渠道参数的关系:

1、应用是商户创建的业务标识,顾客的每次支付都隶属于某个应用。

2、应用绑定闪聚支付平台提供的服务类型。

3、根据所绑定的服务类型,需要为应用配置支付渠道参数。

1576140106748

1.2 创建应用 ​

创建应用的流程如下 :

image-20191118183416542

  1. 填写应用基本信息

    image-20191218152705635

  2. 点击保存信息

1.3 支付渠道参数配置 ​

下图是支付渠道参数的配置流程 :

image-20191118185748088

1)应用创建成功后,会自动跳转到绑定服务类型页面

image-20191217185758615

2)点击开启服务为应用绑定服务类型

image-20191217185910887

3)开启服务后,点击配置实际支付渠道按钮进入参数配置页面

image-20191217190029197

4)配置参数页面会显示对应服务类型下的原始支付渠道

image-20191217190138405

5)点击配置参数按钮,为指定原始支付渠道配置

image-20191217190551351

6)填写支付宝或微信的支付参数

image-20191217190751177

4 商户应用创建 ​

4.1 需求分析 ​

4.1.1 系统交互流程 ​

商户应用创建交互流程如下:

image-20191126153549493

  1. 前端携带应用信息请求商户平台应用

  2. 请求商户服务保存应用信息

  3. 商户服务校验并保存商户应用

  4. 返回前端创建成功

4.2 应用创建 ​

4.2.1 商户服务创建应用接口(接口①) ​

4.2.1.1 接口定义 ​

1、接口描述

1)校验商户是否通过资质审核

如果商户资质审核没有通过不允许创建应用。

2)生成应用ID

应用Id使用UUID方式生成。

3)保存商户应用信息

应用名称需要校验唯一性。

2、接口定义如下:

应用信息保存至商户数据库的app表,根据表字段定义DTO属性。

定义AppDTO:

@ApiModel(value = "AppDTO", description = "应用信息")
@Data
public class AppDTO implements Serializable {

    @ApiModelProperty("应用id,新增时无需传入")
    private String appId;

    @ApiModelProperty("应用名称")
    private String appName;

    @ApiModelProperty("商户id")
    private Long merchantId;

    @ApiModelProperty("应用公钥")
    private String publicKey;

    @ApiModelProperty("支付回调应用的url,创建时可不填")
    private String notifyUrl;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在AppService下定义createApp接口:

java
/**
  * 商户下创建应用
  * @return
*/
AppDTO createApp(Long merchantId, AppDTO app) throws BusinessException;
1
2
3
4
5

4.2.1.2 接口实现 ​

定义AppCovert负责对象转换

@Mapper
public interface AppCovert {

    AppCovert INSTANCE = Mappers.getMapper(AppCovert.class);

    AppDTO entity2dto(App entity);

    App dto2entity(AppDTO dto);

    List<AppDTO> listentity2dto(List<App> app);

}
1
2
3
4
5
6
7
8
9
10
11
12

在AppServiceImpl实现createApp接口实现:

java
package com.shanjupay.merchant.service;

@org.apache.dubbo.config.annotation.Service
public class AppServiceImpl implements AppService {

	@Autowired
	private AppMapper appMapper;

	@Autowired
	private MerchantMapper merchantMapper;

	@Override
	public AppDTO createApp(Long merchantId, AppDTO app) {
		//校验商户是否通过资质审核
		Merchant merchant = merchantMapper.selectById(merchantId);
		if (merchant == null) {
			throw new BusinessException(CommonErrorCode.E_200002);
		}
		if (!"2".equals(merchant.getAuditStatus())) {
			throw new BusinessException(CommonErrorCode.E_200003);
		}

		if(isExistAppName(app.getAppName())){
			throw new BusinessException(CommonErrorCode.E_200004);
		}

		//保存应用信息
		app.setAppId(RandomUuidUtil.getUUID());
		app.setMerchantId(merchant.getId());
		App entity = AppCovert.INSTANCE.dto2entity(app);
		appMapper.insert(entity);
		return AppCovert.INSTANCE.entity2dto(entity);
	}
	
		/**
	 * 校验应用名是否已被使用
	 * @param appName
	 * @return
	 */
	public Boolean isExistAppName(String appName) {
		Integer count = appMapper.selectCount(new QueryWrapper<App>().lambda().eq(App::getAppName, appName));
		return count.intValue() > 0;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

4.2.2 商户平台应用创建应用接口(接口②) ​

4.2.2.1 接口定义 ​

1、接口描述

1)获取当前登录商户ID

2)请求商户服务保存应用信息

2、接口定义如下:

定义AppController类,并且定义createApp方法:

java
package com.shanjupay.merchant.controller;

@Api(value = "商户平台-应用管理", tags = "商户平台-应用相关", description = "商户平台-应用相关")
@RestController
public class AppController {

	@Reference
	private AppService appService;

	@ApiOperation("商户创建应用")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "app", value = "应用信息", required = true, dataType = "AppDTO", paramType = "body")})
	@PostMapping(value = "/my/apps")
	public AppDTO createApp(@RequestBody AppDTO app) {
		Long merchantId = SecurityUtil.getMerchantId();
		return appService.createApp(merchantId, app);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

4.2.2.2 接口测试 ​

1、准备token

用之前的TokenTemp.java来生成token,注意所指定的商户id必须审核通过。

1577437213904

2、添加应用

1577437231675

4.3 应用查询 ​

4.3.1 商户服务应用查询接口 ​

4.3.1.1 接口定义 ​

1、根据商户ID查询应用

接口定义如下:AppService

java
/**
 * 查询商户下的应用列表
 * @param merchantId
 * @return
 */
List<AppDTO> queryAppByMerchant(Long merchantId) throws BusinessException;
1
2
3
4
5
6

2、根据应用ID查询详细信息

接口定义如下:AppService

java
/**
 * 根据业务id查询应用
 * @param id
 * @return
 */
AppDTO getAppById(String id) throws BusinessException;
1
2
3
4
5
6

4.3.1.2 接口实现 ​

1、AppServiceImpl

java
@Override
public List<AppDTO> queryAppByMerchant(Long merchantId) {
    List<App> apps = appMapper.selectList(new QueryWrapper<App>().lambda().eq(App::getMerchantId,merchantId));
    List<AppDTO> appDTOS = AppCovert.INSTANCE.listentity2dto(apps);
    return appDTOS;
}

@Override
public AppDTO getAppById(String id) {
  	App app = appMapper.selectOne(new QueryWrapper<App>().lambda().eq(App::getAppId, id));
  	return AppCovert.INSTANCE.entity2dto(app);
}
1
2
3
4
5
6
7
8
9
10
11
12

4.3.2 商户平台应用查询接口 ​

4.3.2.1 接口定义 ​

1、请求商户服务查询商户下的所有应用

接口定义如下:MerchantController

java
	@ApiOperation("查询商户下的应用列表")
	@GetMapping(value = "/my/apps")
	public List<AppDTO> queryMyApps() {
		Long merchantId = SecurityUtil.getMerchantId();
		return appService.queryAppByMerchant(merchantId);
	}
1
2
3
4
5
6

2、请求商户服务查询应用详细信息

接口定义如下:AppController

java
	@ApiOperation("根据appid获取应用的详细信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "appId", value = "商户应用id", required = true, dataType = "String", paramType = "path")})
	@GetMapping(value = "/my/apps/{appId}")
	public AppDTO getApp(@PathVariable String appId) {
		return appService.getAppById(appId);
	}
1
2
3
4
5
6
7

4.3.2.2 接口测试 ​

1、获取商户的应用列表

1576220052069

2、根据appId获取应用的详细信息

1576220088818

5 支付渠道参数配置 ​

5.1 需求分析 ​

5.1.1 系统交互流程 ​

商户渠道参数配置交互流程如下:

image-20191126175513687

交易服务职责:提供支付渠道参数配置、订单、发起支付、转账、退款等功能

交互流程如下 :

​ 第一阶段:应用绑定服务类型

  1. 前端请求商户平台应用获取平台支持的所有服务类型列表

  2. 请求交易服务查询列表

  3. 返回服务类型列表给前端

    image-20191217185758615

  4. 前端选择要绑定的服务类型请求商户平台应用

  5. 请求交易服务绑定服务类型

    image-20191217185910887

  6. 返回前端绑定成功

    第二阶段:支付渠道参数配置

  7. 前端请求获取第三方支付渠道列表

    image-20191217190029197

  8. 请求交易服务获取列表

  9. 返回结果给前端

    image-20191217190138405

  10. 前端请求配置支付渠道参数

image-20191217190551351

  1. 商户平台应用请求交易服务保存参数配置

    image-20191217190751177

  2. 返回前端保存成功

5.1.2 基础数据 ​

初始化平台基础数据:

platform_channel: 平台服务类型

pay_channel:第三方支付渠道

platform_pay_channel:平台服务类型对应第三方支付渠道

​ 平台服务类型应根据自身特点对接第三方支付渠道,例如:C扫B服务类型则需要对接微信JSAPI接口和支付宝手机网站支付接口。

1577492577995

sql
use shanjupay_transaction;

LOCK TABLES `platform_channel` WRITE;
/*!40000 ALTER TABLE `platform_channel` DISABLE KEYS */;

INSERT INTO `platform_channel` (`ID`, `CHANNEL_NAME`, `CHANNEL_CODE`)
VALUES
	(1,'闪聚B扫C','shanju_b2c'),
	(2,'闪聚C扫B','shanju_c2b'),
	(3,'微信Native支付','wx_native'),
	(4,'支付宝手机网站支付','alipay_wap');

/*!40000 ALTER TABLE `platform_channel` ENABLE KEYS */;
UNLOCK TABLES;

LOCK TABLES `pay_channel` WRITE;
/*!40000 ALTER TABLE `pay_channel` DISABLE KEYS */;

INSERT INTO `pay_channel` (`ID`, `CHANNEL_NAME`, `CHANNEL_CODE`)
VALUES
	(1,'微信JSAPI','WX_JSAPI'),
	(2,'支付宝手机网站支付','ALIPAY_WAP'),
	(3,'支付宝条码支付','ALIPAY_BAR_CODE'),
	(4,'微信付款码支付','WX_MICROPAY'),
	(5,'微信native支付','WX_NATIVE');

/*!40000 ALTER TABLE `pay_channel` ENABLE KEYS */;
UNLOCK TABLES;

LOCK TABLES `platform_pay_channel` WRITE;
/*!40000 ALTER TABLE `platform_pay_channel` DISABLE KEYS */;

INSERT INTO `platform_pay_channel` (`ID`, `PLATFORM_CHANNEL`, `PAY_CHANNEL`)
VALUES
	(1,'shanju_b2c','WX_MICROPAY'),
	(2,'shanju_b2c','ALIPAY_BAR_CODE'),
	(3,'wx_native','WX_NATIVE'),
	(4,'alipay_wap','ALIPAY_WAP'),
	(5,'shanju_c2b','WX_JSAPI'),
	(6,'shanju_c2b','ALIPAY_WAP');

/*!40000 ALTER TABLE `platform_pay_channel` ENABLE KEYS */;
UNLOCK TABLES;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

5.2 搭建交易服务工程 ​

5.2.1 交易服务介绍 ​

交易服务:提供渠道参数配置、订单、发起支付、转账、退款等功能

工程名职责
交易服务API(shanjupay-transaction-api)定义交易服务提供的接口
交易服务(shanjupay-transaction-service)实现交易服务的接口实现

5.2.2 搭建工程 ​

  1. 复制提供的shanjupay-transaction目录到shanjupay根目录,导入shanjupay-transaction及api和service三个工程。

  2. 添加Module到IDEA中

    image-20191114184240270

  3. 在Nacos中添加transaction-service.yaml配置,Group: SHANJUPAY_GROUP

    yaml
    # 覆盖spring-boot-http.yaml的项目
    server:
      servlet:
        context-path: /transaction
    
    # 覆盖spring-boot-starter-druid.yaml的项目
    spring:
      datasource:
        druid:
         url: jdbc:mysql://127.0.0.1:3306/shanjupay_transaction?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
         username: root
         password: yourpassword
    
    # 覆盖spring-boot-mybatis-plus.yaml的项目
    mybatis-plus:
      typeAliasesPackage: com.shanjupay.transaction.entity
      mapper-locations: classpath:com/shanjupay/*/mapper/*.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    image-20191114184512843

  4. 打开shanjupay-transaction-service工程的bootstrap.yml,将其中的namespace替换为dev命名空间的ID

    1576142658496

  5. 启动TransactionBootstrap测试

    image-20191114184914658

启动成功后观察nacos的服务列表,看transaction-service是否注册服务成功,如果注册成功则说明交易服务启动成功。

5.3 应用绑定服务类型 ​

5.3.1 系统设计 ​

为应用绑定服务类型即指定应用使用哪些服务类型,数据模型设计如下 :

1577493348921

5.3.2 交易服务获取平台服务类型(接口①) ​

绑定服务类型页面,页面中列表出服务类型。

image-20191217185758615

5.3.1.1 接口定义 ​

1、接口描述:查询平台支持的所有服务类型

2、接口定义如下:PayChannelService

java
package com.shanjupay.transaction.api;

/**
 * 支付渠道服务 管理平台支付渠道,原始支付渠道,以及相关配置
 */
public interface PayChannelService {

   /**
    * 获取平台服务类型
    * @return
    */
   List<PlatformChannelDTO> queryPlatformChannel() throws BusinessException;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

5.3.1.2 接口实现 ​

定义PayChannelServiceImpl类及queryPlatformChannel实现方法:

java
package com.shanjupay.transaction.service;

import com.shanjupay.transaction.api.PayChannelService;
import com.shanjupay.transaction.api.dto.PlatformChannelDTO;
import com.shanjupay.transaction.convert.PlatformChannelConvert;
import com.shanjupay.transaction.entity.PlatformChannel;
import com.shanjupay.transaction.mapper.PlatformChannelMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


@org.apache.dubbo.config.annotation.Service
public class PayChannelServiceImpl implements PayChannelService {

    @Autowired
    private PlatformChannelMapper platformChannelMapper;

    @Override
    public List<PlatformChannelDTO> queryPlatformChannel() {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        List<PlatformChannelDTO> platformChannelDTOS = PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);
        return platformChannelDTOS;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

5.3.3 商户平台应用获取平台服务类型(接口②) ​

5.3.3.1 接口定义 ​

在商户平台应用工程添加依赖:

<dependency>
    <groupId>com.shanjupay</groupId>
    <artifactId>shanjupay-transaction-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
1
2
3
4
5

1、接口描述:请求交易服务查询平台支持的所有服务类型

2、接口定义如下:PlatformParamController

java
package com.shanjupay.merchant.controller;

@Api(value = "商户平台-渠道和支付参数相关", tags = "商户平台-渠道和支付参数", description = "商户平台-渠道和支付参数相关")
@Slf4j
@RestController
public class PlatformParamController {

	@Reference
	private PayChannelService payChannelService;

	@ApiOperation("获取平台服务类型")
	@GetMapping(value="/my/platform-channels")
	public List<PlatformChannelDTO> queryPlatformChannel(){
		return payChannelService.queryPlatformChannel();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

5.3.3.2 接口测试 ​

1576225005808

5.3.4 交易服务绑定服务类型接口(接口③) ​

点击开启服务为应用绑定服务类型

image-20191217185910887

5.3.4.1 接口定义 ​

1、接口描述:

1)查询出指定应用就否已绑定选定的服务类型

2)如果该应用没有绑定该 服务类型则进行绑定

2、接口定义如下:

在PayChannelService接口中定义bindPlatformChannelForApp

java
	/**
	 * 为app绑定平台服务类型
	 * @param appId 应用id
	 * @param platformChannelCodes 平台服务类型列表
	 */
	void bindPlatformChannelForApp(String appId, String platformChannelCodes) throws BusinessException;
1
2
3
4
5
6

5.3.4.2 接口实现 ​

定义PayChannelServiceImpl类及bindPlatformChannelForApp实现方法:

java
package com.shanjupay.transaction.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shanjupay.transaction.api.PayChannelService;
import com.shanjupay.transaction.entity.AppPlatformChannel;
import com.shanjupay.transaction.mapper.AppPlatformChannelMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

@Service
public class PayChannelServiceImpl implements PayChannelService {

   @Autowired
   private AppPlatformChannelMapper appPlatformChannelMapper;

	@Override
    @Transactional
    public void bindPlatformChannelForApp(String appId, String platformChannelCodes) throws BusinessException {
        //根据appId和平台服务类型code查询app_platform_channel
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>()
                .eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannelCodes));
        //如果没有绑定则绑定
        if(appPlatformChannel ==null){
            appPlatformChannel = new AppPlatformChannel();
            appPlatformChannel.setAppId(appId);
            appPlatformChannel.setPlatformChannel(platformChannelCodes);
            appPlatformChannelMapper.insert(appPlatformChannel);
        }


    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

5.3.5 商户平台应用绑定服务类型接口(接口④) ​

5.3.5.1 接口定义 ​

1、接口描述:请求交易服务为指定应用添加服务类型

2、接口定义如下:

在AppController类中定义bindPlatformForApp方法:

java
	@Reference
	private PayChannelService payChannelService;

	
	@ApiOperation("绑定服务类型")
    @PostMapping(value="/my/apps/{appId}/platform-channels")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "应用id",name = "appId",dataType = "string",paramType = "path"),
            @ApiImplicitParam(value = "服务类型code",name = "platformChannelCodes",dataType = "string",paramType = "query")
    })
    public void bindPlatformForApp(@PathVariable("appId") String appId, @RequestParam("platformChannelCodes") String platformChannelCodes){
        payChannelService.bindPlatformChannelForApp(appId,platformChannelCodes);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

5.3.5.2 接口测试 ​

1577450704088

5.3.6 交易服务查询服务类型绑定状态 ​

5.3.6.1 接口定义 ​

1、接口描述

1)查询应用是否已经绑定了某个服务类型

2、接口定义如下

1)PayChannelService

java
 /**
     * 应用是否已经绑定了某个服务类型
     * @param appId
     * @param platformChannel
     * @return 已绑定返回1,否则 返回0
     */
    int queryAppBindPlatformChannel(String appId,String platformChannel) throws BusinessException;
1
2
3
4
5
6
7
8

5.5.5.2 接口实现 ​

在PayChannelServiceImpl中实现queryAppBindPlatformChannel方法:

java
@Override
public int queryAppBindPlatformChannel(String appId, String platformChannel) {
   int count = appPlatformChannelMapper.selectCount(
         new QueryWrapper<AppPlatformChannel>().lambda().eq(AppPlatformChannel::getAppId, appId)
               .eq(AppPlatformChannel::getPlatformChannel, platformChannel));
   //已存在绑定关系返回1
   if (count > 0) {
      return 1;
   } else {
      return 0;
   }
}
1
2
3
4
5
6
7
8
9
10
11
12

5.3.7 商户平台查询服务类型绑定状态 ​

5.3.7.1 接口实现 ​

接口描述

查询应用是否已经绑定了某个服务类型

在AppController中定义:

java
@ApiOperation("查询应用是否绑定了某个服务类型")
@ApiImplicitParams({
      @ApiImplicitParam(name = "appId", value = "应用appId", required = true, dataType = "String", paramType = "query"),
      @ApiImplicitParam(name = "platformChannel", value = "服务类型", required = true, dataType = "String", paramType = "query")
})
@GetMapping("/my/merchants/apps/platformchannels")
public int queryAppBindPlatformChannel(@RequestParam String appId, @RequestParam String platformChannel){
   return payChannelService.queryAppBindPlatformChannel(appId,platformChannel);
}
1
2
3
4
5
6
7
8
9

​

5.4 支付渠道参数配置 ​

5.4.1 系统设计 ​

支付渠道参数配置数据模型如下:

1577494095950

支付渠道参数数据存储至支付渠道参数表(pay_channel_param)

1577491097941

APP_PLATFORM_CHANNEL_ID:为app_platform_channel表的主键即应用绑定服务类型表的主键,应用加服务类型表示一个APP_PLATFORM_CHANNEL_ID。

APP_PLATFORM_CHANNEL_ID和PAY_CHANNEL唯一约束:即应用、服务类型、第三方支付渠道唯一约束,表示为某应用所绑定的某服务类型的某支付渠道配置参数

例如:

应用app01,服务类型为shanju_c2b,两者在app_platform_channel表示app01应用绑定了shanju_c2b服务类型。

又由于shanju_c2b服务类型对应WX_JSAPI支付渠道,所以在支付渠道参数表pay_channel_param中为应用app01所绑定的服务类型为shanju_c2b配置WX_JSAPI支付渠道参数。

5.4.2 交易服务原始支付渠道查询接口(接口⑤) ​

配置参数页面会显示对应服务类型下的原始支付渠道

image-20191217190138405

5.4.2.1 接口定义 ​

这里是要查询某服务类型下的支付渠道,以便下一步为某支付渠道配置参数。

可从服务类型与支付渠道对应关系表关联查询:

1577492577995

1、接口描述:根据平台服务类型获取支付渠道列表

2、接口定义如下:

在PayChannelService接口中定义queryPayChannelByPlatformChannel:

java
    /**
     * 根据平台服务类型获取支付渠道列表
     * @param platformChannelCode
     * @return
     */
    List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) throws BusinessException;
1
2
3
4
5
6

5.4.2.2 接口实现 ​

1、在PlatformChannelMapper中定义selectPayChannelByPlatformChannel方法:

java
/**
 * 根据平台服务类型获取原始支付渠道
 * @param platformChannelCode
 * @return 
 */
    @Select("SELECT " +
            "  pay.* " +
            "FROM" +
            "  pay_channel pay," +
            "  platform_pay_channel pac," +
            "  platform_channel pla " +
            "WHERE pay.CHANNEL_CODE = pac.PAY_CHANNEL " +
            "  AND pla.CHANNEL_CODE = pac.PLATFORM_CHANNEL " +
            "  AND pla.CHANNEL_CODE = #{platformChannelCode} ")
    public List<PayChannelDTO> selectPayChannelByPlatformChannel(String platformChannelCode) ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

2、在PayChannelServiceImpl类定义queryPayChannelByPlatformChannel实现方法:

java
	@Override
	public List<PayChannelDTO> queryPayChannelByPlatformChannel(String platformChannelCode) {
		return platformChannelMapper.selectPayChannelByPlatformChannel(platformChannelCode);
	}
1
2
3
4

5.4.2.3 接口测试 ​

在交易 服务进行单元 测试,编写单元 测试类

package com.shanjupay.transaction;

import com.shanjupay.transaction.api.PayChannelService;
import com.shanjupay.transaction.api.dto.PayChannelDTO;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @author Administrator
 * @version 1.0
 **/
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class TestPayChannelService {

    @Autowired
    PayChannelService payChannelService;

    //测试根据服务类型查询支付渠道
    @Test
    public void testqueryPayChannelByPlatformChannel(){
        List<PayChannelDTO> shanju_c2b = payChannelService.queryPayChannelByPlatformChannel("shanju_c2b");
        System.out.println(shanju_c2b);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

5.4.3 商户平台应用支付渠道查询接口(接口⑥) ​

5.4.3.1 接口定义 ​

1、接口描述:根据服务类型查询支付渠道列表

2、接口定义如下:

在PlatformParamController类中定义queryPayChannelByPlatformChannel:

java
	@ApiOperation("根据平台服务类型获取支付渠道列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "platformChannelCode", value = "服务类型编码", required = true, dataType = "String", paramType = "path")
	})
	@GetMapping(value="/my/pay-channels/platform-channel/{platformChannelCode}")
	public List<PayChannelDTO> queryPayChannelByPlatformChannel(@PathVariable String platformChannelCode){
		return payChannelService.queryPayChannelByPlatformChannel(platformChannelCode);
	}
1
2
3
4
5
6
7
8

5.4.3.2 接口测试 ​

使用Postman:http://localhost:57010/merchant/my/pay-channels/platform-channel/shanju_c2b

返回值:

json
[
    {
        "id": 1,
        "channelName": "微信JSAPI",
        "channelCode": "WX_JSAPI"
    },
    {
        "id": 2,
        "channelName": "支付宝手机网站支付",
        "channelCode": "ALIPAY_WAP"
    }
]
1
2
3
4
5
6
7
8
9
10
11
12

5.4.4 交易服务支付渠道参数配置接口(接口⑦) ​

为指定原始支付渠道配置

image-20191217190551351

5.4.4.1 接口定义 ​

本接口是为应用配置支付渠道参数,前边为应用绑定了服务类型,此接口即为应用所绑定的服务类型配置支付渠道参数。

1、接口描述:保存支付渠道参数

2、接口定义如下:

在PayChannelService中定义createPayChannelParam方法:

java
/**
 *  保存支付渠道参数
 * @param payChannelParam 商户原始支付渠道参数
 */
void savePayChannelParam(PayChannelParamDTO payChannelParam) throws BusinessException;
1
2
3
4
5

5.4.4.2 接口实现 ​

服务层提供一个接口实现支付渠道参数配置,如果该应用的服务类型已经配置某支付渠道参数则执行更新操作,否执行添加操作。

例如:

在PayChannelServiceImpl类中定义savePayChannelParam实现方法:

java
	@Autowired
	private PayChannelParamMapper payChannelParamMapper;
	
 /**
     * 保存支付渠道参数
     * @param payChannelParamDTO 支付渠道参数
     * @throws BusinessException
     */
    @Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {
        if(payChannelParamDTO == null || StringUtils.isBlank(payChannelParamDTO.getAppId())
                                        || StringUtils.isBlank(payChannelParamDTO.getPlatformChannelCode())
                                        || StringUtils.isBlank(payChannelParamDTO.getPayChannel())){
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //根据appid和服务类型查询应用与服务类型绑定id
        Long appPlatformChannelId = selectIdByAppPlatformChannel(payChannelParamDTO.getAppId(), payChannelParamDTO.getPlatformChannelCode());
        if(appPlatformChannelId == null){
            //应用未绑定该服务类型不可进行支付渠道参数配置
            throw new BusinessException(CommonErrorCode.E_300010);
        }
        //根据应用与服务类型绑定id和支付渠道查询参数信息
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId)
                .eq(PayChannelParam::getPayChannel, payChannelParamDTO.getPayChannel()));

        //更新已有配置
        if (payChannelParam!=null){
            payChannelParam.setChannelName(payChannelParamDTO.getChannelName());
            payChannelParam.setParam(payChannelParamDTO.getParam());
            payChannelParamMapper.updateById(payChannelParam);
        }else{
            //添加新配置
            PayChannelParam entity = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
             entity.setId(null);
            //应用与服务类型绑定id
            entity.setAppPlatformChannelId(appPlatformChannelId);
            payChannelParamMapper.insert(entity);
        }
    }

/**
     * 根据appid和服务类型查询应用与服务类型绑定id
     * @param appId
     * @param platformChannelCode
     * @return
     */
    private Long selectIdByAppPlatformChannel(String appId,String platformChannelCode){
        //根据appid和服务类型查询应用与服务类型绑定id
        AppPlatformChannel appPlatformChannel = appPlatformChannelMapper.selectOne(new LambdaQueryWrapper<AppPlatformChannel>().eq(AppPlatformChannel::getAppId, appId)
                .eq(AppPlatformChannel::getPlatformChannel, platformChannelCode));
        if(appPlatformChannel!=null){
            return appPlatformChannel.getId();
        }
        return null;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

5.4.5 商户平台应用支付渠道参数配置接口(接口⑧) ​

5.4.5.1 接口定义 ​

1、接口描述:请求交易服务保存支付渠道参数配置

2、接口定义如下:

前端提供两个接口:新增和更新

在PlatformParamController类中下定义createPayChannelParam

java
    @ApiOperation("商户配置支付渠道参数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "payChannelParam", value = "商户配置支付渠道参数", required = true, dataType = "PayChannelParamDTO", paramType = "body")
    })
    @RequestMapping(value = "/my/pay-channel-params",method = {RequestMethod.POST,RequestMethod.PUT})
    public void createPayChannelParam(@RequestBody PayChannelParamDTO payChannelParam){
        Long merchantId = SecurityUtil.getMerchantId();
        payChannelParam.setMerchantId(merchantId);
        payChannelService.savePayChannelParam(payChannelParam);
    }
1
2
3
4
5
6
7
8
9
10

5.4.5.2 接口测试 ​

微信:

  1. 微信C扫B渠道参数配置,其中请求参数param和payChannel使用下面的配置

    json
    {
    	"appID": "wxd2bf2dba2e86a8c7",
    	"appSecret": "cec1a9185ad435abe1bced4b93f7ef2e",
    	"key": "95fe355daca50f1ae82f0865c2ce87c8",
    	"mchID": "1502570431",
    	"payKey": "95fe355daca50f1ae82f0865c2ce87c8",
    }
    "payChannel": "WX_JSAPI"
    1
    2
    3
    4
    5
    6
    7
    8

    支付宝:

  2. 申请支付宝开放平台账号,并获取支付宝渠道参数信息

    详见"支付宝开放平台使用指南.pdf"

  3. 支付宝C扫B渠道参数配置,将其中的appId、rsaPrivateKey、alipayPublicKey、notifyUrl、returnUrl替换为自己的配置。

    json
    {
    	"appId": "2016101000652290",
    	"rsaPrivateKey": "MIIEvQIBADANBgkqhkiG9w0...",
      "alipayPublicKey": "MIIBIjANBgkqhkiG9w0BAQ...",
    	"notifyUrl": "http://127.0.0.1:56010/payment-receiver/alipay-notify",
    	"returnUrl": "http://127.0.0.1:56010/payment-receiver/alipay-return",
      
    	"url": "https://openapi.alipaydev.com/gateway.do",
    	"charest": "UTF-8",
    	"format": "json",
    	"log_path": "/log",
    	"signtype": "RSA2"
    }
    
    "payChannel": "ALIPAY_WAP"
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

1577498332045

上图中,param为json串,需要使用EditPlus软件将json串合并为一行,并且用idea工具将字符串双引号转义。

1576236331716

然后替换掉制表符。

最后使用idea将双引号转义,如下:

"{ \"appID\": \"wxd2bf2dba2e86a8c7\", \"appSecret\": \"cec1a9185ad435abe1bced4b93f7ef2e\", \"key\": \"95fe355daca50f1ae82f0865c2ce87c8\", \"mchID\": \"1502570431\", \"payKey\": \"95fe355daca50f1ae82f0865c2ce87c8\" }"
1

5.5 支付渠道参数查询 ​

5.5.1 交易服务渠道参数查询接口 ​

5.5.1.1 接口定义1 ​

1、接口描述

1)根据应用和服务类型获取原始支付参数param,结果可能是多个(支付宝param 微信param)

2、接口定义如下:

在PayChannelService接口中定义queryPayChannelParamByAppAndPlatform方法:

java
	/**
	 *  获取指定应用指定服务类型下所包含的原始支付渠道参数列表
	 * @param appId 应用id
	 * @param platformChannel 服务类型
	 * @return
	 */
	List<PayChannelParamDTO> queryPayChannelParamByAppAndPlatform(String appId, String platformChannel)
			throws BusinessException;
1
2
3
4
5
6
7
8

5.5.1.2 接口定义2 ​

1、接口描述

1)根据应用、服务类型及支付渠道获取原始支付参数param,结果只能是一个

2、接口定义如下:

在PayChannelService接口中定义queryParamByAppPlatformAndPayChannel方法:

java

/**
 * 获取指定应用指定服务类型下所包含的某个原始支付参数
 * @param appId
 * @param platformChannel
 * @param payChannel
 * @return
 * @throws BusinessException
 */
PayChannelParamDTO queryParamByAppPlatformAndPayChannel(String appId, String platformChannel,
      String payChannel) throws BusinessException;
1
2
3
4
5
6
7
8
9
10
11

5.5.1.2 接口实现 ​

在PayChannelServiceImpl中实现queryPayChannelParamByAppAndPlatform:

java

/**
     * 查询支付渠道参数
     *
     * @param appId           应用id
     * @param platformChannel 服务类型代码
     * @return
     */
    @Override
    public List<PayChannelParamDTO> queryPayChannelParamByAppAndPlatform(String appId, String platformChannel) {
        //查出应用id和服务类型代码在app_platform_channel主键
        Long appPlatformChannelId = selectIdByAppPlatformChannel(appId,platformChannel);
        //根据appPlatformChannelId从pay_channel_param查询所有支付参数
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
        return PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

在PayChannelServiceImpl中实现queryParamByAppPlatformAndPayChannel:

@Override
public PayChannelParamDTO queryParamByAppPlatformAndPayChannel(String appId, String platformChannel,
                                                               String payChannel) throws BusinessException {
    List<PayChannelParamDTO> payChannelParamDTOS = queryPayChannelParamByAppAndPlatform(appId, platformChannel);
    for(PayChannelParamDTO payChannelParam:payChannelParamDTOS){
        if(payChannelParam.getPayChannel().equals(payChannel)){
            return payChannelParam;
        }
    }
    return null;
}
1
2
3
4
5
6
7
8
9
10
11

5.5.2 商户平台应用渠道参数查询接口 ​

5.5.2.1 接口定义1 ​

1、接口描述:根据应用和服务类型获取原始支付参数列表

2、接口定义如下:

在PlatformParamController中定义queryPayChannelParam

java
	@ApiOperation("获取指定应用指定服务类型下所包含的原始支付渠道参数列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "appId", value = "应用id", required = true, dataType = "String", paramType = "path"),
			@ApiImplicitParam(name = "platformChannel", value = "服务类型", required = true, dataType = "String", paramType = "path")})
	@GetMapping(value = "/my/pay-channel-params/apps/{appId}/platform-channels/{platformChannel}")
	public List<PayChannelParamDTO> queryPayChannelParam(@PathVariable String appId,
			@PathVariable String platformChannel) {
		return payChannelService.queryPayChannelParamByAppAndPlatform(appId, platformChannel);
	}
1
2
3
4
5
6
7
8
9

5.5.2.1 接口定义2 ​

1、接口描述:根据应用、服务类型及支付渠道获取原始支付参数

2、接口定义如下:

在PlatformParamController中定义queryPayChannelParam

java
@ApiOperation("获取指定应用指定服务类型下所包含的某个原始支付参数")
@ApiImplicitParams({
      @ApiImplicitParam(name = "appId", value = "应用id", required = true, dataType = "String", paramType = "path"),
      @ApiImplicitParam(name = "platformChannel", value = "平台支付渠道编码", required = true, dataType = "String", paramType = "path"),
      @ApiImplicitParam(name = "payChannel", value = "实际支付渠道编码", required = true, dataType = "String", paramType = "path")})
@GetMapping(value = "/my/pay-channel-params/apps/{appId}/platform-channels/{platformChannel}/pay-channels/{payChannel}")
public PayChannelParamDTO queryPayChannelParam(@PathVariable String appId,
      @PathVariable String platformChannel, @PathVariable String payChannel) {
   return payChannelService.queryParamByAppPlatformAndPayChannel(appId, platformChannel, payChannel);
}
1
2
3
4
5
6
7
8
9
10

5.5.2.2 接口测试 ​

postman:get:http://localhost:57010/merchant/my/pay-channel-params/apps/{appId}/platform-channels/{platformChannel}

5.6 支付渠道参数缓存 ​

5.6.1 需求分析 ​

渠道参数查询频繁,每一次支付都会查询渠道参数,为提供查询性能这里我们将渠道参数缓存到redis中,缓存流程如下:

1、保存渠道参数添加缓存

保存渠道参数成功,同时将渠道参数保存在Redis中。

2、查询渠道参数缓存

查询渠道参数,先从Redis查询,如果Redis存在则返回渠道参数,否则从数据库查询同时将查询到的渠道参数存储在Redis中。

5.6.2 搭建redis环境 ​

1、安装redis

参考 资料下的“Redis安装指南.pdf”。

2、在Nacos中添加Redis配置:spring-boot-redis.yaml,Group:COMMON_GROUP

yaml
spring:
  redis:
    # Redis数据库索引(默认为0)
    database: 0
    host: 127.0.0.1
    port: 6379
    # 连接超时时间(毫秒)
    timeout: 1000ms
    password: 123456
    lettuce:
      pool:
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 1000ms
      shutdown-timeout: 1000ms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在shanjupay-transaction-service工程的bootstrap.yml中引入Redis配置

yaml
          -
            refresh: true
            data-id: spring-boot-redis.yaml # redis配置
            group: COMMON_GROUP # 通用配置组
1
2
3
4

3、添加Redis的pom依赖,shanjupay-transaction-service工程的pom.xml:

xml
     <!-- Redis启动器 -->
	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
1
2
3
4
5

4、复制RedisEnum, RedisUtil到shanjupay-common工程

5、复制RedisCache到shanjupay-transaction-service工程的com.shanjupay.transaction.common.util包下

5、添加Redis配置文件,包:com.shanjupay.transaction.config

java
package com.shanjupay.transaction.config;


import com.shanjupay.common.cache.Cache;
import com.shanjupay.transaction.common.util.RedisCache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * redis 的配置类
 *
 */
@Configuration
public class RedisConfig {

   @Bean
   public Cache cache(StringRedisTemplate redisTemplate){
      return new RedisCache(redisTemplate);
   }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

5.6.3 保存缓存 ​

保存渠道参数成功,同时将渠道参数保存在Redis中。

修改交易服务保存支付渠道参数接口,修改PayChannelServiceImpl中的savePayChannelParam方法:

@Resource
private Cache cache;

@Override
    public void savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BusinessException {
    ...
    
    //更新缓存
        updateCache(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode());
}
 private void updateCache(String appId, String platformChannel) {
        //处理redis缓存
        //1.key的构建  如:SJ_PAY_PARAM:b910da455bc84514b324656e1088320b:shanju_c2b
        String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
        //2.查询redis,检查key是否存在
        Boolean exists = cache.exists(redisKey);
        if (exists) {//存在,则清除
            //删除原有缓存
            cache.del(redisKey);
        }
        //3.从数据库查询应用的服务类型对应的实际支付参数,并重新存入缓存
        List<PayChannelParamDTO> paramDTOS = queryPayChannelParamByAppAndPlatform(appId,platformChannel);
        if (paramDTOS != null) {
            //存入缓存
            cache.set(redisKey, JSON.toJSON(paramDTOS).toString());
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

5.6.4 查询缓存 ​

查询渠道参数,先从Redis查询,如果Redis存在则返回渠道参数,否则从数据库查询同时将查询到的渠道参数存储在Redis中。

修改PayChannelServiceImpl中的queryPayChannelParamByAppAndPlatform方法:

/**
 * 查询支付渠道参数
 *
 * @param appId           应用id
 * @param platformChannel 服务类型代码
 * @return
 */
@Override
public List<PayChannelParamDTO> queryPayChannelParamByAppAndPlatform(String appId, String platformChannel) {
    //从缓存查询
    //1.key的构建  如:SJ_PAY_PARAM:b910da455bc84514b324656e1088320b:shanju_c2b
    String redisKey = RedisUtil.keyBuilder(appId, platformChannel);
    //是否有缓存
    Boolean exists = cache.exists(redisKey);
    if(exists){
        //从redis获取key对应的value
        String value = cache.get(redisKey);
        //将value转成对象
        List<PayChannelParamDTO> paramDTOS = JSONObject.parseArray(value, PayChannelParamDTO.class);
        return paramDTOS;
    }
    //查出应用id和服务类型代码在app_platform_channel主键
    Long appPlatformChannelId = selectIdByAppPlatformChannel(appId,platformChannel);
    //根据appPlatformChannelId从pay_channel_param查询所有支付参数
    List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(new LambdaQueryWrapper<PayChannelParam>().eq(PayChannelParam::getAppPlatformChannelId, appPlatformChannelId));
    List<PayChannelParamDTO> paramDTOS = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
    //存入缓存
    updateCache(appId,platformChannel;
    return paramDTOS;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
← 验证码服务使用指南第二章对接SaaS →








如果发现文档内容有错误或排版错乱,请及时联系站长老苗修改,不胜感激。联系方式
关于我们 | 隐私政策 | 豫ICP备2026003386号-4 | 豫公网安备41010202004008号
目录

本页无章节