共绩算力 IDC 商户接口文档
流程说明
整体流程图
余额预警与关机处理
每个商户在共绩平台会有个唯一商户账号,共绩存商户整体的余额。
商户系统中用户的余额信息、以及是否预警由商户自己来维护。
商户系统来判断哪些用户是不能开机、或需要立即关机的,然后把信息告诉共绩,共绩来做限制和处理。
处理流程:
- 商户检测到用户余额不足或欠费,推送预警信息
- 共绩平台接收预警,发送通知给用户
- 启动关机流程,释放相关资源
开机权限验证流程
- 触发时机:用户在共绩平台发起开机请求
- 验证流程:
- 共绩平台接收用户开机请求
- 验证用户是否在黑名单中
- 根据黑名单验证结果决定是否允许开机
整体流程细讲
- 向共绩算力方获取 公私钥-A
- 商户登录流程
- 商户前端生成 RSA 公私钥对-B
export async function generateApiKeyPair() { //生成密钥对 return new Promise(async (resolve) => { // crypto 默认不需要引入第三方依赖,使用浏览器内置 API const keyPair = await crypto.subtle.generateKey( { name: 'RSA-OAEP', //算法名称 modulusLength: 2048, //密钥长度 publicExponent: new Uint8Array([1, 0, 1]), //公钥的指数 65537 最大值 hash: { name: 'SHA-256' } //使用 SHA-256 算法 }, true, ['encrypt', 'decrypt'] ) //“spki” 表示导出公钥 const exportedPublicKey = await crypto.subtle.exportKey('spki', keyPair.publicKey) //window.btoa是浏览器方法用于创建一个 base-64 编码的字符串。 const publicKeyPem = window.btoa(String.fromCharCode(...new Uint8Array(exportedPublicKey))) //pkcs8是表示导出私钥 const exportedPrivateKey = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey) const privateKeyPem = window.btoa(String.fromCharCode(...new Uint8Array(exportedPrivateKey))) resolve({ publicKeyPem: publicKeyPem, privateKeyPem: privateKeyPem }) }) }
1. 前端将登录信息和公钥 B 传给商户后端进行登录验证
3. 共绩后台登录流程
1. 商户后台验证通过后,调用共绩后台进行商户用户登录
2. 商户后台调用共绩[获取登录信息接口](https://apifox.com/apidoc/shared/15f9f602-8d24-438f-bb47-2f5496a7bc6f/api-270986655),传入公钥 B(接口本身的加密和加签通过静态商户 Token 与公私钥-A 进行计算)
3. 共绩后台验证通过后,会返回用户 Token 与公钥 C
4. 商户后台将获取到的用户 Token 与公钥 C 返回前端
4. 商户前端调用内嵌 WEB 服务,并将用户 Token 与私钥 B 和公钥 C 传入内嵌 WEB 服务:
1. 示例代码如下
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Iframe 接入示例</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.header {
width: 100%;
height: 60px;
background-color: #1a73e8;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.header button {
margin-left: 10px;
}
.content {
display: flex;
flex: 1;
}
.content .sidebar {
width: 200px;
background-color: #000000;
color: #ffffff;
padding: 20px;
}
.content .iframe-container {
flex: 1;
}
.content #iframeContainer {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<header class="header">
<h3>您的导航栏</h3>
<button onclick="changeIframeData()">模拟切换登录信息</button>
</header>
<div class="content">
<aside class="sidebar">
<h3>您的菜单栏</h3>
</aside>
<div class="iframe-container">
<!-- 生产需替换 src 为 https://suanli.cn/serverless/idc?type=other -->
<iframe
id="iframeContainer"
src="https://idc-output.suanleme.vip/serverless/idc?type=other"
></iframe>
</div>
</div>
<script>
const iframe = document.getElementById('iframeContainer');
let flag = true
function getLoginData() {
// 向 iframe 传登陆信息,需替换成真实的
return flag ? {
// 用户 Token,通过接口[获取登录信息接口](https://apifox.com/apidoc/shared/15f9f602-8d24-438f-bb47-2f5496a7bc6f/api-270986655) 中返回的 token 字段
"token": "7f91a52f-9c5f-4218-93e1-aedb08c3ece5-20250416114830",
// 公钥 C 通过接口 [获取登录信息接口](https://apifox.com/apidoc/shared/15f9f602-8d24-438f-bb47-2f5496a7bc6f/api-270986655) 中返回的公钥 C
"rsa_pubk": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4kG9wEaKPCAbiQagEIhcdO9RNnqN4qTebG1aoz/rBzt0UYvOupQhqB4fG/HIA5qEQ4mXXtonDQKUfRms+FH6f/QbpUN9FTNNruKFE4zwcOKaT+iRpkUZfueUIY/jYC3s5kmmRtsux764Yy8eu0NlgPZbaDcDyII+euiHu0exCPFkSvgYRkDqsUBg3jPJGMlJHwQJs5j/pCBit3YhgKWL7ByBUE35gpULnOaMmirkevsaSpWaaUKgQ49KXJeiiVuMCexPDxGjrUlJncT9lWyO5+bVbBgTdRpCLtddeM+ABXcZEwOeGREORv/Bin87gPEW/gbdDRmoU73KTC3bEnobzQIDAQAB",
// 私钥 B 商户前端生成 RSA 公私钥对-B 中的私钥
"rsa_prik": "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJj9uE0lHBmOXKHMv5/ubjcA8z43m5fiAKnT983bs8CHJhbeHbkKQJvu72GIcyyf8AMptRTzYxM/zVlE6Yy8lhjVZ0Z1iDmrMd+RcpBgUoduzNBOY3JUDyuo7XhUuNNjiAhFslF1faYs9jVkVTF6Lx9IiYNC/jT+aqELVfYm7jbcoavKEKq4/uGof94Alr1FWEwI5F6iju/Ctz2qf3p/gWN3JC36JDXQfu+kcHf8ElMXRH/tEFnQcyHLD3ANF5axTcFfmbQsesR0txboBaiI7UE7uhMgmzS3IjhOmFMAmVSLt6UfWhDglJjkwGgTVE48W4wyPdZPdU0M+9CNNaYNWTAgMBAAECggEANvaKhsKPVrpp1t5ZZPd0YIq7KowaMlHJTPuqR1NzbiBjiFvdXfEoOhwdr2/q1hes+JHUNqzh+zLQ/DCv6gyQApD3BVD1GxYBR+gXv7ELkQg09Icke98lwcrLjsujWYNyjuEItamS5FNTeCQbTVhBr7bd1JtOf67XGILr4nHGCS/4LMF7q9hWyxcfeUrKZ2bnaXeOWTg3Uxr43SGHbOs65EOBjv4jEgPMgyX1NeGFRu/xaen595daSEIoaXRX5H3oo8sIcLixFT9h4TyF2/OZXWO5zAwEsKp6EMOn0bOapBzfFAN2FUy9SnM7BzHLW32bgEbBs9/zzK24gf+n23cfUQKBgQDjZAgDkyQuFlrpeyTGi/jRZ3hNVbjrixiFla7ko7e9UcVncmTnj3edEdODn2tSlROs8uwGE2J6uH2P6HcsG2VoGWr/7tCWZ2X0CS520Te33SHfC6p7wPlP/444mHCYQPzhgNq5onB0iYpoJJ1CY1inNB8AaEzGG2ajpF+Q1i8beQKBgQDi6+m9b3MPdEcYidU1PAFLH+shVzzKzQPsHZiNchGNTN62nrDDCaHpOXRI0Qcbg9nfqHP1zFILGSp1KeqBgAhECRRRMBcAx7s8RFxMg0OdAZ2SRRVnOx4UoPAbjdqOBq0+XWrFM6YYjPQu6PgukZjFXJlz00VvV55TlGlYIYKqawKBgAy5JSWmDwkxIQcdZ9JgNJzq8DVLjZxIXSfkVzPd4UMLl0MRiInYYjX8sFwWCHhHdSFhOkmgvgrl1ci+liR2p/bqLS2C3FL+GBtOhDYLwNVd3y5OxcxE4O5T+045YVtzj3LCtfpbF3W92Gu5WL9FNcmtRerM6zbOg7C2Ws6M3XfpAoGBAKAyH47mcPoGAnLmSygLtnYMkHe3GGmrFgvIUPv5/T4deFS/7tWhpTX6o4cMWdIo4NSuHT73ASxolbqk3rKRakRtjHRMWNDqL9o6AFbbjA35J/4s2xFHgNLbUuaA3DvLpt4SIOAauDU4vOGpAhwOGSWrW4GTMr+JwXILodrfvVkFAoGAZq1aXKEN70X5h5UioMucnpa/1ABPqaBYQi8BKvSgCNypNwEI0457WAQW2q3LOOIt1uISg+Sk8MTt2uH46oJA1CbY03DUO+0ZtOgSQP920fbMN+Ek18MtDwXmzPBB1e4zP9fahBq2JU+WUiQ2ksS8TBZjrlYL9TOAmisyl6qqrl8="
} : {
"token": "97f0b147-159c-40cd-a516-cd14cb6cce7d-20250416135548",
"rsa_pubk": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv9Oeil09bMGQMmzbJQWDlW+RxLWM1MGDOU7uDmKr/d0j5TYSVVioPNf8JOkQB4SP9EaklmeCIPlJZlBn9nLPK7xVVYMm+6ZA2pVxL/fp0qWgLx2Febk47gLWGn4nLv+alWDkpJJRHzV/MWr259l86/bHoRPlFCp0qItLyIsgrDnlUTtIRy6o3ijP7I2Bv/bMMbx81u7mC+jKVUgT4ovJwXcseoa6JyZ2bpXA5OxIf7sZfzxA8EM9YdAqyDBhUBo6eq5xSLrZY7/Njtn2YTHuNr0FpuQ90e5Vu7Hi5sPAdHX+YsEWrbHN2H4svdScDyMJ/Yfbae9c8PV2xGPw7NmrBQIDAQAB",
"rsa_prik": "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrhaVY9BNjydWDZUKiGi4J9R5dsosEC76GTe/ruCI2vjARI9OdeFYQNR6LthP6gVqANxiXt21RMcNv57zARiGb7iuWfBQ3RcYqZWZ3iwbkhfSh3cRWvG2Yohq7AmFuNlY80RlKBf4h5NESvyHrAdXg0vMj9kMt6rJDKEw/9+9bCDIki09iX/8tYuVUQkM7I5vBv5v/beMrq6ph8pBJBJ5l0oymMhfY5vebglqc2N+XY6NyN+6F7/dSXW9cc7/wJQoCDOJqqtZR71gdGIYh1zVbtfFaYrZmy3h+Ew6UcmhwbkztFY5djKRFLbt+07N/7KTq0PamsXpMONZrsH1XgYd3AgMBAAECggEAUnn5x7vZ5QaFKmETOPKAx937o496hFAHZfptDzpkDVHHuD4zgAmAzNtWHFVJ5w+zTmrv4uhbYwscUJ+spgIzIBFXGU4BxJBDGVjX/Ey4XEPDneAPDKwfwSDV3K3o3r+3GRhs4ijeijrGhA6vRxuDVk/phZXhuN8dp+hlPe9BQ9J0CwPQpZdL0J+V83h5ttDzom+hVE/rKj2HdBpjelm7DqG+J80aajHr4m+I/XqO1SiTgWpXiWqTLi9EGWbBAXIB8N4C13UCkXc770jbJpakRGLc59BihoHAJ9uG9CwvP7CV8OK8sVNkFnVGSAZYguvyol2b1BF6oKyNj5rRW9TaJQKBgQDUeFozrh0/lV6KDmWuNHnaScGCnitNPgruMeT95lZrxWZkip/kSk+dSm9uIJ2b0DFMRx9PEvfGaiZGFIzA3PdEZGhoLH5XpbwOzaRJ07ltynny0sQMMxMQFm2unwf00jEVNduxsNKVU4IFH2sL6TAwErinoQZ3NvmCjd1Hn3AuLQKBgQDOqaVxjuKM+ANkrvr5hxLzkTjWiUEQDCy628LB/Lynfx0awqtg4TE8VHdUs5rfLdA/dLZtJGf8Y/5kVEmtaWr0fEBQIowG6YB8HVZ5w5JZU70GjenDjWOutGx91dSdQIku+qhjxrN1b3fnHpDj2tsqt/sUKGXGGklaqiLcb7r2swKBgAb15maZBqZFm3JEZHpfh7pp/ifsTJjcNnl1Mv5KZHxlXCRhEjnlYVRS0vG1qdQn7uWD0vfBNFLQuW5EUBQlaQhZjb4T7xOp/04w2Hf+sq1xG6uj0f5gUfiN84vr89PGaws513erxkpUEQdf7x7VxdldU6VSNicDqwrm4N/uzjsFAoGAC0OL1OioyG4sISy4WSlXixb7NhY9CZbgST75GoGf9rEi8PZzSNB9UoB4EJHJeyiQFSVTXBeD42m/z9AYQ+9e+PxctQFtCGNpsVoYAIL8UwoRX24Us6fdKwSCdUlWUUvXLkxTKT0HQvtUWbB8zS58i5ODh9G72lRMcziatdERK6kCgYEAzEML9bYj+KDxzZgLDR7nxtQsNKgPlDml9oHjV9VE8+2RJqiJX0lVrtN4naaG0z+9DWNjKBoi6lQbFfWl3QvdM03nHMlUT2wPdmM/fTZHB8+c7CbZ09bwCeL+eEg+GsJ1N0ESRINunh63x65kh7wsWubTjyaUrsl/Ld/LSStY1ks="
};
}
document.addEventListener('DOMContentLoaded', () => {
// 向iframe传登陆信息,需替换成真实的
iframe.addEventListener('load', function() {
setTimeout(() => {
// 向iframe发送参数
iframe.contentWindow.postMessage(getLoginData(), "*");
}, 500);
}, { once: true });
});
function changeIframeData() {
// 切换iframe登陆信息
flag = !flag
iframe.contentWindow.postMessage(getLoginData(), "*");
}
</script>
</body>
</html>
- 操作内嵌 WEB 服务进行业务操作
接口文档地址
加签教程
https://www.gongjiyun.com/docs/y/openapi/M0icwE2tfiX4tTkJsi0cXiKpnCd.html
版本记录
版本号 | 变更记录 | 变更日期 | 变更说明 |
---|---|---|---|
1.0.0 | 新建 | 2025/04/11 | 新建商户接口文档,含流程说明、用户登录接口、计费查询接口、商户黑名单变更接口。 |