26. 尚融宝账户绑定

编程入门 行业动态 更新时间:2024-10-24 07:34:06

26. 尚融宝账户<a href=https://www.elefans.com/category/jswz/34/1769902.html style=绑定"/>

26. 尚融宝账户绑定

准备工作

一、运行汇付宝

1、数据库

hfb.sql

2、程序

hfb

3、数据库配置

application-dev.yml 中修改数据库配置

4、启动程序

端口:9999

二、参考文档

1、传入参数

参考《汇付宝商户账户技术文档》业务接口3.1参数说明

2、返回结果

参考《汇付宝商户账户技术文档》业务接口3.2返回/通知结果

3、数据接口

参考《汇付宝商户账户技术文档》业务接口3.3账户绑定

账户创建

需求

step1:用户在个人中心点击 “立即开通” http://localhost:3000/user/bind

step2:尚融宝展示账户绑定页面

step3:用户填写基本信息(注意:身份证必须是尚未开户),点击“开户”按钮

step4:尚融宝后台创建用户绑定信息(新建user_bind记录)

step5:跳转到汇付宝页面(资金托管接口调用)

后端准备工作

1、indi-common

util包引入HttpUtils.java工具类

这个工具类使用了另一个常见的远程连接工具:java.HttpURLConnection

package com.indimon.util;import lombok.extern.slf4j.Slf4j;import java.io.*;
import java.HttpURLConnection;
import java.URL;/****/
@Slf4j
public final class HttpUtils {static final String POST = "POST";static final String GET = "GET";static final int CONN_TIMEOUT = 30000;// msstatic final int READ_TIMEOUT = 30000;// ms/*** post 方式发送http请求.* * @param strUrl* @param reqData* @return*/public static byte[] doPost(String strUrl, byte[] reqData) {return send(strUrl, POST, reqData);}/*** get方式发送http请求.* * @param strUrl* @return*/public static byte[] doGet(String strUrl) {return send(strUrl, GET, null);}/*** @param strUrl* @param reqmethod* @param reqData* @return*/public static byte[] send(String strUrl, String reqmethod, byte[] reqData) {try {URL url = new URL(strUrl);HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();httpcon.setDoOutput(true);httpcon.setDoInput(true);httpcon.setUseCaches(false);httpcon.setInstanceFollowRedirects(true);httpcon.setConnectTimeout(CONN_TIMEOUT);httpcon.setReadTimeout(READ_TIMEOUT);httpcon.setRequestMethod(reqmethod);httpcon.connect();if (reqmethod.equalsIgnoreCase(POST)) {OutputStream os = httpcon.getOutputStream();os.write(reqData);os.flush();os.close();}BufferedReader in = new BufferedReader(new InputStreamReader(httpcon.getInputStream(),"utf-8"));String inputLine;StringBuilder bankXmlBuffer = new StringBuilder();while ((inputLine = in.readLine()) != null) {  bankXmlBuffer.append(inputLine);  }  in.close();  httpcon.disconnect();return bankXmlBuffer.toString().getBytes();} catch (Exception ex) {log.error(ex.toString(), ex);return null;}}/*** 从输入流中读取数据* * @param inStream* @return* @throws Exception*/public static byte[] readInputStream(InputStream inStream) throws Exception {ByteArrayOutputStream outStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = inStream.read(buffer)) != -1) {outStream.write(buffer, 0, len);}byte[] data = outStream.toByteArray();// 网页的二进制数据outStream.close();inStream.close();return data;}
}

2、service-base

添加依赖

    <!-- json解析 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency>

3、service-core

创建hfb包,添加辅助类

FormHelper:构建表单工具

package com.indi.srb.core.hfb;import java.util.Iterator;
import java.util.Map;public class FormHelper {/*** 构建自动提交form表单* @param url 表单提交的url* @param paramMap 表单的提交项* @return*/public static String buildForm(String url, Map<String, Object> paramMap) {StringBuffer inputStr = new StringBuffer();Iterator<Map.Entry<String, Object>> entries = paramMap.entrySet().iterator();while(entries.hasNext()){Map.Entry<String, Object> entry = entries.next();String key = entry.getKey();Object value = entry.getValue();inputStr.append("<input type='hidden' name='"+key+"' value='"+value+"'/>");}String formStr = "<!DOCTYPE html>\n" +"<html lang=\"en\" xmlns:th=\"\">\n" +"<head>\n" +"</head>\n" +"<body>\n" +"<form name=\"form\" action=\""+url+"\" method=\"post\">\n"+inputStr +"</form>\n" +"<script>\n" +"\tdocument.form.submit();\n" +"</script>\n" +"</body>\n" +"</html>";return formStr;}}

HfbConst:常量定义

