Virtual POS Transactions General Concepts
Garanti Virtual POS is a secure payment solution created to receive credit card payments for online sales.
Merchants can open an online branch in their stores and turn it into a sales platform that never closes with Garanti Virtual POS. This will contribute to increasing both the number of customers and turnover.
The following transactions are generally performed under Garanti Virtual POS:
- Sales Transactions
- Common Payment Page Operations
- Cancellation Procedures
- Refund Procedures
- Closing Operations
- Inquiry Procedures
This document describes the steps required for merchants to enable 3D-free Sales transactions under Garanti Virtual POS, the transactions that must be performed within each step, and the structure of the transaction requests sent and response messages received.
Virtual POS Common Payment Transactions
The sub-transaction types under Virtual POS Common Payment transactions are generally as follows:
- Advance: This is the type of transaction that enables advance purchase.
- Installment Sales: This is the transaction type that enables installment transactions.
- Preauthorization Preauth - Preauthorization process ensures that the amount to be taken from the card is blocked between 7 and 9 days by blocking an amount on the card. In this way, it is guaranteed that the card will not receive a limit error when the authorization is closed. During this period, pre-authorization closing process must be performed in order for the amount to be recognized. At the end of the pre-authorization blocking period, the amount block on the card is removed. In the pre-authorization closing requests sent after the end of this period, the transaction result is returned according to whether the card has a limit or not.
- Sale with Points: This is the transaction type that enables purchasing with bonus. Total transaction amount is sent in the Amount field. In UsedAmount field, the bonus rate to be used is sent. Debit is passed to the card side as amount - usedbonus amount. Used bonus is deducted from card bonuses. Bonus utilization is reflected in the workplace accounting the next day regardless of the workplace working conditions.
- Repeat Sales: This is when the sales transaction is realized at regular intervals and goes to authorization.
- DCC: DCC (dynamic currency conversion) is a system that ensures that the amount to be reflected on the card side in transactions made to foreign bank cards is made at the exchange rate of the card. In this system, the transaction amount is reflected to the merchant side in TL. The card side is reflected with the selected exchange rate. In this way, the cardholder clearly knows the amount to be reflected on the statement. For this transaction, the merchant and the bank side earn commission. Before the DCC transaction, DCC query is performed to obtain the supported exchange rates and exchange rate values. These values are reflected on the screen and the customer is asked to select one of the TL or incoming exchange rate values. The transaction is realized at the selected exchange rate.
- Multi Currency: Transactions in foreign currencies other than Turkish Lira.
- Common Card: The Common Card is a card payment system that regulates the cash and document flow that occurs in the sales made by companies to their customers and allows for term shopping.
- Forward Sale: The process of receiving the sales price on a specified date.
3D Concept
3D Secure is a version of the application on VirtualPoS where cardholders are verified with a password on PoS. The cardholder is directed to the verification screens of the card bank to use a password in the transaction. By entering the information requested by the bank on these screens, the cardholder shows that the card actually used is a card belonging to him.
After verification, the verification status is returned to the merchant bank (merchant). Then, depending on the status of the 3D information, the authorization process is carried out or the transaction is terminated.
3D Secure is an application supported by Master, Visa and American Express (Amex) cards. Merchants using 3D model (information about merchant models is given below) are required to come directly to the authorization without performing 3D verification for cards other than Mastercard, Visa and Amex. Since 3D secure is not supported, the responsibility for Fraud in such transactions belongs to the merchant. The merchant must take measures to protect itself.
Virtual POS Transactions without 3D
This is when the transaction is concluded without touching any 3D secure stage during the authorization flow. In this type of transaction, the customer's "I didn't do it" objections turn into a chargeback request. The chargeback process is evaluated by requesting evidence from the merchant that the transaction was made by the customer. In 3D transactions with successful verification, "I did not do it" claims are terminated by the bank.
Test / Prod Environment Selections:
For Virtual POS Sales transactions, it is possible to proceed with 2 different methods by the merchant. If the merchant wishes, they can make all the improvements in the test environment. Alternatively, necessary improvements can be made for these transactions directly in the broadcast environment.
According to the method to be selected by the merchant, before starting Virtual POS sales transactions, the first transactions must be made according to the appropriate one of the following headings:
If the work to be done is carried out in a test environment, the following predefined values can be used as they are:
Parameter |
Value |
MerchantID |
7000679 |
ProvUserID |
PROVAUT / PROVRFN / PROVOOS |
ProvisionPassword |
123qweASD/ |
TerminalID |
30691297 |
StoreKey |
12345678 |
In the studies to be carried out in the test environment "https://sanalposprovtest.garantibbva.com.tr/VPServlet" url will be used.
A panel where the operations performed in the test environment can be monitored and displayed at this address you can access.
Variable |
Value |
Kullanıcı Adı |
99999999999 |
Passcode |
Destek.1 |
Password |
147852 |
Not: In the event of an error in the password process, please try a second time before making a second attempt. Send Us a Question Please provide information with the form.
List of all test cards that can be used in the test environment from this page you can reach.
When proceeding with this method, the passwords to be used by the merchant in the setup as the first step are (“PROVAUT”,“PROVOOS”, “PROVRFN” ve “3D” (storekey) passwords) Virtual POS First Steps virtual POS management panel as specified in the document.
Passwords and accounts created in this way will be used in the next steps.
In the studies to be carried out in PROD environment "https://sanalposprov.garanti.com.tr/VPServlet" url will be used.
Hash Algorithm
This document explains step by step how to create the data
required for the <HashData> tag in the request message, which is used
under many transaction types.
The <HashData> tag in the request messages is the
field that allows the password verification of the user. Hash creation details
are explained separately below.
In the new VirtualPoS application, the HASH structure is
used to prevent the password of the terminal from circulating openly.
Hash account:
1. SHA1 in the calculation of hashedpassword information
2. SHA512 algorithm is used to calculate the hashvalue.
In the hash calculation, a two-part HASH structure is used.
In the first stage, the hashedpassword value will be obtained using the SHA1
algorithm by juxtaposing the provisioning password with the terminal number.
The operations required to generate hash are presented
below for different programming languages:
public static string Sha1(string text) {\n var provider = CodePagesEncodingProvider.Instance;\n Encoding.RegisterProvider(provider);\n\n var cryptoServiceProvider = new SHA1CryptoServiceProvider();\n var inputbytes = cryptoServiceProvider.ComputeHash(Encoding.GetEncoding(\"ISO-8859-9\").GetBytes(text));\n\n var builder = new StringBuilder();\n for (int i = 0; i < inputbytes.Length; i++) {\n builder.Append(string.Format(\"{0,2:x}\", inputbytes[i]).Replace(\" \", \"0\"));\n }\n\n return builder.ToString().ToUpper();\n}\n\npublic static string Sha512(string text) {\n var provider = CodePagesEncodingProvider.Instance;\n Encoding.RegisterProvider(provider);\n\n var cryptoServiceProvider = new SHA512CryptoServiceProvider();\n var inputbytes = cryptoServiceProvider.ComputeHash(Encoding.GetEncoding(\"ISO-8859-9\").GetBytes(text));\n\n var builder = new StringBuilder();\n for (int i = 0; i < inputbytes.Length; i++) {\n builder.Append(string.Format(\"{0,2:x}\", inputbytes[i]).Replace(\" \", \"0\"));\n }\n\n return builder.ToString().ToUpper();\n}\n\npublic static string GetHashData(string provisionPassword, string terminalId, string orderId, int installmentCount, string storeKey, ulong amount, int currencyCode, string successUrl, string type, string errorUrl) {\n var hashedPassword = Sha1(provisionPassword + \"0\" + terminalId);\n return Sha512(terminalId + orderId + amount + currencyCode + successUrl + errorUrl + type + installmentCount + storeKey + hashedPassword).ToUpper();\n}
Public Shared Function Sha1(ByVal text As String) As String\n Dim provider = CodePagesEncodingProvider.Instance\n Encoding.RegisterProvider(provider)\n Dim cryptoServiceProvider = New SHA1CryptoServiceProvider()\n Dim inputbytes = cryptoServiceProvider.ComputeHash(Encoding.GetEncoding(\"ISO-8859-9\").GetBytes(text))\n Dim builder = New StringBuilder()\n\n For i As Integer = 0 To inputbytes.Length - 1\n builder.Append(String.Format(\"{0,2:x}\", inputbytes(i)).Replace(\" \", \"0\"))\n Next\n\n Return builder.ToString().ToUpper()\nEnd Function\n\nPublic Shared Function Sha512(ByVal text As String) As String\n Dim provider = CodePagesEncodingProvider.Instance\n Encoding.RegisterProvider(provider)\n Dim cryptoServiceProvider = New SHA512CryptoServiceProvider()\n Dim inputbytes = cryptoServiceProvider.ComputeHash(Encoding.GetEncoding(\"ISO-8859-9\").GetBytes(text))\n Dim builder = New StringBuilder()\n\n For i As Integer = 0 To inputbytes.Length - 1\n builder.Append(String.Format(\"{0,2:x}\", inputbytes(i)).Replace(\" \", \"0\"))\n Next\n\n Return builder.ToString().ToUpper()\nEnd Function\n\nPublic Shared Function GetHashData(provisionPassword As String, terminalId As String, orderId As String, installmentCount As Integer, storeKey As String, amount As ULong, currencyCode As Integer, successUrl As String, type As String, errorUrl As String) As String\n Dim hashedPassword As String = Sha1(provisionPassword & \"0\" & terminalId)\n Return Sha512(terminalId & orderId & amount & currencyCode & successUrl & errorUrl & type & installmentCount & storeKey & hashedPassword).ToUpper()\nEnd Function
public static String calculateHash(String data, String algorithm, String charset) throws UnsupportedEncodingException, NoSuchAlgorithmException {\n\tMessageDigest md = MessageDigest.getInstance(algorithm);\n\tbyte[] databytes = data.getBytes(charset);\n\t\n\tmd.update(databytes);\n byte[] hashBytes = md.digest();\n \n return byteArray2HexaDecimal(hashBytes);\n}\n\npublic static String sha1(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException { \n return calculateHash(data, \"SHA-1\", \"ISO-8859-9\").toUpperCase();\n}\n\npublic static String sha512(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException { \n return calculateHash(data, \"SHA-512\", \"ISO-8859-9\").toUpperCase();\n}\n\npublic static String getHashData(String provisionPassword, String terminalId, String orderId, int installmentCount, String storeKey, long amount, int currencyCode, String successUrl, String type, String errorUrl) throws NoSuchAlgorithmException {\n String hashedPassword = sha1(provisionPassword + \"0\" + terminalId);\n return sha512(terminalId + orderId + amount + currencyCode + successUrl + errorUrl + type + installmentCount + storeKey + hashedPassword).toUpperCase();\n}
private function GenerateSecurityData($terminalId)\n {\n $password = \"password\";\n $data = [\n $password,\n str_pad((int)$terminalId, 9, 0, STR_PAD_LEFT)\n ];\n $shaData = sha1(implode('', $data));\n return strtoupper($shaData);\n }\n\n public function GenerateHashData()\n {\n $orderId = \"order_id\"; //must be uniqe\n $terminalId = \"terminal_id\"; //must be integer\n $amount = \"100\"; //amount\n $currencyCode = \"currency_code\"; //must be int\n $storeKey = \"\";\n $installmentCount = 0;\n $successUrl = \"https://localhost/success\";\n $errorUrl = \"https://localhost/error\";\n $type = \"\",\n $hashedPassword = GenerateSecurityData($terminalId); \n return strtoupper(hash('sha512', $terminalId . $orderId . $amount . $currencyCode . $successUrl . $errorUrl . $type . $installmentCount . $storeKey . $hashedPassword));\n }
Virtual POS Common Payment General Form Structure for All Transaction Types
<form method=\"post\" role=\"form\" action=\"https://sanalposprovtest.garantibbva.com.tr/servlet/gt3dengine\">\n\t<!--Value alanı test ortamı için: TEST üretim ortamı için: PROD olmalıdır.-->\n\t<input type=\"hidden\" name=\"mode\" id=\"mode\" value=\"TEST\" />\n\t<!--API Sürümü-->\n\t<input type=\"hidden\" name=\"apiversion\" id=\"apiversion\" value=\"512\" />\n\t<!--Güvenlik Düzeyi (Value değeri 3d'siz: \"OOS_PAY\", 3d'li: \"3D_OOS_PAY\" olmalıdır.)-->\n\t<input type=\"hidden\" name=\"secure3dsecuritylevel\" id=\"secure3dsecuritylevel\" value=\"OOS_PAY\" />\n\t<!--Terminal Provision User ID-->\n\t<input type=\"hidden\" name=\"terminalprovuserid\" id=\"terminalprovuserid\" value=\"PROVAUT\" />\n\t<!--Terminal User ID-->\n\t<input type=\"hidden\" name=\"terminaluserid\" id=\"terminaluserid\" value=\"GARANTI\" />\n\t<!--Terimal Merchant ID-->\n\t<input type=\"hidden\" name=\"terminalmerchantid\" id=\"terminalmerchantid\" value=\"7000679\" />\n\t<!--Terminal ID-->\n\t<input type=\"hidden\" name=\"terminalid\" id=\"terminalid\" value=\"30691297\" />\n\t<!--Sipariş ID (Benzersiz bir işlem numarası olmalıdır.)-->\n\t<input type=\"hidden\" name=\"orderid\" id=\"orderid\" value=\"ef43ef579b97484d9f67d445e4b15b93\" />\n\t<!--Başarılı İşlem Dönüş Bağlantısı-->\n\t<input type=\"hidden\" name=\"successurl\" id=\"successurl\" value=\"oospayment/result\" />\n\t<!--Başarısız İşlem Dönüş Bağlantısı-->\n\t<input type=\"hidden\" name=\"errorurl\" id=\"errorurl\" value=\"oospayment/result\" />\n\t<!--Müşteri E-Posta Adresi-->\n\t<input type=\"hidden\" name=\"customeremailaddress\" id=\"customeremailaddress\" value=\"eticaret@garanti.com.tr\" />\n\t<!--Müşteri IP Adresi-->\n\t<input type=\"hidden\" name=\"customeripaddress\" id=\"customeripaddress\" value=\"192.168.0.1\" />\n\t<!--Firma Adı-->\n\t<input type=\"hidden\" name=\"companyname\" id=\"companyname\" Value=\"GARANTI TEST\" />\n\t<!--Dil Bilgisi-->\n\t<input type=\"hidden\" name=\"lang\" id=\"lang\" Value=\"tr\" />\n\t<!--İşlem Zamanı (UTC)-->\n\t<input type=\"hidden\" name=\"txntimestamp\" id=\"txntimestamp\" value=\"2023-04-30T11:31:53Z\" />\n\t<!--Yenileme Süresi-->\n\t<input type=\"hidden\" name=\"refreshtime\" id=\"refreshtime\" value=\"1\" />\n\t<!--Güvenli Hash Anahtarı (Bu alana hash algoritasmasından gelen değer girilmelidir.)-->\n\t<input type=\"hidden\" name=\"secure3dhash\" id=\"secure3dhash\" value=\"Hesaplanan hash değeri eklenmelidir.\" />\n\t<!--İşlem Yapılan Tutar-->\n\t<input type=\"hidden\" name=\"txnamount\" id=\"txnamount\" value=\"100\" />\n\n\t<!--İşlem Tipi-->\n\t<!--Ön otorizasyon işlem tipinde value değeri: \"preauth\"-->\n\t<!--Bonus kullanımında işlem tipinde value değeri: \"preauth\"-->\n\t<!--Tekrarlı satış işlem tipinde value değeri: \"preauth\"-->\n\t<!--DCC işlem tipinde value değeri: \"dccinq\"-->\n\t<!--Ortak Kart işlem tipinde value değeri: \"commercialcard\"-->\n\t<!--Futures Sale işlem tipinde value değeri: \"extendedcredit\"-->\n\t<input type=\"hidden\" name=\"txntype\" id=\"txntype\" value=\"sales\" />\n\t<!--Para Birimi value değerleri: TR: \"949\" | USD: \"840\" | EURO: \"978\" | GBP: \"826\" | JPY: \"392\"-->\n\t<input type=\"hidden\" name=\"txncurrencycode\" id=\"txncurrencycode\" value=\"949\" />\n\t<!--Taksit Sayısı (Taksit gerekmeyen işlemlerde: \"\" girilmelidir.)-->\n\t<input type=\"hidden\" name=\"txninstallmentcount\" id=\"txninstallmentcount\" value=\"\" />\n\n\t<!--EK Parametreler Bu Alana Eklenebilir Başlangıç _____________________________ -->\n\t\n\t<!--Bonus Kullanım Parametreleri Başlangıç-->\n\t<input type=\"text\" name=\"txnrewardcount\" value=\"1\"><br>\n\t<input type=\"text\" name=\"txnrewardtype1\" value=\"BNS\"><br>\n\t<input type=\"text\" name=\"txnrewardusedamount1\" value=\"100\"><br>\n\t<!--Bonus Kullanım Parametreleri Bitiş-->\n\n\t<!--Firma Bonus Kullanım Parametreleri Başlangıç-->\n\t<input type=\"text\" name=\"txnrewardcount\" value=\"1\"><br>\n\t<input type=\"text\" name=\"txnrewardtype1\" value=\"FBB\"><br>\n\t<input type=\"text\" name=\"txnrewardusedamount1\" value=\"100\"><br>\n\t<!--Firma Bonus Kullanım Parametreleri Bitiş-->\n\n\t<!--Bonus ve Firma Bonus Kullanım Parametreleri Başlangıç-->\n\t<input type=\"text\" name=\"txnrewardcount\" value=\"2\"><br>\n\t<input type=\"text\" name=\"txnrewardtype1\" value=\"BNS\"><br>\n\t<input type=\"text\" name=\"txnrewardusedamount1\" value=\"100\"><br>\n\t<input type=\"text\" name=\"txnrewardtype2\" value=\"FBB\"><br>\n\t<input type=\"text\" name=\"txnrewardusedamount2\" value=\"100\"><br>\n\t<!--Bonus ve Firma Bonus Kullanım Parametreleri Bitiş-->\n\n\t<!--Sabit Tekrarlı Satış Başlangıç-->\n\t<input type=\"hidden\" name=\"recurringtype\" value=\"R\" />\n\t<input type=\"hidden\" name=\"totalpaymentnum\" value=\"5\" /> <!--Tekrar Sayısı-->\n\t<input type=\"hidden\" name=\"frequencytype\" value=\"M\" /> <!--Ay: (M), Gün: (D), Hafta: (W)-->\n\t<input type=\"hidden\" name=\"frequencyinterval\" value=\"1\" /> <!--1 Tekrar Frekans (M/D/W)-->\n\t<input type=\"hidden\" name=\"startdate\" value=\"20221213\" /> <!--YYYYMMDD-->\n\t<!--Sabit Tekrarlı Satış Bitiş-->\n\n\t<!--Değişken Tekrarlı Satış Başlangıç-->\n\t<input type=\"hidden\" name=\"recurringamount1\" value=\"\" />\t<!-- 1. Değişken tutar -->\n\t<input type=\"hidden\" name=\"recurringamount2\" value=\"\" />\t<!-- 2. Değişken tutar -->\n\t<!-- + istenilen taktirde ek tutarlaar recurringamount3 4 5 ... olarak eklenebilir.-->\n\t<!--Değişken Tekrarlı Satış Bitiş-->\n\n\t<!--EK Parametreler Bu Alana Eklenebilir Bitiş _____________________________ -->\n\n\t<!--Müşteri Kart Üzerindeki Adı-->\n\t<input name=\"cardholdername\" value=\"Test User\" />\n\t<!--Müşteri Kart Numarası-->\n\t<input name=\"cardnumber\" value=\"5406697543211173\" />\n\t<!--Müşteri Kartı Son Kullanma Ay-->\n\t<input name=\"cardexpiredatemonth\" value=\"03\"/>\n\t<!--Müşteri Kartı Son Kullanma Yıl-->\n\t<input name=\"cardexpiredateyear\" value=\"23\" />\n\t<!--Müşteri Kartı CVC Güvenlik Numarası-->\n\t<input name=\"cardcvv2\" value=\"465\" />\n</form>
The form structure in html format below contains both common and differentiated tags for all transaction types under Virtual POS Common Payment.
The related description page of the transaction type describes in detail the changes that need to be made to this common structure.
Special Form Structure Arrangements for Virtual POS Common Payment Common Card Transaction
On the common html structure given above; the form structure required for the transaction type can be obtained by providing the following operations:
Delete the entire code block starting with the description "Additional Parameters can be added to this field" and ending with the description "Additional Parameters can be added to this field". The transaction type expressed as a "sales" in the code block should be edited as "commercialcard" as follows:
<input type=\"hidden\" name=\"txntype\" id=\"txntype\" value=\"commercialcard\" />
If the transaction is successful, the merchant writes the page url where the parameters of the successful transaction return will be met in the following code block:
<!--Successful Transaction Return Link-->\n<input type=\"hidden\" name=\"successurl\" id=\"successurl\" value=\"oospayment/result\" />
In case the transaction fails, the merchant writes the page url where the parameters of the successful transaction return will be met in the following code block:
<!--Failed Transaction Return Link-->\n<input type=\"hidden\" name=\"errorurl\" id=\"errorurl\" value=\"oospayment/result\" />
After the addition and subtraction processes specific to the transaction type mentioned above, the form block is ready and placed in the relevant html page.
After the form is filled and submitted by the visitors, the transaction continues on the Garanti BBVA Common Payment page.
Common Payment Page Transaction Answer
After the transaction is completed on the partner payment page, the system will post a form to the address specified in the previous steps (Successful transaction url or failed transaction url)
In the page at the relevant address, this form data coming from the system must be parse as described here.
The following table contains descriptions of the data coming from the system. The data obtained after the parse process should be interpreted according to this table:
Domain Name |
Description |
mdstatus |
Field where the transaction status is given numerically |
mderrormessage |
Textual description of the process status |
errmsg |
Error message in case of incorrect operation |
clientid |
Terminal id information of the merchant |
oid |
Order number sent during the transaction |
response |
|
procreturncode |
|
successurl |
The url information to be returned in case of a successful transaction |
txninstallmentcount |
Number of installments sent during the transaction |
refreshtime |
Renewal time sent when processing |
orderid |
Order number sent during the transaction |
cardholdername |
Customer name sent during the transaction |
txntype |
Transaction type specified during the transaction |
terminalmerchantid |
Merchant number during the transaction |
txnamount |
Total amount information sent during the transaction |
txntimestamp |
Process time |
terminaluserid |
Merchant username |
mode |
Processed media information |
txncurrencycode |
The currency specified at the time of the transaction |
secure3dhash |
The hash information calculated during the transaction |
apiversion |
API version information sent during the transaction |
companyname |
Merchant name |
errorurl |
The url information where the erroneous transactions sent during the transaction will be returned |
secure3dsecuritylevel |
Field information that is specified during the transaction and indicates whether the transaction will be with or without 3d |
customeremailaddress |
Customer email information sent during the transaction |
customeripaddress |
Customer IP address information sent during the transaction |
terminalid |
Merchant number |
terminalprovuserid |
Provision user information sent during the transaction |
lang |
Service response language preference information sent during the process |
Code Examples
Below are the github repo links for custom code examples written in different programming languages, including this transaction type. You can examine the codes written with predefined values through the link of your preferred programming language.
Error Codes
Error codes from this page you can reach.
Test Cards
List of test cards from this page you can reach.