1、数据库
hfb.sql
2、程序
hfb
3、数据库配置
application-dev.yml 中修改数据库配置
4、启动程序
端口:9999
1、传入参数
参考《汇付宝商户账户技术文档》业务接口3.1参数说明
2、返回结果
参考《汇付宝商户账户技术文档》业务接口3.2返回/通知结果
3、数据接口
参考《汇付宝商户账户技术文档》业务接口3.3账户绑定
尚融宝应该在网站引导客户在“资金托管平台“开设账户。也就是说投资人和借款人必须在资金托管平台页面上自主开户,与尚融宝建立对应的账户体系。
以后所有的资金操作都会到“资金托管平台”进行,绑定账户流程如图:
guigu-common中引入HttpUtils工具类
这个工具类使用了另一个常见的远程连接工具:java.net.HttpURLConnection
service-base中添加依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
service-core中添加FormHelper:构建表单工具
service-core中添加HfbConst:常量定义
service-core中添加RequestHelper:签名工具
service-core中添加
package com.atguigu.srb.core.pojo.vo;
@Data
@ApiModel(description = "账户绑定")
public class UserBindVO {
@ApiModelProperty(value = "身份证号")
private String idCard;
@ApiModelProperty(value = "用户姓名")
private String name;
@ApiModelProperty(value = "银行类型")
private String bankType;
@ApiModelProperty(value = "银行卡号")
private String bankNo;
@ApiModelProperty(value = "手机号")
private String mobile;
}
service-core中创建包enums,创建枚举UserBindEnum
package com.atguigu.srb.core.enums;
@AllArgsConstructor
@Getter
public enum UserBindEnum {
NO_BIND(0, "未绑定"),
BIND_OK(1, "绑定成功"),
BIND_FAIL(-1, "绑定失败"),
;
private Integer status;
private String msg;
}
完整的枚举源代码:资料中 java代码\service-core\enums目录
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head> head>
<body>
<form name="form" action="远程地址" method="post">
<input type="text" name="mobile" value="13900000000" />
<input type="text" name="sign" value="123456" />
form>
<script>
document.form.submit()
script>
body>
html>
UserBindController
package com.atguigu.srb.core.controller.api;
@Api(tags = "会员账号绑定")
@RestController
@RequestMapping("/api/core/userBind")
@Slf4j
public class UserBindController {
@Resource
private UserBindService userBindService;
@ApiOperation("账户绑定提交数据")
@PostMapping("/auth/bind")
public R bind(@RequestBody UserBindVO userBindVO, HttpServletRequest request) {
String token = request.getHeader("token");
Long userId = JwtUtils.getUserId(token);
String formStr = userBindService.commitBindUser(userBindVO, userId);
return R.ok().data("formStr", formStr);
}
}
接口:UserBindService
/**
* 账户绑定提交到托管平台的数据
*/
String commitBindUser(UserBindVO userBindVO, Long userId);
相关常量:HfbConst
/**
* 用户绑定
*/
//用户绑定汇付宝平台url地址
public static final String USERBIND_URL = "http://localhost:9999/userBind/BindAgreeUserV2";
//用户绑定异步回调
public static final String USERBIND_NOTIFY_URL = "http://localhost/api/core/userBind/notify";
//用户绑定同步回调
public static final String USERBIND_RETURN_URL = "http://localhost:3000/user";
实现:UserBindServiceImpl
@Override
public String commitBindUser(UserBindVO userBindVO, Long userId) {
//查询身份证号码是否绑定
QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper
.eq("id_card", userBindVO.getIdCard())
.ne("user_id", userId);
UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
//USER_BIND_IDCARD_EXIST_ERROR(-301, "身份证号码已绑定"),
Assert.isNull(userBind, ResponseEnum.USER_BIND_IDCARD_EXIST_ERROR);
//查询用户绑定信息
userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper.eq("user_id", userId);
userBind = baseMapper.selectOne(userBindQueryWrapper);
//判断是否有绑定记录
if(userBind == null) {
//如果未创建绑定记录,则创建一条记录
userBind = new UserBind();
BeanUtils.copyProperties(userBindVO, userBind);
userBind.setUserId(userId);
userBind.setStatus(UserBindEnum.NO_BIND.getStatus());
baseMapper.insert(userBind);
} else {
//曾经跳转到托管平台,但是未操作完成,此时将用户最新填写的数据同步到userBind对象
BeanUtils.copyProperties(userBindVO, userBind);
baseMapper.updateById(userBind);
}
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("agentId", HfbConst.AGENT_ID);
paramMap.put("agentUserId", userId);
paramMap.put("idCard",userBindVO.getIdCard());
paramMap.put("personalName", userBindVO.getName());
paramMap.put("bankType", userBindVO.getBankType());
paramMap.put("bankNo", userBindVO.getBankNo());
paramMap.put("mobile", userBindVO.getMobile());
paramMap.put("returnUrl", HfbConst.USERBIND_RETURN_URL);
paramMap.put("notifyUrl", HfbConst.USERBIND_NOTIFY_URL);
paramMap.put("timestamp", RequestHelper.getTimestamp());
paramMap.put("sign", RequestHelper.getSign(paramMap));
//构建充值自动提交表单
String formStr = FormHelper.buildForm(HfbConst.USERBIND_URL, paramMap);
return formStr;
}
pages/user/bind.vue
commitBind() {
this.$alert(
'您即将前往汇付宝绑定账号',
'前往汇付宝资金托管平台',
{
dangerouslyUseHTMLString: true,
confirmButtonText: '立即前往',
callback: (action) => {
if (action === 'confirm') {
this.$axios
.$post('/api/core/userBind/auth/bind', this.userBind)
.then((response) => {
document.write(response.data.formStr)
})
}
},
}
)
},
1、登录
使用借款人账号登录
2、测试
访问 http://127.0.0.1:3000/user/bind
3、结果
尚融宝数据库中创建了user_bind记录
汇付宝数据库中创建了user_bind 和 user_account两条数据记录
step1:用户在个人中心点击 “立即开通” (http://localhost:3000/user/bind)
step2:尚融宝展示账户绑定页面
step3:用户填写基本信息(注意:身份证必须是尚未开户),点击“开户”按钮
step4:尚融宝后台创建用户绑定信息(新建user_bind记录)
step5:跳转到汇付宝页面(资金托管接口调用)
step6:汇付宝验证用户身份、用户设置交易密码
step7:汇付宝创建绑定账号(新建user_bind和user_account记录)
step8:异步回调:
尚融宝user_bind表更新bind_code字段、status字段
尚融宝user_info表更新 bind_code字段、name字段、idCard字段、bind_status字段
step9:用户点击“返回平台”,返回尚融宝
UserBindController中创建回调方法
@ApiOperation("账户绑定异步回调")
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
Map<String, Object> paramMap = RequestHelper.switchMap(request.getParameterMap());
log.info("用户账号绑定异步回调:" + JSON.toJSONString(paramMap));
//校验签名
if(!RequestHelper.isSignEquals(paramMap)) {
log.error("用户账号绑定异步回调签名错误:" + JSON.toJSONString(paramMap));
return "fail";
}
//修改绑定状态
userBindService.notify(paramMap);
return "success";
}
接口:UserBindService
void notify(Map<String, Object> paramMap);
实现:UserBindServiceImpl
@Resource
private UserInfoMapper userInfoMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void notify(Map<String, Object> paramMap) {
// 校验是否绑定成功
String resultCode = (String) paramMap.get("resultCode");
if (!"0001".equals(resultCode)) {
throw new BusinessException("用户绑定失败");
}
String bindCode = (String)paramMap.get("bindCode");
//会员id
String agentUserId = (String)paramMap.get("agentUserId");
//根据user_id查询user_bind记录
QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper.eq("user_id", agentUserId);
//更新用户绑定表
UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
userBind.setBindCode(bindCode);
userBind.setStatus(UserBindEnum.BIND_OK.getStatus());
baseMapper.updateById(userBind);
//更新用户表
UserInfo userInfo = userInfoMapper.selectById(agentUserId);
userInfo.setBindCode(bindCode);
userInfo.setName(userBind.getName());
userInfo.setIdCard(userBind.getIdCard());
userInfo.setBindStatus(UserBindEnum.BIND_OK.getStatus());
userInfoMapper.updateById(userInfo);
}
本文章参考B站 尚硅谷《尚融宝》Java微服务分布式金融项目,仅供个人学习使用,部分内容为本人自己见解,与尚硅谷无关。