package com.indi.srb.core.hfb;/*** 汇付宝常量定义*/
public class HfbConst {//给商户分配的唯一标识public static final String AGENT_ID = "999888";//签名keypublic static final String SIGN_KEY = "9876543210";/*** 用户绑定*///用户绑定汇付宝平台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";/*** 充值*///充值汇付宝平台url地址public static final String RECHARGE_URL = "http://localhost:9999/userAccount/AgreeBankCharge";//充值异步回调public static final String RECHARGE_NOTIFY_URL = "http://localhost/api/core/userAccount/notify";//充值同步回调public static final String RECHARGE_RETURN_URL = "http://localhost:3000/user";/*** 投标*///充值汇付宝平台url地址public static final String INVEST_URL = "http://localhost:9999/userInvest/AgreeUserVoteProject";//充值异步回调public static final String INVEST_NOTIFY_URL = "http://localhost/api/core/lendItem/notify";//充值同步回调public static final String INVEST_RETURN_URL = "http://localhost:3000/user";/*** 放款*/public static final String MAKE_LOAD_URL = "http://localhost:9999/userInvest/AgreeAccountLendProject";/*** 提现*///充值汇付宝平台url地址public static final String WITHDRAW_URL = "http://localhost:9999/userAccount/CashBankManager";//充值异步回调public static final String WITHDRAW_NOTIFY_URL = "http://localhost/api/core/userAccount/notifyWithdraw";//充值同步回调public static final String WITHDRAW_RETURN_URL = "http://localhost:3000/user";/*** 还款扣款*///充值汇付宝平台url地址public static final String BORROW_RETURN_URL = "http://localhost:9999/lendReturn/AgreeUserRepayment";//充值异步回调public static final String BORROW_RETURN_NOTIFY_URL = "http://localhost/api/core/lendReturn/notifyUrl";//充值同步回调public static final String BORROW_RETURN_RETURN_URL = "http://localhost:3000/user";}

RequestHelper.java:签名工具

package com.indi.srb.core.hfb;import com.alibaba.fastjson.JSONObject;
import com.indimon.util.HttpUtils;
import com.indimon.util.MD5;
import lombok.extern.slf4j.Slf4j;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;@Slf4j
public class RequestHelper {public static void main(String[] args) {Map<String, Object> paramMap = new HashMap<>();paramMap.put("d", "4");paramMap.put("b", "2");paramMap.put("c", "3");paramMap.put("a", "1");}/*** 请求数据获取签名* @param paramMap* @return*/public static String getSign(Map<String, Object> paramMap) {if(paramMap.containsKey("sign")) {paramMap.remove("sign");}TreeMap<String, Object> sorted = new TreeMap<>(paramMap);StringBuilder str = new StringBuilder();for (Map.Entry<String, Object> param : sorted.entrySet()) {str.append(param.getValue()).append("|");}str.append(HfbConst.SIGN_KEY);log.info("加密前:" + str.toString());String md5Str = MD5.encrypt(str.toString());log.info("加密后:" + md5Str);return md5Str;}/*** Map转换* @param paramMap* @return*/public static Map<String, Object> switchMap(Map<String, String[]> paramMap) {Map<String, Object> resultMap = new HashMap<>();for (Map.Entry<String, String[]> param : paramMap.entrySet()) {resultMap.put(param.getKey(), param.getValue()[0]);}return resultMap;}/***  签名校验* @param paramMap* @return*/public static boolean isSignEquals(Map<String, Object> paramMap) {String sign = (String)paramMap.get("sign");String md5Str = getSign(paramMap);if(!sign.equals(md5Str)) {return false;}return true;}/*** 获取时间戳* @return*/public static long getTimestamp() {return new Date().getTime();}/*** 封装同步请求* @param paramMap* @param url* @return*/public static JSONObject sendRequest(Map<String, Object> paramMap, String url){String result = "";try {//封装post参数StringBuilder postdata = new StringBuilder();for (Map.Entry<String, Object> param : paramMap.entrySet()) {postdata.append(param.getKey()).append("=").append(param.getValue()).append("&");}log.info(String.format("--> 发送请求到汇付宝:post data %1s", postdata));byte[] reqData = postdata.toString().getBytes("utf-8");byte[] respdata = HttpUtils.doPost(url,reqData);result = new String(respdata);log.info(String.format("--> 汇付宝应答结果:result data %1s", result));} catch (Exception ex) {ex.printStackTrace();}return JSONObject.parseObject(result);}
}

还有一些枚举类,太多了,我就不添加了,看看以后传到gitee上吧

后端实现

vo

UserBindVO.java

package com.indi.srb.core.pojo.vo;@Data
@ApiModel(description = "账户绑定")
public class UserBindVO {@ApiModelProperty(value = "用户姓名")private String name;@ApiModelProperty(value = "身份证号")private String idCard;@ApiModelProperty(value = "银行卡号")private String bankNo;@ApiModelProperty(value = "银行类型")private String bankType;@ApiModelProperty(value = "手机号")private String mobile;
}

service

UserBindService.java

    String commitBindUser(UserBindVO userBindVO,Long userId);

UserBindServiceImpl.java

