@doola/js (英语)
嵌入 杜拉语name 你的产品是美国公司 您的客户表 专卖中心或C公司,在您的应用程序和 在你的品牌下.
这个包是故意小的(在 1 KB gziped 下),没有UI. 装上多拉的
版本装入器 js.doola.com,它搭载了从 sdk.doola.com每一个
屏幕、字段和验证都生活在这个框架内:
- 敏感数据从不触及你的代码. SSN、ITIN和签名被打入多拉的 并且被送到了Doola的API。 它们从未出现在您的 JavaScript, 您的错误跟踪器, 您的 会话重放或您的日志 .
- 你从不为我们的改变而重新部署. 国家要求、IRS表格和UI改进船 在iframe内。 这个软件包固定了呼叫的形状,从来就没有它背后的行为.
完整文档: docs.doola.com/sdk 页面存档备份,存于互联网档案馆。 。 。 . 此页面为 短版本:安装,三步并多读到何处.
如何融为一体
- 您的服务器 使用您的密钥为注册客户提供短寿命的薄荷会话.
- 您的页面 电话
loadDoola()并附加它创建的元素。 顾客完成 iframe内部的阵型向导. - 提交时 你会得到
onFormed({ companyId })。你在自己的离职单和你的 服务器确认为 Doola 。 没有档案,没有花费 直到你这样做.
在你开始之前
你需要两把钥匙。 可公布的密钥选择浏览器的环境和秘诀 键在您的服务器上也这样做.
| 密钥 | 前缀 | 它的栖息地点 | 如何获得它 |
|---|---|---|---|
| 可出版 | pk_test_ 或者说 pk_live_ | 你的前门 设计公开. | 伙伴门户下页 SDK 软件,则 安装它识别你并选择你的品牌. |
| 秘诀 | dk_test_ 或者说 dk_live_ | 只有你的服务器 永远不要在浏览器或捆绑中. | 伙伴门户下页 设置,则 API 密钥。 。 。 . |
测试和活性是独立的堆栈,有独立的数据. 使用匹配对 :
| 环境 | 密钥 | 合作伙伴 API | 嵌入式应用程序 |
|---|---|---|---|
| 测试 | pk_test_, (中文(简体) ), dk_test_ | https://api.test.doola.com | https://sdk.test.doola.com |
| 现场直播 | pk_live_, (中文(简体) ), dk_live_ | https://api.doola.com | https://sdk.doola.com |
安装
npm install @doola/js
包含类型脚本。 一揽子措施是无害环境管理和共同JS,有两个切入点: @doola/js
仅在浏览器中运行,以及 @doola/js/server 运行在您的服务器上, 在节点 18 或 18 或 任何
使用网络标准的运行时间 fetch。 。 。 .
1. 在您的服务器上装入一个会话
你的服务器是你秘密钥匙生活的唯一地点 添加一个认证的路由
创建客户会话
给签到的客户。 它不需要数据库. createSessionHandler 构建路径: 它
使用网络标准 Request 返回 a Response。这使得它成为一个 Next.js 路由处理器
和在Remix中装有一行的包装器(action霍诺 邦 德诺 和克云弗莱尔工人,
地点 process.env 需求 nodejs_compat 旗帜.
// POST /doola-session
import { createSessionHandler } from '@doola/js/server';
export const POST = createSessionHandler({
// Your dk_ secret key. Its prefix selects the API host. A missing key is refused per
// request, so `next build` passes without it, and a pk_ key throws here.
apiKey: process.env.DOOLA_API_KEY,
// Return null when nobody is signed in. The route answers 401, and the loader reports
// partner_session_expired.
getCustomer: async (request) => {
const user = await getSignedInUser(request); // your own auth
// externalCustomerId is optional but recommended: it is matched before the email, so a
// customer who changes their email with you stays the same doola customer.
return user ? { email: user.email, externalCustomerId: user.id } : null;
},
// The browser gets the status, plus doola's error code when doola refused the customer.
// This says why, for your logs: a revoked key, an outage, or a field doola rejected.
onFailure: (failure) => console.error('doola session failed', failure),
});
该标志就是一个客户,在几分钟内失效。 装填器再次呼叫您的路线
更新它,所以杜拉会话 永远不会超过你的登录。 保护路线与其它路线一样
认证 POST包括你的CSRF保护.
快取、快取和其他语言: 创建会话。 。 。 .
2. 在浏览器中挂载
import { loadDoola } from '@doola/js';
const doola = await loadDoola({
publishableKey: 'pk_live_…',
// Called on mount, on every renewal and on Try again. Always fetch a fresh session.
fetchAccessToken: async () => {
const r = await fetch('/doola-session', { method: 'POST' });
if (!r.ok) {
// Reject with the status and doola's error code: the loader maps them to error types.
const { code } = await r.json().catch(() => ({}));
throw Object.assign(new Error('doola session'), { status: r.status, code });
}
return r.json();
},
// Can fire more than once, so keep it idempotent.
onAuthError: (error) => {
if (error.type === 'partner_session_expired') location.assign('/login');
if (error.type === 'email_in_use' || error.type === 'customer_revoked') showSupportMessage();
// Your mapping between users and externalCustomerId, not the customer's to fix.
if (error.type === 'external_id_conflict') console.error('doola session conflict', error);
},
// The customer submitted the wizard. Start your checkout for this company.
onFormed: ({ companyId }) => startCheckout(companyId),
});
// Mount into an element on your page: <div id="doola"></div>
const element = doola.create();
document.getElementById('doola')!.append(element);
create() 没有争论。 应用程序决定从客户状态显示什么:巫师
对于新客户,他们的公司一旦存在.
每页保留一个实例: 选项由第一个选项固定 loadDoola() 电话 框架,
电话上的签名和全屏模式 : 装入了SDK。 。 。 .
3. 接受付款,然后确认
onFormed 故意给你公司身份证明 而不是别的 任何送到你身边的东西
页面的JavaScript可以在 DevTools 中被编辑,所以您的服务器可以处理欠下的内容. 当你
退出开始 :
- 把公司找来 用您的密钥, 使用
找一个公司。仅装入
时
formationSubmissionStatus实值AWAITING_PAYMENT。 。 。 . - 检查它属于注册客户. 通过公司
doolaCustomerId改为 找一个客人 比较 页:1email。 。 。 . - 在您的服务器上定价 从公司
state, (中文(简体) ),entityType页:1services, (中文(简体) ), 加上国家收费 列出国家申报费。 。 。 . 从未从浏览器读取价格 . - 充电,然后确认 与 确认付款。 。 。 . 在你做之前,任何文件都不会归档:
// On your server, after the charge succeeds.
const DOOLA_API = 'https://api.doola.com'; // https://api.test.doola.com with a dk_test_ key
function doolaKey(): string {
const key = process.env.DOOLA_API_KEY; // your dk_ secret key
if (!key) throw new Error('DOOLA_API_KEY is not set');
return key;
}
async function confirmPayment(companyId: string, paymentReference: string): Promise<void> {
const path = `/v1/partner/companies/${encodeURIComponent(companyId)}/payment-confirmed`;
const r = await fetch(`${DOOLA_API}${path}`, {
method: 'POST',
headers: { authorization: doolaKey(), 'content-type': 'application/json' },
// Your own reference (a payment intent id, an order id). Logged, never verified.
body: JSON.stringify({ partnerReference: paymentReference }),
});
// Idempotent, so a failed call is safe to retry.
if (!r.ok) throw new Error(`doola payment-confirmed failed with ${r.status}`);
}
onFormed 例如当创始人回到一个没有报酬的公司时
组织起来并要求支付。 按键命令 companyId 所以你从不收两次钱.
在您确认后, 替换您安装在步骤 2: element.replaceWith(doola.create())。 。 。 .
它的支付屏幕不监视您的确认, 所以只有一个新元素显示创建者
他们的公司。 每个 create() 是一个单独的iframe, 所以永远不要在旧的旁边附加第二个.
从那时起,合伙人API 网络用户 告诉你如何
阵型开始.
边际案件、退款及对账: 收钱。 。 。 .
文档
| 读取 | 对于 |
|---|---|
| 快速启动 | 工作嵌入和测试费大约15分钟 |
| 如何运作 | 关键、会话和形成周期 |
| 收钱 | 您的离职,确认电话和每一个边缘案件 |
| 客户参考 | 每一个选项、方法和召回 |
| 服务器参考 | @doola/js/server 和合作伙伴 API 结尾 |
| 错误 | onAuthError, (中文(简体) ), onLoadError 和怎么办 每一个 |
| 安全和数据 | 内容安全政策、信任类型和数据流动 |
| 测试 | 测试环境和沙盒游乐场 |
| 启用清单 | 所有要检查的,在直播键之前 |
| 合作伙伴 API | 支付后需采取的行动 |
版本
@doola/js 随取出
更改日志 列表中
释放。 装载器在 js.doola.com/v1 更新并保持与每个
@doola/js 释放在主, 所以修复到达你的站点 不升级或部署.
支助和安全
- 问题: 工程学@ doola.com,或见 支助。 。 。 .
- 如本报告所述,私下报告脆弱性 警卫从不公开 问题.