Payout Components SDK
1. 概述
Midasbuy Payout Components SDK 是一个统一 Payout Components 加载器。该 SDK 提供开箱即用且可定制的组件,用于处理国际汇款与收款人信息管理。
2. 接入步骤
步骤 1. 安装并引入 SDK
# npm
npm install @txgw/payout-components
# pnpm
pnpm add @txgw/payout-components
# yarn
yarn add @txgw/payout-components
import { init, createElement } from "@txgw/payout-components";
步骤 2. 初始化 SDK
2.1 生成 code_verifier
在调用 SDK 初始化前,需要在前端生成 PKCE code_verifier。该值在交换授权码时是必需的,并遵循 RFC 7636 第 4 节。示例如下:
const dec2hex = (dec: number) => {
return ("0" + dec.toString(16)).slice(-2);
};
const generateCodeVerifier = () => {
const length = Math.random() * (129 - 43) + 43;
const array = new Uint32Array(length / 2);
window.crypto.getRandomValues(array);
return Array.from(array, dec2hex).join("");
};
const codeVerifier = generateCodeVerifier();
请将 codeVerifier 通过安全通道发送到服务端以便后续生成 code_challenge。
请先在服务端安装
js-base64以便对哈希结果进行编码:
npm install js-base64
import crypto from "node:crypto";
import { Base64 } from "js-base64";
const sha256 = (value: string) => {
const hash = crypto.createHash("sha256");
hash.update(value);
return hash.digest();
};
const generateCodeChallenge = (codeVerifier: string) => {
const digest = sha256(codeVerifier);
return Base64.fromUint8Array(new Uint8Array(digest), true); // base64url 编码
};
const codeVerifier = "34d7704c787a698409dc581e22b11ff48d634d249e7f242dcb14"; // from request
const codeChallenge = generateCodeChallenge(codeVerifier);
请在前端安全保存 code_verifier,服务端仅持有生成出的 code_challenge 用于授权请求。
2.2 配置服务端获取授权码
页面加载后,服务端需要调用 GetAuthorizationCode 接口,并携带客户端生成的 code_challenge。示例请求体如下:
{
"merchant_id": "{{merchant_id}}",
"sub_merchant_id": "{{sub_merchant_id}}",
"code_challenge": "xxxxx_obfuscated_xxxxx",
"scope": ["r:midas:beneficiary_form"]
}
2.3 初始化 SDK
import { init, createElement } from "@txgw/payout-components";
import getAuthCode from "getAuthCode"; // 加载获取 authCode 实现
const { authCode, domain } = getAuthCode();
// 使用鉴权信息进行初始化
init({
authCode,
domain,
codeVerifier: "your_code_verifier",
});
2.4 导入组件样式
为确保组件正确渲染,你需要导入组件的 CSS 样式。可以通过以下两种方式之一导入:
方式 1:在 CSS 文件中导入(如 index.css)
@import "@txgw/payout-components/index.css";
方式 2:在 JavaScript 文件中导入
import "@txgw/payout-components/index.css";
步骤 3. 创建并挂载组件
3.1 渲染带有转账方式选择的组件
// 创建收款人表单组件
const beneficiaryForm = createElement("beneficiaryForm");
// 将组件挂载到指定 DOM 元素
beneficiaryForm.mount(document.querySelector("#form-container"));
// 监听表单提交
beneficiaryForm.on("submit", (data) => {
console.log("Form submitted:", data);
// 处理提交的收款人数据
});
3.2 渲染带有预设转账方式的组件
// 创建收款人表单组件
const beneficiaryForm = createElement("beneficiaryForm", {
defaultValues: {
region_code: "US",
currency: "USD",
payment_method: "LOCAL",
payout_type: "B2P",
},
customizations: {
layout: [
{
name: "bankDetails",
hidden: true,
},
],
},
});
// 将组件挂载到指定 DOM 元素
beneficiaryForm.mount(document.querySelector("#form-container"));
// 监听表单提交
beneficiaryForm.on("submit", (data) => {
console.log("Form submitted:", data);
// 处理提交的收款人数据
});
4. API 参考
4.1 init(options: InitOptions)
使用鉴权信息初始化 SDK。
参数:
options.authCode(string):authCodeoptions.domain(string):API 域名,用于请求后续数据,如付款方式信息options.codeVerifier(string): 请求 auth token 时用到的code_verifier字段
4.2 createElement(type, options?)
创建一个新的组件实例。
参数:
type(string):组件类型(当前支持'beneficiaryForm')options(object):组件相关可选项
返回: SDKComponent 实例
4.3 SDKComponent 方法
4.3.1 mount(container: Element)
将组件挂载到某个 DOM 容器。
4.3.2 unmount()
卸载组件并清理资源。
4.3.3 on(eventType, handler)
订阅组件事件。
4.3.4 off(eventType, handler?)
取消订阅组件事件。
4.3.5 isMounted()
返回组件当前是否处于挂载状态。
5. BeneficiaryForm 组件
beneficiaryForm 组件提供用于采集收款人信息的动态表单。
5.1 配置项(Options)
interface BeneficiaryFormOptions {
defaultValues?: {
region_code?: string; // 国家/地区代码(如 'US'、'ID')
currency?: string; // 币种代码(如 'USD'、'IDR')
payment_method?: string; // 转账方式(如 'LOCAL'、'SWIFT')
payout_type?: "B2P"; // 出款类型(当前仅支持 B2P)
};
customizations?: {
layout?: Array<{
name: "bankDetails";
hidden?: boolean;
}>;
};
}
5.2 表单流程
- 国家与币种选择:用户选择开户国家/地区与账户币种
- 转账方式选择:基于国家/币种展示可用转账方式
- 收款人信息:依据所选转账方式动态展示所需字段
- 提交:校验并提交表单数据
5.3 示例数据结构
表单提交后,你将收到如下格式的数据:
{
"beneficiary": {
"address": {
"country": "US",
"street_address": "123 Main St"
},
"bank_account": {
"account_name": "John Doe",
"account_number": "1234567890"
},
"entity_details": {
"mobile_number": "+1234567890"
}
}
}