@montarist/pos
v1.0.0
Published
Turkish Virtual POS Integration Library for Node.js/NestJS - Supporting all major Turkish banks and payment institutions
Downloads
42
Readme
@vignetim/pos
A comprehensive TypeScript/Node.js library for Turkish Virtual POS (Payment Gateway) integrations. Supports all major Turkish banks and payment institutions with unified API, 3D Secure authentication, and NestJS integration.
Table of Contents
- Features
- Installation
- Quick Start
- Bank Support Matrix
- API Reference
- Bank-Specific Configuration
- NestJS Integration
- BIN (Card Number) Lookup
- Error Handling
- Test Cards
- Migration from Other Libraries
- Contributing
- License
Features
- Unified API: Single interface for all banks and payment institutions
- Type-Safe: Full TypeScript support with comprehensive type definitions
- 3D Secure: Complete 3D Secure 1.0/2.0 payment flow support
- Multi-Currency: Support for TRY, USD, EUR, GBP
- Installment Support: Up to 36 months installment payments
- Validation: Built-in request validation with detailed error messages
- BIN Database: Credit card BIN lookup for card identification
- NestJS Ready: First-class NestJS module support
- ESM & CJS: Dual module format support
- Test Cards: Built-in test card data for development
Installation
# Using npm
npm install @vignetim/pos
# Using yarn
yarn add @vignetim/pos
# Using pnpm
pnpm add @vignetim/posRequirements
- Node.js >= 18.0.0
- TypeScript >= 5.0 (for TypeScript users)
Quick Start
import { VPOSClient, BankCode, Currency, SaleRequest, VirtualPOSAuth } from '@vignetim/pos';
// 1. Configure authentication
const auth = new VirtualPOSAuth({
bankCode: BankCode.GarantiBBVA,
merchantId: '7000679',
merchantUser: 'PROVAUT',
merchantPassword: '123qweASD/',
merchantStoreKey: '12345678',
terminalId: '30691298',
testPlatform: true, // Set to false for production
});
// 2. Create sale request
const request = new SaleRequest({
orderNumber: 'ORDER-2024-001',
customerIpAddress: '192.168.1.100',
amount: 150.00,
currency: Currency.TRY,
installment: 1, // Single payment
card: {
holderName: 'John Doe',
cardNumber: '4155650100416111',
expiryMonth: 12,
expiryYear: 2028,
cvv: '123',
},
});
// 3. Process payment
const response = await VPOSClient.sale(request, auth);
if (response.isSuccess()) {
console.log('Payment successful!');
console.log('Transaction ID:', response.transactionId);
console.log('Auth Code:', response.authCode);
} else {
console.error('Payment failed:', response.message);
console.error('Error Code:', response.errorCode);
}Bank Support Matrix
Traditional Banks
| Bank | Code | Sale | 3D Secure | Cancel | Refund | Query | Protocol |
|------|------|:----:|:---------:|:------:|:------:|:-----:|----------|
| Garanti BBVA | 0062 | ✅ | ✅ | ✅ | ✅ | ✅ | GVP (XML) |
| Yapi Kredi | 0067 | ✅ | ✅ | ✅ | ✅ | ✅ | Posnet (XML) |
| Akbank (Direct) | 0046 | ✅ | ✅ | ✅ | ✅ | ❌ | JSON API + HMAC-SHA512 |
| Vakifbank | 0015 | ✅ | ✅ | ❌ | ❌ | ❌ | VPos XML |
| Denizbank | 0134 | ✅ | ✅ | ✅ | ✅ | ❌ | InterPOS |
| QNB Finansbank (Direct) | 0111 | ✅ | ✅ | ✅ | ✅ | ❌ | Form POST |
NestPay (EST) Banks
These banks use the NestPay/EST payment gateway:
| Bank | Bank Code | Sale | 3D Secure | Cancel | Refund | Query |
|------|-----------|:----:|:---------:|:------:|:------:|:-----:|
| Is Bankasi | 0064 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Akbank | 9046 | ✅ | ✅ | ✅ | ✅ | ✅ |
| QNB Finansbank | 9111 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Halkbank | 0012 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ziraat Bankasi | 0010 | ✅ | ✅ | ✅ | ✅ | ✅ |
| TEB | 0032 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Sekerbank | 0059 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Anadolubank | 0135 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Alternatif Bank | 0124 | ✅ | ✅ | ✅ | ✅ | ✅ |
| ING Bank | 0099 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Turkiye Finans | 0206 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Cardplus | 9998 | ✅ | ✅ | ✅ | ✅ | ✅ |
Participation Banks (Katilim Bankalari)
| Bank | Code | Sale | 3D Secure | Cancel | Refund | Query | Protocol |
|------|------|:----:|:---------:|:------:|:------:|:-----:|----------|
| Kuveyt Turk | 0205 | ✅ | ✅ | ✅ | ✅ | ✅ | XML + SHA256 |
| Albaraka Turk | 0203 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON |
Payment Institutions
| Institution | Code | Sale | 3D Secure | Cancel | Refund | Query | Notes |
|-------------|------|:----:|:---------:|:------:|:------:|:-----:|-------|
| Iyzico | 9997 | ✅ | ✅ | ✅ | ✅ | ❌ | Marketplace support |
| Moka | 9984 | ✅ | ✅ | ✅ | ✅ | ❌ | SHA256 CheckKey auth |
| PayTR | 9994 | ✅ | ✅ | ✅ | ✅ | ✅ | iFrame integration |
| iPara | 9995 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
| Hepsipay | 9992 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
| Tosla (AKOde) | 9970 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
| Lidio | 9971 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
| PayU | 9996 | ✅ | ✅ | ✅ | ✅ | ✅ | OAuth 2.0 REST |
| Paratika | 9999 | ✅ | ✅ | ✅ | ✅ | ✅ | Payten MSU |
| Payten | 9993 | ✅ | ✅ | ✅ | ✅ | ✅ | MSU API |
| ZiraatPay | 9982 | ✅ | ✅ | ✅ | ✅ | ✅ | Payten-based |
| VakifPayS | 9981 | ✅ | ✅ | ✅ | ✅ | ✅ | Payten-based |
| Sipay | 9991 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| QNBpay | 9990 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| PayBull | 9988 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| Parolapara | 9987 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| IQmoney | 9986 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| Vepara | 9983 | ✅ | ✅ | ✅ | ✅ | ✅ | CCPayment |
| ParamPos | 9989 | ✅ | ✅ | ✅ | ✅ | ✅ | SOAP API |
| Tami | 9980 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
| Ahlpay | 9985 | ✅ | ✅ | ✅ | ✅ | ✅ | JSON API |
Legend
- ✅ Fully supported
- ❌ Not supported / Not implemented
- Bank Codes starting with
9xxxare virtual codes for payment institutions
API Reference
Authentication
All operations require a VirtualPOSAuth object:
import { VirtualPOSAuth, BankCode } from '@vignetim/pos';
const auth = new VirtualPOSAuth({
// Required fields
bankCode: BankCode.GarantiBBVA, // Bank identifier
merchantId: '7000679', // Merchant ID from bank
merchantUser: 'PROVAUT', // API username
merchantPassword: '123qweASD/', // API password
// Optional fields
merchantStoreKey: '12345678', // Required for 3D Secure
terminalId: '30691298', // Required by some banks
testPlatform: true, // Use test environment
options: {}, // Bank-specific options
});Sale Transaction
2D (Non-3D Secure) Payment
import { VPOSClient, SaleRequest, Currency } from '@vignetim/pos';
const request = new SaleRequest({
orderNumber: 'ORDER-001',
customerIpAddress: '192.168.1.100',
amount: 100.00,
currency: Currency.TRY,
installment: 1,
card: {
holderName: 'John Doe',
cardNumber: '4111111111111111',
expiryMonth: 12,
expiryYear: 2028,
cvv: '123',
},
// Optional: Billing information
billingInfo: {
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
phone: '+905551234567',
address: '123 Main Street',
city: 'Istanbul',
country: 'TR',
postalCode: '34000',
},
});
const response = await VPOSClient.sale(request, auth);Installment Payment
const request = new SaleRequest({
orderNumber: 'ORDER-002',
customerIpAddress: '192.168.1.100',
amount: 1200.00,
currency: Currency.TRY,
installment: 12, // 12-month installment
card: {
holderName: 'John Doe',
cardNumber: '4111111111111111',
expiryMonth: 12,
expiryYear: 2028,
cvv: '123',
},
});3D Secure Flow
3D Secure payments require a two-step process:
Step 1: Initiate 3D Payment
import { VPOSClient, SaleRequest, Payment3DConfig, SaleResponseStatus } from '@vignetim/pos';
const request = new SaleRequest({
orderNumber: 'ORDER-3D-001',
customerIpAddress: '192.168.1.100',
amount: 250.00,
currency: Currency.TRY,
installment: 1,
card: {
holderName: 'John Doe',
cardNumber: '4111111111111111',
expiryMonth: 12,
expiryYear: 2028,
cvv: '123',
},
// Enable 3D Secure
payment3D: new Payment3DConfig({
enabled: true,
returnUrl: 'https://yoursite.com/payment/callback',
callbackUrl: 'https://yoursite.com/payment/notify', // Optional
}),
});
const response = await VPOSClient.sale(request, auth);
// Handle 3D redirect
if (response.status === SaleResponseStatus.RedirectUrl) {
// Redirect customer to the URL
console.log('Redirect URL:', response.message);
// res.redirect(response.message);
} else if (response.status === SaleResponseStatus.RedirectHtml) {
// Render the HTML form that auto-submits
console.log('HTML Form:', response.secure3D?.htmlContent);
// res.send(response.secure3D.htmlContent);
}Step 2: Handle 3D Callback
import { VPOSClient, Sale3DResponseRequest } from '@vignetim/pos';
// In your callback handler (Express example)
app.post('/payment/callback', async (req, res) => {
const callbackRequest = new Sale3DResponseRequest({
orderNumber: 'ORDER-3D-001',
rawData: req.body, // POST data from bank
});
const response = await VPOSClient.sale3DResponse(callbackRequest, auth);
if (response.isSuccess()) {
// Payment completed successfully
res.redirect('/payment/success');
} else {
// Payment failed
res.redirect('/payment/failed?error=' + response.message);
}
});Cancel (Void)
Cancel a same-day transaction (before settlement):
import { VPOSClient, CancelRequest } from '@vignetim/pos';
const cancelRequest = new CancelRequest({
orderNumber: 'ORDER-001', // Original order number
transactionId: 'TXN123456', // Transaction ID from sale response
});
const response = await VPOSClient.cancel(cancelRequest, auth);
if (response.status === ResponseStatus.Success) {
console.log('Transaction cancelled successfully');
}Refund
Refund a transaction (full or partial):
import { VPOSClient, RefundRequest, Currency } from '@vignetim/pos';
// Full refund
const fullRefund = new RefundRequest({
orderNumber: 'ORDER-001',
transactionId: 'TXN123456',
amount: 100.00,
currency: Currency.TRY,
});
// Partial refund
const partialRefund = new RefundRequest({
orderNumber: 'ORDER-001',
transactionId: 'TXN123456',
amount: 50.00, // Refund only 50 TRY
currency: Currency.TRY,
});
const response = await VPOSClient.refund(fullRefund, auth);
if (response.status === ResponseStatus.Success) {
console.log('Refunded amount:', response.refundedAmount);
}Transaction Query
Query the status of a transaction:
import { VPOSClient, SaleQueryRequest } from '@vignetim/pos';
const queryRequest = new SaleQueryRequest({
orderNumber: 'ORDER-001',
// OR
transactionId: 'TXN123456',
});
const response = await VPOSClient.saleQuery(queryRequest, auth);
console.log('Transaction Status:', response.transactionStatus);
console.log('Amount:', response.amount);
console.log('Date:', response.transactionDate);Installment Query
Query available installment options:
import { VPOSClient, BINInstallmentQueryRequest } from '@vignetim/pos';
// Query by card BIN
const request = new BINInstallmentQueryRequest({
bin: '411111', // First 6 digits of card
amount: 1000.00,
currency: Currency.TRY,
});
const response = await VPOSClient.binInstallmentQuery(request, auth);
for (const option of response.installments) {
console.log(`${option.count} months: ${option.monthlyAmount} TRY/month`);
}Bank-Specific Configuration
Garanti BBVA
const auth = new VirtualPOSAuth({
bankCode: BankCode.GarantiBBVA,
merchantId: '7000679', // Merchant ID (Uye Is Yeri No)
merchantUser: 'PROVAUT', // Provision Username
merchantPassword: '123qweASD/', // Provision Password
merchantStoreKey: '12345678', // 3D Secure Store Key
terminalId: '30691298', // Terminal ID
testPlatform: true,
});Yapi Kredi (Posnet)
const auth = new VirtualPOSAuth({
bankCode: BankCode.YapiKrediBankasi,
merchantId: '6706598320', // Merchant ID
merchantUser: '67005551', // Terminal ID (used as user)
merchantPassword: '', // Not used for Posnet
merchantStoreKey: '10,10,10,10,10,10,10,10', // Encryption Key
terminalId: '67005551',
testPlatform: true,
});NestPay Banks (Akbank, Is Bankasi, etc.)
const auth = new VirtualPOSAuth({
bankCode: BankCode.IsBankasi, // Or any NestPay bank
merchantId: '100100000', // Client ID
merchantUser: 'ISBANK', // Username
merchantPassword: 'ISBANK123', // Password
merchantStoreKey: 'TRPS1234', // 3D Secure Store Key
testPlatform: true,
});Kuveyt Turk
const auth = new VirtualPOSAuth({
bankCode: BankCode.KuveytTurk,
merchantId: '496', // Customer ID (Musteri No)
merchantUser: '496', // Merchant ID (Magaza Kodu)
merchantPassword: 'apiuser', // API Username
merchantStoreKey: 'Api123', // API Password
testPlatform: true,
});Albaraka Turk
const auth = new VirtualPOSAuth({
bankCode: BankCode.AlbarakaTurk,
merchantId: 'merchant123', // Uye Isyeri No
terminalId: 'terminal123', // Terminal No
merchantUser: 'username', // API Username
merchantPassword: 'password', // API Password
testPlatform: true,
});Iyzico
const auth = new VirtualPOSAuth({
bankCode: BankCode.Iyzico,
merchantId: 'sandbox-xxxxx', // API Key
merchantUser: '', // Not used
merchantPassword: 'sandbox-secret-xxxxx', // Secret Key
testPlatform: true,
});PayTR
const auth = new VirtualPOSAuth({
bankCode: BankCode.PayTR,
merchantId: 'merchant_id', // Merchant ID
merchantUser: 'merchant_key', // Merchant Key
merchantPassword: 'merchant_salt', // Merchant Salt
testPlatform: true,
});iPara
const auth = new VirtualPOSAuth({
bankCode: BankCode.IPara,
merchantId: 'public_key', // Public Key
merchantUser: '', // Not used
merchantPassword: 'private_key', // Private Key
testPlatform: true,
});PayU
const auth = new VirtualPOSAuth({
bankCode: BankCode.PayU,
merchantId: 'pos_id', // POS ID (merchant_pos_id)
merchantUser: 'client_id', // OAuth Client ID
merchantPassword: 'client_secret', // OAuth Client Secret
testPlatform: true,
});CCPayment Banks (Sipay, QNBpay, PayBull, etc.)
const auth = new VirtualPOSAuth({
bankCode: BankCode.Sipay, // Or QNBpay, PayBull, Parolapara, IQmoney, Vepara
merchantId: 'merchant_id', // Uye Isyeri ID
merchantUser: 'app_key', // Uygulama Anahtari
merchantPassword: 'app_secret', // Uygulama Parolasi
merchantStoreKey: 'merchant_key', // Uye Isyeri Anahtari
testPlatform: true,
});NestJS Integration
Module Setup
// app.module.ts
import { Module } from '@nestjs/common';
import { PosModule } from '@vignetim/pos/nestjs';
@Module({
imports: [
PosModule.forRoot({
timeout: 30000,
debug: process.env.NODE_ENV === 'development',
}),
],
})
export class AppModule {}Service Usage
// payment.service.ts
import { Injectable } from '@nestjs/common';
import { PosService } from '@vignetim/pos/nestjs';
import { SaleRequest, VirtualPOSAuth, Currency, BankCode } from '@vignetim/pos';
@Injectable()
export class PaymentService {
constructor(private readonly posService: PosService) {}
async processPayment(orderData: any) {
const auth = new VirtualPOSAuth({
bankCode: BankCode.GarantiBBVA,
merchantId: process.env.POS_MERCHANT_ID,
merchantUser: process.env.POS_USER,
merchantPassword: process.env.POS_PASSWORD,
merchantStoreKey: process.env.POS_STORE_KEY,
terminalId: process.env.POS_TERMINAL_ID,
testPlatform: process.env.NODE_ENV !== 'production',
});
const request = new SaleRequest({
orderNumber: orderData.orderId,
customerIpAddress: orderData.clientIp,
amount: orderData.amount,
currency: Currency.TRY,
installment: orderData.installment || 1,
card: orderData.card,
});
return this.posService.sale(request, auth);
}
}BIN (Card Number) Lookup
Identify card type and issuing bank from card number:
import { VPOSClient } from '@vignetim/pos';
// Query by card number
const result = VPOSClient.queryBIN('411111');
console.log('Bank:', result.bankName);
console.log('Card Brand:', result.cardBrand); // Visa, Mastercard, etc.
console.log('Card Type:', result.cardType); // Credit, Debit
console.log('Is Commercial:', result.isCommercial);
// Check card type
const isDebit = VPOSClient.isDebitCard('411111');
const isCommercial = VPOSClient.isCommercialCard('411111');
// Get issuing bank
const bankName = VPOSClient.getCardBank('411111');Error Handling
Response Status Codes
import { SaleResponseStatus, ResponseStatus, SaleQueryResponseStatus } from '@vignetim/pos';
// Sale Response Statuses
SaleResponseStatus.Success // Payment completed
SaleResponseStatus.Error // Payment failed
SaleResponseStatus.RedirectUrl // Redirect to 3D URL
SaleResponseStatus.RedirectHtml // Render 3D HTML form
// General Response Statuses (Cancel, Refund)
ResponseStatus.Success // Operation successful
ResponseStatus.Error // Operation failed
// Query Response Statuses
SaleQueryResponseStatus.Success // Transaction found
SaleQueryResponseStatus.Error // Query failed
SaleQueryResponseStatus.NotFound // Transaction not foundError Response
const response = await VPOSClient.sale(request, auth);
if (response.isError()) {
console.error('Error Message:', response.message);
console.error('Error Code:', response.errorCode);
console.error('Raw Response:', response.rawResponse);
}Common Error Codes
| Bank | Code | Description |
|------|------|-------------|
| All | 05 | Transaction not approved |
| All | 12 | Invalid transaction |
| All | 13 | Invalid amount |
| All | 14 | Invalid card number |
| All | 51 | Insufficient funds |
| All | 54 | Expired card |
| All | 57 | Transaction not permitted |
| All | 91 | Issuer unavailable |
| Garanti | 0054 | Card expired |
| NestPay | 99 | General error |
| Vakifbank | 0057 | Card restricted |
Test Cards
The library includes comprehensive test card data for development and testing.
Using Built-in Test Cards
import {
NestPayTestCards,
GarantiTestCards,
IyzicoTestCards,
TestCredentials,
getTestCardsByBank,
getRandomTestCard,
} from '@vignetim/pos';
// Get a specific bank's test cards
const garantiCards = GarantiTestCards;
const isbankCards = getTestCardsByBank('Is Bankasi');
// Get a random test card
const randomCard = getRandomTestCard();
// Use test credentials
const auth = new VirtualPOSAuth({
bankCode: BankCode.GarantiBBVA,
...TestCredentials.GarantiBBVA,
testPlatform: true,
});Test Cards Reference
NestPay Banks (Is Bankasi, Akbank, Halkbank, Ziraat, etc.)
| Bank | Card Number | Expiry | CVV | 3D Password |
|------|-------------|--------|-----|-------------|
| Is Bankasi | 4508034508034509 | 12/26 | 000 | a |
| Is Bankasi | 5406675406675403 | 12/26 | 000 | a |
| Akbank | 4355084355084358 | 12/30 | 000 | a |
| Akbank | 5571135571135575 | 12/30 | 000 | a |
| Ziraat | 4546711234567894 | 12/26 | 000 | a |
| Ziraat | 5401341234567891 | 12/26 | 000 | a |
| Halkbank | 5818775818772285 | 12/26 | 001 | a |
| Halkbank | 4531444531442283 | 12/26 | 001 | a |
Garanti BBVA
| Card Number | Expiry | CVV | Type |
|-------------|--------|-----|------|
| 5289394722895016 | 01/25 | 030 | Mastercard |
| 5406697543211173 | 04/27 | 423 | Mastercard |
| 5170410000000004 | 12/30 | 123 | Debit |
| 5400360000000003 | 12/30 | 123 | Credit |
Yapi Kredi
| Card Number | Expiry | CVV | 3D Password |
|-------------|--------|-----|-------------|
| 4506347027911094 | 03/25 | 000 | 34020 |
| 5400619360964581 | 03/25 | 000 | 34020 |
QNB Finansbank
| Card Number | Expiry | CVV | Type |
|-------------|--------|-----|------|
| 4022774022774026 | 12/26 | 000 | Credit |
| 4155650100416111 | 01/25 | 123 | Credit |
| 5311570000000005 | 12/30 | 123 | Credit |
Kuveyt Turk
| Card Number | Expiry | CVV | 3D Password |
|-------------|--------|-----|-------------|
| 5188961939192544 | 06/25 | 929 | 123456 |
Iyzico (Sandbox)
For Iyzico sandbox, expiry and CVV can be any valid future date and 3-digit number.
| Card Number | Bank | Type | Notes |
|-------------|------|------|-------|
| 5890040000000016 | Akbank | Debit | Success |
| 5526080000000006 | Akbank | Credit | Success |
| 4766620000000001 | Denizbank | Debit | Success |
| 4603450000000000 | Denizbank | Credit | Success |
| 9792072000017956 | Akbank | Troy | Success |
| 374427000000003 | Garanti | Amex | CVV: 1234 |
Iyzico Error Cards:
| Card Number | Error Type |
|-------------|------------|
| 4111111111111129 | Insufficient funds |
| 4129111111111111 | Do not honor |
| 4125111111111115 | Expired card |
| 4124111111111116 | Invalid CVC |
CCPayment (Sipay, QNBpay, PayBull, etc.)
| Card Number | Expiry | CVV | Notes |
|-------------|--------|-----|-------|
| 4022780520669303 | 01/50 | 988 | Works with all CCPayment providers |
Foreign/International Cards
| Card Number | Type | Notes |
|-------------|------|-------|
| 5400010000000004 | Credit | Non-Turkish |
| 4054180000000007 | Debit | Non-Turkish |
Test Credentials
// Garanti BBVA
{
merchantId: '7000679',
merchantUser: '30691297',
merchantPassword: '123qweASD/',
merchantStoreKey: '12345678',
terminalId: '30691298',
}
// Is Bankasi
{
merchantId: '700655000200',
merchantUser: 'ISBANKAPI',
merchantPassword: 'ISBANK07',
merchantStoreKey: 'TRPS0200',
}
// QNBpay
{
merchantId: '20158',
merchantUser: '07fb70f9d8de575f32baa6518e38c5d6',
merchantPassword: '61d97b2cac247069495be4b16f8604db',
merchantStoreKey: '$2y$10$N9IJkgazXMUwCzpn7NJrZePy3v.dIFOQUyW4yGfT3eWry6m.KxanK',
}Migration from Other Libraries
From CP.VPOS (C#)
This library is a TypeScript port of CP.VPOS with an identical API structure:
| CP.VPOS (C#) | @vignetim/pos (TypeScript) |
|--------------|---------------------------|
| VirtualPOSFactory.CreateVirtualPOSService() | VPOSClient.sale() |
| SaleRequest | SaleRequest |
| SaleResponse | SaleResponse |
| VirtualPOSAuth | VirtualPOSAuth |
| BankCode.GarantiBBVA | BankCode.GarantiBBVA |
From nestpay-js
// Before (nestpay-js)
const nestpay = new NestPay({ clientId: '...', storeKey: '...' });
await nestpay.pay({ amount: 100, ... });
// After (@vignetim/pos)
const auth = new VirtualPOSAuth({ bankCode: BankCode.IsBankasi, merchantId: '...', ... });
const request = new SaleRequest({ amount: 100, ... });
await VPOSClient.sale(request, auth);Project Structure
src/
├── enums/ # Enumerations (BankCode, Currency, etc.)
├── models/ # Data models (Request/Response classes)
├── interfaces/ # TypeScript interfaces
├── helpers/ # Utility functions (HTTP, XML, Crypto)
├── services/ # Core services (Bank, BIN)
├── data/ # Test cards and credentials
├── integrations/
│ ├── banks/
│ │ ├── garanti/ # Garanti BBVA (GVP Protocol)
│ │ ├── yapikredi/ # Yapi Kredi (Posnet Protocol)
│ │ ├── akbank/ # Akbank Direct (JSON API)
│ │ ├── vakifbank/ # Vakifbank (XML VPos)
│ │ ├── denizbank/ # Denizbank (InterPOS)
│ │ ├── qnb-finansbank/ # QNB Finansbank Direct
│ │ ├── kuveytturk/ # Kuveyt Turk (XML + SHA256)
│ │ ├── albaraka/ # Albaraka Turk (JSON)
│ │ └── nestpay/ # NestPay banks (EST Protocol)
│ └── payment-institutions/
│ ├── iyzico/ # Iyzico
│ ├── moka/ # Moka
│ ├── paytr/ # PayTR
│ ├── ipara/ # iPara
│ ├── hepsipay/ # Hepsipay
│ ├── tosla/ # Tosla (AKOde)
│ ├── lidio/ # Lidio
│ ├── payu/ # PayU
│ ├── payten/ # Payten, Paratika, ZiraatPay, VakifPayS
│ ├── ccpayment/ # Sipay, QNBpay, PayBull, Parolapara, IQmoney, Vepara
│ ├── parampos/ # ParamPos
│ ├── tami/ # Tami
│ └── ahlpay/ # Ahlpay
├── nestjs/ # NestJS module integration
├── vpos-client.ts # Main client facade
└── index.ts # Public exportsAdding Custom Bank Integration
import { BaseVirtualPOSService, IVirtualPOSService, VPOSClient, VirtualPOSAuth, SaleRequest, SaleResponse } from '@vignetim/pos';
class CustomBankService extends BaseVirtualPOSService implements IVirtualPOSService {
readonly bankCode = 'CUSTOM';
readonly bankName = 'Custom Bank';
protected getApiUrl(auth: VirtualPOSAuth): string {
return auth.testPlatform ? 'https://test-api.bank.com' : 'https://api.bank.com';
}
protected get3DUrl(auth: VirtualPOSAuth): string {
return this.getApiUrl(auth) + '/3d';
}
async sale(request: SaleRequest, auth: VirtualPOSAuth): Promise<SaleResponse> {
// Implement bank-specific logic
request.validateOrThrow();
// Make API call...
// Parse response...
// Return SaleResponse
}
async sale3DResponse(request: Sale3DResponseRequest, auth: VirtualPOSAuth): Promise<SaleResponse> {
// Handle 3D callback
}
async cancel(request: CancelRequest, auth: VirtualPOSAuth): Promise<CancelResponse> {
// Implement cancel logic
}
async refund(request: RefundRequest, auth: VirtualPOSAuth): Promise<RefundResponse> {
// Implement refund logic
}
async saleQuery(request: SaleQueryRequest, auth: VirtualPOSAuth): Promise<SaleQueryResponse> {
// Implement query logic
}
}
// Register the custom service
VPOSClient.registerService('CUSTOM', CustomBankService);Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/vignetim/pos.git
cd pos
# Install dependencies
npm install
# Run in development mode
npm run dev
# Run tests
npm test
# Build
npm run build
# Lint
npm run lint
# Format
npm run formatLicense
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- Issues: GitHub Issues
- Documentation: Wiki
- Email: [email protected]
Made with by Vignetim
