超详细对接法大大电子合同(JAVA) | 项目实测全过程

目录

一、开发前准备

1.点击查看 法大大API文档

2.获取 法大大相关配置(配合官方技术支持)

二、引入依赖完成配置

1.引入法大大依赖

2.yml配置文件 

3.配置文件config

 三、对接法大大API(参考API文档)

1.创建 FaDaDaController 注入config

2.编写生成随机数方法

3. 创建签署任务

4. 获取参与方签署链接

 5.前端请求接口、集合签署

6.编写签署完成回调

 四、在法大大平台配置回调地址


一、开发前准备

1.点击查看 法大大API文档

 

2.获取 法大大相关配置(配合官方技术支持)

  • 创建应用获取 AppId、oppenCorpId、appSecret
  • 创建模板获取模板id  signTemplateId

二、引入依赖完成配置

1.引入法大大依赖

<dependency>
    <groupId>com.fadada.api</groupId>
    <artifactId>fasc-openapi-java-sdk</artifactId>
    <version>{sdk-version}</version>
</dependency>

2.yml配置文件 

#法大大配置
fadada:
  oppenCorpId: xxxxxxxxx
  appId: xxxxxx
  appSecret: xxxxxxxxx
  serverUrl: https://api.fadada.com/api/v5/
  signTemplateId: xxxxxxxxxxxxxxx

3.配置文件config

创建配置文件 FaDaDaConfig

@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "fadada")
public class FaDaDaConfig {

    @Value("${fadada.appId}")
    private String appId;

    @Value("${fadada.appSecret}")
    private String appSecret;

    @Value("${fadada.serverUrl}")
    private String serverUrl;

    @Value("${fadada.oppenCorpId}")
    private String oppenCorpId;

    @Value("${fadada.signTemplateId}")
    private String signTemplateId;

    @Bean
    public OpenApiClient appClient() {
        return new OpenApiClient(appId, appSecret, serverUrl);
    }

    //获取凭证
    public String getAccessToken(OpenApiClient openApiClient) throws ApiException {
        ServiceClient serviceClient = new ServiceClient(openApiClient);
        log.info("获取凭证:{}", openApiClient.getAppId(), openApiClient.getAppSecret());
        BaseRes<AccessTokenRes> res = serviceClient.getAccessToken();
        ResultUtil.printLog(res, openApiClient.getJsonStrategy());
        return res.getData().getAccessToken();
    }
}

 三、对接法大大API(参考API文档)

1.创建 FaDaDaController 注入config

@Slf4j
@RestController
@RequestMapping("/faDaDa")
public class FaDaDaController {

    @Resource
    private FaDaDaConfig faDaDaConfig;
}

2.编写生成随机数方法

/**
* 生成随机数
*/
private String generateNonce() {
  // 生成一个随机数,最长32个字符
  return UUID.randomUUID().toString().replace("-", "").substring(0, 32);
}

3. 创建签署任务

/**
     * 创建签署任务
     */
    public String createTest(String accessToken, Map<String, Object> bizContent) throws Exception {
        // 构造请求URL
        String url = faDaDaConfig.getServerUrl() + "/sign-task/create-with-template";

        // Unix标准时间戳
        String timestamp = Long.toString(System.currentTimeMillis());

        // 构造请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("X-FASC-App-Id", faDaDaConfig.getAppId());
        headers.put("X-FASC-Sign-Type", "HMAC-SHA256");
        headers.put("X-FASC-Timestamp", timestamp);
        headers.put("X-FASC-Nonce", generateNonce());
        headers.put("X-FASC-AccessToken", accessToken);
        headers.put("X-FASC-Api-SubVersion", "5.1");
        headers.put("bizContent", JSON.toJSONString(bizContent));

        // 排序后的参数字符串,FddCryptUtil为法大大提供得签名工具类
        String paramToSignStr = FddCryptUtil.sortParameters(headers);
        // 计算之后得到签名字符串,该签名字符串需放到请求头中的X-FASC-Sign字段
        String signature = FddCryptUtil.sign(paramToSignStr, timestamp, faDaDaConfig.getAppSecret());
        headers.put("X-FASC-Sign", signature);

        // 构造请求体
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("bizContent", JSON.toJSONString(bizContent));

        // 发送POST请求
        String response = HttpUtils.Post(url, requestParams, headers);

        // 解析返回结果
        JSONObject jsonObject = JSON.parseObject(response);
        JSONObject data = jsonObject.getJSONObject("data");
        String taskId = data.getString("signTaskId");

        return taskId;
    }

