在日常开发中,调用第三方开放平台接口时,直接对接往往需要处理繁琐的参数校验、签名加密、环境切换等问题。本文就以拉卡拉开放平台为例,手把手教你开发一个 TypeScript SDK 包,从项目初始化到发布上线,每一步都详细讲解,让你轻松掌握 SDK 开发技巧。
一、 准备工作
1、 环境搭建
首先,确保你的开发环境中已经安装了 Node.js 和 npm。可以通过以下命令检查版本:
node -v
npm -v
2、 初始化项目
创建一个项目文件夹,比如lkl-zf-bs-laop-ts-sdk,然后进入文件夹初始化项目:
bash
mkdir lkl-zf-bs-laop-ts-sdk
cd lkl-zf-bs-laop-ts-sdk
npm init -y
执行后会生成一个package.json文件,包含了项目的基本信息
3、 安装依赖
sql
npm install typescript eslint prettier @types/node --save-dev
# 安装接口请求库axios
npm install axios --save
4、 配置TypeScript
在项目根目录下创建tsconfig.json文件,配置 TypeScript 编译选项:
json
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true
}
}
这里declaration设为true,会自动生成类型声明文件,方便其他开发者使用时获得类型提示。
5、 配置 ESLint 和 Prettier
ESLint 用于代码检查,Prettier 用于代码格式化,让代码风格保持一致。
初始化 ESLint 配置:
csharp
npx eslint --init
按照提示选择合适的配置,比如选择 Node.js 环境、TypeScript 语言等。 然后创建.prettierrc文件:
json
{
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 80,
"tabWidth": 2
}
二、 项目结构设计
参考拉卡拉开放平台 PHP SDK的结构,我设计 TypeScript SDK 的目录结构如下:
scss
lkl-zf-bs-laop-ts-sdk/
├── src/
│ ├── v3/
│ │ ├── src/
│ │ │ ├── Configuration.ts // 配置处理
│ │ │ ├── LakalaApi.ts // API调用核心
│ │ │ └── utils/ // 工具函数
│ │ └── test/ // 测试代码
│ └── index.ts // 入口文件
├── dist/ // 编译输出目录
├── .eslintrc.js
├── .prettierrc
├── tsconfig.json
└── package.json
三、 核心功能实现
1、 配置类实现
拉卡拉开放平台 SDK 需要一些配置信息,如 appId、密钥路径等。我们创建Configuration类来管理这些配置。 在src/v3/src/Configuration.ts中:
ini
export class Configuration {
appDebug: boolean;
appId: string;
serialNo: string;
hostPro: string;
hostTest: string;
sm4Key: string;
merchantPrivateKeyPath: string;
lklCertificatePath: string;
/**
* 初始化配置
* @param config 配置对象
*/
constructor(config?: Partial<Configuration>) {
// 默认配置
this.appDebug = false;
this.appId = '';
this.serialNo = '';
this.hostPro = 'https://s2.lakala.com';
this.hostTest = 'https://test.wsmsd.cn/sit';
this.sm4Key = '';
this.merchantPrivateKeyPath = '';
this.lklCertificatePath = '';
// 合并用户配置
if (config) {
Object.assign(this, config);
}
}
/**
* 获取当前环境的主机地址
*/
getHost(): string {
return this.appDebug ? this.hostTest : this.hostPro;
}
}
2、 API调用核心类
创建LakalaApi类,封装接口调用的逻辑,包括请求发送、参数处理等。 在src/v3/src/LakalaApi.ts中:
typescript
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { Configuration } from './Configuration';
export class LakalaApi {
private config: Configuration;
private axiosInstance: AxiosInstance;
constructor(config: Configuration) {
this.config = config;
this.axiosInstance = axios.create({
timeout: 5000,
headers: {
'Content-Type': 'application/json',
'User-Agent': 'lkl-zf-bs-laop-ts-sdk/1.0.0'
}
});
}
/**
* 发送带body的POST请求
* @param path 接口路径
* @param body 请求体
* @returns 响应结果
*/
async apiWithBody<T = any>(path: string, body: any): Promise<AxiosResponse<T>> {
const url = `${this.config.getHost()}${path}`;
try {
const response = await this.axiosInstance.post<T>(url, body);
return response;
} catch (error) {
console.error('API请求失败:', error);
throw error;
}
}
}
3、 工具函数
在src/v3/src/utils/index.ts中,我们可以添加一些常用的工具函数,比如时间格式化:
scss
/**
* 生成当前时间戳,格式YYYYMMDDHHmmss
*/
export function getCurrentTime(): string {
const date = new Date();
return date.getFullYear().toString() +
padZero(date.getMonth() + 1) +
padZero(date.getDate()) +
padZero(date.getHours()) +
padZero(date.getMinutes()) +
padZero(date.getSeconds());
}
/**
* 数字补零
* @param num 数字
* @returns 补零后的字符串
*/
function padZero(num: number): string {
return num < 10 ? `0${num}` : num.toString();
}
四、 测试用例编写
为了保证 SDK 的正确性,我们编写测试用例。这里使用 Jest 作为测试框架。
1、 安装Jest
sql
npm install jest @types/jest ts-jest --save-dev
在package.json中添加测试脚本:
json
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
创建jest.config.js:
java
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/src/**/*.test.ts']
};
2、 编写查询交易测试用例
在src/v3/test/tradeQuery.test.ts中:
javascript
import { Configuration } from '../src/Configuration';
import { LakalaApi } from '../src/LakalaApi';
import { getCurrentTime } from '../src/utils';
describe('交易查询接口测试', () => {
let api: LakalaApi;
beforeAll(() => {
// 初始化配置,实际使用时替换为你的配置
const config = new Configuration({
appDebug: true, // 测试环境
appId: '你的appId',
serialNo: '你的serialNo'
});
api = new LakalaApi(config);
});
it('应该成功查询交易', async () => {
const body = {
req_time: getCurrentTime(),
version: '3.0',
req_data: {
merchant_no: '822290070111135',
term_no: '29034705',
out_trade_no: `TEST${getCurrentTime()}`,
trade_no: ''
}
};
const response = await api.apiWithBody('/api/v3/labs/query/tradequery', body);
expect(response.status).toBe(200);
console.log('查询结果:', response.data);
});
});
五、 编译与运行
- 编译代码
在package.json中添加编译脚本:
json
"scripts": {
"build": "tsc",
"test": "jest",
"test:watch": "jest --watch"
}
执行编译:
arduino
npm run build
编译后的代码会输出到dist目录。
- 运行测试
bash
npm test
如果一切正常,会看到测试通过的结果,并输出查询到的交易信息。
六、 使用示例
其他开发者安装 SDK 后,可以这样使用:
javascript
import { Configuration, LakalaApi, getCurrentTime } from 'lkl-zf-bs-laop-ts-sdk';
// 初始化配置
const config = new Configuration({
appId: '你的appId',
serialNo: '你的serialNo',
appDebug: false // 生产环境
});
const api = new LakalaApi(config);
// 调用接口
async function queryTrade() {
try {
const body = {
req_time: getCurrentTime(),
version: '3.0',
req_data: {
merchant_no: '商户号',
out_trade_no: '订单号'
}
};
const response = await api.apiWithBody('/api/v3/labs/query/tradequery', body);
console.log('交易信息:', response.data);
} catch (error) {
console.error('查询失败:', error);
}
}
queryTrade();
总结
本文详细介绍了如何将拉卡拉开放平台的支付接口包装成 TypeScript SDK 的开发全过程,从环境搭建到核心功能实现,再到测试。通过这个过程,你不仅能得到一个可用的 SDK,还能掌握 TypeScript SDK 开发的通用方法。
在实际开发中,还可以根据拉卡拉开放平台的其他接口,扩展 SDK 的功能,比如退款、订单创建等。同时,要注意处理加密、签名等安全相关的逻辑,确保接口调用的安全性。
希望这篇教程对你有帮助,如果你在开发过程中遇到问题,可以参考拉卡拉开放平台官方文档或留言讨论。