Validation Reference
Complete reference for input validation in @joyida/payme.
New API: Named Functions
The recommended way to use validation is with named functions:
import { validateAmount, validateCardNumber, ValidationError } from '@joyida/payme';
// Validate before API call
try {
validateAmount(500000);
validateCardNumber('8600069195406311');
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
}
}Available Validation Functions
| Function | Purpose |
|---|---|
validateAmount(amount) | Validates payment amount (positive integer in tiyin) |
validateCardNumber(number) | Validates card number (13-19 digits) |
validateCardExpiry(expire) | Validates card expiry (MMYY format) |
validatePhone(phone) | Validates Uzbekistan phone (998XXXXXXXXX) |
validatePaymeId(id) | Validates Payme transaction ID (24 characters) |
validateTimestamp(timestamp) | Validates Unix timestamp (13-digit ms) |
validateAccount(account) | Validates account object (non-empty) |
validateToken(token) | Validates card token (non-empty string) |
validateSecretKey(secretKey) | Validates merchant secret key |
validateCancelReason(reason) | Validates cancel reason (1,2,3,4,5,10) |
validateFiscalDataType(type) | Validates fiscal data type (PERFORM/CANCEL) |
validateFiscalData(fiscalData) | Validates fiscal data object |
validateNonEmptyString(value, fieldName) | Validates non-empty string |
validateReceiptId(id) | Validates receipt ID |
Deprecated: Validator Class
Deprecation Notice
The Validator class is deprecated and will be removed in version 0.5.0. Please use the named validation functions instead.
Migration:
// ❌ Old (deprecated)
import { Validator } from '@joyida/payme';
Validator.validateAmount(500000);
// ✅ New (recommended)
import { validateAmount } from '@joyida/payme';
validateAmount(500000);The Validator class provides static methods for validating inputs before API calls.
import { Validator, ValidationError } from '@joyida/payme';Methods
validateAmount
Validate payment amount (must be positive integer in tiyin).
static validateAmount(amount: number): voidRules:
- Must be a number
- Must be positive (> 0)
- Must be an integer (no decimals)
- Represents amount in tiyin (1 UZS = 100 tiyin)
Examples:
// ✅ Valid amounts
Validator.validateAmount(500000); // 5000 UZS
Validator.validateAmount(100); // 1 UZS
Validator.validateAmount(1); // 0.01 UZS
// ❌ Invalid amounts
Validator.validateAmount(-100); // Throws: negative
Validator.validateAmount(0); // Throws: zero
Validator.validateAmount(100.5); // Throws: decimal
Validator.validateAmount('100'); // Throws: not a numberError Message:
"Amount must be a positive integer"validateCardNumber
Validate card number (13-19 digits).
static validateCardNumber(cardNumber: string): voidRules:
- Must be a string
- Must contain 13-19 digits
- Spaces are allowed and will be removed
- Only digits and spaces allowed
Examples:
// ✅ Valid card numbers
Validator.validateCardNumber('8600069195406311');
Validator.validateCardNumber('8600 0691 9540 6311');
Validator.validateCardNumber('4111111111111111');
// ❌ Invalid card numbers
Validator.validateCardNumber('123'); // Throws: too short
Validator.validateCardNumber('12345678901234567890'); // Throws: too long
Validator.validateCardNumber('abcd1234'); // Throws: contains letters
Validator.validateCardNumber(''); // Throws: emptyError Message:
"Card number must be 13-19 digits"validateCardExpiry
Validate card expiry date (MMYY format).
static validateCardExpiry(expire: string): voidRules:
- Must be a string
- Must be exactly 4 characters
- Format: MMYY (e.g., "0399" = March 2099)
- Month must be 01-12
- Must not be expired
Examples:
// ✅ Valid expiry dates
Validator.validateCardExpiry('0399'); // March 2099
Validator.validateCardExpiry('1225'); // December 2025
Validator.validateCardExpiry('0126'); // January 2026
// ❌ Invalid expiry dates
Validator.validateCardExpiry('1323'); // Throws: invalid month (13)
Validator.validateCardExpiry('0020'); // Throws: expired
Validator.validateCardExpiry('03/99'); // Throws: wrong format
Validator.validateCardExpiry('399'); // Throws: wrong lengthError Messages:
"Invalid card expiry format. Expected MMYY (e.g., 0399)"
"Invalid month in card expiry"
"Card has expired"validatePhone
Validate phone number (Uzbekistan format).
static validatePhone(phone: string): voidRules:
- Must be a string
- Must start with "998"
- Must be exactly 12 digits
- Format: 998XXXXXXXXX
Examples:
// ✅ Valid phone numbers
Validator.validatePhone('998901234567');
Validator.validatePhone('998971234567');
Validator.validatePhone('998331234567');
// ❌ Invalid phone numbers
Validator.validatePhone('901234567'); // Throws: missing country code
Validator.validatePhone('998901234'); // Throws: too short
Validator.validatePhone('+998901234567'); // Throws: contains +
Validator.validatePhone('998 90 123 45 67'); // Throws: contains spacesError Message:
"Invalid phone number format. Expected 998XXXXXXXXX"validatePaymeId
Validate Payme transaction ID (24 characters).
static validatePaymeId(id: string): voidRules:
- Must be a string
- Must be exactly 24 characters
- Typically hexadecimal (0-9, a-f)
Examples:
// ✅ Valid Payme IDs
Validator.validatePaymeId('5305e3bab097f420a62ced0b');
Validator.validatePaymeId('61396aaed8b87a4c215ae556');
// ❌ Invalid Payme IDs
Validator.validatePaymeId('5305e3ba'); // Throws: too short
Validator.validatePaymeId('5305e3bab097f420a62ced0b123'); // Throws: too long
Validator.validatePaymeId(''); // Throws: emptyError Message:
"Payme ID must be 24 characters"validateTimestamp
Validate Unix timestamp (13 digits, milliseconds).
static validateTimestamp(timestamp: number): voidRules:
- Must be a number
- Must be exactly 13 digits
- Represents Unix timestamp in milliseconds
Examples:
// ✅ Valid timestamps
Validator.validateTimestamp(Date.now());
Validator.validateTimestamp(1399114284039);
Validator.validateTimestamp(1700000000000);
// ❌ Invalid timestamps
Validator.validateTimestamp(1399114284); // Throws: 10 digits (seconds)
Validator.validateTimestamp(139911428403); // Throws: 12 digits
Validator.validateTimestamp('1399114284039'); // Throws: not a numberError Message:
"Timestamp must be 13 digits (Unix timestamp in milliseconds)"validateAccount
Validate account object.
static validateAccount(account: Record<string, string | number>): voidRules:
- Must be an object
- Must not be empty
- Keys must be strings
- Values must be strings or numbers
Examples:
// ✅ Valid accounts
Validator.validateAccount({ order_id: 'ORD-123' });
Validator.validateAccount({ user_id: 12345 });
Validator.validateAccount({ order_id: 'ORD-123', user_id: 12345 });
// ❌ Invalid accounts
Validator.validateAccount({}); // Throws: empty
Validator.validateAccount(null); // Throws: not an object
Validator.validateAccount('order_id'); // Throws: not an object
Validator.validateAccount({ order_id: [] }); // Throws: invalid value typeError Message:
"Account must be a non-empty object"validateToken
Validate card token.
static validateToken(token: string): voidRules:
- Must be a string
- Must not be empty
Examples:
// ✅ Valid tokens
Validator.validateToken('card_token_here');
Validator.validateToken('abc123xyz');
// ❌ Invalid tokens
Validator.validateToken(''); // Throws: empty
Validator.validateToken(null); // Throws: not a stringError Message:
"Token must be a non-empty string"Usage Examples
Validate Before API Call
import { Validator, ValidationError } from '@joyida/payme';
async function createTransaction(params) {
try {
// Validate all inputs
Validator.validatePaymeId(params.id);
Validator.validateTimestamp(params.time);
Validator.validateAmount(params.amount);
Validator.validateAccount(params.account);
// All valid, proceed with API call
return await payme.createTransaction(params);
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
throw error;
}
}
}Validate User Input
import { Validator, ValidationError } from '@joyida/payme';
function validateCardForm(cardNumber: string, cardExpiry: string) {
const errors: string[] = [];
try {
Validator.validateCardNumber(cardNumber);
} catch (error) {
if (error instanceof ValidationError) {
errors.push(error.message);
}
}
try {
Validator.validateCardExpiry(cardExpiry);
} catch (error) {
if (error instanceof ValidationError) {
errors.push(error.message);
}
}
return {
valid: errors.length === 0,
errors
};
}
// Usage
const result = validateCardForm('8600069195406311', '0399');
if (!result.valid) {
console.error('Validation errors:', result.errors);
}Validate with Custom Messages
import { Validator, ValidationError } from '@joyida/payme';
function validateAmount(amount: number, fieldName: string = 'Amount') {
try {
Validator.validateAmount(amount);
} catch (error) {
if (error instanceof ValidationError) {
throw new Error(`${fieldName}: ${error.message}`);
}
}
}
// Usage
try {
validateAmount(-100, 'Payment amount');
} catch (error) {
console.error(error.message); // "Payment amount: Amount must be a positive integer"
}Batch Validation
import { Validator, ValidationError } from '@joyida/payme';
function validatePaymentData(data: {
amount: number;
cardNumber: string;
cardExpiry: string;
phone: string;
}) {
const errors: Record<string, string> = {};
// Validate amount
try {
Validator.validateAmount(data.amount);
} catch (error) {
if (error instanceof ValidationError) {
errors.amount = error.message;
}
}
// Validate card number
try {
Validator.validateCardNumber(data.cardNumber);
} catch (error) {
if (error instanceof ValidationError) {
errors.cardNumber = error.message;
}
}
// Validate card expiry
try {
Validator.validateCardExpiry(data.cardExpiry);
} catch (error) {
if (error instanceof ValidationError) {
errors.cardExpiry = error.message;
}
}
// Validate phone
try {
Validator.validatePhone(data.phone);
} catch (error) {
if (error instanceof ValidationError) {
errors.phone = error.message;
}
}
return {
valid: Object.keys(errors).length === 0,
errors
};
}
// Usage
const result = validatePaymentData({
amount: 500000,
cardNumber: '8600069195406311',
cardExpiry: '0399',
phone: '998901234567'
});
if (!result.valid) {
console.error('Validation errors:', result.errors);
}Automatic Validation
The library automatically validates inputs before API calls:
// This will automatically validate amount and account
await payme.checkPerformTransaction({
amount: 500000,
account: { order_id: 'ORD-123' }
});
// This will automatically validate card number and expiry
await subscribe.cardsCreate({
card: {
number: '8600069195406311',
expire: '0399'
},
save: true
});Best Practices
✅ Do's
Validate early
typescript// Validate user input before processing Validator.validateAmount(userInput.amount);Provide user-friendly messages
typescripttry { Validator.validateCardNumber(cardNumber); } catch (error) { if (error instanceof ValidationError) { showError('Please enter a valid card number'); } }Validate all inputs
typescript// Validate all fields before API call Validator.validateAmount(amount); Validator.validateAccount(account); Validator.validatePaymeId(id);
❌ Don'ts
Don't skip validation
typescript// ❌ BAD - No validation await payme.createTransaction(params); // ✅ GOOD - Validate first Validator.validateAmount(params.amount); await payme.createTransaction(params);Don't ignore validation errors
typescript// ❌ BAD - Ignore errors try { Validator.validateAmount(amount); } catch (error) { // Ignore } // ✅ GOOD - Handle errors try { Validator.validateAmount(amount); } catch (error) { if (error instanceof ValidationError) { console.error(error.message); throw error; } }
Next Steps
- Learn about Error Handling
- Check Merchant API Reference
- Explore Subscribe API Reference
- See Complete Examples