diff --git a/README.md b/README.md index 35c015b9..24681398 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Bu paket ile amaçlanan; ortak bir arayüz sınıfı ile, tüm Türk banka sanal pos sistemlerinin kullanılabilmesidir. -- **EST POS** altyapısı tam olarak test edilmiş ve kullanıma hazırdır. Akbank, TEB ve Ziraat bankası test edilmiştir. +- **EST POS** (Asseco) altyapısı tam olarak test edilmiş ve kullanıma hazırdır. Akbank, TEB ve Ziraat bankası test edilmiştir. - **Garanti Virtual POS** ödeme sistemi çalışmaktadır, fakat 3D ödeme kısmının üretim ortamında test edilmesi gerekiyor. @@ -16,7 +16,18 @@ Bu paket ile amaçlanan; ortak bir arayüz sınıfı ile, tüm Türk banka sanal - **Kuveyt POS** 3d secure ödeme desteği eklenmiştir, test edildikçe, sorunları bulundukça hatalar giderilecek. -### Özellikler +### Ana başlıklar +- [Özellikler](#ozellikler) +- [Latest updates](#latest-updates) +- [Minimum Gereksinimler](#minimum-gereksinimler) +- [Kurulum](#kurulum) +- [Farklı Banka Sanal Poslarını Eklemek](#farkli-gatewayler-tek-islem-akisi) +- [Örnek Kodlar](#ornek-kodlar) +- [Troubleshoots](#troubleshoots) +- [Genel Kültür](#genel-kultur) +- [Docker ile test ortamı](#docker-ile-test-ortami) + +### Ozellikler - Standart E-Commerce modeliyle ödeme (`AbstractGateway::MODEL_NON_SECURE`) - 3D Secure modeliyle ödeme (`AbstractGateway::MODEL_3D_SECURE`) - 3D Pay modeliyle ödeme (`AbstractGateway::MODEL_3D_PAY`) @@ -26,8 +37,8 @@ Bu paket ile amaçlanan; ortak bir arayüz sınıfı ile, tüm Türk banka sanal - Sipariş/Para iadesi yapma (`AbstractGateway::TX_REFUND`) - Sipariş iptal etme (`AbstractGateway::TX_CANCEL`) -#### Farklı Gateway'ler Tek işlem akışı -* Farklı bankaya geçiş yapmak için sadece doğru `AccountFactory` method'u kullanarak account degistirmek. +#### Farkli Gateway'ler Tek islem akisi +* Farklı bankaya geçiş yapmak için sadece doğru `AccountFactory` method'u kullanarak account degistirmek yeterli. * **3D**, **3DPay**, **3DHost** ödemeler arasında geçiş yapmak için tek yapmanız gereken Account konfigurasyonunda account tipini değiştirmek (`AbstractGateway::MODEL_3D_PAY` vs.). İşlem akışı aynı olduğu için kod değiştirmenize gerek kalmıyor. * Aynı tip işlem için farklı POS Gateway'lerden dönen değerler aynı formata normalize edilmiş durumda. Yani kod güncellemenize gerek yok. * Aynı tip işlem için farklı Gateway gönderilecek değerler de genel olarak aynı formatta olacak şekilde normalize edişmiştir. @@ -67,12 +78,12 @@ require './vendor/autoload.php'; // API kullanıcı bilgileri $account = \Mews\Pos\Factory\AccountFactory::createEstPosAccount( 'akbank', //pos config'deki ayarın index name'i -'XXXXXXX', -'XXXXXXX', -'XXXXXXX', -AbstractGateway::MODEL_3D_SECURE, -'XXXXXXX', -\Mews\Pos\Gateways\EstPos::LANG_TR +'yourClientID', +'yourKullaniciAdi', +'yourSifre', +AbstractGateway::MODEL_3D_SECURE, //storetype +'yourStoreKey', +AbstractGateway::LANG_TR ); // API kullanıcı hesabı ile paket bir değişkene aktarılıyor @@ -95,8 +106,8 @@ require 'config.php'; $order = [ 'id' => 'BENZERSIZ-SIPERIS-ID', 'amount' => 1.01, - 'currency' => 'TRY', //TRY|USD|EUR - 'installment' => 0, //0 ya da 1'den büyük değer + 'currency' => 'TRY', //TRY|USD|EUR, optional. default: TRY + 'installment' => 0, //0 ya da 1'den büyük değer, optional. default: 0 //MODEL_3D_SECURE, MODEL_3D_PAY, MODEL_3D_HOST odemeler icin zorunlu //Success ve Fail URL'ler farklı olabilir ama kütüphane success ve fail için aynı kod çalıştırır. @@ -111,7 +122,7 @@ $order = [ 'rand' => md5(uniqid(time())), // EstPos, Garanti, PayFor, InterPos, VakifBank. Rastegele değer. //lang degeri verilmezse account (EstPosAccount) dili kullanılacak - 'lang' => 'tr', //tr|en. Kullanıcının yönlendirileceği banka gateway sayfasının ve gateway'den dönen mesajların dili. + 'lang' => AbstractGateway::LANG_TR, //LANG_TR|LANG_EN. Kullanıcının yönlendirileceği banka gateway sayfasının ve gateway'den dönen mesajların dili. ]; $session->set('order', $order); @@ -159,7 +170,7 @@ $pos->isSuccess(); dump($pos->getResponse()); //response içeriği için /examples/template/_payment_response.php dosyaya bakınız. ```` -### Farklı Banka Sanal Poslarını Eklemek +### Farkli Banka Sanal Poslarini Eklemek Kendi projenizin dizinindeyken ```sh $ cp ./vendor/mews/pos/config/pos.php ./pos_ayarlar.php @@ -219,7 +230,7 @@ $yeni_ayarlar = require './pos_ayarlar.php'; $pos = \Mews\Pos\Factory\PosFactory::createPosGateway($account, $yeni_ayarlar); ``` -## Örnek Kodlar +## Ornek Kodlar `/examples` dizini içerisinde. 3D ödeme örnek kodlar genel olarak kart bilgilerini website sunucusuna POST eder (`index.php` => `form.php`), @@ -233,28 +244,32 @@ Fakat, ## Troubleshoots -### session sıfırlanması +### Session sıfırlanması Cookie session kullanığınızda, kullanıcı gatewayden geri websitenize yönlendirilidiğinde session'nin sıfırlanabilir. Bu durumda PHP header'de `samesite=None` set etmeyi deneyin. Bu header'ı set ettikten sonra, taraycıda yeni session oluşturun, çünkü bu değişiklik var olan session'i etkilemez. - - -## NonSecure, 3D, 3DPay ve 3DHost ödeme modeller arasındaki farklar -- **3D** - Gateway'den (3D şifre girdiginiz sayfadan) döndükten sonra ödemeyi tamamlamak için banka gateway'ne 1 istek daha (_provizyon_ isteği) gönderir. +###Shared hosting'lerde IP tanımsız hatası +Shared hosting'lerde Cpanel'de gördüğünüz IP'den farklı olarak fiziksel sunucun bir tane daha IP'si olur. +O IP adres Cpanel'de gözükmez, hosting firmanızdan sorup öğrenmeniz gerekmekte. +Bu hatayı alırsanız hosting firmanın verdiği IP adrese'de banka gateway'i tarafından izin verilmesini sağlayın. + +## Genel Kultur +### NonSecure, 3D Secure, 3DPay ve 3DHost ödeme modeller arasındaki farklar +- **3D** - Bankaya göre farklı isimler verilebilir, örn. 3D Full. Gateway'den (3D şifre girdiginiz sayfadan) döndükten sonra ödemeyi tamamlamak için banka gateway'ne 1 istek daha (_provizyon_ isteği) gönderir. Bu isteği göndermeden ödeme tamamlanmaz. -- **3DPay** - Gateway'den (3D şifre girdiginiz sayfadan) döndükten sonra ödeme bitmiş sayılır. 3D ödeme yapıldığı gibi ekstra provizyon istek gönderilmez. +- **3DPay** - Bankaya göre farklı isimler verilebilir, örn. 3D Half. Gateway'den (3D şifre girdiginiz sayfadan) döndükten sonra ödeme bitmiş sayılır. 3D ödeme yapıldığı gibi ekstra provizyon istek gönderilmez. - **3DHost** - Kredi kart girişi için kullanıcı bankanın sayfasına yönledirilir, kredi kart bilgileri girdikten sonra bankanın 3D gateway sayfasına yönlendirilir, ordan da websitenize geri yönlendirilir. Yönlendirme sonucunda ödeme tamanlanmış olur. - **NonSecure** - Ödeme işlemi kullanıcı 3D onay işlemi yapmadan gerçekleşir. - **NonSecure, 3D ve 3DPay** - Ödemede kredi kart bilgisi websiteniz tarafından alınır. **3DHost** ödemede ise banka websayfasından alınır. - -## Otorizasyon, Ön Otorizasyon, Post Otorizasyon İşlemler arasındaki farklar + +### Otorizasyon, Ön Otorizasyon, Ön Provizyon Kapama İşlemler arasındaki farklar - **Otorizasyon** - bildiğimiz ve genel olarak kullandığımız işlem. Tek seferde ödeme işlemi biter. Bu işlem için kullanıcıdan hep kredi kart bilgisini _alınır_. İşlemin kütüphanedeki karşılığı `AbstractGateway::TX_PAY` - **Ön Otorizasyon** - müşteriden parayı direk çekmek yerine, işlem sonucunda para bloke edilir. Bu işlem için kullanıcıdan hep kredi kart bilgisini _alınır_. İşlemin kütüphanedeki karşılığı `AbstractGateway::TX_PRE_PAY` -- **Post Otorizasyon** - ön provizyon sonucunda bloke edilen miktarın satışını tamamlar. +- **Ön Provizyon Kapama** - ön provizyon sonucunda bloke edilen miktarın satışını tamamlar. Ön otorizasyon yapıldıktan sonra, örneğin 1 hafta sonra, Post Otorizasyon isteği gönderilebilinir. Bu işlem için kullanıcıdan kredi kart bilgisi _alınmaz_. Onun yerine bazı gateway'ler `orderId` degeri isteri, bazıları ise ön provizyon sonucu dönen banka tarafındaki `orderId`'yi ister. @@ -262,18 +277,17 @@ Satıcı _ön otorizasyon_ isteği iptal etmek isterse de `cancel` isteği gönd Post Otorizasyon İşlemin kütüphanedeki karşılığı `AbstractGateway::TX_POST_PAY` - Bu 3 çeşit işlemler bütün ödeme modelleri (NonSecure, 3D, 3DPay ve 3DHost) tarafından desteklenir. - -## Refund ve Cancel işlemler arasındaki farklar +### Refund ve Cancel işlemler arasındaki farklar - **Refund** - Tamamlanan ödemeyi iade etmek için kullanılır. Bu işlemi yapabilmek için ödeme yapıldıktan belli bir süre _sonra_ (örn. 12 saat) yapılabilir. İade işlemi için _miktar zorunlu_, çünkü ödenen ve iade edilen miktarı aynı olmayabilir. -İşlemin kütüphanedeli karşılığı `AbstractGateway::TX_REFUND` +İşlemin kütüphanedeki karşılığı `AbstractGateway::TX_REFUND` - **Cancel** - Tamamlanan ödemeyi iptal etmek için kullanılır. Belli bir süre _içinde_ (örn. 12 saat) yapılması gerekir. Gateway'ler tarafında değişen bu süreyi geçerse `refund` işlemi kullanmak zorundasınız. Genel olarak _miktar_ bilgisi _istenmez_, ancak bazı Gateway'ler ister. -İşlemin kütüphanedeli karşılığı `AbstractGateway::TX_CANCEL` +İşlemin kütüphanedeki karşılığı `AbstractGateway::TX_CANCEL` -## Docker ile test ortamı +## Docker ile test ortami Makinenizde Docker kurulu olmasi gerekiyor. Projenin root klasöründe `docker-compose up` komutu çalıştırmanız yeterli. **Note**: localhost port 80 boş olması gerekiyor. diff --git a/config/pos.php b/config/pos.php index f18201f1..18334ed1 100644 --- a/config/pos.php +++ b/config/pos.php @@ -18,6 +18,10 @@ 'production' => 'https://www.sanalakpos.com/fim/est3Dgate', 'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate', ], + 'gateway_3d_host' => [ + 'production' => 'https://sanalpos.isbank.com.tr/fim/est3Dgate', + 'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate', + ], ], ], 'ziraat' => [ @@ -78,6 +82,10 @@ 'production' => 'https://sanalpos.isbank.com.tr/fim/est3Dgate', 'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate', ], + 'gateway_3d_host' => [ + 'production' => 'https://sanalpos.isbank.com.tr/fim/est3Dgate', + 'test' => 'https://entegrasyon.asseco-see.com.tr/fim/est3Dgate', + ], ], ], 'yapikredi' => [ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index bd9af970..97bced8c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,60 @@ # Changelog +## [0.7.0] - 2022-05-18 +### Changed +- `\Mews\Pos\PosInterface::prepare()` method artık sipariş verilerini (_currency, id, amount, installment, transaction type_) değiştirmez/formatlamaz. + Sipariş verilerinin formatlanmasını artık Data Request Mapper'de (örn. `PosNetRequestDataMapper`) istek göndermeden önce yapılır. + + Önce: + ```php + protected function preparePaymentOrder(array $order) + { + $installment = 0; + if (isset($order['installment']) && $order['installment'] > 1) { + $installment = $order['installment']; + } + + return (object) array_merge($order, [ + 'id' => self::formatOrderId($order['id']), + 'installment' => self::formatInstallment($installment), + 'amount' => self::amountFormat($order['amount']), + 'currency' => $this->mapCurrency($order['currency']), + ]); + } + ``` + Şimdi: + ```php + protected function preparePaymentOrder(array $order) + { + return (object) array_merge($order, [ + 'id' => $order['id'], + 'installment' => $order['installment'] ?? 0, + 'amount' => $order['amount'], + 'currency' => $order['currency'] ?? 'TRY', + ]); + } + ``` +- **GarantiPos** - tekrarlanan (`recurring`) ödeme desteği teklendi. +- **EstPos** - IP adres artık zorunlu değil. +- Language degerleri artık Gateway bazlı tanımlanmıyor. Önceden gateway bazlı: + ```php + \Mews\Pos\Gateways\EstPos::LANG_TR; + \Mews\Pos\Gateways\EstPos::LANG_EN; + \Mews\Pos\Gateways\GarantiPos::LANG_TR; + \Mews\Pos\Gateways\GarantiPos::LANG_EN; + ... + ``` + Şimdi sadece: + ```php + \Mews\Pos\Gateways\AbstractGateway::LANG_TR; + \Mews\Pos\Gateways\AbstractGateway::LANG_EN; + ``` +- Siparişde `currency` ve `installment` artık zorunlu değil. Varsayılan olarak `currency=TRY`, `installment=0` olarak kabul edilir. +- Single Responsibility prensibe uygun olarak bütün gateway sınıflarında istek verilerini hazırlama Request Data Mapper'lere + (`EstPosRequestDataMapper`, `GarantiPosRequestDataMapper`, `InterPosRequestDataMapper`, `KuveytPosRequestDataMapper`, `PayForPosRequestDataMapper`, `PosNetRequestDataMapper`, `VakifBankPosRequestDataMapper`) taşındı. + Bununla birlikte bazı sabit değerler Gateway sınıflardan Request Data Mapper sınıflara taşındı. + + ## [0.6.0] - 2022-04-18 ### Changed - Kredi kart class'ları bütün gateway'ler için **tek** `Mews\Pos\Entity\Card\CreditCard` class'ı olacak şekilde güncellendi. diff --git a/examples/_common-codes/3d-host/index.php b/examples/_common-codes/3d-host/index.php index d1ca1eee..c9ee9956 100644 --- a/examples/_common-codes/3d-host/index.php +++ b/examples/_common-codes/3d-host/index.php @@ -3,7 +3,15 @@ require '_config.php'; require '../../template/_header.php'; -$order = getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = getNewOrder( + $baseUrl, + $ip, + $request->get('currency', 'TRY'), + $session, + $request->get('installment'), + false, + $request->get('lang', \Mews\Pos\Gateways\AbstractGateway::LANG_TR) +); $session->set('order', $order); $pos->prepare($order, $transaction); diff --git a/examples/_common-codes/3d/form.php b/examples/_common-codes/3d/form.php index 44872a2b..69c7ae93 100644 --- a/examples/_common-codes/3d/form.php +++ b/examples/_common-codes/3d/form.php @@ -10,7 +10,15 @@ exit(); } $transaction = $request->get('tx', \Mews\Pos\Gateways\AbstractGateway::TX_PAY); -$order = getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session, $request->get('installment')); +$order = getNewOrder( + $baseUrl, + $ip, + $request->get('currency', 'TRY'), + $session, + $request->get('installment'), + false, + $request->get('lang', \Mews\Pos\Gateways\AbstractGateway::LANG_TR) +); $session->set('order', $order); $card = createCard($pos, $request->request->all()); @@ -24,6 +32,7 @@ try { $formData = $pos->get3DFormData(); + //dd($formData); } catch (\Throwable $e) { dd($e); } diff --git a/examples/_common-codes/regular/form.php b/examples/_common-codes/regular/form.php index 7f75ca95..3ccf12e3 100644 --- a/examples/_common-codes/regular/form.php +++ b/examples/_common-codes/regular/form.php @@ -2,7 +2,15 @@ require_once '_config.php'; -$order = getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session, $request->get('installment')); +$order = getNewOrder( + $baseUrl, + $ip, + $request->get('currency', 'TRY'), + $session, + $request->get('installment'), + false, + $request->get('lang', \Mews\Pos\Gateways\AbstractGateway::LANG_TR) +); $session->set('order', $order); $transaction = $request->get('tx', \Mews\Pos\Gateways\AbstractGateway::TX_PAY); diff --git a/examples/akbank/3d-host/_config.php b/examples/akbank/3d-host/_config.php index 7147ba1d..a872fd25 100644 --- a/examples/akbank/3d-host/_config.php +++ b/examples/akbank/3d-host/_config.php @@ -1,9 +1,11 @@ $ord['email'], 'amount' => $ord['amount'], 'currency' => $ord['currency'], - 'ref_ret_num' => '831803579226', + 'ref_ret_num' => $session->get('ref_ret_num'), ]; $transaction = AbstractGateway::TX_CANCEL; $pos->prepare($order, $transaction); diff --git a/examples/interpos/3d-host/_config.php b/examples/interpos/3d-host/_config.php index 8bb86f9c..e1ff97d7 100644 --- a/examples/interpos/3d-host/_config.php +++ b/examples/interpos/3d-host/_config.php @@ -1,5 +1,7 @@ 1, //'PaymentFrequency' => 2, - return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, \Mews\Pos\Gateways\InterPos::LANG_TR); + return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, $lang); } function doPayment(\Mews\Pos\PosInterface $pos, string $transaction, ?\Mews\Pos\Entity\Card\AbstractCreditCard $card) diff --git a/examples/interpos/regular/_config.php b/examples/interpos/regular/_config.php index f293ccd7..192d11dc 100644 --- a/examples/interpos/regular/_config.php +++ b/examples/interpos/regular/_config.php @@ -8,6 +8,7 @@ $userPass = '3'; $shopCode = '3123'; //$merchantPass non secure islemler icin kullanilmiyor +//account bilgileri kendi account bilgilerinizle degistiriniz $account = \Mews\Pos\Factory\AccountFactory::createInterPosAccount('denizbank', $shopCode, $userCode, $userPass); $pos = getGateway($account); diff --git a/examples/kuveytpos/3d/_config.php b/examples/kuveytpos/3d/_config.php index 049a1c21..84585126 100644 --- a/examples/kuveytpos/3d/_config.php +++ b/examples/kuveytpos/3d/_config.php @@ -3,7 +3,7 @@ require '../_payment_config.php'; $baseUrl = $bankTestsUrl.'/3d/'; - +//account bilgileri kendi account bilgilerinizle degistiriniz $account = \Mews\Pos\Factory\AccountFactory::createKuveytPosAccount( 'kuveytpos', '496', diff --git a/examples/kuveytpos/_payment_config.php b/examples/kuveytpos/_payment_config.php index 325feee8..7509fcd8 100644 --- a/examples/kuveytpos/_payment_config.php +++ b/examples/kuveytpos/_payment_config.php @@ -27,9 +27,10 @@ function getNewOrder( string $currency, \Symfony\Component\HttpFoundation\Session\Session $session, ?int $installment = 0, - bool $tekrarlanan = false + bool $tekrarlanan = false, + string $lang = AbstractGateway::LANG_TR ): array { - return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, \Mews\Pos\Gateways\KuveytPos::LANG_TR); + return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, $lang); } diff --git a/examples/template/_credit_card_form.php b/examples/template/_credit_card_form.php index abdf2903..0ada898f 100644 --- a/examples/template/_credit_card_form.php +++ b/examples/template/_credit_card_form.php @@ -67,6 +67,13 @@ +
+ +

