From bb6df2d616375f3469aaf3c5f792f4be09ed1881 Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Wed, 29 May 2024 17:33:00 +0200 Subject: [PATCH 1/5] tests - added refund test to AkbankPos functional test --- tests/Functional/AkbankPosTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Functional/AkbankPosTest.php b/tests/Functional/AkbankPosTest.php index 2fd8bbe7..0d53f7c8 100644 --- a/tests/Functional/AkbankPosTest.php +++ b/tests/Functional/AkbankPosTest.php @@ -231,6 +231,33 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro return $lastResponse; } + /** + * @depends testNonSecurePostPaymentSuccess + */ + public function testRefundSuccess(array $lastResponse): array + { + $refundOrder = $this->createRefundOrder(\get_class($this->pos), $lastResponse); + + $eventIsThrown = false; + $this->eventDispatcher->addListener( + RequestDataPreparedEvent::class, + function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { + $eventIsThrown = true; + $this->assertSame(PosInterface::TX_TYPE_REFUND, $requestDataPreparedEvent->getTxType()); + $this->assertCount(7, $requestDataPreparedEvent->getRequestData()); + }); + + $this->pos->refund($refundOrder); + + $response = $this->pos->getResponse(); + $this->assertTrue($this->pos->isSuccess(), $response['error_message'] ?? ''); + $this->assertIsArray($response); + $this->assertNotEmpty($response); + $this->assertTrue($eventIsThrown); + + return $lastResponse; + } + public function testNonSecurePaymentRecurringSuccess(): array { $order = $this->createPaymentOrder( @@ -403,6 +430,7 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro $this->recurringPos->history($historyOrder); $response = $this->recurringPos->getResponse(); + $this->assertTrue($this->recurringPos->isSuccess()); $this->assertIsArray($response); $this->assertTrue($eventIsThrown); $this->assertNotEmpty($response['transactions']); From 23a045a48b27c8281a07565fe7ea22b50938dab1 Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Wed, 29 May 2024 17:47:26 +0200 Subject: [PATCH 2/5] issue 218 add TX_TYPE_REFUND_PARTIAL --- .../AkbankPosRequestDataMapper.php | 19 ++-- .../EstPosRequestDataMapper.php | 19 ++-- .../GarantiPosRequestDataMapper.php | 19 ++-- .../InterPosRequestDataMapper.php | 17 ++-- .../KuveytPosRequestDataMapper.php | 17 ++-- .../PayFlexCPV4PosRequestDataMapper.php | 19 ++-- .../PayFlexV4PosRequestDataMapper.php | 17 ++-- .../PayForPosRequestDataMapper.php | 19 ++-- .../PosNetRequestDataMapper.php | 17 ++-- .../PosNetV1PosRequestDataMapper.php | 15 ++-- .../RequestDataMapperInterface.php | 5 +- .../ToslaPosRequestDataMapper.php | 13 +-- .../VakifKatilimPosRequestDataMapper.php | 2 +- .../KuveytPosResponseDataMapper.php | 3 + src/Gateways/AbstractGateway.php | 5 +- src/Gateways/AkbankPos.php | 19 ++-- src/Gateways/EstPos.php | 17 ++-- src/Gateways/GarantiPos.php | 17 ++-- src/Gateways/InterPos.php | 17 ++-- src/Gateways/KuveytPos.php | 27 +++--- src/Gateways/PayFlexCPV4Pos.php | 17 ++-- src/Gateways/PayFlexV4Pos.php | 17 ++-- src/Gateways/PayForPos.php | 17 ++-- src/Gateways/PosNet.php | 17 ++-- src/Gateways/PosNetV1Pos.php | 17 ++-- src/Gateways/ToslaPos.php | 28 +++--- src/Gateways/VakifKatilimPos.php | 38 ++++---- src/PosInterface.php | 3 + src/Serializer/KuveytPosSerializer.php | 1 + src/Serializer/PayFlexCPV4PosSerializer.php | 4 +- tests/Functional/EstV3PosTest.php | 2 +- tests/Functional/KuveytPosTest.php | 2 +- tests/Functional/ToslaPosTest.php | 2 +- .../AkbankPosRequestDataMapperTest.php | 6 +- .../EstPosRequestDataMapperTest.php | 81 +++++++++-------- .../GarantiPosRequestDataMapperTest.php | 61 +++++++++---- .../InterPosRequestDataMapperTest.php | 80 ++++++++++------- .../KuveytPosRequestDataMapperTest.php | 10 ++- .../PayFlexV4PosRequestDataMapperTest.php | 68 +++++++++----- .../PayForPosRequestDataMapperTest.php | 89 +++++++++++-------- .../PosNetRequestDataMapperTest.php | 14 +-- .../PosNetV1PosRequestDataMapperTest.php | 17 ++-- .../ToslaPosRequestDataMapperTest.php | 9 +- .../VakifKatilimPosRequestDataMapperTest.php | 10 ++- tests/Unit/Gateways/AkbankPosTest.php | 25 ++++-- tests/Unit/Gateways/EstPosTest.php | 2 +- tests/Unit/Gateways/GarantiPosTest.php | 2 +- tests/Unit/Gateways/InterPosTest.php | 2 +- tests/Unit/Gateways/KuveytPosTest.php | 5 ++ tests/Unit/Gateways/PayFlexCPV4PosTest.php | 2 +- tests/Unit/Gateways/PayFlexV4PosTest.php | 2 +- tests/Unit/Gateways/PayForTest.php | 2 +- tests/Unit/Gateways/PosNetTest.php | 2 +- tests/Unit/Gateways/PosNetV1PosTest.php | 2 +- tests/Unit/Gateways/ToslaPosTest.php | 11 ++- tests/Unit/Gateways/VakifKatilimTest.php | 27 ++++-- .../Serializer/KuveytPosSerializerTest.php | 6 ++ 57 files changed, 608 insertions(+), 395 deletions(-) diff --git a/src/DataMapper/RequestDataMapper/AkbankPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/AkbankPosRequestDataMapper.php index b070454d..02620c82 100644 --- a/src/DataMapper/RequestDataMapper/AkbankPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/AkbankPosRequestDataMapper.php @@ -29,23 +29,24 @@ class AkbankPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_NON_SECURE => '1000', PosInterface::MODEL_3D_SECURE => '3000', PosInterface::MODEL_3D_PAY => '3000', PosInterface::MODEL_3D_HOST => '3000', ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => [ + PosInterface::TX_TYPE_PAY_PRE_AUTH => [ PosInterface::MODEL_NON_SECURE => '1004', PosInterface::MODEL_3D_SECURE => '3004', PosInterface::MODEL_3D_PAY => '3004', PosInterface::MODEL_3D_HOST => '3004', ], - PosInterface::TX_TYPE_PAY_POST_AUTH => '1005', - PosInterface::TX_TYPE_REFUND => '1002', - PosInterface::TX_TYPE_CANCEL => '1003', - PosInterface::TX_TYPE_ORDER_HISTORY => '1010', - PosInterface::TX_TYPE_HISTORY => '1009', + PosInterface::TX_TYPE_PAY_POST_AUTH => '1005', + PosInterface::TX_TYPE_REFUND => '1002', + PosInterface::TX_TYPE_REFUND_PARTIAL => '1002', + PosInterface::TX_TYPE_CANCEL => '1003', + PosInterface::TX_TYPE_ORDER_HISTORY => '1010', + PosInterface::TX_TYPE_HISTORY => '1009', ]; /** @@ -261,13 +262,13 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); $requestData = $this->getRequestAccountData($posAccount) + [ 'version' => self::API_VERSION, - 'txnCode' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'txnCode' => $this->mapTxType($refundTxType), 'requestDateTime' => $this->formatRequestDateTime($order['transaction_time']), 'randomNumber' => $this->crypt->generateRandomString(), 'transaction' => [ diff --git a/src/DataMapper/RequestDataMapper/EstPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/EstPosRequestDataMapper.php index cdd53a23..8a01b4c5 100644 --- a/src/DataMapper/RequestDataMapper/EstPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/EstPosRequestDataMapper.php @@ -31,13 +31,14 @@ class EstPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', - PosInterface::TX_TYPE_CANCEL => 'Void', - PosInterface::TX_TYPE_REFUND => 'Credit', - PosInterface::TX_TYPE_STATUS => 'ORDERSTATUS', - PosInterface::TX_TYPE_HISTORY => 'ORDERHISTORY', + PosInterface::TX_TYPE_PAY_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', + PosInterface::TX_TYPE_CANCEL => 'Void', + PosInterface::TX_TYPE_REFUND => 'Credit', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Credit', + PosInterface::TX_TYPE_STATUS => 'ORDERSTATUS', + PosInterface::TX_TYPE_HISTORY => 'ORDERHISTORY', ]; /** @@ -199,14 +200,14 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * {@inheritDoc} * @return array{OrderId: string, Currency: string, Type: string, Total?: string, Name: string, Password: string, ClientId: string} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); $requestData = [ 'OrderId' => (string) $order['id'], 'Currency' => $this->mapCurrency($order['currency']), - 'Type' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'Type' => $this->mapTxType($refundTxType), ]; if (isset($order['amount'])) { diff --git a/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php index 4d930394..d48c2865 100644 --- a/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php @@ -47,13 +47,14 @@ class GarantiPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'sales', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'preauth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'postauth', - PosInterface::TX_TYPE_CANCEL => 'void', - PosInterface::TX_TYPE_REFUND => 'refund', - PosInterface::TX_TYPE_HISTORY => 'orderhistoryinq', - PosInterface::TX_TYPE_STATUS => 'orderinq', + PosInterface::TX_TYPE_PAY_AUTH => 'sales', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'preauth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'postauth', + PosInterface::TX_TYPE_CANCEL => 'void', + PosInterface::TX_TYPE_REFUND => 'refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'refund', + PosInterface::TX_TYPE_HISTORY => 'orderhistoryinq', + PosInterface::TX_TYPE_STATUS => 'orderinq', ]; protected array $recurringOrderFrequencyMapping = [ @@ -254,7 +255,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); @@ -269,7 +270,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'OrderID' => $order['id'], ], 'Transaction' => [ - 'Type' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'Type' => $this->mapTxType($refundTxType), 'InstallmentCnt' => $this->mapInstallment($order['installment']), 'Amount' => $this->formatAmount($order['amount']), //sabit olarak amount 100 gonderilecek, 'CurrencyCode' => $this->mapCurrency($order['currency']), diff --git a/src/DataMapper/RequestDataMapper/InterPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/InterPosRequestDataMapper.php index b64e9c7b..fa7219ba 100644 --- a/src/DataMapper/RequestDataMapper/InterPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/InterPosRequestDataMapper.php @@ -42,12 +42,13 @@ class InterPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritdoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', - PosInterface::TX_TYPE_CANCEL => 'Void', - PosInterface::TX_TYPE_REFUND => 'Refund', - PosInterface::TX_TYPE_STATUS => 'StatusHistory', + PosInterface::TX_TYPE_PAY_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', + PosInterface::TX_TYPE_CANCEL => 'Void', + PosInterface::TX_TYPE_REFUND => 'Refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Refund', + PosInterface::TX_TYPE_STATUS => 'StatusHistory', ]; /** @@ -170,7 +171,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * {@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 $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); @@ -178,7 +179,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'OrderId' => null, 'orgOrderId' => (string) $order['id'], 'PurchAmount' => (string) $order['amount'], - 'TxnType' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'TxnType' => $this->mapTxType($refundTxType), 'SecureType' => $this->secureTypeMappings[PosInterface::MODEL_NON_SECURE], 'Lang' => $this->getLang($posAccount, $order), 'MOTO' => self::MOTO, diff --git a/src/DataMapper/RequestDataMapper/KuveytPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/KuveytPosRequestDataMapper.php index 739dd145..12ba644e 100644 --- a/src/DataMapper/RequestDataMapper/KuveytPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/KuveytPosRequestDataMapper.php @@ -40,10 +40,11 @@ class KuveytPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Sale', - PosInterface::TX_TYPE_CANCEL => 'SaleReversal', - PosInterface::TX_TYPE_STATUS => 'GetMerchantOrderDetail', - PosInterface::TX_TYPE_REFUND => 'Drawback', // Also there is a "PartialDrawback" + PosInterface::TX_TYPE_PAY_AUTH => 'Sale', + PosInterface::TX_TYPE_CANCEL => 'SaleReversal', + PosInterface::TX_TYPE_STATUS => 'GetMerchantOrderDetail', + PosInterface::TX_TYPE_REFUND => 'Drawback', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'PartialDrawback', ]; /** @@ -309,13 +310,10 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * @param KuveytPosAccount $posAccount * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); - $isPartialRefund = isset($order['order_amount']) && $order['order_amount'] > $order['amount']; - $txType = $isPartialRefund ? 'PartialDrawback' : $this->mapTxType(PosInterface::TX_TYPE_REFUND); - $result = [ 'IsFromExternalNetwork' => true, 'BusinessKey' => 0, @@ -337,7 +335,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'SubMerchantId' => 0, 'CardType' => $this->cardTypeMapping[CreditCardInterface::CARD_TYPE_VISA], //Default gönderilebilir. 'BatchID' => 0, - 'TransactionType' => $txType, + 'TransactionType' => $this->mapTxType($refundTxType), 'InstallmentCount' => 0, 'Amount' => $this->formatAmount($order['amount']), 'DisplayAmount' => 0, @@ -466,7 +464,6 @@ protected function prepareRefundOrder(array $order): array 'auth_code' => $order['auth_code'], 'transaction_id' => $order['transaction_id'], 'amount' => $order['amount'], - 'order_amount' => $order['order_amount'] ?? null, 'currency' => $order['currency'] ?? PosInterface::CURRENCY_TRY, ]); } diff --git a/src/DataMapper/RequestDataMapper/PayFlexCPV4PosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/PayFlexCPV4PosRequestDataMapper.php index ec53fee0..0ca2d167 100644 --- a/src/DataMapper/RequestDataMapper/PayFlexCPV4PosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/PayFlexCPV4PosRequestDataMapper.php @@ -24,13 +24,14 @@ class PayFlexCPV4PosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Sale', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', - PosInterface::TX_TYPE_CANCEL => 'Cancel', - PosInterface::TX_TYPE_REFUND => 'Refund', - PosInterface::TX_TYPE_HISTORY => 'TxnHistory', - PosInterface::TX_TYPE_STATUS => 'OrderInquiry', + PosInterface::TX_TYPE_PAY_AUTH => 'Sale', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', + PosInterface::TX_TYPE_CANCEL => 'Cancel', + PosInterface::TX_TYPE_REFUND => 'Refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Refund', + PosInterface::TX_TYPE_HISTORY => 'TxnHistory', + PosInterface::TX_TYPE_STATUS => 'OrderInquiry', ]; /** @@ -241,12 +242,12 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * @return array{MerchantId: string, Password: string, TransactionType: string, ReferenceTransactionId: string, * ClientIp: string, CurrencyAmount: string} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); return $this->getRequestAccountData($posAccount) + [ - 'TransactionType' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'TransactionType' => $this->mapTxType($refundTxType), 'ReferenceTransactionId' => (string) $order['transaction_id'], 'ClientIp' => (string) $order['ip'], 'CurrencyAmount' => $this->formatAmount($order['amount']), diff --git a/src/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapper.php index 4c019ee2..c2637081 100644 --- a/src/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapper.php @@ -28,12 +28,13 @@ class PayFlexV4PosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Sale', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', - PosInterface::TX_TYPE_CANCEL => 'Cancel', - PosInterface::TX_TYPE_REFUND => 'Refund', - PosInterface::TX_TYPE_STATUS => 'status', + PosInterface::TX_TYPE_PAY_AUTH => 'Sale', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', + PosInterface::TX_TYPE_CANCEL => 'Cancel', + PosInterface::TX_TYPE_REFUND => 'Refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Refund', + PosInterface::TX_TYPE_STATUS => 'status', ]; /** @@ -233,14 +234,14 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * @return array{MerchantId: string, Password: string, TransactionType: string, ReferenceTransactionId: string, * ClientIp: string, CurrencyAmount: string} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); return [ 'MerchantId' => $posAccount->getClientId(), 'Password' => $posAccount->getPassword(), - 'TransactionType' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'TransactionType' => $this->mapTxType($refundTxType), 'ReferenceTransactionId' => (string) $order['transaction_id'], 'ClientIp' => (string) $order['ip'], 'CurrencyAmount' => $this->formatAmount($order['amount']), diff --git a/src/DataMapper/RequestDataMapper/PayForPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/PayForPosRequestDataMapper.php index 8d60dbcd..7a03c07d 100644 --- a/src/DataMapper/RequestDataMapper/PayForPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/PayForPosRequestDataMapper.php @@ -43,13 +43,14 @@ class PayForPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', - PosInterface::TX_TYPE_CANCEL => 'Void', - PosInterface::TX_TYPE_REFUND => 'Refund', - PosInterface::TX_TYPE_HISTORY => 'TxnHistory', - PosInterface::TX_TYPE_STATUS => 'OrderInquiry', + PosInterface::TX_TYPE_PAY_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'PostAuth', + PosInterface::TX_TYPE_CANCEL => 'Void', + PosInterface::TX_TYPE_REFUND => 'Refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Refund', + PosInterface::TX_TYPE_HISTORY => 'TxnHistory', + PosInterface::TX_TYPE_STATUS => 'OrderInquiry', ]; /** @@ -155,7 +156,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * {@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 $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); @@ -164,7 +165,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'SecureType' => $this->secureTypeMappings[PosInterface::MODEL_NON_SECURE], 'Lang' => $this->getLang($posAccount, $order), 'OrgOrderId' => (string) $order['id'], - 'TxnType' => $this->mapTxType(PosInterface::TX_TYPE_REFUND), + 'TxnType' => $this->mapTxType($refundTxType), 'PurchAmount' => (string) $order['amount'], 'Currency' => $this->mapCurrency($order['currency']), ]; diff --git a/src/DataMapper/RequestDataMapper/PosNetRequestDataMapper.php b/src/DataMapper/RequestDataMapper/PosNetRequestDataMapper.php index 8a94bf64..d2d5a711 100644 --- a/src/DataMapper/RequestDataMapper/PosNetRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/PosNetRequestDataMapper.php @@ -46,12 +46,13 @@ class PosNetRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Sale', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capt', - PosInterface::TX_TYPE_CANCEL => 'reverse', - PosInterface::TX_TYPE_REFUND => 'return', - PosInterface::TX_TYPE_STATUS => 'agreement', + PosInterface::TX_TYPE_PAY_AUTH => 'Sale', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capt', + PosInterface::TX_TYPE_CANCEL => 'reverse', + PosInterface::TX_TYPE_REFUND => 'return', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'return', + PosInterface::TX_TYPE_STATUS => 'agreement', ]; /** @@ -201,11 +202,11 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); - $txType = $this->mapTxType(PosInterface::TX_TYPE_REFUND); + $txType = $this->mapTxType($refundTxType); $requestData = [ 'mid' => $posAccount->getClientId(), 'tid' => $posAccount->getTerminalId(), diff --git a/src/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapper.php index 3c98209e..2e912cb2 100644 --- a/src/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapper.php @@ -51,12 +51,13 @@ class PosNetV1PosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => 'Sale', - PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', - PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', - PosInterface::TX_TYPE_CANCEL => 'Reverse', - PosInterface::TX_TYPE_REFUND => 'Return', - PosInterface::TX_TYPE_STATUS => 'TransactionInquiry', + PosInterface::TX_TYPE_PAY_AUTH => 'Sale', + PosInterface::TX_TYPE_PAY_PRE_AUTH => 'Auth', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'Capture', + PosInterface::TX_TYPE_CANCEL => 'Reverse', + PosInterface::TX_TYPE_REFUND => 'Return', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'Return', + PosInterface::TX_TYPE_STATUS => 'TransactionInquiry', ]; /** @@ -281,7 +282,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); diff --git a/src/DataMapper/RequestDataMapper/RequestDataMapperInterface.php b/src/DataMapper/RequestDataMapper/RequestDataMapperInterface.php index bdf3919c..9fe2a730 100644 --- a/src/DataMapper/RequestDataMapper/RequestDataMapperInterface.php +++ b/src/DataMapper/RequestDataMapper/RequestDataMapperInterface.php @@ -135,14 +135,17 @@ public function createStatusRequestData(AbstractPosAccount $posAccount, array $o public function createCancelRequestData(AbstractPosAccount $posAccount, array $order): array; /** + * @phpstan-param PosInterface::TX_TYPE_REFUND* $refundTxType + * * @param AbstractPosAccount $posAccount * @param array $order + * @param string $refundTxType * * @return array * * @throws UnsupportedTransactionTypeException */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array; + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array; /** * @param AbstractPosAccount $posAccount diff --git a/src/DataMapper/RequestDataMapper/ToslaPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/ToslaPosRequestDataMapper.php index 234f61d1..3e50d328 100644 --- a/src/DataMapper/RequestDataMapper/ToslaPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/ToslaPosRequestDataMapper.php @@ -23,11 +23,12 @@ class ToslaPosRequestDataMapper extends AbstractRequestDataMapper * {@inheritDoc} */ protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => '1', - PosInterface::TX_TYPE_PAY_PRE_AUTH => '2', - PosInterface::TX_TYPE_PAY_POST_AUTH => '3', - PosInterface::TX_TYPE_CANCEL => '4', - PosInterface::TX_TYPE_REFUND => '5', + PosInterface::TX_TYPE_PAY_AUTH => '1', + PosInterface::TX_TYPE_PAY_PRE_AUTH => '2', + PosInterface::TX_TYPE_PAY_POST_AUTH => '3', + PosInterface::TX_TYPE_CANCEL => '4', + PosInterface::TX_TYPE_REFUND => '5', + PosInterface::TX_TYPE_REFUND_PARTIAL => '5', ]; /** @@ -146,7 +147,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o /** * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); diff --git a/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php index 606025f5..d5c5f567 100644 --- a/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php @@ -229,7 +229,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o * @param KuveytPosAccount $posAccount * {@inheritDoc} */ - public function createRefundRequestData(AbstractPosAccount $posAccount, array $order): array + public function createRefundRequestData(AbstractPosAccount $posAccount, array $order, string $refundTxType): array { $order = $this->prepareRefundOrder($order); diff --git a/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php index 60460e0d..ef4c5723 100644 --- a/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/KuveytPosResponseDataMapper.php @@ -196,6 +196,9 @@ public function mapStatusResponse(array $rawResponseData): array return $defaultResponse; } + /** + * @inheritDoc + */ public function mapRefundResponse(array $rawResponseData): array { $rawResponseData = $this->emptyStringsToNull($rawResponseData); diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 03ccd7f8..3d4fc245 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -311,7 +311,10 @@ public function makeRegularPostPayment(array $order): PosInterface public function refund(array $order): PosInterface { $txType = PosInterface::TX_TYPE_REFUND; - $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $order); + if (isset($order['order_amount']) && $order['amount'] < $order['order_amount']) { + $txType = PosInterface::TX_TYPE_REFUND_PARTIAL; + } + $requestData = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); $event = new RequestDataPreparedEvent( $requestData, diff --git a/src/Gateways/AkbankPos.php b/src/Gateways/AkbankPos.php index d374bc7f..54d2b752 100644 --- a/src/Gateways/AkbankPos.php +++ b/src/Gateways/AkbankPos.php @@ -27,19 +27,20 @@ class AkbankPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => false, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_ORDER_HISTORY => true, - PosInterface::TX_TYPE_HISTORY => true, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => false, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_HISTORY => true, ]; /** @@ -196,7 +197,7 @@ protected function send($contents, string $txType, string $paymentModel, string $response = $this->client->post($url, [ 'headers' => [ 'Content-Type' => 'application/json', - 'auth-hash' => $hash, + 'auth-hash' => $hash, ], 'body' => $contents, ]); diff --git a/src/Gateways/EstPos.php b/src/Gateways/EstPos.php index 8f0b84c6..9fc39856 100644 --- a/src/Gateways/EstPos.php +++ b/src/Gateways/EstPos.php @@ -30,20 +30,21 @@ class EstPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_3D_PAY_HOSTING, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_ORDER_HISTORY => true, - PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_HISTORY => false, ]; diff --git a/src/Gateways/GarantiPos.php b/src/Gateways/GarantiPos.php index 550ba002..24d5df15 100644 --- a/src/Gateways/GarantiPos.php +++ b/src/Gateways/GarantiPos.php @@ -37,18 +37,19 @@ class GarantiPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_ORDER_HISTORY => true, - PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_HISTORY => false, ]; diff --git a/src/Gateways/InterPos.php b/src/Gateways/InterPos.php index b121a76f..b2b450d9 100644 --- a/src/Gateways/InterPos.php +++ b/src/Gateways/InterPos.php @@ -39,19 +39,20 @@ class InterPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** @return InterPosAccount */ diff --git a/src/Gateways/KuveytPos.php b/src/Gateways/KuveytPos.php index 344f8d6f..fcab2e4a 100644 --- a/src/Gateways/KuveytPos.php +++ b/src/Gateways/KuveytPos.php @@ -43,17 +43,18 @@ class KuveytPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_NON_SECURE, PosInterface::MODEL_3D_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => false, - PosInterface::TX_TYPE_PAY_POST_AUTH => false, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => false, + PosInterface::TX_TYPE_PAY_POST_AUTH => false, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** @return KuveytPosAccount */ @@ -73,6 +74,7 @@ public function getApiURL(string $txType = null, string $paymentModel = null, ?s $txType, [ PosInterface::TX_TYPE_REFUND, + PosInterface::TX_TYPE_REFUND_PARTIAL, PosInterface::TX_TYPE_STATUS, PosInterface::TX_TYPE_CANCEL, ], @@ -211,7 +213,12 @@ public function make3DPayment(Request $request, array $order, string $txType, Cr */ protected function send($contents, string $txType, string $paymentModel, string $url): array { - if (\in_array($txType, [PosInterface::TX_TYPE_REFUND, PosInterface::TX_TYPE_STATUS, PosInterface::TX_TYPE_CANCEL], true)) { + if (\in_array($txType, [ + PosInterface::TX_TYPE_REFUND, + PosInterface::TX_TYPE_REFUND_PARTIAL, + PosInterface::TX_TYPE_STATUS, + PosInterface::TX_TYPE_CANCEL, + ], true)) { if (!\is_array($contents)) { throw new InvalidArgumentException(\sprintf('Invalid data type provided for %s transaction!', $txType)); } @@ -233,7 +240,7 @@ protected function send($contents, string $txType, string $paymentModel, string } /** - * @phpstan-param PosInterface::TX_TYPE_STATUS|PosInterface::TX_TYPE_REFUND|PosInterface::TX_TYPE_CANCEL $txType + * @phpstan-param PosInterface::TX_TYPE_STATUS|PosInterface::TX_TYPE_REFUND|PosInterface::TX_TYPE_REFUND_PARTIAL|PosInterface::TX_TYPE_CANCEL $txType * * @param array $contents * @param string $txType diff --git a/src/Gateways/PayFlexCPV4Pos.php b/src/Gateways/PayFlexCPV4Pos.php index 9915391a..fe9bab34 100644 --- a/src/Gateways/PayFlexCPV4Pos.php +++ b/src/Gateways/PayFlexCPV4Pos.php @@ -39,18 +39,19 @@ class PayFlexCPV4Pos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => false, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => false, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** @return PayFlexAccount */ diff --git a/src/Gateways/PayFlexV4Pos.php b/src/Gateways/PayFlexV4Pos.php index 93d38102..13af344f 100644 --- a/src/Gateways/PayFlexV4Pos.php +++ b/src/Gateways/PayFlexV4Pos.php @@ -41,17 +41,18 @@ class PayFlexV4Pos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** @return PayFlexAccount */ diff --git a/src/Gateways/PayForPos.php b/src/Gateways/PayForPos.php index bc9d2958..4b0a2a05 100644 --- a/src/Gateways/PayForPos.php +++ b/src/Gateways/PayForPos.php @@ -36,19 +36,20 @@ class PayForPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_PAY, PosInterface::MODEL_3D_HOST, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => true, - PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => true, + PosInterface::TX_TYPE_ORDER_HISTORY => true, ]; /** @return PayForAccount */ diff --git a/src/Gateways/PosNet.php b/src/Gateways/PosNet.php index 7a7f2806..bf7317a6 100644 --- a/src/Gateways/PosNet.php +++ b/src/Gateways/PosNet.php @@ -41,17 +41,18 @@ class PosNet extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** diff --git a/src/Gateways/PosNetV1Pos.php b/src/Gateways/PosNetV1Pos.php index 759f24e1..adf17d20 100644 --- a/src/Gateways/PosNetV1Pos.php +++ b/src/Gateways/PosNetV1Pos.php @@ -36,17 +36,18 @@ class PosNetV1Pos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => false, + PosInterface::TX_TYPE_PAY_PRE_AUTH => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => false, ]; /** @return PosNetAccount */ diff --git a/src/Gateways/ToslaPos.php b/src/Gateways/ToslaPos.php index 20770418..7cb51ce1 100644 --- a/src/Gateways/ToslaPos.php +++ b/src/Gateways/ToslaPos.php @@ -49,12 +49,13 @@ class ToslaPos extends AbstractGateway PosInterface::MODEL_3D_HOST, ], - PosInterface::TX_TYPE_HISTORY => false, - PosInterface::TX_TYPE_ORDER_HISTORY => true, - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_STATUS => true, ]; @@ -260,20 +261,21 @@ private function registerPayment(array $order, string $paymentModel, string $txT private function getRequestURIByTransactionType(string $txType, string $paymentModel): string { $arr = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_NON_SECURE => 'Payment', PosInterface::MODEL_3D_PAY => 'threeDPayment', PosInterface::MODEL_3D_HOST => 'threeDPayment', ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => [ + PosInterface::TX_TYPE_PAY_PRE_AUTH => [ PosInterface::MODEL_3D_PAY => 'threeDPreAuth', PosInterface::MODEL_3D_HOST => 'threeDPreAuth', ], - PosInterface::TX_TYPE_PAY_POST_AUTH => 'postAuth', - PosInterface::TX_TYPE_CANCEL => 'void', - PosInterface::TX_TYPE_REFUND => 'refund', - PosInterface::TX_TYPE_STATUS => 'inquiry', - PosInterface::TX_TYPE_ORDER_HISTORY => 'history', + PosInterface::TX_TYPE_PAY_POST_AUTH => 'postAuth', + PosInterface::TX_TYPE_CANCEL => 'void', + PosInterface::TX_TYPE_REFUND => 'refund', + PosInterface::TX_TYPE_REFUND_PARTIAL => 'refund', + PosInterface::TX_TYPE_STATUS => 'inquiry', + PosInterface::TX_TYPE_ORDER_HISTORY => 'history', ]; if (!isset($arr[$txType])) { diff --git a/src/Gateways/VakifKatilimPos.php b/src/Gateways/VakifKatilimPos.php index 16c67595..2ffa8b59 100644 --- a/src/Gateways/VakifKatilimPos.php +++ b/src/Gateways/VakifKatilimPos.php @@ -39,20 +39,21 @@ class VakifKatilimPos extends AbstractGateway /** @inheritdoc */ protected static array $supportedTransactions = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_NON_SECURE, PosInterface::MODEL_3D_SECURE, PosInterface::MODEL_3D_HOST, ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => [ + PosInterface::TX_TYPE_PAY_PRE_AUTH => [ PosInterface::MODEL_NON_SECURE, ], - PosInterface::TX_TYPE_PAY_POST_AUTH => true, - PosInterface::TX_TYPE_STATUS => true, - PosInterface::TX_TYPE_CANCEL => true, - PosInterface::TX_TYPE_REFUND => true, - PosInterface::TX_TYPE_HISTORY => true, - PosInterface::TX_TYPE_ORDER_HISTORY => true, + PosInterface::TX_TYPE_PAY_POST_AUTH => true, + PosInterface::TX_TYPE_STATUS => true, + PosInterface::TX_TYPE_CANCEL => true, + PosInterface::TX_TYPE_REFUND => true, + PosInterface::TX_TYPE_REFUND_PARTIAL => true, + PosInterface::TX_TYPE_HISTORY => true, + PosInterface::TX_TYPE_ORDER_HISTORY => true, ]; /** @return KuveytPosAccount */ @@ -244,29 +245,34 @@ private function getRequestURIByTransactionType(string $txType, string $paymentM $orderTxType ??= PosInterface::TX_TYPE_PAY_AUTH; $arr = [ - PosInterface::TX_TYPE_PAY_AUTH => [ + PosInterface::TX_TYPE_PAY_AUTH => [ PosInterface::MODEL_NON_SECURE => 'Non3DPayGate', PosInterface::MODEL_3D_SECURE => 'ThreeDModelProvisionGate', ], - PosInterface::TX_TYPE_PAY_PRE_AUTH => [ + PosInterface::TX_TYPE_PAY_PRE_AUTH => [ PosInterface::MODEL_NON_SECURE => 'PreAuthorizaten', ], - PosInterface::TX_TYPE_PAY_POST_AUTH => 'PreAuthorizatenClose', - PosInterface::TX_TYPE_CANCEL => [ + PosInterface::TX_TYPE_PAY_POST_AUTH => 'PreAuthorizatenClose', + PosInterface::TX_TYPE_CANCEL => [ PosInterface::MODEL_NON_SECURE => [ PosInterface::TX_TYPE_PAY_AUTH => 'SaleReversal', PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuthorizationReversal', ], ], - PosInterface::TX_TYPE_REFUND => [ + PosInterface::TX_TYPE_REFUND => [ PosInterface::MODEL_NON_SECURE => [ PosInterface::TX_TYPE_PAY_AUTH => 'DrawBack', PosInterface::TX_TYPE_PAY_PRE_AUTH => 'PreAuthorizationDrawBack', ], ], - PosInterface::TX_TYPE_STATUS => 'SelectOrderByMerchantOrderId', - PosInterface::TX_TYPE_ORDER_HISTORY => 'SelectOrder', - PosInterface::TX_TYPE_HISTORY => 'SelectOrder', + PosInterface::TX_TYPE_REFUND_PARTIAL => [ + PosInterface::MODEL_NON_SECURE => [ + PosInterface::TX_TYPE_PAY_AUTH => 'PartialDrawBack', + ], + ], + PosInterface::TX_TYPE_STATUS => 'SelectOrderByMerchantOrderId', + PosInterface::TX_TYPE_ORDER_HISTORY => 'SelectOrder', + PosInterface::TX_TYPE_HISTORY => 'SelectOrder', ]; if (\is_string($arr[$txType])) { diff --git a/src/PosInterface.php b/src/PosInterface.php index 6b149835..0a486a81 100644 --- a/src/PosInterface.php +++ b/src/PosInterface.php @@ -39,6 +39,9 @@ interface PosInterface /** @var string */ public const TX_TYPE_REFUND = 'refund'; + /** @var string */ + public const TX_TYPE_REFUND_PARTIAL = 'refund_partial'; + /** @var string */ public const TX_TYPE_STATUS = 'status'; diff --git a/src/Serializer/KuveytPosSerializer.php b/src/Serializer/KuveytPosSerializer.php index 365e41f3..a1a9f9c1 100644 --- a/src/Serializer/KuveytPosSerializer.php +++ b/src/Serializer/KuveytPosSerializer.php @@ -23,6 +23,7 @@ class KuveytPosSerializer implements SerializerInterface /** @var string[] */ private array $nonPaymentTransactions = [ PosInterface::TX_TYPE_REFUND, + PosInterface::TX_TYPE_REFUND_PARTIAL, PosInterface::TX_TYPE_STATUS, PosInterface::TX_TYPE_CANCEL, ]; diff --git a/src/Serializer/PayFlexCPV4PosSerializer.php b/src/Serializer/PayFlexCPV4PosSerializer.php index 6c61f97c..6822ea75 100644 --- a/src/Serializer/PayFlexCPV4PosSerializer.php +++ b/src/Serializer/PayFlexCPV4PosSerializer.php @@ -48,7 +48,9 @@ public function encode(array $data, string $txType) ); } - if (PosInterface::TX_TYPE_REFUND === $txType || PosInterface::TX_TYPE_CANCEL === $txType) { + if (PosInterface::TX_TYPE_REFUND === $txType + || PosInterface::TX_TYPE_REFUND_PARTIAL === $txType + || PosInterface::TX_TYPE_CANCEL === $txType) { return $this->serializer->encode($data, XmlEncoder::FORMAT); } diff --git a/tests/Functional/EstV3PosTest.php b/tests/Functional/EstV3PosTest.php index f50edc19..da15f1d0 100644 --- a/tests/Functional/EstV3PosTest.php +++ b/tests/Functional/EstV3PosTest.php @@ -230,7 +230,7 @@ public function testRefundSuccess(array $lastResponse): array RequestDataPreparedEvent::class, function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; - $this->assertSame(PosInterface::TX_TYPE_REFUND, $requestDataPreparedEvent->getTxType()); + $this->assertSame(PosInterface::TX_TYPE_REFUND_PARTIAL, $requestDataPreparedEvent->getTxType()); $this->assertCount(7, $requestDataPreparedEvent->getRequestData()); }); diff --git a/tests/Functional/KuveytPosTest.php b/tests/Functional/KuveytPosTest.php index 95274b51..5d4fcf40 100644 --- a/tests/Functional/KuveytPosTest.php +++ b/tests/Functional/KuveytPosTest.php @@ -287,7 +287,7 @@ public function testPartialRefundSuccess(array $lastResponse): array RequestDataPreparedEvent::class, function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; - $this->assertSame(PosInterface::TX_TYPE_REFUND, $requestDataPreparedEvent->getTxType()); + $this->assertSame(PosInterface::TX_TYPE_REFUND_PARTIAL, $requestDataPreparedEvent->getTxType()); $this->assertCount(14, $requestDataPreparedEvent->getRequestData()); }); diff --git a/tests/Functional/ToslaPosTest.php b/tests/Functional/ToslaPosTest.php index 5c9f1bad..cd146842 100644 --- a/tests/Functional/ToslaPosTest.php +++ b/tests/Functional/ToslaPosTest.php @@ -211,7 +211,7 @@ public function testPartialRefundSuccess(): array RequestDataPreparedEvent::class, function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; - $this->assertSame(PosInterface::TX_TYPE_REFUND, $requestDataPreparedEvent->getTxType()); + $this->assertSame(PosInterface::TX_TYPE_REFUND_PARTIAL, $requestDataPreparedEvent->getTxType()); $this->assertCount(7, $requestDataPreparedEvent->getRequestData()); }); diff --git a/tests/Unit/DataMapper/RequestDataMapper/AkbankPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/AkbankPosRequestDataMapperTest.php index 5df8d1d2..565386b8 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/AkbankPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/AkbankPosRequestDataMapperTest.php @@ -368,13 +368,13 @@ public function testCreateCancelRequestData(array $order, array $expectedData): /** * @dataProvider refundRequestDataProvider */ - public function testCreateRefundRequestData(array $order, array $expectedData): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { $this->crypt->expects(self::once()) ->method('generateRandomString') ->willReturn($expectedData['randomNumber']); - $actualData = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actualData = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); $this->assertSame(23, \strlen($actualData['requestDateTime'])); unset($actualData['requestDateTime']); @@ -552,6 +552,7 @@ public static function refundRequestDataProvider(): array 'amount' => 1.02, 'currency' => PosInterface::CURRENCY_TRY, ], + 'txType' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'terminal' => [ 'merchantSafeId' => '2023090417500272654BD9A49CF07574', @@ -576,6 +577,7 @@ public static function refundRequestDataProvider(): array 'currency' => PosInterface::CURRENCY_TRY, 'recurringOrderInstallmentNumber' => 2, ], + 'txType' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'terminal' => [ 'merchantSafeId' => '2023090417500272654BD9A49CF07574', diff --git a/tests/Unit/DataMapper/RequestDataMapper/EstPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/EstPosRequestDataMapperTest.php index 5a3cf5b2..b3694e12 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/EstPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/EstPosRequestDataMapperTest.php @@ -272,20 +272,15 @@ public function testCreateRecurringStatusRequestData(): void } /** - * @return void + * @dataProvider refundRequestDataProvider */ - public function testCreateRefundRequestData(): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $order = [ - 'id' => '2020110828BC', - 'amount' => 50, - 'currency' => PosInterface::CURRENCY_TRY, - ]; + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); - - $expectedData = $this->getSampleRefundXMLData($this->account, $order); - $this->assertEquals($expectedData, $actual); + \ksort($actual); + \ksort($expectedData); + $this->assertSame($expectedData, $actual); } @@ -545,6 +540,46 @@ public static function orderHistoryRequestDataProvider(): array ]; } + public static function refundRequestDataProvider(): array + { + return [ + 'full_refund' => [ + 'order' => [ + 'id' => 'order-123', + 'currency' => PosInterface::CURRENCY_TRY, + 'amount' => 5, + ], + 'txType' => PosInterface::TX_TYPE_REFUND, + 'expected' => [ + 'ClientId' => '700655000200', + 'Currency' => '949', + 'Name' => 'ISBANKAPI', + 'OrderId' => 'order-123', + 'Password' => 'ISBANK07', + 'Total' => '5', + 'Type' => 'Credit', + ], + ], + 'partial_refund' => [ + 'order' => [ + 'id' => 'order-123', + 'currency' => PosInterface::CURRENCY_TRY, + 'amount' => 5, + ], + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'expected' => [ + 'ClientId' => '700655000200', + 'Currency' => '949', + 'Name' => 'ISBANKAPI', + 'OrderId' => 'order-123', + 'Password' => 'ISBANK07', + 'Total' => '5', + 'Type' => 'Credit', + ], + ], + ]; + } + /** * @param AbstractPosAccount $posAccount * @param array $order @@ -645,28 +680,4 @@ private function getSampleRecurringStatusRequestData(AbstractPosAccount $posAcco ], ]; } - - /** - * @param AbstractPosAccount $posAccount - * @param array $order - * - * @return array - */ - private function getSampleRefundXMLData(AbstractPosAccount $posAccount, array $order): array - { - $data = [ - 'Name' => $posAccount->getUsername(), - 'Password' => $posAccount->getPassword(), - 'ClientId' => $posAccount->getClientId(), - 'OrderId' => $order['id'], - 'Currency' => 949, - 'Type' => 'Credit', - ]; - - if ($order['amount']) { - $data['Total'] = $order['amount']; - } - - return $data; - } } diff --git a/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php index 21cae2a2..eace3103 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php @@ -281,11 +281,13 @@ public function testCreateStatusRequestData(): void /** * @dataProvider refundOrderDataProvider */ - public function testCreateRefundRequestData(GarantiPosAccount $garantiPosAccount, array $order, array $expectedData): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $actual = $this->requestDataMapper->createRefundRequestData($garantiPosAccount, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $this->assertEquals($expectedData, $actual); + \ksort($actual); + \ksort($expectedData); + $this->assertSame($expectedData, $actual); } /** @@ -435,7 +437,7 @@ private function getSampleStatusRequestData(AbstractPosAccount $posAccount, arra public static function refundOrderDataProvider(): \Generator { - $order = [ + $order = [ 'id' => '2020110828BC', 'ip' => '127.15.15.1', 'currency' => PosInterface::CURRENCY_TRY, @@ -443,20 +445,41 @@ public static function refundOrderDataProvider(): \Generator 'ref_ret_num' => '831803579226', 'installment' => 0, ]; - $account = AccountFactory::createGarantiPosAccount( - 'garanti', - '7000679', - 'PROVAUT', - '123qweASD/', - '30691298', - PosInterface::MODEL_3D_SECURE, - '12345678', - 'PROVRFN', - '123qweASD/' - ); + + yield [ + 'order' => $order, + 'tx_type' => PosInterface::TX_TYPE_REFUND, + 'expectedData' => [ + 'Mode' => 'TEST', + 'Version' => '512', + 'Terminal' => [ + 'ProvUserID' => 'PROVRFN', + 'UserID' => 'PROVRFN', + 'HashData' => 'CF49751B3B793B9E1946A08815451989D0231D68A5B495C6EABA9C400442F2E6B7DF97446CE2D3562780767E634A6ECBAA1DF69F6DF7F447884A71BDE38D12AA', + 'ID' => '30691298', + 'MerchantID' => '7000679', + ], + 'Customer' => [ + 'IPAddress' => '127.15.15.1', + ], + 'Order' => [ + 'OrderID' => '2020110828BC', + ], + 'Transaction' => [ + 'Type' => 'refund', + 'InstallmentCnt' => '', + 'Amount' => 12310, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + 'OriginalRetrefNum' => '831803579226', + ], + ], + ]; + yield [ - 'account' => $account, 'order' => $order, + 'tx_type' => PosInterface::TX_TYPE_REFUND_PARTIAL, 'expectedData' => [ 'Mode' => 'TEST', 'Version' => '512', @@ -476,7 +499,7 @@ public static function refundOrderDataProvider(): \Generator 'Transaction' => [ 'Type' => 'refund', 'InstallmentCnt' => '', - 'Amount' => '12310', + 'Amount' => 12310, 'CurrencyCode' => '949', 'CardholderPresentCode' => '0', 'MotoInd' => 'N', @@ -491,8 +514,8 @@ public static function orderHistoryRequestDataProvider(): array return [ [ 'order' => [ - 'id' => 'order222', - 'ip' => '156.155.154.153', + 'id' => 'order222', + 'ip' => '156.155.154.153', 'installment' => 0, ], 'expected' => [ diff --git a/tests/Unit/DataMapper/RequestDataMapper/InterPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/InterPosRequestDataMapperTest.php index 03b77856..e26d72a2 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/InterPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/InterPosRequestDataMapperTest.php @@ -254,19 +254,15 @@ public function testCreateStatusRequestData(): void } /** - * @return void + * @dataProvider refundOrderDataProvider */ - public function testCreateRefundRequestData(): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $order = [ - 'id' => '2020110828BC', - 'amount' => 50, - ]; - - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $expectedData = $this->getSampleRefundXMLData($order, $this->account); - $this->assertEquals($expectedData, $actual); + \ksort($actual); + \ksort($expectedData); + $this->assertSame($expectedData, $actual); } /** @@ -390,28 +386,6 @@ private function getSampleStatusRequestData(array $order, InterPosAccount $inter ]; } - /** - * @param array $order - * @param InterPosAccount $interPosAccount - * - * @return array - */ - private function getSampleRefundXMLData(array $order, InterPosAccount $interPosAccount): array - { - return [ - 'UserCode' => $interPosAccount->getUsername(), - 'UserPass' => $interPosAccount->getPassword(), - 'ShopCode' => $interPosAccount->getClientId(), - 'OrderId' => null, - 'orgOrderId' => $order['id'], - 'PurchAmount' => $order['amount'], - 'TxnType' => 'Refund', - 'SecureType' => 'NonSecure', - 'Lang' => $interPosAccount->getLang(), - 'MOTO' => '0', - ]; - } - public static function threeDFormDataProvider(): array { $order = [ @@ -507,4 +481,46 @@ public static function threeDFormDataProvider(): array ], ]; } + + public static function refundOrderDataProvider(): \Generator + { + $order = [ + 'id' => '2020110828BC', + 'amount' => 123.1, + ]; + + yield [ + 'order' => $order, + 'tx_type' => PosInterface::TX_TYPE_REFUND, + 'expectedData' => [ + 'Lang' => 'tr', + 'MOTO' => '0', + 'OrderId' => null, + 'PurchAmount' => '123.1', + 'SecureType' => 'NonSecure', + 'ShopCode' => '3123', + 'TxnType' => 'Refund', + 'UserCode' => 'InterTestApi', + 'UserPass' => '3', + 'orgOrderId' => '2020110828BC', + ], + ]; + + yield [ + 'order' => $order, + 'tx_type' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'expectedData' => [ + 'Lang' => 'tr', + 'MOTO' => '0', + 'OrderId' => null, + 'PurchAmount' => '123.1', + 'SecureType' => 'NonSecure', + 'ShopCode' => '3123', + 'TxnType' => 'Refund', + 'UserCode' => 'InterTestApi', + 'UserPass' => '3', + 'orgOrderId' => '2020110828BC', + ], + ]; + } } diff --git a/tests/Unit/DataMapper/RequestDataMapper/KuveytPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/KuveytPosRequestDataMapperTest.php index bfe66992..d5e7da15 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/KuveytPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/KuveytPosRequestDataMapperTest.php @@ -184,13 +184,13 @@ public function testCreateCancelRequestData(array $order, array $expected): void /** * @dataProvider createRefundRequestDataProvider */ - public function testCreateRefundRequestData(array $order, array $expected): void + public function testCreateRefundRequestData(array $order, string $txType, array $expected): void { $this->crypt->expects(self::once()) ->method('createHash') ->willReturn('request-hash'); - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); foreach ($actual as &$item) { if (is_array($item)) { @@ -384,7 +384,7 @@ public static function createCancelRequestDataProvider(): iterable public static function createRefundRequestDataProvider(): Generator { yield [ - 'full_order' => [ + 'full_refund' => [ 'id' => '2023070849CD', 'remote_order_id' => '114293600', 'ref_ret_num' => '318923298433', @@ -393,7 +393,8 @@ public static function createRefundRequestDataProvider(): Generator 'amount' => 1.01, 'currency' => PosInterface::CURRENCY_TRY, ], - 'expected' => [ + 'tx_type' => PosInterface::TX_TYPE_REFUND, + 'expected' => [ 'IsFromExternalNetwork' => true, 'BusinessKey' => 0, 'ResourceId' => 0, @@ -445,6 +446,7 @@ public static function createRefundRequestDataProvider(): Generator 'order_amount' => 10.01, 'currency' => PosInterface::CURRENCY_TRY, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND_PARTIAL, 'expected' => [ 'IsFromExternalNetwork' => true, 'BusinessKey' => 0, diff --git a/tests/Unit/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapperTest.php index d42623f8..a24f0afa 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/PayFlexV4PosRequestDataMapperTest.php @@ -213,16 +213,16 @@ public function testCreateCancelRequestData(): void $this->assertEquals($expectedValue, $actualData); } - public function testCreateRefundRequestData(): void + /** + * @dataProvider refundRequestDataProvider + */ + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $order = $this->order; - $order['transaction_id'] = '7022b92e-3aa1-44fb-86d4-33658c700c80'; - $order['amount'] = 1000; + $actualData = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $expectedValue = $this->getSampleRefundRequestData(); - $actualData = $this->requestDataMapper->createRefundRequestData($this->account, $order); - - $this->assertEquals($expectedValue, $actualData); + \ksort($actualData); + \ksort($expectedData); + $this->assertSame($expectedData, $actualData); } /** @@ -235,7 +235,7 @@ public function testCreate3DFormData(): void $this->dispatcher->expects(self::never()) ->method('dispatch'); - $actualData = $this->requestDataMapper->create3DFormData( + $actualData = $this->requestDataMapper->create3DFormData( null, null, null, @@ -451,6 +451,44 @@ public static function three3DEnrollmentRequestDataDataProvider(): \Generator ]; } + public static function refundRequestDataProvider(): array + { + return [ + 'full_refund' => [ + 'order' => [ + 'transaction_id' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'amount' => 5, + 'ip' => '127.0.0.1', + ], + 'txType' => PosInterface::TX_TYPE_REFUND, + 'expected' => [ + 'ClientIp' => '127.0.0.1', + 'CurrencyAmount' => '5.00', + 'MerchantId' => '000000000111111', + 'Password' => '3XTgER89as', + 'ReferenceTransactionId' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'TransactionType' => 'Refund', + ], + ], + 'partial_refund' => [ + 'order' => [ + 'transaction_id' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'amount' => 5, + 'ip' => '127.0.0.1', + ], + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'expected' => [ + 'ClientIp' => '127.0.0.1', + 'CurrencyAmount' => '5.00', + 'MerchantId' => '000000000111111', + 'Password' => '3XTgER89as', + 'ReferenceTransactionId' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'TransactionType' => 'Refund', + ], + ], + ]; + } + /** * @param PayFlexAccount $posAccount * @param array $order @@ -497,18 +535,6 @@ private function getSampleNonSecurePaymentPostRequestData(AbstractPosAccount $po ]; } - private function getSampleRefundRequestData(): array - { - return [ - 'MerchantId' => '000000000111111', - 'Password' => '3XTgER89as', - 'TransactionType' => 'Refund', - 'ReferenceTransactionId' => '7022b92e-3aa1-44fb-86d4-33658c700c80', - 'ClientIp' => '127.0.0.1', - 'CurrencyAmount' => '1000.00', - ]; - } - /** * @return array */ diff --git a/tests/Unit/DataMapper/RequestDataMapper/PayForPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/PayForPosRequestDataMapperTest.php index e33f8398..c7c32c05 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/PayForPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/PayForPosRequestDataMapperTest.php @@ -264,20 +264,15 @@ public function testCreateStatusRequestData(): void } /** - * @return void + * @dataProvider refundRequestDataProvider */ - public function testCreateRefundRequestData(): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $order = [ - 'id' => '2020110828BC', - 'currency' => PosInterface::CURRENCY_TRY, - 'amount' => 10.1, - ]; - - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $expectedData = $this->getSampleRefundXMLData($this->account, $order); - $this->assertEquals($expectedData, $actual); + \ksort($expectedData); + \ksort($actual); + $this->assertSame($expectedData, $actual); } /** @@ -390,34 +385,12 @@ private function getSampleStatusRequestData(AbstractPosAccount $posAccount, arra ]; } - /** - * @param AbstractPosAccount $posAccount - * @param array $order - * - * @return array - */ - private function getSampleRefundXMLData(AbstractPosAccount $posAccount, array $order): array - { - return [ - 'MbrId' => '5', - 'MerchantId' => $posAccount->getClientId(), - 'UserCode' => $posAccount->getUsername(), - 'UserPass' => $posAccount->getPassword(), - 'OrgOrderId' => $order['id'], - 'SecureType' => 'NonSecure', - 'Lang' => 'tr', - 'TxnType' => 'Refund', - 'PurchAmount' => $order['amount'], - 'Currency' => 949, - ]; - } - public static function orderHistoryRequestDataProvider(): array { return [ [ 'order' => [ - 'id' => '2020110828BC', + 'id' => '2020110828BC', ], 'expected' => [ 'MerchantId' => '085300000009704', @@ -437,7 +410,7 @@ public static function historyRequestDataProvider(): array { return [ [ - 'data' => [ + 'data' => [ 'transaction_date' => new \DateTime('2022-05-18'), ], 'expected' => [ @@ -554,4 +527,50 @@ public static function threeDFormDataProvider(): array ], ]; } + + public static function refundRequestDataProvider(): array + { + return [ + 'full_refund' => [ + 'order' => [ + 'id' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'currency' => PosInterface::CURRENCY_TRY, + 'amount' => 5, + ], + 'txType' => PosInterface::TX_TYPE_REFUND, + 'expected' => [ + 'Currency' => '949', + 'Lang' => 'tr', + 'MbrId' => '5', + 'MerchantId' => '085300000009704', + 'OrgOrderId' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'PurchAmount' => '5', + 'SecureType' => 'NonSecure', + 'TxnType' => 'Refund', + 'UserCode' => 'QNB_API_KULLANICI_3DPAY', + 'UserPass' => 'UcBN0', + ], + ], + 'partial_refund' => [ + 'order' => [ + 'id' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'currency' => PosInterface::CURRENCY_TRY, + 'amount' => 5, + ], + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'expected' => [ + 'Currency' => '949', + 'Lang' => 'tr', + 'MbrId' => '5', + 'MerchantId' => '085300000009704', + 'OrgOrderId' => '7022b92e-3aa1-44fb-86d4-33658c700c80', + 'PurchAmount' => '5', + 'SecureType' => 'NonSecure', + 'TxnType' => 'Refund', + 'UserCode' => 'QNB_API_KULLANICI_3DPAY', + 'UserPass' => 'UcBN0', + ], + ], + ]; + } } diff --git a/tests/Unit/DataMapper/RequestDataMapper/PosNetRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/PosNetRequestDataMapperTest.php index abb2457e..6c23fa7d 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/PosNetRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/PosNetRequestDataMapperTest.php @@ -259,13 +259,15 @@ public function testCreateStatusRequestData(array $order, array $expectedData): } /** - * @dataProvider refundDataProvider + * @dataProvider refundRequestDataProvider */ - public function testCreateRefundRequestData(array $order, array $expectedData): void + public function testCreateRefundRequestData(array $order, string $txType, array $expectedData): void { - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $this->assertEquals($expectedData, $actual); + \ksort($actual); + \ksort($expectedData); + $this->assertSame($expectedData, $actual); } public static function threeDFormDataDataProvider(): array @@ -450,7 +452,7 @@ public static function statusRequestDataProvider(): array ]; } - public static function refundDataProvider(): array + public static function refundRequestDataProvider(): array { return [ 'with_order_id' => [ @@ -460,6 +462,7 @@ public static function refundDataProvider(): array 'amount' => 50, 'currency' => PosInterface::CURRENCY_TRY, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'mid' => '6706598320', 'tid' => '67005551', @@ -478,6 +481,7 @@ public static function refundDataProvider(): array 'amount' => 50, 'currency' => PosInterface::CURRENCY_TRY, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'mid' => '6706598320', 'tid' => '67005551', diff --git a/tests/Unit/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapperTest.php index e1031aaa..c88de79c 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/PosNetV1PosRequestDataMapperTest.php @@ -163,7 +163,7 @@ public function testCreateNonSecurePostAuthPaymentRequestData(array $order, arra */ public function testCreateNonSecurePaymentRequestData(array $order, array $expectedData): void { - $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account,$order, PosInterface::TX_TYPE_PAY_AUTH, $this->card); + $actual = $this->requestDataMapper->createNonSecurePaymentRequestData($this->account, $order, PosInterface::TX_TYPE_PAY_AUTH, $this->card); $this->assertEquals($expectedData, $actual); } @@ -216,10 +216,13 @@ public function testCreateStatusRequestData(array $order, array $expected): void /** * @dataProvider createRefundRequestDataDataProvider */ - public function testCreateRefundRequestData(array $order, array $expected): void + public function testCreateRefundRequestData(array $order, string $txType, array $expected): void { - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); - $this->assertEquals($expected, $actual); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); + + ksort($actual); + ksort($expected); + $this->assertSame($expected, $actual); } @@ -281,7 +284,7 @@ public static function threeDFormDataTestProvider(): iterable public static function nonSecurePaymentRequestDataDataProvider(): iterable { yield [ - 'order' => [ + 'order' => [ 'id' => '123', 'amount' => 10.0, 'installment' => 0, @@ -449,6 +452,7 @@ public static function createRefundRequestDataDataProvider(): iterable 'payment_model' => PosInterface::MODEL_3D_SECURE, 'transaction_type' => PosInterface::TX_TYPE_PAY_AUTH, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'ApiType' => 'JSON', 'ApiVersion' => 'V100', @@ -473,6 +477,7 @@ public static function createRefundRequestDataDataProvider(): iterable 'payment_model' => PosInterface::MODEL_3D_SECURE, 'transaction_type' => PosInterface::TX_TYPE_PAY_AUTH, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'ApiType' => 'JSON', 'ApiVersion' => 'V100', @@ -497,6 +502,7 @@ public static function createRefundRequestDataDataProvider(): iterable 'payment_model' => PosInterface::MODEL_3D_SECURE, 'transaction_type' => PosInterface::TX_TYPE_PAY_AUTH, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'ApiType' => 'JSON', 'ApiVersion' => 'V100', @@ -521,6 +527,7 @@ public static function createRefundRequestDataDataProvider(): iterable 'amount' => 112, 'transaction_type' => PosInterface::TX_TYPE_PAY_PRE_AUTH, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'ApiType' => 'JSON', 'ApiVersion' => 'V100', diff --git a/tests/Unit/DataMapper/RequestDataMapper/ToslaPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/ToslaPosRequestDataMapperTest.php index ae1b2beb..bf04cad4 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/ToslaPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/ToslaPosRequestDataMapperTest.php @@ -234,7 +234,7 @@ public function testCreateStatusRequestData(array $order, array $expected): void /** * @dataProvider refundRequestDataProvider */ - public function testCreateRefundRequestData(array $order, array $expected): void + public function testCreateRefundRequestData(array $order, string $txType, array $expected): void { $this->crypt->expects(self::once()) ->method('generateRandomString') @@ -243,9 +243,11 @@ public function testCreateRefundRequestData(array $order, array $expected): void ->method('createHash') ->willReturn($expected['hash']); - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); - $this->assertEquals($expected, $actual); + ksort($actual); + ksort($expected); + $this->assertSame($expected, $actual); } public static function statusRequestDataProvider(): array @@ -297,6 +299,7 @@ public static function refundRequestDataProvider(): array 'amount' => 1.02, 'time_span' => '20231209215355', ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'clientId' => '1000000494', 'apiUser' => 'POS_ENT_Test_001', diff --git a/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php index b1a63bdd..2a307581 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php @@ -204,10 +204,13 @@ public function testCreateCancelRequestData(array $order, array $expected): void /** * @dataProvider createRefundRequestDataProvider */ - public function testCreateRefundRequestData(array $order, array $expected): void + public function testCreateRefundRequestData(array $order, string $txType, array $expected): void { - $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order); - $this->assertEquals($expected, $actual); + $actual = $this->requestDataMapper->createRefundRequestData($this->account, $order, $txType); + + \ksort($actual); + \ksort($expected); + $this->assertSame($expected, $actual); } /** @@ -321,6 +324,7 @@ public static function createRefundRequestDataProvider(): Generator 'remote_order_id' => '114293600', 'amount' => 1.01, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, 'expected' => [ 'MerchantId' => '1', 'CustomerId' => '11111', diff --git a/tests/Unit/Gateways/AkbankPosTest.php b/tests/Unit/Gateways/AkbankPosTest.php index c454e32c..179c2b39 100644 --- a/tests/Unit/Gateways/AkbankPosTest.php +++ b/tests/Unit/Gateways/AkbankPosTest.php @@ -600,15 +600,14 @@ public function testCancelRequest(array $order, string $apiUrl): void /** * @dataProvider refundRequestDataProvider */ - public function testRefundRequest(array $order, string $apiUrl): void + public function testRefundRequest(array $order, string $txType, string $apiUrl): void { $account = $this->pos->getAccount(); - $txType = PosInterface::TX_TYPE_REFUND; $requestData = ['createRefundRequestData']; $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $this->configureClientResponse( @@ -648,6 +647,11 @@ public static function getApiUrlDataProvider(): array 'paymentModel' => PosInterface::MODEL_NON_SECURE, 'expected' => 'https://apipre.akbank.com/api/v1/payment/virtualpos/transaction/process', ], + [ + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'paymentModel' => PosInterface::MODEL_NON_SECURE, + 'expected' => 'https://apipre.akbank.com/api/v1/payment/virtualpos/transaction/process', + ], [ 'txType' => PosInterface::TX_TYPE_HISTORY, 'paymentModel' => PosInterface::MODEL_NON_SECURE, @@ -702,10 +706,21 @@ public static function cancelRequestDataProvider(): array public static function refundRequestDataProvider(): array { return [ - [ + 'full_refund' => [ 'order' => [ - 'id' => '2020110828BC', + 'id' => '2020110828BC', + 'amount' => 5, + ], + 'tx_type' => PosInterface::TX_TYPE_REFUND, + 'api_url' => 'https://apipre.akbank.com/api/v1/payment/virtualpos/transaction/process', + ], + 'partial_refund' => [ + 'order' => [ + 'id' => '2020110828BC', + 'amount' => 5, + 'order_amount' => 10, ], + 'tx_type' => PosInterface::TX_TYPE_REFUND_PARTIAL, 'api_url' => 'https://apipre.akbank.com/api/v1/payment/virtualpos/transaction/process', ], ]; diff --git a/tests/Unit/Gateways/EstPosTest.php b/tests/Unit/Gateways/EstPosTest.php index 3a70de9a..d032f8dc 100644 --- a/tests/Unit/Gateways/EstPosTest.php +++ b/tests/Unit/Gateways/EstPosTest.php @@ -365,7 +365,7 @@ public function testRefund(array $bankResponse, array $expectedData, bool $isSuc $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $this->configureClientResponse( diff --git a/tests/Unit/Gateways/GarantiPosTest.php b/tests/Unit/Gateways/GarantiPosTest.php index c29803fa..159bb71d 100644 --- a/tests/Unit/Gateways/GarantiPosTest.php +++ b/tests/Unit/Gateways/GarantiPosTest.php @@ -426,7 +426,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/InterPosTest.php b/tests/Unit/Gateways/InterPosTest.php index e8d17011..4cac171b 100644 --- a/tests/Unit/Gateways/InterPosTest.php +++ b/tests/Unit/Gateways/InterPosTest.php @@ -454,7 +454,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/KuveytPosTest.php b/tests/Unit/Gateways/KuveytPosTest.php index 103aff46..0d433790 100644 --- a/tests/Unit/Gateways/KuveytPosTest.php +++ b/tests/Unit/Gateways/KuveytPosTest.php @@ -487,6 +487,11 @@ public static function getApiUrlDataProvider(): array 'paymentModel' => PosInterface::MODEL_NON_SECURE, 'expected' => 'https://boatest.kuveytturk.com.tr/BOA.Integration.WCFService/BOA.Integration.VirtualPos/VirtualPosService.svc?wsdl', ], + [ + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'paymentModel' => PosInterface::MODEL_NON_SECURE, + 'expected' => 'https://boatest.kuveytturk.com.tr/BOA.Integration.WCFService/BOA.Integration.VirtualPos/VirtualPosService.svc?wsdl', + ], [ 'txType' => PosInterface::TX_TYPE_CANCEL, 'paymentModel' => PosInterface::MODEL_NON_SECURE, diff --git a/tests/Unit/Gateways/PayFlexCPV4PosTest.php b/tests/Unit/Gateways/PayFlexCPV4PosTest.php index b98b7e3b..f4939630 100644 --- a/tests/Unit/Gateways/PayFlexCPV4PosTest.php +++ b/tests/Unit/Gateways/PayFlexCPV4PosTest.php @@ -444,7 +444,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/PayFlexV4PosTest.php b/tests/Unit/Gateways/PayFlexV4PosTest.php index cb0cef3f..232ef759 100644 --- a/tests/Unit/Gateways/PayFlexV4PosTest.php +++ b/tests/Unit/Gateways/PayFlexV4PosTest.php @@ -461,7 +461,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/PayForTest.php b/tests/Unit/Gateways/PayForTest.php index 50ec1c45..04f71d13 100644 --- a/tests/Unit/Gateways/PayForTest.php +++ b/tests/Unit/Gateways/PayForTest.php @@ -459,7 +459,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/PosNetTest.php b/tests/Unit/Gateways/PosNetTest.php index ea16862e..8989393b 100644 --- a/tests/Unit/Gateways/PosNetTest.php +++ b/tests/Unit/Gateways/PosNetTest.php @@ -502,7 +502,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/PosNetV1PosTest.php b/tests/Unit/Gateways/PosNetV1PosTest.php index 53bab61a..f656c860 100644 --- a/tests/Unit/Gateways/PosNetV1PosTest.php +++ b/tests/Unit/Gateways/PosNetV1PosTest.php @@ -440,7 +440,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; diff --git a/tests/Unit/Gateways/ToslaPosTest.php b/tests/Unit/Gateways/ToslaPosTest.php index 9bd8a0ec..90cf1a80 100644 --- a/tests/Unit/Gateways/ToslaPosTest.php +++ b/tests/Unit/Gateways/ToslaPosTest.php @@ -383,6 +383,7 @@ public function testCancel( */ public function testRefund( array $order, + string $txType, array $requestData, string $encodedRequest, string $responseContent, @@ -393,7 +394,7 @@ public function testRefund( { $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($this->pos->getAccount(), $order) + ->with($this->pos->getAccount(), $order, $txType) ->willReturn($requestData); $this->responseMapperMock->expects(self::once()) @@ -499,6 +500,7 @@ public static function refundDataProvider(): iterable { yield [ 'order' => ToslaPosRequestDataMapperTest::refundRequestDataProvider()[0]['order'], + 'txType' => PosInterface::TX_TYPE_REFUND, 'requestData' => ToslaPosRequestDataMapperTest::refundRequestDataProvider()[0]['expected'], 'encodedRequestData' => \json_encode(ToslaPosRequestDataMapperTest::refundRequestDataProvider()[0]['expected'], JSON_THROW_ON_ERROR), 'responseData' => \json_encode(ToslaPosResponseDataMapperTest::refundDataProvider()['success1']['responseData'], JSON_THROW_ON_ERROR), @@ -721,7 +723,7 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; @@ -793,6 +795,11 @@ public static function getApiUrlDataProvider(): array 'paymentModel' => PosInterface::MODEL_NON_SECURE, 'expected' => 'https://ent.akodepos.com/api/Payment/refund', ], + [ + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'paymentModel' => PosInterface::MODEL_NON_SECURE, + 'expected' => 'https://ent.akodepos.com/api/Payment/refund', + ], [ 'txType' => PosInterface::TX_TYPE_ORDER_HISTORY, 'paymentModel' => PosInterface::MODEL_NON_SECURE, diff --git a/tests/Unit/Gateways/VakifKatilimTest.php b/tests/Unit/Gateways/VakifKatilimTest.php index 46c0120b..979d0b4f 100644 --- a/tests/Unit/Gateways/VakifKatilimTest.php +++ b/tests/Unit/Gateways/VakifKatilimTest.php @@ -489,15 +489,14 @@ public function testCancelRequest(array $order, string $apiUrl): void /** * @dataProvider refundRequestDataProvider */ - public function testRefundRequest(array $order, string $apiUrl): void + public function testRefundRequest(array $order, string $txType, string $apiUrl): void { $account = $this->pos->getAccount(); - $txType = PosInterface::TX_TYPE_REFUND; $requestData = ['createRefundRequestData']; $this->requestMapperMock->expects(self::once()) ->method('createRefundRequestData') - ->with($account, $order) + ->with($account, $order, $txType) ->willReturn($requestData); $decodedResponse = ['decodedData']; @@ -659,6 +658,12 @@ public static function getApiUrlDataProvider(): array 'paymentModel' => PosInterface::MODEL_NON_SECURE, 'expected' => 'https://boa.vakifkatilim.com.tr/VirtualPOS.Gateway/Home/DrawBack', ], + [ + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'orderTxType' => PosInterface::TX_TYPE_PAY_AUTH, + 'paymentModel' => PosInterface::MODEL_NON_SECURE, + 'expected' => 'https://boa.vakifkatilim.com.tr/VirtualPOS.Gateway/Home/PartialDrawBack', + ], [ 'txType' => PosInterface::TX_TYPE_CANCEL, 'orderTxType' => PosInterface::TX_TYPE_PAY_PRE_AUTH, @@ -752,20 +757,32 @@ public static function cancelRequestDataProvider(): array public static function refundRequestDataProvider(): array { return [ - 'pay_order' => [ + 'pay_order' => [ 'order' => [ 'id' => '2020110828BC', 'transaction_type' => PosInterface::TX_TYPE_PAY_AUTH, ], + 'txType' => PosInterface::TX_TYPE_REFUND, 'api_url' => 'https://boa.vakifkatilim.com.tr/VirtualPOS.Gateway/Home/DrawBack', ], - 'pay_auth_order' => [ + 'pay_auth_order' => [ 'order' => [ 'id' => '2020110828BC', 'transaction_type' => PosInterface::TX_TYPE_PAY_PRE_AUTH, ], + 'txType' => PosInterface::TX_TYPE_REFUND, 'api_url' => 'https://boa.vakifkatilim.com.tr/VirtualPOS.Gateway/Home/PreAuthorizationDrawBack', ], + 'pay_order_partial_refund' => [ + 'order' => [ + 'id' => '2020110828BC', + 'order_amount' => 10, + 'amount' => 5, + 'transaction_type' => PosInterface::TX_TYPE_PAY_AUTH, + ], + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'api_url' => 'https://boa.vakifkatilim.com.tr/VirtualPOS.Gateway/Home/PartialDrawBack', + ], ]; } diff --git a/tests/Unit/Serializer/KuveytPosSerializerTest.php b/tests/Unit/Serializer/KuveytPosSerializerTest.php index 28e2288c..f429b5eb 100644 --- a/tests/Unit/Serializer/KuveytPosSerializerTest.php +++ b/tests/Unit/Serializer/KuveytPosSerializerTest.php @@ -105,6 +105,12 @@ public static function encodeDataProvider(): Generator 'expected' => $refundTests[0]['expected'], ]; + yield 'test_partial_refund' => [ + 'input' => $refundTests[0]['expected'], + 'txType' => PosInterface::TX_TYPE_REFUND_PARTIAL, + 'expected' => $refundTests[0]['expected'], + ]; + yield 'test_cancel' => [ 'input' => ['abc' => 1], 'txType' => PosInterface::TX_TYPE_CANCEL, From eaf0d5e05ac44aa2445067b9d690943466b084a0 Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Wed, 29 May 2024 17:54:23 +0200 Subject: [PATCH 3/5] VakifKatilimPosRequestDataMapper remove unnecessary $txTypeMappings --- .../VakifKatilimPosRequestDataMapper.php | 7 ------- .../VakifKatilimPosRequestDataMapperTest.php | 19 ------------------- 2 files changed, 26 deletions(-) diff --git a/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php index d5c5f567..466b193c 100644 --- a/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapper.php @@ -34,13 +34,6 @@ class VakifKatilimPosRequestDataMapper extends AbstractRequestDataMapper PosInterface::MODEL_NON_SECURE => '5', ]; - /** - * {@inheritDoc} - */ - protected array $txTypeMappings = [ - PosInterface::TX_TYPE_PAY_AUTH => '1', - ]; - /** * Currency mapping * diff --git a/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php index 2a307581..12838e71 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/VakifKatilimPosRequestDataMapperTest.php @@ -9,7 +9,6 @@ use Mews\Pos\DataMapper\RequestDataMapper\VakifKatilimPosRequestDataMapper; use Mews\Pos\Entity\Account\KuveytPosAccount; use Mews\Pos\Entity\Card\CreditCardInterface; -use Mews\Pos\Exceptions\UnsupportedTransactionTypeException; use Mews\Pos\Factory\AccountFactory; use Mews\Pos\Factory\CreditCardFactory; use Mews\Pos\Factory\CryptFactory; @@ -60,24 +59,6 @@ protected function setUp(): void $this->requestDataMapper = new VakifKatilimPosRequestDataMapper($this->dispatcher, $crypt); } - /** - * @testWith ["pay", "1"] - */ - public function testMapTxType(string $txType, string $expected): void - { - $actual = $this->requestDataMapper->mapTxType($txType); - $this->assertSame($expected, $actual); - } - - /** - * @testWith ["Sale"] - */ - public function testMapTxTypeException(string $txType): void - { - $this->expectException(UnsupportedTransactionTypeException::class); - $this->requestDataMapper->mapTxType($txType); - } - /** * @return void */ From 6f330de00a9be829f7c16c1337ce580a47a9723d Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Thu, 30 May 2024 11:28:53 +0200 Subject: [PATCH 4/5] GarantiPosRequestDataMapper fix txtype for order history --- .../GarantiPosRequestDataMapper.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php index 4d930394..b3dd223d 100644 --- a/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/GarantiPosRequestDataMapper.php @@ -52,7 +52,7 @@ class GarantiPosRequestDataMapper extends AbstractRequestDataMapper PosInterface::TX_TYPE_PAY_POST_AUTH => 'postauth', PosInterface::TX_TYPE_CANCEL => 'void', PosInterface::TX_TYPE_REFUND => 'refund', - PosInterface::TX_TYPE_HISTORY => 'orderhistoryinq', + PosInterface::TX_TYPE_ORDER_HISTORY => 'orderhistoryinq', PosInterface::TX_TYPE_STATUS => 'orderinq', ]; @@ -79,10 +79,10 @@ public function create3DPaymentRequestData(AbstractPosAccount $posAccount, array 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount), 'Customer' => [ - 'IPAddress' => $responseData['customeripaddress'], + 'IPAddress' => $responseData['customeripaddress'], ], 'Order' => [ - 'OrderID' => $responseData['orderid'], + 'OrderID' => $responseData['orderid'], ], 'Transaction' => [ 'Type' => $responseData['txntype'], @@ -123,11 +123,11 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $posAccount 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Card' => $this->getCardData($creditCard), 'Order' => [ - 'OrderID' => $order['id'], + 'OrderID' => $order['id'], ], 'Transaction' => [ 'Type' => $this->mapTxType($txType), @@ -162,7 +162,7 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $po 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Order' => [ 'OrderID' => $order['id'], @@ -194,7 +194,7 @@ public function createStatusRequestData(AbstractPosAccount $posAccount, array $o 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Order' => [ 'OrderID' => $order['id'], @@ -228,7 +228,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount, true), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Order' => [ 'OrderID' => $order['id'], @@ -263,7 +263,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount, true), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Order' => [ 'OrderID' => $order['id'], @@ -298,13 +298,13 @@ public function createOrderHistoryRequestData(AbstractPosAccount $posAccount, ar 'Version' => self::API_VERSION, 'Terminal' => $this->getTerminalData($posAccount), 'Customer' => [ - 'IPAddress' => $order['ip'], + 'IPAddress' => $order['ip'], ], 'Order' => [ 'OrderID' => $order['id'], ], 'Transaction' => [ - 'Type' => $this->mapTxType(PosInterface::TX_TYPE_HISTORY), + 'Type' => $this->mapTxType(PosInterface::TX_TYPE_ORDER_HISTORY), 'InstallmentCnt' => $this->mapInstallment($order['installment']), 'Amount' => $this->formatAmount($order['amount']), //sabit olarak amount 100 gonderilecek 'CurrencyCode' => $this->mapCurrency($order['currency']), From e202b3e442291d0158e1b11eb9762f84d7257e84 Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Mon, 3 Jun 2024 15:34:43 +0200 Subject: [PATCH 5/5] GarantiPos - implement history request --- README.md | 2 +- docs/HISTORY-EXAMPLE.md | 12 +- examples/_common-codes/regular/history.php | 13 +- examples/garanti/regular/history.php | 3 + .../GarantiPosRequestDataMapper.php | 68 ++++- .../GarantiPosResponseDataMapper.php | 177 ++++++++++++- src/Gateways/GarantiPos.php | 11 +- tests/Functional/AkbankPosTest.php | 4 +- tests/Functional/GarantiPosTest.php | 24 ++ tests/Functional/PayForPosTest.php | 2 +- tests/Functional/PaymentTestTrait.php | 19 +- .../GarantiPosRequestDataMapperTest.php | 62 ++++- .../GarantiPosResponseDataMapperTest.php | 244 ++++++++++++++++++ tests/Unit/Gateways/GarantiPosTest.php | 49 +++- .../history/daily_range_history_expected.json | 155 +++++++++++ .../garanti/history/date_range_history.json | 225 ++++++++++++++++ 16 files changed, 1035 insertions(+), 35 deletions(-) create mode 100644 examples/garanti/regular/history.php create mode 100644 tests/Unit/test_data/garanti/history/daily_range_history_expected.json create mode 100644 tests/Unit/test_data/garanti/history/date_range_history.json diff --git a/README.md b/README.md index 23ad3e18..cd6e8592 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ sistemlerinin kullanılabilmesidir. | EST V3 POS

EstPos altyapının
daha güvenli
(sha512) hash
algoritmasıyla
uygulaması.
| -----"----- | -----"----- | -----"----- | | PayFlex MPI VPOS V4 | Ziraat
Vakıfbank VPOS 7/24
İşbank | NonSecure
3DSecure
Tekrarlanan Ödeme | İptal
İade
Durum sorgulama | | PayFlex
Common Payment V4
(Ortak Ödeme) | Ziraat
Vakıfbank
İşbank | NonSecure
3DPay
3DHost | İptal
İade | -| Garanti Virtual POS | Garanti | NonSecure
3DSecure
3DPay
3DHost
Tekrarlanan Ödeme | İptal
İade
Durum sorgulama
Sipariş Tarihçesini sorgulama | +| Garanti Virtual POS | Garanti | NonSecure
3DSecure
3DPay
3DHost
Tekrarlanan Ödeme | İptal
İade
Durum sorgulama
Sipariş Tarihçesini sorgulama
Geçmiş İşlemleri sorgulama | | PosNet | YapıKredi | NonSecure
3DSecure
| İptal
İade
Durum sorgulama | | PosNetV1
(JSON API) | Albaraka Türk | NonSecure
3DSecure | İptal
İade
Durum sorgulama | | PayFor | Finansbank
Enpara | NonSecure
3DSecure
3DPay
3DHost | İptal
İade
Durum sorgulama
Sipariş Tarihçesini sorgulama
Geçmiş İşlemleri sorgulama | diff --git a/docs/HISTORY-EXAMPLE.md b/docs/HISTORY-EXAMPLE.md index a3e5434f..5a1af137 100644 --- a/docs/HISTORY-EXAMPLE.md +++ b/docs/HISTORY-EXAMPLE.md @@ -44,7 +44,7 @@ try { require 'config.php'; -function createHistoryOrder(string $gatewayClass, array $extraData): array +function createHistoryOrder(string $gatewayClass, array $extraData, string $ip): array { $order = []; $txTime = new \DateTimeImmutable(); @@ -60,6 +60,14 @@ function createHistoryOrder(string $gatewayClass, array $extraData): array 'start_date' => $txTime->modify('-1 day'), 'end_date' => $txTime->modify('+1 day'), ]; + } elseif (\Mews\Pos\Gateways\GarantiPos::class === $gatewayClass) { + $order = [ + 'ip' => $ip, + 'page' => 1, //optional + // Başlangıç ve bitiş tarihleri arasında en fazla 30 gün olabilir + 'start_date' => $txTime, + 'end_date' => $txTime->modify('+1 day'), + ]; } elseif (\Mews\Pos\Gateways\AkbankPos::class === $gatewayClass) { $order = [ // Gün aralığı 1 günden fazla girilemez @@ -75,7 +83,7 @@ function createHistoryOrder(string $gatewayClass, array $extraData): array return $order; } -$order = createHistoryOrder(get_class($pos), []); +$order = createHistoryOrder(get_class($pos), [], '127.0.0.1'); $pos->history($order); $response = $pos->getResponse(); diff --git a/examples/_common-codes/regular/history.php b/examples/_common-codes/regular/history.php index 4cb080e1..efbee45c 100644 --- a/examples/_common-codes/regular/history.php +++ b/examples/_common-codes/regular/history.php @@ -8,7 +8,7 @@ require '../../_templates/_header.php'; -function createHistoryOrder(string $gatewayClass, array $extraData): array +function createHistoryOrder(string $gatewayClass, array $extraData, string $ip): array { $order = []; $txTime = new \DateTimeImmutable(); @@ -27,6 +27,15 @@ function createHistoryOrder(string $gatewayClass, array $extraData): array 'start_date' => $txTime->modify('-1 day'), 'end_date' => $txTime->modify('+1 day'), ]; + } elseif (\Mews\Pos\Gateways\GarantiPos::class === $gatewayClass) { + $order = [ + 'ip' => $ip, + 'currency' => \Mews\Pos\PosInterface::CURRENCY_USD, + 'page' => 1, //optional + // Başlangıç ve bitiş tarihleri arasında en fazla 30 gün olabilir + 'start_date' => $txTime, + 'end_date' => $txTime->modify('+1 day'), + ]; } elseif (\Mews\Pos\Gateways\AkbankPos::class === $gatewayClass) { $order = [ // Gün aralığı 1 günden fazla girilemez @@ -42,7 +51,7 @@ function createHistoryOrder(string $gatewayClass, array $extraData): array return $order; } -$order = createHistoryOrder(get_class($pos), []); +$order = createHistoryOrder(get_class($pos), [], $ip); dump($order); $transaction = \Mews\Pos\PosInterface::TX_TYPE_HISTORY; diff --git a/examples/garanti/regular/history.php b/examples/garanti/regular/history.php new file mode 100644 index 00000000..34a3742d --- /dev/null +++ b/examples/garanti/regular/history.php @@ -0,0 +1,3 @@ + 'void', PosInterface::TX_TYPE_REFUND => 'refund', PosInterface::TX_TYPE_ORDER_HISTORY => 'orderhistoryinq', + PosInterface::TX_TYPE_HISTORY => 'orderlistinq', PosInterface::TX_TYPE_STATUS => 'orderinq', ]; @@ -319,11 +324,45 @@ public function createOrderHistoryRequestData(AbstractPosAccount $posAccount, ar } /** + * @param GarantiPosAccount $posAccount * {@inheritDoc} */ public function createHistoryRequestData(AbstractPosAccount $posAccount, array $data = []): array { - throw new NotImplementedException(); + $order = $this->prepareHistoryOrder($data); + + $result = [ + 'Mode' => $this->getMode(), + 'Version' => self::API_VERSION, + 'Terminal' => $this->getTerminalData($posAccount), + 'Customer' => [ + 'IPAddress' => $order['ip'], + ], + 'Order' => [ + 'OrderID' => null, + 'GroupID' => null, + 'Description' => null, + // Başlangıç ve bitiş tarihleri arasında en fazla 30 gün olabilir + 'StartDate' => $this->formatRequestDateTime($order['start_date']), + 'EndDate' => $this->formatRequestDateTime($order['end_date']), + /** + * 500 adetten fazla işlem olması durumunda ListPageNum alanında diğer 500 lü grupların görüntülenmesi + * için sayfa numarası yazılır. + */ + 'ListPageNum' => $order['page'], + ], + 'Transaction' => [ + 'Type' => $this->mapTxType(PosInterface::TX_TYPE_HISTORY), + 'Amount' => $this->formatAmount(1), //sabit olarak amount 100 gonderilecek + 'CurrencyCode' => $this->mapCurrency(PosInterface::CURRENCY_TRY), + 'CardholderPresentCode' => '0', + 'MotoInd' => self::MOTO, + ], + ]; + + $result['Terminal']['HashData'] = $this->crypt->createHash($posAccount, $result); + + return $result; } @@ -462,6 +501,19 @@ protected function prepareOrderHistoryOrder(array $order): array return $this->prepareStatusOrder($order); } + /** + * @inheritDoc + */ + protected function prepareHistoryOrder(array $data): array + { + return [ + 'start_date' => $data['start_date'], + 'end_date' => $data['end_date'], + 'page' => $data['page'] ?? 1, + 'ip' => $data['ip'], + ]; + } + /** * @inheritDoc */ @@ -573,4 +625,14 @@ private function createRecurringData(array $recurringData): array 'StartDate' => isset($recurringData['startDate']) ? $recurringData['startDate']->format('Ymd') : '', ]; } + + /** + * @param \DateTimeInterface $dateTime + * + * @return string example 01/12/2010 11:11 + */ + private function formatRequestDateTime(\DateTimeInterface $dateTime): string + { + return $dateTime->format('d/m/Y H:i'); + } } diff --git a/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php index 46979b18..62a89917 100644 --- a/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapper.php @@ -253,7 +253,7 @@ public function mapStatusResponse(array $rawResponseData): array } /** @var array{Response: array} $transaction */ - $transaction = $rawResponseData['Transaction']; + $transaction = $rawResponseData['Transaction']; /** @var array $orderInqResult */ $orderInqResult = $rawResponseData['Order']['OrderInqResult']; $defaultResponse = $this->getDefaultStatusResponse($rawResponseData); @@ -333,7 +333,36 @@ public function mapOrderHistoryResponse(array $rawResponseData): array */ public function mapHistoryResponse(array $rawResponseData): array { - throw new NotImplementedException(); + $rawResponseData = $this->emptyStringsToNull($rawResponseData); + $procReturnCode = $this->getProcReturnCode($rawResponseData); + $status = self::TX_DECLINED; + if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { + $status = self::TX_APPROVED; + } + + $mappedTransactions = []; + if (self::TX_APPROVED === $status) { + $rawTransactions = $rawResponseData['Order']['OrderListInqResult']['OrderTxnList']['OrderTxn']; + if (\count($rawTransactions) !== \count($rawTransactions, COUNT_RECURSIVE)) { + foreach ($rawTransactions as $transaction) { + $mappedTransaction = $this->mapSingleHistoryTransaction($transaction); + $mappedTransactions[] = $mappedTransaction; + } + } else { + $mappedTransactions[] = $this->mapSingleHistoryTransaction($rawTransactions); + } + } + + return [ + 'proc_return_code' => $procReturnCode, + 'error_code' => self::TX_DECLINED === $status ? $procReturnCode : null, + 'error_message' => self::TX_DECLINED === $status ? $rawResponseData['Transaction']['Response']['ErrorMsg'] : null, + 'status' => $status, + 'status_detail' => $this->getStatusDetail($procReturnCode), + 'trans_count' => \count($mappedTransactions), + 'transactions' => $mappedTransactions, + 'all' => $rawResponseData, + ]; } /** @@ -352,6 +381,23 @@ public function extractMdStatus(array $raw3DAuthResponseData): ?string return $raw3DAuthResponseData['mdstatus'] ?? null; } + /** + * @inheritDoc + */ + public function mapTxType($txType): ?string + { + $historyResponseTxTypes = [ + 'Satis' => PosInterface::TX_TYPE_PAY_AUTH, + 'On Otorizasyon' => PosInterface::TX_TYPE_PAY_PRE_AUTH, + 'On Otorizasyon Kapama' => PosInterface::TX_TYPE_PAY_POST_AUTH, + 'Iade' => PosInterface::TX_TYPE_REFUND, + 'Iptal' => PosInterface::TX_TYPE_CANCEL, + // ... Odul Sorgulama + ]; + + return $historyResponseTxTypes[$txType] ?? parent::mapTxType($txType); + } + /** * 100001 => 1000.01 * @param string $amount @@ -458,6 +504,40 @@ protected function getProcReturnCode(array $response): ?string return $response['Transaction']['Response']['Code'] ?? null; } + /** + * @inheritDoc + */ + protected function mapCurrency(string $currency): string + { + $historyResponseCurrencyMapping = [ + 'TL' => PosInterface::CURRENCY_TRY, + 'USD' => PosInterface::CURRENCY_USD, + 'EUR' => PosInterface::CURRENCY_EUR, + 'RUB' => PosInterface::CURRENCY_RUB, + 'JPY' => PosInterface::CURRENCY_JPY, + 'GBP' => PosInterface::CURRENCY_GBP, + ]; + + return $historyResponseCurrencyMapping[$currency] ?? parent::mapCurrency($currency); + } + + /** + * @inheritDoc + */ + protected function mapInstallment(?string $installment): int + { + if (null === $installment) { + return 0; + } + + // history response + if ('Pesin' === $installment || '1' === $installment) { + return 0; + } + + return parent::mapInstallment($installment); + } + /** * @param array $rawTx * @@ -494,4 +574,97 @@ private function mapSingleOrderHistoryTransaction(array $rawTx): array return $defaultResponse; } + + /** + * @param array $rawTx + * + * @return array + */ + private function mapSingleHistoryTransaction(array $rawTx): array + { + $procReturnCode = $rawTx['ResponseCode']; + $status = self::TX_DECLINED; + if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { + $status = self::TX_APPROVED; + } + + $defaultResponse = $this->getDefaultOrderHistoryTxResponse(); + $defaultResponse['auth_code'] = $rawTx['AuthCode'] ?? null; + $defaultResponse['ref_ret_num'] = $rawTx['RetrefNum'] ?? null; + $defaultResponse['order_id'] = $rawTx['OrderID']; + $defaultResponse['batch_num'] = $rawTx['BatchNum']; + $defaultResponse['proc_return_code'] = $procReturnCode; + $defaultResponse['transaction_type'] = null !== $rawTx['TrxType'] ? $this->mapTxType($rawTx['TrxType']) : null; + $defaultResponse['order_status'] = null !== $rawTx['Status'] ? $this->mapHistoryOrderStatus($rawTx['Status'], $defaultResponse['transaction_type']) : null; + $defaultResponse['status'] = $status; + $defaultResponse['status_detail'] = $this->getStatusDetail($procReturnCode); + $defaultResponse['error_code'] = self::TX_APPROVED === $status ? null : $procReturnCode; + $defaultResponse['error_message'] = self::TX_APPROVED === $status ? null : $rawTx['SysErrMsg']; + + // 3D Secure => 3D + // 3D Pay => 3D + // NonSecure => '' + $defaultResponse['payment_model'] = '3D' === $rawTx['SafeType'] ? PosInterface::MODEL_3D_SECURE : PosInterface::MODEL_NON_SECURE; + $defaultResponse['transaction_time'] = null !== $rawTx['LastTrxDate'] ? new \DateTimeImmutable($rawTx['LastTrxDate']) : null; + if (self::TX_APPROVED === $status) { + $defaultResponse['masked_number'] = $rawTx['CardNumberMasked']; + $defaultResponse['installment_count'] = $this->mapInstallment($rawTx['InstallmentCnt']); + $defaultResponse['currency'] = null !== $rawTx['CurrencyCode'] ? $this->mapCurrency($rawTx['CurrencyCode']) : null; + $defaultResponse['first_amount'] = null !== $rawTx['AuthAmount'] ? $this->formatAmount($rawTx['AuthAmount']) : null; + if ($defaultResponse['order_status'] === PosInterface::PAYMENT_STATUS_PAYMENT_COMPLETED) { + $defaultResponse['capture_amount'] = $defaultResponse['first_amount']; + $defaultResponse['capture'] = $defaultResponse['first_amount'] > 0 ? $defaultResponse['capture_amount'] === $defaultResponse['first_amount'] : null; + $defaultResponse['capture_time'] = $defaultResponse['transaction_time']; + } + } + + return $defaultResponse; + } + + /** + * todo anlasilmayan durumlar: + * - "Status" => "Iptal", "TrxType" => "Satis" + * - "Status" => "Iptal", "TrxType" => "On Otorizasyon" + * - "Status" => "Iptal", "TrxType" => "Iptal" + * - "Status" => "Iptal", "TrxType" => "Iade" + * + * @param string $txStatus + * @param PosInterface::TX_TYPE_*|null $txType + * + * @return string|null + */ + private function mapHistoryOrderStatus(string $txStatus, ?string $txType): ?string + { + if (null === $txType) { + return null; + } + // txStatus possible values: + // Basarili + // Basarisiz + // Iptal + // Onaylandi + + if ('Basarili' === $txStatus || 'Onaylandi' === $txStatus) { + if (PosInterface::TX_TYPE_CANCEL === $txType) { + return PosInterface::PAYMENT_STATUS_CANCELED; + } + if (PosInterface::TX_TYPE_REFUND === $txType) { + // todo how can we decide if order is partially or fully refunded? + return PosInterface::PAYMENT_STATUS_FULLY_REFUNDED; + } + if (PosInterface::TX_TYPE_PAY_AUTH === $txType || PosInterface::TX_TYPE_PAY_POST_AUTH === $txType) { + return PosInterface::PAYMENT_STATUS_PAYMENT_COMPLETED; + } + if (PosInterface::TX_TYPE_PAY_PRE_AUTH === $txType) { + return PosInterface::PAYMENT_STATUS_PRE_AUTH_COMPLETED; + } + + return null; + } + if ('Iptal' === $txStatus) { + return null; + } + + return PosInterface::PAYMENT_STATUS_ERROR; + } } diff --git a/src/Gateways/GarantiPos.php b/src/Gateways/GarantiPos.php index 550ba002..b54fc28a 100644 --- a/src/Gateways/GarantiPos.php +++ b/src/Gateways/GarantiPos.php @@ -14,7 +14,6 @@ use Mews\Pos\Event\RequestDataPreparedEvent; use Mews\Pos\Exceptions\HashMismatchException; use Mews\Pos\Exceptions\UnsupportedPaymentModelException; -use Mews\Pos\Exceptions\UnsupportedTransactionTypeException; use Mews\Pos\PosInterface; use Symfony\Component\HttpFoundation\Request; @@ -48,7 +47,7 @@ class GarantiPos extends AbstractGateway PosInterface::TX_TYPE_CANCEL => true, PosInterface::TX_TYPE_REFUND => true, PosInterface::TX_TYPE_ORDER_HISTORY => true, - PosInterface::TX_TYPE_HISTORY => false, + PosInterface::TX_TYPE_HISTORY => true, ]; @@ -138,14 +137,6 @@ public function make3DHostPayment(Request $request, array $order, string $txType throw new UnsupportedPaymentModelException(); } - /** - * @inheritDoc - */ - public function history(array $data): PosInterface - { - throw new UnsupportedTransactionTypeException(); - } - /** * @inheritDoc * diff --git a/tests/Functional/AkbankPosTest.php b/tests/Functional/AkbankPosTest.php index 2fd8bbe7..667f75e3 100644 --- a/tests/Functional/AkbankPosTest.php +++ b/tests/Functional/AkbankPosTest.php @@ -146,7 +146,7 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro public function testHistorySuccess(): void { - $historyOrder = $this->createHistoryOrder(\get_class($this->pos), []); + $historyOrder = $this->createHistoryOrder(\get_class($this->pos), [], '127.0.0.1'); $eventIsThrown = false; $this->eventDispatcher->addListener( @@ -389,7 +389,7 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro */ public function testRecurringHistorySuccess(): void { - $historyOrder = $this->createHistoryOrder(\get_class($this->pos), []); + $historyOrder = $this->createHistoryOrder(\get_class($this->pos), [], '127.0.0.1'); $eventIsThrown = false; $this->eventDispatcher->addListener( diff --git a/tests/Functional/GarantiPosTest.php b/tests/Functional/GarantiPosTest.php index 65f6c24a..1c5a5e5c 100644 --- a/tests/Functional/GarantiPosTest.php +++ b/tests/Functional/GarantiPosTest.php @@ -260,4 +260,28 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro $this->assertNotEmpty($response); $this->assertTrue($eventIsThrown); } + + /** + * @depends testStatusSuccess + */ + public function testHistorySuccess(): void + { + $historyOrder = $this->createHistoryOrder(\get_class($this->pos), [], '127.0.0.1'); + + $eventIsThrown = false; + $this->eventDispatcher->addListener( + RequestDataPreparedEvent::class, + function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { + $eventIsThrown = true; + $this->assertSame(PosInterface::TX_TYPE_HISTORY, $requestDataPreparedEvent->getTxType()); + $this->assertCount(6, $requestDataPreparedEvent->getRequestData()); + }); + + $this->pos->history($historyOrder); + + $response = $this->pos->getResponse(); + $this->assertIsArray($response); + $this->assertTrue($eventIsThrown); + $this->assertNotEmpty($response['transactions']); + } } diff --git a/tests/Functional/PayForPosTest.php b/tests/Functional/PayForPosTest.php index e72d60e8..75f157e9 100644 --- a/tests/Functional/PayForPosTest.php +++ b/tests/Functional/PayForPosTest.php @@ -171,7 +171,7 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro public function testHistorySuccess(): void { - $historyOrder = $this->createHistoryOrder(\get_class($this->pos), []); + $historyOrder = $this->createHistoryOrder(\get_class($this->pos), [], '127.0.0.1'); $eventIsThrown = false; $this->eventDispatcher->addListener( diff --git a/tests/Functional/PaymentTestTrait.php b/tests/Functional/PaymentTestTrait.php index 60144077..9119da54 100644 --- a/tests/Functional/PaymentTestTrait.php +++ b/tests/Functional/PaymentTestTrait.php @@ -248,18 +248,17 @@ private function createOrderHistoryOrder(string $gatewayClass, array $lastRespon return $order; } - private function createHistoryOrder(string $gatewayClass, array $extraData): array + private function createHistoryOrder(string $gatewayClass, array $extraData, string $ip): array { + $txTime = new \DateTimeImmutable(); if (PayForPos::class === $gatewayClass) { return [ // odeme tarihi - 'transaction_date' => $extraData['transaction_date'] ?? new \DateTimeImmutable(), + 'transaction_date' => $extraData['transaction_date'] ?? $txTime, ]; } if (\Mews\Pos\Gateways\VakifKatilimPos::class === $gatewayClass) { - $txTime = new \DateTimeImmutable(); - return [ 'page' => 1, 'page_size' => 20, @@ -271,9 +270,17 @@ private function createHistoryOrder(string $gatewayClass, array $extraData): arr ]; } - if (\Mews\Pos\Gateways\AkbankPos::class === $gatewayClass) { - $txTime = new \DateTimeImmutable(); + if (\Mews\Pos\Gateways\GarantiPos::class === $gatewayClass) { + return [ + 'ip' => $ip, + 'page' => 1, + // Başlangıç ve bitiş tarihleri arasında en fazla 30 gün olabilir + 'start_date' => $txTime->modify('-1 day'), + 'end_date' => $txTime->modify('+1 day'), + ]; + } + if (\Mews\Pos\Gateways\AkbankPos::class === $gatewayClass) { return [ // Gün aralığı 1 günden fazla girilemez 'start_date' => $txTime->modify('-23 hour'), diff --git a/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php index 21cae2a2..7d5c2f11 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/GarantiPosRequestDataMapperTest.php @@ -190,6 +190,19 @@ public function testCreateOrderHistoryRequestData(array $order, array $expectedD $this->assertEquals($expectedData, $actual); } + /** + * @dataProvider historyRequestDataProvider + */ + public function testCreateHistoryRequestData(array $data, array $expectedData): void + { + $actualData = $this->requestDataMapper->createHistoryRequestData($this->account, $data); + + \ksort($expectedData); + \ksort($actualData); + + $this->assertSame($expectedData, $actualData); + } + /** * @dataProvider create3DPaymentRequestDataDataProvider */ @@ -491,8 +504,8 @@ public static function orderHistoryRequestDataProvider(): array return [ [ 'order' => [ - 'id' => 'order222', - 'ip' => '156.155.154.153', + 'id' => 'order222', + 'ip' => '156.155.154.153', 'installment' => 0, ], 'expected' => [ @@ -524,6 +537,51 @@ public static function orderHistoryRequestDataProvider(): array ]; } + public static function historyRequestDataProvider(): array + { + return [ + [ + 'data' => [ + 'start_date' => new \DateTime('2022-05-18 00:00:00'), + 'end_date' => new \DateTime('2022-05-18 23:59:59'), + 'ip' => '127.0.0.1', + ], + 'expected' => [ + 'Customer' => [ + 'IPAddress' => '127.0.0.1', + ], + + 'Mode' => 'TEST', + 'Order' => [ + 'OrderID' => null, + 'GroupID' => null, + 'Description' => null, + 'StartDate' => '18/05/2022 00:00', + 'EndDate' => '18/05/2022 23:59', + 'ListPageNum' => 1, + ], + + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT', + 'UserID' => 'PROVAUT', + 'HashData' => '9B53A55199EBAD2F486089FD7310C4BC0C61A99FC37EF61F6BBAE67FA17E47641540B203E83C9F2E64DB64B971FE6FF604274316F6D010426D6AA91BE1D924E6', + 'ID' => '30691298', + 'MerchantID' => '7000679', + ], + + 'Transaction' => [ + 'Type' => 'orderlistinq', + 'Amount' => 100, + 'CurrencyCode' => '949', + 'CardholderPresentCode' => '0', + 'MotoInd' => 'N', + ], + 'Version' => '512', + ], + ], + ]; + } + public static function create3DPaymentRequestDataDataProvider(): \Generator { $account = AccountFactory::createGarantiPosAccount( diff --git a/tests/Unit/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapperTest.php b/tests/Unit/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapperTest.php index 5ceca6d8..d33877b4 100644 --- a/tests/Unit/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapperTest.php +++ b/tests/Unit/DataMapper/ResponseDataMapper/GarantiPosResponseDataMapperTest.php @@ -7,6 +7,7 @@ use Mews\Pos\DataMapper\RequestDataMapper\GarantiPosRequestDataMapper; use Mews\Pos\DataMapper\ResponseDataMapper\GarantiPosResponseDataMapper; +use Mews\Pos\Exceptions\NotImplementedException; use Mews\Pos\Factory\CryptFactory; use Mews\Pos\Gateways\GarantiPos; use Mews\Pos\PosInterface; @@ -97,6 +98,12 @@ public function testMap3DPaymentData(array $order, string $txType, array $threeD $this->assertSame($expectedData, $actualData); } + public function testMap3DHostResponseData(): void + { + $this->expectException(NotImplementedException::class); + $this->responseDataMapper->map3DHostResponseData([], PosInterface::TX_TYPE_PAY_AUTH, []); + } + /** * @dataProvider threeDPayPaymentDataProvider */ @@ -164,6 +171,44 @@ public function testOrderMapHistoryResponse(array $responseData, array $expected $this->assertCount($actualData['trans_count'], $actualData['transactions']); + $this->assertArrayHasKey('all', $actualData); + $this->assertIsArray($actualData['all']); + $this->assertNotEmpty($actualData['all']); + unset($actualData['all']); + $this->assertSame($expectedData, $actualData); + } + + /** + * @dataProvider historyTestDataProvider + */ + public function testMapHistoryResponse(array $responseData, array $expectedData): void + { + $actualData = $this->responseDataMapper->mapHistoryResponse($responseData); + + if (count($actualData['transactions']) > 1 + && null !== $actualData['transactions'][0]['transaction_time'] + && null !== $actualData['transactions'][1]['transaction_time'] + ) { + $this->assertGreaterThan( + $actualData['transactions'][0]['transaction_time'], + $actualData['transactions'][1]['transaction_time'] + ); + } + + $this->assertCount($actualData['trans_count'], $actualData['transactions']); + + foreach (array_keys($actualData['transactions']) as $key) { + $this->assertEquals($expectedData['transactions'][$key]['transaction_time'], $actualData['transactions'][$key]['transaction_time'], 'tx: '.$key); + $this->assertEquals($expectedData['transactions'][$key]['capture_time'], $actualData['transactions'][$key]['capture_time'], 'tx: '.$key); + unset($actualData['transactions'][$key]['transaction_time'], $expectedData['transactions'][$key]['transaction_time']); + unset($actualData['transactions'][$key]['capture_time'], $expectedData['transactions'][$key]['capture_time']); + \ksort($actualData['transactions'][$key]); + \ksort($expectedData['transactions'][$key]); + } + + $this->assertArrayHasKey('all', $actualData); + $this->assertIsArray($actualData['all']); + $this->assertNotEmpty($actualData['all']); unset($actualData['all']); $this->assertSame($expectedData, $actualData); } @@ -1732,4 +1777,203 @@ public function orderHistoryTestDataProvider(): array ], ]; } + + public static function historyTestDataProvider(): \Generator + { + $dateRangeHistoryExpected = \json_decode(\file_get_contents(__DIR__.'/../../test_data/garanti/history/daily_range_history_expected.json'), true); + + foreach ($dateRangeHistoryExpected['transactions'] as &$item) { + if (null !== $item['transaction_time']) { + $item['transaction_time'] = new \DateTimeImmutable( + $item['transaction_time']['date'], + new \DateTimeZone($item['transaction_time']['timezone']) + ); + } + if (null !== $item['capture_time']) { + $item['capture_time'] = new \DateTimeImmutable( + $item['capture_time']['date'], + new \DateTimeZone($item['capture_time']['timezone']) + ); + } + } + + yield 'success_data_range_history' => [ + 'responseData' => \json_decode(\file_get_contents(__DIR__.'/../../test_data/garanti/history/date_range_history.json'), true), + //'responseData' => \json_decode(\file_get_contents(__DIR__.'/../../../../var/garanti-last-2-year-history.json'), true), + 'expectedData' => $dateRangeHistoryExpected, + ]; + yield 'success_single_transaction' => [ + 'responseData' => [ + 'Mode' => '', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT', + 'UserID' => 'PROVAUT', + 'ID' => '30691298', + 'MerchantID' => '7000679', + ], + 'Customer' => [ + 'IPAddress' => '172.26.0.1', + 'EmailAddress' => '', + ], + 'Order' => [ + 'OrderID' => '', + 'GroupID' => '', + 'OrderListInqResult' => [ + 'OrderTxnList' => [ + 'TotalTxnCount' => '1', + 'TotalPageCount' => '1', + 'ActPageNum' => '1', + 'OrderTxn' => [ + 'Id' => '1', + 'LastTrxDate' => '2024-06-03 16:06:29', + 'TrxType' => 'Satis', + 'OrderID' => '202406036C78', + 'Name' => '', + 'CardNumberMasked' => '42822090****8015', + 'ExpireDate' => '0830', + 'BankBin' => '42822090', + 'BatchNum' => '576200', + 'AuthCode' => '304919', + 'RetrefNum' => '415501677066', + 'OrigRetrefNum' => '', + 'InstallmentCnt' => 'Pesin', + 'Status' => 'Basarili', + 'AuthAmount' => '1001', + 'CurrencyCode' => 'TL', + 'RemainingBNSAmount' => '0', + 'UsedFBBAmount' => '0', + 'UsedChequeType' => '', + 'UsedChequeCount' => '0', + 'UsedChequeAmount' => '0', + 'SafeType' => '', + 'Comment1' => '', + 'Comment2' => '', + 'Comment3' => '', + 'UserId' => 'PROVAUT', + 'Settlement' => 'N', + 'EmailAddress' => '', + 'RecurringTotalPaymentNum' => '0', + 'RecurringLastPaymentNum' => '0', + 'RecurringTxnAmount' => '0', + 'ResponseCode' => '00', + 'SysErrMsg' => '', + ], + ], + ], + ], + 'Transaction' => [ + 'Response' => [ + 'Source' => 'GVPS', + 'Code' => '00', + 'ReasonCode' => '', + 'Message' => 'Approved', + 'ErrorMsg' => '', + 'SysErrMsg' => '', + ], + 'RetrefNum' => '', + 'AuthCode' => '', + 'BatchNum' => '', + 'SequenceNum' => '', + 'ProvDate' => '20240603 16:07:07', + 'CardNumberMasked' => '', + 'CardHolderName' => '', + 'CardType' => '', + 'HashData' => 'C1DD90277E3CE36D6226FF02E59D95999D78793CF8942860600BA2800A63CB991A518C1DECA1609C99DA8F8995CBB78A54E7D34F337A8BFF60D10B6DB47C8750', + 'HostMsgList' => '', + 'RewardInqResult' => [ + 'RewardList' => '', + 'ChequeList' => '', + ], + ], + ], + 'expectedData' => [ + 'proc_return_code' => '00', + 'error_code' => null, + 'error_message' => null, + 'status' => 'approved', + 'status_detail' => 'approved', + 'trans_count' => 1, + 'transactions' => [ + [ + 'auth_code' => '304919', + 'proc_return_code' => '00', + 'transaction_id' => null, + 'transaction_time' => new \DateTimeImmutable('2024-06-03 16:06:29'), + 'capture_time' => new \DateTimeImmutable('2024-06-03 16:06:29'), + 'error_message' => null, + 'ref_ret_num' => '415501677066', + 'order_status' => 'PAYMENT_COMPLETED', + 'transaction_type' => 'pay', + 'first_amount' => 10.01, + 'capture_amount' => 10.01, + 'status' => 'approved', + 'error_code' => null, + 'status_detail' => 'approved', + 'capture' => true, + 'currency' => 'TRY', + 'masked_number' => '42822090****8015', + 'order_id' => '202406036C78', + 'batch_num' => '576200', + 'payment_model' => 'regular', + 'installment_count' => 0, + ], + ], + ], + ]; + yield 'fail_invalid_fields' => [ + 'responseData' => [ + 'Mode' => '', + 'Terminal' => [ + 'ProvUserID' => 'PROVAUT', + 'UserID' => 'PROVAUT', + 'ID' => '30691298', + 'MerchantID' => '7000679', + ], + 'Customer' => [ + 'IPAddress' => '', + 'EmailAddress' => '', + ], + 'Order' => [ + 'OrderID' => '', + 'GroupID' => '', + 'OrderListInqResult' => [ + 'OrderTxnList' => '', + ], + ], + 'Transaction' => [ + 'Response' => [ + 'Source' => 'GVPS', + 'Code' => '92', + 'ReasonCode' => '0002', + 'Message' => 'Declined', + 'ErrorMsg' => 'Giriş yaptığınız işlem tipi için zorunlu alanları kontrol ediniz', + 'SysErrMsg' => 'CustomerIPAddress field must contain value because of the Mandatory Rule:null', + ], + 'RetrefNum' => '', + 'AuthCode' => '', + 'BatchNum' => '', + 'SequenceNum' => '', + 'ProvDate' => '20240530 12:53:46', + 'CardNumberMasked' => '', + 'CardHolderName' => '', + 'CardType' => '', + 'HashData' => '09852B466F45FE00769BE0E40F028FFF7B560CCA5871F8E562B910C2E9CEF9972A8C7F8655D67D1E31B24E81BF57F5B35F8446A94591256DCFEB92D551FEC858', + 'HostMsgList' => '', + 'RewardInqResult' => [ + 'RewardList' => '', + 'ChequeList' => '', + ], + ], + ], + 'expectedData' => [ + 'proc_return_code' => '92', + 'error_code' => '92', + 'error_message' => 'Giriş yaptığınız işlem tipi için zorunlu alanları kontrol ediniz', + 'status' => 'declined', + 'status_detail' => 'invalid_transaction', + 'trans_count' => 0, + 'transactions' => [], + ], + ]; + } } diff --git a/tests/Unit/Gateways/GarantiPosTest.php b/tests/Unit/Gateways/GarantiPosTest.php index c29803fa..a47b9671 100644 --- a/tests/Unit/Gateways/GarantiPosTest.php +++ b/tests/Unit/Gateways/GarantiPosTest.php @@ -13,7 +13,6 @@ use Mews\Pos\Entity\Card\CreditCardInterface; use Mews\Pos\Event\RequestDataPreparedEvent; use Mews\Pos\Exceptions\UnsupportedPaymentModelException; -use Mews\Pos\Exceptions\UnsupportedTransactionTypeException; use Mews\Pos\Factory\AccountFactory; use Mews\Pos\Factory\CreditCardFactory; use Mews\Pos\Gateways\GarantiPos; @@ -449,10 +448,38 @@ public function testRefundRequest(array $order, string $apiUrl): void $this->pos->refund($order); } - public function testHistoryRequest(): void + /** + * @dataProvider historyRequestDataProvider + */ + public function testHistoryRequest(array $order, string $apiUrl): void { - $this->expectException(UnsupportedTransactionTypeException::class); - $this->pos->history([]); + $account = $this->pos->getAccount(); + $txType = PosInterface::TX_TYPE_HISTORY; + $requestData = ['createHistoryRequestData']; + + $this->requestMapperMock->expects(self::once()) + ->method('createHistoryRequestData') + ->with($account, $order) + ->willReturn($requestData); + + $decodedResponse = ['decodedData']; + $this->configureClientResponse( + $txType, + $apiUrl, + $requestData, + 'request-body', + 'response-body', + $decodedResponse, + $order, + PosInterface::MODEL_NON_SECURE + ); + + $this->responseMapperMock->expects(self::once()) + ->method('mapHistoryResponse') + ->with($decodedResponse) + ->willReturn(['result']); + + $this->pos->history($order); } /** @@ -632,4 +659,18 @@ private function configureClientResponse( && $order === $dispatchedEvent->getOrder() && $paymentModel === $dispatchedEvent->getPaymentModel())); } + + public static function historyRequestDataProvider(): array + { + return [ + [ + 'order' => [ + 'ip' => '127.0.0.1', + 'start_date' => new \DateTimeImmutable(), + 'end_date' => new \DateTimeImmutable(), + ], + 'api_url' => 'https://sanalposprovtest.garantibbva.com.tr/VPServlet', + ], + ]; + } } diff --git a/tests/Unit/test_data/garanti/history/daily_range_history_expected.json b/tests/Unit/test_data/garanti/history/daily_range_history_expected.json new file mode 100644 index 00000000..aa52d2c7 --- /dev/null +++ b/tests/Unit/test_data/garanti/history/daily_range_history_expected.json @@ -0,0 +1,155 @@ +{ + "proc_return_code": "00", + "error_code": null, + "error_message": null, + "status": "approved", + "status_detail": "approved", + "trans_count": 5, + "transactions": [ + { + "auth_code": "304919", + "proc_return_code": "00", + "transaction_id": null, + "transaction_time": { + "date": "2024-06-03 14:04:19.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "capture_time": { + "date": "2024-06-03 14:04:19.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "error_message": null, + "ref_ret_num": "415501676495", + "order_status": "PAYMENT_COMPLETED", + "transaction_type": "pay", + "first_amount": 10.01, + "capture_amount": 10.01, + "status": "approved", + "error_code": null, + "status_detail": "approved", + "capture": true, + "currency": "TRY", + "masked_number": "42822090****8015", + "order_id": "202406033030", + "batch_num": "576200", + "payment_model": "regular", + "installment_count": 0 + }, + { + "auth_code": null, + "proc_return_code": "05", + "transaction_id": null, + "transaction_time": { + "date": "2024-06-03 14:04:29.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "capture_time": null, + "error_message": "RPC-05 condition was raised", + "ref_ret_num": "415501676496", + "order_status": "ERROR", + "transaction_type": "refund", + "first_amount": null, + "capture_amount": null, + "status": "declined", + "error_code": "05", + "status_detail": "reject", + "capture": null, + "currency": null, + "masked_number": null, + "order_id": "202406033030", + "batch_num": "576200", + "payment_model": "regular" + }, + { + "auth_code": "304919", + "proc_return_code": "00", + "transaction_id": null, + "transaction_time": { + "date": "2024-06-03 14:20:59.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "capture_time": { + "date": "2024-06-03 14:20:59.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "error_message": null, + "ref_ret_num": "415501676585", + "order_status": "PAYMENT_COMPLETED", + "transaction_type": "pay", + "first_amount": 4903.17, + "capture_amount": 4903.17, + "status": "approved", + "error_code": null, + "status_detail": "approved", + "capture": true, + "currency": "TRY", + "masked_number": "42822090****8015", + "order_id": "__lwyvqzf9_____65848", + "batch_num": "576200", + "payment_model": "3d", + "installment_count": 0 + }, + { + "auth_code": "304919", + "proc_return_code": "00", + "transaction_id": null, + "transaction_time": { + "date": "2024-06-03 14:50:07.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "capture_time": { + "date": "2024-06-03 14:50:07.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "error_message": null, + "ref_ret_num": "415501676711", + "order_status": "PAYMENT_COMPLETED", + "transaction_type": "pay", + "first_amount": 276.0, + "capture_amount": 276.0, + "status": "approved", + "error_code": null, + "status_detail": "approved", + "capture": true, + "currency": "TRY", + "masked_number": "42822090****8015", + "order_id": "00000093877E202406031450", + "batch_num": "576200", + "payment_model": "3d", + "installment_count": 0 + }, + { + "auth_code": null, + "proc_return_code": "14", + "transaction_id": null, + "transaction_time": { + "date": "2024-06-03 15:09:57.000000", + "timezone_type": 3, + "timezone": "UTC" + }, + "capture_time": null, + "error_message": "HATALI KART NUMARASI.", + "ref_ret_num": "415501676775", + "order_status": "ERROR", + "transaction_type": "pre", + "first_amount": null, + "capture_amount": null, + "status": "declined", + "error_code": "14", + "status_detail": null, + "capture": null, + "currency": null, + "masked_number": null, + "order_id": "202406038F95", + "batch_num": "576200", + "payment_model": "regular" + } + ] +} diff --git a/tests/Unit/test_data/garanti/history/date_range_history.json b/tests/Unit/test_data/garanti/history/date_range_history.json new file mode 100644 index 00000000..fbfce410 --- /dev/null +++ b/tests/Unit/test_data/garanti/history/date_range_history.json @@ -0,0 +1,225 @@ +{ + "Mode": "", + "Terminal": { + "ProvUserID": "PROVAUT", + "UserID": "PROVAUT", + "ID": "30691298", + "MerchantID": "7000679" + }, + "Customer": { + "IPAddress": "172.26.0.1", + "EmailAddress": "" + }, + "Order": { + "OrderID": "", + "GroupID": "", + "OrderListInqResult": { + "OrderTxnList": { + "TotalTxnCount": "5", + "TotalPageCount": "1", + "ActPageNum": "1", + "OrderTxn": [ + { + "Id": "1", + "LastTrxDate": "2024-06-03 14:04:19", + "TrxType": "Satis", + "OrderID": "202406033030", + "Name": "", + "CardNumberMasked": "42822090****8015", + "ExpireDate": "0830", + "BankBin": "42822090", + "BatchNum": "576200", + "AuthCode": "304919", + "RetrefNum": "415501676495", + "OrigRetrefNum": "", + "InstallmentCnt": "Pesin", + "Status": "Basarili", + "AuthAmount": "1001", + "CurrencyCode": "TL", + "RemainingBNSAmount": "0", + "UsedFBBAmount": "0", + "UsedChequeType": "", + "UsedChequeCount": "0", + "UsedChequeAmount": "0", + "SafeType": "", + "Comment1": "", + "Comment2": "", + "Comment3": "", + "UserId": "PROVAUT", + "Settlement": "N", + "EmailAddress": "", + "RecurringTotalPaymentNum": "0", + "RecurringLastPaymentNum": "0", + "RecurringTxnAmount": "0", + "ResponseCode": "00", + "SysErrMsg": "" + }, + { + "Id": "2", + "LastTrxDate": "2024-06-03 14:04:29", + "TrxType": "Iade", + "OrderID": "202406033030", + "Name": "", + "CardNumberMasked": "42822090****8015", + "ExpireDate": "0830", + "BankBin": "42822090", + "BatchNum": "576200", + "AuthCode": "", + "RetrefNum": "415501676496", + "OrigRetrefNum": "415501676495", + "InstallmentCnt": "Pesin", + "Status": "Basarisiz", + "AuthAmount": "801", + "CurrencyCode": "TL", + "RemainingBNSAmount": "0", + "UsedFBBAmount": "0", + "UsedChequeType": "", + "UsedChequeCount": "0", + "UsedChequeAmount": "0", + "SafeType": "", + "Comment1": "", + "Comment2": "", + "Comment3": "", + "UserId": "PROVRFN", + "Settlement": "E", + "EmailAddress": "", + "RecurringTotalPaymentNum": "0", + "RecurringLastPaymentNum": "0", + "RecurringTxnAmount": "0", + "ResponseCode": "05", + "SysErrMsg": "RPC-05 condition was raised" + }, + { + "Id": "3", + "LastTrxDate": "2024-06-03 14:20:59", + "TrxType": "Satis", + "OrderID": "__lwyvqzf9_____65848", + "Name": "", + "CardNumberMasked": "42822090****8015", + "ExpireDate": "0327", + "BankBin": "42822090", + "BatchNum": "576200", + "AuthCode": "304919", + "RetrefNum": "415501676585", + "OrigRetrefNum": "", + "InstallmentCnt": "Pesin", + "Status": "Basarili", + "AuthAmount": "490317", + "CurrencyCode": "TL", + "RemainingBNSAmount": "0", + "UsedFBBAmount": "0", + "UsedChequeType": "", + "UsedChequeCount": "0", + "UsedChequeAmount": "0", + "SafeType": "3D", + "Comment1": "", + "Comment2": "", + "Comment3": "", + "UserId": "GARANTI", + "Settlement": "N", + "EmailAddress": "yigit.ozerdem@etstur.com", + "RecurringTotalPaymentNum": "0", + "RecurringLastPaymentNum": "0", + "RecurringTxnAmount": "0", + "ResponseCode": "00", + "SysErrMsg": "" + }, + { + "Id": "4", + "LastTrxDate": "2024-06-03 14:50:07", + "TrxType": "Satis", + "OrderID": "00000093877E202406031450", + "Name": "", + "CardNumberMasked": "42822090****8015", + "ExpireDate": "0926", + "BankBin": "42822090", + "BatchNum": "576200", + "AuthCode": "304919", + "RetrefNum": "415501676711", + "OrigRetrefNum": "", + "InstallmentCnt": "Pesin", + "Status": "Basarili", + "AuthAmount": "27600", + "CurrencyCode": "TL", + "RemainingBNSAmount": "0", + "UsedFBBAmount": "0", + "UsedChequeType": "", + "UsedChequeCount": "0", + "UsedChequeAmount": "0", + "SafeType": "3D", + "Comment1": "", + "Comment2": "", + "Comment3": "", + "UserId": "KKB_USER", + "Settlement": "N", + "EmailAddress": "ozlemtopuz@kkb.com.tr", + "RecurringTotalPaymentNum": "0", + "RecurringLastPaymentNum": "0", + "RecurringTxnAmount": "0", + "ResponseCode": "00", + "SysErrMsg": "" + }, + { + "Id": "5", + "LastTrxDate": "2024-06-03 15:09:57", + "TrxType": "On Otorizasyon", + "OrderID": "202406038F95", + "Name": "", + "CardNumberMasked": "42822090****8015", + "ExpireDate": "0830", + "BankBin": "42822090", + "BatchNum": "576200", + "AuthCode": "", + "RetrefNum": "415501676775", + "OrigRetrefNum": "", + "InstallmentCnt": "Pesin", + "Status": "Basarisiz", + "AuthAmount": "1001", + "CurrencyCode": "TL", + "RemainingBNSAmount": "0", + "UsedFBBAmount": "0", + "UsedChequeType": "", + "UsedChequeCount": "0", + "UsedChequeAmount": "0", + "SafeType": "", + "Comment1": "", + "Comment2": "", + "Comment3": "", + "UserId": "PROVAUT", + "Settlement": "E", + "EmailAddress": "", + "RecurringTotalPaymentNum": "0", + "RecurringLastPaymentNum": "0", + "RecurringTxnAmount": "0", + "ResponseCode": "14", + "SysErrMsg": "HATALI KART NUMARASI." + } + ] + } + } + }, + "Transaction": { + "Response": { + "Source": "GVPS", + "Code": "00", + "ReasonCode": "", + "Message": "Approved", + "ErrorMsg": "", + "SysErrMsg": "" + }, + "RetrefNum": "", + "AuthCode": "", + "BatchNum": "", + "SequenceNum": "", + "ProvDate": "20240603 15:12:44", + "CardNumberMasked": "", + "CardHolderName": "", + "CardType": "", + "HashData": "8143B6233C873EC7C38AA560C98F34C646CB1F375B84C6760D6EDEFD914F396042C88625F5F5BA205C64C0C7D4C2ACD8F478EEE730AFA159930B5D479BEEC1F5", + "HostMsgList": "", + "RewardInqResult": { + "RewardList": "", + "ChequeList": "" + } + } +}