	@Transactional(rollbackFor = Exception.class)@Overridepublic String commitBindUser(UserBindVO userBindVO, Long userId) {// 查询其他人的绑定信息QueryWrapper<UserBind> queryWrapper = new QueryWrapper<>();queryWrapper.eq("id_card", userBindVO.getIdCard()).ne("user_id", userId);UserBind userBind = baseMapper.selectOne(queryWrapper);// 有没有人用过这个身份证号码Assert.isNull(userBind, ResponseEnum.USER_BIND_IDCARD_EXIST_ERROR);// 查询当前用户绑定信息queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_id", userId);userBind = baseMapper.selectOne(queryWrapper);// 判断是否有绑定记录if (userBind == null) {// 没有则创建userBind = new UserBind();// 把用户填的类信息拷贝到绑定表对应的实体类BeanUtils.copyProperties(userBindVO,userBind);userBind.setId(userId);userBind.setStatus(UserBindEnum.NO_BIND.getStatus());baseMapper.insert(userBind);}else{// 有则更新BeanUtils.copyProperties(userBindVO,userBind);baseMapper.updateById(userBind);}// 创建自动提交表单Map<String, Object> map = new HashMap<>();map.put("agentId", HfbConst.AGENT_ID);map.put("agentUserId",userBind.getUserId());map.put("personalName",userBindVO.getName());map.put("idCard",userBindVO.getIdCard());map.put("bankNo",userBindVO.getBankNo());map.put("bankType",userBindVO.getBankType());map.put("mobile",userBindVO.getMobile());map.put("returnUrl",HfbConst.USERBIND_RETURN_URL);map.put("notifyUrl",HfbConst.USERBIND_NOTIFY_URL);map.put("timestamp", RequestHelper.getTimestamp());map.put("sign",RequestHelper.getSign(map));String formStr = FormHelper.buildForm(HfbConst.USERBIND_URL, map);return formStr;}

controller

UserBindController.java

@Api(tags = "用户认证")
@Slf4j
@RestController
@RequestMapping("/api/core/userBind")
public class UserBindController {@Resourceprivate 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 = userBindServicemitBindUser(userBindVO, userId);return R.ok().setData("formStr",formStr);}
}

前端实现

pages/user/bind.vue

commitBind() {this.$alert('<div style="size: 18px;color: red;">您即将前往汇付宝绑定账号</div>','前往汇付宝资金托管平台',{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)})}},})
},

账户绑定

账户绑定流程

尚融宝应该在网站引导客户在“资金托管平台“开设账户。也就是说投资人和借款人必须在资金托管平台页面上自主开户,与尚融宝建立对应的账户体系。

以后所有的资金操作都会到“资金托管平台”进行,绑定账户流程如图:

相关数据库表

srb:

绑定步骤

step6:汇付宝验证用户身份、用户设置交易密码

step7:点击确定汇付宝创建绑定账号(新建user_bind和user_account记录)

step8:异步回调

尚融宝user_bind表更新bind_code字段、status字段

尚融宝user_info表更新 bind_code字段、name字段、idCard字段、bind_status字段

step9:用户点击“返回平台”,返回尚融宝

后端实现

pojo

UserInfo.java

    /*** 用户完成汇付宝认证时使用**/public UserInfo(Long id, String name, String idCard, Integer bindStatus, String bindCode) {this.id = id;this.name = name;this.idCard = idCard;this.bindStatus = bindStatus;this.bindCode = bindCode;}

service

UserBindService.java

    void notify(Map<String,Object> map);

UserBindServiceImpl.java

    @Transactional(rollbackFor = Exception.class)@Overridepublic void notify(Map<String, Object> map) {String bindCode = (String) map.get("bindCode");String agentUserId = (String) map.get("agentUserId");// 更新用户绑定表:绑定状态、绑定协议QueryWrapper<UserBind> queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_id", agentUserId);UserBind userBind = baseMapper.selectOne(queryWrapper);userBind.setBindCode(bindCode);userBind.setStatus(UserBindEnum.BIND_OK.getStatus());baseMapper.updateById(userBind);// 更新用户表:用户名称、身份证、绑定状态、绑定协议UserInfo userInfo = new UserInfo(new Long(agentUserId),userBind.getName(),userBind.getIdCard(),UserBindEnum.BIND_OK.getStatus(),bindCode);userInfoMapper.updateById(userInfo);}

controller

UserBindController.java

    @ApiOperation("绑定之后的回调")@PostMapping("/notify")public String notify(HttpServletRequest request){Map<String, Object> map = RequestHelper.switchMap(request.getParameterMap());log.info("用户账号绑定异步回调:"+ JSON.toJSONString(map));if (!RequestHelper.isSignEquals(map)){log.error("用户账号绑定异步回调签名错误:"+JSON.toJSONString(map));return "fail";}userBindService.notify(map);return "success";}

更多推荐

26. 尚融宝账户绑定

本文发布于:2024-02-17 10:22:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1693685.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:绑定   账户   尚融宝

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!