diff --git a/examples/template/_payment_response.php b/examples/template/_payment_response.php index 6f77b812..04c851d1 100644 --- a/examples/template/_payment_response.php +++ b/examples/template/_payment_response.php @@ -24,6 +24,9 @@ $response = $pos->getResponse(); +if ($pos->isSuccess()) { + $session->set('ref_ret_num', $response->host_ref_num); +} ?>
diff --git a/examples/vakifbank/3d/_config.php b/examples/vakifbank/3d/_config.php index f3e77d20..9588b16e 100644 --- a/examples/vakifbank/3d/_config.php +++ b/examples/vakifbank/3d/_config.php @@ -7,6 +7,7 @@ $merchantId = '000000000111111'; $terminalId = 'VP000095'; $isyeriSifre = '3XTgER89as'; +//account bilgileri kendi account bilgilerinizle degistiriniz $account = \Mews\Pos\Factory\AccountFactory::createVakifBankAccount( 'vakifbank', $merchantId, diff --git a/examples/vakifbank/_payment_config.php b/examples/vakifbank/_payment_config.php index 0c3d3b05..f7d35bc2 100644 --- a/examples/vakifbank/_payment_config.php +++ b/examples/vakifbank/_payment_config.php @@ -40,9 +40,10 @@ function getNewOrder( string $currency, \Symfony\Component\HttpFoundation\Session\Session $session, ?int $installment = 0, - bool $tekrarlanan = false + bool $tekrarlanan = false, + string $lang = AbstractGateway::LANG_TR ): array { - $order = createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment); + $order = createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, $lang); $order['extraData'] = $session->getId(); //optional, istekte SessionInfo degere atanir if ($tekrarlanan) { @@ -53,6 +54,7 @@ function getNewOrder( //recurring işlemin toplamda kaç kere tekrar edeceği bilgisini içerir 'recurringInstallmentCount' => 4, 'recurringEndDate' => '202112', //optional + // yukardaki belirtilen ayarin anlami 3 ayda bir kesintip yap ve bunu toplam 4 kere tekrarla. ]); } diff --git a/examples/vakifbank/regular/_config.php b/examples/vakifbank/regular/_config.php index 7d72b5f1..ac5f7edf 100644 --- a/examples/vakifbank/regular/_config.php +++ b/examples/vakifbank/regular/_config.php @@ -7,7 +7,7 @@ $merchantId = '000000000111111'; $terminalId = 'VP000095'; $isyeriSifre = '3XTgER89as'; - +//account bilgileri kendi account bilgilerinizle degistiriniz $account = \Mews\Pos\Factory\AccountFactory::createVakifBankAccount( 'vakifbank', $merchantId, diff --git a/examples/ykb/3d/_config.php b/examples/ykb/3d/_config.php index 4493da45..5cfabe7c 100644 --- a/examples/ykb/3d/_config.php +++ b/examples/ykb/3d/_config.php @@ -6,7 +6,7 @@ require '../_payment_config.php'; $baseUrl = $bankTestsUrl.'/3d/'; - +//account bilgileri kendi account bilgilerinizle degistiriniz $account = AccountFactory::createPosNetAccount( 'yapikredi', '6706598320', @@ -18,6 +18,16 @@ '10,10,10,10,10,10,10,10' ); +/** + * vftCode: Vade Farklı işlemler için kullanılacak olan kampanya kodunu belirler. + * Üye İşyeri için tanımlı olan kampanya kodu, İşyeri Yönetici Ekranlarına giriş + * yapıldıktan sonra, Üye İşyeri bilgileri sayfasından öğrenilebilinir. + * vtfCode set etmek icin simdilik bu sekilde: + * $account->promotion_code = 'xxx'; + * + * ilerde vtfCode atanmasi duzgun ele alinacak + */ + $pos = getGateway($account); $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_PAY; diff --git a/examples/ykb/_payment_config.php b/examples/ykb/_payment_config.php index ef35fe38..9ce8549e 100644 --- a/examples/ykb/_payment_config.php +++ b/examples/ykb/_payment_config.php @@ -43,9 +43,16 @@ function getNewOrder( string $currency, \Symfony\Component\HttpFoundation\Session\Session $session, ?int $installment = 0, - bool $tekrarlanan = false + bool $tekrarlanan = false, + string $lang = AbstractGateway::LANG_TR ): array { - return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, \Mews\Pos\Gateways\InterPos::LANG_TR); + /** + * useJokerVadaa: Sadece TDS sistemini kullanacak Üye İşyerleri için, 3D-Secure doğrulamasından + * önce Joker Vadaa(üye işyerlerine özel ek taksit ve öteleme kampanyaları) + * sorgulamasını ve kullanımını aktif etmek için kullanılır. Opsiyoneldir. + * useJokerVadaa degeri $order->koiCode = 1; sekilde set etebilirsiniz. + */ + return createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, $lang); } function doPayment(\Mews\Pos\PosInterface $pos, string $transaction, ?\Mews\Pos\Entity\Card\AbstractCreditCard $card) diff --git a/examples/ykb/regular/_config.php b/examples/ykb/regular/_config.php index 61259924..724228c2 100644 --- a/examples/ykb/regular/_config.php +++ b/examples/ykb/regular/_config.php @@ -3,7 +3,7 @@ require '../_payment_config.php'; $baseUrl = $bankTestsUrl.'/regular/'; - +//account bilgileri kendi account bilgilerinizle degistiriniz $account = \Mews\Pos\Factory\AccountFactory::createPosNetAccount( 'yapikredi', '6706598320', diff --git a/src/DataMapper/AbstractRequestDataMapper.php b/src/DataMapper/AbstractRequestDataMapper.php index db48ad79..0cc0ce36 100644 --- a/src/DataMapper/AbstractRequestDataMapper.php +++ b/src/DataMapper/AbstractRequestDataMapper.php @@ -1,12 +1,15 @@ 'tr', + AbstractGateway::LANG_EN => 'en', + ]; + /** + * default olarak ISO 4217 kodlar tanimliyoruz. + * fakat bazi banklar ISO standarti kullanmiyorlar. * Currency mapping * * @var array */ - protected $currencyMappings = []; + protected $currencyMappings = [ + 'TRY' => 949, + 'USD' => 840, + 'EUR' => 978, + 'GBP' => 826, + 'JPY' => 392, + 'RUB' => 643, + ]; /** * period mapping for recurring orders @@ -38,6 +55,9 @@ abstract class AbstractRequestDataMapper */ protected $recurringOrderFrequencyMapping = []; + /** @var bool */ + protected $testMode = false; + /** * @param array $currencyMappings */ @@ -51,7 +71,7 @@ public function __construct(array $currencyMappings = []) /** * @param AbstractPosAccount $account * @param $order - * @param string $txType mapped value from AbstractGateway::TX_PAY + * @param string $txType ex: AbstractGateway::TX_PAY * @param array $responseData gateway'den gelen cevap * * @return array @@ -61,7 +81,7 @@ abstract public function create3DPaymentRequestData(AbstractPosAccount $account, /** * @param AbstractPosAccount $account * @param $order - * @param string $txType mapped value from AbstractGateway::TX_PAY + * @param string $txType ex: AbstractGateway::TX_PAY * @param AbstractCreditCard|null $card * * @return array @@ -104,7 +124,7 @@ abstract public function createRefundRequestData(AbstractPosAccount $account, $o /** * @param AbstractPosAccount $account * @param $order - * @param string $txType mapped value from AbstractGateway::TX_PAY + * @param string $txType ex: AbstractGateway::TX_PAY * @param string $gatewayURL * @param AbstractCreditCard|null $card * @@ -115,7 +135,7 @@ abstract public function create3DFormData(AbstractPosAccount $account, $order, s /** * @param AbstractPosAccount $account * @param $order - * @param string $txType mapped value from AbstractGateway::TX_PAY + * @param string $txType ex: AbstractGateway::TX_PAY * * @return string */ @@ -126,10 +146,18 @@ abstract public function create3DHash(AbstractPosAccount $account, $order, strin * @param $order * @param array $extraData bankaya gore degisen ozel degerler * - * @return string + * @return array */ abstract public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array; + /** + * @return bool + */ + public function isTestMode(): bool + { + return $this->testMode; + } + /** * @param string $period * @@ -172,6 +200,55 @@ public function getCurrencyMappings(): array return $this->currencyMappings; } + + /** + * @param bool $testMode + * + * @return AbstractRequestDataMapper + */ + public function setTestMode(bool $testMode): self + { + $this->testMode = $testMode; + + return $this; + } + + /** + * @param string $currency TRY, USD + * + * @return string currency code that is accepted by bank + */ + public function mapCurrency(string $currency): string + { + return $this->currencyMappings[$currency] ?? $currency; + } + + /** + * @param string $txType + * + * @return string + * + * @throws UnsupportedTransactionTypeException + */ + public function mapTxType(string $txType): string + { + if (!$this->isSupportedTxType($txType)) { + throw new UnsupportedTransactionTypeException(); + } + + return $this->txTypeMappings[$txType]; + } + + /** + * @param string $txType + * + * @return bool + */ + public function isSupportedTxType(string $txType): bool + { + return isset($this->txTypeMappings[$txType]); + } + /** * @return array */ @@ -180,6 +257,13 @@ public function getRecurringOrderFrequencyMapping(): array return $this->recurringOrderFrequencyMapping; } + /** + * @param int|null $installment + * + * @return int|string + */ + abstract public function mapInstallment(?int $installment); + /** * @param string $str * @@ -202,9 +286,9 @@ protected function hashString(string $str): string protected function getLang(AbstractPosAccount $account, $order): string { if ($order && isset($order->lang)) { - return $order->lang; + return $this->langMappings[$order->lang]; } - return $account->getLang(); + return $this->langMappings[$account->getLang()]; } } diff --git a/src/DataMapper/EstPosRequestDataMapper.php b/src/DataMapper/EstPosRequestDataMapper.php new file mode 100644 index 00000000..28ca66d7 --- /dev/null +++ b/src/DataMapper/EstPosRequestDataMapper.php @@ -0,0 +1,267 @@ + 'Auth', + AbstractGateway::TX_PRE_PAY => 'PreAuth', + AbstractGateway::TX_POST_PAY => 'PostAuth', + AbstractGateway::TX_CANCEL => 'Void', + AbstractGateway::TX_REFUND => 'Credit', + AbstractGateway::TX_STATUS => 'ORDERSTATUS', + AbstractGateway::TX_HISTORY => 'ORDERHISTORY', + ]; + + protected $cardTypeMapping = [ + AbstractCreditCard::CARD_TYPE_VISA => '1', + AbstractCreditCard::CARD_TYPE_MASTERCARD => '2', + ]; + + protected $recurringOrderFrequencyMapping = [ + 'DAY' => 'D', + 'WEEK' => 'W', + 'MONTH' => 'M', + 'YEAR' => 'Y', + ]; + + protected $secureTypeMappings = [ + AbstractGateway::MODEL_3D_SECURE => '3d', + AbstractGateway::MODEL_3D_PAY => '3d_pay', + AbstractGateway::MODEL_3D_HOST => '3d_host', + AbstractGateway::MODEL_NON_SECURE => 'regular', + ]; + + /** + * @inheritDoc + */ + public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array + { + $requestData = $this->getRequestAccountData($account) + [ + 'Type' => $this->mapTxType($txType), + 'IPAddress' => $order->ip ?? null, + 'Email' => $order->email, + 'OrderId' => $order->id, + 'UserId' => $order->user_id ?? null, + 'Total' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'Taksit' => $this->mapInstallment($order->installment), + 'Number' => $responseData['md'], + 'PayerTxnId' => $responseData['xid'], + 'PayerSecurityLevel' => $responseData['eci'], + 'PayerAuthenticationCode' => $responseData['cavv'], + 'Mode' => 'P', + ]; + + if ($order->name) { + $requestData['BillTo'] = [ + 'Name' => $order->name, + ]; + } + + if (isset($order->recurringFrequency)) { + $requestData['PbOrder'] = [ + 'OrderType' => 0, + // Periyodik İşlem Frekansı + 'OrderFrequencyInterval' => $order->recurringFrequency, + //D|M|Y + 'OrderFrequencyCycle' => $this->mapRecurringFrequency($order->recurringFrequencyType), + 'TotalNumberPayments' => $order->recurringInstallmentCount, + ]; + } + + return $requestData; + } + + /** + * @inheritDoc + */ + public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + return $this->getRequestAccountData($account) + [ + 'Type' => $this->mapTxType($txType), + 'IPAddress' => $order->ip ?? null, + 'Email' => $order->email, + 'OrderId' => $order->id, + 'UserId' => $order->user_id ?? null, + 'Total' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'Taksit' => $this->mapInstallment($order->installment), + 'Number' => $card->getNumber(), + 'Expires' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), + 'Cvv2Val' => $card->getCvv(), + 'Mode' => 'P', + 'BillTo' => [ + 'Name' => $order->name ?: null, + ], + ]; + } + + /** + * @inheritDoc + */ + public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array + { + return $this->getRequestAccountData($account) + [ + 'Type' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'OrderId' => $order->id, + ]; + } + + /** + * @inheritDoc + */ + public function createStatusRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'OrderId' => $order->id, + 'Extra' => [ + $this->mapTxType(AbstractGateway::TX_STATUS) => 'QUERY', + ], + ]; + } + + /** + * @inheritDoc + */ + public function createCancelRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'OrderId' => $order->id, + 'Type' => $this->mapTxType(AbstractGateway::TX_CANCEL), + ]; + } + + /** + * @inheritDoc + */ + public function createRefundRequestData(AbstractPosAccount $account, $order): array + { + $requestData = [ + 'OrderId' => $order->id, + 'Currency' => $this->mapCurrency($order->currency), + 'Type' => $this->mapTxType(AbstractGateway::TX_REFUND), + ]; + + if (isset($order->amount)) { + $requestData['Total'] = $order->amount; + } + + return $this->getRequestAccountData($account) + $requestData; + } + + /** + * @inheritDoc + */ + public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array + { + $requestData = [ + 'OrderId' => $extraData['order_id'], //todo orderId ya da id olarak degistirilecek, Payfor'da orderId, Garanti'de id + 'Extra' => [ + $this->mapTxType(AbstractGateway::TX_HISTORY) => 'QUERY', + ], + ]; + + return $this->getRequestAccountData($account) + $requestData; + } + + + /** + * @inheritDoc + */ + public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array + { + $hash = $this->create3DHash($account, $order, $txType); + + $inputs = [ + 'clientid' => $account->getClientId(), + 'storetype' => $this->secureTypeMappings[$account->getModel()], + 'hash' => $hash, + 'firmaadi' => $order->name, + 'Email' => $order->email, + 'amount' => $order->amount, + 'oid' => $order->id, + 'okUrl' => $order->success_url, + 'failUrl' => $order->fail_url, + 'rnd' => $order->rand, + 'lang' => $this->getLang($account, $order), + 'currency' => $this->mapCurrency($order->currency), + 'taksit' => $this->mapInstallment($order->installment), + 'islemtipi' => $this->mapTxType($txType), + ]; + + if ($card) { + $inputs['cardType'] = $this->cardTypeMapping[$card->getType()]; + $inputs['pan'] = $card->getNumber(); + $inputs['Ecom_Payment_Card_ExpDate_Month'] = $card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); + $inputs['Ecom_Payment_Card_ExpDate_Year'] = $card->getExpireYear(self::CREDIT_CARD_EXP_YEAR_FORMAT); + $inputs['cv2'] = $card->getCvv(); + } + + return [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + } + + /** + * @inheritDoc + */ + public function create3DHash(AbstractPosAccount $account, $order, string $txType): string + { + $hashData = [ + $account->getClientId(), + $order->id, + $order->amount, + $order->success_url, + $order->fail_url, + $this->mapTxType($txType), + $this->mapInstallment($order->installment), + $order->rand, + $account->getStoreKey(), + ]; + + $hashStr = implode(static::HASH_SEPARATOR, $hashData); + + return $this->hashString($hashStr); + } + + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : ''; + } + + /** + * @param AbstractPosAccount $account + * + * @return array + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + ]; + } +} diff --git a/src/DataMapper/GarantiPosRequestDataMapper.php b/src/DataMapper/GarantiPosRequestDataMapper.php new file mode 100644 index 00000000..acde24a6 --- /dev/null +++ b/src/DataMapper/GarantiPosRequestDataMapper.php @@ -0,0 +1,531 @@ + '3D', + AbstractGateway::MODEL_3D_PAY => '3D_PAY', + AbstractGateway::MODEL_3D_HOST => null, //todo + AbstractGateway::MODEL_NON_SECURE => null, + ]; + + + /** + * @inheritdoc + */ + protected $txTypeMappings = [ + AbstractGateway::TX_PAY => 'sales', + AbstractGateway::TX_PRE_PAY => 'preauth', + AbstractGateway::TX_POST_PAY => 'postauth', + AbstractGateway::TX_CANCEL => 'void', + AbstractGateway::TX_REFUND => 'refund', + AbstractGateway::TX_HISTORY => 'orderhistoryinq', + AbstractGateway::TX_STATUS => 'orderinq', + ]; + + private const MOTO = 'N'; + + protected $recurringOrderFrequencyMapping = [ + 'DAY' => 'D', + 'WEEK' => 'W', + 'MONTH' => 'M', + ]; + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array + { + $hash = $this->createHash($account, $order, $txType); + + $result = [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash), + 'Customer' => [ + 'IPAddress' => $responseData['customeripaddress'], + 'EmailAddress' => $responseData['customeremailaddress'], + ], + 'Order' => [ + 'OrderID' => $responseData['orderid'], + 'AddressList' => $this->getOrderAddressData($order), + ], + 'Transaction' => [ + 'Type' => $responseData['txntype'], + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => $responseData['txnamount'], + 'CurrencyCode' => $responseData['txncurrencycode'], + 'CardholderPresentCode' => '13', //13 for 3D secure payment + 'MotoInd' => self::MOTO, + 'Secure3D' => [ + 'AuthenticationCode' => $responseData['cavv'], + 'SecurityLevel' => $responseData['eci'], + 'TxnID' => $responseData['xid'], + 'Md' => $responseData['md'], + ], + ], + ]; + + if (isset($order->recurringInstallmentCount)) { + $result['Recurring'] = $this->createRecurringData($order); + } + + return $result; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + $hash = $this->createHash($account, $order, $txType, $card); + + $result = [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash), + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Card' => $this->getCardData($card), + 'Order' => [ + 'OrderID' => $order->id, + 'AddressList' => $this->getOrderAddressData($order), + ], + 'Transaction' => [ + 'Type' => $this->mapTxType($txType), + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + ], + ]; + + if (isset($order->recurringInstallmentCount)) { + $result['Recurring'] = $this->createRecurringData($order); + } + + return $result; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array + { + $hash = $this->createHash($account, $order, AbstractGateway::TX_POST_PAY, $card); + + return [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash), + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'Amount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createStatusRequestData(AbstractPosAccount $account, $order): array + { + $hash = $this->createHash($account, $order, AbstractGateway::TX_STATUS); + + return [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash), + 'Customer' => [ + 'IPAddress' => $order->ip ?? '', + 'EmailAddress' => $order->email ?? '', + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(AbstractGateway::TX_STATUS), + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => self::amountFormat($order->amount), //sabit olarak amount 100 gonderilecek + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createCancelRequestData(AbstractPosAccount $account, $order): array + { + $hash = $this->createHash($account, $order, AbstractGateway::TX_CANCEL); + + return [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash, true), + 'Customer' => [ + 'IPAddress' => $order->ip ?? '', + 'EmailAddress' => $order->email ?? '', + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(AbstractGateway::TX_CANCEL), + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => self::amountFormat($order->amount), //sabit olarak amount 100 gonderilecek + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createRefundRequestData(AbstractPosAccount $account, $order): array + { + $hash = $this->createHash($account, $order, AbstractGateway::TX_REFUND); + + return [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash, true), + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(AbstractGateway::TX_REFUND), + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => self::amountFormat($order->amount), //sabit olarak amount 100 gonderilecek, + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array + { + $hash = $this->createHash($account, $order, AbstractGateway::TX_HISTORY); + + return [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($account, $hash), + 'Customer' => [ + 'IPAddress' => $order->ip ?? '', + 'EmailAddress' => $order->email ?? '', + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(AbstractGateway::TX_HISTORY), + 'InstallmentCnt' => $this->mapInstallment($order->installment), + 'Amount' => self::amountFormat($order->amount), //sabit olarak amount 100 gonderilecek + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + ], + ]; + } + + + /** + * @inheritDoc + */ + public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array + { + $hashData = $this->create3DHash($account, $order, $txType); + + $inputs = [ + 'secure3dsecuritylevel' => $this->secureTypeMappings[$account->getModel()], + 'mode' => $this->getMode(), + 'apiversion' => self::API_VERSION, + 'terminalprovuserid' => $account->getUsername(), + 'terminaluserid' => $account->getUsername(), + 'terminalmerchantid' => $account->getClientId(), + 'terminalid' => $account->getTerminalId(), + 'txntype' => $this->mapTxType($txType), + 'txnamount' => self::amountFormat($order->amount), + 'txncurrencycode' => $this->mapCurrency($order->currency), + 'txninstallmentcount' => $this->mapInstallment($order->installment), + 'orderid' => $order->id, + 'successurl' => $order->success_url, + 'errorurl' => $order->fail_url, + 'customeremailaddress' => $order->email ?? null, + 'customeripaddress' => $order->ip, + 'secure3dhash' => $hashData, + ]; + + if ($card) { + $inputs['cardnumber'] = $card->getNumber(); + $inputs['cardexpiredatemonth'] = $card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); + $inputs['cardexpiredateyear'] = $card->getExpireYear(self::CREDIT_CARD_EXP_YEAR_FORMAT); + $inputs['cardcvv2'] = $card->getCvv(); + } + + return [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + } + + /** + * @param GarantiPosAccount $account + * + * @inheritDoc + */ + public function create3DHash(AbstractPosAccount $account, $order, string $txType): string + { + $map = [ + $account->getTerminalId(), + $order->id, + self::amountFormat($order->amount), + $order->success_url, + $order->fail_url, + $this->mapTxType($txType), + $this->mapInstallment($order->installment), + $account->getStoreKey(), + $this->createSecurityData($account, $txType), + ]; + + return $this->hashString(implode(static::HASH_SEPARATOR, $map)); + } + + /** + * Make Hash Data + * + * @param GarantiPosAccount $account + * @param $order + * @param string $txType + * @param AbstractCreditCard|null $card + * + * @return string + */ + public function createHash(GarantiPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): string + { + $map = [ + $order->id, + $account->getTerminalId(), + isset($card) ? $card->getNumber() : null, + self::amountFormat($order->amount), + $this->createSecurityData($account, $txType), + ]; + + return $this->hashString(implode(static::HASH_SEPARATOR, $map)); + } + + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : ''; + } + + /** + * Amount Formatter + * converts 100 to 10000, or 10.01 to 1001 + * @param float $amount + * + * @return int + */ + public static function amountFormat($amount): int + { + return round($amount, 2) * 100; + } + + /** + * @param string $str + * + * @return string + */ + protected function hashString(string $str): string + { + return strtoupper(hash(static::HASH_ALGORITHM, $str)); + } + + /** + * @return string + */ + private function getMode(): string + { + return !$this->isTestMode() ? 'PROD' : 'TEST'; + } + + /** + * Make Security Data + * + * @param GarantiPosAccount $account + * @param string $txType + * + * @return string + */ + private function createSecurityData(AbstractPosAccount $account, string $txType): string + { + if (AbstractGateway::TX_REFUND === $txType || AbstractGateway::TX_CANCEL === $txType) { + $password = $account->getRefundPassword(); + } else { + $password = $account->getPassword(); + } + + $map = [ + $password, + str_pad((int) $account->getTerminalId(), 9, 0, STR_PAD_LEFT), + ]; + + return $this->hashString(implode(static::HASH_SEPARATOR, $map)); + } + + /** + * @param GarantiPosAccount $account + * @param string $hash + * @param bool $isRefund + * + * @return array + */ + private function getTerminalData(AbstractPosAccount $account, string $hash, bool $isRefund = false): array + { + return [ + 'ProvUserID' => $isRefund ? $account->getRefundUsername() : $account->getUsername(), + 'UserID' => $isRefund ? $account->getRefundUsername() : $account->getUsername(), + 'HashData' => $hash, + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ]; + } + + /** + * @param AbstractCreditCard|null $card + * + * @return array + */ + private function getCardData(?AbstractCreditCard $card = null): array + { + if ($card) { + return [ + 'Number' => $card->getNumber(), + 'ExpireDate' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), + 'CVV2' => $card->getCvv(), + ]; + } + + return [ + 'Number' => '', + 'ExpireDate' => '', + 'CVV2' => '', + ]; + } + + /** + * @param $order + * + * @return array + */ + private function getOrderAddressData($order): array + { + return [ + 'Address' => [ + 'Type' => 'B', //S - shipping, B - billing + 'Name' => $order->name, + 'LastName' => '', + 'Company' => '', + 'Text' => '', + 'District' => '', + 'City' => '', + 'PostalCode' => '', + 'Country' => '', + 'PhoneNumber' => '', + ], + ]; + } + + /** + * ornek: + * + * G veya R R:Sabit Tutarli G:Degisken Tutar + * + * M , W , D Monthly, weekly, daily + * + * + * + * + * + * + * YYYYMMDD + * + * + * + * @param $order + * + * @return array + */ + private function createRecurringData($order): array + { + return [ + 'TotalPaymentNum' => $order->recurringInstallmentCount, //kac kere tekrarlanacak + 'FrequencyType' => $this->mapRecurringFrequency($order->recurringFrequencyType), //Monthly, weekly, daily + 'FrequencyInterval' => $order->recurringFrequency, + 'Type' => $order->recurringType ?? 'R', //R:Sabit Tutarli G:Degisken Tuta + 'StartDate' => $order->startDate ?? '', + ]; + } +} diff --git a/src/DataMapper/InterPosRequestDataMapper.php b/src/DataMapper/InterPosRequestDataMapper.php index 6738c683..02e1f27a 100644 --- a/src/DataMapper/InterPosRequestDataMapper.php +++ b/src/DataMapper/InterPosRequestDataMapper.php @@ -1,5 +1,7 @@ '3DModel', AbstractGateway::MODEL_3D_PAY => '3DPay', @@ -41,42 +48,25 @@ class InterPosRequestDataMapper extends AbstractRequestDataMapper AbstractCreditCard::CARD_TYPE_AMEX => '3', ]; - /** - * Currency mapping - * - * @var array - */ - protected $currencyMappings = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 810, - ]; - /** * @inheritDoc */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array { - return [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'TxnType' => $txType, - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'OrderId' => $order->id, - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, - 'MD' => $responseData['MD'], - 'PayerTxnId' => $responseData['PayerTxnId'], - 'Eci' => $responseData['Eci'], - 'PayerAuthenticationCode' => $responseData['PayerAuthenticationCode'], - 'MOTO' => '0', - 'Lang' => $this->getLang($account, $order), - ]; + return $this->getRequestAccountData($account) + [ + 'TxnType' => $this->mapTxType($txType), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'OrderId' => $order->id, + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'InstallmentCount' => $this->mapInstallment($order->installment), + 'MD' => $responseData['MD'], + 'PayerTxnId' => $responseData['PayerTxnId'], + 'Eci' => $responseData['Eci'], + 'PayerAuthenticationCode' => $responseData['PayerAuthenticationCode'], + 'MOTO' => self::MOTO, + 'Lang' => $this->getLang($account, $order), + ]; } /** @@ -84,19 +74,16 @@ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, */ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array { - $requestData = [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ShopCode' => $account->getClientId(), - 'TxnType' => $txType, - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'OrderId' => $order->id, - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, - 'MOTO' => '0', - 'Lang' => $this->getLang($account, $order), - ]; + $requestData = $this->getRequestAccountData($account) + [ + 'TxnType' => $this->mapTxType($txType), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'OrderId' => $order->id, + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'InstallmentCount' => $this->mapInstallment($order->installment), + 'MOTO' => self::MOTO, + 'Lang' => $this->getLang($account, $order), + ]; if ($card) { $requestData['CardType'] = $this->cardTypeMapping[$card->getType()]; @@ -113,18 +100,15 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { - return [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ShopCode' => $account->getClientId(), - 'TxnType' => $this->txTypeMappings[AbstractGateway::TX_POST_PAY], - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'OrderId' => null, - 'orgOrderId' => $order->id, - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'MOTO' => '0', - ]; + return $this->getRequestAccountData($account) + [ + 'TxnType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'OrderId' => null, + 'orgOrderId' => $order->id, + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'MOTO' => self::MOTO, + ]; } /** @@ -132,16 +116,13 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $ac */ public function createStatusRequestData(AbstractPosAccount $account, $order): array { - return [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ShopCode' => $account->getClientId(), - 'OrderId' => null, //todo buraya hangi deger verilecek? - 'orgOrderId' => $order->id, - 'TxnType' => $this->txTypeMappings[AbstractGateway::TX_STATUS], - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'Lang' => $this->getLang($account, $order), - ]; + return $this->getRequestAccountData($account) + [ + 'OrderId' => null, //todo buraya hangi deger verilecek? + 'orgOrderId' => $order->id, + 'TxnType' => $this->mapTxType(AbstractGateway::TX_STATUS), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'Lang' => $this->getLang($account, $order), + ]; } /** @@ -149,16 +130,13 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar */ public function createCancelRequestData(AbstractPosAccount $account, $order): array { - return [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ShopCode' => $account->getClientId(), - 'OrderId' => null, //todo buraya hangi deger verilecek? - 'orgOrderId' => $order->id, - 'TxnType' => $this->txTypeMappings[AbstractGateway::TX_CANCEL], - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'Lang' => $this->getLang($account, $order), - ]; + return $this->getRequestAccountData($account) + [ + 'OrderId' => null, //todo buraya hangi deger verilecek? + 'orgOrderId' => $order->id, + 'TxnType' => $this->mapTxType(AbstractGateway::TX_CANCEL), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'Lang' => $this->getLang($account, $order), + ]; } /** @@ -166,18 +144,15 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar */ public function createRefundRequestData(AbstractPosAccount $account, $order): array { - return [ - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'ShopCode' => $account->getClientId(), - 'OrderId' => null, - 'orgOrderId' => $order->id, - 'PurchAmount' => $order->amount, - 'TxnType' => $this->txTypeMappings[AbstractGateway::TX_REFUND], - 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'Lang' => $this->getLang($account, $order), - 'MOTO' => '0', - ]; + return $this->getRequestAccountData($account) + [ + 'OrderId' => null, + 'orgOrderId' => $order->id, + 'PurchAmount' => $order->amount, + 'TxnType' => $this->mapTxType(AbstractGateway::TX_REFUND), + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'Lang' => $this->getLang($account, $order), + 'MOTO' => self::MOTO, + ]; } /** @@ -198,7 +173,7 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx $inputs = [ 'ShopCode' => $account->getClientId(), - 'TxnType' => $txType, + 'TxnType' => $this->mapTxType($txType), 'SecureType' => $this->secureTypeMappings[$account->getModel()], 'Hash' => $hash, 'PurchAmount' => $order->amount, @@ -207,8 +182,8 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx 'FailUrl' => $order->fail_url, 'Rnd' => $order->rand, 'Lang' => $this->getLang($account, $order), - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, + 'Currency' => $this->mapCurrency($order->currency), + 'InstallmentCount' => $this->mapInstallment($order->installment), ]; if ($card) { @@ -235,8 +210,8 @@ public function create3DHash(AbstractPosAccount $account, $order, string $txType $order->amount, $order->success_url, $order->fail_url, - $txType, - $order->installment, + $this->mapTxType($txType), + $this->mapInstallment($order->installment), $order->rand, $account->getStoreKey(), ]; @@ -245,4 +220,26 @@ public function create3DHash(AbstractPosAccount $account, $order, string $txType return $this->hashString($hashStr); } + + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : ''; + } + + /** + * @param AbstractPosAccount $account + * + * @return array + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'ShopCode' => $account->getClientId(), + ]; + } } diff --git a/src/DataMapper/KuveytPosRequestDataMapper.php b/src/DataMapper/KuveytPosRequestDataMapper.php index c7fafc48..323f879d 100644 --- a/src/DataMapper/KuveytPosRequestDataMapper.php +++ b/src/DataMapper/KuveytPosRequestDataMapper.php @@ -1,5 +1,7 @@ create3DHash($account, $order, $txType, true); - return [ - 'APIVersion' => KuveytPos::API_VERSION, + return $this->getRequestAccountData($account) + [ + 'APIVersion' => self::API_VERSION, 'HashData' => $hash, - 'MerchantId' => $account->getClientId(), - 'CustomerId' => $account->getCustomerId(), - 'UserName' => $account->getUsername(), 'CustomerIPAddress' => $order->ip, 'KuveytTurkVPosAdditionalData' => [ 'AdditionalData' => [ @@ -111,19 +113,16 @@ public function create3DEnrollmentCheckRequestData(KuveytPosAccount $account, $o { $hash = $this->create3DHash($account, $order, $txType); - $inputs = [ - 'APIVersion' => KuveytPos::API_VERSION, - 'MerchantId' => $account->getClientId(), - 'UserName' => $account->getUsername(), - 'CustomerId' => $account->getCustomerId(), + $inputs = $this->getRequestAccountData($account) + [ + 'APIVersion' => self::API_VERSION, 'HashData' => $hash, - 'TransactionType' => $txType, + 'TransactionType' => $this->mapTxType($txType), 'TransactionSecurity' => $this->secureTypeMappings[$account->getModel()], - 'InstallmentCount' => $order->installment, + 'InstallmentCount' => $this->mapInstallment($order->installment), 'Amount' => self::amountFormat($order->amount), //DisplayAmount: Amount değeri ile aynı olacak şekilde gönderilmelidir. 'DisplayAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => $this->mapCurrency($order->currency), 'MerchantOrderId' => $order->id, 'OkUrl' => $order->success_url, 'FailUrl' => $order->fail_url, @@ -223,6 +222,14 @@ public function createHistoryRequestData(AbstractPosAccount $account, $order, ar throw new NotImplementedException(); } + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : 0; + } + /** * @param AbstractPosAccount $account * @param $order @@ -260,4 +267,18 @@ private function createHashDataForProvision(AbstractPosAccount $account, $order, $hashedPassword, ]; } + + /** + * @param KuveytPosAccount $account + * + * @return array + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'MerchantId' => $account->getClientId(), + 'CustomerId' => $account->getCustomerId(), + 'UserName' => $account->getUsername(), + ]; + } } diff --git a/src/DataMapper/PayForPosRequestDataMapper.php b/src/DataMapper/PayForPosRequestDataMapper.php new file mode 100644 index 00000000..597b23e6 --- /dev/null +++ b/src/DataMapper/PayForPosRequestDataMapper.php @@ -0,0 +1,247 @@ + '3DModel', + AbstractGateway::MODEL_3D_PAY => '3DPay', + AbstractGateway::MODEL_3D_HOST => '3DHost', + AbstractGateway::MODEL_NON_SECURE => 'NonSecure', + ]; + + /** + * @inheritdoc + */ + protected $txTypeMappings = [ + AbstractGateway::TX_PAY => 'Auth', + AbstractGateway::TX_PRE_PAY => 'PreAuth', + AbstractGateway::TX_POST_PAY => 'PostAuth', + AbstractGateway::TX_CANCEL => 'Void', + AbstractGateway::TX_REFUND => 'Refund', + AbstractGateway::TX_HISTORY => 'TxnHistory', + AbstractGateway::TX_STATUS => 'OrderInquiry', + ]; + + /** + * @inheritDoc + */ + public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array + { + return [ + 'RequestGuid' => $responseData['RequestGuid'], + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrderId' => $order->id, + 'SecureType' => '3DModelPayment', + ]; + } + + /** + * @inheritDoc + */ + public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + return $this->getRequestAccountData($account) + [ + 'MbrId' => self::MBR_ID, + 'MOTO' => self::MOTO, + 'OrderId' => $order->id, + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'TxnType' => $this->mapTxType($txType), + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'InstallmentCount' => $this->mapInstallment($order->installment), + 'Lang' => $this->getLang($account, $order), + 'CardHolderName' => $card->getHolderName(), + 'Pan' => $card->getNumber(), + 'Expiry' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), + 'Cvv2' => $card->getCvv(), + ]; + } + + /** + * @inheritDoc + */ + public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array + { + return $this->getRequestAccountData($account) + [ + 'MbrId' => self::MBR_ID, + 'OrgOrderId' => $order->id, + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'TxnType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + 'Lang' => $this->getLang($account, $order), + ]; + } + + /** + * @inheritDoc + */ + public function createStatusRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'MbrId' => self::MBR_ID, + 'OrgOrderId' => $order->id, + 'SecureType' => 'Inquiry', + 'Lang' => $this->getLang($account, $order), + 'TxnType' => $this->mapTxType(AbstractGateway::TX_STATUS), + ]; + } + + /** + * @inheritDoc + */ + public function createCancelRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'MbrId' => self::MBR_ID, + 'OrgOrderId' => $order->id, + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'TxnType' => $this->mapTxType(AbstractGateway::TX_CANCEL), + 'Currency' => $this->mapCurrency($order->currency), + 'Lang' => $this->getLang($account, $order), + ]; + } + + /** + * @inheritDoc + */ + public function createRefundRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'MbrId' => self::MBR_ID, + 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], + 'Lang' => $this->getLang($account, $order), + 'OrgOrderId' => $order->id, + 'TxnType' => $this->mapTxType(AbstractGateway::TX_REFUND), + 'PurchAmount' => $order->amount, + 'Currency' => $this->mapCurrency($order->currency), + ]; + } + + /** + * @inheritDoc + */ + public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array + { + $requestData = [ + 'MbrId' => self::MBR_ID, + 'SecureType' => 'Report', + 'TxnType' => $this->mapTxType(AbstractGateway::TX_HISTORY), + 'Lang' => $this->getLang($account, $order), + ]; + + if (isset($extraData['orderId'])) { + $requestData['OrderId'] = $extraData['orderId']; + } elseif (isset($extraData['reqDate'])) { + //ReqData YYYYMMDD format + $requestData['ReqDate'] = $extraData['reqDate']; + } + + return $this->getRequestAccountData($account) + $requestData; + } + + + /** + * @inheritDoc + */ + public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array + { + $hash = $this->create3DHash($account, $order, $txType); + + $inputs = [ + 'MbrId' => self::MBR_ID, + 'MerchantID' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'OrderId' => $order->id, + 'Lang' => $this->getLang($account, $order), + 'SecureType' => $this->secureTypeMappings[$account->getModel()], + 'TxnType' => $this->mapTxType($txType), + 'PurchAmount' => $order->amount, + 'InstallmentCount' => $this->mapInstallment($order->installment), + 'Currency' => $this->mapCurrency($order->currency), + 'OkUrl' => $order->success_url, + 'FailUrl' => $order->fail_url, + 'Rnd' => $order->rand, + 'Hash' => $hash, + ]; + + if ($card) { + $inputs['CardHolderName'] = $card->getHolderName(); + $inputs['Pan'] = $card->getNumber(); + $inputs['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT); + $inputs['Cvv2'] = $card->getCvv(); + } + + return [ + 'gateway' => $gatewayURL, //to be filled by the caller + 'inputs' => $inputs, + ]; + } + + /** + * @inheritDoc + */ + public function create3DHash(AbstractPosAccount $account, $order, string $txType): string + { + $hashData = [ + self::MBR_ID, + $order->id, + $order->amount, + $order->success_url, + $order->fail_url, + $this->mapTxType($txType), + $this->mapInstallment($order->installment), + $order->rand, + $account->getStoreKey(), + ]; + $hashStr = implode(static::HASH_SEPARATOR, $hashData); + + return $this->hashString($hashStr); + } + + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : 0; + } + + /** + * @param AbstractPosAccount $account + * + * @return array + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + ]; + } +} diff --git a/src/DataMapper/PosNetRequestDataMapper.php b/src/DataMapper/PosNetRequestDataMapper.php new file mode 100644 index 00000000..928048be --- /dev/null +++ b/src/DataMapper/PosNetRequestDataMapper.php @@ -0,0 +1,407 @@ + 'Sale', + AbstractGateway::TX_PRE_PAY => 'Auth', + AbstractGateway::TX_POST_PAY => 'Capt', + AbstractGateway::TX_CANCEL => 'reverse', + AbstractGateway::TX_REFUND => 'return', + AbstractGateway::TX_STATUS => 'agreement', + ]; + + /** + * @inheritdoc + */ + protected $currencyMappings = [ + 'TRY' => 'TL', + 'USD' => 'US', + 'EUR' => 'EU', + 'GBP' => 'GB', + 'JPY' => 'JP', + 'RUB' => 'RU', + ]; + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosTranData' => [ + 'bankData' => $responseData['BankPacket'], + 'merchantData' => $responseData['MerchantPacket'], + 'sign' => $responseData['Sign'], + 'wpAmount' => 0, + 'mac' => $this->create3DHash($account, $order, $txType), + ], + ]; + } + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + $requestData = [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + strtolower($this->mapTxType($txType)) => [ + 'orderID' => self::formatOrderId($order->id), + 'installment' => $this->mapInstallment($order->installment), + 'amount' => self::amountFormat($order->amount), + 'currencyCode' => $this->mapCurrency($order->currency), + 'ccno' => $card->getNumber(), + 'expDate' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), + 'cvc' => $card->getCvv(), + ], + ]; + + if (isset($order->koiCode) && $order->koiCode > 0) { + $requestData[strtolower($this->mapTxType($txType))]['koiCode'] = $order->koiCode; + } + + return $requestData; + } + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + strtolower($this->mapTxType(AbstractGateway::TX_POST_PAY)) => [ + 'hostLogKey' => $order->host_ref_num, + 'amount' => self::amountFormat($order->amount), + 'currencyCode' => $this->mapCurrency($order->currency), + 'installment' => $this->mapInstallment($order->installment), + ], + ]; + } + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function createStatusRequestData(AbstractPosAccount $account, $order): array + { + $txType = $this->mapTxType(AbstractGateway::TX_STATUS); + + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + $txType => [ + 'orderID' => self::mapOrderIdToPrefixedOrderId($order->id, $account->getModel()), + ], + ]; + } + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function createCancelRequestData(AbstractPosAccount $account, $order): array + { + $txType = $this->mapTxType(AbstractGateway::TX_CANCEL); + $requestData = [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + $txType => [ + 'transaction' => 'sale', + ], + ]; + + if (isset($order->auth_code)) { + $requestData[$txType]['authCode'] = $order->auth_code; + } + + //either will work + if (isset($order->host_ref_num)) { + $requestData[$txType]['hostLogKey'] = $order->host_ref_num; + } else { + $requestData[$txType]['orderID'] = self::mapOrderIdToPrefixedOrderId($order->id, $account->getModel()); + } + + return $requestData; + } + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function createRefundRequestData(AbstractPosAccount $account, $order): array + { + $txType = $this->mapTxType(AbstractGateway::TX_REFUND); + $requestData = [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + $txType => [ + 'amount' => self::amountFormat($order->amount), + 'currencyCode' => $this->mapCurrency($order->currency), + ], + ]; + + if (isset($order->host_ref_num)) { + $requestData[$txType]['hostLogKey'] = $order->host_ref_num; + } else { + $requestData[$txType]['orderID'] = self::mapOrderIdToPrefixedOrderId($order->id, $account->getModel()); + } + + return $requestData; + } + + /** + * @inheritDoc + */ + public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array + { + throw new NotImplementedException(); + } + + + /** + * @param PosNetAccount $account + * + * @inheritDoc + * + * @throws Exception + */ + public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null, $extraData = null): array + { + $inputs = [ + 'mid' => $account->getClientId(), + 'posnetID' => $account->getPosNetId(), + 'vftCode' => $account->promotion_code ?? null, //todo bunun account icine veya order icin tasinmasi gerekiyor + 'posnetData' => $extraData['data1'], //Ödeme bilgilerini içermektedir. + 'posnetData2' => $extraData['data2'], //Kart bilgileri request içerisinde bulunuyorsa bu alan oluşturulmaktadır + 'digest' => $extraData['sign'], //Servis imzası. + 'merchantReturnURL' => $order->success_url, + 'url' => '', //todo belki kaldirabiliriz + 'lang' => $this->getLang($account, $order), + ]; + + if (isset($order->koiCode) && $order->koiCode > 0) { + $inputs['useJokerVadaa'] = 1; + } + + return [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * @param string $txType + * @param AbstractCreditCard $card + * + * @return array + */ + public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, $order, string $txType, AbstractCreditCard $card): array + { + if (null === $card->getHolderName() && isset($order->name)) { + $card->setHolderName($order->name); + } + + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosRequestData' => [ + 'posnetid' => $account->getPosNetId(), + 'ccno' => $card->getNumber(), + 'expDate' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), + 'cvc' => $card->getCvv(), + 'amount' => self::amountFormat($order->amount), + 'currencyCode' => $this->mapCurrency($order->currency), + 'installment' => $this->mapInstallment($order->installment), + 'XID' => self::formatOrderId($order->id), + 'cardHolderName' => $card->getHolderName(), + 'tranType' => $txType, + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * @param array $responseData + * + * @return array + */ + public function create3DResolveMerchantRequestData(AbstractPosAccount $account, $order, array $responseData): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosResolveMerchantData' => [ + 'bankData' => $responseData['BankPacket'], + 'merchantData' => $responseData['MerchantPacket'], + 'sign' => $responseData['Sign'], + 'mac' => $this->create3DHash($account, $order, ''), + ], + ]; + } + + + /** + * @param PosNetAccount $account + * + * @inheritDoc + */ + public function create3DHash(AbstractPosAccount $account, $order, string $txType): string + { + if ($account->getModel() === AbstractGateway::MODEL_3D_SECURE || $account->getModel() === AbstractGateway::MODEL_3D_PAY) { + $secondHashData = [ + self::formatOrderId($order->id), + self::amountFormat($order->amount), + $this->mapCurrency($order->currency), + $account->getClientId(), + $this->createSecurityData($account), + ]; + $hashStr = implode(static::HASH_SEPARATOR, $secondHashData); + + return $this->hashString($hashStr); + } + + return ''; + } + + /** + * Make Security Data + * + * @param PosNetAccount $account + * + * @return string + */ + public function createSecurityData(PosNetAccount $account): string + { + $hashData = [ + $account->getStoreKey(), + $account->getTerminalId(), + ]; + $hashStr = implode(static::HASH_SEPARATOR, $hashData); + + return $this->hashString($hashStr); + } + + /** + * Get amount + * formats 10.01 to 1001 + * + * @param float $amount + * + * @return int + */ + public static function amountFormat($amount): int + { + return round($amount, 2) * 100; + } + + /** + * Get PrefixedOrderId + * To check the status of an order or cancel/refund order Yapikredi + * - requires the order length to be 24 + * - and order id prefix which is "TDSC" for 3D payments + * + * @param string $orderId + * @param string $accountModel + * + * @return string + */ + public static function mapOrderIdToPrefixedOrderId(string $orderId, string $accountModel): string + { + $prefix = self::ORDER_ID_REGULAR_PREFIX; + if (AbstractGateway::MODEL_3D_SECURE === $accountModel) { + $prefix = self::ORDER_ID_3D_PREFIX; + } elseif (AbstractGateway::MODEL_3D_PAY === $accountModel) { + $prefix = self::ORDER_ID_3D_PAY_PREFIX; + } + + return $prefix.self::formatOrderId($orderId, self::ORDER_ID_TOTAL_LENGTH - strlen($prefix)); + } + + + /** + * formats order id by adding 0 pad to the left + * + * @param string $orderId + * @param int|null $padLength + * + * @return string + */ + public static function formatOrderId(string $orderId, int $padLength = null): string + { + if (null === $padLength) { + $padLength = self::ORDER_ID_LENGTH; + } + + return str_pad($orderId, $padLength, '0', STR_PAD_LEFT); + } + + /** + * formats installment in 00, 02, 06 format + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + if ($installment > 1) { + return str_pad($installment, 2, '0', STR_PAD_LEFT); + } + + return '00'; + } +} diff --git a/src/DataMapper/VakifBankPosRequestDataMapper.php b/src/DataMapper/VakifBankPosRequestDataMapper.php index b68076fe..3e14fac5 100644 --- a/src/DataMapper/VakifBankPosRequestDataMapper.php +++ b/src/DataMapper/VakifBankPosRequestDataMapper.php @@ -4,7 +4,6 @@ */ namespace Mews\Pos\DataMapper; -use Exception; use Mews\Pos\Entity\Account\AbstractPosAccount; use Mews\Pos\Entity\Account\VakifBankAccount; use Mews\Pos\Entity\Card\AbstractCreditCard; @@ -39,20 +38,6 @@ class VakifBankPosRequestDataMapper extends AbstractRequestDataMapper AbstractCreditCard::CARD_TYPE_AMEX => '400', ]; - /** - * Currency mapping - * - * @var array - */ - protected $currencyMappings = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 643, - ]; - protected $recurringOrderFrequencyMapping = [ 'DAY' => 'Day', 'MONTH' => 'Month', @@ -70,14 +55,11 @@ class VakifBankPosRequestDataMapper extends AbstractRequestDataMapper */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData, ?AbstractCreditCard $card = null): array { - $requestData = [ - 'MerchantId' => $account->getClientId(), - 'Password' => $account->getPassword(), - 'TerminalNo' => $account->getTerminalId(), - 'TransactionType' => $txType, + $requestData = $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType($txType), 'TransactionId' => $order->id, 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => $this->mapCurrency($order->currency), 'CardHoldersName' => $card->getHolderName(), 'Cvv' => $card->getCvv(), 'Pan' => $card->getNumber(), @@ -92,7 +74,7 @@ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, ]; if ($order->installment) { - $requestData['NumberOfInstallments'] = $order->installment; + $requestData['NumberOfInstallments'] = $this->mapInstallment($order->installment); } return $requestData; @@ -113,7 +95,7 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, 'MerchantType' => $account->getMerchantType(), 'PurchaseAmount' => self::amountFormat($order->amount), 'VerifyEnrollmentRequestId' => $order->rand, - 'Currency' => $order->currency, + 'Currency' => $this->mapCurrency($order->currency), 'SuccessUrl' => $order->success_url, 'FailureUrl' => $order->fail_url, 'Pan' => $card->getNumber(), @@ -122,7 +104,7 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, 'IsRecurring' => 'false', ]; if ($order->installment) { - $requestData['InstallmentCount'] = $order->installment; + $requestData['InstallmentCount'] = $this->mapInstallment($order->installment); } if (isset($order->extraData)) { $requestData['SessionInfo'] = $order->extraData; @@ -157,14 +139,11 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, */ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array { - $requestData = [ - 'MerchantId' => $account->getClientId(), - 'Password' => $account->getPassword(), - 'TerminalNo' => $account->getTerminalId(), - 'TransactionType' => $txType, + $requestData = $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType($txType), 'OrderId' => $order->id, 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => $this->mapCurrency($order->currency), 'ClientIp' => $order->ip, 'TransactionDeviceSource' => 0, ]; @@ -187,14 +166,11 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { - return [ - 'MerchantId' => $account->getClientId(), - 'Password' => $account->getPassword(), - 'TerminalNo' => $account->getTerminalId(), - 'TransactionType' => $this->txTypeMappings[AbstractGateway::TX_POST_PAY], + return $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), 'ReferenceTransactionId' => $order->id, 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => $this->mapCurrency($order->currency), 'ClientIp' => $order->ip, ]; } @@ -215,7 +191,7 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar return [ 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), - 'TransactionType' => $this->txTypeMappings[AbstractGateway::TX_CANCEL], + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_CANCEL), 'ReferenceTransactionId' => $order->id, 'ClientIp' => $order->ip, ]; @@ -229,7 +205,7 @@ public function createRefundRequestData(AbstractPosAccount $account, $order): ar return [ 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), - 'TransactionType' => $this->txTypeMappings[AbstractGateway::TX_REFUND], + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_REFUND), 'ReferenceTransactionId' => $order->id, 'ClientIp' => $order->ip, 'CurrencyAmount' => self::amountFormat($order->amount), @@ -245,49 +221,20 @@ public function createHistoryRequestData(AbstractPosAccount $account, $order, ar } /** - * @inheritDoc - */ - public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array - { - throw new NotImplementedException(); - } - - /** - * @param array $data + * @param array $extraData * - * @return array - * - * @throws Exception + * @inheritDoc */ - public function create3DFormDataFromEnrollmentResponse(array $data): array + public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null, array $extraData = []): array { - $response = $data['Message']['VERes']; - /** - * Status values: - * Y:Kart 3-D Secure programına dâhil - * N:Kart 3-D Secure programına dâhil değil - * U:İşlem gerçekleştirilemiyor - * E:Hata durumu - */ - if ('E' === $response['Status']) { - throw new Exception($data['ErrorMessage'], $data['MessageErrorCode']); - } - if ('N' === $response['Status']) { - // todo devam half secure olarak devam et yada satisi iptal et. - throw new Exception('Kart 3-D Secure programına dâhil değil'); - } - if ('U' === $response['Status']) { - throw new Exception('İşlem gerçekleştirilemiyor'); - } - $inputs = [ - 'PaReq' => $response['PaReq'], - 'TermUrl' => $response['TermUrl'], - 'MD' => $response['MD'], + 'PaReq' => $extraData['PaReq'], + 'TermUrl' => $extraData['TermUrl'], + 'MD' => $extraData['MD'], ]; return [ - 'gateway' => $response['ACSUrl'], + 'gateway' => $extraData['ACSUrl'], 'inputs' => $inputs, ]; } @@ -311,4 +258,26 @@ public static function amountFormat(float $amount): string { return number_format($amount, 2, '.', ''); } + + /** + * @inheritdoc + */ + public function mapInstallment(?int $installment) + { + return $installment > 1 ? $installment : 0; + } + + /** + * @param VakifBankAccount $account + * + * @return array + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'MerchantId' => $account->getClientId(), + 'Password' => $account->getPassword(), + 'TerminalNo' => $account->getTerminalId(), + ]; + } } diff --git a/src/Entity/Account/PosNetAccount.php b/src/Entity/Account/PosNetAccount.php index 2e853df7..976b52df 100644 --- a/src/Entity/Account/PosNetAccount.php +++ b/src/Entity/Account/PosNetAccount.php @@ -1,26 +1,18 @@ posNetId = $posNetId; } - /** - * @return string - */ - public function getRefundPassword(): string - { - return $this->refundPassword; - } - - /** - * @return string - */ - public function getRefundUsername(): string - { - return $this->refundUsername; - } - /** * @return string */ @@ -71,5 +47,4 @@ public function getPosNetId(): string { return $this->posNetId; } - -} \ No newline at end of file +} diff --git a/src/Factory/AccountFactory.php b/src/Factory/AccountFactory.php index 1c29f4c6..244a228c 100644 --- a/src/Factory/AccountFactory.php +++ b/src/Factory/AccountFactory.php @@ -1,5 +1,7 @@ getBank()], $posAccount, $currencies); + return new $class($config['banks'][$posAccount->getBank()], $posAccount, self::getGatewayMapper($class, $currencies)); + } + + /** + * @param string $gatewayClass + * @param array $currencies + * + * @return AbstractRequestDataMapper + */ + public static function getGatewayMapper(string $gatewayClass, array $currencies = []): AbstractRequestDataMapper + { + switch ($gatewayClass) { + case EstPos::class: + return new EstPosRequestDataMapper($currencies); + case GarantiPos::class: + return new GarantiPosRequestDataMapper($currencies); + case InterPos::class: + return new InterPosRequestDataMapper($currencies); + case KuveytPos::class: + return new KuveytPosRequestDataMapper($currencies); + case PayForPos::class: + return new PayForPosRequestDataMapper($currencies); + case PosNet::class: + return new PosNetRequestDataMapper($currencies); + case VakifBankPos::class: + return new VakifBankPosRequestDataMapper($currencies); + } + throw new DomainException('unsupported gateway'); } } diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index beefe9ff..7292c9b7 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -1,7 +1,10 @@ requestDataMapper = $requestDataMapper; + $this->cardTypeMapping = $requestDataMapper->getCardTypeMapping(); + $this->recurringOrderFrequencyMapping = $requestDataMapper->getRecurringOrderFrequencyMapping(); + $this->config = $config; $this->account = $account; - - if (count($currencies) > 0) { - $this->currencies = $currencies; - } } /** @@ -147,7 +143,7 @@ public function prepare(array $order, string $txType, $card = null) } /** - * @return mixed + * @return object */ public function getResponse() { @@ -159,7 +155,7 @@ public function getResponse() */ public function getCurrencies(): array { - return $this->currencies; + return $this->requestDataMapper->getCurrencyMappings(); } /** @@ -309,11 +305,9 @@ public function isTestMode(): bool */ public function setTxType(string $txType) { - if (array_key_exists($txType, $this->types)) { - $this->type = $this->types[$txType]; - } else { - throw new UnsupportedTransactionTypeException(); - } + $this->requestDataMapper->mapTxType($txType); + + $this->type = $txType; } /** @@ -347,9 +341,9 @@ public function payment($card = null) public function makeRegularPayment() { $contents = ''; - if (in_array($this->type, [$this->types[self::TX_PAY], $this->types[self::TX_PRE_PAY]])) { + if (in_array($this->type, [self::TX_PAY, self::TX_PRE_PAY])) { $contents = $this->createRegularPaymentXML(); - } elseif ($this->types[self::TX_POST_PAY] === $this->type) { + } elseif (self::TX_POST_PAY === $this->type) { $contents = $this->createRegularPostXML(); } @@ -422,20 +416,14 @@ public function history(array $meta) public function setTestMode(bool $testMode): self { $this->testMode = $testMode; + if (isset($this->requestDataMapper)) { + //todo remove if check after all gateways has requestDataMapper + $this->requestDataMapper->setTestMode($testMode); + } return $this; } - /** - * @param string $currency TRY, USD - * - * @return string - */ - public function mapCurrency(string $currency): string - { - return $this->currencies[$currency] ?? $currency; - } - /** * @param string $period * @@ -454,6 +442,14 @@ public function getCardTypeMapping(): array return $this->cardTypeMapping; } + /** + * @return string[] + */ + public function getLanguages(): array + { + return [self::LANG_TR, self::LANG_EN]; + } + /** * Create Regular Payment XML * @@ -629,7 +625,7 @@ protected function getDefaultPaymentResponse(): array 'order_id' => null, 'trans_id' => null, 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'auth_code' => null, 'host_ref_num' => null, 'proc_return_code' => null, @@ -643,20 +639,6 @@ protected function getDefaultPaymentResponse(): array ]; } - /** - * bank returns error messages for specified language value - * usually accepted values are tr,en - * @return string - */ - protected function getLang(): string - { - if ($this->order && isset($this->order->lang)) { - return $this->order->lang; - } - - return $this->account->getLang(); - } - /** * @param string $str * diff --git a/src/Gateways/EstPos.php b/src/Gateways/EstPos.php index ac68dbaf..e89e4daf 100644 --- a/src/Gateways/EstPos.php +++ b/src/Gateways/EstPos.php @@ -1,8 +1,11 @@ '1', - AbstractCreditCard::CARD_TYPE_MASTERCARD => '2', - ]; - /** * Response Codes @@ -53,42 +44,6 @@ class EstPos extends AbstractGateway '99' => 'general_error', ]; - /** - * Transaction Types - * - * @var array - */ - protected $types = [ - self::TX_PAY => 'Auth', - self::TX_PRE_PAY => 'PreAuth', - self::TX_POST_PAY => 'PostAuth', - self::TX_CANCEL => 'Void', - self::TX_REFUND => 'Credit', - self::TX_STATUS => 'ORDERSTATUS', - self::TX_HISTORY => 'ORDERHISTORY', - ]; - - protected $recurringOrderFrequencyMapping = [ - 'DAY' => 'D', - 'WEEK' => 'W', - 'MONTH' => 'M', - 'YEAR' => 'Y', - ]; - - /** - * Currency mapping - * - * @var array - */ - protected $currencies = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 643, - ]; - /** * @var EstPosAccount */ @@ -101,14 +56,13 @@ class EstPos extends AbstractGateway /** * EstPos constructor. + * @inheritdoc * - * @param array $config - * @param EstPosAccount $account - * @param array $currencies + * @param EstPosAccount $account */ - public function __construct($config, $account, array $currencies = []) + public function __construct(array $config, AbstractPosAccount $account, AbstractRequestDataMapper $requestDataMapper) { - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -119,46 +73,6 @@ public function createXML(array $nodes, string $encoding = 'ISO-8859-9', bool $i return parent::createXML(['CC5Request' => $nodes], $encoding, $ignorePiNode); } - /** - * Create 3D Hash - * - * @param AbstractPosAccount $account - * @param $order - * @param string $txType - * - * @return string - */ - public function create3DHash(AbstractPosAccount $account, $order, string $txType): string - { - $hashData = []; - if ($account->getModel() === self::MODEL_3D_SECURE) { - $hashData = [ - $account->getClientId(), - $order->id, - $order->amount, - $order->success_url, - $order->fail_url, - $order->rand, - $account->getStoreKey(), - ]; - } elseif ($account->getModel() === self::MODEL_3D_PAY || $account->getModel() === self::MODEL_3D_HOST) { - $hashData = [ - $account->getClientId(), - $order->id, - $order->amount, - $order->success_url, - $order->fail_url, - $txType, - $order->installment, - $order->rand, - $account->getStoreKey(), - ]; - } - $hashStr = implode(static::HASH_SEPARATOR, $hashData); - - return $this->hashString($hashStr); - } - /** * Check 3D Hash * @@ -245,42 +159,7 @@ public function get3DFormData(): array return []; } - $this->order->hash = $this->create3DHash($this->account, $this->order, $this->type); - - $inputs = [ - 'clientid' => $this->account->getClientId(), - 'storetype' => $this->account->getModel(), - 'hash' => $this->order->hash, - 'firmaadi' => $this->order->name, - 'Email' => $this->order->email, - 'amount' => $this->order->amount, - 'oid' => $this->order->id, - 'okUrl' => $this->order->success_url, - 'failUrl' => $this->order->fail_url, - 'rnd' => $this->order->rand, - 'lang' => $this->getLang(), - 'currency' => $this->order->currency, - ]; - - if ($this->account->getModel() === self::MODEL_3D_PAY || $this->account->getModel() === self::MODEL_3D_HOST) { - $inputs = array_merge($inputs, [ - 'islemtipi' => $this->type, - 'taksit' => $this->order->installment, - ]); - } - - if ($this->card) { - $inputs['cardType'] = $this->cardTypeMapping[$this->card->getType()]; - $inputs['pan'] = $this->card->getNumber(); - $inputs['Ecom_Payment_Card_ExpDate_Month'] = $this->card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); - $inputs['Ecom_Payment_Card_ExpDate_Year'] = $this->card->getExpireYear(self::CREDIT_CARD_EXP_YEAR_FORMAT); - $inputs['cv2'] = $this->card->getCvv(); - } - - return [ - 'gateway' => $this->get3DGatewayURL(), - 'inputs' => $inputs, - ]; + return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card); } /** @@ -326,29 +205,7 @@ public function getAccount() */ public function createRegularPaymentXML() { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'Type' => $this->type, - 'IPAddress' => $this->order->ip, - 'Email' => $this->order->email, - 'OrderId' => $this->order->id, - 'UserId' => $this->order->user_id ?? null, - 'Total' => $this->order->amount, - 'Currency' => $this->order->currency, - 'Taksit' => $this->order->installment, - 'CardType' => $this->card->getType(), - 'Number' => $this->card->getNumber(), - 'Expires' => $this->card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), - 'Cvv2Val' => $this->card->getCvv(), - 'Mode' => 'P', //TODO what is this constant for? - 'GroupId' => '', - 'TransId' => '', - 'BillTo' => [ - 'Name' => $this->order->name ?: null, - ], - ]; + $requestData = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $this->order, $this->type, $this->card); return $this->createXML($requestData); } @@ -358,13 +215,7 @@ public function createRegularPaymentXML() */ public function createRegularPostXML() { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'Type' => $this->types[self::TX_POST_PAY], - 'OrderId' => $this->order->id, - ]; + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -374,46 +225,7 @@ public function createRegularPostXML() */ public function create3DPaymentXML($responseData) { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'Type' => $this->type, - 'IPAddress' => $this->order->ip, - 'Email' => $this->order->email, - 'OrderId' => $this->order->id, - 'UserId' => $this->order->user_id ?? null, - 'Total' => $this->order->amount, - 'Currency' => $this->order->currency, - 'Taksit' => $this->order->installment, - 'Number' => $responseData['md'], - 'Expires' => '', - 'Cvv2Val' => '', - 'PayerTxnId' => $responseData['xid'], - 'PayerSecurityLevel' => $responseData['eci'], - 'PayerAuthenticationCode' => $responseData['cavv'], - 'CardholderPresentCode' => '13', - 'Mode' => 'P', - 'GroupId' => '', - 'TransId' => '', - ]; - - if ($this->order->name) { - $requestData['BillTo'] = [ - 'Name' => $this->order->name, - ]; - } - - if (isset($this->order->recurringFrequency)) { - $requestData['PbOrder'] = [ - 'OrderType' => 0, - // Periyodik İşlem Frekansı - 'OrderFrequencyInterval' => $this->order->recurringFrequency, - //D|M|Y - 'OrderFrequencyCycle' => $this->order->recurringFrequencyType, - 'TotalNumberPayments' => $this->order->recurringInstallmentCount, - ]; - } + $requestData = $this->requestDataMapper->create3DPaymentRequestData($this->account, $this->order, $this->type, $responseData); return $this->createXML($requestData); } @@ -423,15 +235,7 @@ public function create3DPaymentXML($responseData) */ public function createStatusXML() { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'OrderId' => $this->order->id, - 'Extra' => [ - $this->types[self::TX_STATUS] => 'QUERY', - ], - ]; + $requestData = $this->requestDataMapper->createStatusRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -441,15 +245,7 @@ public function createStatusXML() */ public function createHistoryXML($customQueryData) { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'OrderId' => $customQueryData['order_id'], - 'Extra' => [ - $this->types[self::TX_HISTORY] => 'QUERY', - ], - ]; + $requestData = $this->requestDataMapper->createHistoryRequestData($this->account, $this->order, $customQueryData); return $this->createXML($requestData); } @@ -459,13 +255,7 @@ public function createHistoryXML($customQueryData) */ public function createCancelXML() { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'OrderId' => $this->order->id, - 'Type' => $this->types[self::TX_CANCEL], - ]; + $requestData = $this->requestDataMapper->createCancelRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -475,18 +265,7 @@ public function createCancelXML() */ public function createRefundXML() { - $requestData = [ - 'Name' => $this->account->getUsername(), - 'Password' => $this->account->getPassword(), - 'ClientId' => $this->account->getClientId(), - 'OrderId' => $this->order->id, - 'Currency' => $this->order->currency, - 'Type' => $this->types[self::TX_REFUND], - ]; - - if (isset($this->order->amount)) { - $requestData['Total'] = $this->order->amount; - } + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -543,16 +322,21 @@ protected function map3DPaymentData($raw3DAuthResponseData, $rawPaymentResponseD 'month' => $raw3DAuthResponseData['Ecom_Payment_Card_ExpDate_Month'], 'year' => $raw3DAuthResponseData['Ecom_Payment_Card_ExpDate_Year'], 'amount' => $raw3DAuthResponseData['amount'], - 'currency' => array_search($raw3DAuthResponseData['currency'], $this->currencies), - 'eci' => $raw3DAuthResponseData['eci'], + 'currency' => array_search($raw3DAuthResponseData['currency'], $this->requestDataMapper->getCurrencyMappings()), + 'eci' => null, 'tx_status' => null, - 'cavv' => $raw3DAuthResponseData['cavv'], + 'cavv' => null, 'xid' => $raw3DAuthResponseData['oid'], 'md_error_message' => 'Authenticated' !== $raw3DAuthResponseData['mdErrorMsg'] ? $raw3DAuthResponseData['mdErrorMsg'] : null, 'name' => $raw3DAuthResponseData['firmaadi'], '3d_all' => $raw3DAuthResponseData, ]; + if ('Authenticated' === $raw3DAuthResponseData['mdErrorMsg']) { + $threeDResponse['eci'] = $raw3DAuthResponseData['eci']; + $threeDResponse['cavv'] = $raw3DAuthResponseData['cavv']; + } + return (object) $this->mergeArraysPreferNonNullValues($threeDResponse, $paymentResponseData); } @@ -586,7 +370,7 @@ protected function map3DPayResponseData($raw3DAuthResponseData) 'response' => $raw3DAuthResponseData['Response'], 'order_id' => $raw3DAuthResponseData['oid'], 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'transaction_security' => $transactionSecurity, 'code' => $raw3DAuthResponseData['ProcReturnCode'], 'md_status' => $raw3DAuthResponseData['mdStatus'], @@ -646,7 +430,7 @@ protected function map3DHostResponseData($raw3DAuthResponseData) 'response' => null, 'order_id' => $raw3DAuthResponseData['oid'], 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'transaction_security' => $transactionSecurity, 'code' => null, 'md_status' => $raw3DAuthResponseData['mdStatus'], @@ -660,7 +444,7 @@ protected function map3DHostResponseData($raw3DAuthResponseData) 'month' => $raw3DAuthResponseData['Ecom_Payment_Card_ExpDate_Month'], 'year' => $raw3DAuthResponseData['Ecom_Payment_Card_ExpDate_Year'], 'amount' => $raw3DAuthResponseData['amount'], - 'currency' => array_search($raw3DAuthResponseData['currency'], $this->currencies), + 'currency' => array_search($raw3DAuthResponseData['currency'], $this->requestDataMapper->getCurrencyMappings()), 'tx_status' => null, 'eci' => $raw3DAuthResponseData['eci'], 'cavv' => $raw3DAuthResponseData['cavv'], @@ -800,7 +584,7 @@ protected function mapPaymentResponse($responseData): array 'trans_id' => $responseData['TransId'], 'response' => $responseData['Response'], 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'auth_code' => $responseData['AuthCode'], 'host_ref_num' => $responseData['HostRefNum'], 'proc_return_code' => $responseData['ProcReturnCode'], @@ -844,20 +628,14 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = (int) $order['installment']; - } - if (isset($order['recurringFrequency'])) { $order['recurringFrequencyType'] = $this->mapRecurringFrequency($order['recurringFrequencyType']); } // Order return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($order['currency']), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', ]); } @@ -902,7 +680,7 @@ protected function prepareRefundOrder(array $order) { return (object) [ 'id' => $order['id'], - 'currency' => $this->mapCurrency($order['currency']), + 'currency' => $order['currency'] ?? 'TRY', 'amount' => $order['amount'], ]; } diff --git a/src/Gateways/GarantiPos.php b/src/Gateways/GarantiPos.php index 8c70854a..23adccb3 100644 --- a/src/Gateways/GarantiPos.php +++ b/src/Gateways/GarantiPos.php @@ -1,8 +1,13 @@ 'general_error', ]; - /** - * Transaction Types - * - * @var array - */ - protected $types = [ - self::TX_PAY => 'sales', - self::TX_PRE_PAY => 'preauth', - self::TX_POST_PAY => 'postauth', - self::TX_CANCEL => 'void', - self::TX_REFUND => 'refund', - self::TX_HISTORY => 'orderhistoryinq', - self::TX_STATUS => 'orderinq', - ]; - - protected $secureTypeMappings = [ - self::MODEL_3D_SECURE => '3D', - self::MODEL_3D_PAY => '3D_PAY', - self::MODEL_3D_HOST => null, //todo - self::MODEL_NON_SECURE => null, //todo - ]; - - /** - * currency mapping - * - * @var array - */ - protected $currencies = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 643, - ]; - - /** - * @var GarantiPosAccount - */ + /** @var GarantiPosAccount */ protected $account; - /** - * @var AbstractCreditCard - */ + /**4 @var AbstractCreditCard */ protected $card; + /** @var GarantiPosRequestDataMapper */ + protected $requestDataMapper; + /** * GarantiPost constructor. + * @inheritdoc * - * @param array $config - * @param GarantiPosAccount $account - * @param array $currencies + * @param GarantiPosAccount $account */ - public function __construct($config, $account, array $currencies = []) + public function __construct(array $config, AbstractPosAccount $account, AbstractRequestDataMapper $requestDataMapper) { - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -132,7 +86,7 @@ public function createXML(array $nodes, string $encoding = 'UTF-8', bool $ignore public function make3DPayment(Request $request) { $bankResponse = null; - //TODO hash check + //TODO add hash check if (in_array($request->get('mdstatus'), [1, 2, 3, 4])) { $contents = $this->create3DPaymentXML($request->request->all()); $bankResponse = $this->send($contents); @@ -153,7 +107,6 @@ public function make3DPayPayment(Request $request) return $this; } - /** * @inheritDoc */ @@ -193,39 +146,7 @@ public function get3DFormData(): array return []; } - $hashData = $this->create3DHash($this->account, $this->order, $this->type); - - $inputs = [ - 'secure3dsecuritylevel' => $this->secureTypeMappings[$this->account->getModel()], - 'mode' => $this->getMode(), - 'apiversion' => self::API_VERSION, - 'terminalprovuserid' => $this->account->getUsername(), - 'terminaluserid' => $this->account->getUsername(), - 'terminalmerchantid' => $this->account->getClientId(), - 'txntype' => $this->type, - 'txnamount' => $this->order->amount, - 'txncurrencycode' => $this->order->currency, - 'txninstallmentcount' => $this->order->installment, - 'orderid' => $this->order->id, - 'terminalid' => $this->account->getTerminalId(), - 'successurl' => $this->order->success_url, - 'errorurl' => $this->order->fail_url, - 'customeremailaddress' => $this->order->email ?? null, - 'customeripaddress' => $this->order->ip, - 'secure3dhash' => $hashData, - ]; - - if ($this->card) { - $inputs['cardnumber'] = $this->card->getNumber(); - $inputs['cardexpiredatemonth'] = $this->card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); - $inputs['cardexpiredateyear'] = $this->card->getExpireYear(self::CREDIT_CARD_EXP_YEAR_FORMAT); - $inputs['cardcvv2'] = $this->card->getCvv(); - } - - return [ - 'gateway' => $this->get3DGatewayURL(), - 'inputs' => $inputs, - ]; + return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card); } /** @@ -242,54 +163,7 @@ public function make3DHostPayment(Request $request) */ public function createRegularPaymentXML() { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'Terminal' => [ - 'ProvUserID' => $this->account->getUsername(), - 'UserID' => $this->account->getUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type, $this->card), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Card' => [ - 'Number' => $this->card->getNumber(), - 'ExpireDate' => $this->card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), - 'CVV2' => $this->card->getCvv(), - ], - 'Order' => [ - 'OrderID' => $this->order->id, - 'GroupID' => '', - 'AddressList' => [ - 'Address' => [ - 'Type' => 'S', - 'Name' => $this->order->name, - 'LastName' => '', - 'Company' => '', - 'Text' => '', - 'District' => '', - 'City' => '', - 'PostalCode' => '', - 'Country' => '', - 'PhoneNumber' => '', - ], - ], - ], - 'Transaction' => [ - 'Type' => $this->type, - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $this->order->amount, - 'CurrencyCode' => $this->order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'Description' => '', - 'OriginalRetrefNum' => '', - ], - ]; + $requestData = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $this->order, $this->type, $this->card); return $this->createXML($requestData); } @@ -299,30 +173,7 @@ public function createRegularPaymentXML() */ public function createRegularPostXML() { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'Terminal' => [ - 'ProvUserID' => $this->account->getUsername(), - 'UserID' => $this->account->getUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type, $this->card), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Order' => [ - 'OrderID' => $this->order->id, - ], - 'Transaction' => [ - 'Type' => $this->types[self::TX_POST_PAY], - 'Amount' => $this->order->amount, - 'CurrencyCode' => $this->order->currency, - 'OriginalRetrefNum' => $this->order->ref_ret_num, - ], - ]; + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -332,59 +183,7 @@ public function createRegularPostXML() */ public function create3DPaymentXML($responseData) { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $this->account->getUsername(), - 'UserID' => $this->account->getUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type, $this->card), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $responseData['customeripaddress'], - 'EmailAddress' => $responseData['customeremailaddress'], - ], - 'Card' => [ - 'Number' => '', - 'ExpireDate' => '', - 'CVV2' => '', - ], - 'Order' => [ - 'OrderID' => $responseData['orderid'], - 'GroupID' => '', - 'AddressList' => [ - 'Address' => [ - 'Type' => 'B', - 'Name' => $this->order->name, - 'LastName' => '', - 'Company' => '', - 'Text' => '', - 'District' => '', - 'City' => '', - 'PostalCode' => '', - 'Country' => '', - 'PhoneNumber' => '', - ], - ], - ], - 'Transaction' => [ - 'Type' => $responseData['txntype'], - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $responseData['txnamount'], - 'CurrencyCode' => $responseData['txncurrencycode'], - 'CardholderPresentCode' => '13', - 'MotoInd' => 'N', - 'Secure3D' => [ - 'AuthenticationCode' => $responseData['cavv'], - 'SecurityLevel' => $responseData['eci'], - 'TxnID' => $responseData['xid'], - 'Md' => $responseData['md'], - ], - ], - ]; + $requestData = $this->requestDataMapper->create3DPaymentRequestData($this->account, $this->order, $this->type, $responseData); return $this->createXML($requestData); } @@ -394,35 +193,7 @@ public function create3DPaymentXML($responseData) */ public function createCancelXML() { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $this->account->getRefundUsername(), - 'UserID' => $this->account->getRefundUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Order' => [ - 'OrderID' => $this->order->id, - 'GroupID' => '', - ], - 'Transaction' => [ - 'Type' => $this->types[self::TX_CANCEL], - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $this->order->amount, //TODO we need this field here? - 'CurrencyCode' => $this->order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'OriginalRetrefNum' => $this->order->ref_ret_num, - ], - ]; + $requestData = $this->requestDataMapper->createCancelRequestData($this->getAccount(), $this->getOrder()); return $this->createXML($requestData); } @@ -432,35 +203,7 @@ public function createCancelXML() */ public function createRefundXML() { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $this->account->getRefundUsername(), - 'UserID' => $this->account->getRefundUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Order' => [ - 'OrderID' => $this->order->id, - 'GroupID' => '', - ], - 'Transaction' => [ - 'Type' => $this->types[self::TX_REFUND], - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $this->order->amount, - 'CurrencyCode' => $this->order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'OriginalRetrefNum' => $this->order->ref_ret_num, - ], - ]; + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -470,39 +213,7 @@ public function createRefundXML() */ public function createHistoryXML($customQueryData) { - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $this->account->getUsername(), - 'UserID' => $this->account->getUsername(), - 'HashData' => $this->createHashData($this->account, $this->order, $this->type), - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ //TODO we need this data? - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Order' => [ - 'OrderID' => $this->order->id, - 'GroupID' => '', - ], - 'Card' => [ - 'Number' => '', - 'ExpireDate' => '', - 'CVV2' => '', - ], - 'Transaction' => [ - 'Type' => $this->types[self::TX_HISTORY], - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $this->order->amount, - 'CurrencyCode' => $this->order->currency, //TODO we need it? - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - ], - ]; + $requestData = $this->requestDataMapper->createHistoryRequestData($this->account, $this->order, $customQueryData); return $this->createXML($requestData); } @@ -512,115 +223,11 @@ public function createHistoryXML($customQueryData) */ public function createStatusXML() { - $hashData = $this->createHashData($this->account, $this->order, $this->type); - - $requestData = [ - 'Mode' => $this->getMode(), - 'Version' => self::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $this->account->getUsername(), - 'UserID' => $this->account->getUsername(), - 'HashData' => $hashData, - 'ID' => $this->account->getTerminalId(), - 'MerchantID' => $this->account->getClientId(), - ], - 'Customer' => [ //TODO we need this data? - 'IPAddress' => $this->order->ip, - 'EmailAddress' => $this->order->email, - ], - 'Order' => [ - 'OrderID' => $this->order->id, - 'GroupID' => '', - ], - 'Card' => [ - 'Number' => '', - 'ExpireDate' => '', - 'CVV2' => '', - ], - 'Transaction' => [ - 'Type' => $this->types[self::TX_STATUS], - 'InstallmentCnt' => $this->order->installment, - 'Amount' => $this->order->amount, //TODO we need it? - 'CurrencyCode' => $this->order->currency, //TODO we need it? - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - ], - ]; + $requestData = $this->requestDataMapper->createStatusRequestData($this->account, $this->order); return $this->createXML($requestData); } - /** - * Make Hash Data - * - * @param GarantiPosAccount $account - * @param $order - * @param string $txType - * @param AbstractCreditCard|null $card - * - * @return string - */ - public function createHashData(GarantiPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): string - { - $map = [ - $order->id, - $account->getTerminalId(), - isset($card) ? $card->getNumber() : null, - $order->amount, - $this->createSecurityData($account, $txType), - ]; - - return $this->hashString(implode(static::HASH_SEPARATOR, $map)); - } - - - /** - * Make 3d Hash Data - * - * @param GarantiPosAccount $account - * @param $order - * @param string $txType - * - * @return string - */ - public function create3DHash(GarantiPosAccount $account, $order, string $txType): string - { - $map = [ - $account->getTerminalId(), - $order->id, - $order->amount, - $order->success_url, - $order->fail_url, - $txType, - $order->installment, - $account->getStoreKey(), - $this->createSecurityData($account, $txType), - ]; - - return $this->hashString(implode(static::HASH_SEPARATOR, $map)); - } - - /** - * Amount Formatter - * converts 100 to 10000, or 10.01 to 1001 - * @param float $amount - * - * @return int - */ - public static function amountFormat($amount): int - { - return round($amount, 2) * 100; - } - - /** - * @return string - */ - protected function getMode(): string - { - return !$this->isTestMode() ? 'PROD' : 'TEST'; - } - /** * todo use tDPayResponseCommon() method to map response * @inheritDoc @@ -725,7 +332,7 @@ protected function tDPayResponseCommon(array $raw3DAuthResponseData): array 'host_ref_num' => null, 'response' => $response, 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'transaction_security' => $transactionSecurity, 'proc_return_code' => $procReturnCode, 'code' => $procReturnCode, @@ -770,7 +377,7 @@ protected function mapPaymentResponse($responseData): array 'trans_id' => isset($responseData->Transaction->AuthCode) ? $this->printData($responseData->Transaction->AuthCode) : null, 'response' => isset($responseData->Transaction->Response->Message) ? $this->printData($responseData->Transaction->Response->Message) : null, 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'auth_code' => isset($responseData->Transaction->AuthCode) ? $this->printData($responseData->Transaction->AuthCode) : null, 'host_ref_num' => isset($responseData->Transaction->RetrefNum) ? $this->printData($responseData->Transaction->RetrefNum) : null, 'ret_ref_num' => isset($responseData->Transaction->RetrefNum) ? $this->printData($responseData->Transaction->RetrefNum) : null, @@ -915,17 +522,10 @@ protected function getStatusDetail(): ?string */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = ''; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = $order['installment']; - } - - // Order return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($order['currency']), - 'amount' => self::amountFormat($order['amount']), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', + 'amount' => $order['amount'], 'ip' => $order['ip'] ?? '', 'email' => $order['email'] ?? '', ]); @@ -939,8 +539,8 @@ protected function preparePostPaymentOrder(array $order) return (object) [ 'id' => $order['id'], 'ref_ret_num' => $order['ref_ret_num'], - 'currency' => $this->mapCurrency($order['currency']), - 'amount' => self::amountFormat($order['amount']), + 'currency' => $order['currency'] ?? 'TRY', + 'amount' => $order['amount'], 'ip' => $order['ip'] ?? '', 'email' => $order['email'] ?? '', ]; @@ -953,11 +553,11 @@ protected function prepareStatusOrder(array $order) { return (object) [ 'id' => $order['id'], - 'amount' => self::amountFormat(1), - 'currency' => $this->mapCurrency($order['currency']), + 'amount' => 1, //sabit deger gonderilmesi gerekiyor + 'currency' => $order['currency'] ?? 'TRY', 'ip' => $order['ip'] ?? '', 'email' => $order['email'] ?? '', - 'installment' => '', + 'installment' => 0, ]; } @@ -976,12 +576,12 @@ protected function prepareCancelOrder(array $order) { return (object) [ 'id' => $order['id'], - 'amount' => self::amountFormat(1), - 'currency' => $this->mapCurrency($order['currency']), + 'amount' => 1, //sabit deger gonderilmesi gerekiyor + 'currency' => $order['currency'] ?? 'TRY', 'ref_ret_num' => $order['ref_ret_num'], 'ip' => $order['ip'] ?? '', 'email' => $order['email'] ?? '', - 'installment' => '', + 'installment' => 0, ]; } @@ -992,38 +592,4 @@ protected function prepareRefundOrder(array $order) { return $this->prepareCancelOrder($order); } - - /** - * @param string $str - * - * @return string - */ - protected function hashString(string $str): string - { - return strtoupper(hash(static::HASH_ALGORITHM, $str)); - } - - /** - * Make Security Data - * - * @param GarantiPosAccount $account - * @param string $txType - * - * @return string - */ - private function createSecurityData(GarantiPosAccount $account, string $txType): string - { - if ($txType === $this->types[self::TX_REFUND] || $txType === $this->types[self::TX_CANCEL]) { - $password = $account->getRefundPassword(); - } else { - $password = $account->getPassword(); - } - - $map = [ - $password, - str_pad((int) $account->getTerminalId(), 9, 0, STR_PAD_LEFT), - ]; - - return $this->hashString(implode(static::HASH_SEPARATOR, $map)); - } } diff --git a/src/Gateways/InterPos.php b/src/Gateways/InterPos.php index da546854..6f8a5a81 100644 --- a/src/Gateways/InterPos.php +++ b/src/Gateways/InterPos.php @@ -1,8 +1,11 @@ requestDataMapper = new InterPosRequestDataMapper($currencies); - $this->types = $this->requestDataMapper->getTxTypeMappings(); - $this->currencies = $this->requestDataMapper->getCurrencyMappings(); - $this->cardTypeMapping = $this->requestDataMapper->getCardTypeMapping(); - - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -307,7 +302,7 @@ protected function map3DPaymentData($raw3DAuthResponseData, $rawPaymentResponseD 'month' => null, 'year' => null, 'amount' => $raw3DAuthResponseData['PurchAmount'], - 'currency' => array_search($raw3DAuthResponseData['Currency'], $this->currencies), + 'currency' => array_search($raw3DAuthResponseData['Currency'], $this->requestDataMapper->getCurrencyMappings()), 'eci' => $raw3DAuthResponseData['Eci'], 'tx_status' => $raw3DAuthResponseData['TxnStat'], 'cavv' => null, @@ -468,15 +463,9 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = ''; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = (int) $order['installment']; - } - return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($order['currency']), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', ]); } @@ -488,7 +477,7 @@ protected function preparePostPaymentOrder(array $order) return (object) [ 'id' => $order['id'], 'amount' => $order['amount'], - 'currency' => $order['currency'], + 'currency' => $order['currency'] ?? 'TRY', ]; } diff --git a/src/Gateways/KuveytPos.php b/src/Gateways/KuveytPos.php index 682ca58a..4ebcb1bb 100644 --- a/src/Gateways/KuveytPos.php +++ b/src/Gateways/KuveytPos.php @@ -1,5 +1,7 @@ requestDataMapper = new KuveytPosRequestDataMapper($currencies); - $this->types = $this->requestDataMapper->getTxTypeMappings(); - $this->currencies = $this->requestDataMapper->getCurrencyMappings(); - $this->cardTypeMapping = $this->requestDataMapper->getCardTypeMapping(); - - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -305,7 +299,7 @@ protected function mapPaymentResponse($responseData): array $result['order_id'] = $responseData['MerchantOrderId']; $result['host_ref_num'] = $responseData['RRN']; $result['amount'] = $responseData['VPosMessage']['Amount']; - $result['currency'] = array_search($responseData['VPosMessage']['CurrencyCode'], $this->currencies); + $result['currency'] = array_search($responseData['VPosMessage']['CurrencyCode'], $this->requestDataMapper->getCurrencyMappings()); $result['masked_number'] = $responseData['VPosMessage']['CardNumber']; return $result; @@ -356,15 +350,9 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = (int) $order['installment']; - } - return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($order['currency']), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', ]); } @@ -523,7 +511,7 @@ private function tDPayResponseCommon(array $raw3DAuthResponseData): array 'order_id' => $orderId, 'response' => $response, 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'transaction_security' => $transactionSecurity, 'proc_return_code' => $procReturnCode, 'code' => $procReturnCode, @@ -545,7 +533,7 @@ private function tDPayResponseCommon(array $raw3DAuthResponseData): array if ('approved' === $status) { $default['hash'] = $raw3DAuthResponseData['VPosMessage']['HashData']; $default['amount'] = $raw3DAuthResponseData['VPosMessage']['Amount']; - $default['currency'] = array_search($raw3DAuthResponseData['VPosMessage']['CurrencyCode'], $this->currencies); + $default['currency'] = array_search($raw3DAuthResponseData['VPosMessage']['CurrencyCode'], $this->requestDataMapper->getCurrencyMappings()); $default['masked_number'] = $raw3DAuthResponseData['VPosMessage']['CardNumber']; } diff --git a/src/Gateways/PayForPos.php b/src/Gateways/PayForPos.php index c6663b21..e048cbd3 100644 --- a/src/Gateways/PayForPos.php +++ b/src/Gateways/PayForPos.php @@ -1,9 +1,12 @@ 'Auth', - self::TX_PRE_PAY => 'PreAuth', - self::TX_POST_PAY => 'PostAuth', - self::TX_CANCEL => 'Void', - self::TX_REFUND => 'Refund', - self::TX_HISTORY => 'TxnHistory', - self::TX_STATUS => 'OrderInquiry', - ]; - - protected $secureTypeMappings = [ - self::MODEL_3D_SECURE => '3DModel', - self::MODEL_3D_PAY => '3DPay', - self::MODEL_3D_HOST => '3DHost', - self::MODEL_NON_SECURE => 'NonSecure', - ]; - - /** - * currency mapping - * - * @var array - */ - protected $currencies = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 643, - ]; + protected $requestDataMapper; /** * @inheritDoc * * @param PayForAccount $account */ - public function __construct($config, $account, array $currencies) + public function __construct(array $config, AbstractPosAccount $account, AbstractRequestDataMapper $requestDataMapper) { - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -205,18 +162,12 @@ public function get3DFormData(): array return []; } - $this->order->hash = $this->create3DHash($this->account, $this->order, $this->type); - - $formData = $this->getCommon3DFormData(); - if (self::MODEL_3D_PAY === $this->account->getModel()) { - $formData['gateway'] = $this->get3DGatewayURL(); - } elseif (self::MODEL_3D_SECURE === $this->account->getModel()) { - $formData['gateway'] = $this->get3DGatewayURL(); - } else { - $formData['gateway'] = $this->get3DHostGatewayURL(); + $gatewayURL = $this->get3DGatewayURL(); + if (self::MODEL_3D_HOST === $this->account->getModel()) { + $gatewayURL = $this->get3DHostGatewayURL(); } - return $formData; + return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $gatewayURL, $this->card); } @@ -243,9 +194,9 @@ public function send($postData, ?string $url = null) * \r\n * \r\n * \r\n - * redundant whitespaces causes non empty value for response properties + * redundant whitespaces causes non-empty value for response properties */ - $contents = preg_replace('/\\r\\n /', '', $contents); + $contents = preg_replace('/\\r\\n\s*/', '', $contents); try { $this->data = $this->XMLStringToObject($contents); @@ -265,32 +216,6 @@ public function createXML(array $nodes, string $encoding = 'UTF-8', bool $ignore return parent::createXML(['PayforRequest' => $nodes], $encoding, $ignorePiNode); } - - /** - * @param AbstractPosAccount $account - * @param $order - * @param string $txType - * - * @return string - */ - public function create3DHash(AbstractPosAccount $account, $order, string $txType): string - { - $hashData = [ - self::MBR_ID, - $order->id, - $order->amount, - $order->success_url, - $order->fail_url, - $txType, - $order->installment, - $order->rand, - $account->getStoreKey(), - ]; - $hashStr = implode(static::HASH_SEPARATOR, $hashData); - - return $this->hashString($hashStr); - } - /** * validates response hash * @@ -324,24 +249,7 @@ public function check3DHash(AbstractPosAccount $account, array $data): bool */ public function createRegularPaymentXML() { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'MOTO' => self::MOTO, - 'OrderId' => $this->order->id, - 'SecureType' => $this->secureTypeMappings[self::MODEL_NON_SECURE], - 'TxnType' => $this->type, - 'PurchAmount' => $this->order->amount, - 'Currency' => $this->order->currency, - 'InstallmentCount' => $this->order->installment, - 'Lang' => $this->getLang(), - 'CardHolderName' => $this->card->getHolderName(), - 'Pan' => $this->card->getNumber(), - 'Expiry' => $this->card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), - 'Cvv2' => $this->card->getCvv(), - ]; + $requestData = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $this->order, $this->type, $this->card); return $this->createXML($requestData); } @@ -351,18 +259,7 @@ public function createRegularPaymentXML() */ public function createRegularPostXML() { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'OrgOrderId' => $this->order->id, - 'SecureType' => $this->secureTypeMappings[self::MODEL_NON_SECURE], - 'TxnType' => $this->type, - 'PurchAmount' => $this->order->amount, - 'Currency' => $this->order->currency, - 'Lang' => $this->getLang(), - ]; + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -372,13 +269,7 @@ public function createRegularPostXML() */ public function create3DPaymentXML($responseData) { - $requestData = [ - 'RequestGuid' => $responseData['RequestGuid'], - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'OrderId' => $this->order->id, - 'SecureType' => '3DModelPayment', - ]; + $requestData = $this->requestDataMapper->create3DPaymentRequestData($this->account, $this->order, '', $responseData); return $this->createXML($requestData); } @@ -388,16 +279,7 @@ public function create3DPaymentXML($responseData) */ public function createStatusXML() { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'OrgOrderId' => $this->order->id, - 'SecureType' => 'Inquiry', - 'Lang' => $this->getLang(), - 'TxnType' => $this->types[self::TX_STATUS], - ]; + $requestData = $this->requestDataMapper->createStatusRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -407,23 +289,7 @@ public function createStatusXML() */ public function createHistoryXML($customQueryData) { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'SecureType' => 'Report', - 'TxnType' => $this->types[self::TX_HISTORY], - 'Lang' => $this->getLang(), - ]; - - if (isset($customQueryData['orderId'])) { - $requestData['OrderId'] = $customQueryData['orderId']; - } elseif (isset($customQueryData['reqDate'])) { - //ReqData YYYYMMDD format - $requestData['ReqDate'] = $customQueryData['reqDate']; - } - + $requestData = $this->requestDataMapper->createHistoryRequestData($this->account, $this->order, $customQueryData); return $this->createXML($requestData); } @@ -433,18 +299,7 @@ public function createHistoryXML($customQueryData) */ public function createRefundXML() { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'SecureType' => $this->secureTypeMappings[self::MODEL_NON_SECURE], - 'Lang' => $this->getLang(), - 'OrgOrderId' => $this->order->id, - 'TxnType' => $this->types[self::TX_REFUND], - 'PurchAmount' => $this->order->amount, - 'Currency' => $this->order->currency, - ]; + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -454,17 +309,7 @@ public function createRefundXML() */ public function createCancelXML() { - $requestData = [ - 'MbrId' => self::MBR_ID, - 'MerchantId' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'UserPass' => $this->account->getPassword(), - 'OrgOrderId' => $this->order->id, - 'SecureType' => $this->secureTypeMappings[self::MODEL_NON_SECURE], - 'TxnType' => $this->types[self::TX_CANCEL], - 'Currency' => $this->order->currency, - 'Lang' => $this->getLang(), - ]; + $requestData = $this->requestDataMapper->createCancelRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -521,8 +366,8 @@ protected function map3DPayResponseData($raw3DAuthResponseData) 'status_detail' => $this->codes[$raw3DAuthResponseData['ProcReturnCode']] ?? null, 'error_code' => ('approved' !== $status) ? $raw3DAuthResponseData['ProcReturnCode'] : null, 'error_message' => ('approved' !== $status) ? $raw3DAuthResponseData['ErrMsg'] : null, - 'transaction_type' => array_search($raw3DAuthResponseData['TxnType'], $this->types, true), - 'transaction' => $this->type, + 'transaction' => array_search($raw3DAuthResponseData['TxnType'], $this->requestDataMapper->getTxTypeMappings(), true), + 'transaction_type' => $this->type, ]; return (object) array_merge($threeDResponse, $this->map3DCommonResponseData($raw3DAuthResponseData)); @@ -545,7 +390,7 @@ protected function map3DCommonResponseData($raw3DAuthResponseData): array 'rand' => $raw3DAuthResponseData['ResponseRnd'], 'masked_number' => $raw3DAuthResponseData['CardMask'], 'amount' => $raw3DAuthResponseData['PurchAmount'], - 'currency' => array_search($raw3DAuthResponseData['Currency'], $this->currencies), + 'currency' => array_search($raw3DAuthResponseData['Currency'], $this->requestDataMapper->getCurrencyMappings()), 'tx_status' => $raw3DAuthResponseData['TxnResult'], 'xid' => $raw3DAuthResponseData['PayerTxnId'], 'md_code' => $raw3DAuthResponseData['ProcReturnCode'], @@ -606,7 +451,7 @@ protected function mapPaymentResponse($responseData): array 'order_id' => $responseData->TransId, 'trans_id' => $responseData->TransId, 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'auth_code' => $responseData->AuthCode, 'host_ref_num' => $responseData->HostRefNum, 'proc_return_code' => $responseData->ProcReturnCode, @@ -646,53 +491,16 @@ protected function mapStatusResponse($rawResponseData) 'error_message' => ('declined' === $status) ? $rawResponseData->ErrMsg : null, 'host_ref_num' => $rawResponseData->HostRefNum ?? null, 'order_status' => $orderStatus, - 'process_type' => isset($rawResponseData->TxnType) ? array_search($rawResponseData->TxnType, $this->types, true) : null, + 'process_type' => isset($rawResponseData->TxnType) ? array_search($rawResponseData->TxnType, $this->requestDataMapper->getTxTypeMappings(), true) : null, 'masked_number' => $rawResponseData->CardMask ?? null, 'amount' => $rawResponseData->PurchAmount ?? null, - 'currency' => isset($rawResponseData->Currency) ? array_search($rawResponseData->Currency, $this->currencies) : null, + 'currency' => isset($rawResponseData->Currency) ? array_search($rawResponseData->Currency, $this->requestDataMapper->getCurrencyMappings()) : null, 'status' => $status, 'status_detail' => $this->codes[$rawResponseData->ProcReturnCode] ?? null, 'all' => $rawResponseData, ]; } - /** - * returns common form data used by all 3D payment gates - * - * @return array - */ - protected function getCommon3DFormData(): array - { - $inputs = [ - 'MbrId' => self::MBR_ID, - 'MerchantID' => $this->account->getClientId(), - 'UserCode' => $this->account->getUsername(), - 'OrderId' => $this->order->id, - 'Lang' => $this->getLang(), - 'SecureType' => $this->secureTypeMappings[$this->account->getModel()], - 'TxnType' => $this->type, - 'PurchAmount' => $this->order->amount, - 'InstallmentCount' => $this->order->installment, - 'Currency' => $this->order->currency, - 'OkUrl' => $this->order->success_url, - 'FailUrl' => $this->order->fail_url, - 'Rnd' => $this->order->rand, - 'Hash' => $this->order->hash, - ]; - - if ($this->card) { - $inputs['CardHolderName'] = $this->card->getHolderName(); - $inputs['Pan'] = $this->card->getNumber(); - $inputs['Expiry'] = $this->card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT); - $inputs['Cvv2'] = $this->card->getCvv(); - } - - return [ - 'gateway' => null, //to be filled by the caller - 'inputs' => $inputs, - ]; - } - /** * @inheritDoc */ @@ -706,18 +514,9 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = (int) $order['installment']; - } - - $currency = $order['currency'] ?? 'TRY'; - - // Order return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($currency), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', ]); } @@ -729,7 +528,7 @@ protected function preparePostPaymentOrder(array $order) return (object) [ 'id' => $order['id'], 'amount' => $order['amount'], - 'currency' => $this->mapCurrency($order['currency']), + 'currency' => $order['currency'] ?? 'TRY', ]; } @@ -758,8 +557,6 @@ protected function prepareHistoryOrder(array $order) */ protected function prepareCancelOrder(array $order) { - $order['currency'] = $this->mapCurrency($order['currency']); - return (object) $order; } @@ -768,8 +565,6 @@ protected function prepareCancelOrder(array $order) */ protected function prepareRefundOrder(array $order) { - $order['currency'] = $this->mapCurrency($order['currency']); - return (object) $order; } } diff --git a/src/Gateways/PosNet.php b/src/Gateways/PosNet.php index 6b4898fd..4ade27b7 100644 --- a/src/Gateways/PosNet.php +++ b/src/Gateways/PosNet.php @@ -1,9 +1,14 @@ 'bank_call', ]; - /** - * Transaction Types - * - * @var array - */ - protected $types = [ - self::TX_PAY => 'Sale', - self::TX_PRE_PAY => 'Auth', - self::TX_POST_PAY => 'Capt', - self::TX_CANCEL => 'reverse', - self::TX_REFUND => 'return', - self::TX_STATUS => 'agreement', - ]; - - /** - * Fixed Currencies - * @var array - */ - protected $currencies = [ - 'TRY' => 'TL', - 'USD' => 'US', - 'EUR' => 'EU', - 'GBP' => 'GB', - 'JPY' => 'JP', - 'RUB' => 'RU', - ]; + /** @var PosNetAccount */ + protected $account; - /** - * API Account - * - * @var PosNetAccount - */ - protected $account = []; - - /** - * @var AbstractCreditCard|null - */ + /** @var AbstractCreditCard|null */ protected $card; - /** - * Request - * - * @var Request - */ + /** @var Request */ protected $request; - /** - * @var PosNetCrypt|null - */ - public $crypt; + /** @var PosNetCrypt|null */ + private $crypt; + + /** @var PosNetRequestDataMapper */ + protected $requestDataMapper; /** * PosNet constructor. + * @inheritdoc * - * @param array $config * @param PosNetAccount $account - * @param array $currencies */ - public function __construct($config, $account, array $currencies) + public function __construct(array $config, AbstractPosAccount $account, AbstractRequestDataMapper $requestDataMapper) { $this->crypt = new PosNetCrypt(); - parent::__construct($config, $account, $currencies); + + parent::__construct($config, $account, $requestDataMapper); } /** @@ -151,59 +99,34 @@ public function make3DHostPayment(Request $request) /** * Get OOS transaction data - * + * siparis bilgileri ve kart bilgilerinin şifrelendiği adımdır. * @return object * * @throws GuzzleException */ public function getOosTransactionData() { - $requestData = $this->getOosTransactionRequestData($this->account, $this->card, $this->order, $this->type); + $requestData = $this->requestDataMapper->create3DEnrollmentCheckRequestData($this->account, $this->order, $this->type, $this->card); $xml = $this->createXML($requestData); return $this->send($xml); } /** - * @param PosNetAccount $account - * @param AbstractCreditCard $card - * @param $order - * @param string $txType - * - * @return array - */ - public function getOosTransactionRequestData(PosNetAccount $account, AbstractCreditCard $card, $order, string $txType): array - { - if (null === $card->getHolderName() && isset($order->name)) { - $card->setHolderName($order->name); - } - - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'oosRequestData' => [ - 'posnetid' => $account->getPosNetId(), - 'ccno' => $card->getNumber(), - 'expDate' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), - 'cvc' => $card->getCvv(), - 'amount' => $order->amount, - 'currencyCode' => $order->currency, - 'installment' => $order->installment, - 'XID' => self::formatOrderId($order->id), - 'cardHolderName' => $card->getHolderName(), - 'tranType' => $txType, - ], - ]; - } - - /** + * Kullanıcı doğrulama sonucunun sorgulanması ve verilerin doğruluğunun teyit edilmesi için kullanılır. * @inheritDoc */ public function make3DPayment(Request $request) { $bankResponse = null; if ($this->check3DHash($request->request->all())) { - $contents = $this->create3DResolveMerchantDataXML($request->request->all()); + $requestData = $this->requestDataMapper->create3DResolveMerchantRequestData( + $this->account, + $this->order, + $request->request->all() + ); + + $contents = $this->createXML($requestData); $bankResponse = $this->send($contents); } else { goto end; @@ -249,30 +172,13 @@ public function get3DFormData(): array } $data = $this->getOosTransactionData(); - if (!$data->approved) { - throw new \Exception($data->respText, $data->respCode); - } - - $inputs = [ - 'posnetData' => $data->oosRequestDataResponse->data1 ?? '', - 'posnetData2' => $data->oosRequestDataResponse->data2 ?? '', - 'mid' => $this->account->getClientId(), - 'posnetID' => $this->account->getPosNetId(), - 'digest' => $data->oosRequestDataResponse->sign ?? '', - 'vftCode' => $this->account->promotion_code ?? null, - 'merchantReturnURL' => $this->order->success_url, - 'url' => '', - 'lang' => $this->getLang(), - ]; + $data = parent::emptyStringsToNull($data); - if (isset($this->order->koiCode) && $this->order->koiCode > 0) { - $inputs['useJokerVadaa'] = 1; + if ('0' === $data['approved']) { + throw new \Exception($data['respText'], $data['respCode']); } - return [ - 'gateway' => $this->get3DGatewayURL(), - 'inputs' => $inputs, - ]; + return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card, $data['oosRequestDataResponse']); } /** @@ -304,32 +210,6 @@ public function getAccount() return $this->account; } - /** - * Create 3D Hash (MAC) - * - * @param PosNetAccount $account - * @param $order - * - * @return string - */ - public function create3DHash(PosNetAccount $account, $order): string - { - if ($account->getModel() === self::MODEL_3D_SECURE || $account->getModel() === self::MODEL_3D_PAY) { - $secondHashData = [ - self::formatOrderId($order->id), - $order->amount, - $order->currency, - $account->getClientId(), - $this->createSecurityData($account), - ]; - $hashStr = implode(static::HASH_SEPARATOR, $secondHashData); - - return $this->hashString($hashStr); - } - - return ''; - } - /** * verifies the if request came from bank * @@ -346,11 +226,11 @@ public function verifyResponseMAC(PosNetAccount $account, $order, $data): bool if ($account->getModel() === self::MODEL_3D_SECURE || $account->getModel() === self::MODEL_3D_PAY) { $secondHashData = [ $data->mdStatus, - self::formatOrderId($order->id), - $order->amount, - $order->currency, + $this->requestDataMapper::formatOrderId($order->id), + $this->requestDataMapper::amountFormat($order->amount), + $this->requestDataMapper->mapCurrency($order->currency), $account->getClientId(), - $this->createSecurityData($account), + $this->requestDataMapper->createSecurityData($account), ]; $hashStr = implode(static::HASH_SEPARATOR, $secondHashData); } @@ -358,99 +238,12 @@ public function verifyResponseMAC(PosNetAccount $account, $order, $data): bool return $this->hashString($hashStr) === $data->mac; } - /** - * formats order id by adding 0 pad to the left - * - * @param $orderId - * @param int|null $padLength - * - * @return string - */ - public static function formatOrderId($orderId, int $padLength = null): string - { - if (null === $padLength) { - $padLength = self::ORDER_ID_LENGTH; - } - - return str_pad($orderId, $padLength, '0', STR_PAD_LEFT); - } - - /** - * Get amount - * formats 10.01 to 1001 - * - * @param float $amount - * - * @return int - */ - public static function amountFormat($amount): int - { - return round($amount, 2) * 100; - } - - /** - * Get PrefixedOrderId - * To check the status of an order or cancel/refund order Yapikredi - * - requires the order length to be 24 - * - and order id prefix which is "TDSC" for 3D payments - * - * @param string $orderId - * @param string $accountModel - * - * @return string - */ - public static function mapOrderIdToPrefixedOrderId(string $orderId, string $accountModel): string - { - $prefix = self::ORDER_ID_REGULAR_PREFIX; - if (self::MODEL_3D_SECURE === $accountModel) { - $prefix = self::ORDER_ID_3D_PREFIX; - } elseif (self::MODEL_3D_PAY === $accountModel) { - $prefix = self::ORDER_ID_3D_PAY_PREFIX; - } - - return $prefix.self::formatOrderId($orderId, self::ORDER_ID_TOTAL_LENGTH - strlen($prefix)); - } - - - /** - * formats installment in 00, 02, 06 format - * - * @param int|string $installment - * - * @return string - */ - public static function formatInstallment($installment): string - { - if ($installment > 1) { - return str_pad($installment, 2, '0', STR_PAD_LEFT); - } - - return '00'; - } - /** * @inheritDoc */ public function createRegularPaymentXML() { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'tranDateRequired' => '1', - strtolower($this->type) => [ - 'orderID' => self::formatOrderId($this->order->id), - 'installment' => $this->order->installment, - 'amount' => $this->order->amount, - 'currencyCode' => $this->order->currency, - 'ccno' => $this->card->getNumber(), - 'expDate' => $this->card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), - 'cvc' => $this->card->getCvv(), - ], - ]; - - if (isset($this->order->koiCode) && $this->order->koiCode > 0) { - $requestData[strtolower($this->type)]['koiCode'] = $this->order->koiCode; - } + $requestData = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $this->order, $this->type, $this->card); return $this->createXML($requestData); } @@ -460,17 +253,7 @@ public function createRegularPaymentXML() */ public function createRegularPostXML() { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'tranDateRequired' => '1', - strtolower($this->types[self::TX_POST_PAY]) => [ - 'hostLogKey' => $this->order->host_ref_num, - 'amount' => $this->order->amount, - 'currencyCode' => $this->order->currency, - 'installment' => $this->order->installment, - ], - ]; + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -480,38 +263,7 @@ public function createRegularPostXML() */ public function create3DPaymentXML($responseData) { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'oosTranData' => [ - 'bankData' => $responseData['BankPacket'], - 'merchantData' => $responseData['MerchantPacket'], - 'sign' => $responseData['Sign'], - 'wpAmount' => 0, - 'mac' => $this->create3DHash($this->account, $this->order), - ], - ]; - - return $this->createXML($requestData); - } - - /** - * @param $responseData - * - * @return string - */ - public function create3DResolveMerchantDataXML($responseData) - { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'oosResolveMerchantData' => [ - 'bankData' => $responseData['BankPacket'], - 'merchantData' => $responseData['MerchantPacket'], - 'sign' => $responseData['Sign'], - 'mac' => $this->create3DHash($this->account, $this->order), - ], - ]; + $requestData = $this->requestDataMapper->create3DPaymentRequestData($this->account, $this->order, '', $responseData); return $this->createXML($requestData); } @@ -531,13 +283,7 @@ public function createHistoryXML($customQueryData) */ public function createStatusXML() { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - $this->types[self::TX_STATUS] => [ - 'orderID' => $this->order->id, - ], - ]; + $requestData = $this->requestDataMapper->createStatusRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -547,25 +293,7 @@ public function createStatusXML() */ public function createCancelXML() { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'tranDateRequired' => '1', - $this->types[self::TX_CANCEL] => [ - 'transaction' => 'sale', - ], - ]; - - if (isset($this->order->auth_code)) { - $requestData[$this->types[self::TX_CANCEL]]['authCode'] = $this->order->auth_code; - } - - //either will work - if (isset($this->order->host_ref_num)) { - $requestData[$this->types[self::TX_CANCEL]]['hostLogKey'] = $this->order->host_ref_num; - } else { - $requestData[$this->types[self::TX_CANCEL]]['orderID'] = $this->order->id; - } + $requestData = $this->requestDataMapper->createCancelRequestData($this->account, $this->order); return $this->createXML($requestData); } @@ -575,23 +303,46 @@ public function createCancelXML() */ public function createRefundXML() { - $requestData = [ - 'mid' => $this->account->getClientId(), - 'tid' => $this->account->getTerminalId(), - 'tranDateRequired' => '1', - $this->types[self::TX_REFUND] => [ - 'amount' => $this->order->amount, - 'currencyCode' => $this->order->currency, - ], - ]; + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $this->order); - if (isset($this->order->host_ref_num)) { - $requestData[$this->types[self::TX_REFUND]]['hostLogKey'] = $this->order->host_ref_num; - } else { - $requestData[$this->types[self::TX_REFUND]]['orderID'] = $this->order->id; + return $this->createXML($requestData); + } + + /** + * Check 3D Hash + * + * @param array $data + * + * @return bool + */ + public function check3DHash(array $data): bool + { + if (!($this->crypt instanceof PosNetCrypt)) { + return false; } + $decryptedString = $this->crypt->decrypt($data['MerchantPacket'], $this->account->getStoreKey()); + if (!$decryptedString) { + return false; + } + $decryptedData = explode(';', $decryptedString); + + $originalData = array_map('strval', [ + $this->account->getClientId(), + $this->account->getTerminalId(), + $this->requestDataMapper::amountFormat($this->order->amount), + $this->order->installment, + $this->requestDataMapper::formatOrderId($this->order->id), + ]); - return $this->createXML($requestData); + $decryptedDataList = array_map('strval', [ + $decryptedData[0], + $decryptedData[1], + $decryptedData[2], + ((int) $decryptedData[3]), + $decryptedData[4], + ]); + + return $originalData === $decryptedDataList; } /** @@ -616,43 +367,6 @@ protected function getStatusDetail(): ?string return isset($this->codes[$procReturnCode]) ? (string) $this->codes[$procReturnCode] : null; } - - /** - * Check 3D Hash - * - * @param array $data - * - * @return bool - */ - protected function check3DHash(array $data): bool - { - if ($this->crypt instanceof PosNetCrypt) { - $decryptedString = $this->crypt->decrypt($data['MerchantPacket'], $this->account->getStoreKey()); - - $decryptedData = explode(';', $decryptedString); - - $originalData = array_map('strval', [ - $this->account->getClientId(), - $this->account->getTerminalId(), - $this->order->amount, - ((int) $this->order->installment), - self::formatOrderId($this->order->id), - ]); - - $decryptedDataList = array_map('strval', [ - $decryptedData[0], - $decryptedData[1], - $decryptedData[2], - ((int) $decryptedData[3]), - $decryptedData[4], - ]); - - return $originalData === $decryptedDataList; - } - - return false; - } - /** * @inheritDoc */ @@ -681,7 +395,7 @@ protected function map3DPaymentData($raw3DAuthResponseData, $rawPaymentResponseD 'trans_id' => isset($rawPaymentResponseData->authCode) ? $this->printData($rawPaymentResponseData->authCode) : null, 'response' => $this->getStatusDetail(), 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'transaction_security' => $transactionSecurity, 'auth_code' => isset($rawPaymentResponseData->authCode) ? $this->printData($rawPaymentResponseData->authCode) : null, 'host_ref_num' => isset($rawPaymentResponseData->hostlogkey) ? $this->printData($rawPaymentResponseData->hostlogkey) : null, @@ -733,12 +447,12 @@ protected function mapPaymentResponse($responseData): array return [ 'id' => isset($responseData->authCode) ? $this->printData($responseData->authCode) : null, 'order_id' => $this->order->id, - 'fixed_order_id' => self::formatOrderId($this->order->id), + 'fixed_order_id' => $this->requestDataMapper::formatOrderId($this->order->id), 'group_id' => isset($responseData->groupID) ? $this->printData($responseData->groupID) : null, 'trans_id' => isset($responseData->authCode) ? $this->printData($responseData->authCode) : null, 'response' => $this->getStatusDetail(), 'transaction_type' => $this->type, - 'transaction' => $this->type, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), 'auth_code' => isset($responseData->authCode) ? $this->printData($responseData->authCode) : null, 'host_ref_num' => isset($responseData->hostlogkey) ? $this->printData($responseData->hostlogkey) : null, 'ret_ref_num' => isset($responseData->hostlogkey) ? $this->printData($responseData->hostlogkey) : null, @@ -775,13 +489,13 @@ protected function mapRefundResponse($rawResponseData) $state = $rawResponseData->state ?? null; if ('Sale' === $state) { $transaction = 'pay'; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Authorization' === $state) { $transaction = 'pre'; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Capture' === $state) { $transaction = 'post'; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } return (object) [ @@ -852,15 +566,15 @@ protected function mapStatusResponse($rawResponseData) if ('Sale' === $state) { $transaction = 'pay'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Authorization' === $state) { $transaction = 'pre'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Capture' === $state) { $transaction = 'post'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Bonus_Reverse' === $state) { $state = 'cancel'; } else { @@ -870,7 +584,7 @@ protected function mapStatusResponse($rawResponseData) return (object) [ 'id' => $authCode, 'order_id' => isset($this->order->id) ? $this->printData($this->order->id) : null, - 'fixed_order_id' => self::formatOrderId($this->order->id), + 'fixed_order_id' => $this->requestDataMapper::formatOrderId($this->order->id), 'group_id' => isset($rawResponseData->transactions->transaction->groupID) ? $this->printData($rawResponseData->transactions->transaction->groupID) : null, 'trans_id' => $authCode, 'response' => $this->getStatusDetail(), @@ -924,7 +638,7 @@ protected function mapHistoryResponse($rawResponseData) $authCode = $rawResponseData->transactions->transaction[0]->authCode; if (count($rawResponseData->transactions->transaction) > 1) { - $currencies = array_flip($this->currencies); + $currencies = array_flip($this->requestDataMapper->getCurrencyMappings()); foreach ($rawResponseData->transactions->transaction as $key => $_transaction) { if ($key > 0) { @@ -946,15 +660,15 @@ protected function mapHistoryResponse($rawResponseData) if ('Sale' === $state) { $transaction = 'pay'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Authorization' === $state) { $transaction = 'pre'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Capture' === $state) { $transaction = 'post'; $state = $transaction; - $transactionType = $this->types[$transaction]; + $transactionType = $this->requestDataMapper->mapTxType($transaction); } elseif ('Bonus_Reverse' === $state) { $state = 'cancel'; } else { @@ -991,17 +705,11 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = $order['installment']; - } - return (object) array_merge($order, [ - 'id' => self::formatOrderId($order['id']), - 'installment' => self::formatInstallment($installment), - 'amount' => self::amountFormat($order['amount']), - 'currency' => $this->mapCurrency($order['currency']), + 'id' => $order['id'], + 'installment' => $order['installment'] ?? 0, + 'amount' => $order['amount'], + 'currency' => $order['currency'] ?? 'TRY', ]); } @@ -1010,18 +718,12 @@ protected function preparePaymentOrder(array $order) */ protected function preparePostPaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = $order['installment']; - } - return (object) [ - 'id' => self::formatOrderId($order['id']), + 'id' => $order['id'], + 'amount' => $order['amount'], + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', 'host_ref_num' => $order['host_ref_num'], - 'amount' => self::amountFormat($order['amount']), - 'currency' => $this->mapCurrency($order['currency']), - 'installment' => self::formatInstallment($installment), ]; } @@ -1031,7 +733,7 @@ protected function preparePostPaymentOrder(array $order) protected function prepareStatusOrder(array $order) { return (object) [ - 'id' => self::mapOrderIdToPrefixedOrderId($order['id'], $this->account->getModel()), + 'id' => $order['id'], ]; } @@ -1050,7 +752,7 @@ protected function prepareCancelOrder(array $order) { return (object) [ //id or host_ref_num - 'id' => isset($order['id']) ? self::mapOrderIdToPrefixedOrderId($order['id'], $this->account->getModel()) : null, + 'id' => $order['id'] ?? null, 'host_ref_num' => $order['host_ref_num'] ?? null, //optional 'auth_code' => $order['auth_code'] ?? null, @@ -1064,29 +766,10 @@ protected function prepareRefundOrder(array $order) { return (object) [ //id or host_ref_num - 'id' => isset($order['id']) ? self::mapOrderIdToPrefixedOrderId($order['id'], $this->account->getModel()) : null, + 'id' => $order['id'] ?? null, 'host_ref_num' => $order['host_ref_num'] ?? null, - 'amount' => self::amountFormat($order['amount']), - 'currency' => self::mapCurrency($order['currency']), + 'amount' => $order['amount'], + 'currency' => $order['currency'] ?? 'TRY', ]; } - - - /** - * Make Security Data - * - * @param PosNetAccount $account - * - * @return string - */ - private function createSecurityData(PosNetAccount $account): string - { - $hashData = [ - $account->getStoreKey(), - $account->getTerminalId(), - ]; - $hashStr = implode(static::HASH_SEPARATOR, $hashData); - - return$this->hashString($hashStr); - } } diff --git a/src/Gateways/VakifBankPos.php b/src/Gateways/VakifBankPos.php index 0ceb7e89..c872f189 100644 --- a/src/Gateways/VakifBankPos.php +++ b/src/Gateways/VakifBankPos.php @@ -1,11 +1,15 @@ requestDataMapper = new VakifBankPosRequestDataMapper($currencies); - $this->types = $this->requestDataMapper->getTxTypeMappings(); - $this->currencies = $this->requestDataMapper->getCurrencyMappings(); - $this->cardTypeMapping = $this->requestDataMapper->getCardTypeMapping(); - $this->recurringOrderFrequencyMapping = $this->requestDataMapper->getRecurringOrderFrequencyMapping(); - - parent::__construct($config, $account, $currencies); + parent::__construct($config, $account, $requestDataMapper); } /** @@ -141,7 +139,26 @@ public function get3DFormData(): array $data = $this->sendEnrollmentRequest(); $data = parent::emptyStringsToNull($data); - return $this->requestDataMapper->create3DFormDataFromEnrollmentResponse($data); + $status = $data['Message']['VERes']['Status']; + /** + * Status values: + * Y:Kart 3-D Secure programına dâhil + * N:Kart 3-D Secure programına dâhil değil + * U:İşlem gerçekleştirilemiyor + * E:Hata durumu + */ + if ('E' === $status) { + throw new Exception($data['ErrorMessage'], $data['MessageErrorCode']); + } + if ('N' === $status) { + //half secure olarak devam et yada satisi iptal et. + throw new Exception('Kart 3-D Secure programına dâhil değil'); + } + if ('U' === $status) { + throw new Exception('İşlem gerçekleştirilemiyor'); + } + + return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, '', $data['Message']['VERes']); } /** @@ -382,18 +399,9 @@ protected function mapHistoryResponse($rawResponseData) */ protected function preparePaymentOrder(array $order) { - // Installment - $installment = 0; - if (isset($order['installment']) && $order['installment'] > 1) { - $installment = (int) $order['installment']; - } - - $currency = $order['currency'] ?? 'TRY'; - - // Order return (object) array_merge($order, [ - 'installment' => $installment, - 'currency' => $this->mapCurrency($currency), + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', 'amount' => $order['amount'], ]); } @@ -406,7 +414,7 @@ protected function preparePostPaymentOrder(array $order) return (object) [ 'id' => $order['id'], 'amount' => $order['amount'], - 'currency' => $this->mapCurrency($order['currency']), + 'currency' => $order['currency'] ?? 'TRY', 'ip' => $order['ip'], ]; } @@ -466,8 +474,8 @@ private function getCommonPaymentResponse($responseData): array 'auth_code' => null, 'host_ref_num' => null, 'order_id' => null, - 'transaction' => $this->type, - 'transaction_type' => null, + 'transaction' => empty($this->type) ? null : $this->requestDataMapper->mapTxType($this->type), + 'transaction_type' => $this->type, 'response' => null, 'eci' => null, 'proc_return_code' => $resultCode, diff --git a/src/PosInterface.php b/src/PosInterface.php index 6d0971d6..d1e3436e 100644 --- a/src/PosInterface.php +++ b/src/PosInterface.php @@ -1,8 +1,11 @@ config = require __DIR__.'/../../config/pos.php'; + + $this->threeDAccount = AccountFactory::createEstPosAccount( + 'akbank', + '700655000200', + 'ISBANKAPI', + 'ISBANK07', + AbstractGateway::MODEL_3D_SECURE, + 'TRPS0200', + AbstractGateway::LANG_TR + ); + + $this->order = [ + 'id' => 'order222', + 'ip' => '127.0.0.1', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '100.25', + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'rand' => microtime(), + ]; + + $this->pos = PosFactory::createPosGateway($this->threeDAccount); + $this->pos->setTestMode(true); + $this->requestDataMapper = new EstPosRequestDataMapper(); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); + } + + /** + * @return void + */ + public function testMapRecurringFrequency() + { + $this->assertEquals('M', $this->requestDataMapper->mapRecurringFrequency('MONTH')); + $this->assertEquals('M', $this->requestDataMapper->mapRecurringFrequency('M')); + } + + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", ""] + * ["1", ""] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePostAuthPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_POST_PAY); + + $actual = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleNonSecurePaymentPostRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePaymentRequestData() + { + $order = $this->order; + $pos = $this->pos; + $card = $this->card; + $pos->prepare($order, AbstractGateway::TX_PAY, $card); + + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $card); + + $expectedData = $this->getSampleNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DHashFor3DSecure() + { + $this->order['rand'] = 'rand'; + $pos = $this->pos; + + $expected = 'S7UxUAohxaxzl35WxHyDfuQx0sg='; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreate3DHashForNon3DSecure() + { + $this->order['rand'] = 'rand'; + + $account = AccountFactory::createEstPosAccount( + 'akbank', + 'XXXXXXX', + 'XXXXXXX', + 'XXXXXXX', + AbstractGateway::MODEL_3D_PAY, + 'VnM5WZ3sGrPusmWP' + ); + $pos = PosFactory::createPosGateway($account); + $expected = 'zQJGquP0/PXt6LeutjN1Qxq32Zg='; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->create3DHash($account, $pos->getOrder(), AbstractGateway::TX_PAY); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreateCancelRequestData() + { + $order = [ + 'id' => '2020110828BC', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + + $actual = $this->requestDataMapper->createCancelRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleCancelXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateHistoryRequestData() + { + $order = [ + 'order_id' => '2020110828BC', + ]; + $pos = $this->pos; + + $actual = $this->requestDataMapper->createHistoryRequestData($pos->getAccount(), (object) [], $order); + + $expectedData = $this->getSampleHistoryRequestData($pos->getAccount(), $order); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'email' => 'samp@iexample.com', + 'name' => 'john doe', + 'user_id' => '1535', + 'ip' => '192.168.1.0', + 'amount' => 100.01, + 'installment' => '0', + 'currency' => 'TRY', + 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', + ]; + $responseData = [ + 'md' => '1', + 'xid' => '100000005xid', + 'eci' => '100000005eci', + 'cavv' => 'cavv', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $responseData); + + $expectedData = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DPaymentRequestDataRecurringOrder() + { + $order = [ + 'id' => '2020110828BC', + 'email' => 'samp@iexample.com', + 'name' => 'john doe', + 'user_id' => '1535', + 'ip' => '192.168.1.0', + 'amount' => 100.01, + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'recurringFrequency' => 3, + 'recurringFrequencyType' => 'MONTH', + 'recurringInstallmentCount' => 4, + ]; + + $responseData = [ + 'md' => '1', + 'xid' => '100000005xid', + 'eci' => '100000005eci', + 'cavv' => 'cavv', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $responseData); + + $expectedData = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $this->assertEquals($expectedData, $actual); + } + + + /** + * @return void + */ + public function testGet3DFormData() + { + $account = $this->threeDAccount; + $txType = AbstractGateway::TX_PAY; + $this->pos->prepare($this->order, $txType); + $hash = $this->requestDataMapper->create3DHash($account, $this->pos->getOrder(), $txType); + $card = $this->card; + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test']; + + $inputs = [ + 'clientid' => $account->getClientId(), + 'storetype' => $account->getModel(), + 'hash' => $hash, + 'firmaadi' => $this->order['name'], + 'Email' => $this->order['email'], + 'amount' => $this->order['amount'], + 'oid' => $this->order['id'], + 'okUrl' => $this->order['success_url'], + 'failUrl' => $this->order['fail_url'], + 'rnd' => $this->order['rand'], + 'lang' => 'tr', + 'currency' => 949, + 'islemtipi' => 'Auth', + 'taksit' => '', + ]; + $form = [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + //test without card + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $this->pos->getAccount(), + $this->pos->getOrder(), + $txType, + $gatewayURL + )); + + //test with card + if ($card) { + $form['inputs']['cardType'] = '1'; + $form['inputs']['pan'] = $card->getNumber(); + $form['inputs']['Ecom_Payment_Card_ExpDate_Month'] = '01'; + $form['inputs']['Ecom_Payment_Card_ExpDate_Year'] = '22'; + $form['inputs']['cv2'] = $card->getCvv(); + } + + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $this->pos->getAccount(), + $this->pos->getOrder(), + $txType, + $gatewayURL, + $card + )); + } + + /** + * todo + * @return void + */ + public function testGet3DHostFormData() + { + $account = AccountFactory::createEstPosAccount( + 'akbank', + 'XXXXXXX', + 'XXXXXXX', + 'XXXXXXX', + AbstractGateway::MODEL_3D_HOST, + 'VnM5WZ3sGrPusmWP', + AbstractGateway::LANG_TR + ); + + /** @var EstPos $pos */ + $pos = PosFactory::createPosGateway($account); + $pos->setTestMode(true); + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $order = $pos->getOrder(); + $hash = $this->requestDataMapper->create3DHash($account, $order, AbstractGateway::TX_PAY); + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway_3d_host']['test']; + $inputs = [ + 'clientid' => $account->getClientId(), + 'storetype' => $account->getModel(), + 'hash' => $hash, + 'firmaadi' => $this->order['name'], + 'Email' => $this->order['email'], + 'amount' => $this->order['amount'], + 'oid' => $this->order['id'], + 'okUrl' => $this->order['success_url'], + 'failUrl' => $this->order['fail_url'], + 'rnd' => $this->order['rand'], + 'lang' => 'tr', + 'currency' => '949', + 'islemtipi' => 'Auth', + 'taksit' => '', + ]; + $form = [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $pos->getAccount(), + $pos->getOrder(), + AbstractGateway::TX_PAY, + $gatewayURL + )); + } + + /** + * @return void + */ + public function testCreateStatusRequestData() + { + $order = [ + 'id' => '2020110828BC', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_STATUS); + + $actualData = $this->requestDataMapper->createStatusRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleStatusRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actualData); + } + + /** + * todo + * @return void + */ + public function testCreateRefundRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 50, + 'currency' => 'TRY', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_REFUND); + + $actual = $this->requestDataMapper->createRefundRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleRefundXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @param AbstractPosAccount $account + * @param $order + * @param array $responseData + * + * @return array + */ + private function getSample3DPaymentRequestData(AbstractPosAccount $account, $order, array $responseData): array + { + $requestData = [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'Type' => 'Auth', + 'IPAddress' => $order->ip, + 'Email' => $order->email, + 'OrderId' => $order->id, + 'UserId' => isset($order->user_id) ? $order->user_id : null, + 'Total' => 100.01, + 'Currency' => '949', + 'Taksit' => '', + 'Number' => $responseData['md'], + 'PayerTxnId' => $responseData['xid'], + 'PayerSecurityLevel' => $responseData['eci'], + 'PayerAuthenticationCode' => $responseData['cavv'], + 'Mode' => 'P', + ]; + if (isset($order->name)) { + $requestData['BillTo'] = [ + 'Name' => $order->name, + ]; + } + + if (isset($order->recurringFrequency)) { + $requestData['PbOrder'] = [ + 'OrderType' => 0, + 'OrderFrequencyInterval' => $order->recurringFrequency, + 'OrderFrequencyCycle' => 'M', + 'TotalNumberPayments' => $order->recurringInstallmentCount, + ]; + } + + return $requestData; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleCancelXMLData(AbstractPosAccount $account, $order): array + { + return [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'OrderId' => $order->id, + 'Type' => 'Void', + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * @param AbstractCreditCard $card + * + * @return array + */ + private function getSampleNonSecurePaymentRequestData(AbstractPosAccount $account, $order, AbstractCreditCard $card): array + { + return [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'Type' => 'Auth', + 'IPAddress' => $order->ip, + 'Email' => $order->email, + 'OrderId' => $order->id, + 'UserId' => $order->user_id ?? null, + 'Total' => '100.25', + 'Currency' => '949', + 'Taksit' => '', + 'Number' => $card->getNumber(), + 'Expires' => '01/22', + 'Cvv2Val' => $card->getCvv(), + 'Mode' => 'P', + 'BillTo' => [ + 'Name' => $order->name ?: null, + ], + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleNonSecurePaymentPostRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'Type' => 'PostAuth', + 'OrderId' => $order->id, + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleStatusRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'OrderId' => $order->id, + 'Extra' => [ + 'ORDERSTATUS' => 'QUERY', + ], + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleRefundXMLData(AbstractPosAccount $account, $order): array + { + $data = [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'OrderId' => $order->id, + 'Currency' => 949, + 'Type' => 'Credit', + ]; + + if ($order->amount) { + $data['Total'] = $order->amount; + } + + return $data; + } + + /** + * @param AbstractPosAccount $account + * @param $customQueryData + * + * @return array + */ + private function getSampleHistoryRequestData(AbstractPosAccount $account, $customQueryData): array + { + $requestData = [ + 'Name' => $account->getUsername(), + 'Password' => $account->getPassword(), + 'ClientId' => $account->getClientId(), + 'OrderId' => $customQueryData['order_id'], + 'Extra' => [ + 'ORDERHISTORY' => 'QUERY', + ], + ]; + + return $requestData; + } +} diff --git a/tests/DataMapper/GarantiPosRequestDataMapperTest.php b/tests/DataMapper/GarantiPosRequestDataMapperTest.php new file mode 100644 index 00000000..5cfdfef6 --- /dev/null +++ b/tests/DataMapper/GarantiPosRequestDataMapperTest.php @@ -0,0 +1,644 @@ +config = require __DIR__.'/../../config/pos.php'; + + $this->threeDAccount = AccountFactory::createGarantiPosAccount( + 'garanti', + '7000679', + 'PROVAUT', + '123qweASD/', + '30691298', + AbstractGateway::MODEL_3D_SECURE, + '12345678', + 'PROVRFN', + '123qweASD/' + ); + + $this->order = [ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '100.25', + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'lang' => 'tr', + 'ip' => '156.155.154.153', + ]; + + $this->pos = PosFactory::createPosGateway($this->threeDAccount); + $this->pos->setTestMode(true); + $this->requestDataMapper = new GarantiPosRequestDataMapper(); + $this->requestDataMapper->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); + } + + /** + * @return void + */ + public function testAmountFormat() + { + $this->assertEquals(100000, $this->requestDataMapper::amountFormat(1000)); + $this->assertEquals(100000, $this->requestDataMapper::amountFormat(1000.00)); + $this->assertEquals(100001, $this->requestDataMapper::amountFormat(1000.01)); + } + + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", ""] + * ["1", ""] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePostAuthPaymentRequestData() + { + $this->order['ref_ret_num'] = '831803579226'; + $order = $this->order; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_POST_PAY); + + $actual = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleNonSecurePaymentPostRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePaymentRequestData() + { + $order = $this->order; + $pos = $this->pos; + $card = $this->card; + $pos->prepare($order, AbstractGateway::TX_PAY, $card); + + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $card); + + $expectedData = $this->getSampleNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DHash() + { + $expected = '1D319D5EA945F5730FF5BCC970FF96690993F4BD'; + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateHash() + { + $expected = '00CD5B6C29D4CEA1F3002D785A9F9B09974AD51D'; + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->createHash($pos->getAccount(), $pos->getOrder(), 'sales'); + $this->assertEquals($expected, $actual); + + $pos->prepare($this->order, AbstractGateway::TX_PRE_PAY); + $actual = $this->requestDataMapper->createHash($pos->getAccount(), $pos->getOrder(), 'preauth'); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreateHashForCancelAndRefund() + { + $order = [ + 'id' => '4499996', + 'ref_ret_num' => '446ss', + 'amount' => '1.00', + 'currency' => 'TRY', + ]; + $expected = '9788649A0C3AE14C082783CEA6775E08A7EFB311'; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + $actual = $this->requestDataMapper->createHash($pos->getAccount(), $pos->getOrder(), 'void'); + $this->assertEquals($expected, $actual); + + $pos->prepare($order, AbstractGateway::TX_REFUND); + $actual = $this->requestDataMapper->createHash($pos->getAccount(), $pos->getOrder(), 'refund'); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreateCancelRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'currency' => 'TRY', + 'amount' => '1.00', + 'ref_ret_num' => '831803579226', + ]; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + + $actual = $this->requestDataMapper->createCancelRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleCancelXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateHistoryRequestData() + { + $order = $this->order; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_HISTORY); + $actual = $this->requestDataMapper->createHistoryRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleHistoryRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DPaymentRequestData() + { + $pos = $this->pos; + $order = $this->order; + $responseData = $this->getSample3DResponseData(); + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), '', $responseData); + + $expectedData = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testGet3DFormData() + { + $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $pos = $this->pos; + $account = $pos->getAccount(); + $order = $pos->getOrder(); + $card = $pos->getCard(); + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test']; + $inputs = [ + 'secure3dsecuritylevel' => '3D', + 'mode' => 'TEST', + 'apiversion' => 'v0.01', + 'terminalprovuserid' => $account->getUsername(), + 'terminaluserid' => $account->getUsername(), + 'terminalmerchantid' => $account->getClientId(), + 'terminalid' => $account->getTerminalId(), + 'txntype' => 'sales', + 'txnamount' => 10025, + 'txncurrencycode' => '949', + 'txninstallmentcount' => '', + 'orderid' => $this->order['id'], + 'successurl' => $this->order['success_url'], + 'errorurl' => $this->order['fail_url'], + 'customeremailaddress' => $order->email, + 'customeripaddress' => $this->order['ip'], + 'secure3dhash' => '1D319D5EA945F5730FF5BCC970FF96690993F4BD', + 'cardnumber' => $card->getNumber(), + 'cardexpiredatemonth' => '01', + 'cardexpiredateyear' => '22', + 'cardcvv2' => $card->getCvv(), + ]; + + $form = [ + 'inputs' => $inputs, + 'gateway' => $gatewayURL, + ]; + + //test without card + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $this->pos->getAccount(), + $this->pos->getOrder(), + AbstractGateway::TX_PAY, + $gatewayURL, + $this->card + )); + } + + /** + * @return void + */ + public function testCreateStatusRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'currency' => 'TRY', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_STATUS); + + $actualData = $this->requestDataMapper->createStatusRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleStatusRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actualData); + } + + /** + * @return void + */ + public function testCreateRefundRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'currency' => 'TRY', + 'ref_ret_num' => '831803579226', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_REFUND); + + $actual = $this->requestDataMapper->createRefundRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleRefundXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @param GarantiPosAccount $account + * @param $order + * @param array $responseData + * + * @return array + */ + private function getSample3DPaymentRequestData(AbstractPosAccount $account, $order, array $responseData): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getUsername(), + 'UserID' => $account->getUsername(), + 'HashData' => '00CD5B6C29D4CEA1F3002D785A9F9B09974AD51D', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $responseData['customeripaddress'], + 'EmailAddress' => $responseData['customeremailaddress'], + ], + 'Order' => [ + 'OrderID' => $responseData['orderid'], + 'AddressList' => [ + 'Address' => [ + 'Type' => 'B', + 'Name' => $order->name, + 'LastName' => '', + 'Company' => '', + 'Text' => '', + 'District' => '', + 'City' => '', + 'PostalCode' => '', + 'Country' => '', + 'PhoneNumber' => '', + ], + ], + ], + 'Transaction' => [ + 'Type' => $responseData['txntype'], + 'InstallmentCnt' => '', + 'Amount' => $responseData['txnamount'], + 'CurrencyCode' => $responseData['txncurrencycode'], + 'CardholderPresentCode' => '13', + 'MotoInd' => 'N', + 'Secure3D' => [ + 'AuthenticationCode' => $responseData['cavv'], + 'SecurityLevel' => $responseData['eci'], + 'TxnID' => $responseData['xid'], + 'Md' => $responseData['md'], + ], + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleCancelXMLData(AbstractPosAccount $account, $order): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getRefundUsername(), + 'UserID' => $account->getRefundUsername(), + 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => 'void', + 'InstallmentCnt' => '', + 'Amount' => 100, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * @param $order + * @param AbstractCreditCard $card + * + * @return array + */ + private function getSampleNonSecurePaymentRequestData(AbstractPosAccount $account, $order, AbstractCreditCard $card): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getUsername(), + 'UserID' => $account->getUsername(), + 'HashData' => '3732634F78053D42304B0966E263629FE44E258B', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Card' => [ + 'Number' => $card->getNumber(), + 'ExpireDate' => '0122', + 'CVV2' => $card->getCvv(), + ], + 'Order' => [ + 'OrderID' => $order->id, + 'AddressList' => [ + 'Address' => [ + 'Type' => 'B', + 'Name' => $order->name, + 'LastName' => '', + 'Company' => '', + 'Text' => '', + 'District' => '', + 'City' => '', + 'PostalCode' => '', + 'Country' => '', + 'PhoneNumber' => '', + ], + ], + ], + 'Transaction' => [ + 'Type' => 'sales', + 'InstallmentCnt' => '', + 'Amount' => 10025, + 'CurrencyCode' => 949, + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleNonSecurePaymentPostRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getUsername(), + 'UserID' => $account->getUsername(), + 'HashData' => '00CD5B6C29D4CEA1F3002D785A9F9B09974AD51D', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => 'postauth', + 'Amount' => 10025, + 'CurrencyCode' => '949', + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleStatusRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getUsername(), + 'UserID' => $account->getUsername(), + 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => 'orderinq', + 'InstallmentCnt' => '', + 'Amount' => 100, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + ], + ]; + } + + /** + * @param GarantiPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleRefundXMLData(AbstractPosAccount $account, $order): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getRefundUsername(), + 'UserID' => $account->getRefundUsername(), + 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => 'refund', + 'InstallmentCnt' => '', + 'Amount' => 100, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + 'OriginalRetrefNum' => $order->ref_ret_num, + ], + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleHistoryRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'Mode' => 'TEST', + 'Version' => 'v0.01', + 'Terminal' => [ + 'ProvUserID' => $account->getUsername(), + 'UserID' => $account->getUsername(), + 'HashData' => '19460C02029180F8F7E19A4835D62E4118600A34', + 'ID' => $account->getTerminalId(), + 'MerchantID' => $account->getClientId(), + ], + 'Customer' => [ + 'IPAddress' => $order->ip, + 'EmailAddress' => $order->email, + ], + 'Order' => [ + 'OrderID' => $order->id, + ], + 'Transaction' => [ + 'Type' => 'orderhistoryinq', + 'InstallmentCnt' => '', + 'Amount' => 100, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + ], + ]; + } + + /** + * @return string[] + */ + private function getSample3DResponseData(): array + { + return [ + 'orderid' => '2020110828BC', + 'md' => '1', + 'xid' => '100000005xid', + 'eci' => '100000005eci', + 'cavv' => 'cavv', + 'txncurrencycode' => 'txncurrencycode', + 'txnamount' => 'txnamount', + 'txntype' => 'txntype', + 'customeripaddress' => 'customeripaddress', + 'customeremailaddress' => 'customeremailaddress', + ]; + } +} diff --git a/tests/DataMapper/InterPosRequestDataMapperTest.php b/tests/DataMapper/InterPosRequestDataMapperTest.php index 5fa67396..ef4a2f4c 100644 --- a/tests/DataMapper/InterPosRequestDataMapperTest.php +++ b/tests/DataMapper/InterPosRequestDataMapperTest.php @@ -1,5 +1,7 @@ order = [ @@ -61,7 +63,7 @@ protected function setUp(): void 'currency' => 'TRY', 'success_url' => 'https://domain.com/success', 'fail_url' => 'https://domain.com/fail_url', - 'lang' => InterPos::LANG_TR, + 'lang' => AbstractGateway::LANG_TR, 'rand' => microtime(true), ]; @@ -73,6 +75,32 @@ protected function setUp(): void $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); } + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", ""] + * ["1", ""] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + /** * @return void */ @@ -103,7 +131,7 @@ public function testCreateNonSecurePaymentRequestData() $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); $pos->prepare($order, AbstractGateway::TX_PAY, $card); - $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), 'Auth', $card); + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $card); $expectedData = $this->getSampleNonSecurePaymentRequestData($pos->getOrder(), $pos->getCard(), $pos->getAccount()); $this->assertEquals($expectedData, $actual); @@ -118,7 +146,7 @@ public function testCreate3DHash() $pos = $this->pos; $expected = 'vEbwP8wnsGrBR9oCjfxP9wlho1g='; $pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), 'Auth'); + $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY); $this->assertEquals($expected, $actual); } @@ -129,7 +157,7 @@ public function testCreateCancelRequestData() { $order = [ 'id' => '2020110828BC', - 'lang' => InterPos::LANG_EN, + 'lang' => AbstractGateway::LANG_EN, ]; $pos = $this->pos; $pos->prepare($order, AbstractGateway::TX_CANCEL); @@ -148,11 +176,11 @@ public function testCreate3DPaymentRequestData() $order = [ 'id' => '2020110828BC', 'amount' => 100.01, - 'installment' => '', + 'installment' => 0, 'currency' => 'TRY', 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'lang' => InterPos::LANG_EN, + 'lang' => AbstractGateway::LANG_EN, ]; $responseData = [ 'MD' => '1', @@ -164,7 +192,7 @@ public function testCreate3DPaymentRequestData() $pos = $this->pos; $pos->prepare($order, AbstractGateway::TX_PAY); - $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), 'Auth', $responseData); + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $responseData); $expectedData = $this->getSample3DPaymentRequestData($pos->getOrder(), $pos->getAccount(), $responseData); $this->assertEquals($expectedData, $actual); @@ -178,7 +206,7 @@ public function testGet3DFormData() $order = (object) $this->order; $account = $this->account; $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - $hash = $this->requestDataMapper->create3DHash($account, $this->pos->getOrder(), 'Auth'); + $hash = $this->requestDataMapper->create3DHash($account, $this->pos->getOrder(), AbstractGateway::TX_PAY); $card = $this->card; $gatewayURL = $this->config['banks'][$this->account->getBank()]['urls']['gateway']['test']; @@ -204,7 +232,7 @@ public function testGet3DFormData() $this->assertEquals($form, $this->requestDataMapper->create3DFormData( $this->pos->getAccount(), $this->pos->getOrder(), - 'Auth', + AbstractGateway::TX_PAY, $gatewayURL )); @@ -219,7 +247,7 @@ public function testGet3DFormData() $this->assertEquals($form, $this->requestDataMapper->create3DFormData( $this->pos->getAccount(), $this->pos->getOrder(), - 'Auth', + AbstractGateway::TX_PAY, $gatewayURL, $card )); @@ -237,14 +265,14 @@ public function testGet3DHostFormData() 'XXXXXXX', AbstractGateway::MODEL_3D_HOST, 'VnM5WZ3sGrPusmWP', - InterPos::LANG_TR + AbstractGateway::LANG_TR ); /** @var InterPos $pos */ $pos = PosFactory::createPosGateway($account); $pos->setTestMode(true); $pos->prepare($this->order, AbstractGateway::TX_PAY); $order = $pos->getOrder(); - $hash = $this->requestDataMapper->create3DHash($account, $pos->getOrder(), 'Auth'); + $hash = $this->requestDataMapper->create3DHash($account, $pos->getOrder(), AbstractGateway::TX_PAY); $gatewayURL = $this->config['banks'][$account->getBank()]['urls']['gateway_3d_host']['test']; $inputs = [ 'ShopCode' => $account->getClientId(), @@ -268,7 +296,7 @@ public function testGet3DHostFormData() $this->assertEquals($form, $this->requestDataMapper->create3DFormData( $pos->getAccount(), $pos->getOrder(), - 'Auth', + AbstractGateway::TX_PAY, $gatewayURL )); } @@ -280,7 +308,7 @@ public function testCreateStatusRequestData() { $order = [ 'id' => '2020110828BC', - 'lang' => InterPos::LANG_EN, + 'lang' => AbstractGateway::LANG_EN, ]; $pos = $this->pos; @@ -323,13 +351,13 @@ private function getSample3DPaymentRequestData($order, InterPosAccount $account, return [ 'UserCode' => $account->getUsername(), 'UserPass' => $account->getPassword(), - 'ClientId' => $account->getClientId(), + 'ShopCode' => $account->getClientId(), 'TxnType' => 'Auth', 'SecureType' => 'NonSecure', 'OrderId' => $order->id, 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, + 'Currency' => '949', + 'InstallmentCount' => '', 'MD' => $responseData['MD'], 'PayerTxnId' => $responseData['PayerTxnId'], 'Eci' => $responseData['Eci'], @@ -376,8 +404,8 @@ private function getSampleNonSecurePaymentRequestData($order, AbstractCreditCard 'SecureType' => 'NonSecure', 'OrderId' => $order->id, 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, + 'Currency' => '949', + 'InstallmentCount' => '', 'MOTO' => '0', 'Lang' => $order->lang, ]; @@ -407,7 +435,7 @@ private function getSampleNonSecurePaymentPostRequestData($order, InterPosAccoun 'OrderId' => null, 'orgOrderId' => $order->id, 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, + 'Currency' => '949', 'MOTO' => '0', ]; } diff --git a/tests/DataMapper/KuveytPosRequestDataMapperTest.php b/tests/DataMapper/KuveytPosRequestDataMapperTest.php index 549471e4..c597181a 100644 --- a/tests/DataMapper/KuveytPosRequestDataMapperTest.php +++ b/tests/DataMapper/KuveytPosRequestDataMapperTest.php @@ -1,5 +1,7 @@ '0.43625700 1604831630', 'hash' => 'zmSUxYPhmCj7QOzqpk/28LuE1Oc=', 'ip' => '127.0.0.1', - 'lang' => KuveytPos::LANG_TR, + 'lang' => AbstractGateway::LANG_TR, ]; $this->pos = PosFactory::createPosGateway($this->threeDAccount); @@ -76,6 +78,32 @@ protected function setUp(): void $this->requestDataMapper = new KuveytPosRequestDataMapper(); } + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('0949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('0978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", 0] + * ["1", 0] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + /** * @return void */ @@ -87,17 +115,17 @@ public function testCompose3DFormData() $card = $this->pos->getCard(); $inputs = [ - 'APIVersion' => KuveytPos::API_VERSION, + 'APIVersion' => KuveytPosRequestDataMapper::API_VERSION, 'MerchantId' => $account->getClientId(), 'UserName' => $account->getUsername(), 'CustomerId' => $account->getCustomerId(), - 'HashData' => $this->requestDataMapper->create3DHash($account, $order, 'Auth'), + 'HashData' => $this->requestDataMapper->create3DHash($account, $order, AbstractGateway::TX_PAY), 'TransactionType' => 'Sale', 'TransactionSecurity' => 3, 'InstallmentCount' => $order->installment, 'Amount' => KuveytPosRequestDataMapper::amountFormat($order->amount), 'DisplayAmount' => KuveytPosRequestDataMapper::amountFormat($order->amount), - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => '0949', 'MerchantOrderId' => $order->id, 'OkUrl' => $order->success_url, 'FailUrl' => $order->fail_url, @@ -111,8 +139,8 @@ public function testCompose3DFormData() $inputs['CardExpireDateMonth'] = '01'; $inputs['CardCVV2'] = $card->getCvv(); } - $txType = 'Sale'; - $result = $this->requestDataMapper->create3DEnrollmentCheckRequestData($account, $order, $txType, $card); + + $result = $this->requestDataMapper->create3DEnrollmentCheckRequestData($account, $order, AbstractGateway::TX_PAY, $card); $this->assertEquals($inputs, $result); } @@ -121,11 +149,10 @@ public function testCompose3DFormData() */ public function testCreate3DPaymentXML() { - $txType = 'Sale'; $responseData = [ 'MD' => '67YtBfBRTZ0XBKnAHi8c/A==', 'VPosMessage' => [ - 'TransactionType' => $txType, + 'TransactionType' => 'Sale', 'InstallmentCount' => '0', 'Amount' => '100', 'DisplayAmount' => '100', @@ -135,9 +162,9 @@ public function testCreate3DPaymentXML() ], ]; $this->pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $this->requestDataMapper->create3DPaymentRequestData($this->pos->getAccount(), $this->pos->getOrder(), $txType, $responseData); + $actual = $this->requestDataMapper->create3DPaymentRequestData($this->pos->getAccount(), $this->pos->getOrder(), AbstractGateway::TX_PAY, $responseData); - $expectedData = $this->getSample3DPaymentXMLData($this->pos, $txType, $responseData); + $expectedData = $this->getSample3DPaymentXMLData($this->pos, AbstractGateway::TX_PAY, $responseData); $this->assertEquals($expectedData, $actual); } @@ -194,7 +221,7 @@ private function getSample3DPaymentXMLData(KuveytPos $pos, string $txType, $resp $hash = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), $txType, true); return [ - 'APIVersion' => KuveytPos::API_VERSION, + 'APIVersion' => KuveytPosRequestDataMapper::API_VERSION, 'HashData' => $hash, 'MerchantId' => $account->getClientId(), 'CustomerId' => $account->getCustomerId(), diff --git a/tests/DataMapper/PayForPosRequestDataMapperTest.php b/tests/DataMapper/PayForPosRequestDataMapperTest.php new file mode 100644 index 00000000..dd379084 --- /dev/null +++ b/tests/DataMapper/PayForPosRequestDataMapperTest.php @@ -0,0 +1,512 @@ +config = require __DIR__.'/../../config/pos.php'; + + $this->threeDAccount = AccountFactory::createPayForAccount( + 'qnbfinansbank-payfor', + '085300000009704', + 'QNB_API_KULLANICI_3DPAY', + 'UcBN0', + AbstractGateway::MODEL_3D_SECURE, + '12345678' + ); + + $this->order = [ + 'id' => '2020110828BC', + 'email' => 'mail@customer.com', // optional + 'name' => 'John Doe', // optional + 'amount' => 100.01, + 'installment' => '0', + 'currency' => 'TRY', + 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'rand' => '0.43625700 1604831630', + 'lang' => AbstractGateway::LANG_TR, + ]; + + $this->pos = PosFactory::createPosGateway($this->threeDAccount); + $this->pos->setTestMode(true); + $this->requestDataMapper = new PayForPosRequestDataMapper(); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); + } + + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", 0] + * ["1", 0] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePostAuthPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 100.01, + 'installment' => '0', + 'currency' => 'TRY', + 'lang' => AbstractGateway::LANG_TR, + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_POST_PAY); + + $actual = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleNonSecurePaymentPostRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePaymentRequestData() + { + $order = $this->order; + $pos = $this->pos; + $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet'); + $pos->prepare($order, AbstractGateway::TX_PAY, $card); + + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $card); + + $expectedData = $this->getSampleNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DHash() + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 100.01, + 'installment' => '0', + 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', + 'rand' => '0.43625700 1604831630', + ]; + $expected = 'zmSUxYPhmCj7QOzqpk/28LuE1Oc='; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateCancelRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'currency' => 'TRY', + ]; + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + + $actual = $this->requestDataMapper->createCancelRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleCancelXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateHistoryRequestData() + { + $order = [ + 'orderId' => '2020110828BC', + 'reqDate' => '20220518', + ]; + $pos = $this->pos; + + $actual = $this->requestDataMapper->createHistoryRequestData($pos->getAccount(), (object) [], $order); + + $expectedData = $this->getSampleHistoryRequestData($pos->getAccount(), $order); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + ]; + $responseData = ['RequestGuid' => '1000000057437884']; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), '', $responseData); + + $expectedData = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testGet3DFormData() + { + $order = (object) $this->order; + $account = $this->threeDAccount; + $this->pos->prepare($this->order, AbstractGateway::TX_PAY); + $hash = $this->requestDataMapper->create3DHash($account, $this->pos->getOrder(), AbstractGateway::TX_PAY); + $card = $this->card; + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test']; + + $inputs = [ + 'MbrId' => '5', + 'MerchantID' => $this->threeDAccount->getClientId(), + 'UserCode' => $this->threeDAccount->getUsername(), + 'OrderId' => $order->id, + 'Lang' => $order->lang, + 'SecureType' => '3DModel', + 'TxnType' => 'Auth', + 'PurchAmount' => $order->amount, + 'InstallmentCount' => 0, + 'Currency' => 949, + 'OkUrl' => $order->success_url, + 'FailUrl' => $order->fail_url, + 'Rnd' => $order->rand, + 'Hash' => $hash, + ]; + $form = [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + //test without card + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $this->pos->getAccount(), + $this->pos->getOrder(), + AbstractGateway::TX_PAY, + $gatewayURL + )); + + //test with card + if ($card) { + $form['inputs']['CardHolderName'] = $card->getHolderName(); + $form['inputs']['Pan'] = $card->getNumber(); + $form['inputs']['Expiry'] = '0122'; + $form['inputs']['Cvv2'] = $card->getCvv(); + } + + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $this->pos->getAccount(), + $this->pos->getOrder(), + AbstractGateway::TX_PAY, + $gatewayURL, + $card + )); + } + + /** + * @return void + */ + public function testGet3DHostFormData() + { + $account = AccountFactory::createPayForAccount( + 'qnbfinansbank-payfor', + '085300000009704', + 'QNB_API_KULLANICI_3DPAY', + 'UcBN0', + AbstractGateway::MODEL_3D_HOST, + '12345678' + ); + /** @var PayForPos $pos */ + $pos = PosFactory::createPosGateway($account); + $pos->setTestMode(true); + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $order = $pos->getOrder(); + $hash = $this->requestDataMapper->create3DHash($account, $order, AbstractGateway::TX_PAY); + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway_3d_host']['test']; + $inputs = [ + 'MbrId' => '5', + 'MerchantID' => $this->threeDAccount->getClientId(), + 'UserCode' => $this->threeDAccount->getUsername(), + 'OrderId' => $order->id, + 'Lang' => 'tr', + 'SecureType' => '3DHost', + 'TxnType' => 'Auth', + 'PurchAmount' => $order->amount, + 'InstallmentCount' => 0, + 'Currency' => 949, + 'OkUrl' => $order->success_url, + 'FailUrl' => $order->fail_url, + 'Rnd' => $order->rand, + 'Hash' => $hash, + ]; + $form = [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + + $this->assertEquals($form, $this->requestDataMapper->create3DFormData( + $pos->getAccount(), + $pos->getOrder(), + AbstractGateway::TX_PAY, + $gatewayURL + )); + } + + /** + * @return void + */ + public function testCreateStatusRequestData() + { + $order = [ + 'id' => '2020110828BC', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_STATUS); + + $actualData = $this->requestDataMapper->createStatusRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleStatusRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actualData); + } + + /** + * @return void + */ + public function testCreateRefundRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'currency' => 'TRY', + 'amount' => 10.1, + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_REFUND); + + $actual = $this->requestDataMapper->createRefundRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleRefundXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @param AbstractPosAccount $account + * @param $order + * @param array $responseData + * + * @return array + */ + private function getSample3DPaymentRequestData(AbstractPosAccount $account, $order, array $responseData): array + { + return [ + 'RequestGuid' => $responseData['RequestGuid'], + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrderId' => $order->id, + 'SecureType' => '3DModelPayment', + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleCancelXMLData(AbstractPosAccount $account, $order): array + { + return [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrgOrderId' => $order->id, + 'SecureType' => 'NonSecure', + 'Lang' => 'tr', + 'TxnType' => 'Void', + 'Currency' => 949, + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * @param AbstractCreditCard $card + * + * @return array + */ + private function getSampleNonSecurePaymentRequestData(AbstractPosAccount $account, $order, AbstractCreditCard $card): array + { + return [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'MOTO' => '0', + 'OrderId' => $order->id, + 'SecureType' => 'NonSecure', + 'TxnType' => 'Auth', + 'PurchAmount' => $order->amount, + 'Currency' => 949, + 'InstallmentCount' => 0, + 'Lang' => 'tr', + 'CardHolderName' => $card->getHolderName(), + 'Pan' => $card->getNumber(), + 'Expiry' => '0122', + 'Cvv2' => $card->getCvv(), + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleNonSecurePaymentPostRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrgOrderId' => $order->id, + 'SecureType' => 'NonSecure', + 'TxnType' => 'PostAuth', + 'PurchAmount' => $order->amount, + 'Currency' => 949, + 'Lang' => 'tr', + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleStatusRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrgOrderId' => $order->id, + 'SecureType' => 'Inquiry', + 'Lang' => 'tr', + 'TxnType' => 'OrderInquiry', + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $order + * + * @return array + */ + private function getSampleRefundXMLData(AbstractPosAccount $account, $order): array + { + return [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'OrgOrderId' => $order->id, + 'SecureType' => 'NonSecure', + 'Lang' => 'tr', + 'TxnType' => 'Refund', + 'PurchAmount' => $order->amount, + 'Currency' => 949, + ]; + } + + /** + * @param AbstractPosAccount $account + * @param $customQueryData + * + * @return array + */ + private function getSampleHistoryRequestData(AbstractPosAccount $account, $customQueryData): array + { + $requestData = [ + 'MbrId' => '5', + 'MerchantId' => $account->getClientId(), + 'UserCode' => $account->getUsername(), + 'UserPass' => $account->getPassword(), + 'SecureType' => 'Report', + 'TxnType' => 'TxnHistory', + 'Lang' => 'tr', + ]; + + if (isset($customQueryData['orderId'])) { + $requestData['OrderId'] = $customQueryData['orderId']; + } elseif (isset($customQueryData['reqDate'])) { + //ReqData YYYYMMDD format + $requestData['ReqDate'] = $customQueryData['reqDate']; + } + + return $requestData; + } +} diff --git a/tests/DataMapper/PosNetRequestDataMapperTest.php b/tests/DataMapper/PosNetRequestDataMapperTest.php new file mode 100644 index 00000000..8c0809db --- /dev/null +++ b/tests/DataMapper/PosNetRequestDataMapperTest.php @@ -0,0 +1,568 @@ +config = require __DIR__.'/../../config/pos.php'; + + $this->threeDAccount = AccountFactory::createPosNetAccount( + 'yapikredi', + '6706598320', + 'XXXXXX', + 'XXXXXX', + '67005551', + '27426', + AbstractGateway::MODEL_3D_SECURE, + '10,10,10,10,10,10,10,10' + ); + + $this->order = [ + 'id' => 'YKB_TST_190620093100_024', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => '1.75', + 'installment' => 0, + 'currency' => 'TL', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'rand' => '0.43625700 1604831630', + 'lang' => AbstractGateway::LANG_TR, + ]; + + $this->pos = PosFactory::createPosGateway($this->threeDAccount); + $this->pos->setTestMode(true); + $this->requestDataMapper = new PosNetRequestDataMapper(); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); + } + + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('TL', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('EU', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @return void + */ + public function testAmountFormat() + { + $this->assertSame(100000, PosNetRequestDataMapper::amountFormat(1000)); + $this->assertSame(100000, PosNetRequestDataMapper::amountFormat(1000.00)); + $this->assertSame(100001, PosNetRequestDataMapper::amountFormat(1000.01)); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", "00"] + * ["1", "00"] + * ["2", "02"] + * ["2", "02"] + * ["12", "12"] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testMapOrderIdToPrefixedOrderId() + { + $this->assertSame('TDSC00000000000000000010', PosNetRequestDataMapper::mapOrderIdToPrefixedOrderId(10, AbstractGateway::MODEL_3D_SECURE)); + $this->assertSame('000000000000000000000010', PosNetRequestDataMapper::mapOrderIdToPrefixedOrderId(10, AbstractGateway::MODEL_3D_PAY)); + $this->assertSame('000000000000000000000010', PosNetRequestDataMapper::mapOrderIdToPrefixedOrderId(10, AbstractGateway::MODEL_NON_SECURE)); + } + + /** + * @return void + */ + public function testCreateSecurityData() + { + $this->assertSame('c1PPl+2UcdixyhgLYnf4VfJyFGaNQNOwE0uMkci7Uag=', $this->requestDataMapper->createSecurityData($this->threeDAccount)); + } + + /** + * @return void + */ + public function testFormatOrderIdd() + { + $this->assertSame('0010', PosNetRequestDataMapper::formatOrderId(10, 4)); + $this->assertSame('12345', PosNetRequestDataMapper::formatOrderId(12345, 4)); + } + + /** + * @return void + */ + public function testCreateNonSecurePostAuthPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'host_ref_num' => '019676067890000191', + 'amount' => 10.02, + 'currency' => 'TRY', + 'installment' => '2', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_POST_PAY); + + $actual = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleNonSecurePaymentPostRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreateNonSecurePaymentRequestData() + { + $order = $this->order; + $pos = $this->pos; + $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet'); + $pos->prepare($order, AbstractGateway::TX_PAY, $card); + + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), AbstractGateway::TX_PAY, $card); + + $expectedData = $this->getSampleNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DHash() + { + $expected = 'J/7/Xprj7F/KDf98luVfIGyUPRQzUCqGwpmvz3KT7oQ='; + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + $actual = $this->requestDataMapper->create3DHash($pos->getAccount(), $pos->getOrder(), ''); + $this->assertSame($expected, $actual); + } + + /** + * @return void + */ + public function testCreateCancelRequestData() + { + $pos = $this->pos; + $order = [ + 'id' => '2020110828BC', + ]; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + $actual = $this->requestDataMapper->createCancelRequestData($pos->getAccount(), $pos->getOrder()); + $expectedData = $this->getSampleCancelXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + + $order = [ + 'host_ref_num' => '2020110828BCNUM', + ]; + $pos->prepare($order, AbstractGateway::TX_CANCEL); + $actual = $this->requestDataMapper->createCancelRequestData($pos->getAccount(), $pos->getOrder()); + $expectedData = $this->getSampleCancelXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DPaymentRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 100.01, + 'installment' => '0', + 'currency' => 'TRY', + ]; + $responseData = [ + 'BankPacket' => 'F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', + 'MerchantPacket' => 'E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', + 'Sign' => '9998F61E1D0C0FB6EC5203A748124F30', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actual = $this->requestDataMapper->create3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), '', $responseData); + + $expectedData = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $this->assertEquals($expectedData, $actual); + } + + /** + * @return void + */ + public function testCreate3DEnrollmentCheckRequestData() + { + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $expected = $this->getSample3DEnrollmentCheckRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); + $actual = $this->requestDataMapper->create3DEnrollmentCheckRequestData($pos->getAccount(), $pos->getOrder(), 'Sale', $pos->getCard()); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreate3DResolveMerchantRequestData() + { + $pos = $this->pos; + $order = [ + 'id' => '2020110828BC', + 'amount' => 100.01, + 'installment' => '0', + 'currency' => 'TRY', + ]; + $responseData = [ + 'BankPacket' => 'F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', + 'MerchantPacket' => 'E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', + 'Sign' => '9998F61E1D0C0FB6EC5203A748124F30', + ]; + + $pos->prepare($order, AbstractGateway::TX_PAY); + + $actualData = $this->requestDataMapper->create3DResolveMerchantRequestData($pos->getAccount(), $pos->getOrder(), $responseData); + $expectedData = $this->getSampleResolveMerchantDataXMLData($pos->getAccount(), $responseData); + $this->assertEquals($expectedData, $actualData); + } + + /** + * @return void + * + * @throws Exception + */ + public function testCreate3DFormData() + { + $gatewayURL = 'https://setmpos.ykb.com/3DSWebService/YKBPaymentService'; + $ooTxSuccessData = $this->getSample3DEnrollmentCheckResponseData(); + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY); + + $expected = $this->requestDataMapper->create3DFormData( + $pos->getAccount(), + $pos->getOrder(), + '', + $gatewayURL, + null, + $ooTxSuccessData['oosRequestDataResponse'] + ); + $actual = $this->getSample3DFormData($pos->getAccount(), $pos->getOrder(), $ooTxSuccessData['oosRequestDataResponse'], $gatewayURL); + $this->assertEquals($expected, $actual); + } + + /** + * @return void + */ + public function testCreateStatusRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'type' => 'status', + ]; + + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_STATUS); + + $actualData = $this->requestDataMapper->createStatusRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleStatusRequestData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actualData); + } + + /** + * @return void + */ + public function testCreateRefundRequestData() + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 50, + 'currency' => 'TRY', + ]; + + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_REFUND); + + $actual = $this->requestDataMapper->createRefundRequestData($pos->getAccount(), $pos->getOrder()); + + $expectedData = $this->getSampleRefundXMLData($pos->getAccount(), $pos->getOrder()); + $this->assertEquals($expectedData, $actual); + } + + /** + * @param PosNetAccount $account + * @param $order + * @param $oosTxResponseData + * @param string $gatewayURL + * + * @return array + */ + private function getSample3DFormData(AbstractPosAccount $account, $order, $oosTxResponseData, string $gatewayURL): array + { + $inputs = [ + 'posnetData' => $oosTxResponseData['data1'], + 'posnetData2' => $oosTxResponseData['data2'], + 'mid' => $account->getClientId(), + 'posnetID' => $account->getPosNetId(), + 'digest' => $oosTxResponseData['sign'], + 'vftCode' => $account->promotion_code ?? null, + 'merchantReturnURL' => $order->success_url, + 'url' => '', + 'lang' => 'tr', + ]; + + return [ + 'gateway' => $gatewayURL, + 'inputs' => $inputs, + ]; + } + + /** + * @return array + */ + private function getSample3DEnrollmentCheckResponseData(): array + { + return [ + 'approved' => '1', //1:Başarılı + 'respCode' => '', + 'respText' => '', + 'oosRequestDataResponse' => [ + 'data1' => 'AEFE78BFC852867FF57078B723E284D1BD52EED8264C6CBD110A1A9EA5EAA7533D1A82EFD614032D686C507738FDCDD2EDD00B22DEFEFE0795DC4674C16C02EBBFEC9DF0F495D5E23BE487A798BF8293C7C1D517D9600C96CBFD8816C9D8F8257442906CB9B10D8F1AABFBBD24AA6FB0E5533CDE67B0D9EA5ED621B91BF6991D5362182302B781241B56E47BAE1E86BC3D5AE7606212126A4E97AFC2', + 'data2' => '69D04861340091B7014B15158CA3C83413031B406F08B3792A0114C9958E6F0F216966C5EE32EAEEC7158BFF59DFCB77E20CD625', + 'sign' => '9998F61E1D0C0FB6EC5203A748124F30', + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * @param array $responseData + * + * @return array + */ + private function getSample3DPaymentRequestData(AbstractPosAccount $account, $order, array $responseData): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosTranData' => [ + 'bankData' => $responseData['BankPacket'], + 'merchantData' => $responseData['MerchantPacket'], + 'sign' => $responseData['Sign'], + 'wpAmount' => 0, + 'mac' => $this->requestDataMapper->create3DHash($account, $order, ''), + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * + * @return array + */ + private function getSampleCancelXMLData(AbstractPosAccount $account, $order): array + { + $requestData = [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + 'reverse' => [ + 'transaction' => 'sale', + ], + ]; + + //either will work + if (isset($order->host_ref_num)) { + $requestData['reverse']['hostLogKey'] = $order->host_ref_num; + } else { + $requestData['reverse']['orderID'] = 'TDSC000000002020110828BC'; + } + + return $requestData; + } + + /** + * @param PosNetAccount $account + * @param $order + * @param AbstractCreditCard $card + * + * @return array + */ + private function getSampleNonSecurePaymentRequestData(AbstractPosAccount $account, $order, AbstractCreditCard $card): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + 'sale' => [ + 'orderID' => $order->id, + 'installment' => $order->installment, + 'amount' => 175, + 'currencyCode' => 'TL', + 'ccno' => $card->getNumber(), + 'expDate' => '2201', + 'cvc' => $card->getCvv(), + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * + * @return array + */ + private function getSampleNonSecurePaymentPostRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + 'capt' => [ + 'hostLogKey' => $order->host_ref_num, + 'amount' => 1002, + 'currencyCode' => 'TL', + 'installment' => '02', + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * + * @return array + */ + private function getSampleStatusRequestData(AbstractPosAccount $account, $order): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'agreement' => [ + 'orderID' => 'TDSC000000002020110828BC', + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param $order + * + * @return array + */ + private function getSampleRefundXMLData(AbstractPosAccount $account, $order): array + { + $requestData = [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'tranDateRequired' => '1', + 'return' => [ + 'amount' => 5000, + 'currencyCode' => 'TL', + ], + ]; + + if (isset($order->host_ref_num)) { + $requestData['return']['hostLogKey'] = $order->host_ref_num; + } else { + $requestData['return']['orderID'] = 'TDSC000000002020110828BC'; + } + + return $requestData; + } + + /** + * @param PosNetAccount $account + * @param $order + * @param AbstractCreditCard $card + * + * @return array + */ + private function getSample3DEnrollmentCheckRequestData(PosNetAccount $account, $order, AbstractCreditCard $card): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosRequestData' => [ + 'posnetid' => $account->getPosNetId(), + 'ccno' => $card->getNumber(), + 'expDate' => '2201', + 'cvc' => $this->card->getCvv(), + 'amount' => 175, + 'currencyCode' => 'TL', + 'installment' => $order->installment, + 'XID' => $this->requestDataMapper::formatOrderId($order->id), + 'cardHolderName' => $card->getHolderName(), + 'tranType' => 'Sale', + ], + ]; + } + + /** + * @param PosNetAccount $account + * @param array $responseData + * + * @return array + */ + private function getSampleResolveMerchantDataXMLData(AbstractPosAccount $account, array $responseData): array + { + return [ + 'mid' => $account->getClientId(), + 'tid' => $account->getTerminalId(), + 'oosResolveMerchantData' => [ + 'bankData' => $responseData['BankPacket'], + 'merchantData' => $responseData['MerchantPacket'], + 'sign' => $responseData['Sign'], + 'mac' => 'oE7zwV87uOc2DFpGPlr4jQRQ0z9LsxGw56c7vaiZkTo=', + ], + ]; + } +} diff --git a/tests/DataMapper/VakifBankPosRequestDataMapperTest.php b/tests/DataMapper/VakifBankPosRequestDataMapperTest.php index 61dab807..88dfd896 100644 --- a/tests/DataMapper/VakifBankPosRequestDataMapperTest.php +++ b/tests/DataMapper/VakifBankPosRequestDataMapperTest.php @@ -82,6 +82,32 @@ public function testMapRecurringFrequency() $this->assertEquals('Month', $this->requestDataMapper->mapRecurringFrequency('Month')); } + /** + * @return void + */ + public function testMapCurrency() + { + $this->assertEquals('949', $this->requestDataMapper->mapCurrency('TRY')); + $this->assertEquals('978', $this->requestDataMapper->mapCurrency('EUR')); + } + + /** + * @param string|int|null $installment + * @param string|int $expected + * + * @testWith ["0", 0] + * ["1", 0] + * ["2", 2] + * [2, 2] + * + * @return void + */ + public function testMapInstallment($installment, $expected) + { + $actual = $this->requestDataMapper->mapInstallment($installment); + $this->assertSame($expected, $actual); + } + /** * @return void */ @@ -91,7 +117,7 @@ public function testCreate3DPaymentRequestData() $order['amount'] = 10.1; $pos = $this->pos; $pos->prepare($order, AbstractGateway::TX_PAY, $this->card); - $txType = 'Sale'; + $txType = AbstractGateway::TX_PAY; $gatewayResponse = [ 'Eci' => (string) rand(1, 100), 'Cavv' => (string) rand(1, 100), @@ -144,9 +170,9 @@ public function testCreateNonSecurePaymentRequestData() { $pos = $this->pos; $order = $this->order; - $txType = 'Sale'; + $txType = AbstractGateway::TX_PAY; $order['amount'] = 1000; - $pos->prepare($order, AbstractGateway::TX_PAY, $this->card); + $pos->prepare($order, $txType, $this->card); $expectedValue = $this->getSampleNonSecurePaymentRequestData($pos->getAccount(), $order, $txType, $pos->getCard()); $actualData = $this->requestDataMapper->createNonSecurePaymentRequestData($pos->getAccount(), $pos->getOrder(), $txType, $pos->getCard()); @@ -206,10 +232,19 @@ public function testCreateRefundRequestData() /** * @return void */ - public function testCreate3DFormDataFromEnrollmentResponse() + public function testCreate3DFormData() { + $pos = $this->pos; + $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $expectedValue = $this->getSample3DFormDataFromEnrollmentResponse(); - $actualData = $this->requestDataMapper->create3DFormDataFromEnrollmentResponse($this->getSampleEnrollmentSuccessResponseData()); + $actualData = $this->requestDataMapper->create3DFormData( + $pos->getAccount(), + $pos->getOrder(), + '', + '', + $pos->getCard(), + $this->getSampleEnrollmentSuccessResponseData()['Message']['VERes'] + ); $this->assertEquals($expectedValue, $actualData); } @@ -246,10 +281,10 @@ private function getSample3DPaymentRequestData(AbstractPosAccount $account, $ord 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), 'TerminalNo' => $account->getTerminalId(), - 'TransactionType' => $txType, + 'TransactionType' => $this->requestDataMapper->mapTxType($txType), 'OrderId' => $order->id, 'ClientIp' => $order->ip, - 'CurrencyCode' => $order->currency, + 'CurrencyCode' => '949', 'CurrencyAmount' => $order->amount, 'OrderDescription' => '', 'TransactionId' => $order->id, @@ -263,7 +298,7 @@ private function getSample3DPaymentRequestData(AbstractPosAccount $account, $ord 'TransactionDeviceSource' => 0, ]; if ($order->installment) { - $expectedValue['NumberOfInstallments'] = $order->installment; + $expectedValue['NumberOfInstallments'] = $this->requestDataMapper->mapInstallment($order->installment); } return $expectedValue; @@ -285,7 +320,7 @@ private function getSample3DEnrollmentRequestData(AbstractPosAccount $account, $ 'MerchantType' => $account->getMerchantType(), 'PurchaseAmount' => $order->amount, 'VerifyEnrollmentRequestId' => $order->rand, - 'Currency' => $order->currency, + 'Currency' => '949', 'SuccessUrl' => $order->success_url, 'FailureUrl' => $order->fail_url, 'SessionInfo' => $order->extraData, @@ -296,7 +331,7 @@ private function getSample3DEnrollmentRequestData(AbstractPosAccount $account, $ ]; if ($order->installment) { - $expectedValue['InstallmentCount'] = $order->installment; + $expectedValue['InstallmentCount'] = $this->requestDataMapper->mapInstallment($order->installment); } if (isset($order->recurringFrequency)) { @@ -326,7 +361,7 @@ private function getSampleNonSecurePaymentRequestData(AbstractPosAccount $accoun 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), 'TerminalNo' => $account->getTerminalId(), - 'TransactionType' => $txType, + 'TransactionType' => $this->requestDataMapper->mapTxType($txType), 'OrderId' => $order['id'], 'CurrencyAmount' => '1000.00', 'CurrencyCode' => 949, diff --git a/tests/Factory/CreditCardFactoryTest.php b/tests/Factory/CreditCardFactoryTest.php index 0294753f..d94c4562 100644 --- a/tests/Factory/CreditCardFactoryTest.php +++ b/tests/Factory/CreditCardFactoryTest.php @@ -1,5 +1,7 @@ expectException(CardTypeNotSupportedException::class); - $pos = $this->getMockBuilder(EstPos::class)->disableOriginalConstructor() - //just any method - ->onlyMethods(['send']) - ->getMock(); + $pos = $this->getMockBuilder(EstPos::class)->disableOriginalConstructor()->getMock(); + $pos->expects($this->once())->method('getCardTypeMapping')->willReturn(['visa' => 'visa']); CreditCardFactory::create( $pos, @@ -94,10 +93,9 @@ public function testCreateUnSupportedCardTypeException() public function testCreateCardTypeRequiredException() { $this->expectException(CardTypeRequiredException::class); - $pos = $this->getMockBuilder(EstPos::class)->disableOriginalConstructor() - //just any method - ->onlyMethods(['send']) - ->getMock(); + $pos = $this->getMockBuilder(EstPos::class)->disableOriginalConstructor()->getMock(); + + $pos->expects($this->once())->method('getCardTypeMapping')->willReturn(['visa' => 'visa']); CreditCardFactory::create( $pos, diff --git a/tests/Gateways/EstPostTest.php b/tests/Gateways/EstPostTest.php index 68484642..4552207b 100644 --- a/tests/Gateways/EstPostTest.php +++ b/tests/Gateways/EstPostTest.php @@ -1,5 +1,7 @@ order = [ @@ -72,8 +63,6 @@ protected function setUp(): void $this->pos->setTestMode(true); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); - - $this->xmlDecoder = new XmlEncoder(); } /** @@ -95,106 +84,6 @@ public function testPrepare() $this->assertEquals($this->card, $this->pos->getCard()); } - /** - * @return void - */ - public function testMapRecurringFrequency() - { - $this->assertEquals('M', $this->pos->mapRecurringFrequency('MONTH')); - $this->assertEquals('M', $this->pos->mapRecurringFrequency('M')); - } - - public function testGet3DFormWithCardData() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - - $form = [ - 'gateway' => $this->config['banks'][$this->account->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'clientid' => $this->account->getClientId(), - 'storetype' => $this->account->getModel(), - 'hash' => $this->pos->create3DHash($this->pos->getAccount(), $this->pos->getOrder(), 'Auth'), - 'cardType' => '1', - 'pan' => $this->card->getNumber(), - 'Ecom_Payment_Card_ExpDate_Month' => '12', - 'Ecom_Payment_Card_ExpDate_Year' => '21', - 'cv2' => $this->card->getCvv(), - 'firmaadi' => $this->order['name'], - 'Email' => $this->order['email'], - 'amount' => $this->order['amount'], - 'oid' => $this->order['id'], - 'okUrl' => $this->order['success_url'], - 'failUrl' => $this->order['fail_url'], - 'rnd' => $this->order['rand'], - 'lang' => $this->order['lang'], - 'currency' => 949, - ], - ]; - $this->assertEquals($form, $this->pos->get3DFormData()); - } - - public function testGet3DFormWithoutCardData() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY); - - $form = [ - 'gateway' => $this->config['banks'][$this->account->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'clientid' => $this->account->getClientId(), - 'storetype' => $this->account->getModel(), - 'hash' => $this->pos->create3DHash($this->pos->getAccount(), $this->pos->getOrder(), 'Auth'), - 'firmaadi' => $this->order['name'], - 'Email' => $this->order['email'], - 'amount' => $this->order['amount'], - 'oid' => $this->order['id'], - 'okUrl' => $this->order['success_url'], - 'failUrl' => $this->order['fail_url'], - 'rnd' => $this->order['rand'], - 'lang' => $this->order['lang'], - 'currency' => 949, - ], - ]; - $this->assertEquals($form, $this->pos->get3DFormData()); - } - - public function testGet3DHostFormData() - { - $account = AccountFactory::createEstPosAccount( - 'akbank', - 'XXXXXXX', - 'XXXXXXX', - 'XXXXXXX', - AbstractGateway::MODEL_3D_HOST, - 'VnM5WZ3sGrPusmWP', - EstPos::LANG_TR - ); - $pos = PosFactory::createPosGateway($account); - $pos->setTestMode(true); - - $pos->prepare($this->order, AbstractGateway::TX_PAY); - - $form = [ - 'gateway' => $this->config['banks'][$account->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'clientid' => $account->getClientId(), - 'storetype' => $account->getModel(), - 'hash' => $pos->create3DHash($pos->getAccount(), $pos->getOrder(), 'Auth'), - 'firmaadi' => $this->order['name'], - 'Email' => $this->order['email'], - 'amount' => $this->order['amount'], - 'oid' => $this->order['id'], - 'okUrl' => $this->order['success_url'], - 'failUrl' => $this->order['fail_url'], - 'rnd' => $this->order['rand'], - 'lang' => $this->order['lang'], - 'currency' => 949, - 'islemtipi' => 'Auth', - 'taksit' => $this->order['installment'], - ], - ]; - $this->assertEquals($form, $pos->get3DFormData()); - } - /** * @return void */ @@ -207,233 +96,6 @@ public function testCheck3DHash() $this->assertFalse($this->pos->check3DHash($data)); } - public function testCreateRegularPaymentXML() - { - $order = [ - 'id' => '2020110828BC', - 'email' => 'samp@iexample.com', - 'name' => 'john doe', - 'user_id' => '1535', - 'ip' => '192.168.1.0', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); - - $pos->prepare($order, AbstractGateway::TX_PAY, $card); - - $actualXML = $pos->createRegularPaymentXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPaymentXMLData($pos->getOrder(), $pos->getCard(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRegularPostXML() - { - $order = [ - 'id' => '2020110828BC', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_POST_PAY); - - $actualXML = $pos->createRegularPostXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPostXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreate3DPaymentXML() - { - - $order = [ - 'id' => '2020110828BC', - 'email' => 'samp@iexample.com', - 'name' => 'john doe', - 'user_id' => '1535', - 'ip' => '192.168.1.0', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', - ]; - $responseData = [ - 'md' => '1', - 'xid' => '100000005xid', - 'eci' => '100000005eci', - 'cavv' => 'cavv', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_PAY); - - $actualXML = $pos->create3DPaymentXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSample3DPaymentXMLData($pos->getOrder(), $pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreate3DPaymentXMLForRecurringOrder() - { - - $order = [ - 'id' => '2020110828BC', - 'email' => 'samp@iexample.com', - 'name' => 'john doe', - 'user_id' => '1535', - 'ip' => '192.168.1.0', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'recurringFrequency' => 3, - 'recurringFrequencyType' => 'MONTH', - 'recurringInstallmentCount' => 4, - ]; - - $responseData = [ - 'md' => '1', - 'xid' => '100000005xid', - 'eci' => '100000005eci', - 'cavv' => 'cavv', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_PAY); - - $actualXML = $pos->create3DPaymentXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSample3DPaymentXMLData($pos->getOrder(), $pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - $this->assertEquals($expectedData['PbOrder'], $actualData['PbOrder']); - } - - public function testCreateStatusXML() - { - $order = [ - 'id' => '2020110828BC', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_STATUS); - - $actualXML = $pos->createStatusXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleStatusXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - - public function testCreateCancelXML() - { - $order = [ - 'id' => '2020110828BC', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_CANCEL); - - $actualXML = $pos->createCancelXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleCancelXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRefundXML() - { - $order = [ - 'id' => '2020110828BC', - 'amount' => 50, - 'currency' => 'TRY', - ]; - - /** - * @var EstPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_REFUND); - - $actualXML = $pos->createRefundXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRefundXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - /** - * @return void - */ - public function testCreate3DHashFor3DSecure() - { - $this->order['rand'] = 'rand'; - - $account = AccountFactory::createEstPosAccount( - 'akbank', - 'XXXXXXX', - 'XXXXXXX', - 'XXXXXXX', - AbstractGateway::MODEL_3D_SECURE, - 'VnM5WZ3sGrPusmWP' - ); - $pos = PosFactory::createPosGateway($account); - - $expected = '3Wb9YCz1uz3OCFHEI0u2Djga294='; - $pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $pos->create3DHash($account, $pos->getOrder(), 'Auth'); - $this->assertEquals($expected, $actual); - } - - /** - * @return void - */ - public function testCreate3DHashForNon3DSecure() - { - $this->order['rand'] = 'rand'; - - $account = AccountFactory::createEstPosAccount( - 'akbank', - 'XXXXXXX', - 'XXXXXXX', - 'XXXXXXX', - AbstractGateway::MODEL_3D_PAY, - 'VnM5WZ3sGrPusmWP' - ); - $pos = PosFactory::createPosGateway($account); - $expected = 'zW2HEQR/H0mpo1jrztIgmIPFFEU='; - $pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $pos->create3DHash($account, $pos->getOrder(), 'Auth'); - $this->assertEquals($expected, $actual); - } - /** * @return void */ @@ -442,7 +104,7 @@ public function testMake3DPaymentAuthFail() $request = Request::create('', 'POST', $this->get3DMakePaymentFailResponseData()); $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send']) ->getMock(); @@ -463,7 +125,8 @@ public function testMake3DPaymentAuthFail() $this->assertSame('30', $result['year']); $this->assertSame('1.01', $result['amount']); $this->assertSame('TRY', $result['currency']); - $this->assertSame('Auth', $result['transaction_type']); + $this->assertSame('Auth', $result['transaction']); + $this->assertSame(AbstractGateway::TX_PAY, $result['transaction_type']); $this->assertSame(null, $result['auth_code']); $this->assertSame(null, $result['host_ref_num']); $this->assertSame(null, $result['status_detail']); @@ -479,7 +142,7 @@ public function testMake3DPaymentAuthSuccessAndPaymentFail() $request = Request::create('', 'POST', $this->get3DMakePaymentAuthSuccessResponseData()); $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'check3DHash', 'create3DPaymentXML', 'getProcReturnCode']) ->getMock(); @@ -504,7 +167,8 @@ public function testMake3DPaymentAuthSuccessAndPaymentFail() $this->assertSame('30', $result['year']); $this->assertSame('1.01', $result['amount']); $this->assertSame('TRY', $result['currency']); - $this->assertSame('Auth', $result['transaction_type']); + $this->assertSame('Auth', $result['transaction']); + $this->assertSame(AbstractGateway::TX_PAY, $result['transaction_type']); $this->assertSame(null, $result['auth_code']); $this->assertSame(null, $result['host_ref_num']); $this->assertSame('general_error', $result['status_detail']); @@ -520,7 +184,7 @@ public function testMake3DPaymentAuthSuccessAndPaymentSuccess() $request = Request::create('', 'POST', $this->get3DMakePaymentAuthSuccessResponseData()); $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'check3DHash', 'create3DPaymentXML', 'getProcReturnCode']) ->getMock(); @@ -545,7 +209,8 @@ public function testMake3DPaymentAuthSuccessAndPaymentSuccess() $this->assertSame('30', $result['year']); $this->assertSame('1.01', $result['amount']); $this->assertSame('TRY', $result['currency']); - $this->assertSame('Auth', $result['transaction_type']); + $this->assertSame('Auth', $result['transaction']); + $this->assertSame(AbstractGateway::TX_PAY, $result['transaction_type']); $this->assertSame('P65781', $result['auth_code']); $this->assertSame('210700616852', $result['host_ref_num']); $this->assertSame('approved', $result['status_detail']); @@ -577,7 +242,8 @@ public function testMake3DHostPaymentSuccess() $this->assertSame('30', $result['year']); $this->assertSame('1.01', $result['amount']); $this->assertSame('TRY', $result['currency']); - $this->assertSame('Auth', $result['transaction_type']); + $this->assertSame('Auth', $result['transaction']); + $this->assertSame(AbstractGateway::TX_PAY, $result['transaction_type']); $this->assertSame(null, $result['auth_code']); $this->assertSame(null, $result['host_ref_num']); $this->assertSame(null, $result['status_detail']); @@ -609,7 +275,8 @@ public function testMake3DHostPaymentFail() $this->assertSame('30', $result['year']); $this->assertSame('1.01', $result['amount']); $this->assertSame('TRY', $result['currency']); - $this->assertSame('Auth', $result['transaction_type']); + $this->assertSame('Auth', $result['transaction']); + $this->assertSame(AbstractGateway::TX_PAY, $result['transaction_type']); $this->assertSame(null, $result['auth_code']); $this->assertSame(null, $result['host_ref_num']); $this->assertSame(null, $result['status_detail']); @@ -623,7 +290,7 @@ public function testMake3DHostPaymentFail() public function testStatusSuccess() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createStatusXML', 'getProcReturnCode']) ->getMock(); @@ -656,7 +323,7 @@ public function testStatusSuccess() public function testStatusFail() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createStatusXML', 'getProcReturnCode']) ->getMock(); @@ -689,7 +356,7 @@ public function testStatusFail() public function testHistorySuccess() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createHistoryXML', 'getProcReturnCode']) ->getMock(); @@ -720,7 +387,7 @@ public function testHistorySuccess() public function testHistoryFail() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createHistoryXML', 'getProcReturnCode']) ->getMock(); @@ -751,7 +418,7 @@ public function testHistoryFail() public function testCancelSuccess() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createCancelXML', 'getProcReturnCode']) ->getMock(); @@ -785,7 +452,7 @@ public function testCancelSuccess() public function testCancelFail() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createCancelXML', 'getProcReturnCode']) ->getMock(); @@ -819,7 +486,7 @@ public function testCancelFail() public function testRefundFail() { $posMock = $this->getMockBuilder(EstPos::class) - ->setConstructorArgs([[], $this->account, []]) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(EstPos::class)]) ->onlyMethods(['send', 'createRefundXML', 'getProcReturnCode']) ->getMock(); @@ -1308,166 +975,4 @@ private function get3DHostPaymentFailResponseData(): array 'HASHPARAMSVAL' => '700655000200202204175A830435508:524D8E0D689F6F5E1DD0C737ED160B6073038B4FBBC73E6D7C69341793A2DC0E:3379:##700655000200g+XYZKbjrxFj5EgZNZFj', ]; } - - - /** - * @param $order - * @param AbstractCreditCard $card - * @param EstPosAccount $account - * - * @return array - */ - private function getSampleRegularPaymentXMLData($order, AbstractCreditCard $card, EstPosAccount $account) - { - return [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'Type' => 'Auth', - 'IPAddress' => $order->ip, - 'Email' => $order->email, - 'OrderId' => $order->id, - 'UserId' => isset($order->user_id) ? $order->user_id : null, - 'Total' => $order->amount, - 'Currency' => $order->currency, - 'Taksit' => $order->installment, - 'CardType' => AbstractCreditCard::CARD_TYPE_VISA, - 'Number' => $card->getNumber(), - 'Expires' => '01/22', - 'Cvv2Val' => $card->getCvv(), - 'Mode' => 'P', - 'GroupId' => '', - 'TransId' => '', - 'BillTo' => [ - 'Name' => $order->name ?: null, - ], - ]; - } - - /** - * @param $order - * @param EstPosAccount $account - * - * @return array - */ - private function getSampleRegularPostXMLData($order, EstPosAccount $account) - { - return [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'Type' => 'PostAuth', - 'OrderId' => $order->id, - ]; - } - - /** - * @param $order - * @param EstPosAccount $account - * @param array $responseData - * - * @return array - */ - private function getSample3DPaymentXMLData($order, EstPosAccount $account, array $responseData) - { - $requestData = [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'Type' => 'Auth', - 'IPAddress' => $order->ip, - 'Email' => $order->email, - 'OrderId' => $order->id, - 'UserId' => isset($order->user_id) ? $order->user_id : null, - 'Total' => $order->amount, - 'Currency' => $order->currency, - 'Taksit' => $order->installment, - 'Number' => $responseData['md'], - 'Expires' => '', - 'Cvv2Val' => '', - 'PayerTxnId' => $responseData['xid'], - 'PayerSecurityLevel' => $responseData['eci'], - 'PayerAuthenticationCode' => $responseData['cavv'], - 'CardholderPresentCode' => '13', - 'Mode' => 'P', - 'GroupId' => '', - 'TransId' => '', - ]; - if (isset($order->name)) { - $requestData['BillTo'] = [ - 'Name' => $order->name, - ]; - } - - if (isset($order->recurringFrequency)) { - $requestData['PbOrder'] = [ - 'OrderType' => 0, - 'OrderFrequencyInterval' => $order->recurringFrequency, - 'OrderFrequencyCycle' => $order->recurringFrequencyType, - 'TotalNumberPayments' => $order->recurringInstallmentCount, - ]; - } - - return $requestData; - } - - /** - * @param $order - * @param EstPosAccount $account - * - * @return array - */ - private function getSampleStatusXMLData($order, EstPosAccount $account) - { - return [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'OrderId' => $order->id, - 'Extra' => [ - 'ORDERSTATUS' => 'QUERY', - ], - ]; - } - - /** - * @param $order - * @param EstPosAccount $account - * - * @return array - */ - private function getSampleCancelXMLData($order, EstPosAccount $account) - { - return [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'OrderId' => $order->id, - 'Type' => 'Void', - ]; - } - - /** - * @param $order - * @param EstPosAccount $account - * - * @return array - */ - private function getSampleRefundXMLData($order, EstPosAccount $account) - { - $data = [ - 'Name' => $account->getUsername(), - 'Password' => $account->getPassword(), - 'ClientId' => $account->getClientId(), - 'OrderId' => $order->id, - 'Currency' => 949, - 'Type' => 'Credit', - ]; - - if ($order->amount) { - $data['Total'] = $order->amount; - } - - return $data; - } } diff --git a/tests/Gateways/GarantiPosTest.php b/tests/Gateways/GarantiPosTest.php index 9e884dfc..47821256 100644 --- a/tests/Gateways/GarantiPosTest.php +++ b/tests/Gateways/GarantiPosTest.php @@ -1,5 +1,7 @@ pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122'); - - $this->xmlDecoder = new XmlEncoder(); } + /** + * @return void + */ public function testInit() { $this->assertEquals($this->config['banks'][$this->account->getBank()], $this->pos->getConfig()); @@ -82,312 +78,74 @@ public function testInit() $this->assertNotEmpty($this->pos->getCurrencies()); } + /** + * @return void + */ public function testPrepare() { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $this->assertEquals($this->card, $this->pos->getCard()); - } - - public function testAmountFormat() - { - $this->assertEquals(100000, GarantiPos::amountFormat(1000)); - $this->assertEquals(100000, GarantiPos::amountFormat(1000.00)); - $this->assertEquals(100001, GarantiPos::amountFormat(1000.01)); - } - - public function testGet3DFormWithCardData() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - - $form = [ - 'gateway' => $this->config['banks'][$this->account->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'secure3dsecuritylevel' => $this->account->getModel() === AbstractGateway::MODEL_3D_PAY ? '3D_PAY' : '3D', - 'mode' => 'TEST', - 'apiversion' => GarantiPos::API_VERSION, - 'terminalprovuserid' => $this->account->getUsername(), - 'terminaluserid' => $this->account->getUsername(), - 'terminalmerchantid' => $this->account->getClientId(), - 'txntype' => 'sales', - 'txnamount' => GarantiPos::amountFormat($this->order['amount']), - 'txncurrencycode' => $this->pos->mapCurrency($this->order['currency']), - 'txninstallmentcount' => empty($this->order['installment']) ? '' : $this->order['installment'], - 'orderid' => $this->order['id'], - 'terminalid' => $this->account->getTerminalId(), - 'successurl' => $this->order['success_url'], - 'errorurl' => $this->order['fail_url'], - 'customeremailaddress' => isset($this->order['email']) ? $this->order['email'] : null, - 'customeripaddress' => $this->order['ip'], - 'secure3dhash' => '1D319D5EA945F5730FF5BCC970FF96690993F4BD', - 'cardnumber' => $this->card->getNumber(), - 'cardexpiredatemonth' => '12', - 'cardexpiredateyear' => '21', - 'cardcvv2' => $this->card->getCvv(), - ], - ]; - - $actualForm = $this->pos->get3DFormData(); - $this->assertNotEmpty($actualForm['inputs']); - - $this->assertEquals($form, $actualForm); - } - - - public function testGet3DFormWithoutCardData() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY); - - $form = [ - 'gateway' => $this->config['banks'][$this->account->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'secure3dsecuritylevel' => $this->account->getModel() === AbstractGateway::MODEL_3D_PAY ? '3D_PAY' : '3D', - 'mode' => 'TEST', - 'apiversion' => GarantiPos::API_VERSION, - 'terminalprovuserid' => $this->account->getUsername(), - 'terminaluserid' => $this->account->getUsername(), - 'terminalmerchantid' => $this->account->getClientId(), - 'txntype' => 'sales', - 'txnamount' => GarantiPos::amountFormat($this->order['amount']), - 'txncurrencycode' => $this->pos->mapCurrency($this->order['currency']), - 'txninstallmentcount' => empty($this->order['installment']) ? '' : $this->order['installment'], - 'orderid' => $this->order['id'], - 'terminalid' => $this->account->getTerminalId(), - 'successurl' => $this->order['success_url'], - 'errorurl' => $this->order['fail_url'], - 'customeremailaddress' => isset($this->order['email']) ? $this->order['email'] : null, - 'customeripaddress' => $this->order['ip'], - 'secure3dhash' => '1D319D5EA945F5730FF5BCC970FF96690993F4BD', - ], - ]; - - $actualForm = $this->pos->get3DFormData(); - $this->assertNotEmpty($actualForm['inputs']); - - $this->assertEquals($form, $actualForm); - } - - public function testCreateRegularPaymentXML() - { - $order = [ - 'id' => '2020110828BC', - 'email' => 'samp@iexample.com', - 'name' => 'john doe', - 'user_id' => '1535', - 'ip' => '192.168.1.0', - 'amount' => 100.01, - 'installment' => 0, - 'currency' => 'TRY', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet'); - $pos->prepare($order, AbstractGateway::TX_PAY, $card); - - $actualXML = $pos->createRegularPaymentXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPaymentXMLData($pos->getOrder(), $pos->getCard(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRegularPostXML() - { - $order = [ - 'id' => '2020110828BC', - 'ref_ret_num' => '831803579226', - 'currency' => 'TRY', - 'amount' => 100.01, - 'email' => 'samp@iexample.com', - 'ip' => '192.168.1.0', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $pos->prepare($order, AbstractGateway::TX_POST_PAY); - - $actualXML = $pos->createRegularPostXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPostXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreate3DPaymentXML() - { - $order = [ - 'id' => '2020110828BC', - 'email' => 'samp@iexample.com', - 'name' => 'john doe', - 'user_id' => '1535', - 'ip' => '192.168.1.0', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', - ]; - $responseData = [ - 'orderid' => '2020110828BC', - 'md' => '1', - 'xid' => '100000005xid', - 'eci' => '100000005eci', - 'cavv' => 'cavv', - 'txncurrencycode' => 'txncurrencycode', - 'txnamount' => 'txnamount', - 'txntype' => 'txntype', - 'customeripaddress' => 'customeripaddress', - 'customeremailaddress' => 'customeremailaddress', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $pos->prepare($order, AbstractGateway::TX_PAY); - - $actualXML = $pos->create3DPaymentXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSample3DPaymentXMLData($pos->getOrder(), $pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateStatusXML() - { - $order = [ - 'id' => '2020110828BC', - 'currency' => 'TRY', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $pos->prepare($order, AbstractGateway::TX_STATUS); - - $actualXML = $pos->createStatusXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleStatusXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - - public function testCreateCancelXML() - { - $order = [ - 'id' => '2020110828BC', - 'currency' => 'TRY', - 'amount' => 10.01, - 'ref_ret_num' => '831803579226', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $pos->prepare($order, AbstractGateway::TX_CANCEL); - - $actualXML = $pos->createCancelXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleCancelXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRefundXML() - { - $order = [ - 'id' => '2020110828BC', - 'currency' => 'TRY', - 'amount' => 10.01, - 'ref_ret_num' => '831803579226', - ]; - - /** - * @var GarantiPos $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->setTestMode(true); - $pos->prepare($order, AbstractGateway::TX_REFUND); - - $actualXML = $pos->createRefundXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRefundXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['Transaction']); + $this->assertSame(0, $this->pos->getOrder()->installment); } /** - * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() - * * @return void + * + * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() */ public function testMap3DPayResponseDataSuccess() { $gatewayResponse = [ - "xid" => "bVi+A/h6SjXabcde=", - "mdstatus" => "1", - "mderrormessage" => "TROY Gateway Result: [Code: '000', Message: 'Success', Description: 'Successful']", - "txnstatus" => "", - "eci" => "", - "cavv" => "ABIBBDYABBBBBAAABAAAAAAAAAAA=", - "paressyntaxok" => "", - "paresverified" => "", - "version" => "", - "ireqcode" => "", - "ireqdetail" => "", - "vendorcode" => "", - "cavvalgorithm" => "", - "md" => "longstring", - "terminalid" => "10012345", - "oid" => "1221513409", - "authcode" => "", - "response" => "", - "errmsg" => "", - "hostmsg" => "", - "procreturncode" => "", - "transid" => "1001513409", - "hostrefnum" => "", - "rnd" => "vNOc4abcde2aCL/HBzs", - "hash" => "1I9zDunx0hashTRI816trOG0Ao0=", - "hashparams" => "clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:", - "hashparamsval" => "longstring", - "clientid" => "10012345", - "MaskedPan" => "454311***7965", - "customeripaddress" => "134.170.165.149", - "orderid" => "1221513409", - "txntype" => "sales", - "terminalprovuserid" => "PROVAUT", - "secure3dhash" => "BE3C507794AhashE021E8EA239415D774EEF2", - "mode" => "PROD", - "txncurrencycode" => "949", - "customeremailaddress" => "admin@admin.com", - "terminaluserid" => "PROVAUT", - "terminalmerchantid" => "1234567", - "secure3dsecuritylevel" => "3D", - "user_id" => "1", - "errorurl" => "https://example.com/odeme_basarisiz", - "apiversion" => "v0.01", - "txnamount" => "100", - "txninstallmentcount" => "", - "successurl" => "https://example.com/odeme_basarili", - ]; - $expected = '{"id":"","order_id":"1221513409","trans_id":"1001513409","auth_code":"","host_ref_num":"","response":"Approved","transaction_type":null,"transaction":null,"transaction_security":"Full 3D Secure","proc_return_code":"","code":"","md_status":"1","status":"approved","status_detail":null,"hash":"BE3C507794AhashE021E8EA239415D774EEF2","rand":"vNOc4abcde2aCL\/HBzs","hash_params":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hash_params_val":"longstring","masked_number":"454311***7965","amount":"100","currency":"949","tx_status":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","xid":"bVi+A\/h6SjXabcde=","error_code":null,"error_message":"","md_error_message":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","campaign_url":null,"email":"admin@admin.com","extra":null,"3d_all":{"xid":"bVi+A\/h6SjXabcde=","mdstatus":"1","mderrormessage":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","txnstatus":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","paressyntaxok":"","paresverified":"","version":"","ireqcode":"","ireqdetail":"","vendorcode":"","cavvalgorithm":"","md":"longstring","terminalid":"10012345","oid":"1221513409","authcode":"","response":"","errmsg":"","hostmsg":"","procreturncode":"","transid":"1001513409","hostrefnum":"","rnd":"vNOc4abcde2aCL\/HBzs","hash":"1I9zDunx0hashTRI816trOG0Ao0=","hashparams":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hashparamsval":"longstring","clientid":"10012345","MaskedPan":"454311***7965","customeripaddress":"134.170.165.149","orderid":"1221513409","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"BE3C507794AhashE021E8EA239415D774EEF2","mode":"PROD","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"1234567","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"100","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; - $method = $this->getMethod('map3DPayResponseData'); - $result1 = $method->invoke($this->pos, $gatewayResponse); + 'xid' => 'bVi+A/h6SjXabcde=', + 'mdstatus' => '1', + 'mderrormessage' => 'TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']', + 'txnstatus' => '', + 'eci' => '', + 'cavv' => 'ABIBBDYABBBBBAAABAAAAAAAAAAA=', + 'paressyntaxok' => '', + 'paresverified' => '', + 'version' => '', + 'ireqcode' => '', + 'ireqdetail' => '', + 'vendorcode' => '', + 'cavvalgorithm' => '', + 'md' => 'longstring', + 'terminalid' => '10012345', + 'oid' => '1221513409', + 'authcode' => '', + 'response' => '', + 'errmsg' => '', + 'hostmsg' => '', + 'procreturncode' => '', + 'transid' => '1001513409', + 'hostrefnum' => '', + 'rnd' => 'vNOc4abcde2aCL/HBzs', + 'hash' => '1I9zDunx0hashTRI816trOG0Ao0=', + 'hashparams' => 'clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:', + 'hashparamsval' => 'longstring', + 'clientid' => '10012345', + 'MaskedPan' => '454311***7965', + 'customeripaddress' => '134.170.165.149', + 'orderid' => '1221513409', + 'txntype' => 'sales', + 'terminalprovuserid' => 'PROVAUT', + 'secure3dhash' => 'BE3C507794AhashE021E8EA239415D774EEF2', + 'mode' => 'PROD', + 'txncurrencycode' => '949', + 'customeremailaddress' => 'admin@admin.com', + 'terminaluserid' => 'PROVAUT', + 'terminalmerchantid' => '1234567', + 'secure3dsecuritylevel' => '3D', + 'user_id' => '1', + 'errorurl' => 'https://example.com/odeme_basarisiz', + 'apiversion' => 'v0.01', + 'txnamount' => '100', + 'txninstallmentcount' => '', + 'successurl' => 'https://example.com/odeme_basarili', + ]; + $expected = '{"id":"","order_id":"1221513409","trans_id":"1001513409","auth_code":"","host_ref_num":"","response":"Approved","transaction_type":null,"transaction":null,"transaction_security":"Full 3D Secure","proc_return_code":"","code":"","md_status":"1","status":"approved","status_detail":null,"hash":"BE3C507794AhashE021E8EA239415D774EEF2","rand":"vNOc4abcde2aCL\/HBzs","hash_params":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hash_params_val":"longstring","masked_number":"454311***7965","amount":"100","currency":"949","tx_status":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","xid":"bVi+A\/h6SjXabcde=","error_code":null,"error_message":"","md_error_message":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","campaign_url":null,"email":"admin@admin.com","extra":null,"3d_all":{"xid":"bVi+A\/h6SjXabcde=","mdstatus":"1","mderrormessage":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","txnstatus":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","paressyntaxok":"","paresverified":"","version":"","ireqcode":"","ireqdetail":"","vendorcode":"","cavvalgorithm":"","md":"longstring","terminalid":"10012345","oid":"1221513409","authcode":"","response":"","errmsg":"","hostmsg":"","procreturncode":"","transid":"1001513409","hostrefnum":"","rnd":"vNOc4abcde2aCL\/HBzs","hash":"1I9zDunx0hashTRI816trOG0Ao0=","hashparams":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hashparamsval":"longstring","clientid":"10012345","MaskedPan":"454311***7965","customeripaddress":"134.170.165.149","orderid":"1221513409","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"BE3C507794AhashE021E8EA239415D774EEF2","mode":"PROD","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"1234567","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"100","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; + $method = $this->getMethod('map3DPayResponseData'); + $result1 = $method->invoke($this->pos, $gatewayResponse); $this->assertIsArray($result1); $this->assertSame(json_decode($expected, true), $result1); @@ -395,375 +153,47 @@ public function testMap3DPayResponseDataSuccess() /** * @return void - */ - public function testCreate3DHashFor3DSecure() - { - $expected = '1D319D5EA945F5730FF5BCC970FF96690993F4BD'; - $pos = $this->pos; - $pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $pos->create3DHash($pos->getAccount(), $pos->getOrder(), 'sales'); - $this->assertEquals($expected, $actual); - } - - /** - * @return void - */ - public function testCreateHashForPayment() - { - $expected = '00CD5B6C29D4CEA1F3002D785A9F9B09974AD51D'; - $pos = $this->pos; - $pos->prepare($this->order, AbstractGateway::TX_PAY); - $actual = $pos->createHashData($pos->getAccount(), $pos->getOrder(), 'sales'); - $this->assertEquals($expected, $actual); - - $pos->prepare($this->order, AbstractGateway::TX_PRE_PAY); - $actual = $pos->createHashData($pos->getAccount(), $pos->getOrder(), 'preauth'); - $this->assertEquals($expected, $actual); - } - - /** - * @return void - */ - public function testCreateHashForCancelAndRefund() - { - $order = [ - 'id' => '4499996', - 'ref_ret_num' => '446ss', - 'currency' => 'TRY', - ]; - $expected = '9788649A0C3AE14C082783CEA6775E08A7EFB311'; - $pos = $this->pos; - $pos->prepare($order, AbstractGateway::TX_CANCEL); - $actual = $pos->createHashData($pos->getAccount(), $pos->getOrder(), 'void'); - $this->assertEquals($expected, $actual); - - $pos->prepare($order, AbstractGateway::TX_REFUND); - $actual = $pos->createHashData($pos->getAccount(), $pos->getOrder(), 'refund'); - $this->assertEquals($expected, $actual); - } - - /** - * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() * - * @return void + * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() */ public function testMap3DPayResponseDataFail() { - $failResponse = [ - "mdstatus" => "0", - "mderrormessage" => "User Gave Up", - "errmsg" => "User Gave Up", - "clientid" => "10012345", - "oid" => "1221166825", - "response" => "Error", - "procreturncode" => "99", - "customeripaddress" => "111.222.333.444", - "orderid" => "1221166825", - "txntype" => "sales", - "terminalprovuserid" => "PROVAUT", - "secure3dhash" => "hashhash", - "mode" => "PROD", - "terminalid" => "10012345", - "txncurrencycode" => "949", - "customeremailaddress" => "admin@admin.com", - "terminaluserid" => "PROVAUT", - "terminalmerchantid" => "5220607", - "secure3dsecuritylevel" => "3D", - "user_id" => "1", - "errorurl" => "https://example.com/odeme_basarisiz", - "apiversion" => "v0.01", - "txnamount" => "9000", - "txninstallmentcount" => "", - "successurl" => "https://example.com/odeme_basarili", - ]; - $expected = '{"id":null,"order_id":"1221166825","trans_id":null,"auth_code":null,"host_ref_num":null,"response":"Declined","transaction_type":null,"transaction":null,"transaction_security":"MPI fallback","proc_return_code":"99","code":"99","md_status":"0","status":"declined","status_detail":"99","hash":"hashhash","rand":null,"hash_params":null,"hash_params_val":null,"masked_number":null,"amount":"9000","currency":"949","tx_status":null,"eci":null,"cavv":null,"xid":null,"error_code":"99","error_message":"User Gave Up","md_error_message":"User Gave Up","campaign_url":null,"email":"admin@admin.com","extra":null,"3d_all":{"mdstatus":"0","mderrormessage":"User Gave Up","errmsg":"User Gave Up","clientid":"10012345","oid":"1221166825","response":"Error","procreturncode":"99","customeripaddress":"111.222.333.444","orderid":"1221166825","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"hashhash","mode":"PROD","terminalid":"10012345","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"5220607","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"9000","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; - $method = $this->getMethod('map3DPayResponseData'); - $result1 = $method->invoke($this->pos, $failResponse); + $failResponse = [ + 'mdstatus' => '0', + 'mderrormessage' => 'User Gave Up', + 'errmsg' => 'User Gave Up', + 'clientid' => '10012345', + 'oid' => '1221166825', + 'response' => 'Error', + 'procreturncode' => '99', + 'customeripaddress' => '111.222.333.444', + 'orderid' => '1221166825', + 'txntype' => 'sales', + 'terminalprovuserid' => 'PROVAUT', + 'secure3dhash' => 'hashhash', + 'mode' => 'PROD', + 'terminalid' => '10012345', + 'txncurrencycode' => '949', + 'customeremailaddress' => 'admin@admin.com', + 'terminaluserid' => 'PROVAUT', + 'terminalmerchantid' => '5220607', + 'secure3dsecuritylevel' => '3D', + 'user_id' => '1', + 'errorurl' => 'https://example.com/odeme_basarisiz', + 'apiversion' => 'v0.01', + 'txnamount' => '9000', + 'txninstallmentcount' => '', + 'successurl' => 'https://example.com/odeme_basarili', + ]; + $expected = '{"id":null,"order_id":"1221166825","trans_id":null,"auth_code":null,"host_ref_num":null,"response":"Declined","transaction_type":null,"transaction":null,"transaction_security":"MPI fallback","proc_return_code":"99","code":"99","md_status":"0","status":"declined","status_detail":"99","hash":"hashhash","rand":null,"hash_params":null,"hash_params_val":null,"masked_number":null,"amount":"9000","currency":"949","tx_status":null,"eci":null,"cavv":null,"xid":null,"error_code":"99","error_message":"User Gave Up","md_error_message":"User Gave Up","campaign_url":null,"email":"admin@admin.com","extra":null,"3d_all":{"mdstatus":"0","mderrormessage":"User Gave Up","errmsg":"User Gave Up","clientid":"10012345","oid":"1221166825","response":"Error","procreturncode":"99","customeripaddress":"111.222.333.444","orderid":"1221166825","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"hashhash","mode":"PROD","terminalid":"10012345","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"5220607","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"9000","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; + $method = $this->getMethod('map3DPayResponseData'); + $result1 = $method->invoke($this->pos, $failResponse); $this->assertSame(json_decode($expected, true), $result1); } - /** - * @param $order - * @param AbstractCreditCard $card - * @param GarantiPosAccount $account - * - * @return array - */ - private function getSampleRegularPaymentXMLData($order, AbstractCreditCard $card, GarantiPosAccount $account) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'Terminal' => [ - 'ProvUserID' => $account->getUsername(), - 'UserID' => $account->getUsername(), - 'HashData' => 'F0641E566B7B98260FD1608D1DF81E8D55461877', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $order->ip, - 'EmailAddress' => $order->email, - ], - 'Card' => [ - 'Number' => $card->getNumber(), - 'ExpireDate' => '0122', - 'CVV2' => $card->getCvv(), - ], - 'Order' => [ - 'OrderID' => $order->id, - 'GroupID' => '', - 'AddressList' => [ - 'Address' => [ - 'Type' => 'S', - 'Name' => $order->name, - 'LastName' => '', - 'Company' => '', - 'Text' => '', - 'District' => '', - 'City' => '', - 'PostalCode' => '', - 'Country' => '', - 'PhoneNumber' => '', - ], - ], - ], - 'Transaction' => [ - 'Type' => 'sales', - 'InstallmentCnt' => $order->installment, - 'Amount' => $order->amount, - 'CurrencyCode' => $order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'Description' => '', - 'OriginalRetrefNum' => '', - ], - ]; - } - - /** - * @param $order - * @param GarantiPosAccount $account - * - * @return array - */ - private function getSampleRegularPostXMLData($order, $account) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'Terminal' => [ - 'ProvUserID' => $account->getUsername(), - 'UserID' => $account->getUsername(), - 'HashData' => '7598B3D1A15C45095CD139E9CFD780B050D1C4AA', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $order->ip, - 'EmailAddress' => $order->email, - ], - 'Order' => [ - 'OrderID' => $order->id, - ], - 'Transaction' => [ - 'Type' => 'postauth', - 'Amount' => $order->amount, - 'CurrencyCode' => $order->currency, - 'OriginalRetrefNum' => $order->ref_ret_num, - ], - ]; - } - - /** - * @param $order - * @param GarantiPosAccount $account - * @param array $responseData - * - * @return array - */ - private function getSample3DPaymentXMLData($order, $account, array $responseData) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $account->getUsername(), - 'UserID' => $account->getUsername(), - 'HashData' => '7598B3D1A15C45095CD139E9CFD780B050D1C4AA', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $responseData['customeripaddress'], - 'EmailAddress' => $responseData['customeremailaddress'], - ], - 'Card' => [ - 'Number' => '', - 'ExpireDate' => '', - 'CVV2' => '', - ], - 'Order' => [ - 'OrderID' => $responseData['orderid'], - 'GroupID' => '', - 'AddressList' => [ - 'Address' => [ - 'Type' => 'B', - 'Name' => $order->name, - 'LastName' => '', - 'Company' => '', - 'Text' => '', - 'District' => '', - 'City' => '', - 'PostalCode' => '', - 'Country' => '', - 'PhoneNumber' => '', - ], - ], - ], - 'Transaction' => [ - 'Type' => $responseData['txntype'], - 'InstallmentCnt' => $order->installment, - 'Amount' => $responseData['txnamount'], - 'CurrencyCode' => $responseData['txncurrencycode'], - 'CardholderPresentCode' => '13', - 'MotoInd' => 'N', - 'Secure3D' => [ - 'AuthenticationCode' => $responseData['cavv'], - 'SecurityLevel' => $responseData['eci'], - 'TxnID' => $responseData['xid'], - 'Md' => $responseData['md'], - ], - ], - ]; - } - - /** - * @param $order - * @param GarantiPosAccount $account - * - * @return array - */ - private function getSampleStatusXMLData($order, $account) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $account->getUsername(), - 'UserID' => $account->getUsername(), - 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $order->ip, - 'EmailAddress' => $order->email, - ], - 'Order' => [ - 'OrderID' => $order->id, - 'GroupID' => '', - ], - 'Card' => [ - 'Number' => '', - 'ExpireDate' => '', - 'CVV2' => '', - ], - 'Transaction' => [ - 'Type' => 'orderinq', - 'InstallmentCnt' => '', - 'Amount' => $order->amount, - 'CurrencyCode' => $order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - ], - ]; - } - - /** - * @param $order - * @param GarantiPosAccount $account - * - * @return array - */ - private function getSampleCancelXMLData($order, $account) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $account->getRefundUsername(), - 'UserID' => $account->getRefundUsername(), - 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $order->ip, - 'EmailAddress' => $order->email, - ], - 'Order' => [ - 'OrderID' => $order->id, - 'GroupID' => '', - ], - 'Transaction' => [ - 'Type' => 'void', - 'InstallmentCnt' => $order->installment, - 'Amount' => $order->amount, - 'CurrencyCode' => $order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'OriginalRetrefNum' => $order->ref_ret_num, - ], - ]; - - } - - /** - * @param $order - * @param GarantiPosAccount $account - * - * @return array - */ - private function getSampleRefundXMLData($order, $account) - { - return [ - 'Mode' => 'TEST', - 'Version' => GarantiPos::API_VERSION, - 'ChannelCode' => '', - 'Terminal' => [ - 'ProvUserID' => $account->getRefundUsername(), - 'UserID' => $account->getRefundUsername(), - 'HashData' => '8DD74209DEEB7D333105E1C69998A827419A3B04', - 'ID' => $account->getTerminalId(), - 'MerchantID' => $account->getClientId(), - ], - 'Customer' => [ - 'IPAddress' => $order->ip, - 'EmailAddress' => $order->email, - ], - 'Order' => [ - 'OrderID' => $order->id, - 'GroupID' => '', - ], - 'Transaction' => [ - 'Type' => 'refund', - 'InstallmentCnt' => '', - 'Amount' => $order->amount, - 'CurrencyCode' => $order->currency, - 'CardholderPresentCode' => '0', - 'MotoInd' => 'N', - 'OriginalRetrefNum' => $order->ref_ret_num, - ], - ]; - } - private static function getMethod(string $name): ReflectionMethod { - $class = new ReflectionClass(GarantiPos::class); + $class = new ReflectionClass(GarantiPos::class); $method = $class->getMethod($name); $method->setAccessible(true); diff --git a/tests/Gateways/InterPosTest.php b/tests/Gateways/InterPosTest.php index 443e37a3..a48be2a4 100644 --- a/tests/Gateways/InterPosTest.php +++ b/tests/Gateways/InterPosTest.php @@ -1,5 +1,7 @@ order = [ @@ -55,7 +57,7 @@ protected function setUp(): void 'currency' => 'TRY', 'success_url' => 'https://domain.com/success', 'fail_url' => 'https://domain.com/fail_url', - 'lang' => InterPos::LANG_TR, + 'lang' => AbstractGateway::LANG_TR, 'rand' => microtime(true), ]; diff --git a/tests/Gateways/KuveytPosTest.php b/tests/Gateways/KuveytPosTest.php index f32ee0eb..f36959d4 100644 --- a/tests/Gateways/KuveytPosTest.php +++ b/tests/Gateways/KuveytPosTest.php @@ -1,9 +1,10 @@ '0.43625700 1604831630', 'hash' => 'zmSUxYPhmCj7QOzqpk/28LuE1Oc=', 'ip' => '127.0.0.1', - 'lang' => KuveytPos::LANG_TR, + 'lang' => AbstractGateway::LANG_TR, ]; $this->pos = PosFactory::createPosGateway($this->threeDAccount); @@ -89,8 +87,6 @@ protected function setUp(): void AbstractCreditCard::CARD_TYPE_VISA ); - $this->requestDataMapper = new KuveytPosRequestDataMapper(); - $this->xmlDecoder = new XmlEncoder(); } @@ -180,7 +176,7 @@ public function testGetCommon3DFormDataSuccessResponse() 'gateway' => [ 'test' => $testGateway, ], - ], ], $this->threeDAccount, [], ]) + ], ], $this->threeDAccount, PosFactory::getGatewayMapper(KuveytPos::class), ]) ->onlyMethods(['send']) ->getMock(); $posMock->setTestMode(true); @@ -228,7 +224,7 @@ public function testMake3DPaymentAuthSuccessProvisionFail() ]); $posMock = $this->getMockBuilder(KuveytPos::class) - ->setConstructorArgs([[], $this->threeDAccount, []]) + ->setConstructorArgs([[], $this->threeDAccount, PosFactory::getGatewayMapper(KuveytPos::class)]) ->onlyMethods(['send', 'check3DHash']) ->getMock(); @@ -277,7 +273,7 @@ public function testMake3DPaymentAuthSuccessProvisionSuccess() ]); $posMock = $this->getMockBuilder(KuveytPos::class) - ->setConstructorArgs([[], $this->threeDAccount, []]) + ->setConstructorArgs([[], $this->threeDAccount, PosFactory::getGatewayMapper(KuveytPos::class)]) ->onlyMethods(['send', 'check3DHash']) ->getMock(); diff --git a/tests/Gateways/PayForTest.php b/tests/Gateways/PayForTest.php index 3fcc78a6..da4e7fb8 100644 --- a/tests/Gateways/PayForTest.php +++ b/tests/Gateways/PayForTest.php @@ -1,5 +1,7 @@ 'http://localhost/finansbank-payfor/3d/response.php', 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', 'rand' => '0.43625700 1604831630', - 'hash' => 'zmSUxYPhmCj7QOzqpk/28LuE1Oc=', - 'lang' => PayForPos::LANG_TR, + 'lang' => AbstractGateway::LANG_TR, ]; $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); - - $this->xmlDecoder = new XmlEncoder(); } + /** + * @return void + */ public function testInit() { $this->assertEquals($this->config['banks'][$this->threeDAccount->getBank()], $this->pos->getConfig()); $this->assertEquals($this->threeDAccount, $this->pos->getAccount()); $this->assertNotEmpty($this->pos->getCurrencies()); + $this->assertEquals($this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway_3d_host']['test'], $this->pos->get3DHostGatewayURL()); $this->assertEquals($this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test'], $this->pos->get3DGatewayURL()); $this->assertEquals($this->config['banks'][$this->threeDAccount->getBank()]['urls']['test'], $this->pos->getApiURL()); - } + /** + * @return void + */ public function testSetTestMode() { $this->pos->setTestMode(false); @@ -92,85 +88,25 @@ public function testSetTestMode() $this->assertTrue($this->pos->isTestMode()); } - + /** + * @return void + */ public function testPrepare() { $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $this->assertEquals($this->card, $this->pos->getCard()); - } + $this->assertNotEmpty($this->pos->getOrder()); - public function testGet3DFormDataWithCard() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - $order = $this->pos->getOrder(); - $form = [ - 'gateway' => $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantID' => $this->threeDAccount->getClientId(), - 'UserCode' => $this->threeDAccount->getUsername(), - 'OrderId' => $order->id, - 'Lang' => $order->lang, - 'SecureType' => '3DModel', - 'TxnType' => 'Auth', - 'PurchAmount' => $order->amount, - 'InstallmentCount' => $order->installment, - 'Currency' => $order->currency, - 'OkUrl' => $order->success_url, - 'FailUrl' => $order->fail_url, - 'Rnd' => $order->rand, - 'Hash' => $this->pos->create3DHash($this->pos->getAccount(), $this->pos->getOrder(), 'Auth'), - 'CardHolderName' => 'ahmet', - 'Pan' => '5555444433332222', - 'Expiry' => '0122', - 'Cvv2' => '123', - ], - ]; - $this->assertEquals($form, $this->pos->get3DFormData()); - } + $this->pos->prepare($this->order, AbstractGateway::TX_POST_PAY); - public function testGet3DFormDataWithoutCard() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY); - $order = $this->pos->getOrder(); - $form = [ - 'gateway' => $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway']['test'], - 'inputs' => [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantID' => $this->threeDAccount->getClientId(), - 'UserCode' => $this->threeDAccount->getUsername(), - 'OrderId' => $order->id, - 'Lang' => $order->lang, - 'SecureType' => '3DModel', - 'TxnType' => 'Auth', - 'PurchAmount' => $order->amount, - 'InstallmentCount' => $order->installment, - 'Currency' => $order->currency, - 'OkUrl' => $order->success_url, - 'FailUrl' => $order->fail_url, - 'Rnd' => $order->rand, - 'Hash' => $this->pos->create3DHash($this->pos->getAccount(), $this->pos->getOrder(), 'Auth'), - ], - ]; - $this->assertEquals($form, $this->pos->get3DFormData()); - } + $this->pos->prepare($this->order, AbstractGateway::TX_CANCEL); - public function testCreate3DHash() - { - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '0', - 'success_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'fail_url' => 'http://localhost/finansbank-payfor/3d/response.php', - 'rand' => '0.43625700 1604831630', - ]; - $hash = 'zmSUxYPhmCj7QOzqpk/28LuE1Oc='; - $pos = $this->pos; - $pos->prepare($order, AbstractGateway::TX_PAY); - $this->assertEquals($hash, $this->pos->create3DHash($pos->getAccount(), $pos->getOrder(), 'Auth')); + $this->pos->prepare($this->order, AbstractGateway::TX_REFUND); } + /** + * @return void + */ public function testCheck3DHash() { $data = [ @@ -187,265 +123,4 @@ public function testCheck3DHash() $data['3DStatus'] = ''; $this->assertFalse($this->pos->check3DHash($this->pos->getAccount(), $data)); } - - public function testCreateRegularPaymentXML() - { - - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - 'lang' => PayForPos::LANG_TR, - ]; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet'); - $pos->prepare($order, AbstractGateway::TX_PAY, $card); - - $actualXML = $pos->createRegularPaymentXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPaymentXMLData($pos->getOrder(), $pos->getCard(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRegularPostXML() - { - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - 'lang' => PayForPos::LANG_TR, - ]; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $pos->prepare($order, AbstractGateway::TX_POST_PAY); - - $actualXML = $pos->createRegularPostXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPostXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreate3DPaymentXML() - { - - $order = [ - 'id' => '2020110828BC', - ]; - $responseData = ['RequestGuid' => '1000000057437884']; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $pos->prepare($order, AbstractGateway::TX_PAY); - - $actualXML = $pos->create3DPaymentXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSample3DPaymentXMLData($pos->getOrder(), $pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateStatusXML() - { - $order = [ - 'id' => '2020110828BC', - ]; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $pos->prepare($order, AbstractGateway::TX_STATUS); - - $actualXML = $pos->createStatusXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleStatusXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateCancelXML() - { - $order = [ - 'id' => '2020110828BC', - 'currency' => 'TRY', - ]; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $pos->prepare($order, AbstractGateway::TX_CANCEL); - - $actualXML = $pos->createCancelXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleCancelXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - public function testCreateRefundXML() - { - $order = [ - 'id' => '2020110828BC', - 'currency' => 'TRY', - 'amount' => 10.1, - ]; - - /** - * @var PayForPos $pos - */ - $pos = PosFactory::createPosGateway($this->threeDAccount); - $pos->prepare($order, AbstractGateway::TX_REFUND); - - $actualXML = $pos->createRefundXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRefundXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - /** - * @param $order - * @param AbstractCreditCard $card - * @param PayForAccount $account - * - * @return array - */ - private function getSampleRegularPaymentXMLData($order, $card, $account) - { - return [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantId' => $account->getClientId(), - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'MOTO' => PayForPos::MOTO, - 'OrderId' => $order->id, - 'SecureType' => 'NonSecure', - 'TxnType' => 'Auth', - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'InstallmentCount' => $order->installment, - 'Lang' => 'tr', - 'CardHolderName' => $card->getHolderName(), - 'Pan' => $card->getNumber(), - 'Expiry' => '0122', - 'Cvv2' => $card->getCvv(), - ]; - } - - /** - * @param $order - * @param PayForAccount $account - * - * @return array - */ - private function getSampleRegularPostXMLData($order, $account) - { - return [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantId' => $account->getClientId(), - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'OrgOrderId' => $order->id, - 'SecureType' => 'NonSecure', - 'TxnType' => 'PostAuth', - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - 'Lang' => 'tr', - ]; - } - - /** - * @param $order - * @param PayForAccount $account - * @param array $responseData - * - * @return array - */ - private function getSample3DPaymentXMLData($order, $account, array $responseData) - { - return [ - 'RequestGuid' => $responseData['RequestGuid'], - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'OrderId' => $order->id, - 'SecureType' => '3DModelPayment', - ]; - } - - /** - * @param $order - * @param PayForAccount $account - * - * @return array - */ - private function getSampleStatusXMLData($order, $account) - { - return [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantId' => $account->getClientId(), - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'OrgOrderId' => $order->id, - 'SecureType' => 'Inquiry', - 'Lang' => 'tr', - 'TxnType' => 'OrderInquiry', - ]; - } - - /** - * @param $order - * @param PayForAccount $account - * - * @return array - */ - private function getSampleCancelXMLData($order, $account) - { - return [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantId' => $account->getClientId(), - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'OrgOrderId' => $order->id, - 'SecureType' => 'NonSecure', - 'Lang' => 'tr', - 'TxnType' => 'Void', - 'Currency' => $order->currency, - ]; - } - - /** - * @param $order - * @param PayForAccount $account - * - * @return array - */ - private function getSampleRefundXMLData($order, $account) - { - return [ - 'MbrId' => PayForPos::MBR_ID, - 'MerchantId' => $account->getClientId(), - 'UserCode' => $account->getUsername(), - 'UserPass' => $account->getPassword(), - 'OrgOrderId' => $order->id, - 'SecureType' => 'NonSecure', - 'Lang' => 'tr', - 'TxnType' => 'Refund', - 'PurchAmount' => $order->amount, - 'Currency' => $order->currency, - ]; - } } diff --git a/tests/Gateways/PosNetTest.php b/tests/Gateways/PosNetTest.php index c541ff85..68d90b8c 100644 --- a/tests/Gateways/PosNetTest.php +++ b/tests/Gateways/PosNetTest.php @@ -1,7 +1,10 @@ 'test@test.com', 'amount' => '1.75', 'installment' => 0, - 'currency' => 'TL', + 'currency' => 'TRY', 'success_url' => 'https://domain.com/success', 'fail_url' => 'https://domain.com/fail_url', 'lang' => 'tr', @@ -70,10 +65,11 @@ protected function setUp(): void $this->pos->setTestMode(true); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122', 'ahmet'); - - $this->xmlDecoder = new XmlEncoder(); } + /** + * @return void + */ public function testInit() { $this->assertEquals($this->config['banks'][$this->account->getBank()], $this->pos->getConfig()); @@ -81,53 +77,47 @@ public function testInit() $this->assertNotEmpty($this->pos->getCurrencies()); } + /** + * @return void + */ public function testPrepare() { $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $this->assertEquals($this->card, $this->pos->getCard()); - } - public function testCreate3DHash() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - $actual = $this->pos->create3DHash($this->pos->getAccount(), $this->pos->getOrder()); - $this->assertEquals('J/7/Xprj7F/KDf98luVfIGyUPRQzUCqGwpmvz3KT7oQ=', $actual); + $this->order['host_ref_num'] = 'zz'; + $this->pos->prepare($this->order, AbstractGateway::TX_POST_PAY); + + $this->pos->prepare($this->order, AbstractGateway::TX_REFUND); } - public function testCreate3DHashForNon3DSecure() + /** + * @return void + * + * @throws Exception + */ + public function testGet3DFormDataOosTransactionFail() { - $account = AccountFactory::createPosNetAccount( - 'yapikredi', - '6706598320', - 'XXXXXX', - 'XXXXXX', - '67005551', - '27426', - AbstractGateway::MODEL_NON_SECURE, - '10,10,10,10,10,10,10,10' - ); - /** @var PosNet $pos */ - $pos = PosFactory::createPosGateway($account); + $this->expectException(Exception::class); + $this->expectExceptionCode(3); - $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - $actual = $pos->create3DHash($pos->getAccount(), $pos->getOrder()); - $this->assertEquals('', $actual); - } + $posMock = $this->getMockBuilder(PosNet::class) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(PosNet::class)]) + ->onlyMethods(['getOosTransactionData']) + ->getMock(); + $posMock->setTestMode(true); + $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $posMock->expects($this->once())->method('getOosTransactionData')->willReturn($this->getSampleOoTransactionFailResponseData()); - public function testAmountFormat() - { - $this->assertEquals(100000, PosNet::amountFormat(1000)); - $this->assertEquals(100000, PosNet::amountFormat(1000.00)); - $this->assertEquals(100001, PosNet::amountFormat(1000.01)); + $posMock->get3DFormData(); } public function testVerifyResponseMAC() { - - $newOrder = $this->order; - $newOrder['id'] = '895'; - $newOrder['amount'] = 1; - $newOrder['currency'] = 'TL'; + $newOrder = $this->order; + $newOrder['id'] = '895'; + $newOrder['amount'] = 1; + $newOrder['currency'] = 'TRY'; $account = AccountFactory::createPosNetAccount( 'yapikredi', @@ -159,368 +149,56 @@ public function testVerifyResponseMAC() $this->assertFalse($pos->verifyResponseMAC($pos->getAccount(), $pos->getOrder(), $data)); } - public function testCreateRegularPaymentXML() + public function testCheck3DHash() { - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '2', - 'currency' => 'TRY', - ]; - - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $card = CreditCardFactory::create($pos, '5555444433332222', '22', '01', '123', 'ahmet'); - $pos->prepare($order, AbstractGateway::TX_PAY, $card); - - $actualXML = $pos->createRegularPaymentXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); + $account = AccountFactory::createPosNetAccount( + 'yapikredi', + '6706022701', + 'XXXXXX', + 'XXXXXX', + '67002706', + '27426', + AbstractGateway::MODEL_3D_SECURE, + '10,10,10,10,10,10,10,10' + ); - $expectedData = $this->getSampleRegularPaymentXMLData($pos->getOrder(), $pos->getCard(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['sale']); - } + $pos = PosFactory::createPosGateway($account); - public function testCreateRegularPostXML() - { - $order = [ - 'id' => '2020110828BC', - 'host_ref_num' => '019676067890000191', - 'amount' => 10.02, - 'currency' => 'TRY', - 'installment' => '2', + $data = [ + 'MerchantPacket' => 'F57E38055C280283044612E7338A314758CE0BB13FE9CFF2D1ACD415A979C1C65AD1FA664E561809F63262552496B491378DE688980EDFEF32785CB8090E0F3F618D560B4C2C089C7B9FBA8F91F1F4231D6725ECF8D94B18B0AA9EA206083D94BA1315DCC950E7E5BED2B3B5A1571C3E761E2364E590CC6BB95BF4F1165208FA55CE99BDE6C7ACDEFB5A2A6F16B6C3838B9876F00EDF1E7261B626532EE81C40C9DE94588ED36FC4D2E639FA89152D1590A0031416BA8A31A1300EE37E31BD54B6ADA2FF7D4D58EA0A4A1CC7', ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_POST_PAY); - - $actualXML = $pos->createRegularPostXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRegularPostXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['capt']); - } - - public function testCreate3DPaymentXML() - { - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - ]; - $responseData = [ - 'BankPacket' => 'F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', - 'MerchantPacket' => 'E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', - 'Sign' => '9998F61E1D0C0FB6EC5203A748124F30', + 'id' => 'YKB_0000080603153823', + 'amount' => 56.96, + 'currency' => 'TRY', + 'installment' => 0, ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); $pos->prepare($order, AbstractGateway::TX_PAY); + $result = $pos->check3DHash($data); + $this->assertTrue($result); - $actualXML = $pos->create3DPaymentXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSample3DPaymentXMLData($pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['oosTranData']); - } - - public function testGetOosTransactionRequestData() - { - $this->pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); - $order = $this->pos->getOrder(); - $expected = $this->getSampleOosTransactionRequestData($order, $this->card, $this->pos->getAccount()); - $this->assertEquals($expected, $this->pos->getOosTransactionRequestData($this->pos->getAccount(), $this->card, $order, 'Sale')); - } - - - public function testCreate3DResolveMerchantDataXML() - { - - $order = [ - 'id' => '2020110828BC', - 'amount' => 100.01, - 'installment' => '0', - 'currency' => 'TRY', - ]; - $responseData = [ - 'BankPacket' => 'F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', - 'MerchantPacket' => 'E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F309998F61E1D0C0FB6EC5203A748124F30', - 'Sign' => '9998F61E1D0C0FB6EC5203A748124F30', - ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); + $order['amount'] = 56.97; $pos->prepare($order, AbstractGateway::TX_PAY); + $result = $pos->check3DHash($data); + $this->assertFalse($result); - $actualXML = $pos->create3DResolveMerchantDataXML($responseData); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleResolveMerchantDataXMLData($pos->getAccount(), $responseData); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['oosResolveMerchantData']); - } - - public function testCreateStatusXML() - { - $order = [ - 'id' => '2020110828BC', - 'type' => 'status', - ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_STATUS); - - $actualXML = $pos->createStatusXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleStatusXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['agreement']); - } - - - public function testCreateCancelXML() - { - $order = [ - 'id' => '2020110828BC', - 'host_ref_num' => '2020110828BCNUM', - ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_CANCEL); - - $actualXML = $pos->createCancelXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleCancelXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - //$this->assertEquals([], $actualData['reverse']); - } - - public function testCreateRefundXML() - { - $order = [ - 'id' => '2020110828BC', - 'amount' => 50, - 'currency' => 'TRY', - ]; - - /** - * @var PosNet $pos - */ - $pos = PosFactory::createPosGateway($this->account); - $pos->prepare($order, AbstractGateway::TX_REFUND); - - $actualXML = $pos->createRefundXML(); - $actualData = $this->xmlDecoder->decode($actualXML, 'xml'); - - $expectedData = $this->getSampleRefundXMLData($pos->getOrder(), $pos->getAccount()); - $this->assertEquals($expectedData, $actualData); - } - - /** - * @param $order - * @param AbstractCreditCard $card - * @param PosNetAccount $account - * - * @return array - */ - private function getSampleRegularPaymentXMLData($order, AbstractCreditCard $card, PosNetAccount $account) - { - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'tranDateRequired' => '1', - 'sale' => [ - 'orderID' => $order->id, - 'installment' => $order->installment, - 'amount' => $order->amount, - 'currencyCode' => $order->currency, - 'ccno' => $card->getNumber(), - 'expDate' => '2201', - 'cvc' => $card->getCvv(), - ], - ]; - } - - /** - * @param $order - * @param PosNetAccount $account - * - * @return array - */ - private function getSampleRegularPostXMLData($order, $account) - { - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'tranDateRequired' => '1', - 'capt' => [ - 'hostLogKey' => $order->host_ref_num, - 'amount' => $order->amount, - 'currencyCode' => $order->currency, - 'installment' => $order->installment, - ], - ]; - } - - /** - * @param PosNetAccount $account - * @param array $responseData - * - * @return array - */ - private function getSample3DPaymentXMLData($account, array $responseData) - { - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'oosTranData' => [ - 'bankData' => $responseData['BankPacket'], - 'merchantData' => $responseData['MerchantPacket'], - 'sign' => $responseData['Sign'], - 'wpAmount' => 0, - 'mac' => 'oE7zwV87uOc2DFpGPlr4jQRQ0z9LsxGw56c7vaiZkTo=', - ], - ]; + $order['amount'] = 56.96; + $pos->prepare($order, AbstractGateway::TX_PAY); + $data['MerchantPacket'] = $data['MerchantPacket'].'2'; + $result = $pos->check3DHash($data); + $this->assertFalse($result); } - /** - * @param PosNetAccount $account - * @param array $responseData - * - * @return array - */ - private function getSampleResolveMerchantDataXMLData($account, array $responseData) - { - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'oosResolveMerchantData' => [ - 'bankData' => $responseData['BankPacket'], - 'merchantData' => $responseData['MerchantPacket'], - 'sign' => $responseData['Sign'], - 'mac' => 'oE7zwV87uOc2DFpGPlr4jQRQ0z9LsxGw56c7vaiZkTo=', - ], - ]; - } /** - * @param $order - * @param PosNetAccount $account - * - * @return array + * @return string[] */ - private function getSampleStatusXMLData($order, $account) + private function getSampleOoTransactionFailResponseData(): array { return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'agreement' => [ - 'orderID' => $order->id, - ], + 'approved' => '0', + 'respCode' => '0003', + 'respText' => '148 MID,TID,IP HATALI:89.244.149.137', ]; } - - /** - * @param $order - * @param AbstractCreditCard $card - * @param PosNetAccount $account - * - * @return array - */ - private function getSampleOosTransactionRequestData($order, AbstractCreditCard $card, PosNetAccount $account): array - { - return [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'oosRequestData' => [ - 'posnetid' => $account->getPosNetId(), - 'ccno' => $card->getNumber(), - 'expDate' => '2112', - 'cvc' => $this->card->getCvv(), - 'amount' => $order->amount, - 'currencyCode' => $order->currency, - 'installment' => $order->installment, - 'XID' => PosNet::formatOrderId($order->id), - 'cardHolderName' => $card->getHolderName(), - 'tranType' => 'Sale', - ], - ]; - } - - /** - * @param $order - * @param PosNetAccount $account - * - * @return array - */ - private function getSampleCancelXMLData($order, $account) - { - $requestData = [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'tranDateRequired' => '1', - 'reverse' => [ - 'transaction' => 'sale', - ], - ]; - - //either will work - if (isset($order->host_ref_num)) { - $requestData['reverse']['hostLogKey'] = $order->host_ref_num; - } else { - $requestData['reverse']['orderID'] = PosNet::mapOrderIdToPrefixedOrderId($order->id, $account->getModel()); - } - - return $requestData; - } - - /** - * @param $order - * @param PosNetAccount $account - * - * @return array - */ - private function getSampleRefundXMLData($order, $account) - { - $requestData = [ - 'mid' => $account->getClientId(), - 'tid' => $account->getTerminalId(), - 'tranDateRequired' => '1', - 'return' => [ - 'amount' => $order->amount, - 'currencyCode' => $order->currency, - ], - ]; - - if (isset($order->host_ref_num)) { - $requestData['return']['hostLogKey'] = $order->host_ref_num; - } else { - $requestData['return']['orderID'] = $order->id; - } - - return $requestData; - } } diff --git a/tests/Gateways/VakifBankPosTest.php b/tests/Gateways/VakifBankPosTest.php index c30db394..a89ac315 100644 --- a/tests/Gateways/VakifBankPosTest.php +++ b/tests/Gateways/VakifBankPosTest.php @@ -1,7 +1,11 @@ pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $this->assertEquals($this->card, $this->pos->getCard()); + + $this->pos->prepare($this->order, AbstractGateway::TX_POST_PAY); } /** @@ -106,7 +112,7 @@ public function testMap3DPaymentData3DSuccess() 'SubMerchantName' => null, 'SubMerchantNumber' => null, 'PurchAmount' => $preparedOrder['amount'] * 100, - 'PurchCurrency' => $preparedOrder['currency'], + 'PurchCurrency' => '949', 'VerifyEnrollmentRequestId' => $preparedOrder['id'], 'SessionInfo' => $preparedOrder['extraData'], 'InstallmentCount' => null, @@ -135,7 +141,7 @@ public function testMap3DPaymentData3DSuccess() 'HostDate' => '20220404123456', 'Rrn' => '209411062014', 'CurrencyAmount' => $preparedOrder['amount'], - 'CurrencyCode' => $preparedOrder['currency'], + 'CurrencyCode' => '949', 'OrderId' => $preparedOrder['id'], 'TLAmount' => $preparedOrder['amount'], 'ECI' => '02', @@ -144,7 +150,7 @@ public function testMap3DPaymentData3DSuccess() 'BatchNo' => '1', ]; - $method = $this->getMethod('map3DPaymentData'); + $method = $this->getMethod('map3DPaymentData'); $result = $method->invoke($this->pos, $threeDResponse, (object) $provisionResponse); $expected = [ @@ -188,7 +194,7 @@ public function testMap3DPaymentData3DFail() 'SubMerchantName' => null, 'SubMerchantNumber' => null, 'PurchAmount' => $preparedOrder['amount'] * 100, - 'PurchCurrency' => $preparedOrder['currency'], + 'PurchCurrency' => '949', 'VerifyEnrollmentRequestId' => $preparedOrder['id'], 'SessionInfo' => $preparedOrder['extraData'], 'InstallmentCount' => null, @@ -205,7 +211,7 @@ public function testMap3DPaymentData3DFail() $provisionResponse = []; - $method = $this->getMethod('map3DPaymentData'); + $method = $this->getMethod('map3DPaymentData'); $result = $method->invoke($this->pos, $threeDResponse, (object) $provisionResponse); $expected = [ @@ -222,7 +228,7 @@ public function testMap3DPaymentData3DFail() 'id' => null, 'trans_id' => null, 'host_ref_num' => null, - 'transaction_type' => 'Sale', + 'transaction_type' => AbstractGateway::TX_PAY, 'transaction' => 'Sale', 'proc_return_code' => null, 'code' => null, @@ -232,9 +238,47 @@ public function testMap3DPaymentData3DFail() $this->assertEquals($expected, (array) $result); } + /** + * @return void + * + * @throws Exception|GuzzleException + */ + public function testGet3DFormDataEnrollmentFail() + { + $this->expectException(Exception::class); + $this->expectExceptionCode(2005); + + $posMock = $this->getMockBuilder(VakifBankPos::class) + ->setConstructorArgs([[], $this->account, PosFactory::getGatewayMapper(VakifBankPos::class)]) + ->onlyMethods(['sendEnrollmentRequest']) + ->getMock(); + $posMock->setTestMode(true); + $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $posMock->expects($this->once())->method('sendEnrollmentRequest')->willReturn($this->getSampleEnrollmentFailResponseData()); + + $posMock->get3DFormData(); + } + + /** + * @return string[] + */ + private function getSampleEnrollmentFailResponseData(): array + { + return [ + 'Message' => [ + 'VERes' => [ + 'Status' => 'E', + ], + ], + 'VerifyEnrollmentRequestId' => '0aebb0757acccae6fba75b2e4d78cecf', + 'MessageErrorCode' => '2005', + 'ErrorMessage' => 'Merchant cannot be found for this bank', + ]; + } + private static function getMethod(string $name): \ReflectionMethod { - $class = new ReflectionClass(VakifBankPos::class); + $class = new ReflectionClass(VakifBankPos::class); $method = $class->getMethod($name); $method->setAccessible(true);