回调配置说明
回调是每刻提供的调用外部接口的功能,需要先联系每刻管理员开通回调服务,然后在【企业设置】->【安全设置】->【回调管理】页面进行回调配置
关键参数解释
认证名称
选择在认证配置页面配好的认证方式,不需要认证则可以不填
回调类型
回调类型是指回调接口的使用场景,每刻目前提供了7种回调类型,下面给出的是回调类型【发送通知】的使用场景。如果需要了解其他几种回调类型的使用场景,或者定制新的回调类型请联系每刻管理员
发送通知
在单据流程中,推送消息到配置好的回调接口。消息内容如下
字段 | 上级字段 | 类型 | 字段名 | 备注说明 |
---|---|---|---|---|
encryptParams | String | 外调参数加密 | ||
calloutParams | Map | 外调参数(具体对象信息如下) | ||
entCode | calloutParams | String | 企业编号 | |
formCode | calloutParams | String | 单据号 | |
formDataCode | calloutParams | String | 单据内码 | |
formName | calloutParams | String | 单据名称 | 报销事由 |
formType | calloutParams | String | 单据类型 | PRECONSUME 消费申请 REIMBURSE 普通报销 CORP_REIMBURSE 对公报销 CORP_CONTRACT 采购合同 CORP_REPAYMENT对公收款 REPAYMENT还款单 |
formSubType | calloutParams | String | 单据小类 | 企业自定义的 |
submitter | calloutParams | String | 提交人 | 提交人工号 |
submitterName | calloutParams | String | 提交人姓名 | 提交人姓名 |
reimUser | calloutParams | String | 报销人 | 报销人工号 |
reimUserName | calloutParams | String | 报销人姓名 | 报销人姓名 |
reason | calloutParams | String | 审批意见 | |
procInsId | calloutParams | String | 流程任务ID | |
eventScenario | calloutParams | String | 事件场景 | APPROVAL 审批; CASHIER_SETTLE 结算; FINANCE_AUDIT 审核 |
taskId | calloutParams | String | 任务号 | |
taskActionType | calloutParams | String | 任务类型 | PROCESSING 待处理 COMPLETED 完成 REJECTED 驳回 REJECTED_TO_PREVIOUS 驳回到之前的任务处理人 RECALLED 召回 FORWARD 转发 REVERTED 撤回 DELEGATE 转派 COUNTERSIGN 加签 DELETE 删除 PROCESS_COMPLETED 流程完成 BE_REJECTED 驳回提单人 CARBON_COPY 抄送 |
taskAssignee | calloutParams | List<String> | 任务处理人 | 工号,(组下工号列表) |
eventTime | calloutParams | String | 事件发生时间 | |
allocationCode | calloutParams | String | 分摊编码 | |
formSubTypeBizCode | calloutParams | String | 单据小类编码 | 企业自定义的 |
taskName | calloutParams | String | 流程节点名称 | |
assigneUserCodes | calloutParams | List<String> | 任务处理人userCode | |
autoPass | calloutParams | boolean | 该节点自动通过标识 | |
subsidiaryBusinessCode | calloutParams | String | 业务实体businessCode | |
countersign | calloutParams | boolean | 是否是加签标识 | |
reimburseApprovedAmount | calloutParams | String | 临时需要各种金额字段 | 报销单 |
payableAmount | calloutParams | String | 可支付金额 | |
consumeApprovedAmount | calloutParams | String | 申请批准金额 | |
corpApprovedAmount | calloutParams | String | 对公批准金额 | |
paymentApprovedAmount | calloutParams | String | 支付批准金额 | |
repaymentAmount | calloutParams | String | 还款金额 | |
approvedRepaymentAmount | calloutParams | String | 批准收款金额 | |
corpContractTotalAmount | calloutParams | String | 合同总金额 | |
currentDepartmentName | calloutParams | String | 各单据物产回调所需部门名字 |
任务类型实际上只有两种,待处理和已完成,待处理即PROCESSING,已完成包括COMPLETED、REJECTED、REJECTED_TO_PREVIOUS、RECALLED、FORWARD、REVERTED、CARBON_COPY这7种
非分摊流程中除了流程开始和结束的时候只发一条消息,其他节点的时候都会发两条消息。如在审批人A审批通过的时候(假设下一个节点是财务审核),这个时候是会发两条消息:一条是当前审批任务task1的,任务类型是COMPLETED,taskAssignee是A;还有一条消息是财务审核任务task2,任务类型是PROCESSING,taskAssignee是满足条件的财务人员。
推送数据示例
{
"encryptParams": "cTK/UK/bRPAFP5Dnqz7vQmuZHXlAsSqvBRo5H8Yb1MbvF/82Zzzy/T2pOmicOsvE6zvs/IBZBCh2\r\nRjoSzK0c/WNRC2VddxJHcMn+HnN9y4JN5azorhREmtrpMt9FfXu9fvJ73OCAabnC2RUOtVNY8zGZ\r\n6AEwF8snH3Aa9aX3ls3FHJCwUQZd9IuhbDGgQOdEyhIb3LayI78lFkhYLMyFy4uBE37wpSb3q8Jp\r\nsrb+u0SONpf+pEsTpnLlECt9gdWoI4vawAFbS1qhMEHo+OLGtMN2ZN8C7F2gJSvlfeAqIC9eLf7U\r\ngQraMAvHO3hamBClWy/LixHn5uoH1rSaQ3IBAL1Gf5kyJIKj/jl5xCAwmHfT0kTa5xbW2Q+mOVa/\r\nSr3Zxl+qePLS1Z/wxZYwfs4+h4JFBpyULRH1ld6XN/JNFgBzHK819NJTKHcxfwDuU0sa3pPBkGXx\r\na1A=",
"calloutParams": {
"entCode": "EC16040611HZCQGW",
"eventScenario": "APPROVAL",
"eventTime": 1528809459919,
"formCode": "PTBX18044302",
"formSubType": "普通报销",
"formSubTypeBizCode": "FT1712061077W0ZK",
"formType": "REIMBURSE",
"procInsId": "22e1f2e0-6e42-11e8-a640-8c8590cd20da",
"reason": "",
"submitter": "008",
"taskActionType": "COMPLETED",
"taskAssignee": [
"008"
],
"taskId": "23bc9b93-6e42-11e8-a640-8c8590cd20da",
"formDataCode": "BX0002323",
"formName": "**报销单",
"submitterName": "某某",
"reimUser": "UI344342232",
"reimUserName": "某人",
"allocationCode": "ZC23232322",
"taskName": "审批",
"assigneeUserCodes": ["UI53422", "UI343232"],
"autoPass": false,
"subsidiaryBusinessCode": "EP3433",
"countersign": false,
"reimburseApprovedAmount": "10000.00",
"payableAmount": "12300.00",
"consumeApprovedAmount": "2323.00",
"corpApprovedAmount": "232.00",
"paymentApprovedAmount": "111.00",
"repaymentAmount": "3333.00",
"approvedRepaymentAmount": "223.00",
"corpContractTotalAmount":"23.00",
"currentDepartmentName": "部门1"
}
}
简单的流程如图所示
- 推送支付数据
参数 | 类型 | 描述 |
---|---|---|
entCode | String | 企业编码 |
eventType | String | 固定为EXPORT_TO_CASH_MANAGEMENT_SYSTEM |
formTypeList | List<String> | 单据类型,REIMBURSE(报销单),PRECONSUME(申请单),CORP_REIMBURSE(对公支付) |
timestamp | Date | 推送时间 |
在每刻【支付】页面,推送支付数据到资金平台
加密秘钥
没有配置加密秘钥,则不不进⾏行行加密,如果配置了则会对传出内容进行加密,加密规则为先根据密钥进⾏DES加密,然后base64编码。解密则先base64解码,再DES解密。每刻建议对回调接口返回结果以同样的方式进行密,加密解密java代码如下
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DesUtil {
private final static String DES = "DES";
private final static String ENCODE = "UTF-8";
/**
* 使用 默认key 加密
*/
public static String encrypt(String data, String key) throws Exception {
byte[] bt = encrypt(data.getBytes(ENCODE), key.getBytes(ENCODE));
String strs = Base64.getEncoder().encodeToString(bt);
return strs;
}
/**
* 使用 默认key 解密
*/
public static String decrypt(String data, String key) throws IOException, Exception {
if (data == null)
return null;
Base64.Decoder decoder = Base64.getDecoder();
byte[] buf = decoder.decode(data);
byte[] bt = decrypt(buf, key.getBytes(ENCODE));
return new String(bt, ENCODE);
}
/**
* Description 根据键值进行加密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws Exception
*/
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);
// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance(DES);
// 用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
}
/**
* Description 根据键值进行解密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws Exception
*/
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);
// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance(DES);
// 用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
}
}
超时时长
发起回调请求到接收到回调接口返回所需要的时间,超过这个时间会抛异常,默认5000ms,如果回调接口处理请求比较慢,建议延长超时时间
重试次数
调用接口发生异常(连接超时,读取超时等)或者返回的http状态码非200会触发重试。当serviceType为【发送通知时】,除了以上的情况,返回结果不含 {"code":"ACK"}也会触发重试
重试间隔
每次重试的间隔时间,默认2000ms