diff --git "a/.github/ISSUE_TEMPLATE/hata-bildirimi-i\303\247in.md" b/.github/ISSUE_TEMPLATE/hata-bildirimi-icin.md similarity index 100% rename from ".github/ISSUE_TEMPLATE/hata-bildirimi-i\303\247in.md" rename to .github/ISSUE_TEMPLATE/hata-bildirimi-icin.md diff --git "a/.github/ISSUE_TEMPLATE/sorular\304\261n\304\261z-i\303\247in.md" b/.github/ISSUE_TEMPLATE/sorulariniz-icin.md similarity index 100% rename from ".github/ISSUE_TEMPLATE/sorular\304\261n\304\261z-i\303\247in.md" rename to .github/ISSUE_TEMPLATE/sorulariniz-icin.md diff --git a/README.md b/README.md index a9e30612..9493eb1b 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Bu paket ile amaçlanan; ortak bir arayüz sınıfı ile, tüm Türk banka sanal - **VakifBank GET 7/24 MPI ve VPOS 7/24** 3D Secure ödemesi çalışır durumda, diğer işlemlerde sorunlar ortaya çıktıkça giderilecek. +- **VakifBank Common Payment (Ortak Ödeme)** 3DPay ve 3DHost ödeme desteği eklendi. + - **InterPOS (Deniz bank)** destegi eklenmiştir, test edildikçe, sorunlar bulundukça hatalar giderilecek. - **Kuveyt POS** 3d secure ödeme desteği eklenmiştir - testleri yapıldı, calışıyor. diff --git a/composer.json b/composer.json index 39515ed5..ec07236c 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "php-http/curl-client": "^2.2", "phpstan/phpstan": "^1.9", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^8.3", + "phpunit/phpunit": "^8.5", + "rector/rector": "^0.15.12", "slim/psr7": "^1.4", "squizlabs/php_codesniffer": "^3.5", "symfony/var-dumper": "^5.1" diff --git a/config/pos.php b/config/pos.php index f784a941..f44127ca 100644 --- a/config/pos.php +++ b/config/pos.php @@ -3,8 +3,8 @@ return [ //if you need to use custom keys for currency mapping, otherwise leave empty 'currencies' => [ -// 'TRY' => 949, -// 'USD' => 840, +// 'TRY' => '949', +// 'USD' => '840', ], // Banks 'banks' => [ @@ -160,6 +160,22 @@ ], ], ], + 'vakifbank-cp' => [ + 'name' => 'VakifBank-POS-Common-Payment', + 'class' => Mews\Pos\Gateways\VakifBankCPPos::class, + 'urls' => [ + 'production' => 'https://cpweb.vakifbank.com.tr/CommonPayment/api/RegisterTransaction', + 'test' => 'https://cptest.vakifbank.com.tr/CommonPayment/api/RegisterTransaction', + 'gateway' => [ + 'production' => 'https://cpweb.vakifbank.com.tr/CommonPayment/SecurePayment', + 'test' => 'https://cptest.vakifbank.com.tr/CommonPayment/SecurePayment', + ], + 'query' => [ + 'production' => 'https://cpweb.vakifbank.com.tr/CommonPayment/api/VposTransaction', + 'test' => 'https://cptest.vakifbank.com.tr/CommonPayment/api/VposTransaction', + ], + ], + ], 'denizbank' => [ 'name' => 'DenizBank-InterPos', 'class' => Mews\Pos\Gateways\InterPos::class, diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index bba16a72..ffc3cddd 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [0.12.0] - 2023-03-13 +### New Features +- Vakıfbank Common Payment (Ortak Ödeme) gateway desteği eklendi (`VakifBankCPPos`). + Sadece **3DPay** ve **3DHost** ödeme destekleri eklendi. + Örnek kodlar `examples/vakifbank-cp/` altında yer almaktadır. + +### Changed +- **EstPos** - `MODEL_3D_PAY_HOSTING` desteği eklendi @umuttaymaz. +- `get3DFormData()` - artık zorunlu _kart_ veya _sipariş_ bilgileri olmadan çağrıldığında istisna fırlatır. +- `get3DFormData()` - dönen değere HTTP methodu eklendi. Örn: `'method' => 'POST'` (ya da GET); + +### Fixed +- **Vakifbank** - bazı _undefined index_ hatalar giderildi. +- `VakifBankPosRequestDataMapper` - `OrderDescription` tanımsız olma durumu giderildi. + ## [0.11.0] - 2023-01-08 ### Changed - Response formatı **object** yerine artık **array** olarak değiştirildi, `$pos->getResponse();` kod artık array döner. diff --git a/examples/_common-codes/3d-host/index.php b/examples/_common-codes/3d-host/index.php index c9ee9956..ce3ed78d 100644 --- a/examples/_common-codes/3d-host/index.php +++ b/examples/_common-codes/3d-host/index.php @@ -1,7 +1,7 @@ get3DFormData(); -require '../../template/_redirect_form.php'; -require '../../template/_footer.php'; +require '../../_templates/_redirect_form.php'; +require '../../_templates/_footer.php'; diff --git a/examples/_common-codes/3d/form.php b/examples/_common-codes/3d/form.php index ac7478d3..a0c6de21 100644 --- a/examples/_common-codes/3d/form.php +++ b/examples/_common-codes/3d/form.php @@ -3,7 +3,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; if ($request->getMethod() !== 'POST') { echo new RedirectResponse($baseUrl.'index.php'); @@ -38,5 +38,5 @@ } -require '../../template/_redirect_form.php'; -require '../../template/_footer.php'; +require '../../_templates/_redirect_form.php'; +require '../../_templates/_footer.php'; diff --git a/examples/_common-codes/3d/index.php b/examples/_common-codes/3d/index.php index a66cc79a..83ba496f 100644 --- a/examples/_common-codes/3d/index.php +++ b/examples/_common-codes/3d/index.php @@ -1,10 +1,10 @@ request->all()); -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/template/_credit_card_form.php b/examples/_templates/_credit_card_form.php similarity index 100% rename from examples/template/_credit_card_form.php rename to examples/_templates/_credit_card_form.php diff --git a/examples/template/_footer.php b/examples/_templates/_footer.php similarity index 98% rename from examples/template/_footer.php rename to examples/_templates/_footer.php index 50325810..c99eadaa 100644 --- a/examples/template/_footer.php +++ b/examples/_templates/_footer.php @@ -1,4 +1,4 @@ - + diff --git a/examples/template/_header.php b/examples/_templates/_header.php similarity index 94% rename from examples/template/_header.php rename to examples/_templates/_header.php index 88cf1be5..f67586d6 100644 --- a/examples/template/_header.php +++ b/examples/_templates/_header.php @@ -30,7 +30,8 @@
  • PayFor (Finansbank)
  • Garanti POS
  • InterPos (Deniz bank)
  • -
  • VPOS (VakifBank bank)
  • +
  • VPOS 7/24 (VakifBank)
  • +
  • Common Payment (VakifBank)
  • PosNet (YKB)
  • KuveytPOS
  • diff --git a/examples/template/_payment_response.php b/examples/_templates/_payment_response.php similarity index 95% rename from examples/template/_payment_response.php rename to examples/_templates/_payment_response.php index 0b0d138f..9fb83b89 100644 --- a/examples/template/_payment_response.php +++ b/examples/_templates/_payment_response.php @@ -7,7 +7,10 @@ require_once '_config.php'; require '../../template/_header.php'; -if ($request->getMethod() !== 'POST' && AbstractGateway::TX_POST_PAY !== $transaction) { +if (($request->getMethod() !== 'POST' && AbstractGateway::TX_POST_PAY !== $transaction) + // Vakifbank-CP GET request ile cevapliyor + && ($request->getMethod() === 'GET' && [] === $request->query->all()) +) { echo new RedirectResponse($baseUrl); exit(); } diff --git a/examples/template/_redirect_form.php b/examples/_templates/_redirect_form.php similarity index 75% rename from examples/template/_redirect_form.php rename to examples/_templates/_redirect_form.php index c503f4c0..1e1da31a 100644 --- a/examples/template/_redirect_form.php +++ b/examples/_templates/_redirect_form.php @@ -1,4 +1,4 @@ -
    + $value) : ?> diff --git a/examples/template/_simple_response_dump.php b/examples/_templates/_simple_response_dump.php similarity index 100% rename from examples/template/_simple_response_dump.php rename to examples/_templates/_simple_response_dump.php diff --git a/examples/akbank/3d-host/response.php b/examples/akbank/3d-host/response.php index 3b26165b..04d1c82f 100644 --- a/examples/akbank/3d-host/response.php +++ b/examples/akbank/3d-host/response.php @@ -1,4 +1,4 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); if (isset($ord['recurringFrequency'])) { //tekrarlanan odemenin durumunu sorgulamak icin: @@ -29,5 +29,5 @@ $pos->cancel(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/akbank/regular/history.php b/examples/akbank/regular/history.php index d01ff502..7f09112e 100644 --- a/examples/akbank/regular/history.php +++ b/examples/akbank/regular/history.php @@ -3,7 +3,7 @@ $templateTitle = 'History Order'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; $ord = $session->get('order'); @@ -16,5 +16,5 @@ $query = $pos->history($order); $response = $query->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/akbank/regular/post-auth.php b/examples/akbank/regular/post-auth.php index a2a57a0b..bba4a57e 100644 --- a/examples/akbank/regular/post-auth.php +++ b/examples/akbank/regular/post-auth.php @@ -4,7 +4,7 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -14,4 +14,4 @@ $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/akbank/regular/refund.php b/examples/akbank/regular/refund.php index 0a7a9977..50b44494 100644 --- a/examples/akbank/regular/refund.php +++ b/examples/akbank/regular/refund.php @@ -4,9 +4,9 @@ $templateTitle = 'Refund Order'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); // Refund Order $order = [ @@ -21,5 +21,5 @@ $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/akbank/regular/status.php b/examples/akbank/regular/status.php index 9ba2ae1a..73e5bb2d 100644 --- a/examples/akbank/regular/status.php +++ b/examples/akbank/regular/status.php @@ -4,7 +4,7 @@ $templateTitle = 'Order Status'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; $ord = $session->get('order'); $lastResponse = $session->get('last_response'); @@ -28,5 +28,5 @@ $pos->status(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/finansbank-payfor/3d-host/response.php b/examples/finansbank-payfor/3d-host/response.php index 3b26165b..04d1c82f 100644 --- a/examples/finansbank-payfor/3d-host/response.php +++ b/examples/finansbank-payfor/3d-host/response.php @@ -1,4 +1,4 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -21,5 +21,5 @@ $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/finansbank-payfor/regular/history.php b/examples/finansbank-payfor/regular/history.php index ba831b33..d4c69272 100644 --- a/examples/finansbank-payfor/regular/history.php +++ b/examples/finansbank-payfor/regular/history.php @@ -3,7 +3,7 @@ $templateTitle = 'History Order'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; $ord = $session->get('order'); @@ -20,5 +20,5 @@ $response = $query->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/finansbank-payfor/regular/post-auth.php b/examples/finansbank-payfor/regular/post-auth.php index ea29e895..e4fe75ed 100644 --- a/examples/finansbank-payfor/regular/post-auth.php +++ b/examples/finansbank-payfor/regular/post-auth.php @@ -4,10 +4,10 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $session->set('post_order', $order); $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/finansbank-payfor/regular/refund.php b/examples/finansbank-payfor/regular/refund.php index adf64c07..7bc5a384 100644 --- a/examples/finansbank-payfor/regular/refund.php +++ b/examples/finansbank-payfor/regular/refund.php @@ -2,11 +2,11 @@ $templateTitle = 'Refund Order'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; use Mews\Pos\Gateways\AbstractGateway; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); // Refund Order $order = [ @@ -21,5 +21,5 @@ $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/finansbank-payfor/regular/status.php b/examples/finansbank-payfor/regular/status.php index f415cca7..3b1328ca 100644 --- a/examples/finansbank-payfor/regular/status.php +++ b/examples/finansbank-payfor/regular/status.php @@ -2,11 +2,11 @@ $templateTitle = 'Order Status'; require '_config.php'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; use Mews\Pos\Gateways\AbstractGateway; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -18,5 +18,5 @@ $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/garanti/3d-pay/response.php b/examples/garanti/3d-pay/response.php index 3b26165b..04d1c82f 100644 --- a/examples/garanti/3d-pay/response.php +++ b/examples/garanti/3d-pay/response.php @@ -1,4 +1,4 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -22,5 +22,5 @@ $pos->cancel(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/garanti/regular/history.php b/examples/garanti/regular/history.php index f671d2fa..645db02e 100644 --- a/examples/garanti/regular/history.php +++ b/examples/garanti/regular/history.php @@ -2,9 +2,9 @@ require '_config.php'; $templateTitle = 'History Order'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -18,5 +18,5 @@ $query = $pos->history([]); $response = $query->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/garanti/regular/post-auth.php b/examples/garanti/regular/post-auth.php index db142903..76413834 100644 --- a/examples/garanti/regular/post-auth.php +++ b/examples/garanti/regular/post-auth.php @@ -4,7 +4,7 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $order['id'], @@ -18,4 +18,4 @@ $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/garanti/regular/refund.php b/examples/garanti/regular/refund.php index 13989660..23ad80da 100644 --- a/examples/garanti/regular/refund.php +++ b/examples/garanti/regular/refund.php @@ -2,11 +2,11 @@ require '_config.php'; $templateTitle = 'Refund Order'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; use Mews\Pos\Gateways\AbstractGateway; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -22,5 +22,5 @@ $pos->refund(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/garanti/regular/status.php b/examples/garanti/regular/status.php index 370524fa..4a38491c 100644 --- a/examples/garanti/regular/status.php +++ b/examples/garanti/regular/status.php @@ -2,11 +2,11 @@ require '_config.php'; $templateTitle = 'Order Status'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; use Mews\Pos\Gateways\AbstractGateway; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -19,5 +19,5 @@ $pos->status(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/index.php b/examples/index.php index 8ae8553b..7d2c104b 100644 --- a/examples/index.php +++ b/examples/index.php @@ -5,5 +5,5 @@ */ $templateTitle = 'POS'; require './_main_config.php'; -require './template/_header.php'; -require './template/_footer.php'; +require './_templates/_header.php'; +require './_templates/_footer.php'; diff --git a/examples/interpos/3d-host/response.php b/examples/interpos/3d-host/response.php index 3b26165b..04d1c82f 100644 --- a/examples/interpos/3d-host/response.php +++ b/examples/interpos/3d-host/response.php @@ -1,4 +1,4 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -19,5 +19,5 @@ $pos->cancel(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/interpos/regular/post-auth.php b/examples/interpos/regular/post-auth.php index ea29e895..e4fe75ed 100644 --- a/examples/interpos/regular/post-auth.php +++ b/examples/interpos/regular/post-auth.php @@ -4,10 +4,10 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $session->set('post_order', $order); $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/interpos/regular/refund.php b/examples/interpos/regular/refund.php index ad393176..983205cb 100644 --- a/examples/interpos/regular/refund.php +++ b/examples/interpos/regular/refund.php @@ -4,9 +4,9 @@ require '_config.php'; $templateTitle = 'Refund Order'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); // Refund Order $order = [ @@ -20,5 +20,5 @@ $pos->refund(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/interpos/regular/status.php b/examples/interpos/regular/status.php index 7d315848..ce1e2ce3 100644 --- a/examples/interpos/regular/status.php +++ b/examples/interpos/regular/status.php @@ -4,7 +4,7 @@ require '_config.php'; $templateTitle = 'Order Status'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; $ord = $session->get('order'); @@ -17,5 +17,5 @@ $pos->status(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/kuveytpos/3d/response.php b/examples/kuveytpos/3d/response.php index 3b26165b..04d1c82f 100644 --- a/examples/kuveytpos/3d/response.php +++ b/examples/kuveytpos/3d/response.php @@ -1,4 +1,4 @@ get('card'); +$card = createCard($pos, $savedCard); + +require '../../_templates/_payment_response.php'; diff --git a/examples/vakifbank-cp/_payment_config.php b/examples/vakifbank-cp/_payment_config.php new file mode 100644 index 00000000..d8c1e073 --- /dev/null +++ b/examples/vakifbank-cp/_payment_config.php @@ -0,0 +1,79 @@ + [ + 'path' => '/3d-pay/index.php', + 'label' => '3D Pay Ödeme', + ], + AbstractGateway::MODEL_3D_HOST => [ + 'path' => '/3d-host/index.php', + 'label' => '3D Host Ödeme', + ], + AbstractGateway::MODEL_NON_SECURE => [ + 'path' => '/regular/index.php', + 'label' => 'Non Secure Ödeme', + ], + AbstractGateway::TX_CANCEL => [ + 'path' => '/regular/cancel.php', + 'label' => 'İptal', + ], + AbstractGateway::TX_REFUND => [ + 'path' => '/regular/refund.php', + 'label' => 'İade', + ], +]; + + +$installments = [ + 0 => 'Peşin', + 2 => '2 Taksit', + 6 => '6 Taksit', + 12 => '12 Taksit', +]; + +function getNewOrder( + string $baseUrl, + string $ip, + string $currency, + \Symfony\Component\HttpFoundation\Session\Session $session, + ?int $installment = 0, + bool $tekrarlanan = false, + string $lang = AbstractGateway::LANG_TR +): array { + $order = createNewPaymentOrderCommon($baseUrl, $ip, $currency, $installment, $lang); + + $order['extraData'] = $session->getId(); //optional, istekte SessionInfo degere atanir + + return $order; +} + +function doPayment(\Mews\Pos\PosInterface $pos, string $transaction, ?\Mews\Pos\Entity\Card\AbstractCreditCard $card) +{ + if (\Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY !== $transaction) { + /** + * diger banklaradan farkli olarak 3d islemler icin de Vakifbank bu asamada kredi kart bilgileri istiyor + */ + $pos->payment($card); + } else { + $pos->payment(); + } +} + +$testCards = [ + 'visa1' => [ + // NOTE: 3D Secure sifre 123456 + 'number' => '4938460158754205', + 'year' => '24', + 'month' => '11', + 'cvv' => '715', + 'name' => 'John Doe', + 'type' => AbstractCreditCard::CARD_TYPE_VISA, + ], +]; diff --git a/examples/vakifbank-cp/index.php b/examples/vakifbank-cp/index.php new file mode 100644 index 00000000..28334452 --- /dev/null +++ b/examples/vakifbank-cp/index.php @@ -0,0 +1,6 @@ + $session->get('ref_ret_num'), //ReferenceTransactionId + 'ip' => $request->getClientIp(), +]; +$transaction = AbstractGateway::TX_CANCEL; +$pos->prepare($order, $transaction); + +// Cancel Order +$pos->cancel(); + +$response = $pos->getResponse(); + +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/vakifbank-cp/regular/form.php b/examples/vakifbank-cp/regular/form.php new file mode 100644 index 00000000..2d74d020 --- /dev/null +++ b/examples/vakifbank-cp/regular/form.php @@ -0,0 +1,3 @@ +get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); + +$order = [ + 'id' => $order['id'], + 'amount' => $order['amount'], + 'currency' => $order['currency'], + 'ip' => $order['ip'], +]; + +$session->set('post_order', $order); +$transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; +$card = null; + +require '../../_templates/_payment_response.php'; diff --git a/examples/vakifbank-cp/regular/refund.php b/examples/vakifbank-cp/regular/refund.php new file mode 100644 index 00000000..83d794b2 --- /dev/null +++ b/examples/vakifbank-cp/regular/refund.php @@ -0,0 +1,23 @@ +get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +// Refund Order +$order = [ + 'id' => $order['id'], //ReferenceTransactionId + 'amount' => $order['amount'], + 'ip' => $order['ip'], +]; +$transaction = AbstractGateway::TX_REFUND; +$pos->prepare($order, $transaction); + +$pos->refund(); + +$response = $pos->getResponse(); +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/vakifbank/3d/response.php b/examples/vakifbank/3d/response.php index d85e7523..5288543c 100644 --- a/examples/vakifbank/3d/response.php +++ b/examples/vakifbank/3d/response.php @@ -5,4 +5,4 @@ $savedCard = $session->get('card'); $card = createCard($pos, $savedCard); -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/vakifbank/_payment_config.php b/examples/vakifbank/_payment_config.php index be2c4a50..dd891908 100644 --- a/examples/vakifbank/_payment_config.php +++ b/examples/vakifbank/_payment_config.php @@ -76,10 +76,11 @@ function doPayment(\Mews\Pos\PosInterface $pos, string $transaction, ?\Mews\Pos\ $testCards = [ 'visa1' => [ - 'number' => '4543600299100712', - 'year' => '23', + // NOTE: 3D Secure sifre 123456 + 'number' => '4938460158754205', + 'year' => '24', 'month' => '11', - 'cvv' => '454', + 'cvv' => '715', 'name' => 'John Doe', 'type' => AbstractCreditCard::CARD_TYPE_VISA, ], diff --git a/examples/vakifbank/index.php b/examples/vakifbank/index.php index 235791dc..b5f50122 100644 --- a/examples/vakifbank/index.php +++ b/examples/vakifbank/index.php @@ -1,6 +1,6 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +require '../../_templates/_header.php'; $order = [ - 'id' => $order['id'], //ReferenceTransactionId - 'ip' => $order['ip'], + 'id' => $session->get('ref_ret_num'), //ReferenceTransactionId + 'ip' => $request->getClientIp(), ]; $transaction = AbstractGateway::TX_CANCEL; $pos->prepare($order, $transaction); @@ -20,5 +18,5 @@ $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/vakifbank/regular/post-auth.php b/examples/vakifbank/regular/post-auth.php index 1e6998cb..aa052295 100644 --- a/examples/vakifbank/regular/post-auth.php +++ b/examples/vakifbank/regular/post-auth.php @@ -4,7 +4,7 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $order['id'], @@ -17,4 +17,4 @@ $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/vakifbank/regular/refund.php b/examples/vakifbank/regular/refund.php index f84ecc96..1268afa9 100644 --- a/examples/vakifbank/regular/refund.php +++ b/examples/vakifbank/regular/refund.php @@ -4,14 +4,14 @@ require '_config.php'; $templateTitle = 'Refund Order'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); // Refund Order $order = [ - 'id' => $order['id'], //ReferenceTransactionId + 'id' => $session->get('ref_ret_num'), //ReferenceTransactionId + 'ip' => $request->getClientIp(), 'amount' => $order['amount'], - 'ip' => $order['ip'], ]; $transaction = AbstractGateway::TX_REFUND; $pos->prepare($order, $transaction); @@ -19,5 +19,5 @@ $pos->refund(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/ykb/3d/response.php b/examples/ykb/3d/response.php index 3b26165b..04d1c82f 100644 --- a/examples/ykb/3d/response.php +++ b/examples/ykb/3d/response.php @@ -1,4 +1,4 @@ get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -25,5 +25,5 @@ $pos->cancel(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/ykb/regular/post-auth.php b/examples/ykb/regular/post-auth.php index a343dacf..97113795 100644 --- a/examples/ykb/regular/post-auth.php +++ b/examples/ykb/regular/post-auth.php @@ -4,7 +4,7 @@ $templateTitle = 'Post Auth Order (ön provizyonu tamamlama)'; -$order = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$order = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $order['id'], @@ -18,4 +18,4 @@ $transaction = \Mews\Pos\Gateways\AbstractGateway::TX_POST_PAY; $card = null; -require '../../template/_payment_response.php'; +require '../../_templates/_payment_response.php'; diff --git a/examples/ykb/regular/refund.php b/examples/ykb/regular/refund.php index 0057c14d..aca4c3be 100644 --- a/examples/ykb/regular/refund.php +++ b/examples/ykb/regular/refund.php @@ -4,9 +4,9 @@ require '_config.php'; $templateTitle = 'Refund Order'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $transaction = AbstractGateway::TX_REFUND; $pos->prepare([ @@ -19,5 +19,5 @@ $pos->refund(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/examples/ykb/regular/status.php b/examples/ykb/regular/status.php index 247bf8ed..e26ed876 100644 --- a/examples/ykb/regular/status.php +++ b/examples/ykb/regular/status.php @@ -4,9 +4,9 @@ require '_config.php'; $templateTitle = 'Order Status'; -require '../../template/_header.php'; +require '../../_templates/_header.php'; -$ord = $session->get('order') ? $session->get('order') : getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); +$ord = $session->get('order') ?: getNewOrder($baseUrl, $ip, $request->get('currency', 'TRY'), $session); $order = [ 'id' => $ord['id'], @@ -18,5 +18,5 @@ $pos->status(); $response = $pos->getResponse(); -require '../../template/_simple_response_dump.php'; -require '../../template/_footer.php'; +require '../../_templates/_simple_response_dump.php'; +require '../../_templates/_footer.php'; diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 2f8c087c..355d5eb3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15,21 +15,11 @@ parameters: count: 2 path: src/Crypt/KuveytPosCrypt.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:__construct\\(\\) has parameter \\$currencyMappings with no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/AbstractRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:create3DFormData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/AbstractRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/AbstractRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -110,26 +100,11 @@ parameters: count: 1 path: src/DataMapper/AbstractRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:getCurrencyMappings\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/AbstractRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:getLang\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/AbstractRequestDataMapper.php - - - message: "#^Property Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:\\$currencyMappings type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/AbstractRequestDataMapper.php - - - - message: "#^Property Mews\\\\Pos\\\\DataMapper\\\\AbstractRequestDataMapper\\:\\:\\$langMappings has no type specified\\.$#" - count: 1 - path: src/DataMapper/AbstractRequestDataMapper.php - - message: "#^Access to an undefined property object\\:\\:\\$id\\.$#" count: 2 @@ -155,31 +130,16 @@ parameters: count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DFormDataCommon\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DFormDataCommon\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$responseData with no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -210,31 +170,16 @@ parameters: count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createNonSecurePaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -250,26 +195,11 @@ parameters: count: 1 path: src/DataMapper/EstPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:getRecurringRequestOrderData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstPosRequestDataMapper\\:\\:getRequestAccountData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstV3PosRequestDataMapper\\:\\:create3DFormData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/EstV3PosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\EstV3PosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/EstV3PosRequestDataMapper.php - - message: "#^Access to an undefined property object\\:\\:\\$amount\\.$#" count: 2 @@ -310,11 +240,6 @@ parameters: count: 1 path: src/DataMapper/GarantiPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/GarantiPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -375,11 +300,6 @@ parameters: count: 1 path: src/DataMapper/GarantiPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:createRecurringData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/GarantiPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -410,16 +330,6 @@ parameters: count: 1 path: src/DataMapper/GarantiPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:getOrderAddressData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/GarantiPosRequestDataMapper.php - - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:getTerminalData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/GarantiPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\GarantiPosRequestDataMapper\\:\\:mapPaymentOrder\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -445,31 +355,16 @@ parameters: count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$responseData with no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createCancelRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) has parameter \\$extraData with no value type specified in iterable type array\\.$#" count: 1 @@ -500,36 +395,16 @@ parameters: count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/InterPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:getRequestAccountData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/InterPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:create3DEnrollmentCheckRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -545,11 +420,6 @@ parameters: count: 1 path: src/DataMapper/KuveytPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/KuveytPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -560,11 +430,6 @@ parameters: count: 1 path: src/DataMapper/KuveytPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/KuveytPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:createCancelRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -625,16 +490,6 @@ parameters: count: 1 path: src/DataMapper/KuveytPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:getRequestAccountData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/KuveytPosRequestDataMapper.php - - - - message: "#^Property Mews\\\\Pos\\\\DataMapper\\\\KuveytPosRequestDataMapper\\:\\:\\$currencyMappings type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/KuveytPosRequestDataMapper.php - - message: "#^Access to an undefined property object\\:\\:\\$currency\\.$#" count: 1 @@ -675,11 +530,6 @@ parameters: count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -690,16 +540,6 @@ parameters: count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createCancelRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) has parameter \\$extraData with no value type specified in iterable type array\\.$#" count: 1 @@ -720,46 +560,21 @@ parameters: count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createNonSecurePaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/PayForPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:getRequestAccountData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PayForPosRequestDataMapper.php - - message: "#^Access to an undefined property object\\:\\:\\$id\\.$#" count: 1 @@ -830,11 +645,6 @@ parameters: count: 1 path: src/DataMapper/PosNetRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PosNetRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PosNetRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\PosNetRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -925,11 +735,6 @@ parameters: count: 1 path: src/DataMapper/PosNetRequestDataMapper.php - - - message: "#^Property Mews\\\\Pos\\\\DataMapper\\\\PosNetRequestDataMapper\\:\\:\\$currencyMappings type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/PosNetRequestDataMapper.php - - message: "#^Argument of an invalid type array\\|object supplied for foreach, only iterables are supported\\.$#" count: 1 @@ -971,14 +776,104 @@ parameters: path: src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\VakifBankPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) should return array\\ but returns array\\\\|float\\|string\\|null\\>\\.$#" + message: "#^Access to an undefined property object\\:\\:\\$amount\\.$#" + count: 2 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Access to an undefined property object\\:\\:\\$currency\\.$#" + count: 2 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Access to an undefined property object\\:\\:\\$fail_url\\.$#" count: 1 - path: src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Access to an undefined property object\\:\\:\\$id\\.$#" + count: 2 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\VakifBankPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) should return array\\ but returns array\\\\|string\\|null\\>\\.$#" + message: "#^Access to an undefined property object\\:\\:\\$installment\\.$#" count: 1 - path: src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Access to an undefined property object\\:\\:\\$ip\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Access to an undefined property object\\:\\:\\$success_url\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Default value of the parameter \\#6 \\$extraData \\(array\\{\\}\\) of method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DFormData\\(\\) is incompatible with type array\\{CommonPaymentUrl\\: string, PaymentToken\\: string\\}\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DFormData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$responseData with no value type specified in iterable type array\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) has parameter \\$extraData with no value type specified in iterable type array\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createNonSecurePaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) has parameter \\$order with no type specified\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php + + - + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/DataMapper/VakifBankCPPosRequestDataMapper.php - message: "#^Access to an undefined property object\\:\\:\\$amount\\.$#" @@ -1051,12 +946,12 @@ parameters: path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DEnrollmentCheckRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" + message: "#^Default value of the parameter \\#6 \\$extraData \\(array\\{\\}\\) of method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DFormData\\(\\) is incompatible with type array\\{PaReq\\: string, TermUrl\\: string, MD\\: string, ACSUrl\\: string\\}\\.$#" count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DFormData\\(\\) has parameter \\$extraData with no value type specified in iterable type array\\.$#" + message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DEnrollmentCheckRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php @@ -1065,31 +960,16 @@ parameters: count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) has parameter \\$responseData with no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:create3DPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createCancelRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createHistoryRequestData\\(\\) has parameter \\$extraData with no value type specified in iterable type array\\.$#" count: 1 @@ -1120,21 +1000,11 @@ parameters: count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createNonSecurePostAuthPaymentRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createRefundRequestData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:createStatusRequestData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 @@ -1145,11 +1015,6 @@ parameters: count: 1 path: src/DataMapper/VakifBankPosRequestDataMapper.php - - - message: "#^Method Mews\\\\Pos\\\\DataMapper\\\\VakifBankPosRequestDataMapper\\:\\:getRequestAccountData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/DataMapper/VakifBankPosRequestDataMapper.php - - message: "#^Property Mews\\\\Pos\\\\Entity\\\\Account\\\\GarantiPosAccount\\:\\:\\$refundPassword \\(string\\) does not accept string\\|null\\.$#" count: 1 @@ -1210,11 +1075,6 @@ parameters: count: 1 path: src/Factory/PosFactory.php - - - message: "#^Method Mews\\\\Pos\\\\Factory\\\\PosFactory\\:\\:getGatewayRequestMapper\\(\\) has parameter \\$currencies with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Factory/PosFactory.php - - message: "#^Access to undefined constant Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\NonPaymentResponseMapperInterface&Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\PaymentResponseMapperInterface\\:\\:TX_APPROVED\\.$#" count: 1 @@ -1280,21 +1140,11 @@ parameters: count: 1 path: src/Gateways/AbstractGateway.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\AbstractGateway\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/AbstractGateway.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\AbstractGateway\\:\\:getConfig\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: src/Gateways/AbstractGateway.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\AbstractGateway\\:\\:getCurrencies\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/AbstractGateway.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\AbstractGateway\\:\\:getOrder\\(\\) should return object but returns object\\|null\\.$#" count: 1 @@ -1440,11 +1290,6 @@ parameters: count: 1 path: src/Gateways/EstPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\EstPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/EstPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\EstPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" count: 1 @@ -1500,11 +1345,6 @@ parameters: count: 1 path: src/Gateways/EstPos.php - - - message: "#^Parameter \\#2 \\$payload of method Mews\\\\Pos\\\\Client\\\\HttpClient\\:\\:post\\(\\) expects array\\{body\\?\\: array\\, headers\\?\\: array\\, form_params\\?\\: array\\\\}\\|null, array\\{body\\: array\\|string\\} given\\.$#" - count: 1 - path: src/Gateways/EstPos.php - - message: "#^Parameter \\#2 \\$rawPaymentResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\PaymentResponseMapperInterface\\:\\:map3DPaymentData\\(\\) expects array\\\\|null, array\\|string\\|null given\\.$#" count: 1 @@ -1560,11 +1400,6 @@ parameters: count: 1 path: src/Gateways/GarantiPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\GarantiPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/GarantiPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\GarantiPos\\:\\:prepareCancelOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" count: 1 @@ -1605,11 +1440,6 @@ parameters: count: 1 path: src/Gateways/GarantiPos.php - - - message: "#^Parameter \\#2 \\$payload of method Mews\\\\Pos\\\\Client\\\\HttpClient\\:\\:post\\(\\) expects array\\{body\\?\\: array\\, headers\\?\\: array\\, form_params\\?\\: array\\\\}\\|null, array\\{body\\: array\\|string\\} given\\.$#" - count: 1 - path: src/Gateways/GarantiPos.php - - message: "#^Parameter \\#2 \\$rawPaymentResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\GarantiPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) expects array\\{Order\\: array\\\\|string\\>, Response\\: array\\, Transaction\\: array\\\\|string\\>\\}\\|null, array\\|string\\|null given\\.$#" count: 1 @@ -1625,11 +1455,6 @@ parameters: count: 1 path: src/Gateways/InterPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createCancelXML\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createHistoryXML\\(\\) has parameter \\$customQueryData with no value type specified in iterable type array\\.$#" count: 1 @@ -1640,31 +1465,11 @@ parameters: count: 1 path: src/Gateways/InterPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createRefundXML\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createRegularPaymentXML\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: src/Gateways/InterPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createRegularPostXML\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:createStatusXML\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\InterPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" count: 1 @@ -1715,21 +1520,11 @@ parameters: count: 1 path: src/Gateways/InterPos.php - - - message: "#^Parameter \\#2 \\$payload of method Mews\\\\Pos\\\\Client\\\\HttpClient\\:\\:post\\(\\) expects array\\{body\\?\\: array\\, headers\\?\\: array\\, form_params\\?\\: array\\\\}\\|null, array\\{form_params\\: array\\|string\\} given\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - message: "#^Parameter \\#2 \\$rawPaymentResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\InterPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) expects array\\\\|null, array\\|string\\|null given\\.$#" count: 1 path: src/Gateways/InterPos.php - - - message: "#^Parameter \\#4 \\$gatewayURL of method Mews\\\\Pos\\\\DataMapper\\\\InterPosRequestDataMapper\\:\\:create3DFormData\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/Gateways/InterPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:builtInputsFromHTMLDoc\\(\\) has parameter \\$inputNodes with generic class DOMNodeList but does not specify its types\\: TNode$#" count: 1 @@ -1780,21 +1575,11 @@ parameters: count: 1 path: src/Gateways/KuveytPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/KuveytPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:getCommon3DFormData\\(\\) has parameter \\$order with no type specified\\.$#" count: 1 path: src/Gateways/KuveytPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:getCommon3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/KuveytPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" count: 1 @@ -1840,11 +1625,6 @@ parameters: count: 1 path: src/Gateways/KuveytPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:transformReceived3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/KuveytPos.php - - message: "#^PHPDoc type Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\KuveytPosResponseDataMapper of property Mews\\\\Pos\\\\Gateways\\\\KuveytPos\\:\\:\\$responseDataMapper is not covariant with PHPDoc type Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\NonPaymentResponseMapperInterface&Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\PaymentResponseMapperInterface of overridden property Mews\\\\Pos\\\\Gateways\\\\AbstractGateway\\:\\:\\$responseDataMapper\\.$#" count: 1 @@ -1855,11 +1635,6 @@ parameters: count: 1 path: src/Gateways/KuveytPos.php - - - message: "#^Parameter \\#2 \\$payload of method Mews\\\\Pos\\\\Client\\\\HttpClient\\:\\:post\\(\\) expects array\\{body\\?\\: array\\, headers\\?\\: array\\, form_params\\?\\: array\\\\}\\|null, array\\{body\\: array\\|string, headers\\: array\\{Content\\-Type\\: 'text/xml; charset…'\\}\\} given\\.$#" - count: 1 - path: src/Gateways/KuveytPos.php - - message: "#^Parameter \\#2 \\$rawPaymentResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\KuveytPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) expects array\\\\|null, array\\|string\\|null given\\.$#" count: 1 @@ -1910,11 +1685,6 @@ parameters: count: 1 path: src/Gateways/PayForPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\PayForPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/PayForPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\PayForPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" count: 1 @@ -1975,21 +1745,11 @@ parameters: count: 1 path: src/Gateways/PayForPos.php - - - message: "#^Parameter \\#2 \\$payload of method Mews\\\\Pos\\\\Client\\\\HttpClient\\:\\:post\\(\\) expects array\\{body\\?\\: array\\, headers\\?\\: array\\, form_params\\?\\: array\\\\}\\|null, array\\{headers\\: array\\{Content\\-Type\\: 'text/xml; charset…'\\}, body\\: array\\|string\\} given\\.$#" - count: 1 - path: src/Gateways/PayForPos.php - - message: "#^Parameter \\#2 \\$rawPaymentResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\PayForPosResponseDataMapper\\:\\:map3DPaymentData\\(\\) expects array\\\\|null, array\\|string\\|null given\\.$#" count: 1 path: src/Gateways/PayForPos.php - - - message: "#^Parameter \\#4 \\$gatewayURL of method Mews\\\\Pos\\\\DataMapper\\\\PayForPosRequestDataMapper\\:\\:create3DFormData\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/Gateways/PayForPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\PosNet\\:\\:create3DPaymentXML\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -2035,11 +1795,6 @@ parameters: count: 1 path: src/Gateways/PosNet.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\PosNet\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/PosNet.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\PosNet\\:\\:getOosTransactionData\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -2121,9 +1876,109 @@ parameters: path: src/Gateways/PosNet.php - - message: "#^Part \\$contents \\(array\\|string\\) of encapsed string cannot be cast to string\\.$#" + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:create3DPaymentXML\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 - path: src/Gateways/PosNet.php + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createCancelXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createHistoryXML\\(\\) has parameter \\$customQueryData with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createHistoryXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createRefundXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createRegularPaymentXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createRegularPostXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createStatusXML\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:createXML\\(\\) has parameter \\$nodes with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:prepareCancelOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:prepareHistoryOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:preparePaymentOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:preparePostPaymentOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:prepareRefundOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:prepareStatusOrder\\(\\) has parameter \\$order with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:registerPayment\\(\\) should return array\\{CommonPaymentUrl\\: string\\|null, PaymentToken\\: string\\|null, ErrorCode\\: string\\|null, ResponseMessage\\: string\\|null\\} but returns array\\|string\\|null\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:send\\(\\) has parameter \\$contents with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankCPPos\\:\\:send\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Parameter \\#1 \\$raw3DAuthResponseData of method Mews\\\\Pos\\\\DataMapper\\\\ResponseDataMapper\\\\VakifBankCPPosResponseDataMapper\\:\\:map3DPayResponseData\\(\\) expects array\\{ErrorCode\\: string\\}\\|array\\{Rc\\: string, AuthCode\\: string, TransactionId\\: string, PaymentToken\\: string, MaskedPan\\: string\\}\\|array\\{Rc\\: string, Message\\: string, TransactionId\\: string, PaymentToken\\: string\\}, array given\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php + + - + message: "#^Parameter \\#6 \\$extraData of method Mews\\\\Pos\\\\DataMapper\\\\VakifBankCPPosRequestDataMapper\\:\\:create3DFormData\\(\\) expects array\\{CommonPaymentUrl\\: string, PaymentToken\\: string\\}, array\\{CommonPaymentUrl\\: string\\|null, PaymentToken\\: string\\|null, ErrorCode\\: null, ResponseMessage\\: string\\|null\\} given\\.$#" + count: 1 + path: src/Gateways/VakifBankCPPos.php - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankPos\\:\\:create3DPaymentXML\\(\\) return type has no value type specified in iterable type array\\.$#" @@ -2170,11 +2025,6 @@ parameters: count: 1 path: src/Gateways/VakifBankPos.php - - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankPos\\:\\:get3DFormData\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Gateways/VakifBankPos.php - - message: "#^Method Mews\\\\Pos\\\\Gateways\\\\VakifBankPos\\:\\:history\\(\\) has parameter \\$meta with no value type specified in iterable type array\\.$#" count: 1 diff --git a/rector.php b/rector.php new file mode 100644 index 00000000..06bdc485 --- /dev/null +++ b/rector.php @@ -0,0 +1,48 @@ +paths([ + __DIR__.'/config', + __DIR__.'/src', + __DIR__.'/tests', + ]); + + $rectorConfig->sets([ + SetList::CODE_QUALITY, + SetList::CODING_STYLE, + SetList::EARLY_RETURN, + SetList::DEAD_CODE, + SetList::PSR_4, + LevelSetList::UP_TO_PHP_72, + ]); + + $rectorConfig->rules([ + \Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector::class, + \Rector\CodingStyle\Rector\ClassMethod\DataProviderArrayItemsNewlinedRector::class, + \Rector\TypeDeclaration\Rector\ClassMethod\ArrayShapeFromConstantArrayReturnRector::class, + ]); + + $rectorConfig->skip([ + \Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector::class, + \Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector::class, + \Rector\TypeDeclaration\Rector\ClassMethod\ArrayShapeFromConstantArrayReturnRector::class => [ + __DIR__ . '/src/DataMapper/ResponseDataMapper', + ], + ]); + + $rectorConfig->ruleWithConfiguration(\Rector\CodingStyle\Rector\FuncCall\ConsistentPregDelimiterRector::class, [ + \Rector\CodingStyle\Rector\FuncCall\ConsistentPregDelimiterRector::DELIMITER => '/', + ]); + + $rectorConfig->ruleWithConfiguration(\Rector\CodingStyle\Rector\Property\InlineSimplePropertyAnnotationRector::class, [ + 'var', + 'phpstan-var', + 'property', + ]); +}; diff --git a/src/Client/HttpClient.php b/src/Client/HttpClient.php index 647e3d4a..bcb60456 100644 --- a/src/Client/HttpClient.php +++ b/src/Client/HttpClient.php @@ -10,7 +10,7 @@ use function http_build_query; /** - * @phpstan-type PostPayload array{body?: array, headers?: array, form_params?: array} + * @phpstan-type PostPayload array{body?: array|string, headers?: array, form_params?: array} * PSR18 HTTP Client wrapper */ class HttpClient @@ -70,9 +70,11 @@ private function createRequest(string $method, string $url, ?array $payload = [] $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded'); $payload['body'] = http_build_query($payload['form_params']); } + if (isset($payload['body'])) { $body = $this->streamFactory->createStream($payload['body']); } + $request = $request->withBody($body); } diff --git a/src/Crypt/AbstractCrypt.php b/src/Crypt/AbstractCrypt.php index df05a6c2..1ef7dfac 100644 --- a/src/Crypt/AbstractCrypt.php +++ b/src/Crypt/AbstractCrypt.php @@ -6,7 +6,10 @@ abstract class AbstractCrypt implements CryptInterface { + /** @var string */ protected const HASH_ALGORITHM = 'sha1'; + + /** @var string */ protected const HASH_SEPARATOR = ''; /** @var LoggerInterface */ diff --git a/src/Crypt/EstPosCrypt.php b/src/Crypt/EstPosCrypt.php index f2f92a9d..843041b3 100644 --- a/src/Crypt/EstPosCrypt.php +++ b/src/Crypt/EstPosCrypt.php @@ -42,7 +42,7 @@ public function check3DHash(AbstractPosAccount $account, array $data): bool $hashParamsArr = explode(':', $hashParams); foreach ($hashParamsArr as $value) { if (isset($data[$value])) { - $paramsVal = $paramsVal.$data[$value]; + $paramsVal .= $data[$value]; } } diff --git a/src/Crypt/EstV3PosCrypt.php b/src/Crypt/EstV3PosCrypt.php index 584cbf81..c87bb3a0 100644 --- a/src/Crypt/EstV3PosCrypt.php +++ b/src/Crypt/EstV3PosCrypt.php @@ -9,7 +9,10 @@ class EstV3PosCrypt extends AbstractCrypt { + /** @var string */ protected const HASH_ALGORITHM = 'sha512'; + + /** @var string */ protected const HASH_SEPARATOR = '|'; /** @@ -18,16 +21,18 @@ class EstV3PosCrypt extends AbstractCrypt public function create3DHash(AbstractPosAccount $account, array $requestData, ?string $txType = null): string { ksort($requestData, SORT_NATURAL | SORT_FLAG_CASE); - foreach ($requestData as $key => $value) { + foreach (array_keys($requestData) as $key) { // this part is needed only to create hash from the bank response if (in_array(strtolower($key), ['hash', 'encoding'])) { unset($requestData[$key]); } } + $requestData[] = $account->getStoreKey(); // escape | and \ characters $data = str_replace("\\", "\\\\", array_values($requestData)); $data = str_replace(self::HASH_SEPARATOR, "\\".self::HASH_SEPARATOR, $data); + $hashStr = implode(self::HASH_SEPARATOR, $data); return $this->hashString($hashStr); diff --git a/src/Crypt/GarantiPosCrypt.php b/src/Crypt/GarantiPosCrypt.php index 0af6e6e7..74c07779 100644 --- a/src/Crypt/GarantiPosCrypt.php +++ b/src/Crypt/GarantiPosCrypt.php @@ -41,7 +41,7 @@ public function check3DHash(AbstractPosAccount $account, array $data): bool $hashParamsArr = explode(':', $hashParams); foreach ($hashParamsArr as $value) { if (isset($data[$value])) { - $paramsVal = $paramsVal.$data[$value]; + $paramsVal .= $data[$value]; } } @@ -53,6 +53,7 @@ public function check3DHash(AbstractPosAccount $account, array $data): bool return true; } + $this->logger->log(LogLevel::ERROR, 'hash check failed', [ 'data' => $data, 'generated_hash' => $actualHash, @@ -91,11 +92,7 @@ public function createHash(AbstractPosAccount $account, array $requestData, ?str */ private function createSecurityData(AbstractPosAccount $account, ?string $txType = null): string { - if ('void' === $txType || 'refund' === $txType) { - $password = $account->getRefundPassword(); - } else { - $password = $account->getPassword(); - } + $password = 'void' === $txType || 'refund' === $txType ? $account->getRefundPassword() : $account->getPassword(); $map = [ $password, diff --git a/src/Crypt/PosNetCrypt.php b/src/Crypt/PosNetCrypt.php index cf00289f..5d812a8b 100644 --- a/src/Crypt/PosNetCrypt.php +++ b/src/Crypt/PosNetCrypt.php @@ -11,7 +11,10 @@ class PosNetCrypt extends AbstractCrypt { + /** @var string */ protected const HASH_ALGORITHM = 'sha256'; + + /** @var string */ protected const HASH_SEPARATOR = ';'; /** diff --git a/src/Crypt/VakifBankCPCrypt.php b/src/Crypt/VakifBankCPCrypt.php new file mode 100644 index 00000000..e9469a9d --- /dev/null +++ b/src/Crypt/VakifBankCPCrypt.php @@ -0,0 +1,47 @@ + "5029" + * "ResponseMessage" => "Geçersiz İstek" hash ile istek gonderince hatasi aliyoruz. + * + * {@inheritDoc} + */ + public function create3DHash(AbstractPosAccount $account, array $requestData, ?string $txType = null): string + { + $hashData = [ + $account->getClientId(), + $requestData['currency'], + $requestData['amount'], + $account->getPassword(), + '', + 'VBank3DPay2014', // todo + ]; + + $hashStr = implode(static::HASH_SEPARATOR, $hashData); + + return ''; + //return $this->hashString($hashStr); + } + + /** + * todo implement + * {@inheritdoc} + */ + public function check3DHash(AbstractPosAccount $account, array $data): bool + { + return true; + } + + public function createHash(AbstractPosAccount $account, array $requestData, ?string $txType = null, ?AbstractCreditCard $card = null): string + { + throw new NotImplementedException(); + } +} diff --git a/src/DataMapper/AbstractRequestDataMapper.php b/src/DataMapper/AbstractRequestDataMapper.php index e9d3285e..1eb46070 100644 --- a/src/DataMapper/AbstractRequestDataMapper.php +++ b/src/DataMapper/AbstractRequestDataMapper.php @@ -15,9 +15,7 @@ */ abstract class AbstractRequestDataMapper { - /** - * @var array - */ + /** @var array */ protected $secureTypeMappings = []; /** @@ -30,6 +28,7 @@ abstract class AbstractRequestDataMapper /** @var array */ protected $cardTypeMapping = []; + /** @var array */ protected $langMappings = [ AbstractGateway::LANG_TR => 'tr', AbstractGateway::LANG_EN => 'en', @@ -40,15 +39,15 @@ abstract class AbstractRequestDataMapper * fakat bazi banklar ISO standarti kullanmiyorlar. * Currency mapping * - * @var array + * @var non-empty-array */ protected $currencyMappings = [ - 'TRY' => 949, - 'USD' => 840, - 'EUR' => 978, - 'GBP' => 826, - 'JPY' => 392, - 'RUB' => 643, + 'TRY' => '949', + 'USD' => '840', + 'EUR' => '978', + 'GBP' => '826', + 'JPY' => '392', + 'RUB' => '643', ]; /** @@ -64,13 +63,13 @@ abstract class AbstractRequestDataMapper protected $crypt; /** - * @param CryptInterface|null $crypt - * @param array $currencyMappings + * @param CryptInterface|null $crypt + * @param array $currencyMappings */ public function __construct(?CryptInterface $crypt = null, array $currencyMappings = []) { $this->crypt = $crypt; - if (count($currencyMappings) > 0) { + if ($currencyMappings !== []) { $this->currencyMappings = $currencyMappings; } } @@ -139,7 +138,7 @@ abstract public function createRefundRequestData(AbstractPosAccount $account, $o * @param string $txType * @param AbstractCreditCard|null $card * - * @return array + * @return array{gateway: string, method: 'POST'|'GET', inputs: array} */ abstract public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array; @@ -203,7 +202,7 @@ public function getTxTypeMappings(): array } /** - * @return array + * @return non-empty-array */ public function getCurrencyMappings(): array { @@ -267,12 +266,7 @@ public function getRecurringOrderFrequencyMapping(): array return $this->recurringOrderFrequencyMapping; } - /** - * @param int|null $installment - * - * @return int|string - */ - abstract public function mapInstallment(?int $installment); + abstract public function mapInstallment(?int $installment): string; /** * bank returns error messages for specified language value diff --git a/src/DataMapper/EstPosRequestDataMapper.php b/src/DataMapper/EstPosRequestDataMapper.php index 85d0e4cb..122b6c17 100644 --- a/src/DataMapper/EstPosRequestDataMapper.php +++ b/src/DataMapper/EstPosRequestDataMapper.php @@ -13,8 +13,13 @@ */ class EstPosRequestDataMapper extends AbstractRequestDataMapperCrypt { + /** @var string */ public const CREDIT_CARD_EXP_DATE_FORMAT = 'm/y'; + + /** @var string */ public const CREDIT_CARD_EXP_MONTH_FORMAT = 'm'; + + /** @var string */ public const CREDIT_CARD_EXP_YEAR_FORMAT = 'y'; /** @@ -61,16 +66,18 @@ class EstPosRequestDataMapper extends AbstractRequestDataMapperCrypt /** * {@inheritDoc} + * + * @param array{md: string, xid: string, eci: string, cavv: string} $responseData */ 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, + 'IPAddress' => (string) ($order->ip ?? ''), + 'Email' => (string) $order->email, + 'OrderId' => (string) $order->id, + 'UserId' => (string) ($order->user_id ?? ''), + 'Total' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'Taksit' => $this->mapInstallment($order->installment), 'Number' => $responseData['md'], @@ -82,7 +89,7 @@ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, if ($order->name) { $requestData['BillTo'] = [ - 'Name' => $order->name, + 'Name' => (string) $order->name, ]; } @@ -95,16 +102,17 @@ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, /** * {@inheritDoc} + * @return array{PbOrder?: array{OrderType: string, OrderFrequencyInterval: string, OrderFrequencyCycle: string, TotalNumberPayments: string}, Type: string, IPAddress: mixed, Email: mixed, OrderId: mixed, UserId: mixed, Total: mixed, Currency: string, Taksit: string, Number: string, Expires: string, Cvv2Val: string, Mode: string, BillTo: array{Name: mixed}, Name: string, Password: string, ClientId: string} */ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): 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, + 'IPAddress' => (string) ($order->ip ?? ''), + 'Email' => (string) $order->email, + 'OrderId' => (string) $order->id, + 'UserId' => (string) ($order->user_id ?? ''), + 'Total' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'Taksit' => $this->mapInstallment($order->installment), 'Number' => $card->getNumber(), @@ -112,7 +120,7 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ 'Cvv2Val' => $card->getCvv(), 'Mode' => 'P', 'BillTo' => [ - 'Name' => $order->name ?: null, + 'Name' => (string) ($order->name ?? ''), ], ]; @@ -125,12 +133,14 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ /** * {@inheritDoc} + * + * @return array{Type: string, OrderId: string, Name: string, Password: string, ClientId: string} */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { return $this->getRequestAccountData($account) + [ 'Type' => $this->mapTxType(AbstractGateway::TX_POST_PAY), - 'OrderId' => $order->id, + 'OrderId' => (string) $order->id, ]; } @@ -147,7 +157,7 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar if (isset($order->id)) { $statusRequestData['OrderId'] = $order->id; - } else if (isset($order->recurringId)) { + } elseif (isset($order->recurringId)) { $statusRequestData['Extra']['RECURRINGID'] = $order->recurringId; } @@ -159,6 +169,7 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar */ public function createCancelRequestData(AbstractPosAccount $account, $order): array { + $orderData = []; if (isset($order->recurringOrderInstallmentNumber)) { // this method cancels only pending recurring orders, it will not cancel already fulfilled transactions $orderData['Extra']['RECORDTYPE'] = 'Order'; @@ -184,17 +195,18 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{OrderId: string, Currency: string, Type: string, Total?: string, Name: string, Password: string, ClientId: string} */ public function createRefundRequestData(AbstractPosAccount $account, $order): array { $requestData = [ - 'OrderId' => $order->id, + 'OrderId' => (string) $order->id, 'Currency' => $this->mapCurrency($order->currency), 'Type' => $this->mapTxType(AbstractGateway::TX_REFUND), ]; if (isset($order->amount)) { - $requestData['Total'] = $order->amount; + $requestData['Total'] = (string) $order->amount; } return $this->getRequestAccountData($account) + $requestData; @@ -206,7 +218,7 @@ public function createRefundRequestData(AbstractPosAccount $account, $order): ar 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 + 'OrderId' => (string) $extraData['order_id'], //todo orderId ya da id olarak degistirilecek, Payfor'da orderId, Garanti'de id 'Extra' => [ $this->mapTxType(AbstractGateway::TX_HISTORY) => 'QUERY', ], @@ -222,7 +234,6 @@ public function createHistoryRequestData(AbstractPosAccount $account, $order, ar public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array { $data = $this->create3DFormDataCommon($account, $order, $txType, $gatewayURL, $card); - unset($data['inputs']['hash']); $orderMapped = clone $order; $orderMapped->installment = $this->mapInstallment($order->installment); @@ -234,6 +245,8 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx /** * @param AbstractGateway::TX_* $txType + * + * @return array{gateway: string, method: 'POST', inputs: array} */ public function create3DFormDataCommon(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array { @@ -255,7 +268,7 @@ public function create3DFormDataCommon(AbstractPosAccount $account, $order, stri // todo add custom data dynamically instead of hard coding them ]; - if ($card) { + if ($card !== null) { $inputs['cardType'] = $this->cardTypeMapping[$card->getType()]; $inputs['pan'] = $card->getNumber(); $inputs['Ecom_Payment_Card_ExpDate_Month'] = $card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); @@ -265,22 +278,20 @@ public function create3DFormDataCommon(AbstractPosAccount $account, $order, stri return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : ''; + return $installment > 1 ? (string) $installment : ''; } /** * @param AbstractPosAccount $account * - * @return array + * @return array{Name: string, Password: string, ClientId: string} */ private function getRequestAccountData(AbstractPosAccount $account): array { @@ -291,16 +302,19 @@ private function getRequestAccountData(AbstractPosAccount $account): array ]; } + /** + * @return array{PbOrder: array{OrderType: string, OrderFrequencyInterval: string, OrderFrequencyCycle: string, TotalNumberPayments: string}} + */ private function getRecurringRequestOrderData($order): array { return [ 'PbOrder' => [ - 'OrderType' => 0, + 'OrderType' => '0', // Periyodik İşlem Frekansı - 'OrderFrequencyInterval' => $order->recurringFrequency, + 'OrderFrequencyInterval' => (string) $order->recurringFrequency, //D|M|Y 'OrderFrequencyCycle' => $this->mapRecurringFrequency($order->recurringFrequencyType), - 'TotalNumberPayments' => $order->recurringInstallmentCount, + 'TotalNumberPayments' => (string) $order->recurringInstallmentCount, ], ]; } diff --git a/src/DataMapper/EstV3PosRequestDataMapper.php b/src/DataMapper/EstV3PosRequestDataMapper.php index e36d3280..8e5a6834 100644 --- a/src/DataMapper/EstV3PosRequestDataMapper.php +++ b/src/DataMapper/EstV3PosRequestDataMapper.php @@ -12,12 +12,14 @@ */ class EstV3PosRequestDataMapper extends EstPosRequestDataMapper { + /** + * {@inheritDoc} + */ public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array { $data = $this->create3DFormDataCommon($account, $order, $txType, $gatewayURL, $card); $data['inputs']['hashAlgorithm'] = 'ver3'; - unset($data['inputs']['hash']); $data['inputs']['hash'] = $this->crypt->create3DHash($account, $data['inputs'], $txType); return $data; diff --git a/src/DataMapper/GarantiPosRequestDataMapper.php b/src/DataMapper/GarantiPosRequestDataMapper.php index ca6d8d1e..8219fc49 100644 --- a/src/DataMapper/GarantiPosRequestDataMapper.php +++ b/src/DataMapper/GarantiPosRequestDataMapper.php @@ -16,12 +16,21 @@ */ class GarantiPosRequestDataMapper extends AbstractRequestDataMapperCrypt { + /** @var string */ public const API_VERSION = 'v0.01'; + /** @var string */ public const CREDIT_CARD_EXP_DATE_FORMAT = 'my'; + + /** @var string */ public const CREDIT_CARD_EXP_MONTH_FORMAT = 'm'; + + /** @var string */ public const CREDIT_CARD_EXP_YEAR_FORMAT = 'y'; + /** @var string */ + private const MOTO = 'N'; + /** * {@inheritDoc} */ @@ -43,8 +52,6 @@ class GarantiPosRequestDataMapper extends AbstractRequestDataMapperCrypt AbstractGateway::TX_STATUS => 'orderinq', ]; - private const MOTO = 'N'; - protected $recurringOrderFrequencyMapping = [ 'DAY' => 'D', 'WEEK' => 'W', @@ -153,7 +160,7 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { $hashData = [ - 'id' => $order->id, + 'id' => (string) $order->id, 'amount' => self::amountFormat($order->amount), ]; $hash = $this->crypt->createHash($account, $hashData, $this->mapTxType(AbstractGateway::TX_POST_PAY), $card); @@ -350,7 +357,7 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx $inputs['secure3dhash'] = $this->crypt->create3DHash($account, $mappedOrder, $this->mapTxType($txType)); - if ($card) { + if ($card !== null) { $inputs['cardnumber'] = $card->getNumber(); $inputs['cardexpiredatemonth'] = $card->getExpireMonth(self::CREDIT_CARD_EXP_MONTH_FORMAT); $inputs['cardexpiredateyear'] = $card->getExpireYear(self::CREDIT_CARD_EXP_YEAR_FORMAT); @@ -359,16 +366,14 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : ''; + return $installment > 1 ? (string) $installment : ''; } /** @@ -380,7 +385,7 @@ public function mapInstallment(?int $installment) */ public static function amountFormat($amount): int { - return intval(round($amount, 2) * 100); + return (int) (round($amount, 2) * 100); } /** @@ -388,7 +393,7 @@ public static function amountFormat($amount): int */ private function getMode(): string { - return !$this->isTestMode() ? 'PROD' : 'TEST'; + return $this->isTestMode() ? 'TEST' : 'PROD'; } /** @@ -396,7 +401,7 @@ private function getMode(): string * @param string $hash * @param bool $isRefund * - * @return array + * @return array{ProvUserID: string, UserID: string, HashData: string, ID: string, MerchantID: string} */ private function getTerminalData(AbstractPosAccount $account, string $hash, bool $isRefund = false): array { @@ -416,7 +421,7 @@ private function getTerminalData(AbstractPosAccount $account, string $hash, bool */ private function getCardData(?AbstractCreditCard $card = null): array { - if ($card) { + if ($card !== null) { return [ 'Number' => $card->getNumber(), 'ExpireDate' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT), @@ -434,14 +439,14 @@ private function getCardData(?AbstractCreditCard $card = null): array /** * @param $order * - * @return array + * @return array{Address: array{Type: string, Name: string, LastName: string, Company: string, Text: string, District: string, City: string, PostalCode: string, Country: string, PhoneNumber: string}} */ private function getOrderAddressData($order): array { return [ 'Address' => [ 'Type' => 'B', //S - shipping, B - billing - 'Name' => $order->name, + 'Name' => (string) $order->name, 'LastName' => '', 'Company' => '', 'Text' => '', @@ -472,14 +477,14 @@ private function getOrderAddressData($order): array * * @param $order * - * @return array + * @return array{TotalPaymentNum: string, FrequencyType: string, FrequencyInterval: string, Type: mixed, StartDate: string} */ private function createRecurringData($order): array { return [ - 'TotalPaymentNum' => $order->recurringInstallmentCount, //kac kere tekrarlanacak + 'TotalPaymentNum' => (string) $order->recurringInstallmentCount, //kac kere tekrarlanacak 'FrequencyType' => $this->mapRecurringFrequency($order->recurringFrequencyType), //Monthly, weekly, daily - 'FrequencyInterval' => $order->recurringFrequency, + 'FrequencyInterval' => (string) $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 4ab5b6a3..f6839f37 100644 --- a/src/DataMapper/InterPosRequestDataMapper.php +++ b/src/DataMapper/InterPosRequestDataMapper.php @@ -14,10 +14,12 @@ */ class InterPosRequestDataMapper extends AbstractRequestDataMapperCrypt { + /** @var string */ public const CREDIT_CARD_EXP_DATE_FORMAT = 'my'; /** * MOTO (Mail Order Telephone Order) 0 for false, 1 for true + * @var string */ protected const MOTO = '0'; @@ -54,16 +56,19 @@ class InterPosRequestDataMapper extends AbstractRequestDataMapperCrypt AbstractCreditCard::CARD_TYPE_AMEX => '2', AbstractCreditCard::CARD_TYPE_TROY => '3', ]; + /** * {@inheritDoc} + * + * @param array{MD: string, PayerTxnId: string, Eci: string, PayerAuthenticationCode: string} $responseData */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array { return $this->getRequestAccountData($account) + [ 'TxnType' => $this->mapTxType($txType), 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], - 'OrderId' => $order->id, - 'PurchAmount' => $order->amount, + 'OrderId' => (string) $order->id, + 'PurchAmount' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'InstallmentCount' => $this->mapInstallment($order->installment), 'MD' => $responseData['MD'], @@ -91,7 +96,7 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ 'Lang' => $this->getLang($account, $order), ]; - if ($card) { + if ($card !== null) { $requestData['CardType'] = $this->cardTypeMapping[$card->getType()]; $requestData['Pan'] = $card->getNumber(); $requestData['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT); @@ -103,6 +108,7 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ /** * {@inheritDoc} + * @return array{TxnType: string, SecureType: string, OrderId: null, orgOrderId: mixed, PurchAmount: mixed, Currency: string, MOTO: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { @@ -110,8 +116,8 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $ac 'TxnType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'OrderId' => null, - 'orgOrderId' => $order->id, - 'PurchAmount' => $order->amount, + 'orgOrderId' => (string) $order->id, + 'PurchAmount' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'MOTO' => self::MOTO, ]; @@ -119,12 +125,13 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $ac /** * {@inheritDoc} + * @return array{OrderId: null, orgOrderId: string, TxnType: string, SecureType: string, Lang: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createStatusRequestData(AbstractPosAccount $account, $order): array { return $this->getRequestAccountData($account) + [ 'OrderId' => null, //todo buraya hangi deger verilecek? - 'orgOrderId' => $order->id, + 'orgOrderId' => (string) $order->id, 'TxnType' => $this->mapTxType(AbstractGateway::TX_STATUS), 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'Lang' => $this->getLang($account, $order), @@ -133,12 +140,13 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{OrderId: null, orgOrderId: string, TxnType: string, SecureType: string, Lang: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createCancelRequestData(AbstractPosAccount $account, $order): array { return $this->getRequestAccountData($account) + [ 'OrderId' => null, //todo buraya hangi deger verilecek? - 'orgOrderId' => $order->id, + 'orgOrderId' => (string) $order->id, 'TxnType' => $this->mapTxType(AbstractGateway::TX_CANCEL), 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'Lang' => $this->getLang($account, $order), @@ -147,13 +155,14 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{OrderId: null, orgOrderId: string, PurchAmount: string, TxnType: string, SecureType: string, Lang: string, MOTO: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createRefundRequestData(AbstractPosAccount $account, $order): array { return $this->getRequestAccountData($account) + [ 'OrderId' => null, - 'orgOrderId' => $order->id, - 'PurchAmount' => $order->amount, + 'orgOrderId' => (string) $order->id, + 'PurchAmount' => (string) $order->amount, 'TxnType' => $this->mapTxType(AbstractGateway::TX_REFUND), 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'Lang' => $this->getLang($account, $order), @@ -195,7 +204,7 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx 'InstallmentCount' => $this->mapInstallment($order->installment), ]; - if ($card) { + if ($card !== null) { $inputs['CardType'] = $this->cardTypeMapping[$card->getType()]; $inputs['Pan'] = $card->getNumber(); $inputs['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT); @@ -204,22 +213,20 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : ''; + return $installment > 1 ? (string) $installment : ''; } /** * @param AbstractPosAccount $account * - * @return array + * @return array{UserCode: string, UserPass: string, ShopCode: string} */ private function getRequestAccountData(AbstractPosAccount $account): array { diff --git a/src/DataMapper/KuveytPosRequestDataMapper.php b/src/DataMapper/KuveytPosRequestDataMapper.php index 3f6d71ee..071963f4 100644 --- a/src/DataMapper/KuveytPosRequestDataMapper.php +++ b/src/DataMapper/KuveytPosRequestDataMapper.php @@ -17,8 +17,13 @@ */ class KuveytPosRequestDataMapper extends AbstractRequestDataMapperCrypt { + /** @var string */ public const API_VERSION = '1.0.0'; + + /** @var string */ public const CREDIT_CARD_EXP_YEAR_FORMAT = 'y'; + + /** @var string */ public const CREDIT_CARD_EXP_MONTH_FORMAT = 'm'; /** @@ -72,13 +77,14 @@ class KuveytPosRequestDataMapper extends AbstractRequestDataMapperCrypt */ public static function amountFormat(float $amount): int { - return intval(round($amount, 2) * 100); + return (int) (round($amount, 2) * 100); } /** * @param KuveytPosAccount $account * * {@inheritDoc} + * @return array{APIVersion: string, HashData: string, CustomerIPAddress: mixed, KuveytTurkVPosAdditionalData: array{AdditionalData: array{Key: string, Data: mixed}}, TransactionType: string, InstallmentCount: mixed, Amount: mixed, DisplayAmount: int, CurrencyCode: mixed, MerchantOrderId: mixed, TransactionSecurity: mixed, MerchantId: string, CustomerId: string, UserName: string} */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array { @@ -131,7 +137,7 @@ public function create3DEnrollmentCheckRequestData(KuveytPosAccount $account, $o 'FailUrl' => $order->fail_url, ]; - if ($card) { + if ($card !== null) { $inputs['CardHolderName'] = $card->getHolderName(); $inputs['CardType'] = $this->cardTypeMapping[$card->getType()]; $inputs['CardNumber'] = $card->getNumber(); @@ -199,18 +205,15 @@ public function createHistoryRequestData(AbstractPosAccount $account, $order, ar throw new NotImplementedException(); } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : 0; + return $installment > 1 ? (string) $installment : '0'; } /** * @param KuveytPosAccount $account * - * @return array + * @return array{MerchantId: string, CustomerId: string, UserName: string} */ private function getRequestAccountData(AbstractPosAccount $account): array { diff --git a/src/DataMapper/PayForPosRequestDataMapper.php b/src/DataMapper/PayForPosRequestDataMapper.php index d9275bf6..27a25012 100644 --- a/src/DataMapper/PayForPosRequestDataMapper.php +++ b/src/DataMapper/PayForPosRequestDataMapper.php @@ -15,14 +15,17 @@ class PayForPosRequestDataMapper extends AbstractRequestDataMapper { /** * Kurum kodudur. (Banka tarafından verilir) + * @var string */ - const MBR_ID = '5'; + public const MBR_ID = '5'; /** * MOTO (Mail Order Telephone Order) 0 for false, 1 for true + * @var string */ - const MOTO = '0'; + public const MOTO = '0'; + /** @var string */ public const CREDIT_CARD_EXP_DATE_FORMAT = 'my'; /** {@inheritdoc} */ @@ -48,6 +51,7 @@ class PayForPosRequestDataMapper extends AbstractRequestDataMapper /** * {@inheritDoc} + * @return array{RequestGuid: mixed, UserCode: string, UserPass: string, OrderId: mixed, SecureType: string} */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData): array { @@ -62,16 +66,17 @@ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, /** * {@inheritDoc} + * @return array{MbrId: string, MOTO: string, OrderId: string, SecureType: string, TxnType: string, PurchAmount: string, Currency: string, InstallmentCount: string, Lang: string, CardHolderName: string|null, Pan: string, Expiry: string, Cvv2: string, MerchantId: string, UserCode: string, UserPass: string} */ 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, + 'OrderId' => (string) $order->id, 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'TxnType' => $this->mapTxType($txType), - 'PurchAmount' => $order->amount, + 'PurchAmount' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'InstallmentCount' => $this->mapInstallment($order->installment), 'Lang' => $this->getLang($account, $order), @@ -84,15 +89,16 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ /** * {@inheritDoc} + * @return array{MbrId: string, OrgOrderId: string, SecureType: string, TxnType: string, PurchAmount: string, Currency: string, Lang: string, MerchantId: string, UserCode: string, UserPass: string} */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { return $this->getRequestAccountData($account) + [ 'MbrId' => self::MBR_ID, - 'OrgOrderId' => $order->id, + 'OrgOrderId' => (string) $order->id, 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'TxnType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), - 'PurchAmount' => $order->amount, + 'PurchAmount' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), 'Lang' => $this->getLang($account, $order), ]; @@ -100,12 +106,13 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $ac /** * {@inheritDoc} + * @return array{MbrId: string, OrgOrderId: string, SecureType: string, Lang: string, TxnType: string, MerchantId: string, UserCode: string, UserPass: string} */ public function createStatusRequestData(AbstractPosAccount $account, $order): array { return $this->getRequestAccountData($account) + [ 'MbrId' => self::MBR_ID, - 'OrgOrderId' => $order->id, + 'OrgOrderId' => (string) $order->id, 'SecureType' => 'Inquiry', 'Lang' => $this->getLang($account, $order), 'TxnType' => $this->mapTxType(AbstractGateway::TX_STATUS), @@ -114,12 +121,13 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{MbrId: string, OrgOrderId: string, SecureType: string, TxnType: string, Currency: string, Lang: string, MerchantId: string, UserCode: string, UserPass: string} */ public function createCancelRequestData(AbstractPosAccount $account, $order): array { return $this->getRequestAccountData($account) + [ 'MbrId' => self::MBR_ID, - 'OrgOrderId' => $order->id, + 'OrgOrderId' => (string) $order->id, 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'TxnType' => $this->mapTxType(AbstractGateway::TX_CANCEL), 'Currency' => $this->mapCurrency($order->currency), @@ -129,6 +137,7 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{MbrId: string, SecureType: string, Lang: string, OrgOrderId: string, TxnType: string, PurchAmount: string, Currency: string, MerchantId: string, UserCode: string, UserPass: string} */ public function createRefundRequestData(AbstractPosAccount $account, $order): array { @@ -136,9 +145,9 @@ public function createRefundRequestData(AbstractPosAccount $account, $order): ar 'MbrId' => self::MBR_ID, 'SecureType' => $this->secureTypeMappings[AbstractGateway::MODEL_NON_SECURE], 'Lang' => $this->getLang($account, $order), - 'OrgOrderId' => $order->id, + 'OrgOrderId' => (string) $order->id, 'TxnType' => $this->mapTxType(AbstractGateway::TX_REFUND), - 'PurchAmount' => $order->amount, + 'PurchAmount' => (string) $order->amount, 'Currency' => $this->mapCurrency($order->currency), ]; } @@ -179,21 +188,21 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx 'MbrId' => self::MBR_ID, 'MerchantID' => $account->getClientId(), 'UserCode' => $account->getUsername(), - 'OrderId' => $order->id, + 'OrderId' => (string) $order->id, 'Lang' => $this->getLang($account, $order), 'SecureType' => $this->secureTypeMappings[$account->getModel()], 'TxnType' => $this->mapTxType($txType), - 'PurchAmount' => $order->amount, + 'PurchAmount' => (string) $order->amount, 'InstallmentCount' => $this->mapInstallment($order->installment), 'Currency' => $this->mapCurrency($order->currency), - 'OkUrl' => $order->success_url, - 'FailUrl' => $order->fail_url, - 'Rnd' => $order->rand, + 'OkUrl' => (string) $order->success_url, + 'FailUrl' => (string) $order->fail_url, + 'Rnd' => (string) $order->rand, 'Hash' => $hash, ]; - if ($card) { - $inputs['CardHolderName'] = $card->getHolderName(); + if ($card !== null) { + $inputs['CardHolderName'] = $card->getHolderName() ?? ''; $inputs['Pan'] = $card->getNumber(); $inputs['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_FORMAT); $inputs['Cvv2'] = $card->getCvv(); @@ -201,22 +210,20 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx return [ 'gateway' => $gatewayURL, //to be filled by the caller + 'method' => 'POST', 'inputs' => $inputs, ]; } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : 0; + return $installment > 1 ? (string) $installment : '0'; } /** * @param AbstractPosAccount $account * - * @return array + * @return array{MerchantId: string, UserCode: string, UserPass: string} */ private function getRequestAccountData(AbstractPosAccount $account): array { diff --git a/src/DataMapper/PosNetRequestDataMapper.php b/src/DataMapper/PosNetRequestDataMapper.php index d9818097..3a8430ba 100644 --- a/src/DataMapper/PosNetRequestDataMapper.php +++ b/src/DataMapper/PosNetRequestDataMapper.php @@ -239,11 +239,12 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx ]; if (isset($order->koiCode) && $order->koiCode > 0) { - $inputs['useJokerVadaa'] = 1; + $inputs['useJokerVadaa'] = '1'; } return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } @@ -369,9 +370,8 @@ public static function formatOrderId(string $orderId, int $padLength = null): st /** * formats installment in 00, 02, 06 format - * {@inheritDoc} */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { if ($installment > 1) { return str_pad((string) $installment, 2, '0', STR_PAD_LEFT); diff --git a/src/DataMapper/ResponseDataMapper/AbstractResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/AbstractResponseDataMapper.php index 4b8a74fe..e37b4027 100644 --- a/src/DataMapper/ResponseDataMapper/AbstractResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/AbstractResponseDataMapper.php @@ -7,8 +7,13 @@ abstract class AbstractResponseDataMapper { + /** @var string */ public const TX_APPROVED = 'approved'; + + /** @var string */ public const TX_DECLINED = 'declined'; + + /** @var string */ public const PROCEDURE_SUCCESS_CODE = '00'; /** @var LoggerInterface */ @@ -101,7 +106,8 @@ protected function mergeArraysPreferNonNullValues(array $arr1, array $arr2): arr /** * Returns default payment response data * - * @return array + * @return array{order_id: null, trans_id: null, auth_code: null, ref_ret_num: null, proc_return_code: null, + * status: string, status_detail: null, error_code: null, error_message: null, all: null} */ protected function getDefaultPaymentResponse(): array { diff --git a/src/DataMapper/ResponseDataMapper/EstPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/EstPosResponseDataMapper.php index f6696ab8..03aeb504 100644 --- a/src/DataMapper/ResponseDataMapper/EstPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/EstPosResponseDataMapper.php @@ -38,9 +38,10 @@ class EstPosResponseDataMapper extends AbstractResponseDataMapper implements Pay public function mapPaymentResponse(array $rawPaymentResponseData): array { $this->logger->log(LogLevel::DEBUG, 'mapping payment response', [$rawPaymentResponseData]); - if (empty($rawPaymentResponseData)) { + if ($rawPaymentResponseData === []) { return $this->getDefaultPaymentResponse(); } + $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); $procReturnCode = $this->getProcReturnCode($rawPaymentResponseData); @@ -119,10 +120,8 @@ public function map3DPayResponseData($raw3DAuthResponseData): array $raw3DAuthResponseData = $this->emptyStringsToNull($raw3DAuthResponseData); $procReturnCode = $this->getProcReturnCode($raw3DAuthResponseData); - if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { - if (in_array($raw3DAuthResponseData['mdStatus'], ['1', '2', '3', '4'])) { - $status = self::TX_APPROVED; - } + if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode && in_array($raw3DAuthResponseData['mdStatus'], ['1', '2', '3', '4'])) { + $status = self::TX_APPROVED; } $defaultResponse = $this->getDefaultPaymentResponse(); @@ -342,6 +341,7 @@ public function mapRecurringStatusResponse(array $rawResponseData): array // when order not found for the given recurring order id then RECURRINGCOUNT = 0 $status = self::TX_APPROVED; } + $recurringOrderResponse = [ 'recurringId' => $extra['RECURRINGID'], 'recurringInstallmentCount' => $extra['RECURRINGCOUNT'], @@ -351,22 +351,22 @@ public function mapRecurringStatusResponse(array $rawResponseData): array 'all' => $rawResponseData, ]; - for ($i = 1; isset($extra["ORD_ID_$i"]); $i++) { + for ($i = 1; isset($extra[sprintf('ORD_ID_%d', $i)]); ++$i) { $recurringOrder = [ - 'order_id' => $extra["ORD_ID_$i"], - 'order_status' => $extra["ORDERSTATUS_$i"], - 'masked_number' => $extra["PAN_$i"], - 'status' => $extra["TRANS_STAT_$i"], //C => Completed, PN => Pending, CNCL => Canceled + 'order_id' => $extra[sprintf('ORD_ID_%d', $i)], + 'order_status' => $extra[sprintf('ORDERSTATUS_%d', $i)], + 'masked_number' => $extra[sprintf('PAN_%d', $i)], + 'status' => $extra[sprintf('TRANS_STAT_%d', $i)], //C => Completed, PN => Pending, CNCL => Canceled // following fields are null until transaction is done for respective installment: - 'auth_code' => $extra["AUTH_CODE_$i"] ?? null, - 'auth_time' => $extra["AUTH_DTTM_$i"] ?? null, - 'proc_return_code' => $extra["PROC_RET_CD_$i"] ?? null, - 'trans_id' => $extra["TRANS_ID_$i"] ?? null, - 'ref_ret_num' => $extra["HOST_REF_NUM_$i"] ?? null, - 'first_amount' => $extra["ORIG_TRANS_AMT_$i"], - 'capture_amount' => $extra["CAPTURE_AMT_$i"] ?? null, - 'capture_time' => $extra["CAPTURE_DTTM_$i"] ?? null, + 'auth_code' => $extra[sprintf('AUTH_CODE_%d', $i)] ?? null, + 'auth_time' => $extra[sprintf('AUTH_DTTM_%d', $i)] ?? null, + 'proc_return_code' => $extra[sprintf('PROC_RET_CD_%d', $i)] ?? null, + 'trans_id' => $extra[sprintf('TRANS_ID_%d', $i)] ?? null, + 'ref_ret_num' => $extra[sprintf('HOST_REF_NUM_%d', $i)] ?? null, + 'first_amount' => $extra[sprintf('ORIG_TRANS_AMT_%d', $i)], + 'capture_amount' => $extra[sprintf('CAPTURE_AMT_%d', $i)] ?? null, + 'capture_time' => $extra[sprintf('CAPTURE_DTTM_%d', $i)] ?? null, ]; $recurringOrder['capture'] = $recurringOrder['first_amount'] === $recurringOrder['capture_amount']; @@ -392,6 +392,7 @@ public static function amountFormat(string $amount): float /** * @param PaymentStatusModel $rawResponseData + * * {@inheritDoc} */ public function mapHistoryResponse(array $rawResponseData): array diff --git a/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php index 2dad8918..0bd05300 100644 --- a/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php @@ -48,6 +48,7 @@ public function mapPaymentResponse(array $rawPaymentResponseData): array if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { $status = self::TX_APPROVED; } + $transaction = $rawPaymentResponseData['Transaction']; $mappedResponse = [ @@ -136,12 +137,9 @@ public function map3DPayResponseData($raw3DAuthResponseData): array $commonResult = $this->map3DCommonResponseData($raw3DAuthResponseData); if (self::TX_APPROVED === $commonResult['status']) { $procReturnCode = $raw3DAuthResponseData['procreturncode']; - if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { - $commonResult['status'] = self::TX_APPROVED; - } else { - $commonResult['status'] = self::TX_DECLINED; - } + $commonResult['status'] = self::PROCEDURE_SUCCESS_CODE === $procReturnCode ? self::TX_APPROVED : self::TX_DECLINED; } + if (in_array($raw3DAuthResponseData['mdstatus'], ['1', '2', '3', '4'])) { $commonResult['auth_code'] = $raw3DAuthResponseData['authcode']; $commonResult['trans_id'] = $raw3DAuthResponseData['transid']; @@ -184,6 +182,7 @@ public function mapCancelResponse(array $rawResponseData): array if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { $status = self::TX_APPROVED; } + $transaction = $rawResponseData['Transaction']; @@ -215,6 +214,7 @@ public function mapStatusResponse(array $rawResponseData): array if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { $status = self::TX_APPROVED; } + $transaction = $rawResponseData['Transaction']; return [ @@ -302,15 +302,16 @@ public static function amountFormat(string $amount): float */ protected function mapResponseTransactionSecurity(string $mdStatus): string { - if (in_array($mdStatus, ['1', '2', '3', '4'])) { - if ('1' === $mdStatus) { - return 'Full 3D Secure'; - } else { - // ['2', '3', '4'] - return 'Half 3D Secure'; - } + if (!in_array($mdStatus, ['1', '2', '3', '4'])) { + return 'MPI fallback'; } - return 'MPI fallback'; + + if ('1' === $mdStatus) { + return 'Full 3D Secure'; + } + + // ['2', '3', '4'] + return 'Half 3D Secure'; } /** diff --git a/src/DataMapper/ResponseDataMapper/InterPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/InterPosResponseDataMapper.php index 584be427..e3f287fa 100644 --- a/src/DataMapper/ResponseDataMapper/InterPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/InterPosResponseDataMapper.php @@ -24,9 +24,10 @@ class InterPosResponseDataMapper extends AbstractResponseDataMapper implements P public function mapPaymentResponse(array $rawPaymentResponseData): array { $this->logger->log(LogLevel::DEBUG, 'mapping payment response', [$rawPaymentResponseData]); - if (empty($rawPaymentResponseData)) { + if ($rawPaymentResponseData === []) { return $this->getDefaultPaymentResponse(); } + $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); $status = self::TX_DECLINED; $procReturnCode = $this->getProcReturnCode($rawPaymentResponseData); diff --git a/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php index c3242002..8ff30db5 100644 --- a/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php @@ -30,6 +30,7 @@ public function mapPaymentResponse(array $rawPaymentResponseData): array if (empty($rawPaymentResponseData)) { return $result; } + $status = self::TX_DECLINED; $procReturnCode = $this->getProcReturnCode($rawPaymentResponseData); @@ -49,6 +50,7 @@ public function mapPaymentResponse(array $rawPaymentResponseData): array return $result; } + /** @var array $vPosMessage */ $vPosMessage = $rawPaymentResponseData['VPosMessage']; diff --git a/src/DataMapper/ResponseDataMapper/PayForPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/PayForPosResponseDataMapper.php index e9ec6998..b43305be 100644 --- a/src/DataMapper/ResponseDataMapper/PayForPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/PayForPosResponseDataMapper.php @@ -97,7 +97,7 @@ public function map3DPaymentData(array $raw3DAuthResponseData, ?array $rawPaymen 'error_message' => self::TX_APPROVED !== $threeDAuthStatus ? $raw3DAuthResponseData['ErrMsg'] : null, ]; - if (empty($paymentResponseData)) { + if ($paymentResponseData === []) { return array_merge($this->getDefaultPaymentResponse(), $threeDResponse, $this->map3DCommonResponseData($raw3DAuthResponseData)); } diff --git a/src/DataMapper/ResponseDataMapper/PosNetResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/PosNetResponseDataMapper.php index 331e218d..1409e87e 100644 --- a/src/DataMapper/ResponseDataMapper/PosNetResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/PosNetResponseDataMapper.php @@ -6,6 +6,7 @@ class PosNetResponseDataMapper extends AbstractResponseDataMapper implements PaymentResponseMapperInterface, NonPaymentResponseMapperInterface { + /** @var string */ public const PROCEDURE_SUCCESS_CODE = '1'; /** @@ -44,7 +45,7 @@ public function mapPaymentResponse(array $rawPaymentResponseData): array { $status = self::TX_DECLINED; $this->logger->log(LogLevel::DEBUG, 'mapping payment response', [$rawPaymentResponseData]); - if (empty($rawPaymentResponseData)) { + if ($rawPaymentResponseData === []) { return $this->getDefaultPaymentResponse(); } @@ -88,6 +89,7 @@ public function map3DPaymentData(array $raw3DAuthResponseData, ?array $rawPaymen if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode && $this->getStatusDetail($procReturnCode) === self::TX_APPROVED) { $status = self::TX_APPROVED; } + /** @var array $oosResolveMerchantDataResponse */ $oosResolveMerchantDataResponse = $raw3DAuthResponseData['oosResolveMerchantDataResponse']; @@ -154,6 +156,7 @@ public function mapCancelResponse($rawResponseData): array if (null !== $state) { $transactionType = $this->mapTxType($state); } + $results = [ 'auth_code' => null, 'trans_id' => null, @@ -219,6 +222,7 @@ public function mapStatusResponse(array $rawResponseData): array if (null !== $state) { $transactionType = $this->mapTxType($state); } + $results = [ 'auth_code' => null, 'trans_id' => null, @@ -261,10 +265,11 @@ public function mapHistoryResponse(array $rawResponseData): array $authCode = $transactionDetails['authCode'] ?? null; if (is_array($transactionDetails)) { - if (count($transactionDetails) > 0) { + if ($transactionDetails !== []) { $state = $transactionDetails[0]['state']; $authCode = $transactionDetails[0]['authCode']; } + if (count($transactionDetails) > 1) { foreach ($transactionDetails as $key => $_transaction) { if ($key > 0) { diff --git a/src/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapper.php new file mode 100644 index 00000000..7e561e80 --- /dev/null +++ b/src/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapper.php @@ -0,0 +1,246 @@ + + */ + protected $codes = [ + self::PROCEDURE_SUCCESS_CODE => self::TX_APPROVED, + ]; + + /** + * TODO implement + * {@inheritdoc} + */ + public function map3DPaymentData(array $raw3DAuthResponseData, ?array $rawPaymentResponseData): array + { + throw new NotImplementedException(); + } + + /** + * @param array{ErrorCode: string}|array{ + * Rc: string, + * AuthCode: string, + * TransactionId: string, + * PaymentToken: string, + * MaskedPan: string}|array{ + * Rc: string, + * Message: string, + * TransactionId: string, + * PaymentToken: string} $raw3DAuthResponseData + * {@inheritdoc} + */ + public function map3DPayResponseData(array $raw3DAuthResponseData): array + { + $raw3DAuthResponseData = $this->emptyStringsToNull($raw3DAuthResponseData); + + $paymentResponse = $this->getCommonPaymentResponse($raw3DAuthResponseData); + $paymentResponse['md_status'] = null; + $paymentResponse['md_error_message'] = null; + $paymentResponse['transaction_security'] = null; + + $paymentResponse['trans_id'] = $raw3DAuthResponseData['TransactionId']; + $paymentResponse['masked_number'] = $raw3DAuthResponseData['MaskedPan']; + + if (self::TX_APPROVED === $paymentResponse['status']) { + $paymentResponse['auth_code'] = $raw3DAuthResponseData['AuthCode']; + $paymentResponse['ref_ret_num'] = $raw3DAuthResponseData['TransactionId']; + $paymentResponse['order_id'] = $raw3DAuthResponseData['OrderID']; + } + + return $paymentResponse; + } + + /** + * {@inheritdoc} + * @param array{ErrorCode: string}|array{ + * Rc: string, + * AuthCode: string, + * TransactionId: string, + * PaymentToken: string, + * MaskedPan: string}|array{ + * Rc: string, + * Message: string, + * TransactionId: string, + * PaymentToken: string} $raw3DAuthResponseData + */ + public function map3DHostResponseData(array $raw3DAuthResponseData): array + { + return $this->map3DPayResponseData($raw3DAuthResponseData); + } + + /** + * {@inheritdoc} + */ + public function mapRefundResponse(array $rawResponseData): array + { + return $this->mapCancelResponse($rawResponseData); + } + + /** + * {@inheritdoc} + */ + public function mapCancelResponse(array $rawResponseData): array + { + $rawResponseData = $this->emptyStringsToNull($rawResponseData); + + $response = $this->getCommonNonSecureResponse($rawResponseData); + + if (self::TX_APPROVED === $response['status']) { + $response['order_id'] = $rawResponseData['TransactionId']; + $response['ref_ret_num'] = $rawResponseData['Rrn']; + $response['auth_code'] = $rawResponseData['AuthCode']; + $response['trans_id'] = $rawResponseData['TransactionId']; + } + + return $response; + } + + /** + * {@inheritdoc} + */ + public function mapStatusResponse(array $rawResponseData): array + { + return $this->emptyStringsToNull($rawResponseData); + } + + /** + * {@inheritDoc} + */ + public function mapPaymentResponse(array $rawPaymentResponseData): array + { + $this->logger->log(LogLevel::DEBUG, 'mapping payment response', $rawPaymentResponseData); + $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); + $commonResponse = $this->getCommonPaymentResponse($rawPaymentResponseData); + + if (self::TX_APPROVED === $commonResponse['status']) { + $commonResponse['trans_id'] = $rawPaymentResponseData['TransactionId']; + $commonResponse['auth_code'] = $rawPaymentResponseData['AuthCode']; + $commonResponse['ref_ret_num'] = $rawPaymentResponseData['Rrn']; + $commonResponse['order_id'] = $rawPaymentResponseData['OrderId']; + $commonResponse['transaction_type'] = $this->mapTxType($rawPaymentResponseData['TransactionType']); + $commonResponse['eci'] = $rawPaymentResponseData['ECI']; + } + + $this->logger->log(LogLevel::DEBUG, 'mapped payment response', $commonResponse); + + return $commonResponse; + } + + /** + * @param array $responseData + * + * @return array{order_id: string|null, trans_id: string|null, auth_code: string|null, + * ref_ret_num: string|null, proc_return_code: string|null, + * status: string, status_detail: string|null, error_code: string|null, + * error_message: string|null, all: array} + */ + private function getCommonPaymentResponse(array $responseData): array + { + $status = self::TX_DECLINED; + $resultCode = $this->getProcReturnCode($responseData); + + $errorCode = $responseData['ErrorCode'] ?? null; + $errorMsg = null; + if (null !== $errorCode) { + $resultCode = $errorCode; + $errorMsg = $responseData['Message']; + } elseif (self::PROCEDURE_SUCCESS_CODE === $resultCode) { + $status = self::TX_APPROVED; + } else { + $errorMsg = $responseData['Message']; + } + + $response = $this->getDefaultPaymentResponse(); + + $response['proc_return_code'] = $resultCode; + $response['status'] = $status; + $response['status_detail'] = null; + $response['error_code'] = (self::TX_DECLINED === $status) ? $resultCode : null; + $response['error_message'] = $errorMsg; + $response['all'] = $responseData; + + return $response; + } + + /** + * @param array $responseData + * + * @return array{order_id: string|null, trans_id: string|null, auth_code: string|null, + * ref_ret_num: string|null, proc_return_code: string|null, + * status: string, status_detail: string|null, error_code: string|null, + * error_message: string|null, all: array} + */ + private function getCommonNonSecureResponse(array $responseData): array + { + $status = self::TX_DECLINED; + $resultCode = $this->getProcReturnCode($responseData); + + $errorCode = $responseData['ErrorCode'] ?? null; + $statusDetail = null; + if (null !== $errorCode) { + $resultCode = $errorCode; + $statusDetail = $responseData['ResponseMessage']; + } elseif (self::PROCEDURE_SUCCESS_CODE === $resultCode) { + $status = self::TX_APPROVED; + } else { + $statusDetail = $responseData['ResultDetail']; + } + + $response = $this->getDefaultPaymentResponse(); + + $response['proc_return_code'] = $resultCode; + $response['status'] = $status; + $response['status_detail'] = $statusDetail; + $response['error_code'] = (self::TX_DECLINED === $status) ? $resultCode : null; + $response['error_message'] = $statusDetail; + $response['all'] = $responseData; + + return $response; + } + + /** + * {@inheritDoc} + */ + public function mapHistoryResponse(array $rawResponseData): array + { + return $this->emptyStringsToNull($rawResponseData); + } + + /** + * @param string $mdStatus + * + * @return string + */ + protected function mapResponseTransactionSecurity(string $mdStatus): string + { + return 'MPI fallback'; + } + + /** + * Get ProcReturnCode + * + * @param array $response + * + * @return string|null + */ + protected function getProcReturnCode(array $response): ?string + { + if (isset($response['Rc'])) { + return $response['Rc']; + } + + return $response['ResultCode'] ?? null; + } +} diff --git a/src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php index c753311a..c11b869e 100644 --- a/src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapper.php @@ -6,6 +6,7 @@ class VakifBankPosResponseDataMapper extends AbstractResponseDataMapper implements PaymentResponseMapperInterface, NonPaymentResponseMapperInterface { + /** @var string */ public const PROCEDURE_SUCCESS_CODE = '0000'; /** @@ -26,31 +27,32 @@ public function map3DPaymentData(array $raw3DAuthResponseData, ?array $rawPaymen '3d_auth_response' => $raw3DAuthResponseData, 'provision_response' => $rawPaymentResponseData, ]); - $threeDAuthStatus = ('Y' === $raw3DAuthResponseData['Status']) ? self::TX_APPROVED : self::TX_DECLINED; - $paymentResponseData = []; + $raw3DAuthResponseData = $this->emptyStringsToNull($raw3DAuthResponseData); + $threeDAuthStatus = ('Y' === $raw3DAuthResponseData['Status']) ? self::TX_APPROVED : self::TX_DECLINED; if (self::TX_APPROVED === $threeDAuthStatus && null !== $rawPaymentResponseData) { $paymentResponseData = $this->mapPaymentResponse($rawPaymentResponseData); + } else { + $paymentResponseData = $this->getDefaultPaymentResponse(); } $threeDResponse = [ - 'eci' => $raw3DAuthResponseData['Eci'], - 'cavv' => $raw3DAuthResponseData['Cavv'], - 'auth_code' => null, - 'order_id' => $raw3DAuthResponseData['VerifyEnrollmentRequestId'], - 'status' => $threeDAuthStatus, - 'status_detail' => null, - 'error_code' => self::TX_DECLINED === $threeDAuthStatus ? $raw3DAuthResponseData['ErrorCode'] : null, - 'error_message' => self::TX_DECLINED === $threeDAuthStatus ? $raw3DAuthResponseData['ErrorMessage'] : null, - 'all' => $rawPaymentResponseData, - '3d_all' => $raw3DAuthResponseData, + 'eci' => $raw3DAuthResponseData['Eci'], + 'cavv' => $raw3DAuthResponseData['Cavv'], + 'auth_code' => null, + 'order_id' => $raw3DAuthResponseData['VerifyEnrollmentRequestId'], + 'status' => $threeDAuthStatus, + 'status_detail' => null, + 'error_code' => self::TX_DECLINED === $threeDAuthStatus ? $raw3DAuthResponseData['ErrorCode'] : null, + 'error_message' => self::TX_DECLINED === $threeDAuthStatus ? $raw3DAuthResponseData['ErrorMessage'] : null, + 'md_status' => $raw3DAuthResponseData['Status'], + 'md_error_message' => self::TX_DECLINED === $threeDAuthStatus ? $raw3DAuthResponseData['ErrorMessage'] : null, + 'transaction_security' => null, + 'all' => $rawPaymentResponseData, + '3d_all' => $raw3DAuthResponseData, ]; - if (empty($paymentResponseData)) { - return array_merge($this->getDefaultPaymentResponse(), $threeDResponse); - } - - return array_merge($threeDResponse, $paymentResponseData); + return $this->mergeArraysPreferNonNullValues($threeDResponse, $paymentResponseData); } /** @@ -95,7 +97,7 @@ public function mapCancelResponse($rawResponseData): array 'ref_ret_num' => $rawResponseData['Rrn'] ?? null, 'proc_return_code' => $resultCode, 'trans_id' => $rawResponseData['TransactionId'] ?? null, - 'error_code' => (self::TX_DECLINED === $status) ? $rawResponseData['ResultDetail'] : null, + 'error_code' => (self::TX_DECLINED === $status) ? $resultCode : null, 'error_message' => (self::TX_DECLINED === $status) ? $rawResponseData['ResultDetail'] : null, 'status' => $status, 'status_detail' => $rawResponseData['ResultDetail'], @@ -117,15 +119,15 @@ public function mapStatusResponse(array $rawResponseData): array public function mapPaymentResponse(array $rawPaymentResponseData): array { $this->logger->log(LogLevel::DEBUG, 'mapping payment response', [$rawPaymentResponseData]); - $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); - $commonResponse = $this->getCommonPaymentResponse($rawPaymentResponseData); + $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); + $commonResponse = $this->getCommonPaymentResponse($rawPaymentResponseData); + $commonResponse['order_id'] = $rawPaymentResponseData['OrderId'] ?? null; + if (self::TX_APPROVED === $commonResponse['status']) { $commonResponse['trans_id'] = $rawPaymentResponseData['TransactionId']; $commonResponse['auth_code'] = $rawPaymentResponseData['AuthCode']; - $commonResponse['ref_ret_num'] = $rawPaymentResponseData['Rrn']; - $commonResponse['order_id'] = $rawPaymentResponseData['OrderId']; + $commonResponse['ref_ret_num'] = $rawPaymentResponseData['TransactionId']; $commonResponse['transaction_type'] = $this->mapTxType($rawPaymentResponseData['TransactionType']); - $commonResponse['eci'] = $rawPaymentResponseData['ECI']; } $this->logger->log(LogLevel::DEBUG, 'mapped payment response', $commonResponse); diff --git a/src/DataMapper/VakifBankCPPosRequestDataMapper.php b/src/DataMapper/VakifBankCPPosRequestDataMapper.php new file mode 100644 index 00000000..347a43fd --- /dev/null +++ b/src/DataMapper/VakifBankCPPosRequestDataMapper.php @@ -0,0 +1,311 @@ + 'Sale', + AbstractGateway::TX_PRE_PAY => 'Auth', + AbstractGateway::TX_POST_PAY => 'Capture', + AbstractGateway::TX_CANCEL => 'Cancel', + AbstractGateway::TX_REFUND => 'Refund', + AbstractGateway::TX_HISTORY => 'TxnHistory', + AbstractGateway::TX_STATUS => 'OrderInquiry', + ]; + + /** + * {@inheritdoc} + */ + protected $cardTypeMapping = [ + AbstractCreditCard::CARD_TYPE_VISA => '100', + AbstractCreditCard::CARD_TYPE_MASTERCARD => '200', + AbstractCreditCard::CARD_TYPE_TROY => '300', + AbstractCreditCard::CARD_TYPE_AMEX => '400', + ]; + + /** + * {@inheritdoc} + */ + protected $langMappings = [ + AbstractGateway::LANG_TR => 'tr-TR', + AbstractGateway::LANG_EN => 'en-US', + ]; + + /** + * {@inheritdoc} + */ + protected $recurringOrderFrequencyMapping = [ + 'DAY' => 'Day', + 'MONTH' => 'Month', + 'YEAR' => 'Year', + ]; + + /** + * todo implement + * {@inheritDoc} + * + * @param VakifBankAccount $account + */ + public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData, ?AbstractCreditCard $card = null): array + { + throw new NotImplementedException(); + } + + + /** + * @param VakifBankAccount $account + * @param array{TransactionId: string, PaymentToken: string} $responseData + * + * @return array{HostMerchantId: string, Password: string, TransactionId: string, PaymentToken: string} + */ + public function create3DPaymentStatusRequestData(AbstractPosAccount $account, array $responseData): array + { + return $this->getRequestAccountData($account) + [ + 'HostMerchantId' => $account->getClientId(), + 'Password' => $account->getPassword(), + 'TransactionId' => $responseData['TransactionId'], + 'PaymentToken' => $responseData['PaymentToken'], + ]; + } + + /** + * @param VakifBankAccount $account + * @param object $order + * @param AbstractGateway::TX_* $txType + * @param AbstractCreditCard|null $card + * + * @return array + */ + public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + $mappedOrder = (array) $order; + $mappedOrder['currency'] = $this->mapCurrency($order->currency); + $mappedOrder['amount'] = self::amountFormat($order->amount); + $hashData = $this->crypt->create3DHash($account, $mappedOrder, $txType); + + $requestData = [ + 'HostMerchantId' => $account->getClientId(), + 'MerchantPassword' => $account->getPassword(), + 'HostTerminalId' => $account->getTerminalId(), + 'TransactionType' => $this->mapTxType($txType), + 'AmountCode' => $this->mapCurrency($order->currency), + 'Amount' => self::amountFormat($order->amount), + 'OrderID' => (string) $order->id, + 'OrderDescription' => (string) ($order->description ?? null), + 'IsSecure' => 'true', // Işlemin 3D yapılıp yapılmayacağına dair flag, alabileceği değerler: 'true', 'false' + /** + * 3D Programına Dahil Olmayan Kartlar ile İşlem Yapma Flagi: "3D İşlem Flagi" (IsSecure) "true" gönderilmiş + * işlemler için bir alt seçenektir. Kart sahibi "3D Secure" programına dahil değilse Ortak Ödemenin işlemi + * Sanal Pos'a gönderip göndermeyeceğini belirtir. "true" gönderilmesi durumunda kart sahibi + * 3D Secure programına dahil olmasa bile işlemi Sanal Pos'a gönderecektir. + * Bu tür işlemler "Half Secure" olarak işaretlenecektir. + */ + 'AllowNotEnrolledCard' => 'false', + 'SuccessUrl' => (string) $order->success_url, + 'FailUrl' => (string) $order->fail_url, + 'HashedData' => $hashData, + 'RequestLanguage' => $this->getLang($account, $order), + /** + * Bu alanda gönderilecek değer kart hamili + * ektresinde işlem açıklamasında çıkacaktır. + * (Abone no vb. bilgiler gönderilebilir) + */ + 'Extract' => '', + /** + * Uye işyeri tarafından işleme ait ek bilgiler varsa CustomItems alanında gönderilir. + * İçeriğinde "name" ve "value" attirbutelarını barındırır. + * Örnek: İsim1:Değer1 İsim2:Değer2 İsim3:Değer3 + */ + 'CustomItems' => '', + ]; + + if ($card instanceof AbstractCreditCard) { + $requestData += [ + 'BrandNumber' => $this->cardTypeMapping[$card->getType()], + 'CVV' => $card->getCvv(), + 'PAN' => $card->getNumber(), + 'ExpireMonth' => $card->getExpireMonth(), + 'ExpireYear' => $card->getExpireYear(), + 'CardHoldersName' => (string) $card->getHolderName(), + ]; + } + + if ($order->installment) { + $requestData['InstallmentCount'] = $this->mapInstallment($order->installment); + } + + return $requestData; + } + + /** + * TODO implement + * {@inheritDoc} + * + * @param VakifBankAccount $account + * + * @return array + */ + public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array + { + $requestData = $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType($txType), + 'OrderId' => (string) $order->id, + 'CurrencyAmount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'ClientIp' => (string) $order->ip, + 'TransactionDeviceSource' => '0', + ]; + + if ($card instanceof AbstractCreditCard) { + $requestData['Pan'] = $card->getNumber(); + $requestData['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_LONG_FORMAT); + $requestData['Cvv'] = $card->getCvv(); + } + + return $requestData; + } + + /** + * @param VakifBankAccount $account + * @param $order + * @param AbstractCreditCard|null $card + * + * @return array{TransactionType: string, ReferenceTransactionId: string, + * CurrencyAmount: string, CurrencyCode: string, ClientIp: string, + * MerchantId: string, Password: string} + */ + public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array + { + return $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'ReferenceTransactionId' => (string) $order->id, + 'CurrencyAmount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'ClientIp' => (string) $order->ip, + ]; + } + + /** + * {@inheritDoc} + */ + public function createStatusRequestData(AbstractPosAccount $account, $order): array + { + throw new NotImplementedException(); + } + + /** + * {@inheritDoc} + * + * @param VakifBankAccount $account + * + * @return array{MerchantId: string, Password: string, TransactionType: string, ReferenceTransactionId: string, + * ClientIp: string} + */ + public function createCancelRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_CANCEL), + 'ReferenceTransactionId' => (string) $order->id, + 'ClientIp' => (string) $order->ip, + ]; + } + + /** + * {@inheritDoc} + * + * @param VakifBankAccount $account + * + * @return array{MerchantId: string, Password: string, TransactionType: string, ReferenceTransactionId: string, + * ClientIp: string, CurrencyAmount: string} + */ + public function createRefundRequestData(AbstractPosAccount $account, $order): array + { + return $this->getRequestAccountData($account) + [ + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_REFUND), + 'ReferenceTransactionId' => (string) $order->id, + 'ClientIp' => (string) $order->ip, + 'CurrencyAmount' => self::amountFormat($order->amount), + ]; + } + + /** + * {@inheritDoc} + */ + public function createHistoryRequestData(AbstractPosAccount $account, $order, array $extraData = []): array + { + throw new NotImplementedException(); + } + + /** + * {@inheritDoc} + * + * @param array{CommonPaymentUrl: string, PaymentToken: string} $extraData + * + * @return array{gateway: string, method: 'GET', inputs: array{Ptkn: string}} + */ + public function create3DFormData( + ?AbstractPosAccount $account, + $order, + ?string $txType, + ?string $gatewayURL, + ?AbstractCreditCard $card = null, + array $extraData = []): array + { + return [ + 'gateway' => $extraData['CommonPaymentUrl'], + 'method' => 'GET', + 'inputs' => [ + 'Ptkn' => $extraData['PaymentToken'], + ], + ]; + } + + /** + * Amount Formatter + * + * @param float $amount + * + * @return string ex: 10.1 => 10.10 + */ + public static function amountFormat(float $amount): string + { + return number_format($amount, 2, '.', ''); + } + + public function mapInstallment(?int $installment): string + { + return $installment > 1 ? (string) $installment : '0'; + } + + /** + * @param VakifBankAccount $account + * + * @return array{MerchantId: string, Password: string} + */ + private function getRequestAccountData(AbstractPosAccount $account): array + { + return [ + 'MerchantId' => $account->getClientId(), + 'Password' => $account->getPassword(), + ]; + } +} diff --git a/src/DataMapper/VakifBankPosRequestDataMapper.php b/src/DataMapper/VakifBankPosRequestDataMapper.php index 89c8a140..43aa2e99 100644 --- a/src/DataMapper/VakifBankPosRequestDataMapper.php +++ b/src/DataMapper/VakifBankPosRequestDataMapper.php @@ -15,7 +15,10 @@ */ class VakifBankPosRequestDataMapper extends AbstractRequestDataMapper { + /** @var string */ public const CREDIT_CARD_EXP_DATE_LONG_FORMAT = 'Ym'; + + /** @var string */ public const CREDIT_CARD_EXP_DATE_FORMAT = 'ym'; /** @@ -51,28 +54,30 @@ class VakifBankPosRequestDataMapper extends AbstractRequestDataMapper ]; /** - * @param VakifBankAccount $account + * @param VakifBankAccount $account + * @param array{Eci: string, Cavv: string, VerifyEnrollmentRequestId: string} $responseData + * * {@inheritDoc} */ public function create3DPaymentRequestData(AbstractPosAccount $account, $order, string $txType, array $responseData, ?AbstractCreditCard $card = null): array { $requestData = $this->getRequestAccountData($account) + [ - 'TransactionType' => $this->mapTxType($txType), - 'TransactionId' => $order->id, - 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $this->mapCurrency($order->currency), - 'CardHoldersName' => $card->getHolderName(), - 'Cvv' => $card->getCvv(), - 'Pan' => $card->getNumber(), - 'Expiry' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_LONG_FORMAT), - 'ECI' => $responseData['Eci'], - 'CAVV' => $responseData['Cavv'], - 'MpiTransactionId' => $responseData['VerifyEnrollmentRequestId'], - 'OrderId' => $order->id, - 'OrderDescription' => $this->order->description ?? null, - 'ClientIp' => $order->ip, - 'TransactionDeviceSource' => 0, // ECommerce - ]; + 'TransactionType' => $this->mapTxType($txType), + 'TransactionId' => (string) $order->id, + 'CurrencyAmount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'CardHoldersName' => $card->getHolderName(), + 'Cvv' => $card->getCvv(), + 'Pan' => $card->getNumber(), + 'Expiry' => $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_LONG_FORMAT), + 'ECI' => $responseData['Eci'], + 'CAVV' => $responseData['Cavv'], + 'MpiTransactionId' => $responseData['VerifyEnrollmentRequestId'], + 'OrderId' => (string) $order->id, + 'OrderDescription' => (string) ($order->description ?? ''), + 'ClientIp' => (string) $order->ip, + 'TransactionDeviceSource' => '0', // ECommerce + ]; if ($order->installment) { $requestData['NumberOfInstallments'] = $this->mapInstallment($order->installment); @@ -107,12 +112,15 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, if ($order->installment) { $requestData['InstallmentCount'] = $this->mapInstallment($order->installment); } + if (isset($order->extraData)) { $requestData['SessionInfo'] = $order->extraData; } + if ($account->isSubBranch()) { $requestData['SubMerchantId'] = $account->getSubMerchantId(); } + if (isset($order->recurringFrequency)) { $requestData['IsRecurring'] = 'true'; // Periyodik İşlem Frekansı @@ -131,24 +139,24 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $account, } /** - * @param VakifBankAccount $account + * @param VakifBankAccount $account * {@inheritDoc} */ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $order, string $txType, ?AbstractCreditCard $card = null): array { $requestData = $this->getRequestAccountData($account) + [ - 'TransactionType' => $this->mapTxType($txType), - 'OrderId' => $order->id, - 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $this->mapCurrency($order->currency), - 'ClientIp' => $order->ip, - 'TransactionDeviceSource' => 0, - ]; + 'TransactionType' => $this->mapTxType($txType), + 'OrderId' => (string) $order->id, + 'CurrencyAmount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'ClientIp' => (string) $order->ip, + 'TransactionDeviceSource' => '0', + ]; - if ($card) { - $requestData['Pan'] = $card->getNumber(); - $requestData['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_LONG_FORMAT); - $requestData['Cvv'] = $card->getCvv(); + if ($card instanceof AbstractCreditCard) { + $requestData['Pan'] = $card->getNumber(); + $requestData['Expiry'] = $card->getExpirationDate(self::CREDIT_CARD_EXP_DATE_LONG_FORMAT); + $requestData['Cvv'] = $card->getCvv(); } return $requestData; @@ -159,17 +167,24 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $account, $ * @param $order * @param AbstractCreditCard|null $card * - * @return array + * @return array{TransactionType: string, + * ReferenceTransactionId: string, + * CurrencyAmount: string, + * CurrencyCode: string, + * ClientIp: string, + * MerchantId: string, + * Password: string, + * TerminalNo: string} */ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $account, $order, ?AbstractCreditCard $card = null): array { return $this->getRequestAccountData($account) + [ - 'TransactionType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), - 'ReferenceTransactionId' => $order->id, - 'CurrencyAmount' => self::amountFormat($order->amount), - 'CurrencyCode' => $this->mapCurrency($order->currency), - 'ClientIp' => $order->ip, - ]; + 'TransactionType' => $this->mapTxType(AbstractGateway::TX_POST_PAY), + 'ReferenceTransactionId' => (string) $order->id, + 'CurrencyAmount' => self::amountFormat($order->amount), + 'CurrencyCode' => $this->mapCurrency($order->currency), + 'ClientIp' => (string) $order->ip, + ]; } /** @@ -182,6 +197,8 @@ public function createStatusRequestData(AbstractPosAccount $account, $order): ar /** * {@inheritDoc} + * @return array{MerchantId: string, Password: string, TransactionType: string, + * ReferenceTransactionId: string, ClientIp: string} */ public function createCancelRequestData(AbstractPosAccount $account, $order): array { @@ -189,13 +206,15 @@ public function createCancelRequestData(AbstractPosAccount $account, $order): ar 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), 'TransactionType' => $this->mapTxType(AbstractGateway::TX_CANCEL), - 'ReferenceTransactionId' => $order->id, - 'ClientIp' => $order->ip, + 'ReferenceTransactionId' => (string) $order->id, + 'ClientIp' => (string) $order->ip, ]; } /** * {@inheritDoc} + * @return array{MerchantId: string, Password: string, TransactionType: string, ReferenceTransactionId: string, + * ClientIp: string, CurrencyAmount: string} */ public function createRefundRequestData(AbstractPosAccount $account, $order): array { @@ -203,8 +222,8 @@ public function createRefundRequestData(AbstractPosAccount $account, $order): ar 'MerchantId' => $account->getClientId(), 'Password' => $account->getPassword(), 'TransactionType' => $this->mapTxType(AbstractGateway::TX_REFUND), - 'ReferenceTransactionId' => $order->id, - 'ClientIp' => $order->ip, + 'ReferenceTransactionId' => (string) $order->id, + 'ClientIp' => (string) $order->ip, 'CurrencyAmount' => self::amountFormat($order->amount), ]; } @@ -218,9 +237,11 @@ public function createHistoryRequestData(AbstractPosAccount $account, $order, ar } /** - * @param array $extraData - * * {@inheritDoc} + * + * @param array{PaReq: string, TermUrl: string, MD: string, ACSUrl: string} $extraData + * + * @return array{gateway: string, method: 'POST', inputs: array{PaReq: string, TermUrl: string, MD: string}} */ public function create3DFormData(AbstractPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null, array $extraData = []): array { @@ -232,6 +253,7 @@ public function create3DFormData(AbstractPosAccount $account, $order, string $tx return [ 'gateway' => $extraData['ACSUrl'], + 'method' => 'POST', 'inputs' => $inputs, ]; } @@ -248,18 +270,15 @@ public static function amountFormat(float $amount): string return number_format($amount, 2, '.', ''); } - /** - * {@inheritDoc} - */ - public function mapInstallment(?int $installment) + public function mapInstallment(?int $installment): string { - return $installment > 1 ? $installment : 0; + return $installment > 1 ? (string) $installment : '0'; } /** * @param VakifBankAccount $account * - * @return array + * @return array{MerchantId: string, Password: string, TerminalNo: string} */ private function getRequestAccountData(AbstractPosAccount $account): array { diff --git a/src/Entity/Account/AbstractPosAccount.php b/src/Entity/Account/AbstractPosAccount.php index 70337eec..81f5a3ef 100644 --- a/src/Entity/Account/AbstractPosAccount.php +++ b/src/Entity/Account/AbstractPosAccount.php @@ -6,32 +6,30 @@ abstract class AbstractPosAccount { - /** - * @var string - */ + /** @var string */ protected $clientId; + /** * account models: regular, 3d, 3d_pay, 3d_host * @var string */ protected $model; - /** - * @var string - */ + + /** @var string */ protected $username; - /** - * @var string - */ + + /** @var string */ protected $password; + /** * required for non regular account models * @var string|null */ protected $storeKey; - /** - * @var string - */ + + /** @var string */ protected $lang; + /** * bank key name used in configuration file * diff --git a/src/Entity/Account/GarantiPosAccount.php b/src/Entity/Account/GarantiPosAccount.php index b89ef364..ebb8cf62 100644 --- a/src/Entity/Account/GarantiPosAccount.php +++ b/src/Entity/Account/GarantiPosAccount.php @@ -9,17 +9,13 @@ */ class GarantiPosAccount extends AbstractPosAccount { - /** - * @var string - */ + /** @var string */ private $terminalId; - /** - * @var string - */ + + /** @var string */ private $refundUsername; - /** - * @var string - */ + + /** @var string */ private $refundPassword; public function __construct( diff --git a/src/Entity/Account/VakifBankAccount.php b/src/Entity/Account/VakifBankAccount.php index 0cf6cc6a..bfbc2ad5 100644 --- a/src/Entity/Account/VakifBankAccount.php +++ b/src/Entity/Account/VakifBankAccount.php @@ -4,27 +4,28 @@ class VakifBankAccount extends AbstractPosAccount { + /** @var int */ public const MERCHANT_TYPE_STANDARD = 0; + + /** @var int */ public const MERCHANT_TYPE_MAIN_DEALER = 1; + + /** @var int */ public const MERCHANT_TYPE_SUB_DEALER = 2; - /** - * @var int[] - */ + /** @var int[] */ private static $merchantTypes = [ self::MERCHANT_TYPE_STANDARD, self::MERCHANT_TYPE_MAIN_DEALER, self::MERCHANT_TYPE_SUB_DEALER, ]; - /** - * @var string - */ + /** @var string */ private $terminalId; /** * Banka tarafından Üye işyerine iletilmektedir - * @var int + * @var self::MERCHANT_TYPE_* */ private $merchantType; @@ -43,13 +44,13 @@ class VakifBankAccount extends AbstractPosAccount /** * VakifBankAccount constructor. * - * @param string $bank - * @param string $model - * @param string $merchantId Isyeri No - * @param string $password Isyeri Sifre - * @param string $terminalId Terminal No - * @param int $merchantType - * @param string|null $subMerchantId + * @param string $bank + * @param string $model + * @param string $merchantId Isyeri No + * @param string $password Isyeri Sifre + * @param string $terminalId Terminal No + * @param self::MERCHANT_TYPE_* $merchantType + * @param string|null $subMerchantId */ public function __construct( string $bank, @@ -57,13 +58,14 @@ public function __construct( string $merchantId, string $password, string $terminalId, - int $merchantType = self::MERCHANT_TYPE_STANDARD, + int $merchantType = self::MERCHANT_TYPE_STANDARD, string $subMerchantId = null - ) { + ) + { parent::__construct($bank, $model, $merchantId, '', $password, 'tr'); - $this->model = $model; - $this->terminalId = $terminalId; - $this->merchantType = $merchantType; + $this->model = $model; + $this->terminalId = $terminalId; + $this->merchantType = $merchantType; $this->subMerchantId = $subMerchantId; } diff --git a/src/Entity/Card/AbstractCreditCard.php b/src/Entity/Card/AbstractCreditCard.php index c5601254..fbde0dbd 100644 --- a/src/Entity/Card/AbstractCreditCard.php +++ b/src/Entity/Card/AbstractCreditCard.php @@ -9,9 +9,16 @@ */ abstract class AbstractCreditCard { + /** @var string */ public const CARD_TYPE_VISA = 'visa'; + + /** @var string */ public const CARD_TYPE_MASTERCARD = 'master'; + + /** @var string */ public const CARD_TYPE_AMEX = 'amex'; + + /** @var string */ public const CARD_TYPE_TROY = 'troy'; /** diff --git a/src/Exceptions/CardTypeRequiredException.php b/src/Exceptions/CardTypeRequiredException.php index 4785b128..9de0549d 100644 --- a/src/Exceptions/CardTypeRequiredException.php +++ b/src/Exceptions/CardTypeRequiredException.php @@ -10,9 +10,7 @@ */ class CardTypeRequiredException extends DomainException { - /** - * @var string - */ + /** @var string */ private $gatewayName; /** diff --git a/src/Factory/AccountFactory.php b/src/Factory/AccountFactory.php index 244a228c..1e1d1376 100644 --- a/src/Factory/AccountFactory.php +++ b/src/Factory/AccountFactory.php @@ -123,13 +123,13 @@ public static function createPosNetAccount(string $bank, string $merchantId, str } /** - * @param string $bank - * @param string $merchantId Üye işyeri numarası - * @param string $password Üye işyeri şifres - * @param string $terminalNo İşlemin hangi terminal üzerinden gönderileceği bilgisi. VB007000... - * @param string $model - * @param int $merchantType - * @param null $subMerchantId + * @param string $bank + * @param string $merchantId Üye işyeri numarası + * @param string $password Üye işyeri şifres + * @param string $terminalNo İşlemin hangi terminal üzerinden gönderileceği bilgisi. VB007000... + * @param string $model + * @param VakifBankAccount::MERCHANT_TYPE_* $merchantType + * @param null $subMerchantId * * @return VakifBankAccount * @@ -172,9 +172,15 @@ public static function createInterPosAccount(string $bank, string $shopCode, str */ private static function checkParameters(string $model, ?string $storeKey) { - if (AbstractGateway::MODEL_NON_SECURE !== $model && null === $storeKey) { - throw new MissingAccountInfoException("$model requires storeKey!"); + if (AbstractGateway::MODEL_NON_SECURE === $model) { + return; } + + if (null !== $storeKey) { + return; + } + + throw new MissingAccountInfoException(sprintf('%s requires storeKey!', $model)); } /** @@ -190,6 +196,7 @@ private static function checkVakifBankMerchantType(int $merchantType, ?string $s if (VakifBankAccount::MERCHANT_TYPE_SUB_DEALER === $merchantType && empty($subMerchantId)) { throw new MissingAccountInfoException('SubMerchantId is required for sub branches!'); } + if (!in_array($merchantType, VakifBankAccount::getMerchantTypes())) { throw new MissingAccountInfoException('Invalid MerchantType!'); } diff --git a/src/Factory/CreditCardFactory.php b/src/Factory/CreditCardFactory.php index 6bb82a5e..36fc6658 100644 --- a/src/Factory/CreditCardFactory.php +++ b/src/Factory/CreditCardFactory.php @@ -46,14 +46,16 @@ public static function create( $expireMonth = str_pad($expireMonth, 2, '0', STR_PAD_LEFT); $expDate = DateTimeImmutable::createFromFormat('Ymd', $expireYear.$expireMonth.'01'); - if (!$expDate) { + if (! $expDate instanceof DateTimeImmutable) { throw new DomainException('INVALID DATE FORMAT'); } + $supportedCardTypes = array_keys($pos->getCardTypeMapping()); - if (!empty($supportedCardTypes) && empty($cardType)) { + if ($supportedCardTypes !== [] && empty($cardType)) { throw new CardTypeRequiredException($pos::NAME); } - if (!empty($supportedCardTypes) && !in_array($cardType, $supportedCardTypes)) { + + if ($supportedCardTypes !== [] && !in_array($cardType, $supportedCardTypes)) { throw new CardTypeNotSupportedException($cardType); } diff --git a/src/Factory/PosFactory.php b/src/Factory/PosFactory.php index e66e1ce6..adeab91a 100644 --- a/src/Factory/PosFactory.php +++ b/src/Factory/PosFactory.php @@ -2,6 +2,7 @@ /** * @license MIT */ + namespace Mews\Pos\Factory; use DomainException; @@ -14,6 +15,7 @@ use Mews\Pos\Crypt\KuveytPosCrypt; use Mews\Pos\Crypt\PayForPosCrypt; use Mews\Pos\Crypt\PosNetCrypt; +use Mews\Pos\Crypt\VakifBankCPCrypt; use Mews\Pos\DataMapper\AbstractRequestDataMapper; use Mews\Pos\DataMapper\EstPosRequestDataMapper; use Mews\Pos\DataMapper\EstV3PosRequestDataMapper; @@ -29,7 +31,9 @@ use Mews\Pos\DataMapper\ResponseDataMapper\KuveytPosResponseDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\PayForPosResponseDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\PosNetResponseDataMapper; +use Mews\Pos\DataMapper\ResponseDataMapper\VakifBankCPPosResponseDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\VakifBankPosResponseDataMapper; +use Mews\Pos\DataMapper\VakifBankCPPosRequestDataMapper; use Mews\Pos\DataMapper\VakifBankPosRequestDataMapper; use Mews\Pos\Entity\Account\AbstractPosAccount; use Mews\Pos\Exceptions\BankClassNullException; @@ -41,6 +45,7 @@ use Mews\Pos\Gateways\KuveytPos; use Mews\Pos\Gateways\PayForPos; use Mews\Pos\Gateways\PosNet; +use Mews\Pos\Gateways\VakifBankCPPos; use Mews\Pos\Gateways\VakifBankPos; use Mews\Pos\PosInterface; use Psr\Log\LoggerInterface; @@ -69,12 +74,14 @@ public static function createPosGateway( ?LoggerInterface $logger = null ): PosInterface { - if (!$logger) { + if ($logger === null) { $logger = new NullLogger(); } - if (!$client) { + + if ($client === null) { $client = HttpClientFactory::createDefaultHttpClient(); } + if (is_string($config)) { $config = require $config; } elseif (empty($config)) { @@ -86,10 +93,10 @@ public static function createPosGateway( throw new BankNotFoundException(); } - /** @var class-string $class Gateway Class*/ - $class = $config['banks'][$posAccount->getBank()]['class']; + /** @var class-string|null $class Gateway Class */ + $class = $config['banks'][$posAccount->getBank()]['class'] ?? null; - if (!$class) { + if (null === $class) { throw new BankClassNullException(); } @@ -97,6 +104,7 @@ public static function createPosGateway( if (isset($config['currencies'])) { $currencies = $config['currencies']; } + $logger->debug('creating gateway for bank', ['bank' => $posAccount->getBank()]); $crypt = self::getGatewayCrypt($class, $logger); @@ -115,36 +123,36 @@ public static function createPosGateway( } /** - * @param class-string $gatewayClass - * @param array $currencies - * @param CryptInterface|null $crypt + * @param class-string $gatewayClass + * @param array $currencies + * @param CryptInterface|null $crypt * * @return AbstractRequestDataMapper */ public static function getGatewayRequestMapper(string $gatewayClass, array $currencies = [], ?CryptInterface $crypt = null): AbstractRequestDataMapper { - if (null !== $crypt) { - switch ($gatewayClass) { - case EstPos::class: - return new EstPosRequestDataMapper($crypt, $currencies); - case EstV3Pos::class: - return new EstV3PosRequestDataMapper($crypt, $currencies); - case GarantiPos::class: - return new GarantiPosRequestDataMapper($crypt, $currencies); - case InterPos::class: - return new InterPosRequestDataMapper($crypt, $currencies); - case KuveytPos::class: - return new KuveytPosRequestDataMapper($crypt, $currencies); - case PayForPos::class: - return new PayForPosRequestDataMapper($crypt, $currencies); - case PosNet::class: - return new PosNetRequestDataMapper($crypt, $currencies); + $classMappings = [ + EstPos::class => EstPosRequestDataMapper::class, + EstV3Pos::class => EstV3PosRequestDataMapper::class, + GarantiPos::class => GarantiPosRequestDataMapper::class, + InterPos::class => InterPosRequestDataMapper::class, + KuveytPos::class => KuveytPosRequestDataMapper::class, + PayForPos::class => PayForPosRequestDataMapper::class, + PosNet::class => PosNetRequestDataMapper::class, + VakifBankCPPos::class => VakifBankCPPosRequestDataMapper::class, + ]; + if (isset($classMappings[$gatewayClass])) { + if (null === $crypt) { + throw new \InvalidArgumentException(sprintf('Gateway %s requires Crypt instance', $gatewayClass)); } + + return new $classMappings[$gatewayClass]($crypt, $currencies); } - switch ($gatewayClass) { - case VakifBankPos::class: - return new VakifBankPosRequestDataMapper(null, $currencies); + + if ($gatewayClass === VakifBankPos::class) { + return new VakifBankPosRequestDataMapper(null, $currencies); } + throw new DomainException('unsupported gateway'); } @@ -157,25 +165,26 @@ public static function getGatewayRequestMapper(string $gatewayClass, array $curr */ public static function getGatewayResponseMapper(string $gatewayClass, AbstractRequestDataMapper $requestDataMapper, LoggerInterface $logger): AbstractResponseDataMapper { - $currencyMappings = $requestDataMapper->getCurrencyMappings(); - $txMappings = $requestDataMapper->getTxTypeMappings(); - switch ($gatewayClass) { - case EstV3Pos::class: - case EstPos::class: - return new EstPosResponseDataMapper($currencyMappings, $txMappings, $logger); - case GarantiPos::class: - return new GarantiPosResponseDataMapper($currencyMappings, $txMappings, $logger); - case InterPos::class: - return new InterPosResponseDataMapper($currencyMappings, $txMappings, $logger); - case KuveytPos::class: - return new KuveytPosResponseDataMapper($currencyMappings, $txMappings, $logger); - case PayForPos::class: - return new PayForPosResponseDataMapper($currencyMappings, $txMappings, $logger); - case PosNet::class: - return new PosNetResponseDataMapper($currencyMappings, $txMappings, $logger); - case VakifBankPos::class: - return new VakifBankPosResponseDataMapper($currencyMappings, $txMappings, $logger); + $classMappings = [ + EstV3Pos::class => EstPosResponseDataMapper::class, + EstPos::class => EstPosResponseDataMapper::class, + GarantiPos::class => GarantiPosResponseDataMapper::class, + InterPos::class => InterPosResponseDataMapper::class, + KuveytPos::class => KuveytPosResponseDataMapper::class, + PayForPos::class => PayForPosResponseDataMapper::class, + PosNet::class => PosNetResponseDataMapper::class, + VakifBankPos::class => VakifBankPosResponseDataMapper::class, + VakifBankCPPos::class => VakifBankCPPosResponseDataMapper::class, + ]; + + if (isset($classMappings[$gatewayClass])) { + return new $classMappings[$gatewayClass]( + $requestDataMapper->getCurrencyMappings(), + $requestDataMapper->getTxTypeMappings(), + $logger + ); } + throw new DomainException('unsupported gateway'); } @@ -187,23 +196,21 @@ public static function getGatewayResponseMapper(string $gatewayClass, AbstractRe */ public static function getGatewayCrypt(string $gatewayClass, LoggerInterface $logger): ?CryptInterface { - switch ($gatewayClass) { - case EstV3Pos::class: - return new EstV3PosCrypt($logger); - case EstPos::class: - return new EstPosCrypt($logger); - case GarantiPos::class: - return new GarantiPosCrypt($logger); - case InterPos::class: - return new InterPosCrypt($logger); - case KuveytPos::class: - return new KuveytPosCrypt($logger); - case PayForPos::class: - return new PayForPosCrypt($logger); - case PosNet::class: - return new PosNetCrypt($logger); - default: - return null; + $classMappings = [ + EstV3Pos::class => EstV3PosCrypt::class, + EstPos::class => EstPosCrypt::class, + GarantiPos::class => GarantiPosCrypt::class, + InterPos::class => InterPosCrypt::class, + KuveytPos::class => KuveytPosCrypt::class, + PayForPos::class => PayForPosCrypt::class, + PosNet::class => PosNetCrypt::class, + VakifBankCPPos::class => VakifBankCPCrypt::class, + ]; + + if (isset($classMappings[$gatewayClass])) { + return new $classMappings[$gatewayClass]($logger); } + + return null; } } diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 4177bec4..f9e8e012 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -25,26 +25,50 @@ */ abstract class AbstractGateway implements PosInterface { - + /** @var string */ public const LANG_TR = 'tr'; + + /** @var string */ public const LANG_EN = 'en'; + /** @var string */ public const TX_PAY = 'pay'; + + /** @var string */ public const TX_PRE_PAY = 'pre'; + + /** @var string */ public const TX_POST_PAY = 'post'; + + /** @var string */ public const TX_CANCEL = 'cancel'; + + /** @var string */ public const TX_REFUND = 'refund'; + + /** @var string */ public const TX_STATUS = 'status'; + + /** @var string */ public const TX_HISTORY = 'history'; + /** @var string */ public const MODEL_3D_SECURE = '3d'; + + /** @var string */ public const MODEL_3D_PAY = '3d_pay'; + + /** @var string */ public const MODEL_3D_PAY_HOSTING = '3d_pay_hosting'; + + /** @var string */ public const MODEL_3D_HOST = '3d_host'; + + /** @var string */ public const MODEL_NON_SECURE = 'regular'; /** @var array */ - private $config; + protected $config; /** @var AbstractPosAccount */ protected $account; @@ -59,9 +83,7 @@ abstract class AbstractGateway implements PosInterface */ protected $type; - /** - * @var object|null - */ + /** @var object|null */ protected $order; /** @@ -139,6 +161,7 @@ public function prepare(array $order, string $txType, $card = null) $this->order = $this->prepareHistoryOrder($order); break; } + $this->logger->log(LogLevel::DEBUG, 'gateway prepare - order is prepared', [$this->order]); $this->card = $card; @@ -153,7 +176,7 @@ public function getResponse(): ?array } /** - * @return array + * @return non-empty-array */ public function getCurrencies(): array { @@ -248,7 +271,7 @@ public function get3DGatewayURL(): string */ public function get3DHostGatewayURL(): ?string { - return isset($this->config['urls']['gateway_3d_host'][$this->getModeInWord()]) ? $this->config['urls']['gateway_3d_host'][$this->getModeInWord()] : null; + return $this->config['urls']['gateway_3d_host'][$this->getModeInWord()] ?? null; } /** @@ -284,7 +307,7 @@ public function payment($card = null) $model = $this->account->getModel(); $this->logger->log(LogLevel::DEBUG, 'payment called', [ - 'card_provided' => !!$this->card, + 'card_provided' => (bool) $this->card, 'model' => $model, ]); if (self::MODEL_NON_SECURE === $model) { @@ -463,7 +486,7 @@ abstract public function create3DPaymentXML($responseData); /** * returns form data, key values, necessary for 3D payment * - * @return array + * @return array{gateway: string, method: 'POST'|'GET', inputs: array} */ abstract public function get3DFormData(): array; @@ -550,8 +573,8 @@ protected function XMLStringToArray(string $data, array $context = []): array * return values are used as a key in config file * @return string */ - private function getModeInWord(): string + protected function getModeInWord(): string { - return !$this->isTestMode() ? 'production' : 'test'; + return $this->isTestMode() ? 'test' : 'production'; } } diff --git a/src/Gateways/EstPos.php b/src/Gateways/EstPos.php index 0f419115..0b14a5ae 100644 --- a/src/Gateways/EstPos.php +++ b/src/Gateways/EstPos.php @@ -4,6 +4,7 @@ */ namespace Mews\Pos\Gateways; +use LogicException; use Mews\Pos\Entity\Account\EstPosAccount; use Mews\Pos\Exceptions\HashMismatchException; use Psr\Log\LogLevel; @@ -18,14 +19,10 @@ */ class EstPos extends AbstractGateway { - /** - * @const string - */ + /** @var string */ public const NAME = 'EstPos'; - /** - * @var EstPosAccount - */ + /** @var EstPosAccount */ protected $account; /** @@ -75,6 +72,7 @@ public function make3DPayPayment(Request $request) if (!$this->requestDataMapper->getCrypt()->check3DHash($this->account, $request->request->all())) { throw new HashMismatchException(); } + $this->response = $this->responseDataMapper->map3DPayResponseData($request->request->all()); return $this; @@ -88,6 +86,7 @@ public function make3DHostPayment(Request $request) if (!$this->requestDataMapper->getCrypt()->check3DHash($this->account, $request->request->all())) { throw new HashMismatchException(); } + $this->response = $this->responseDataMapper->map3DHostResponseData($request->request->all()); return $this; @@ -98,10 +97,12 @@ public function make3DHostPayment(Request $request) */ public function get3DFormData(): array { - if (!$this->order) { + if ($this->order === null) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order'); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card); diff --git a/src/Gateways/GarantiPos.php b/src/Gateways/GarantiPos.php index 57e2274d..c956a6b8 100644 --- a/src/Gateways/GarantiPos.php +++ b/src/Gateways/GarantiPos.php @@ -4,6 +4,7 @@ */ namespace Mews\Pos\Gateways; +use LogicException; use Mews\Pos\DataMapper\GarantiPosRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\GarantiPosResponseDataMapper; use Mews\Pos\Entity\Account\GarantiPosAccount; @@ -17,9 +18,7 @@ */ class GarantiPos extends AbstractGateway { - /** - * @const string - */ + /** @var string */ public const NAME = 'GarantiPay'; /** @var GarantiPosAccount */ @@ -58,6 +57,7 @@ public function make3DPayment(Request $request) // todo mdstatus 7 oldugunda hash, hashparam deger gelmiyor, check3dhash calismiyor throw new HashMismatchException(); } + if (in_array($request->get('mdstatus'), [1, 2, 3, 4])) { $this->logger->log(LogLevel::DEBUG, 'finishing payment', ['md_status' => $request->get('mdstatus')]); $contents = $this->create3DPaymentXML($request->all()); @@ -102,10 +102,12 @@ public function send($contents, ?string $url = null) */ public function get3DFormData(): array { - if (!$this->order) { + if ($this->order === null) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order'); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card); diff --git a/src/Gateways/InterPos.php b/src/Gateways/InterPos.php index 131d56c4..5d289361 100644 --- a/src/Gateways/InterPos.php +++ b/src/Gateways/InterPos.php @@ -4,6 +4,7 @@ */ namespace Mews\Pos\Gateways; +use LogicException; use Mews\Pos\DataMapper\InterPosRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\InterPosResponseDataMapper; use Mews\Pos\Entity\Account\InterPosAccount; @@ -18,9 +19,7 @@ */ class InterPos extends AbstractGateway { - /** - * @const string - */ + /** @var string */ public const NAME = 'InterPos'; /** @var InterPosAccount */ @@ -47,7 +46,8 @@ public function send($contents, ?string $url = null) { $url = $url ?: $this->getApiURL(); $this->logger->log(LogLevel::DEBUG, 'sending request', ['url' => $url]); - $response = $this->client->post($url, ['form_params' => $contents]); + $payload = is_array($contents) ? ['form_params' => $contents] : ['body' => $contents]; + $response = $this->client->post($url, $payload); $this->logger->log(LogLevel::DEBUG, 'request completed', ['status_code' => $response->getStatusCode()]); //genelde ;; delimiter kullanilmis, ama bazen arasinda ;;; boyle delimiter de var. @@ -70,6 +70,7 @@ public function make3DPayment(Request $request) { $bankResponse = null; $request = $request->request; + /** @var array{MD: string, PayerTxnId: string, Eci: string, PayerAuthenticationCode: string} $gatewayResponse */ $gatewayResponse = $request->all(); if (!$this->requestDataMapper->getCrypt()->check3DHash($this->account, $gatewayResponse)) { @@ -126,16 +127,23 @@ public function history(array $meta) */ public function get3DFormData(): array { - if (!$this->order) { + if ($this->order === null) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order'); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } + $gatewayUrl = $this->get3DHostGatewayURL(); if (self::MODEL_3D_SECURE === $this->account->getModel()) { $gatewayUrl = $this->get3DGatewayURL(); } elseif (self::MODEL_3D_PAY === $this->account->getModel()) { $gatewayUrl = $this->get3DGatewayURL(); } + + if (null === $gatewayUrl) { + throw new LogicException('Gateway URL\' bulunamadı!'); + } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $gatewayUrl, $this->card); @@ -151,6 +159,7 @@ public function createRegularPaymentXML() /** * @inheritDoc + * @return array{TxnType: string, SecureType: string, OrderId: null, orgOrderId: mixed, PurchAmount: mixed, Currency: string, MOTO: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createRegularPostXML() { @@ -159,6 +168,8 @@ public function createRegularPostXML() /** * @inheritDoc + * + * @param array{MD: string, PayerTxnId: string, Eci: string, PayerAuthenticationCode: string} $responseData */ public function create3DPaymentXML($responseData) { @@ -175,6 +186,7 @@ public function createHistoryXML($customQueryData) /** * @inheritDoc + * @return array{OrderId: null, orgOrderId: string, TxnType: string, SecureType: string, Lang: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createStatusXML() { @@ -183,6 +195,7 @@ public function createStatusXML() /** * @inheritDoc + * @return array{OrderId: null, orgOrderId: string, TxnType: string, SecureType: string, Lang: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createCancelXML() { @@ -191,6 +204,7 @@ public function createCancelXML() /** * @inheritDoc + * @return array{OrderId: null, orgOrderId: string, PurchAmount: string, TxnType: string, SecureType: string, Lang: string, MOTO: string, UserCode: string, UserPass: string, ShopCode: string} */ public function createRefundXML() { diff --git a/src/Gateways/KuveytPos.php b/src/Gateways/KuveytPos.php index 883721ec..49a1d22f 100644 --- a/src/Gateways/KuveytPos.php +++ b/src/Gateways/KuveytPos.php @@ -7,6 +7,7 @@ use DOMDocument; use DOMNodeList; use Exception; +use LogicException; use Mews\Pos\DataMapper\KuveytPosRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\KuveytPosResponseDataMapper; use Mews\Pos\Entity\Account\KuveytPosAccount; @@ -21,6 +22,7 @@ */ class KuveytPos extends AbstractGateway { + /** @var string */ public const NAME = 'KuveytPos'; /** @var KuveytPosAccount */ @@ -67,10 +69,11 @@ public function send($contents, string $url = null) $responseBody = $response->getBody()->getContents(); try { $this->data = $this->XMLStringToArray($responseBody); - } catch (Exception $e) { + } catch (Exception $exception) { if (!$this->isHTML($responseBody)) { - throw new Exception($responseBody); + throw new Exception($responseBody, $exception->getCode(), $exception); } + //icinde form olan HTML response dondu $this->data = $responseBody; } @@ -87,14 +90,17 @@ public function make3DPayment(Request $request) if (!is_string($gatewayResponse)) { throw new \LogicException('AuthenticationResponse is missing'); } + $gatewayResponse = urldecode($gatewayResponse); $gatewayResponse = $this->XMLStringToArray($gatewayResponse); + $bankResponse = null; $procReturnCode = $gatewayResponse['ResponseCode']; if (!$this->requestDataMapper->getCrypt()->check3DHash($this->account, $gatewayResponse)) { throw new HashMismatchException(); } + if ($this->responseDataMapper::PROCEDURE_SUCCESS_CODE === $procReturnCode) { $this->logger->log(LogLevel::DEBUG, 'finishing payment'); @@ -263,14 +269,14 @@ protected function prepareRefundOrder(array $order) * @param string $gatewayURL * @param AbstractCreditCard|null $card * - * @return array + * @return array{gateway: string, method: 'POST', inputs: array} * * @throws Exception */ private function getCommon3DFormData(KuveytPosAccount $account, $order, string $txType, string $gatewayURL, ?AbstractCreditCard $card = null): array { if (!$order) { - return []; + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } $formData = $this->requestDataMapper->create3DEnrollmentCheckRequestData($account, $order, $txType, $card); @@ -285,7 +291,7 @@ private function getCommon3DFormData(KuveytPosAccount $account, $order, string $ * Kutupahenin islem akisina uymasi icin bu HTML form verilerini array'e donusturup, kendimiz post ediyoruz. * @param string $response * - * @return array + * @return array{gateway: string, method: 'POST', inputs: array} */ private function transformReceived3DFormData(string $response): array { @@ -315,6 +321,7 @@ private function transformReceived3DFormData(string $response): array return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } @@ -342,11 +349,13 @@ private function builtInputsFromHTMLDoc(DOMNodeList $inputNodes): array /** @var string|null $key */ $key = $attribute->value; } + if ('value' === $attribute->name) { /** @var string|null $value */ $value = $attribute->value; } } + if ($key && null !== $value && !in_array($key, ['submit', 'submitBtn'])) { $inputs[$key] = $value; } diff --git a/src/Gateways/PayForPos.php b/src/Gateways/PayForPos.php index f4582c5b..b0a150fd 100644 --- a/src/Gateways/PayForPos.php +++ b/src/Gateways/PayForPos.php @@ -4,6 +4,7 @@ */ namespace Mews\Pos\Gateways; +use LogicException; use Mews\Pos\DataMapper\PayForPosRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\PayForPosResponseDataMapper; use Mews\Pos\Entity\Account\PayForAccount; @@ -17,14 +18,10 @@ */ class PayForPos extends AbstractGateway { - /** - * @const string - */ + /** @var string */ public const NAME = 'PayForPOS'; - /** - * @var PayForAccount - */ + /** @var PayForAccount */ protected $account; /** @var PayForPosRequestDataMapper */ @@ -51,6 +48,7 @@ public function make3DPayment(Request $request) if (!$this->requestDataMapper->getCrypt()->check3DHash($this->account, $request->all())) { throw new HashMismatchException(); } + //if customer 3d verification passed finish payment if ('1' === $request->get('3DStatus')) { //valid ProcReturnCode is V033 in case of success 3D Authentication @@ -116,22 +114,26 @@ public function history(array $meta) /** - * returns form data needed for 3d, 3d_pay and 3d_host models - * - * @return array + * {@inheritDoc} */ public function get3DFormData(): array { - if (!$this->order) { + if ($this->order === null) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order'); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); $gatewayURL = $this->get3DGatewayURL(); if (self::MODEL_3D_HOST === $this->account->getModel()) { $gatewayURL = $this->get3DHostGatewayURL(); } + + if (null === $gatewayURL) { + throw new LogicException('Gateway URL\' bulunamadı!'); + } return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $gatewayURL, $this->card); } @@ -167,7 +169,7 @@ public function send($contents, ?string $url = null) try { $this->data = $this->XMLStringToArray($response); - } catch (NotEncodableValueException $e) { + } catch (NotEncodableValueException $notEncodableValueException) { //Finansbank's history request response is in JSON format $this->data = json_decode($response, true); } diff --git a/src/Gateways/PosNet.php b/src/Gateways/PosNet.php index cc93a37a..da4d942c 100644 --- a/src/Gateways/PosNet.php +++ b/src/Gateways/PosNet.php @@ -5,6 +5,7 @@ namespace Mews\Pos\Gateways; use Exception; +use LogicException; use Mews\Pos\DataMapper\PosNetRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\PosNetResponseDataMapper; use Mews\Pos\Entity\Account\PosNetAccount; @@ -18,6 +19,7 @@ */ class PosNet extends AbstractGateway { + /** @var string */ public const NAME = 'PosNet'; /** @var PosNetAccount */ @@ -98,6 +100,7 @@ public function make3DPayment(Request $request) 'md_status' => $userVerifyResponse['oosResolveMerchantDataResponse']['mdStatus'], ]); } + end: $this->response = $this->responseDataMapper->map3DPaymentData($userVerifyResponse, $bankResponse); $this->logger->log(LogLevel::DEBUG, 'finished 3D payment', ['mapped_response' => $this->response]); @@ -121,9 +124,10 @@ public function get3DFormData(): array if (!$this->card || !$this->order) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order', [ 'order' => $this->order, - 'card_provided' => !!$this->card, + 'card_provided' => (bool) $this->card, ]); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } $data = $this->getOosTransactionData(); @@ -132,6 +136,7 @@ public function get3DFormData(): array $this->logger->log(LogLevel::ERROR, 'enrollment fail response', $data); throw new Exception($data['respText']); } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, $this->get3DGatewayURL(), $this->card, $data['oosRequestDataResponse']); @@ -145,13 +150,17 @@ public function send($contents, ?string $url = null) $url = $this->getApiURL(); $this->logger->log(LogLevel::DEBUG, 'sending request', ['url' => $url]); - /** @phpstan-ignore-next-line */ - $response = $this->client->post($url, [ - 'headers' => [ - 'Content-Type' => 'application/x-www-form-urlencoded', - ], - 'body' => "xmldata=$contents", - ]); + if (is_string($contents)) { + $response = $this->client->post($url, [ + 'headers' => [ + 'Content-Type' => 'application/x-www-form-urlencoded', + ], + 'body' => sprintf('xmldata=%s', $contents), + ]); + } else { + $response = $this->client->post($url, ['form_params' => $contents]); + } + $this->logger->log(LogLevel::DEBUG, 'request completed', ['status_code' => $response->getStatusCode()]); $this->data = $this->XMLStringToArray($response->getBody()->getContents()); diff --git a/src/Gateways/VakifBankCPPos.php b/src/Gateways/VakifBankCPPos.php new file mode 100644 index 00000000..e51da3e7 --- /dev/null +++ b/src/Gateways/VakifBankCPPos.php @@ -0,0 +1,353 @@ +account; + } + + /** + * todo implement + * @inheritDoc + */ + public function make3DPayment(Request $request) + { + throw new UnsupportedPaymentModelException(); + } + + /** + * @inheritDoc + */ + public function make3DPayPayment(Request $request): self + { + $resultCode = $request->query->get('Rc'); + if (null !== $resultCode && $this->responseDataMapper::PROCEDURE_SUCCESS_CODE !== $resultCode) { + $this->logger->error('received error response from the bank', $request->query->all()); + $this->response = $this->responseDataMapper->map3DPayResponseData($request->query->all()); + + return $this; + } + + /** @var array{TransactionId: string, PaymentToken: string} $queryParams */ + $queryParams = $request->query->all(); + + $statusRequestData = $this->requestDataMapper->create3DPaymentStatusRequestData($this->account, $queryParams); + /** + * sending request to make sure that payment was successful + * @var array{ErrorCode: string}|array{ + * Rc: string, + * AuthCode: string, + * TransactionId: string, + * PaymentToken: string, + * MaskedPan: string}|array{ + * Rc: string, + * Message: string, + * TransactionId: string, + * PaymentToken: string} $bankResponse */ + $bankResponse = $this->send($statusRequestData, $this->getQueryAPIUrl()); + + $this->response = $this->responseDataMapper->map3DPayResponseData($bankResponse); + + $this->logger->log(LogLevel::DEBUG, 'finished 3D payment', ['mapped_response' => $this->response]); + + return $this; + } + + /** + * @inheritDoc + */ + public function make3DHostPayment(Request $request): self + { + return $this->make3DPayPayment($request); + } + + /** + * TODO implement + * @inheritDoc + */ + public function history(array $meta) + { + throw new UnsupportedPaymentModelException(); + } + + /** + * {@inheritDoc} + */ + public function get3DFormData(): array + { + if (null === $this->order) { + $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order', [ + 'order' => $this->order, + 'card_provided' => (bool) $this->card, + ]); + + throw new LogicException('Sipariş bilgileri eksik!'); + } + + /** @var array{CommonPaymentUrl: string|null, PaymentToken: string|null, ErrorCode: string|null, ResponseMessage: string|null} $data */ + $data = $this->registerPayment(); + + if (null !== $data['ErrorCode']) { + $this->logger->log(LogLevel::ERROR, 'payment register fail response', $data); + throw new Exception('İşlem gerçekleştirilemiyor'); + } + + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); + + return $this->requestDataMapper->create3DFormData( + null, + null, + null, + null, + null, + $data + ); + } + + /** + * @inheritDoc + */ + public function createXML(array $nodes, string $encoding = 'UTF-8', bool $ignorePiNode = true): string + { + return parent::createXML(['VposRequest' => $nodes], $encoding, $ignorePiNode); + } + + /** + * @inheritDoc + */ + public function send($contents, ?string $url = null) + { + $url = $url ?? $this->getApiURL(); + $this->logger->log(LogLevel::DEBUG, 'sending request', ['url' => $url]); + + $isXML = is_string($contents); + $body = $isXML ? ['body' => $contents] : ['form_params' => $contents]; + + $response = $this->client->post($url, $body); + $this->logger->log(LogLevel::DEBUG, 'request completed', ['status_code' => $response->getStatusCode()]); + + $responseBody = $response->getBody()->getContents(); + + try { + $this->data = $this->XMLStringToArray($responseBody); + } catch (NotEncodableValueException $notEncodableValueException) { + if ($this->isHTML($responseBody)) { + // if something wrong server responds with HTML content + throw new Exception($responseBody, $notEncodableValueException->getCode(), $notEncodableValueException); + } + + $this->data = json_decode($responseBody, true); + } + + return $this->data; + } + + /** + * @inheritDoc + */ + public function createRegularPaymentXML() + { + $requestData = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $this->order, $this->type, $this->card); + + return $this->createXML($requestData); + } + + /** + * @inheritDoc + */ + public function createRegularPostXML() + { + if (null === $this->order) { + throw new LogicException('sipariş bilgileri eksik!'); + } + + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); + + return $this->createXML($requestData); + } + + /** + * TODO implement + * @inheritDoc + */ + public function create3DPaymentXML($responseData) + { + throw new NotImplementedException(); + } + + /** + * TODO check if it is working + * @inheritDoc + */ + public function createStatusXML() + { + return $this->requestDataMapper->createStatusRequestData($this->account, $this->order); + } + + /** + * TODO check if it is working + * @inheritDoc + */ + public function createHistoryXML($customQueryData) + { + return $this->requestDataMapper->createHistoryRequestData($this->account, $this->order, $customQueryData); + } + + /** + * @inheritDoc + */ + public function createRefundXML() + { + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $this->order); + + return $this->createXML($requestData); + } + + /** + * @inheritDoc + */ + public function createCancelXML() + { + if (null === $this->order) { + $this->logger->log(LogLevel::ERROR, 'cancel data create without order data', [ + 'order' => $this->order, + ]); + + throw new LogicException('Sipariş bilgileri eksik!'); + } + + $requestData = $this->requestDataMapper->createCancelRequestData($this->account, $this->order); + + return $this->createXML($requestData); + } + + /** + * @inheritDoc + */ + protected function preparePaymentOrder(array $order) + { + return (object) array_merge($order, [ + 'installment' => $order['installment'] ?? 0, + 'currency' => $order['currency'] ?? 'TRY', + 'amount' => $order['amount'], + ]); + } + + /** + * @inheritDoc + */ + protected function preparePostPaymentOrder(array $order) + { + return (object) [ + 'id' => $order['id'], + 'amount' => $order['amount'], + 'currency' => $order['currency'] ?? 'TRY', + 'ip' => $order['ip'], + ]; + } + + /** + * @inheritDoc + */ + protected function prepareStatusOrder(array $order) + { + return (object) $order; + } + + /** + * @inheritDoc + */ + protected function prepareHistoryOrder(array $order) + { + return (object) [ + 'id' => $order['id'] ?? null, + ]; + } + + /** + * @inheritDoc + */ + protected function prepareCancelOrder(array $order) + { + return (object) $order; + } + + /** + * @inheritDoc + */ + protected function prepareRefundOrder(array $order) + { + return (object) $order; + } + + + /** + * @return string + */ + public function getQueryAPIUrl(): string + { + return $this->config['urls']['query'][$this->getModeInWord()]; + } + + + /** + * ORTAK ÖDEME SİSTEMİNE İŞLEM KAYDETME + * Basarili durumda donen cevap formati: array{CommonPaymentUrl: string, PaymentToken: string, ErrorCode: null, ResponseMessage: null} + * Basarisiz durumda donen cevap formati: array{CommonPaymentUrl: null, PaymentToken: null, ErrorCode: string, ResponseMessage: string} + * @return array{CommonPaymentUrl: string|null, PaymentToken: string|null, ErrorCode: string|null, ResponseMessage: string|null} + * + * @throws Exception + */ + public function registerPayment(): array + { + if (null === $this->order) { + $this->logger->log(LogLevel::ERROR, 'register payment without setting order', [ + 'order' => $this->order, + 'card_provided' => (bool) $this->card, + ]); + + throw new LogicException('Sipariş bilgileri eksik!'); + } + + $requestData = $this->requestDataMapper->create3DEnrollmentCheckRequestData( + $this->account, + $this->order, + $this->type, + $this->card + ); + + return $this->send($requestData); + } +} diff --git a/src/Gateways/VakifBankPos.php b/src/Gateways/VakifBankPos.php index 2adaafce..bb708440 100644 --- a/src/Gateways/VakifBankPos.php +++ b/src/Gateways/VakifBankPos.php @@ -5,6 +5,7 @@ namespace Mews\Pos\Gateways; use Exception; +use LogicException; use Mews\Pos\DataMapper\ResponseDataMapper\VakifBankPosResponseDataMapper; use Mews\Pos\DataMapper\VakifBankPosRequestDataMapper; use Mews\Pos\Entity\Account\VakifBankAccount; @@ -14,18 +15,14 @@ use Symfony\Component\Serializer\Exception\NotEncodableValueException; /** - * Class VakifBankPos + * Vakifbank VPOS 7/24 gateway'i destekler */ class VakifBankPos extends AbstractGateway { - /** - * @const string - */ + /** @var string */ public const NAME = 'VakifPOS'; - /** - * @var VakifBankAccount - */ + /** @var VakifBankAccount */ protected $account; /** @var VakifBankPosRequestDataMapper */ @@ -62,8 +59,11 @@ public function make3DPayment(Request $request) return $this; } + $this->logger->log(LogLevel::DEBUG, 'finishing payment', ['md_status' => $status]); - $contents = $this->create3DPaymentXML($request->all()); + /** @var array{Eci: string, Cavv: string, VerifyEnrollmentRequestId: string} $requestData */ + $requestData = $request->all(); + $contents = $this->create3DPaymentXML($requestData); $bankResponse = $this->send($contents); $this->response = $this->responseDataMapper->map3DPaymentData($request->all(), $bankResponse); @@ -100,20 +100,17 @@ public function history(array $meta) } /** - * returns form data needed for 3d model - * - * @return array - * - * @throws Exception + * {@inheritDoc} */ public function get3DFormData(): array { if (!$this->card || !$this->order) { $this->logger->log(LogLevel::ERROR, 'tried to get 3D form data without setting order', [ 'order' => $this->order, - 'card_provided' => !!$this->card, + 'card_provided' => (bool) $this->card, ]); - return []; + + throw new LogicException('Kredi kartı veya sipariş bilgileri eksik!'); } $data = $this->sendEnrollmentRequest(); @@ -130,15 +127,18 @@ public function get3DFormData(): array $this->logger->log(LogLevel::ERROR, 'enrollment fail response', $data); throw new Exception($data['ErrorMessage'], $data['MessageErrorCode']); } + if ('N' === $status) { //half secure olarak devam et yada satisi iptal et. $this->logger->log(LogLevel::ERROR, 'enrollment fail response', $data); throw new Exception('Kart 3-D Secure programına dâhil değil'); } + if ('U' === $status) { $this->logger->log(LogLevel::ERROR, 'enrollment fail response', $data); throw new Exception('İşlem gerçekleştirilemiyor'); } + $this->logger->log(LogLevel::DEBUG, 'preparing 3D form data'); return $this->requestDataMapper->create3DFormData($this->account, $this->order, $this->type, '', null, $data['Message']['VERes']); @@ -185,11 +185,12 @@ public function send($contents, ?string $url = null) try { $this->data = $this->XMLStringToArray($responseBody); - } catch (NotEncodableValueException $e) { + } catch (NotEncodableValueException $notEncodableValueException) { if ($this->isHTML($responseBody)) { // if something wrong server responds with HTML content - throw new Exception($responseBody); + throw new Exception($responseBody, $notEncodableValueException->getCode(), $notEncodableValueException); } + $this->data = json_decode($responseBody, true); } @@ -211,6 +212,10 @@ public function createRegularPaymentXML() */ public function createRegularPostXML() { + if (null === $this->order) { + throw new LogicException('sipariş bilgileri eksik!'); + } + $requestData = $this->requestDataMapper->createNonSecurePostAuthPaymentRequestData($this->account, $this->order); return $this->createXML($requestData); @@ -219,6 +224,8 @@ public function createRegularPostXML() /** * NOT: diger gatewaylerden farkli olarak vakifbank kredit bilgilerini bu asamada da istiyor. * @inheritDoc + * + * @param array{Eci: string, Cavv: string, VerifyEnrollmentRequestId: string} $responseData */ public function create3DPaymentXML($responseData) { diff --git a/tests/Crypt/KuveytPosCryptTest.php b/tests/Crypt/KuveytPosCryptTest.php index 80c4694a..d96a5318 100644 --- a/tests/Crypt/KuveytPosCryptTest.php +++ b/tests/Crypt/KuveytPosCryptTest.php @@ -11,9 +11,13 @@ class KuveytPosCryptTest extends TestCase { - /** - * @var KuveytPosAccount - */ + /** @var array|array */ + public $order = []; + + /** @var KuveytPosCrypt */ + public $crypt; + + /** @var KuveytPosAccount */ private $threeDAccount; protected function setUp(): void diff --git a/tests/Crypt/PayForPosCryptTest.php b/tests/Crypt/PayForPosCryptTest.php index 26aaf482..881f3180 100644 --- a/tests/Crypt/PayForPosCryptTest.php +++ b/tests/Crypt/PayForPosCryptTest.php @@ -3,6 +3,7 @@ namespace Mews\Pos\Tests\Crypt; use Mews\Pos\Crypt\PayForPosCrypt; +use Mews\Pos\Entity\Account\PayForAccount; use Mews\Pos\Factory\AccountFactory; use Mews\Pos\Gateways\AbstractGateway; use PHPUnit\Framework\TestCase; @@ -10,9 +11,13 @@ class PayForPosCryptTest extends TestCase { - /** - * @var PayForPosCrypt - */ + /** @var array|array */ + public $order = []; + + /** @var PayForPosCrypt */ + public $crypt; + + /** @var PayForAccount */ private $threeDAccount; protected function setUp(): void diff --git a/tests/Crypt/PosNetCryptTest.php b/tests/Crypt/PosNetCryptTest.php index 99090f1d..a1fa3764 100644 --- a/tests/Crypt/PosNetCryptTest.php +++ b/tests/Crypt/PosNetCryptTest.php @@ -3,6 +3,7 @@ namespace Mews\Pos\Tests\Crypt; use Mews\Pos\Crypt\PosNetCrypt; +use Mews\Pos\Entity\Account\PosNetAccount; use Mews\Pos\Factory\AccountFactory; use Mews\Pos\Gateways\AbstractGateway; use PHPUnit\Framework\TestCase; @@ -10,9 +11,10 @@ class PosNetCryptTest extends TestCase { - /** - * @var PosNetCrypt - */ + /** @var PosNetCrypt */ + public $crypt; + + /** @var PosNetAccount */ private $threeDAccount; protected function setUp(): void diff --git a/tests/DataMapper/EstPosRequestDataMapperTest.php b/tests/DataMapper/EstPosRequestDataMapperTest.php index 21ccfe29..a3f07673 100644 --- a/tests/DataMapper/EstPosRequestDataMapperTest.php +++ b/tests/DataMapper/EstPosRequestDataMapperTest.php @@ -33,6 +33,7 @@ class EstPosRequestDataMapperTest extends TestCase private $requestDataMapper; private $order; + private $config; protected function setUp(): void @@ -66,6 +67,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $this->requestDataMapper = new EstPosRequestDataMapper(PosFactory::getGatewayCrypt(EstPos::class, new NullLogger())); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); } @@ -94,8 +96,8 @@ public function testMapCurrency() * * @testWith ["0", ""] * ["1", ""] - * ["2", 2] - * [2, 2] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -292,6 +294,7 @@ public function testGet3DFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; //test without card @@ -338,6 +341,7 @@ public function testGet3DHostFormData() $pos = PosFactory::createPosGateway($account); $pos->setTestMode(true); $pos->prepare($this->order, AbstractGateway::TX_PAY); + $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway_3d_host']['test']; $inputs = [ 'clientid' => $account->getClientId(), @@ -357,6 +361,7 @@ public function testGet3DHostFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; diff --git a/tests/DataMapper/EstV3PosRequestDataMapperTest.php b/tests/DataMapper/EstV3PosRequestDataMapperTest.php index ab784aa8..725230ff 100644 --- a/tests/DataMapper/EstV3PosRequestDataMapperTest.php +++ b/tests/DataMapper/EstV3PosRequestDataMapperTest.php @@ -32,6 +32,7 @@ class EstV3PosRequestDataMapperTest extends TestCase private $requestDataMapper; private $order; + private $config; protected function setUp(): void @@ -65,6 +66,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $crypt = PosFactory::getGatewayCrypt(EstV3Pos::class, new NullLogger()); $this->requestDataMapper = new EstV3PosRequestDataMapper($crypt); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); @@ -102,6 +104,7 @@ public function testGet3DFormData() $inputs['hash'] = $hash; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; //test without card @@ -113,13 +116,12 @@ public function testGet3DFormData() )); //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(); - } + $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(); + unset($form['inputs']['hash']); $form['inputs']['hash'] = $this->requestDataMapper->getCrypt()->create3DHash($account, $form['inputs'], $txType); @@ -170,6 +172,7 @@ public function testGet3DHostFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; $form['inputs']['hash'] = $this->requestDataMapper->getCrypt()->create3DHash($account, $inputs, AbstractGateway::TX_PAY); diff --git a/tests/DataMapper/GarantiPosRequestDataMapperTest.php b/tests/DataMapper/GarantiPosRequestDataMapperTest.php index 5bdc4a57..73362410 100644 --- a/tests/DataMapper/GarantiPosRequestDataMapperTest.php +++ b/tests/DataMapper/GarantiPosRequestDataMapperTest.php @@ -34,6 +34,7 @@ class GarantiPosRequestDataMapperTest extends TestCase private $requestDataMapper; private $order; + private $config; protected function setUp(): void @@ -69,9 +70,11 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $crypt = PosFactory::getGatewayCrypt(GarantiPos::class, new NullLogger()); $this->requestDataMapper = new GarantiPosRequestDataMapper($crypt); $this->requestDataMapper->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); } @@ -100,8 +103,8 @@ public function testMapCurrency() * * @testWith ["0", ""] * ["1", ""] - * ["2", 2] - * [2, 2] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -171,6 +174,7 @@ 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()); @@ -200,6 +204,7 @@ 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(); @@ -230,6 +235,7 @@ public function testGet3DFormData() $form = [ 'inputs' => $inputs, + 'method' => 'POST', 'gateway' => $gatewayURL, ]; diff --git a/tests/DataMapper/InterPosRequestDataMapperTest.php b/tests/DataMapper/InterPosRequestDataMapperTest.php index 0dc69c48..fff3e99c 100644 --- a/tests/DataMapper/InterPosRequestDataMapperTest.php +++ b/tests/DataMapper/InterPosRequestDataMapperTest.php @@ -34,6 +34,7 @@ class InterPosRequestDataMapperTest extends TestCase private $requestDataMapper; private $order; + private $config; protected function setUp(): void @@ -92,8 +93,8 @@ public function testMapCurrency() * * @testWith ["0", ""] * ["1", ""] - * ["2", 2] - * [2, 2] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -215,6 +216,7 @@ public function testGet3DFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; //test without card @@ -259,6 +261,7 @@ public function testGet3DHostFormData() $pos = PosFactory::createPosGateway($account); $pos->setTestMode(true); $pos->prepare($this->order, AbstractGateway::TX_PAY); + $order = $pos->getOrder(); $gatewayURL = $this->config['banks'][$account->getBank()]['urls']['gateway_3d_host']['test']; @@ -278,6 +281,7 @@ public function testGet3DHostFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; diff --git a/tests/DataMapper/KuveytPosRequestDataMapperTest.php b/tests/DataMapper/KuveytPosRequestDataMapperTest.php index 9a2a2c3a..36fd2663 100644 --- a/tests/DataMapper/KuveytPosRequestDataMapperTest.php +++ b/tests/DataMapper/KuveytPosRequestDataMapperTest.php @@ -5,6 +5,7 @@ namespace Mews\Pos\Tests\DataMapper; use Mews\Pos\DataMapper\KuveytPosRequestDataMapper; +use Mews\Pos\Entity\Account\KuveytPosAccount; use Mews\Pos\Entity\Card\AbstractCreditCard; use Mews\Pos\Exceptions\BankClassNullException; use Mews\Pos\Exceptions\BankNotFoundException; @@ -21,6 +22,9 @@ */ class KuveytPosRequestDataMapperTest extends TestCase { + /** @var KuveytPosAccount */ + public $threeDAccount; + /** @var AbstractCreditCard */ private $card; @@ -66,6 +70,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create( $this->pos, '4155650100416111', @@ -93,10 +98,10 @@ public function testMapCurrency() * @param string|int|null $installment * @param string|int $expected * - * @testWith ["0", 0] - * ["1", 0] - * ["2", 2] - * [2, 2] + * @testWith ["0", "0"] + * ["1", "0"] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -133,7 +138,7 @@ public function testCompose3DFormData() 'FailUrl' => $order->fail_url, ]; - if ($card) { + if ($card !== null) { $inputs['CardHolderName'] = $card->getHolderName(); $inputs['CardType'] = 'Visa'; $inputs['CardNumber'] = $card->getNumber(); diff --git a/tests/DataMapper/PayForPosRequestDataMapperTest.php b/tests/DataMapper/PayForPosRequestDataMapperTest.php index 18da4d62..231f4bc7 100644 --- a/tests/DataMapper/PayForPosRequestDataMapperTest.php +++ b/tests/DataMapper/PayForPosRequestDataMapperTest.php @@ -33,6 +33,7 @@ class PayForPosRequestDataMapperTest extends TestCase private $requestDataMapper; private $order; + private $config; protected function setUp(): void @@ -65,6 +66,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $crypt = PosFactory::getGatewayCrypt(PayForPos::class, new NullLogger()); $this->requestDataMapper = new PayForPosRequestDataMapper($crypt); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); @@ -83,10 +85,10 @@ public function testMapCurrency() * @param string|int|null $installment * @param string|int $expected * - * @testWith ["0", 0] - * ["1", 0] - * ["2", 2] - * [2, 2] + * @testWith ["0", "0"] + * ["1", "0"] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -215,6 +217,7 @@ public function testGet3DFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; //test without card @@ -259,6 +262,7 @@ public function testGet3DHostFormData() $pos = PosFactory::createPosGateway($account); $pos->setTestMode(true); $pos->prepare($this->order, AbstractGateway::TX_PAY); + $order = $pos->getOrder(); $gatewayURL = $this->config['banks'][$this->threeDAccount->getBank()]['urls']['gateway_3d_host']['test']; $inputs = [ @@ -279,6 +283,7 @@ public function testGet3DHostFormData() ]; $form = [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; diff --git a/tests/DataMapper/PosNetRequestDataMapperTest.php b/tests/DataMapper/PosNetRequestDataMapperTest.php index 29dfacf1..6ed6d329 100644 --- a/tests/DataMapper/PosNetRequestDataMapperTest.php +++ b/tests/DataMapper/PosNetRequestDataMapperTest.php @@ -38,8 +38,6 @@ protected function setUp(): void { parent::setUp(); - $this->config = require __DIR__.'/../../config/pos.php'; - $threeDAccount = AccountFactory::createPosNetAccount( 'yapikredi', '6706598320', @@ -66,6 +64,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($threeDAccount); $this->pos->setTestMode(true); + $crypt = PosFactory::getGatewayCrypt(PosNet::class, new NullLogger()); $this->requestDataMapper = new PosNetRequestDataMapper($crypt); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); @@ -231,6 +230,7 @@ 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(), AbstractGateway::TX_PAY, $pos->getCard()); $this->assertEquals($expected, $actual); @@ -363,6 +363,7 @@ private function getSample3DFormData(AbstractPosAccount $account, $order, $oosTx return [ 'gateway' => $gatewayURL, + 'method' => 'POST', 'inputs' => $inputs, ]; } diff --git a/tests/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapperTest.php b/tests/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapperTest.php index 8f82b8a7..89431be1 100644 --- a/tests/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapperTest.php +++ b/tests/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapperTest.php @@ -366,7 +366,7 @@ public function threeDPaymentDataProvider(): array 'error_code' => null, 'masked_number' => '4025502306586032', ] - ] + ], ]; } } diff --git a/tests/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapperTest.php b/tests/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapperTest.php new file mode 100644 index 00000000..53f7df1a --- /dev/null +++ b/tests/DataMapper/ResponseDataMapper/VakifBankCPPosResponseDataMapperTest.php @@ -0,0 +1,151 @@ +responseDataMapper = new VakifBankCPPosResponseDataMapper( + $requestDataMapper->getCurrencyMappings(), + $requestDataMapper->getTxTypeMappings(), + new NullLogger() + ); + } + + /** + * @dataProvider threesDPayResponseSamplesProvider + */ + public function testMap3DPayResponseData(array $bankResponse, array $expected): void + { + $actual = $this->responseDataMapper->map3DPayResponseData($bankResponse); + + $this->assertNotEmpty($actual['all']); + unset($actual['all']); + $this->assertSame($expected, $actual); + } + + public static function threesDPayResponseSamplesProvider(): Generator + { + yield 'fail_response_from_gateway_1' => [ + 'bank_response' => [ + 'Rc' => '2053', + 'Message' => 'VeRes status is E Message : Directory server communication error', + 'PaymentToken' => '68244b7e3dfd4b3ebea1afbe0185b9ed', + 'TransactionId' => '0cb6a57715144178a014afbe0185b9ed', + 'MaskedPan' => '49384601****4205', + ], + 'expected' => [ + 'order_id' => null, + 'trans_id' => '0cb6a57715144178a014afbe0185b9ed', + 'auth_code' => null, + 'ref_ret_num' => null, + 'proc_return_code' => '2053', + 'status' => 'declined', + 'status_detail' => null, + 'error_code' => '2053', + 'error_message' => 'VeRes status is E Message : Directory server communication error', + 'md_status' => null, + 'md_error_message' => null, + 'transaction_security' => null, + 'masked_number' => '49384601****4205', + ], + ]; + + yield 'fail_response_from_gateway_2' => [ + 'bank_response' => [ + 'Rc' => '0057', + 'AuthCode' => '000000', + 'ErrorCode' => '0057', + 'Message' => 'RED-KARTIN İŞLEM İZNİ YOK', + 'PaymentToken' => '5aeb359892f8400b9d0fafbd016c7636', + 'TransactionId' => '868382724da7480c949dafbd016c7636', + 'MaskedPan' => '49384601****4205', + ], + 'expected' => [ + 'order_id' => null, + 'trans_id' => '868382724da7480c949dafbd016c7636', + 'auth_code' => null, + 'ref_ret_num' => null, + 'proc_return_code' => '0057', + 'status' => 'declined', + 'status_detail' => null, + 'error_code' => '0057', + 'error_message' => 'RED-KARTIN İŞLEM İZNİ YOK', + 'md_status' => null, + 'md_error_message' => null, + 'transaction_security' => null, + 'masked_number' => '49384601****4205', + ], + ]; + + yield 'success_response_from_gateway_1' => [ + 'bank_response' => [ + 'Rc' => '0000', + 'AuthCode' => '735879', + 'Rrn' => '306822971283', + 'Message' => 'İŞLEM BAŞARILI', + 'TransactionId' => '3ee068d5b5a747ada65dafc0016d5887', + 'PaymentToken' => 'b35a56bf37334872a945afc0016d5887', + 'MaskedPan' => '49384601****4205', + 'HostMerchantId' => '000100000013506', + 'HostTerminalId' => 'VP000579', + 'AmountCode' => '949', + 'Amount' => '1,01', + 'TransactionType' => 'Sale', + 'OrderID' => '2023030913ED', + 'OrderDescription' => null, + 'InstallmentCount' => '', + 'IsSecure' => 'True', + 'AllowNotEnrolledCard' => 'True', + 'SuccessUrl' => 'http://localhost/vakifbank-cp/3d-host/response.php', + 'FailUrl' => 'http://localhost/vakifbank-cp/3d-host/response.php', + 'RequestLanguage' => 'tr-TR', + 'Extract' => null, + 'CardHoldersName' => 'Jo* Do*', + 'CustomItems' => null, + 'ExpireMonth' => '11', + 'ExpireYear' => '2024', + 'BrandNumber' => '100', + 'HostDate' => '20230309221037', + 'HostRc' => null, + 'CampaignResult' => [ + 'CampaignInfo' => [], + ], + 'ErrorCode' => null, + 'ResponseMessage' => null, + ], + 'expected' => [ + 'order_id' => '2023030913ED', + 'trans_id' => '3ee068d5b5a747ada65dafc0016d5887', + 'auth_code' => '735879', + 'ref_ret_num' => '3ee068d5b5a747ada65dafc0016d5887', + 'proc_return_code' => '0000', + 'status' => 'approved', + 'status_detail' => null, + 'error_code' => null, + 'error_message' => null, + 'md_status' => null, + 'md_error_message' => null, + 'transaction_security' => null, + 'masked_number' => '49384601****4205', + ], + ]; + } +} diff --git a/tests/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapperTest.php b/tests/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapperTest.php index 969850fb..a7175baf 100644 --- a/tests/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapperTest.php +++ b/tests/DataMapper/ResponseDataMapper/VakifBankPosResponseDataMapperTest.php @@ -27,7 +27,7 @@ protected function setUp(): void /** * @dataProvider threeDPaymentDataProvider */ - public function testMap3DPaymentData(array $threeDResponseData, array $paymentResponse, array $expectedData) + public function testMap3DPaymentData(array $threeDResponseData, array $paymentResponse, array $expectedData): void { $actualData = $this->responseDataMapper->map3DPaymentData($threeDResponseData, $paymentResponse); unset($actualData['all']); @@ -35,7 +35,228 @@ public function testMap3DPaymentData(array $threeDResponseData, array $paymentRe $this->assertSame($expectedData, $actualData); } - public function threeDPaymentDataProvider(): array + /** + * @dataProvider paymentDataProvider + */ + public function testMapPaymentResponse(array $paymentResponse, array $expectedData): void + { + $actualData = $this->responseDataMapper->mapPaymentResponse($paymentResponse); + unset($actualData['all']); + $this->assertSame($expectedData, $actualData); + } + + /** + * @dataProvider cancelDataProvider + */ + public function testMapCancelResponse(array $paymentResponse, array $expectedData): void + { + $actualData = $this->responseDataMapper->mapCancelResponse($paymentResponse); + unset($actualData['all']); + $this->assertSame($expectedData, $actualData); + } + + /** + * @dataProvider refundDataProvider + */ + public function testMapRefundResponse(array $paymentResponse, array $expectedData) + { + $actualData = $this->responseDataMapper->mapRefundResponse($paymentResponse); + unset($actualData['all']); + $this->assertSame($expectedData, $actualData); + } + + public static function refundDataProvider(): iterable + { + yield 'success_1' => [ + 'responseData' => [ + 'MerchantId' => '000100000013506', + 'TransactionType' => 'Refund', + 'TransactionId' => '455ae6c09140434ea6edafc0018acbb9', + 'ReferenceTransactionId' => '6d491ea480564068976fafc0018a9def', + 'ResultCode' => '0000', + 'ResultDetail' => 'İŞLEM BAŞARILI', + 'InstallmentTable' => null, + 'CampaignResult' => null, + 'AuthCode' => '752800', + 'HostDate' => '20230309235724', + 'Rrn' => '306823971382', + 'TerminalNo' => 'VP000579', + 'CurrencyAmount' => '1.01', + 'CurrencyCode' => '949', + 'BatchNo' => '300', + 'TLAmount' => '1.01', + ], + 'expectedData' => [ + 'order_id' => '455ae6c09140434ea6edafc0018acbb9', + 'auth_code' => '752800', + 'ref_ret_num' => '306823971382', + 'proc_return_code' => '0000', + 'trans_id' => '455ae6c09140434ea6edafc0018acbb9', + 'error_code' => null, + 'error_message' => null, + 'status' => 'approved', + 'status_detail' => 'İŞLEM BAŞARILI', + ], + ]; + + yield 'fail_1' => [ + 'responseData' => [ + 'ResultCode' => '1059', + 'ResultDetail' => 'İşlemin tamamı iade edilmiş.', + 'InstallmentTable' => null, + ], + 'expectedData' => [ + 'order_id' => null, + 'auth_code' => null, + 'ref_ret_num' => null, + 'proc_return_code' => '1059', + 'trans_id' => null, + 'error_code' => '1059', + 'error_message' => 'İşlemin tamamı iade edilmiş.', + 'status' => 'declined', + 'status_detail' => 'İşlemin tamamı iade edilmiş.' + ], + ]; + } + + public static function cancelDataProvider(): iterable + { + yield 'success_1' => [ + 'responseData' => [ + 'MerchantId' => '000100000013506', + 'TransactionType' => 'Cancel', + 'TransactionId' => '4a8e979308de4568b500afc00187a501', + 'ReferenceTransactionId' => '3f30ab117aa74826b448afc0018789fa', + 'ResultCode' => '0000', + 'ResultDetail' => 'İŞLEM BAŞARILI', + 'InstallmentTable' => null, + 'CampaignResult' => null, + 'AuthCode' => '836044', + 'HostDate' => '20230309234556', + 'Rrn' => '306823971363', + 'TerminalNo' => 'VP000579', + 'CurrencyAmount' => '1.01', + 'CurrencyCode' => '949', + 'BatchNo' => '300', + 'TLAmount' => '1.01', + ], + 'expectedData' => [ + 'order_id' => '4a8e979308de4568b500afc00187a501', + 'auth_code' => '836044', + 'ref_ret_num' => '306823971363', + 'proc_return_code' => '0000', + 'trans_id' => '4a8e979308de4568b500afc00187a501', + 'error_code' => null, + 'error_message' => null, + 'status' => 'approved', + 'status_detail' => 'İŞLEM BAŞARILI', + ], + ]; + + yield 'fail_1' => [ + 'responseData' => [ + 'ResultCode' => '1083', + 'ResultDetail' => 'Referans islem daha önceden iptal edilmis.', + 'InstallmentTable' => null, + ], + 'expectedData' => [ + 'order_id' => null, + 'auth_code' => null, + 'ref_ret_num' => null, + 'proc_return_code' => '1083', + 'trans_id' => null, + 'error_code' => '1083', + 'error_message' => 'Referans islem daha önceden iptal edilmis.', + 'status' => 'declined', + 'status_detail' => 'Referans islem daha önceden iptal edilmis.', + ], + ]; + } + + public static function paymentDataProvider(): iterable + { + yield 'success_1' => [ + 'responseData' => [ + 'MerchantId' => '000100000013506', + 'TransactionType' => 'Sale', + 'TransactionId' => '9972767117b3400eb2acafc0018643df', + 'ResultCode' => '0000', + 'ResultDetail' => 'İŞLEM BAŞARILI', + 'CustomItems' => [ + 'Item' => [ + '@name' => 'CardHolderName', + '@value' => 'AR* ÖZ*', + '#' => null, + ], + ], + 'InstallmentTable' => null, + 'CampaignResult' => null, + 'AuthCode' => '961451', + 'HostDate' => '20230309234054', + 'Rrn' => '306823971358', + 'TerminalNo' => 'VP000579', + 'GainedPoint' => '10.00', + 'TotalPoint' => '103032.52', + 'CurrencyAmount' => '1.01', + 'CurrencyCode' => '949', + 'OrderId' => '202303095646', + 'ThreeDSecureType' => '1', + 'TransactionDeviceSource' => '0', + 'BatchNo' => '300', + 'TLAmount' => '1.01', + ], + 'expectedData' => [ + 'trans_id' => '9972767117b3400eb2acafc0018643df', + 'auth_code' => '961451', + 'ref_ret_num' => '9972767117b3400eb2acafc0018643df', + 'order_id' => '202303095646', + 'eci' => null, + 'proc_return_code' => '0000', + 'status' => 'approved', + 'status_detail' => 'İŞLEM BAŞARILI', + 'error_code' => null, + 'error_message' => null, + 'transaction_type' => 'pay', + ], + ]; + + yield 'fail_1' => [ + 'responseData' => [ + 'MerchantId' => '000100000013506', + 'TransactionType' => 'Sale', + 'TransactionId' => '9b47227c275246d39454afc00186dfba', + 'ResultCode' => '0312', + 'ResultDetail' => 'RED-GEÇERSİZ KART', + 'InstallmentTable' => null, + 'CampaignResult' => null, + 'AuthCode' => '000000', + 'HostDate' => '20230309234307', + 'Rrn' => '306823971359', + 'TerminalNo' => 'VP000579', + 'CurrencyAmount' => '1.01', + 'CurrencyCode' => '949', + 'OrderId' => '20230309EF68', + 'ThreeDSecureType' => '1', + 'TransactionDeviceSource' => '0', + 'BatchNo' => '300', + 'TLAmount' => '1.01' + ], + 'expectedData' => [ + 'trans_id' => null, + 'auth_code' => null, + 'ref_ret_num' => null, + 'order_id' => '20230309EF68', + 'eci' => null, + 'proc_return_code' => '0312', + 'status' => 'declined', + 'status_detail' => 'RED-GEÇERSİZ KART', + 'error_code' => '0312', + 'error_message' => 'RED-GEÇERSİZ KART', + ], + ]; + } + + public static function threeDPaymentDataProvider(): array { return [ 'authFail1' => [ @@ -61,17 +282,79 @@ public function threeDPaymentDataProvider(): array ], 'paymentData' => [], 'expectedData' => [ - 'order_id' => 'order-id-123', + 'eci' => '02', + 'cavv' => 'AAABBBBBBBBBBBBBBBIIIIII=', + 'md_status' => 'E', + 'md_error_message' => 'Üye isyeri IP si sistemde tanimli degil', + 'transaction_security' => null, 'trans_id' => null, - 'auth_code' => null, 'ref_ret_num' => null, 'proc_return_code' => null, + 'auth_code' => null, + 'order_id' => 'order-id-123', 'status' => 'declined', 'status_detail' => null, 'error_code' => '1105', 'error_message' => 'Üye isyeri IP si sistemde tanimli degil', - 'eci' => '02', - 'cavv' => 'AAABBBBBBBBBBBBBBBIIIIII=', + ], + ], + 'auth_success_payment_fail' => [ + 'threeDResponseData' => [ + 'MerchantId' => '000100000013506', + 'Pan' => '4938460158754205', + 'Expiry' => '2411', + 'PurchAmount' => '101', + 'PurchCurrency' => '949', + 'VerifyEnrollmentRequestId' => 'ce06048a3e9c0cd1d437803fb38b5ad0', + 'Xid' => 'ondg8d9t5besgt88sk8h', + 'SessionInfo' => 'jpf58sdjj8p9mpb9shurh47v64', + 'Status' => 'Y', + 'Cavv' => 'ABIBCBgAAAEnAAABAQAAAAAAAAA=', + 'Eci' => '05', + 'ExpSign' => null, + 'InstallmentCount' => null, + 'SubMerchantNo' => null, + 'SubMerchantName' => null, + 'SubMerchantNumber' => null, + 'ErrorCode' => null, + 'ErrorMessage' => null, + ], + 'paymentData' => [ + 'MerchantId' => '000100000013506', + 'TransactionType' => 'Sale', + 'TransactionId' => '202303091489', + 'ResultCode' => '0312', + 'ResultDetail' => 'RED-GEÇERSİZ KART', + 'InstallmentTable' => null, + 'CampaignResult' => null, + 'AuthCode' => '000000', + 'HostDate' => '20230309235359', + 'Rrn' => '306823971380', + 'TerminalNo' => 'VP000579', + 'CurrencyAmount' => '1.01', + 'CurrencyCode' => '949', + 'OrderId' => '202303091489', + 'ECI' => '05', + 'ThreeDSecureType' => '2', + 'TransactionDeviceSource' => '0', + 'BatchNo' => '300', + 'TLAmount' => '1.01', + ], + 'expectedData' => [ + 'cavv' => 'ABIBCBgAAAEnAAABAQAAAAAAAAA=', + 'md_status' => 'Y', + 'md_error_message' => null, + 'transaction_security' => null, + 'trans_id' => null, + 'ref_ret_num' => null, + 'proc_return_code' => '0312', + 'eci' => '05', + 'auth_code' => null, + 'order_id' => '202303091489', + 'status' => 'declined', + 'status_detail' => 'RED-GEÇERSİZ KART', + 'error_code' => '0312', + 'error_message' => 'RED-GEÇERSİZ KART', ], ], 'success1' => [ @@ -99,7 +382,7 @@ public function threeDPaymentDataProvider(): array 'MerchantId' => '000000000111111', 'TerminalNo' => 'VP999999', 'TransactionType' => 'Sale', - 'TransactionId' => null, + 'TransactionId' => '20230309B838', 'ResultCode' => '0000', 'ResultDetail' => 'İŞLEM BAŞARILI', 'CustomItems' => [], @@ -118,20 +401,23 @@ public function threeDPaymentDataProvider(): array 'BatchNo' => '1', ], 'expectedData' => [ - 'eci' => '02', 'cavv' => 'AAABBBBBBBBBBBBBBBIIIIII=', + 'md_status' => 'Y', + 'md_error_message' => null, + 'transaction_security' => null, + 'trans_id' => '20230309B838', + 'ref_ret_num' => '20230309B838', + 'proc_return_code' => '0000', + 'transaction_type' => 'pay', + 'eci' => '02', 'auth_code' => '822641', 'order_id' => 'order-id-123', 'status' => 'approved', 'status_detail' => 'İŞLEM BAŞARILI', 'error_code' => null, 'error_message' => null, - 'trans_id' => null, - 'ref_ret_num' => '209411062014', - 'proc_return_code' => '0000', - 'transaction_type' => 'pay', ] - ] + ], ]; } } diff --git a/tests/DataMapper/VakifBankCPPosRequestDataMapperTest.php b/tests/DataMapper/VakifBankCPPosRequestDataMapperTest.php new file mode 100644 index 00000000..1644af45 --- /dev/null +++ b/tests/DataMapper/VakifBankCPPosRequestDataMapperTest.php @@ -0,0 +1,230 @@ +account = AccountFactory::createVakifBankAccount( + 'vakifbank-cp', + '000000000111111', + '3XTgER89as', + 'VP999999', + AbstractGateway::MODEL_3D_SECURE + ); + + $this->pos = PosFactory::createPosGateway($this->account); + $this->pos->setTestMode(true); + + $crypt = PosFactory::getGatewayCrypt(VakifBankCPPos::class, new NullLogger()); + $this->requestDataMapper = new VakifBankCPPosRequestDataMapper($crypt); + } + + /** + * @return void + */ + public function testAmountFormat() + { + $this->assertEquals('1000.00', VakifBankCPPosRequestDataMapper::amountFormat(1000)); + } + + /** + * @return void + */ + public function testMapRecurringFrequency() + { + $this->assertEquals('Month', $this->requestDataMapper->mapRecurringFrequency('MONTH')); + $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); + } + + /** + * @dataProvider registerDataProvider + */ + public function testCreate3DEnrollmentCheckData(AbstractPosAccount $account, array $order, string $txType, ?CreditCard $card, array $expectedData): void + { + $pos = $this->pos; + $pos->prepare($order, AbstractGateway::TX_PAY, $card); + + $actual = $this->requestDataMapper->create3DEnrollmentCheckRequestData($account, $pos->getOrder(), $txType, $card); + $this->assertEquals($expectedData, $actual); + } + + /** + * @dataProvider threeDFormDataProvider + */ + public function testCreate3DFormData(array $queryParams, array $expected): void + { + $actualData = $this->requestDataMapper->create3DFormData( + null, + null, + null, + null, + null, + $queryParams + ); + + $this->assertSame($expected, $actualData); + } + + public static function registerDataProvider(): iterable + { + $account = AccountFactory::createVakifBankAccount( + 'vakifbank-cp', + '000000000111111', + '3XTgER89as', + 'VP999999', + AbstractGateway::MODEL_3D_SECURE + ); + + $order = [ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => 100.00, + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'rand' => microtime(true), + 'extraData' => microtime(true), + 'ip' => '127.0.0.1', + ]; + + $pos = PosFactory::createPosGateway($account); + $pos->setTestMode(true); + + $card = CreditCardFactory::create($pos, '5555444433332222', '2021', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); + + yield 'with_card_1' => [ + 'account' => $account, + 'order' => $order, + 'txType' => AbstractGateway::TX_PAY, + 'card' => $card, + 'expected' => [ + 'HostMerchantId' => '000000000111111', + 'MerchantPassword' => '3XTgER89as', + 'HostTerminalId' => 'VP999999', + 'TransactionType' => 'Sale', + 'AmountCode' => '949', + 'Amount' => '100.00', + 'OrderID' => 'order222', + 'OrderDescription' => '', + 'IsSecure' => 'true', + 'AllowNotEnrolledCard' => 'false', + 'SuccessUrl' => 'https://domain.com/success', + 'FailUrl' => 'https://domain.com/fail_url', + 'HashedData' => '', + 'RequestLanguage' => 'tr-TR', + 'Extract' => '', + 'CustomItems' => '', + 'BrandNumber' => '100', + 'CVV' => '122', + 'PAN' => '5555444433332222', + 'ExpireMonth' => '12', + 'ExpireYear' => '21', + 'CardHoldersName' => 'ahmet', + ], + ]; + + yield 'without_card_1_pre_pay' => [ + 'account' => $account, + 'order' => $order, + 'txType' => AbstractGateway::TX_PRE_PAY, + 'card' => null, + 'expected' => [ + 'HostMerchantId' => '000000000111111', + 'MerchantPassword' => '3XTgER89as', + 'HostTerminalId' => 'VP999999', + 'TransactionType' => 'Auth', + 'AmountCode' => '949', + 'Amount' => '100.00', + 'OrderID' => 'order222', + 'OrderDescription' => '', + 'IsSecure' => 'true', + 'AllowNotEnrolledCard' => 'false', + 'SuccessUrl' => 'https://domain.com/success', + 'FailUrl' => 'https://domain.com/fail_url', + 'HashedData' => '', + 'RequestLanguage' => 'tr-TR', + 'Extract' => '', + 'CustomItems' => '', + ], + ]; + } + + public static function threeDFormDataProvider(): iterable + { + yield 'success_1' => [ + 'queryParams' => [ + 'CommonPaymentUrl' => 'https://cptest.vakifbank.com.tr/CommonPayment/SecurePayment', + 'PaymentToken' => 'c5e076e7bf234a339c40afc10166c06d', + 'ErrorCode' => null, + 'ResponseMessage' => null, + ], + 'expected' => [ + 'gateway' => 'https://cptest.vakifbank.com.tr/CommonPayment/SecurePayment', + 'method' => 'GET', + 'inputs' => [ + 'Ptkn' => 'c5e076e7bf234a339c40afc10166c06d' + ], + ], + ]; + } +} diff --git a/tests/DataMapper/VakifBankPosRequestDataMapperTest.php b/tests/DataMapper/VakifBankPosRequestDataMapperTest.php index 4755b2c7..7a9121e0 100644 --- a/tests/DataMapper/VakifBankPosRequestDataMapperTest.php +++ b/tests/DataMapper/VakifBankPosRequestDataMapperTest.php @@ -19,6 +19,9 @@ */ class VakifBankPosRequestDataMapperTest extends TestCase { + /** @var VakifBankAccount */ + public $account; + /** @var AbstractGateway */ private $pos; @@ -34,8 +37,6 @@ protected function setUp(): void { parent::setUp(); - $this->config = require __DIR__.'/../../config/pos.php'; - $this->account = AccountFactory::createVakifBankAccount( 'vakifbank', '000000000111111', @@ -61,6 +62,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); + $this->requestDataMapper = new VakifBankPosRequestDataMapper(); $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '2021', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); } @@ -95,10 +97,10 @@ public function testMapCurrency() * @param string|int|null $installment * @param string|int $expected * - * @testWith ["0", 0] - * ["1", 0] - * ["2", 2] - * [2, 2] + * @testWith ["0", "0"] + * ["1", "0"] + * ["2", "2"] + * [2, "2"] * * @return void */ @@ -117,11 +119,12 @@ public function testCreate3DPaymentRequestData() $order['amount'] = 10.1; $pos = $this->pos; $pos->prepare($order, AbstractGateway::TX_PAY, $this->card); + $txType = AbstractGateway::TX_PAY; $gatewayResponse = [ - 'Eci' => (string) rand(1, 100), - 'Cavv' => (string) rand(1, 100), - 'VerifyEnrollmentRequestId' => (string) rand(1, 100), + 'Eci' => (string) random_int(1, 100), + 'Cavv' => (string) random_int(1, 100), + 'VerifyEnrollmentRequestId' => (string) random_int(1, 100), ]; $expectedValue = $this->getSample3DPaymentRequestData($pos->getAccount(), $pos->getOrder(), $txType, $gatewayResponse, $pos->getCard()); @@ -142,6 +145,7 @@ public function testCreate3DEnrollmentCheckData() { $pos = $this->pos; $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $expectedValue = $this->getSample3DEnrollmentRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); $actual = $this->requestDataMapper->create3DEnrollmentCheckRequestData($pos->getAccount(), $pos->getOrder(), $pos->getCard()); $this->assertEquals($expectedValue, $actual); @@ -236,6 +240,7 @@ public function testCreate3DFormData() { $pos = $this->pos; $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $expectedValue = $this->getSample3DFormDataFromEnrollmentResponse(); $actualData = $this->requestDataMapper->create3DFormData( $pos->getAccount(), @@ -458,6 +463,7 @@ private function getSample3DFormDataFromEnrollmentResponse(): array return [ 'gateway' => 'http', + 'method' => 'POST', 'inputs' => $inputs, ]; } diff --git a/tests/Gateways/EstPosTest.php b/tests/Gateways/EstPosTest.php index 5bb9be03..f1c2ea6c 100644 --- a/tests/Gateways/EstPosTest.php +++ b/tests/Gateways/EstPosTest.php @@ -24,12 +24,15 @@ class EstPosTest extends TestCase { /** @var EstPosAccount */ private $account; + /** @var EstPos */ private $pos; + private $config; /** @var AbstractCreditCard */ private $card; + private $order; /** @var EstPosResponseDataMapperTest */ @@ -115,6 +118,7 @@ public function testMake3DPaymentAuthFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->make3DPayment($request); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); @@ -131,6 +135,7 @@ public function testMake3DHostPaymentSuccess() $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $pos->make3DHostPayment($request); + $result = $pos->getResponse(); $this->assertIsArray($result); $this->assertTrue($pos->isSuccess()); @@ -147,6 +152,7 @@ public function testMake3DPayPaymentSuccess() $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $pos->make3DHostPayment($request); + $result = $pos->getResponse(); $this->assertIsArray($result); $this->assertTrue($pos->isSuccess()); @@ -179,6 +185,7 @@ public function testMake3DPayPayment3DAuthFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->make3DPayment($request); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); @@ -213,6 +220,7 @@ public function testStatusSuccess() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->status(); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertTrue($posMock->isSuccess()); @@ -247,6 +255,7 @@ public function testStatusFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->status(); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); @@ -281,6 +290,7 @@ public function testHistorySuccess() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->history([]); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertTrue($posMock->isSuccess()); @@ -315,6 +325,7 @@ public function testHistoryFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->history([]); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); @@ -349,6 +360,7 @@ public function testCancelSuccess() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->cancel(); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertTrue($posMock->isSuccess()); @@ -383,6 +395,7 @@ public function testCancelFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->cancel(); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); @@ -417,6 +430,7 @@ public function testRefundFail() $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); $posMock->refund(); + $result = $posMock->getResponse(); $this->assertIsArray($result); $this->assertFalse($posMock->isSuccess()); diff --git a/tests/Gateways/GarantiPosTest.php b/tests/Gateways/GarantiPosTest.php index 009a68ba..3b21be69 100644 --- a/tests/Gateways/GarantiPosTest.php +++ b/tests/Gateways/GarantiPosTest.php @@ -20,10 +20,12 @@ class GarantiPosTest extends TestCase { /** @var GarantiPosAccount */ private $account; + private $config; /** @var AbstractCreditCard */ private $card; + private $order; /** @var GarantiPos */ @@ -63,6 +65,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122'); } diff --git a/tests/Gateways/InterPosTest.php b/tests/Gateways/InterPosTest.php index d769e7e4..1b3b2201 100644 --- a/tests/Gateways/InterPosTest.php +++ b/tests/Gateways/InterPosTest.php @@ -22,12 +22,15 @@ class InterPosTest extends TestCase { /** @var InterPosAccount */ private $account; + /** @var InterPos */ private $pos; + /** @var AbstractCreditCard */ private $card; private $config; + private $order; protected function setUp(): void @@ -64,6 +67,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); } diff --git a/tests/Gateways/KuveytPosTest.php b/tests/Gateways/KuveytPosTest.php index 07075d95..b19b0761 100644 --- a/tests/Gateways/KuveytPosTest.php +++ b/tests/Gateways/KuveytPosTest.php @@ -18,29 +18,23 @@ use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Serializer\Encoder\XmlEncoder; /** * KuveytPosTest */ class KuveytPosTest extends TestCase { - /** - * @var KuveytPosAccount - */ + /** @var KuveytPosAccount */ private $threeDAccount; private $config; - /** - * @var AbstractCreditCard - */ + /** @var AbstractCreditCard */ private $card; + private $order; - /** - * @var KuveytPos - */ + /** @var KuveytPos */ private $pos; /** @@ -79,6 +73,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create( $this->pos, '4155650100416111', @@ -88,8 +83,6 @@ protected function setUp(): void 'John Doe', AbstractCreditCard::CARD_TYPE_VISA ); - - $this->xmlDecoder = new XmlEncoder(); } /** @@ -246,6 +239,7 @@ public function testMake3DPaymentAuthSuccessProvisionSuccess() ->getMock(); $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $paymentResponse = $kuveytPosResponseDataMapperTest->threeDPaymentDataProvider()['success1']['paymentData']; $posMock->expects($this->once())->method('send')->willReturn($paymentResponse); @@ -266,7 +260,8 @@ public function parseHTMLResponseTestProvider(): array 'html' => '', 'expected' => [ 'gateway' => 'https://boa.kuveytturk.com.tr/sanalposservice/Home/ThreeDModelPayGate', - 'inputs' => [ + 'method' => 'POST', + 'inputs' => [ 'AuthenticationResponse' => '%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3CVPosTransactionResponseContract%3E%3CVPosMessage%3E%3CAPIVersion%3E1.0.0%3C%2FAPIVersion%3E%3COkUrl%3Ehttp%3A%2F%2Flocalhost%3A44785%2FHome%2FSuccess%3C%2FOkUrl%3E%3CFailUrl%3Ehttp%3A%2F%2Flocalhost%3A44785%2FHome%2FFail%3C%2FFailUrl%3E%3CHashData%3ElYJYMi%2FgVO9MWr32Pshaa%2FzAbSHY%3D%3C%2FHashData%3E%3CMerchantId%3E80%3C%2FMerchantId%3E%3CSubMerchantId%3E0%3C%2FSubMerchantId%3E%3CCustomerId%3E400235%3C%2FCustomerId%3E%3CUserName%3Eapiuser%3C%2FUserName%3E%3CCardNumber%3E4025502306586032%3C%2FCardNumber%3E%3CCardHolderName%3Eafafa%3C%2FCardHolderName%3E%3CCardType%3EMasterCard%3C%2FCardType%3E%3CBatchID%3E0%3C%2FBatchID%3E%3CTransactionType%3ESale%3C%2FTransactionType%3E%3CInstallmentCount%3E0%3C%2FInstallmentCount%3E%3CAmount%3E100%3C%2FAmount%3E%3CDisplayAmount%3E100%3C%2FDisplayAmount%3E%3CMerchantOrderId%3EOrder+123%3C%2FMerchantOrderId%3E%3CFECAmount%3E0%3C%2FFECAmount%3E%3CCurrencyCode%3E0949%3C%2FCurrencyCode%3E%3CQeryId%3E0%3C%2FQeryId%3E%3CDebtId%3E0%3C%2FDebtId%3E%3CSurchargeAmount%3E0%3C%2FSurchargeAmount%3E%3CSGKDebtAmount%3E0%3C%2FSGKDebtAmount%3E%3CTransactionSecurity%3E3%3C%2FTransactionSecurity%3E%3CTransactionSide%3EAuto%3C%2FTransactionSide%3E%3CEntryGateMethod%3EVPOS_ThreeDModelPayGate%3C%2FEntryGateMethod%3E%3C%2FVPosMessage%3E%3CIsEnrolled%3Etrue%3C%2FIsEnrolled%3E%3CIsVirtual%3Efalse%3C%2FIsVirtual%3E%3COrderId%3E0%3C%2FOrderId%3E%3CTransactionTime%3E0001-01-01T00%3A00%3A00%3C%2FTransactionTime%3E%3CMD%3E67YtBfBRTZ0XBKnAHi8c%2FA%3D%3D%3C%2FMD%3E%3CAuthenticationPacket%3EWYGDgSIrSHDtYwF%2FWEN%2BnfwX63sppA%3D%3C%2FAuthenticationPacket%3E%3CACSURL%3Ehttps%3A%2F%2Facs.bkm.com.tr%2Fmdpayacs%2Fpareq%3C%2FACSURL%3E%3C%2FVPosTransactionResponseContract%3E' ] ], @@ -276,7 +271,8 @@ public function parseHTMLResponseTestProvider(): array 'html' => "\n\n\n\n\n3D Secure Processing\n\n\n
    \n
    \n
    \n

    3D Secure Processing

    \nPlease wait..\n
    \n\n
    \n
    \n\n\n\n\n\n\n\n\n\n\n\n
    \n
    \n
    \n
    \n\n
    \n
    \n\n\n", 'expected' => [ 'gateway' => 'https://certemvtds.bkm.com.tr/tds/resultFlow', - 'inputs' => [ + 'method' => 'POST', + 'inputs' => [ 'threeDSServerWebFlowStart' => 'eyJhbGciOiJIUzI1NiJ9.ewogICJ0aHJlZURTU2VydmVyV2ViRmxvd1N0YXJ0IiA6IHsKICAgICJhY3F1aXJlcklEIiA6ICIyMDUiLAogICAgInRocmVlRFNTZXJ2ZXJUcmFuc0lEIiA6ICJhN2QyMjQ4Mi1jMjI2LTRkZjUtODkwNC00M2RmOTZmOTJmNDAiLAogICAgInRocmVlRFNSZXF1ZXN0b3JUcmFuc0lEIiA6ICI4ZGVhOGIwYi1mZTg0LTRhZGQtOWI4Mi05MzM2ZWYyMWM1MjciLAogICAgInRpbWVab25lIiA6ICJVVEMrMDM6MDAiLAogICAgInRpbWVTdGFtcCIgOiAiMjAyMjEyMjgxMjU2NDAiLAogICAgInZlcnNpb24iIDogIjEuMC4wIgogIH0KfQ.w7KQvGhrujSZmzyqEBsqJJKb19vJo16pq_PssXcGc6k', 'browserColorDepth' => '', 'browserScreenHeight' => '', @@ -293,7 +289,8 @@ public function parseHTMLResponseTestProvider(): array 'expected' => [ // 3d form data olusturulmasi icin gonderilen istek banka tarafindan reddedillirse, bankadan fail URL'a yonlendirilecek bir response (html) doner. 'gateway' => 'http://localhost/finansbank-payfor/3d/response.php', - 'inputs' => [ + 'method' => 'POST', + 'inputs' => [ 'AuthenticationResponse' => '%3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-8%22%3f%3e%3cVPosTransactionResponseContract+xmlns%3axsd%3d%22http%3a%2f%2fwww.w3.org%2f2001%2fXMLSchema%22+xmlns%3axsi%3d%22http%3a%2f%2fwww.w3.org%2f2001%2fXMLSchema-instance%22%3e%3cIsEnrolled%3etrue%3c%2fIsEnrolled%3e%3cIsVirtual%3efalse%3c%2fIsVirtual%3e%3cResponseCode%3eHashDataError%3c%2fResponseCode%3e%3cResponseMessage%3e%c5%9eifrelenen+veriler+(Hashdata)+uyu%c5%9fmamaktad%c4%b1r.%3c%2fResponseMessage%3e%3cOrderId%3e0%3c%2fOrderId%3e%3cTransactionTime%3e0001-01-01T00%3a00%3a00%3c%2fTransactionTime%3e%3cMerchantOrderId%3e2020110828BC%3c%2fMerchantOrderId%3e%3cReferenceId%3efbab348b4c074d1b9a5247471d91f5d1%3c%2fReferenceId%3e%3cMerchantId%3e496%3c%2fMerchantId%3e%3cBusinessKey%3e0%3c%2fBusinessKey%3e%3c%2fVPosTransactionResponseContract%3e', ] ], diff --git a/tests/Gateways/PayForTest.php b/tests/Gateways/PayForTest.php index af6621d7..c353a421 100644 --- a/tests/Gateways/PayForTest.php +++ b/tests/Gateways/PayForTest.php @@ -25,6 +25,7 @@ class PayForTest extends TestCase /** @var AbstractCreditCard */ private $card; + private $order; /** @var PayForPos */ @@ -61,6 +62,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->threeDAccount); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '22', '01', '123', 'ahmet'); } diff --git a/tests/Gateways/PosNetTest.php b/tests/Gateways/PosNetTest.php index 0179038c..6d8ef1ff 100644 --- a/tests/Gateways/PosNetTest.php +++ b/tests/Gateways/PosNetTest.php @@ -30,7 +30,9 @@ class PosNetTest extends TestCase /** @var AbstractCreditCard */ private $card; + private $order; + /** @var PosNet */ private $pos; @@ -68,6 +70,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '21', '12', '122', 'ahmet'); } @@ -156,6 +159,7 @@ public function testMake3DPaymentSuccess() ->getMock(); $posMock->setTestMode(true); $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $bankResponses = $responseMapperTest->threeDPaymentDataProvider()['success1']; $posMock->expects($this->exactly(2))->method('send')->will( $this->onConsecutiveCalls( diff --git a/tests/Gateways/VakifBankCPPosTest.php b/tests/Gateways/VakifBankCPPosTest.php new file mode 100644 index 00000000..733fb74c --- /dev/null +++ b/tests/Gateways/VakifBankCPPosTest.php @@ -0,0 +1,219 @@ +config = require __DIR__.'/../../config/pos.php'; + + $this->account = AccountFactory::createVakifBankAccount( + 'vakifbank-cp', + '000000000111111', + '3XTgER89as', + 'VP999999', + AbstractGateway::MODEL_3D_SECURE + ); + + + $this->order = [ + 'id' => 'order222', + 'name' => 'siparis veren', + 'email' => 'test@test.com', + 'amount' => 100.00, + 'installment' => 0, + 'currency' => 'TRY', + 'success_url' => 'https://domain.com/success', + 'fail_url' => 'https://domain.com/fail_url', + 'rand' => microtime(true), + 'extraData' => microtime(true), + 'ip' => '127.0.0.1', + ]; + + $this->pos = PosFactory::createPosGateway($this->account); + + $this->pos->setTestMode(true); + + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '2021', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); + } + + /** + * @return void + */ + public function testInit(): void + { + $this->assertEquals($this->config['banks'][$this->account->getBank()], $this->pos->getConfig()); + $this->assertEquals($this->account, $this->pos->getAccount()); + $this->assertNotEmpty($this->pos->getQueryAPIUrl()); + $this->assertNotEmpty($this->pos->getCurrencies()); + } + + /** + * @return void + */ + public function testPrepare(): void + { + $this->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); + } + + public function testGet3DFormDataSuccess(): void + { + $crypt = PosFactory::getGatewayCrypt(VakifBankCPPos::class, new NullLogger()); + $requestMapper = PosFactory::getGatewayRequestMapper(VakifBankCPPos::class, [], $crypt); + $responseMapper = PosFactory::getGatewayResponseMapper(VakifBankCPPos::class, $requestMapper, new NullLogger()); + + $posMock = $this->getMockBuilder(VakifBankCPPos::class) + ->setConstructorArgs([ + [], + $this->account, + $requestMapper, + $responseMapper, + HttpClientFactory::createDefaultHttpClient(), + new NullLogger() + ]) + ->onlyMethods(['registerPayment']) + ->getMock(); + $posMock->setTestMode(true); + $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $posMock->expects($this->once())->method('registerPayment') + ->willReturn(VakifBankCPPosRequestDataMapperTest::threeDFormDataProvider()->current()['queryParams']); + + $result = $posMock->get3DFormData(); + + $this->assertSame(VakifBankCPPosRequestDataMapperTest::threeDFormDataProvider()->current()['expected'], $result); + } + + public function testGet3DFormDataFail(): void + { + $this->expectException(Exception::class); + $posMock = $this->getMockBuilder(VakifBankCPPos::class) + ->setConstructorArgs([ + [], + $this->account, + $this->createMock(VakifBankCPPosRequestDataMapper::class), + $this->createMock(VakifBankCPPosResponseDataMapper::class), + HttpClientFactory::createDefaultHttpClient(), + new NullLogger() + ]) + ->onlyMethods(['registerPayment']) + ->getMock(); + $posMock->setTestMode(true); + $posMock->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + $posMock->expects($this->once())->method('registerPayment') + ->willReturn([ + 'CommonPaymentUrl' => null, + 'PaymentToken' => null, + 'ErrorCode' => '5007', + 'ResponseMessage' => 'Güvenlik Numarası Hatalı', + ]); + + $posMock->get3DFormData(); + } + + public function testMake3dPayPaymentFail(): void + { + $failResponseData = iterator_to_array( + VakifBankCPPosResponseDataMapperTest::threesDPayResponseSamplesProvider() + )['fail_response_from_gateway_1']['bank_response']; + $request = Request::create('', 'GET', $failResponseData); + + $requestMapper = $this->createMock(VakifBankCPPosRequestDataMapper::class); + $requestMapper->expects($this->never()) + ->method('create3DPaymentStatusRequestData'); + + $responseMapper = $this->createMock(VakifBankCPPosResponseDataMapper::class); + $responseMapper->expects($this->once()) + ->method('map3DPayResponseData')->with($failResponseData); + + $pos = new VakifBankCPPos( + [], + $this->account, + $requestMapper, + $responseMapper, + HttpClientFactory::createDefaultHttpClient(), + new NullLogger()); + + $pos->prepare($this->order, AbstractGateway::TX_PAY, $this->card); + + $pos->make3DPayPayment($request); + } + + public function testMake3dPayPaymentSuccess(): void + { + $bankResponses = iterator_to_array(VakifBankCPPosResponseDataMapperTest::threesDPayResponseSamplesProvider()); + $bankQueryResponse = [ + 'Rc' => '0000', + 'AuthCode' => '368513', + 'Message' => 'İŞLEM BAŞARILI', + 'TransactionId' => '28d2b9c27af545f48d49afc300db246b', + 'PaymentToken' => 'c6b7cecc2a1846088a4eafc300db246b', + 'MaskedPan' => '49384601****4205', + ]; + $bankApiResponse = $bankResponses['success_response_from_gateway_1']['bank_response']; + + $request = Request::create('', 'GET', $bankQueryResponse); + + $requestMapper = $this->createMock(VakifBankCPPosRequestDataMapper::class); + $requestMapper->expects($this->once()) + ->method('create3DPaymentStatusRequestData')->with($this->account, $bankQueryResponse); + + $responseMapper = $this->createMock(VakifBankCPPosResponseDataMapper::class); + $responseMapper->expects($this->once()) + ->method('map3DPayResponseData'); + + $posMock = $this->getMockBuilder(VakifBankCPPos::class) + ->setConstructorArgs([ + [], + $this->account, + $requestMapper, + $responseMapper, + HttpClientFactory::createDefaultHttpClient(), + new NullLogger() + ]) + ->onlyMethods(['send', 'getQueryAPIUrl']) + ->getMock(); + $posMock->expects($this->once())->method('getQueryAPIUrl')->willReturn($this->pos->getQueryAPIUrl()); + $posMock->expects($this->once())->method('send')->willReturn([$bankApiResponse]); + + $posMock->make3DPayPayment($request); + } +} diff --git a/tests/Gateways/VakifBankPosTest.php b/tests/Gateways/VakifBankPosTest.php index 6fcae83f..5dfa9c4b 100644 --- a/tests/Gateways/VakifBankPosTest.php +++ b/tests/Gateways/VakifBankPosTest.php @@ -22,23 +22,19 @@ */ class VakifBankPosTest extends TestCase { - /** - * @var VakifBankAccount - */ + /** @var VakifBankAccount */ private $account; - /** - * @var VakifBankPos - */ + + /** @var VakifBankPos */ private $pos; + private $config; - /** - * @var AbstractCreditCard - */ + /** @var AbstractCreditCard */ private $card; /** @var array */ - private $order; + private $order = []; protected function setUp(): void { @@ -72,6 +68,7 @@ protected function setUp(): void $this->pos = PosFactory::createPosGateway($this->account); $this->pos->setTestMode(true); + $this->card = CreditCardFactory::create($this->pos, '5555444433332222', '2021', '12', '122', 'ahmet', AbstractCreditCard::CARD_TYPE_VISA); } @@ -156,7 +153,8 @@ public function testGet3DFormDataSuccess() $result = $posMock->get3DFormData(); $expected = [ 'gateway' => $enrollmentResponse['Message']['VERes']['ACSUrl'], - 'inputs' => [ + 'method' => 'POST', + 'inputs' => [ 'PaReq' => $enrollmentResponse['Message']['VERes']['PaReq'], 'TermUrl' => $enrollmentResponse['Message']['VERes']['TermUrl'], 'MD' => $enrollmentResponse['Message']['VERes']['MD'],