npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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.

npm version License: MIT TypeScript

Table of Contents


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/pos

Requirements

  • 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 9xxx are 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 found

Error 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 exports

Adding 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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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 format

License

This project is licensed under the MIT License - see the LICENSE file for details.


Support


Made with by Vignetim