Error Codes Usage Examples
Complete guide on using Payme error code constants.
Overview
The library provides comprehensive error code constants for all Payme API errors. This makes error handling more readable and maintainable.
Importing Error Codes
typescript
import {
PAYME_ERROR_CODES,
ERROR_MESSAGES,
getErrorMessage,
PaymeError
} from '@joyida/payme';Using Error Codes
Basic Error Handling
typescript
import { PaymeMerchant, PaymeError, PAYME_ERROR_CODES } from '@joyida/payme';
const payme = new PaymeMerchant({
merchantId: process.env.PAYME_MERCHANT_ID!,
secretKey: process.env.PAYME_SECRET_KEY!
});
try {
await payme.createTransaction(params);
} catch (error) {
if (error instanceof PaymeError) {
switch (error.code) {
case PAYME_ERROR_CODES.FORBIDDEN:
console.error('Invalid credentials');
break;
case PAYME_ERROR_CODES.INVALID_AMOUNT:
console.error('Invalid payment amount');
break;
case PAYME_ERROR_CODES.TRANSACTION_NOT_FOUND:
console.error('Transaction not found');
break;
case PAYME_ERROR_CODES.ACCOUNT_NOT_FOUND:
console.error('Order not found');
break;
case PAYME_ERROR_CODES.ORDER_ALREADY_PAID:
console.error('Order already paid');
break;
case PAYME_ERROR_CODES.CANNOT_CANCEL:
console.error('Cannot cancel - order fulfilled');
break;
default:
console.error(`Payme error: ${error.message}`);
}
}
}Using Merchant API Error Codes
typescript
import { PaymeMerchant, PaymeError, PAYME_ERROR_CODES } from '@joyida/payme';
const payme = new PaymeMerchant({
merchantId: process.env.PAYME_MERCHANT_ID!,
secretKey: process.env.PAYME_SECRET_KEY!
});
try {
await payme.performTransaction({ id: paymeId });
} catch (error) {
if (error instanceof PaymeError) {
switch (error.code) {
case PAYME_ERROR_CODES.TRANSACTION_NOT_FOUND:
console.error('Transaction not found');
break;
case PAYME_ERROR_CODES.INVALID_STATE:
console.error('Invalid transaction state');
break;
case PAYME_ERROR_CODES.CANNOT_PERFORM:
console.error('Cannot perform transaction');
break;
case PAYME_ERROR_CODES.ALREADY_DONE:
console.error('Transaction already completed');
break;
default:
console.error(`Error: ${error.message}`);
}
}
}Using Subscribe API Error Codes
typescript
import { PaymeSubscribe, PaymeError, PAYME_ERROR_CODES } from '@joyida/payme';
const subscribe = new PaymeSubscribe({
merchantId: process.env.PAYME_MERCHANT_ID!,
password: process.env.PAYME_PASSWORD!
}, 'server');
try {
await subscribe.receiptsPay({
id: receiptId,
token: cardToken
});
} catch (error) {
if (error instanceof PaymeError) {
switch (error.code) {
case PAYME_ERROR_CODES.CARD_NOT_FOUND:
console.error('Card not found');
break;
case PAYME_ERROR_CODES.CARD_EXPIRED:
console.error('Card has expired');
break;
case PAYME_ERROR_CODES.CARD_BLOCKED:
console.error('Card is blocked');
break;
case PAYME_ERROR_CODES.INSUFFICIENT_FUNDS:
console.error('Insufficient funds');
break;
case PAYME_ERROR_CODES.CARD_VERIFICATION_FAILED:
console.error('Card verification failed');
break;
case PAYME_ERROR_CODES.RECEIPT_NOT_FOUND:
console.error('Receipt not found');
break;
case PAYME_ERROR_CODES.RECEIPT_ALREADY_PAID:
console.error('Receipt already paid');
break;
default:
console.error(`Error: ${error.message}`);
}
}
}Getting Error Messages
Using ERROR_MESSAGES
typescript
import { ERROR_MESSAGES, PAYME_ERROR_CODES } from '@joyida/payme';
const errorCode = PAYME_ERROR_CODES.INVALID_AMOUNT;
const message = ERROR_MESSAGES[errorCode];
console.log(message); // "Invalid amount"Using getErrorMessage Helper
typescript
import { getErrorMessage, PAYME_ERROR_CODES } from '@joyida/payme';
const message1 = getErrorMessage(PAYME_ERROR_CODES.FORBIDDEN);
console.log(message1); // "Forbidden - Invalid credentials"
const message2 = getErrorMessage(PAYME_ERROR_CODES.CARD_EXPIRED);
console.log(message2); // "Card has expired"
const message3 = getErrorMessage(-99999);
console.log(message3); // "Unknown error (code: -99999)"Complete Error Handling Example
typescript
import {
PaymeMerchant,
PaymeError,
PAYME_ERROR_CODES,
getErrorMessage
} from '@joyida/payme';
const payme = new PaymeMerchant({
merchantId: process.env.PAYME_MERCHANT_ID!,
secretKey: process.env.PAYME_SECRET_KEY!
});
async function processPayment(orderId: string, amount: number) {
try {
const paymeId = generatePaymeId();
const created = await payme.createTransaction({
id: paymeId,
time: Date.now(),
amount,
account: { order_id: orderId }
});
const performed = await payme.performTransaction({
id: paymeId
});
return {
success: true,
transactionId: performed.transaction
};
} catch (error) {
if (error instanceof PaymeError) {
// Log error with code and message
console.error({
code: error.code,
message: error.message,
description: getErrorMessage(error.code)
});
// Handle specific errors
switch (error.code) {
case PAYME_ERROR_CODES.FORBIDDEN:
throw new Error('Payment system configuration error');
case PAYME_ERROR_CODES.INVALID_AMOUNT:
throw new Error('Invalid payment amount');
case PAYME_ERROR_CODES.ACCOUNT_NOT_FOUND:
throw new Error('Order not found');
case PAYME_ERROR_CODES.ORDER_ALREADY_PAID:
throw new Error('Order already paid');
case PAYME_ERROR_CODES.ORDER_CANCELLED:
throw new Error('Order is cancelled');
case PAYME_ERROR_CODES.ORDER_EXPIRED:
throw new Error('Order has expired');
case PAYME_ERROR_CODES.TRANSACTION_NOT_FOUND:
throw new Error('Transaction not found');
case PAYME_ERROR_CODES.CANNOT_PERFORM:
throw new Error('Cannot complete payment');
case PAYME_ERROR_CODES.TRANSPORT_ERROR:
throw new Error('Payment system temporarily unavailable');
default:
throw new Error(`Payment error: ${error.message}`);
}
}
throw error;
}
}Error Code Categories
JSON-RPC Protocol Errors
typescript
import { PAYME_ERROR_CODES } from '@joyida/payme';
// Protocol errors
PAYME_ERROR_CODES.PARSE_ERROR // -32700
PAYME_ERROR_CODES.INVALID_REQUEST // -32600
PAYME_ERROR_CODES.METHOD_NOT_FOUND // -32601
PAYME_ERROR_CODES.INVALID_PARAMS // -32602
PAYME_ERROR_CODES.INTERNAL_ERROR // -32603
PAYME_ERROR_CODES.TRANSPORT_ERROR // -32400
PAYME_ERROR_CODES.METHOD_NOT_POST // -32300
PAYME_ERROR_CODES.FORBIDDEN // -32504Transaction Errors
typescript
// Transaction errors
PAYME_ERROR_CODES.INVALID_AMOUNT // -31001
PAYME_ERROR_CODES.INVALID_ACCOUNT // -31002
PAYME_ERROR_CODES.TRANSACTION_NOT_FOUND // -31003
PAYME_ERROR_CODES.INVALID_STATE // -31004
PAYME_ERROR_CODES.TRANSACTION_CANCELLED // -31005
PAYME_ERROR_CODES.TRANSACTION_EXISTS // -31006
PAYME_ERROR_CODES.CANNOT_CANCEL // -31007
PAYME_ERROR_CODES.CANNOT_PERFORM // -31008Account Errors
typescript
// Account errors (range: -31050 to -31099)
PAYME_ERROR_CODES.ACCOUNT_NOT_FOUND // -31050
PAYME_ERROR_CODES.ACCOUNT_BLOCKED // -31051
PAYME_ERROR_CODES.ACCOUNT_INACTIVE // -31052
PAYME_ERROR_CODES.INSUFFICIENT_PRIVILEGES // -31053
PAYME_ERROR_CODES.ACCOUNT_LIMIT_EXCEEDED // -31054
PAYME_ERROR_CODES.ORDER_ALREADY_PAID // -31055
PAYME_ERROR_CODES.ORDER_CANCELLED // -31056
PAYME_ERROR_CODES.ORDER_NOT_AVAILABLE // -31057
PAYME_ERROR_CODES.INVALID_ORDER_AMOUNT // -31058
PAYME_ERROR_CODES.ORDER_EXPIRED // -31059
PAYME_ERROR_CODES.ALREADY_DONE // -31060
PAYME_ERROR_CODES.PENDING_TRANSACTION // -31099Card Errors
typescript
// Card errors (range: -31300 to -31310)
PAYME_ERROR_CODES.CARD_NOT_FOUND // -31300
PAYME_ERROR_CODES.CARD_EXPIRED // -31301
PAYME_ERROR_CODES.CARD_BLOCKED // -31302
PAYME_ERROR_CODES.INSUFFICIENT_FUNDS // -31303
PAYME_ERROR_CODES.CARD_VERIFICATION_FAILED // -31304
PAYME_ERROR_CODES.INVALID_CARD_NUMBER // -31305
PAYME_ERROR_CODES.INVALID_CARD_EXPIRY // -31306
PAYME_ERROR_CODES.CARD_NOT_SUPPORTED // -31307
PAYME_ERROR_CODES.CARD_LIMIT_EXCEEDED // -31308
PAYME_ERROR_CODES.TOO_MANY_ATTEMPTS // -31309
PAYME_ERROR_CODES.CARD_ALREADY_EXISTS // -31310Receipt Errors
typescript
// Receipt errors (range: -31400 to -31405)
PAYME_ERROR_CODES.RECEIPT_NOT_FOUND // -31400
PAYME_ERROR_CODES.RECEIPT_ALREADY_PAID // -31401
PAYME_ERROR_CODES.RECEIPT_CANCELLED // -31402
PAYME_ERROR_CODES.INVALID_RECEIPT_STATE // -31403
PAYME_ERROR_CODES.RECEIPT_EXPIRED // -31404
PAYME_ERROR_CODES.INVALID_RECEIPT_AMOUNT // -31405Fiscal Errors
typescript
// Fiscal errors
PAYME_ERROR_CODES.FISCAL_CHECK_NOT_FOUND // -32001
PAYME_ERROR_CODES.FISCAL_MODULE_ERROR // -32002
PAYME_ERROR_CODES.FISCAL_DATA_INVALID // -32003Error Logging
Structured Error Logging
typescript
import { PaymeError, PAYME_ERROR_CODES, getErrorMessage } from '@joyida/payme';
function logPaymeError(error: PaymeError, context: Record<string, unknown>) {
const logEntry = {
timestamp: new Date().toISOString(),
errorCode: error.code,
errorMessage: error.message,
errorDescription: getErrorMessage(error.code),
context,
isRetryable: isRetryableError(error.code)
};
console.error(JSON.stringify(logEntry));
}
function isRetryableError(code: number): boolean {
// Network and temporary errors are retryable
return [
PAYME_ERROR_CODES.TRANSPORT_ERROR,
PAYME_ERROR_CODES.INTERNAL_ERROR
].includes(code);
}
// Usage
try {
await payme.createTransaction(params);
} catch (error) {
if (error instanceof PaymeError) {
logPaymeError(error, {
operation: 'createTransaction',
orderId: params.account.order_id,
amount: params.amount
});
}
}Best Practices
✅ Do's
Use constants instead of magic numbers
typescript// ✅ GOOD if (error.code === PAYME_ERROR_CODES.FORBIDDEN) { console.error('Invalid credentials'); } // ❌ BAD if (error.code === -32504) { console.error('Invalid credentials'); }Use getErrorMessage for user-friendly messages
typescript// ✅ GOOD const message = getErrorMessage(error.code); showErrorToUser(message);Handle specific errors
typescript// ✅ GOOD switch (error.code) { case PAYME_ERROR_CODES.CARD_EXPIRED: return 'Please update your card'; case PAYME_ERROR_CODES.INSUFFICIENT_FUNDS: return 'Insufficient funds'; }Log error codes for debugging
typescript// ✅ GOOD console.error({ code: error.code, message: getErrorMessage(error.code), context: { orderId, amount } });
❌ Don'ts
- Don't use magic numbers
- Don't ignore error codes
- Don't show technical errors to users
- Don't retry on non-retryable errors
Next Steps
- Learn about Error Handling
- Check Merchant API Reference
- Explore Subscribe API Reference
- See Basic Payment Example