4. 获取参与方签署链接

public Map<String, Object> getSignUrl(String accessToken, Map<String, Object> bizContent) throws Exception {
        // 构造请求URL
        String url = faDaDaConfig.getServerUrl() + "/sign-task/actor/get-url";

        // Unix标准时间戳
        String timestamp = Long.toString(System.currentTimeMillis());

        // 构造请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("X-FASC-App-Id", faDaDaConfig.getAppId());
        headers.put("X-FASC-Sign-Type", "HMAC-SHA256");
        headers.put("X-FASC-Timestamp", timestamp);
        headers.put("X-FASC-Nonce", generateNonce());
        headers.put("X-FASC-AccessToken", accessToken);
        headers.put("X-FASC-Api-SubVersion", "5.1");
        headers.put("bizContent", JSON.toJSONString(bizContent));

        // 排序后的参数字符串,FddCryptUtil为法大大提供得签名工具类
        String paramToSignStr = FddCryptUtil.sortParameters(headers);
        // 计算之后得到签名字符串,该签名字符串需放到请求头中的X-FASC-Sign字段
        String signature = FddCryptUtil.sign(paramToSignStr, timestamp, faDaDaConfig.getAppSecret());
        headers.put("X-FASC-Sign", signature);

        // 构造请求体
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("bizContent", JSON.toJSONString(bizContent));

        // 发送POST请求
        String response = HttpUtils.Post(url, requestParams, headers);

        // 解析返回结果
        JSONObject jsonObject = JSON.parseObject(response);
        String code = jsonObject.getString("code");
        String msg = jsonObject.getString("msg");

        Map<String, Object> result = new HashMap<>();
        if ("100000".equals(code)) {
            JSONObject data = jsonObject.getJSONObject("data");
            String actorSignTaskUrl = data.getString("actorSignTaskUrl");
            String actorSignTaskEmbedUrl = data.getString("actorSignTaskEmbedUrl");

            result.put("actorSignTaskUrl", actorSignTaskUrl);
            result.put("actorSignTaskEmbedUrl", actorSignTaskEmbedUrl);
        } else {
            result.put("error", msg);
        }
        return result;
    }

 5.前端请求接口、集合签署

@GetMapping("/xxxxx")
    public Map<String, Object> test(@RequestParam Long memberId) throws Exception {
        log.info("id:{}", memberId);
        OpenApiClient apiClient = faDaDaConfig.appClient();
        // 获取应用accessToken
        String accessToken = faDaDaConfig.getAccessToken(apiClient);

        Member member = memberService.getById(memberId);

        // 一、创建签署任务
        // 1.构造请求参数
        Map<String, Object> bizContent = new HashMap<>();
        bizContent.put("signTaskSubject", "xxxx签署任务");
        bizContent.put("signTemplateId", faDaDaConfig.getSignTemplateId());
        bizContent.put("autoStart", true);
        bizContent.put("transReferenceId",member.getPhone());

        Map<String, Object> initiator = new HashMap<>();
        initiator.put("idType", "corp");
        initiator.put("openId", faDaDaConfig.getOppenCorpId());
        bizContent.put("initiator", initiator);

        List<Map<String, Object>> actors = new ArrayList<>();
        Map<String, Object> actor = new HashMap<>();
        Map<String, Object> actorDetail = new HashMap<>();
        actorDetail.put("actorId", "乙方");
        actorDetail.put("actorType", "person");
        actorDetail.put("actorName", member.getName());
        actorDetail.put("permissions", Arrays.asList("fill", "sign"));
        actorDetail.put("sendNotification", "false");
        actor.put("actor", actorDetail);

        Map<String, Object> signConfigInfo = new HashMap<>();
        signConfigInfo.put("blockHere", false);
        signConfigInfo.put("requestVerifyFree", false);
        actor.put("signConfigInfo", signConfigInfo);

        actors.add(actor);
        bizContent.put("actors", actors);

        // 2.调用方法
        String taskId = createTest(accessToken, bizContent);
        log.info("bizContent:{}", bizContent);
        log.info("taskId:{}", taskId);

        // 将taskId存入数据库(可选)
        member.setSignTaskId(taskId);
        member.setMid(memberId);
        memberService.updateMember(member);

        // 二、获取参与方签署链接
        Map<String, Object> signUrlsBizContent = new HashMap<>();
        signUrlsBizContent.put("signTaskId", taskId);
        signUrlsBizContent.put("actorId", "乙方");
        Map<String, Object> signUrls = getSignUrl(accessToken, signUrlsBizContent);
        log.info("signUrlsBizContent:{}", signUrlsBizContent);
        log.info("signUrls:{}", signUrls);

        // 三、将签署链接返回给前端
        Map<String, Object> result = new HashMap<>();
        result.put("taskId", taskId);
        result.putAll(signUrls);
        return result;
    }

