🚀 PayBySquare 生成器
PayBySquare 生成器是一個全面的 Node.js/TypeScript 庫,用於生成、解碼和驗證支付二維碼。PayBySquare 是斯洛伐克銀行協會(SBA)採用的支付二維碼國家標準。

✨ 主要特性
生成功能
- ✅ 基於簡單的 JSON 接口
- ✅ 生成 PNG 格式的二維碼緩衝區或文件
- ✅ 支持所有 PayBySquare 支付字段
- ✅ 可自定義二維碼樣式(尺寸、顏色、糾錯級別)
解碼功能
- ✅ 從 PNG 緩衝區解碼 PayBySquare 二維碼
- ✅ 將支付數據提取為 JSON 格式
- ✅ 往返驗證(無損編碼/解碼)
合規性與驗證
- ✅ IBAN 校驗和驗證(mod - 97 算法)
- ✅ 字段格式合規性檢查
- ✅ 銀行標準驗證(BIC/SWIFT、貨幣代碼)
- ✅ 帶有錯誤嚴重程度級別的詳細合規性報告
開發特性
- ✅ 完全支持 TypeScript 並提供類型定義
- ✅ 零 UI 依賴 - 純基於函數的接口
- ✅ ESM 模塊格式(Node.js >= 18)
- ✅ 經過全面測試(96 個單元測試,覆蓋率超過 90%)
- ✅ MCP 服務器 - 可與 Claude Desktop 和其他 MCP 客戶端配合使用
📦 安裝指南
npm install paybysquare-generator
要求
- Node.js >= 18.0.0
- 支持 ESM 模塊
🚀 快速開始
import { generatePayBySquare } from 'paybysquare-generator';
const buffer = await generatePayBySquare({
iban: 'SK9611000000002918599669',
beneficiaryName: 'John Doe',
amount: 100.50,
currency: 'EUR',
variableSymbol: '123456',
paymentNote: 'Invoice payment'
});
📚 詳細文檔
API 參考
generatePayBySquare(input, options?)
根據支付數據生成 PayBySquare 二維碼 PNG 圖像。
參數:
input: PayBySquareInput - 支付數據(見下文)
options?: GenerationOptions - 可選的二維碼生成選項
返回值: Promise<Buffer> - 以 Node.js Buffer 形式的 PNG 圖像
拋出錯誤:
ValidationError - 如果輸入數據無效
EncodingError - 如果支付數據編碼失敗
GenerationError - 如果二維碼 PNG 生成失敗
generatePayBySquareToFile(input, filePath, options?)
生成 PayBySquare 二維碼並保存到文件。
參數:
input: PayBySquareInput - 支付數據
filePath: string - 保存 PNG 文件的路徑
options?: GenerationOptions - 可選的二維碼生成選項
返回值: Promise<void>
decodePayBySquare(buffer)
從 PNG 緩衝區解碼 PayBySquare 二維碼,還原為支付數據。
參數:
buffer: Buffer - 包含 PayBySquare 二維碼的 PNG 圖像緩衝區
返回值: Promise<PayBySquareInput> - 解碼後的支付數據
拋出錯誤:
DecodingError - 如果二維碼無法讀取或解碼
示例:
import { readFile } from 'fs/promises';
import { decodePayBySquare } from 'paybysquare-generator';
const qrBuffer = await readFile('./payment-qr.png');
const paymentData = await decodePayBySquare(qrBuffer);
console.log(paymentData.iban, paymentData.amount);
isCompliant(input)
對支付數據進行簡單的合規性檢查,返回通過或失敗結果。
參數:
input: PayBySquareInput - 要驗證的支付數據
返回值: boolean - 如果完全合規返回 true,否則返回 false
示例:
import { isCompliant } from 'paybysquare-generator';
const isValid = isCompliant({
iban: 'SK9611000000002918599669',
beneficiaryName: 'Test'
});
console.log(isValid);
checkCompliance(input)
提供詳細的合規性報告,包含錯誤、警告和嚴重程度級別。
參數:
input: PayBySquareInput - 要驗證的支付數據
返回值: Promise<ComplianceResult> - 結構化的合規性報告
示例:
import { checkCompliance } from 'paybysquare-generator';
const report = await checkCompliance(paymentData);
if (!report.isCompliant) {
console.log('錯誤:', report.errors);
console.log('警告:', report.warnings);
console.log('詳情:', report.details);
}
ComplianceResult 接口:
interface ComplianceResult {
isCompliant: boolean;
errors: ComplianceIssue[];
warnings: ComplianceIssue[];
details: {
ibanValid: boolean;
fieldsValid: boolean;
bankingStandardsValid: boolean;
totalIssues: number;
};
}
interface ComplianceIssue {
type: 'error' | 'warning';
field: string;
message: string;
severity: 'critical' | 'major' | 'minor';
}
checkQRCompliance(buffer)
直接從 PNG 緩衝區檢查二維碼的合規性。
參數:
buffer: Buffer - 包含二維碼的 PNG 圖像緩衝區
返回值: Promise<ComplianceResult> - 解碼數據的合規性報告
verifyRoundTrip(input)
驗證支付數據在編碼和解碼過程中是否無損。
參數:
input: PayBySquareInput - 原始支付數據
返回值: Promise<RoundTripResult> - 往返驗證結果
示例:
import { verifyRoundTrip } from 'paybysquare-generator';
const result = await verifyRoundTrip(originalData);
if (!result.isLossless) {
console.log('檢測到數據丟失:', result.differences);
}
RoundTripResult 接口:
interface RoundTripResult {
isLossless: boolean;
differences: FieldDifference[];
input: PayBySquareInput;
decoded: PayBySquareInput;
}
interface FieldDifference {
field: string;
original: any;
decoded: any;
}
輸入數據格式
PayBySquareInput
interface PayBySquareInput {
iban: string;
beneficiaryName: string;
amount?: number;
currency?: string;
variableSymbol?: string;
constantSymbol?: string;
specificSymbol?: string;
paymentNote?: string;
dueDate?: string;
swift?: string;
originatorReference?: string;
beneficiaryAddress?: {
street?: string;
city?: string;
};
}
GenerationOptions
interface GenerationOptions {
width?: number;
margin?: number;
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
color?: {
dark?: string;
light?: string;
};
removeAccents?: boolean;
}
💻 使用示例
最小支付示例
import { generatePayBySquare } from 'paybysquare-generator';
import { writeFile } from 'fs/promises';
const buffer = await generatePayBySquare({
iban: 'SK9611000000002918599669',
beneficiaryName: 'John Doe'
});
await writeFile('payment.png', buffer);
包含所有字段的完整支付示例
const buffer = await generatePayBySquare({
iban: 'SK9611000000002918599669',
beneficiaryName: 'Acme Corporation',
amount: 150.50,
currency: 'EUR',
variableSymbol: '2026001',
constantSymbol: '0308',
paymentNote: 'Invoice #2026001',
dueDate: '2026-02-15',
swift: 'TATRSKBX',
originatorReference: 'REF-2026-001',
beneficiaryAddress: {
street: 'Business Street 123',
city: 'Bratislava 81108'
}
});
捐贈示例(無固定金額)
const buffer = await generatePayBySquare({
iban: 'SK9611000000002918599669',
beneficiaryName: 'Charity Organization',
paymentNote: 'Voluntary donation'
});
自定義二維碼樣式示例
const buffer = await generatePayBySquare(
{
iban: 'SK9611000000002918599669',
beneficiaryName: 'Shop Name',
amount: 99.99
},
{
width: 500,
margin: 2,
errorCorrectionLevel: 'H',
color: {
dark: '#1E40AF',
light: '#FFFFFF'
}
}
);
直接保存到文件示例
import { generatePayBySquareToFile } from 'paybysquare-generator';
await generatePayBySquareToFile(
{
iban: 'SK9611000000002918599669',
beneficiaryName: 'Recipient',
amount: 25.00
},
'./payment.png'
);
錯誤處理示例
import {
generatePayBySquare,
ValidationError,
EncodingError,
GenerationError
} from 'paybysquare-generator';
try {
const buffer = await generatePayBySquare({
iban: 'INVALID',
beneficiaryName: 'Test'
});
} catch (error) {
if (error instanceof ValidationError) {
console.error('輸入無效:', error.message);
} else if (error instanceof EncodingError) {
console.error('編碼失敗:', error.message);
} else if (error instanceof GenerationError) {
console.error('二維碼生成失敗:', error.message);
}
}
解碼二維碼示例
import { decodePayBySquare } from 'paybysquare-generator';
import { readFile } from 'fs/promises';
const qrBuffer = await readFile('./payment-qr.png');
const paymentData = await decodePayBySquare(qrBuffer);
console.log('IBAN:', paymentData.iban);
console.log('收款人:', paymentData.beneficiaryName);
console.log('金額:', paymentData.amount, paymentData.currency);
console.log('可變符號:', paymentData.variableSymbol);
簡單合規性檢查示例
import { isCompliant } from 'paybysquare-generator';
const paymentData = {
iban: 'SK9611000000002918599669',
beneficiaryName: 'Test Merchant',
amount: 100,
currency: 'EUR'
};
if (isCompliant(paymentData)) {
console.log('✓ 支付數據有效');
} else {
console.log('✗ 支付數據存在問題');
}
詳細合規性報告示例
import { checkCompliance } from 'paybysquare-generator';
const paymentData = {
iban: 'SK9999999999999999999999',
beneficiaryName: 'Test',
amount: -50,
variableSymbol: 'ABC123',
swift: 'INVALID'
};
const report = await checkCompliance(paymentData);
console.log('是否合規:', report.isCompliant);
console.log('\n錯誤:');
report.errors.forEach(err => {
console.log(` [${err.severity}] ${err.field}: ${err.message}`);
});
console.log('\n驗證詳情:');
console.log(' IBAN 是否有效:', report.details.ibanValid);
console.log(' 字段是否有效:', report.details.fieldsValid);
console.log(' 銀行標準是否有效:', report.details.bankingStandardsValid);
console.log(' 總問題數:', report.details.totalIssues);
往返驗證示例
import { verifyRoundTrip } from 'paybysquare-generator';
const originalData = {
iban: 'SK9611000000002918599669',
beneficiaryName: 'Test Company',
amount: 250.75,
currency: 'EUR',
variableSymbol: '123456',
paymentNote: 'Testing round-trip'
};
const result = await verifyRoundTrip(originalData);
if (result.isLossless) {
console.log('✓ 數據在編碼/解碼循環中完美保留!');
} else {
console.log('✗ 檢測到數據丟失:');
result.differences.forEach(diff => {
console.log(` ${diff.field}:`);
console.log(` 原始值: ${diff.original}`);
console.log(` 解碼後的值: ${diff.decoded}`);
});
}
🔧 技術細節
驗證規則
該庫對所有輸入進行全面驗證:
- IBAN:必需,必須是有效格式(2 位國家代碼 + 2 位數字 + 11 - 30 位字母數字)
- 收款人姓名:必需,最多 70 個字符
- 金額:可選,提供時必須為正數且有限
- 貨幣:可選,必須是 3 位 ISO 4217 代碼(默認: EUR)
- 可變符號:可選,僅 1 - 10 位數字
- 常量符號:可選,僅 1 - 4 位數字
- 特定符號:可選,僅 1 - 10 位數字
- 支付備註:可選,最多 140 個字符
- 到期日期:可選,必須是 ISO 8601 格式(YYYY - MM - DD)
- 地址字段:可選,每個最多 70 個字符
運行示例
倉庫中包含完整的示例:
git clone https://github.com/yourusername/paybysquare-generator
cd paybysquare-generator
npm install
npm run example
這將生成幾個不同用例的示例二維碼。
運行測試
npm test
npm run test:watch
npm run test:coverage
從源代碼構建
npm run build
PayBySquare 標準
該庫實現了斯洛伐克銀行協會(SBA)定義的 PayBySquare 標準 1.1.0 版本。更多信息:
依賴項
生產環境依賴
TypeScript 支持
該庫使用 TypeScript 編寫,幷包含完整的類型定義。所有類型都已導出,方便使用:
import type {
PayBySquareInput,
BeneficiaryAddress,
GenerationOptions,
ComplianceResult,
ComplianceIssue,
ComplianceDetails,
RoundTripResult,
FieldDifference
} from 'paybysquare-generator';
import {
PayBySquareError,
ValidationError,
EncodingError,
GenerationError,
DecodingError
} from 'paybysquare-generator';
MCP 服務器
該庫包含一個 模型上下文協議(MCP)服務器,可將所有功能暴露給 Claude 和其他 MCP 客戶端。
可用工具
generate_paybysquare - 根據支付數據生成二維碼(保存到文件,返回文件路徑)
- 必需參數:
beneficiaryName(收款人的全名)
- 建議參數:
swift(國際轉賬的 BIC 代碼)
- 可選參數:
outputDirectory(自定義保存位置,默認: ~/paybysquare-qr-codes/)
decode_paybysquare - 將二維碼解碼為支付數據(從 base64 編碼的 PNG 圖像)
check_compliance - 驗證支付數據的合規性,並提供詳細的錯誤報告
verify_roundtrip - 驗證無損編碼/解碼(數據完整性檢查)
快速設置
- 構建服務器:
npm run build:mcp
- 配置 Claude Desktop:
在
claude_desktop_config.json 中添加以下內容:{
"mcpServers": {
"paybysquare": {
"command": "node",
"args": ["/absolute/path/to/paybysquare/dist/mcp-server/index.js"]
}
}
}
- 重啟 Claude Desktop
在 Claude 中的示例用法
配置完成後,你可以使用自然語言進行操作:
為以下信息生成 PayBySquare 二維碼:
- IBAN: SK9611000000002918599669
- 收款人: John Doe
- 金額: 100.50 EUR
- SWIFT: TATRSKBX
- 支付備註: Invoice #12345
Claude 將生成二維碼並保存到文件,返回:
✓ 二維碼生成成功!
文件保存路徑: /Users/username/paybysquare-qr-codes/paybysquare-1705331234567-a3f2.png
解碼這個 PayBySquare 二維碼並告訴我支付詳情
[上傳圖像]
檢查以下支付數據是否符合銀行標準:
- IBAN: SK9611000000002918599669
- 收款人: Test Company
- 金額: 250 EUR
- SWIFT: TATRSKBX
注意: 二維碼默認自動保存到 ~/paybysquare-qr-codes/ 目錄。你可以使用 outputDirectory 選項指定自定義目錄。
詳細的 MCP 服務器文檔請參閱 mcp-server/README.md。
📄 許可證
本項目採用 MIT 許可證。
貢獻
歡迎貢獻代碼!請隨時提交拉取請求。
相關項目
支持
如果你遇到任何問題或有疑問,請在 GitHub 上 提交問題。
為斯洛伐克開發者社區用心打造 ❤️