Oddiy To'lov Misoli
Payme Merchant API dan foydalangan holda to'lovni qayta ishlashning to'liq misoli.
Umumiy Ko'rinish
Ushbu misol quyidagilarni ko'rsatadi:
- To'lov mumkinligini tekshirish
- Tranzaktsiya yaratish
- Tranzaktsiyani bajarish
- Xatolarni ishlash
- Ma'lumotlar bazasi integratsiyasi
Talablar
bash
bun add @joyida/paymeMuxit Sozlash
.env faylini yarating:
bash
PAYME_MERCHANT_ID=your_merchant_id
PAYME_SECRET_KEY=your_secret_key
DATABASE_URL=./app.dbMa'lumotlar BazasiSxemasi
sql
-- Tranzaktsiyalar jadvalini yaratish
CREATE TABLE IF NOT EXISTS payme_transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
payme_id TEXT UNIQUE NOT NULL,
order_id TEXT NOT NULL,
amount INTEGER NOT NULL,
state INTEGER NOT NULL DEFAULT 1,
reason INTEGER,
create_time INTEGER NOT NULL,
perform_time INTEGER DEFAULT 0,
cancel_time INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Buyurtmalar jadvalini yaratish
CREATE TABLE IF NOT EXISTS orders (
id TEXT PRIMARY KEY,
user_id INTEGER NOT NULL,
amount INTEGER NOT NULL,
status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Indekslarni yaratish
CREATE INDEX idx_payme_transactions_payme_id ON payme_transactions(payme_id);
CREATE INDEX idx_payme_transactions_order_id ON payme_transactions(order_id);
CREATE INDEX idx_orders_user_id ON orders(user_id);To'liq Implementatsiya
typescript
import { PaymeMerchant, TransactionStates, PaymeError, ValidationError, NetworkError } from '@joyida/payme';
import { Database } from 'bun:sqlite';
// Payme klientini ishga tushirish
const payme = new PaymeMerchant({
merchantId: process.env.PAYME_MERCHANT_ID!,
secretKey: process.env.PAYME_SECRET_KEY!,
timeout: 30000
});
// Ma'lumotlar bazasini ishga tushirish
const db = new Database(process.env.DATABASE_URL!);
// 24-belgili Payme tranzaktsiya ID yaratish
function generatePaymeId(): string {
const chars = '0123456789abcdef';
let id = '';
for (let i = 0; i < 24; i++) {
id += chars[Math.floor(Math.random() * chars.length)];
}
return id;
}
// Buyurtma mavjudligini tekshirish va tafsilotlarini olish
function getOrder(orderId: string) {
const order = db.query(`
SELECT * FROM orders WHERE id = ? AND status = 'pending'
`).get(orderId);
if (!order) {
throw new Error('Buyurtma topilmadi yoki allaqachon qayta ishlandi');
}
return order;
}
// Tranzaktsiyani ma'lumotlar bazasiga saqlash
function saveTransaction(data: {
paymeId: string;
orderId: string;
amount: number;
state: number;
createTime: number;
}) {
db.run(`
INSERT INTO payme_transactions
(payme_id, order_id, amount, state, create_time)
VALUES (?, ?, ?, ?, ?)
`, [
data.paymeId,
data.orderId,
data.amount,
data.state,
data.createTime
]);
}
// Tranzaktsiya holatini yangilash
function updateTransactionState(paymeId: string, state: number, performTime?: number) {
if (performTime) {
db.run(`
UPDATE payme_transactions
SET state = ?, perform_time = ?, updated_at = CURRENT_TIMESTAMP
WHERE payme_id = ?
`, [state, performTime, paymeId]);
} else {
db.run(`
UPDATE payme_transactions
SET state = ?, updated_at = CURRENT_TIMESTAMP
WHERE payme_id = ?
`, [state, paymeId]);
}
}
// Buyurtma holatini yangilash
function updateOrderStatus(orderId: string, status: string) {
db.run(`
UPDATE orders
SET status = ?, updated_at = CURRENT_TIMESTAMP
WHERE id = ?
`, [status, orderId]);
}
// Asosiy to'lovni qayta ishlash funktsiyasi
async function processPayment(orderId: string) {
console.log(`\n🔄 Buyurtma uchun to'lovni qayta ishlash: ${orderId}`);
try {
// 1. Buyurtma tafsilotlarini olish
console.log('📋 Buyurtma tafsilotlarini olish...');
const order = getOrder(orderId);
console.log(`✅ Buyurtma topildi: ${order.amount} tiyin`);
// 2. To'lov mumkinligini tekshirish
console.log('\n🔍 To\'lov mumkinligini tekshirish...');
const check = await payme.checkPerformTransaction({
amount: order.amount,
account: { order_id: orderId }
});
if (!check.allow) {
throw new Error('To\'lov ruxsat etilmagan');
}
console.log('✅ To\'lov ruxsat etildi');
// 3. Tranzaktsiya yaratish
console.log('\n📝 Tranzaktsiya yaratish...');
const paymeId = generatePaymeId();
console.log(`Yaratilgan Payme ID: ${paymeId}`);
const created = await payme.createTransaction({
id: paymeId,
time: Date.now(),
amount: order.amount,
account: { order_id: orderId }
});
console.log(`✅ Tranzaktsiya yaratildi: ${created.transaction}`);
console.log(` Holat: ${created.state} (yaratilgan)`);
console.log(` Yaratish vaqti: ${new Date(created.create_time).toISOString()}`);
// 4. Ma'lumotlar bazasiga saqlash
console.log('\n💾 Ma\'lumotlar bazasiga saqlash...');
saveTransaction({
paymeId,
orderId,
amount: order.amount,
state: created.state,
createTime: created.create_time
});
updateOrderStatus(orderId, 'awaiting_payment');
console.log('✅ Ma\'lumotlar bazasiga saqlandi');
// 5. Tranzaktsiyani bajarish (to'lovni yakunlash)
console.log('\n💳 Tranzaktsiyani bajarish...');
const performed = await payme.performTransaction({
id: paymeId
});
console.log(`✅ Tranzaktsiya bajarildi: ${performed.transaction}`);
console.log(` Holat: ${performed.state} (yakunlangan)`);
console.log(` Bajarish vaqti: ${new Date(performed.perform_time).toISOString()}`);
// 6. Ma'lumotlar bazasini yangilash
console.log('\n💾 Ma\'lumotlar bazasini yangilash...');
updateTransactionState(paymeId, performed.state, performed.perform_time);
updateOrderStatus(orderId, 'paid');
console.log('✅ Ma\'lumotlar bazasi yangilandi');
// 7. Yakuniy holatni tekshirish
console.log('\n🔍 Yakuniy holatni tekshirish...');
const status = await payme.checkTransaction({
id: paymeId
});
console.log('✅ Yakuniy holat:');
console.log(` Holat: ${status.state}`);
console.log(` Yaratildi: ${new Date(status.create_time).toISOString()}`);
console.log(` Bajarildi: ${new Date(status.perform_time).toISOString()}`);
if (status.state === TransactionStates.COMPLETED) {
console.log('\n🎉 To\'lov muvaffaqiyatli!');
return {
success: true,
paymeId,
transactionId: status.transaction,
amount: order.amount
};
} else {
throw new Error(`Kutilmagan tranzaktsiya holati: ${status.state}`);
}
} catch (error) {
console.error('\n❌ To\'lov muvaffaqiyatsiz!');
if (error instanceof ValidationError) {
console.error('Tekshirish xatosi:', error.message);
throw new Error(`Noto'g'ri kiritma: ${error.message}`);
} else if (error instanceof PaymeError) {
console.error('Payme xatosi:', error.code, error.message);
switch (error.code) {
case -32504:
throw new Error('To\'lov tizimi sozlamalari xatosi');
case -31001:
throw new Error('Noto\'g\'ri to\'lov summasi');
case -31003:
throw new Error('Tranzaktsiya topilmadi');
case -31050:
throw new Error('Buyurtma topilmadi');
case -32400:
throw new Error('To\'lov tizimi vaqtinchalik mavjud emas');
default:
throw new Error(`To'lov xatosi: ${error.message}`);
}
} else if (error instanceof NetworkError) {
console.error('Tarmoq xatosi:', error.message);
if (error.timeout) {
throw new Error(`So'rov ${error.timeout}ms dan keyin vaqt tugadi`);
} else {
throw new Error('Tarmoq aloqa xatosi');
}
} else {
console.error('Noma\'lum xato:', error);
throw error;
}
}
}
// Misol foydalanish
async function main() {
// Test buyurtma yaratish
const orderId = `ORD-${Date.now()}`;
const amount = 500000; // 5000 so'm tiyinda
db.run(`
INSERT INTO orders (id, user_id, amount, status)
VALUES (?, ?, ?, ?)
`, [orderId, 1, amount, 'pending']);
console.log(`Test buyurtma yaratildi: ${orderId}`);
// To'lovni qayta ishlash
try {
const result = await processPayment(orderId);
console.log('\n✅ To\'lov natijasi:', result);
} catch (error) {
console.error('\n❌ To\'lov xatosi:', error.message);
process.exit(1);
}
}
// Misolni ishga tushirish
main();Misolni Ishga Tushirish
bash
# Bog'liqliklarni o'rnatish
bun install
# Muxit o'zgaruvchilarini o'rnatish
export PAYME_MERCHANT_ID=your_merchant_id
export PAYME_SECRET_KEY=your_secret_key
# Misolni ishga tushirish
bun run example.tsKutulgan Natija
Test buyurtma yaratildi: ORD-1234567890
🔄 Buyurtma uchun to'lovni qayta ishlash: ORD-1234567890
📋 Buyurtma tafsilotlarini olish...
✅ Buyurtma topildi: 500000 tiyin
🔍 To'lov mumkinligini tekshirish...
✅ To'lov ruxsat etildi
📝 Tranzaktsiya yaratish...
Yaratilgan Payme ID: 5305e3bab097f420a62ced0b
✅ Tranzaktsiya yaratildi: 5123
Holat: 1 (yaratilgan)
Yaratish vaqti: 2024-01-15T10:30:00.000Z
💾 Ma'lumotlar bazasiga saqlash...
✅ Ma'lumotlar bazasiga saqlandi
💳 Tranzaktsiyani bajarish...
✅ Tranzaktsiya bajarildi: 5123
Holat: 2 (yakunlangan)
Bajarish vaqti: 2024-01-15T10:30:01.000Z
💾 Ma'lumotlar bazasini yangilash...
✅ Ma'lumotlar bazasi yangilandi
🔍 Yakuniy holatni tekshirish...
✅ Yakuniy holat:
Holat: 2
Yaratildi: 2024-01-15T10:30:00.000Z
Bajarildi: 2024-01-15T10:30:01.000Z
🎉 To'lov muvaffaqiyatli!
✅ To'lov natijasi: {
success: true,
paymeId: '5305e3bab097f420a62ced0b',
transactionId: '5123',
amount: 500000
}Xato Ishlash Misollari
Noto'g'ri Suma
typescript
// Bu ValidationError tashlaydi
await payme.createTransaction({
id: paymeId,
time: Date.now(),
amount: -100, // ❌ Manfiy suma
account: { order_id: orderId }
});
// Natija:
// ❌ To'lov muvaffaqiyatsiz!
// Validation error: Amount must be a positive integerBuyurtma Topilmadi
typescript
// Bu -31050 kodli PaymeError tashlaydi
await payme.checkPerformTransaction({
amount: 500000,
account: { order_id: 'NON_EXISTENT' } // ❌ Buyurtma mavjud emas
});
// Natija:
// ❌ To'lov muvaffaqiyatsiz!
// Payme error: -31050 Order not foundTarmoq Vaqt Tugashi
typescript
// Bu NetworkError tashlaydi
const payme = new PaymeMerchant({
merchantId: process.env.PAYME_MERCHANT_ID!,
secretKey: process.env.PAYME_SECRET_KEY!,
timeout: 1 // ❌ Juda qisqa vaqt tugashi
});
// Natija:
// ❌ To'lov muvaffaqiyatsiz!
// Network error: Request timed out after 1msKeyingi Qadamlar
- Takroriy To'lovlar haqida bilib oling
- To'lov Oqimi va Ma'lumotlar Bazasi Integratsiyasi qo'llanmalarini o'qing
- Xatolarni Ishlash ni ko'ring