PayBySquare生成器
一个全面的Node.js/TypeScript库 PayBySquare 二维码:生成、解码和验证支付二维码。PayBySquare是斯洛伐克银行协会(SBA)采用的斯洛伐克国家支付二维码标准。
](https://www.npmjs.com/package/paybysquare-generator) 
特性
生成
- ✅ 简单的基于JSON的API
- ✅ 生成二维码作为PNG缓冲区或文件
- ✅ 支持所有PayBySquare支付字段
- ✅ 可定制的二维码样式(大小、颜色、纠错)
解码
- ✅ 从PNG缓冲区解码PayBySquare二维码
- ✅ 将支付数据提取回JSON格式
- ✅ 往返验证(无损编码/解码)
合规与验证
- ✅ IBAN校验和验证(mod-97算法)
- ✅ 字段格式合规性检查
- ✅ 银行标准验证(BIC/SWIFT、货币代码)
- ✅ 包含错误严重程度的详细合规报告
发展
- ✅ 完全支持TypeScript和类型定义
- ✅ 零UI依赖-纯基于功能的API
- ✅ ESM模块格式(Node.js>=18)
- ✅ 经过全面测试(96个单元测试,覆盖率超过90%)
- ✅ MCP服务器 -与Claude Desktop和其他MCP客户端一起使用
突破性变化
MCP服务器v1.1.0(2026年1月)
⚠️ 突破性变化: generate_paybysquare 该工具现在返回文件路径,而不是base64编码的图像
MCP服务器的 generate_paybysquare 该工具已经更新,可以将二维码保存为文件并返回文件路径,而不是以base64返回二进制数据。此更改提供了更好的LLM上下文效率,并使生成的QR码持久化以供以后使用。
之前(v1.0.0):
{
"success": true,
"imageBase64": "iVBORw0KGgoAAAANSUhEUg...",
"size": 12345,
"message": "QR code generated successfully"
}在(v1.1.0)之后:
{
"success": true,
"filePath": "/Users/username/paybysquare-qr-codes/paybysquare-1705331234567-a3f2.png",
"fileName": "paybysquare-1705331234567-a3f2.png",
"message": "QR code generated and saved successfully"
}迁移:
- 二维码现在保存到
~/paybysquare-qr-codes/默认情况下 - 使用
outputDirectory指定自定义保存位置的选项 - 使用返回的
filePath - 注:核心库函数(
generatePayBySquare,generatePayBySquareToFile)保持不变
增强文档:
- 工具描述现在强调
beneficiaryName是 必需 swift(BIC代码)现在标记为 推荐 国际支付
优点:
- 减少令牌使用(文件路径与base64数据)
- 更好的LLM上下文效率
- 持久二维码供以后参考
- 更容易与基于文件的工作流集成
注: 此更改仅影响MCP服务器。核心Node.js/TypeScript库API保持完全向后兼容。
安装
npm install paybysquare-generator需求
- Node.js>=18.0.0
- ESM模块支持
快速开始
import { generatePayBySquare } from 'paybysquare-generator';
// Generate a payment QR code
const buffer = await generatePayBySquare({
iban: 'SK9611000000002918599669',
beneficiaryName: 'John Doe',
amount: 100.50,
currency: 'EUR',
variableSymbol: '123456',
paymentNote: 'Invoice payment'
});
// buffer is a PNG image as Buffer - save it, send it, etc.API 参考
generatePayBySquare(input, options?)
根据支付数据生成PayBySquare二维码PNG。
参数:
input: PayBySquareInput-付款数据(见下文)options?: GenerationOptions-可选二维码生成选项
退货: Promise -PNG图像作为Node.js缓冲区
投掷:
ValidationError-如果输入数据无效EncodingError-如果支付数据编码失败GenerationError-如果二维码PNG生成失败
generatePayBySquareToFile(input, filePath, options?)
生成PayBySquare二维码并将其保存到文件中。
参数:
input: PayBySquareInput-付款数据filePath: string-保存PNG文件的路径options?: GenerationOptions-可选二维码生成选项
退货: Promise
decodePayBySquare(buffer)
将PayBySquare二维码从PNG缓冲区解码回支付数据。
参数:
buffer: Buffer-包含PayBySquare二维码的PNG图像缓冲区
退货: Promise -已解码的支付数据
投掷:
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); // true or falsecheckCompliance(input)
详细的合规报告,包括错误、警告和严重程度。
参数:
input: PayBySquareInput-要验证的付款数据
退货: Promise -结构化合规报告
例子:
import { checkCompliance } from 'paybysquare-generator';
const report = await checkCompliance(paymentData);
if (!report.isCompliant) {
console.log('Errors:', report.errors);
console.log('Warnings:', report.warnings);
console.log('Details:', report.details);
}合规性结果:
interface ComplianceResult {
isCompliant: boolean;
errors: ComplianceIssue[]; // Critical issues preventing payment
warnings: ComplianceIssue[]; // Non-critical issues
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 -解码数据合规性报告
verifyRoundTrip(input)
验证支付数据在编码和解码过程中是否完好无损。
参数:
input: PayBySquareInput-原始付款数据
退货: Promise -往返验证结果
例子:
import { verifyRoundTrip } from 'paybysquare-generator';
const result = await verifyRoundTrip(originalData);
if (!result.isLossless) {
console.log('Data loss detected:', result.differences);
}RoundTrip结果:
interface RoundTripResult {
isLossless: boolean;
differences: FieldDifference[];
input: PayBySquareInput; // Original data
decoded: PayBySquareInput; // Data after encode/decode cycle
}
interface FieldDifference {
field: string;
original: any;
decoded: any;
}输入数据格式
PayBySquareInput
interface PayBySquareInput {
// Required fields
iban: string; // e.g., "SK9611000000002918599669"
beneficiaryName: string; // Recipient name (max 70 chars)
// Optional payment details
amount?: number; // Payment amount (positive number)
currency?: string; // ISO 4217 code (default: "EUR")
variableSymbol?: string; // 1-10 digits
constantSymbol?: string; // 1-4 digits
specificSymbol?: string; // 1-10 digits
paymentNote?: string; // Max 140 characters
dueDate?: string; // ISO format: "YYYY-MM-DD"
swift?: string; // SWIFT/BIC code
originatorReference?: string; // Reference info
// Optional beneficiary address
beneficiaryAddress?: {
street?: string; // Max 70 characters
city?: string; // Max 70 characters
};
}生成选项
interface GenerationOptions {
width?: number; // QR code width in pixels (default: 300)
margin?: number; // Margin around QR code (default: 4)
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'; // Default: 'M'
color?: {
dark?: string; // Dark color (default: '#000000')
light?: string; // Light color (default: '#ffffff')
};
removeAccents?: boolean; // Remove diacritics (default: true)
}使用示例
最低付款额
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'
}
});捐赠(无固定金额)
// Amount can be omitted for voluntary donations
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, // Larger QR code
margin: 2, // Smaller margin
errorCorrectionLevel: 'H', // High error correction
color: {
dark: '#1E40AF', // Blue QR code
light: '#FFFFFF' // White background
}
}
);直接保存到文件
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('Invalid input:', error.message);
} else if (error instanceof EncodingError) {
console.error('Encoding failed:', error.message);
} else if (error instanceof GenerationError) {
console.error('QR generation failed:', error.message);
}
}解码二维码
import { decodePayBySquare } from 'paybysquare-generator';
import { readFile } from 'fs/promises';
// Read QR code from file
const qrBuffer = await readFile('./payment-qr.png');
// Decode payment data
const paymentData = await decodePayBySquare(qrBuffer);
console.log('IBAN:', paymentData.iban);
console.log('Beneficiary:', paymentData.beneficiaryName);
console.log('Amount:', paymentData.amount, paymentData.currency);
console.log('Variable Symbol:', paymentData.variableSymbol);简单合规性检查
import { isCompliant } from 'paybysquare-generator';
const paymentData = {
iban: 'SK9611000000002918599669',
beneficiaryName: 'Test Merchant',
amount: 100,
currency: 'EUR'
};
if (isCompliant(paymentData)) {
console.log('✓ Payment data is valid');
} else {
console.log('✗ Payment data has issues');
}详细合规报告
import { checkCompliance } from 'paybysquare-generator';
const paymentData = {
iban: 'SK9999999999999999999999', // Invalid checksum
beneficiaryName: 'Test',
amount: -50, // Negative amount
variableSymbol: 'ABC123', // Should be digits only
swift: 'INVALID' // Invalid BIC format
};
const report = await checkCompliance(paymentData);
console.log('Compliant:', report.isCompliant);
console.log('\nErrors:');
report.errors.forEach(err => {
console.log(` [${err.severity}] ${err.field}: ${err.message}`);
});
console.log('\nValidation Details:');
console.log(' IBAN valid:', report.details.ibanValid);
console.log(' Fields valid:', report.details.fieldsValid);
console.log(' Banking standards valid:', report.details.bankingStandardsValid);
console.log(' Total issues:', 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('✓ Data perfectly preserved through encode/decode cycle!');
} else {
console.log('✗ Data loss detected:');
result.differences.forEach(diff => {
console.log(` ${diff.field}:`);
console.log(` Original: ${diff.original}`);
console.log(` Decoded: ${diff.decoded}`);
});
}验证规则
库对所有输入进行全面验证:
- 国际银行账号:必填,必须为有效格式(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 # Run tests once
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage report从源头构建
npm run build # Compile TypeScript to dist/PayBySquare标准
该库实现了斯洛伐克银行协会(SBA)定义的PayBySquare标准版本1.1.0。更多信息:
依赖项
生产
- bysquare -官方PayBySquare编码器/解码器
- 二维码 -二维码PNG生成器
- jsqr -二维码扫描仪(纯JavaScript)
- 吉姆 -二维码解码的图像处理
- ibantools -使用mod-97校验和进行IBAN验证
TypeScript支持
这个库是用TypeScript编写的,包括完整的类型定义。为了您的方便,导出了所有类型:
import type {
// Input/Output types
PayBySquareInput,
BeneficiaryAddress,
GenerationOptions,
// Compliance types
ComplianceResult,
ComplianceIssue,
ComplianceDetails,
RoundTripResult,
FieldDifference
} from 'paybysquare-generator';
// Error classes are also exported
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桌面:
添加到您的 claude_desktop_config.json:
{
"mcpServers": {
"paybysquare": {
"command": "node",
"args": ["/absolute/path/to/paybysquare/dist/mcp-server/index.js"]
}
}
}- 重新启动克劳德桌面
Claude中的示例用法
配置后,您可以使用自然语言:
Generate a PayBySquare QR code for:
- IBAN: SK9611000000002918599669
- Beneficiary: John Doe
- Amount: 100.50 EUR
- SWIFT: TATRSKBX
- Payment note: Invoice #12345Claude将生成二维码并将其保存到文件中,返回:
✓ QR code generated successfully!
File saved to: /Users/username/paybysquare-qr-codes/paybysquare-1705331234567-a3f2.pngDecode this PayBySquare QR code and tell me the payment details
[Attach image]Check if this payment data is compliant with banking standards:
- IBAN: SK9611000000002918599669
- Beneficiary: Test Company
- Amount: 250 EUR
- SWIFT: TATRSKBX注: 二维码会自动保存到 ~/paybysquare-qr-codes/ 默认情况下。您可以使用以下命令指定自定义目录 outputDirectory 选项。
有关MCP服务器的详细文档,请参阅 mcp服务器/README.md.
许可证
麻省理工学院
贡献
欢迎投稿!请随时提交拉取请求。
相关项目
支持
如果您遇到任何问题或有疑问,请 打开一个问题 在GitHub上。
______________________________________________________________________
由以下材料制成❤️ 斯洛伐克开发者社区