这个方法用于处理前端请求,集成了前面的创建签署任务、获取签署链接,可加入自己的业务逻辑,其中参数比较多,需要对照官方文档来填写。

创建签署任务(基于签署任务模板)                        

获取参与方签署链接

6.编写签署完成回调

/**
     * 签署完成回调
     */
    @PassToken
    @ResponseBody
    @PostMapping("/xxxxx")
    public String fddEventCallback(@RequestHeader HttpHeaders headers,
                                   @RequestParam("bizContent") String bizContent) throws Exception {
        log.info("回调方法执行headers:{}", headers);
        log.info("回调方法执行bizContent:{}", bizContent);
        String appSecret = faDaDaConfig.getAppSecret();

        // 获取请求头参数
        String appId = headers.getFirst("X-FASC-App-Id");
        String signType = headers.getFirst("X-FASC-Sign-Type");
        String sign = headers.getFirst("X-FASC-Sign");
        String timestamp = headers.getFirst("X-FASC-Timestamp");
        // 事件名称,开发者可以根据不同事件名称去解析bizContent的值,实现不同的逻辑
        String event = headers.getFirst("X-FASC-Event");
        String nonce = headers.getFirst("X-FASC-Nonce");
        // 验签
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("X-FASC-App-Id", appId);
        paramMap.put("X-FASC-Sign-Type", "HMAC-SHA256");
        paramMap.put("X-FASC-Timestamp", timestamp);
        paramMap.put("X-FASC-Nonce", nonce);
        paramMap.put("X-FASC-Event", event);
        paramMap.put("bizContent", bizContent);
        // 参数排序,ASCII码排序
        String sortParam = FddCryptUtil.sortParameters(paramMap);
        // 生成签名后可以进行校验
        String signature = FddCryptUtil.sign(sortParam, timestamp, appSecret);
        if (!signature.equals(sign)) {
            log.error("日志记录,签名失败");
            // 为了不重复接收该请求,建议这里返回success,返回success后这条消息法大大将中断重试回调机制
            return "{\"msg\":\"success\"}";
        }

        // 解析bizContent
        JSONObject bizContentJson = JSON.parseObject(bizContent);
        String eventTime = bizContentJson.getString("eventTime");
        String signTaskId = bizContentJson.getString("signTaskId");
        String signTaskStatus = bizContentJson.getString("signTaskStatus");

        // 业务处理
        if ("sign-task-signed".equals(event)) {
            // 处理签署任务完成的逻辑
            log.info("签署任务完成回调, 任务ID: {}, 时间: {}", signTaskId, eventTime);
            // 业务处理
            // 写入你自己的逻辑
            }
            return "{\"msg\":\"success\"}";
        } else {
            log.warn("收到未处理的事件或状态, 事件: {}, 状态: {}", event, signTaskStatus);
            return null;
        }

    }

 四、在法大大平台配置回调地址

 

 注意:回调地址必须是可以由外网访问的

......项目实测有效

5.1 注册账号 ......................................................................................................................... 7 SDK 使用说明 .................................................................................................................... 8 5.2 获取企业实名认证地址 ................................................................................................. 9 SDK 使用说明 .................................................................................................................. 12 5.3 获取个人实名认证地址 ............................................................................................... 13 SDK 使用说明 .................................................................................................................. 16 5.4 实名证书申请 ............................................................................................................... 16 SDK 使用说明 .................................................................................................................. 17 5.5 印章上传 ....................................................................................................................... 17 SDK 使用说明 .................................................................................................................. 18 5.6 自定义印章 ................................................................................................................... 19 SDK 使用说明 .................................................................................................................. 20 5.7 合同上传 ....................................................................................................................... 20 SDK 使用说明 .................................................................................................................. 21 5.8 模板上传 ....................................................................................................................... 22 SDK 使用说明 ..........................................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值