diff --git a/config/pos_test.php b/config/pos_test.php index 01c92514..82005369 100644 --- a/config/pos_test.php +++ b/config/pos_test.php @@ -15,12 +15,9 @@ 'name' => 'TURK Elektronik Para A.Ş', 'class' => Mews\Pos\Gateways\ParamPos::class, 'gateway_endpoints' => [ - //'payment_api' => 'https://testposws.param.com.tr/turkpos.ws/service_turkpos_prod.asmx', - //'payment_api' => 'https://test-dmz.param.com.tr/turkpos.ws/service_turkpos_test.asmx?wsdl', - 'payment_api' => 'https://test-dmz.param.com.tr/turkpos.ws/service_turkpos_test.asmx', //xml + 'payment_api' => 'https://test-dmz.param.com.tr/turkpos.ws/service_turkpos_test.asmx', + 'payment_api_2' => 'https://test-pos.param.com.tr/to.ws/Service_Odeme.asmx', 'gateway_3d_host' => 'https://test-pos.param.com.tr/default.aspx', - //'payment_api' => 'https://test-dmz.param.com.tr:4443/turkpos.ws/service_turkpos_test.asmx?WSDL', - //prod: 'payment_api' => 'https://posws.param.com.tr/turkpos.ws/service_turkpos_prod.asmx?wsdl', ], ], 'payten_v3_hash' => [ diff --git a/examples/_common-codes/regular/history.php b/examples/_common-codes/regular/history.php index 52690c4d..a03896ec 100644 --- a/examples/_common-codes/regular/history.php +++ b/examples/_common-codes/regular/history.php @@ -49,17 +49,15 @@ function createHistoryOrder(string $gatewayClass, array $extraData, string $ip): // ]; } elseif (\Mews\Pos\Gateways\ParamPos::class === $gatewayClass) { $order = [ - // Gün aralığı 1 günden fazla girilemez + // Gün aralığı 7 günden fazla girilemez 'start_date' => $txTime->modify('-23 hour'), - 'end_date' => $txTime, + 'end_date' => $txTime->modify('+2 days'), + // optional: - 'transaction_type' => \Mews\Pos\PosInterface::TX_TYPE_PAY_AUTH, // TX_TYPE_CANCEL, TX_TYPE_REFUND - 'order_status' => 'Başarılı', // Başarılı, Başarısız + // Bu değerler gönderilince API nedense hata veriyor. +// 'transaction_type' => \Mews\Pos\PosInterface::TX_TYPE_PAY_AUTH, // TX_TYPE_CANCEL, TX_TYPE_REFUND +// 'order_status' => 'Başarılı', // Başarılı, Başarısız ]; -// ya da batch number ile (batch number odeme isleminden alinan response'da bulunur): -// $order = [ -// 'batch_num' => 24, -// ]; } return $order; diff --git a/examples/_common-codes/regular/order_history.php b/examples/_common-codes/regular/order_history.php deleted file mode 100644 index 54debb30..00000000 --- a/examples/_common-codes/regular/order_history.php +++ /dev/null @@ -1,77 +0,0 @@ - $lastResponse['order_id'], - ]; - } elseif (\Mews\Pos\Gateways\AkbankPos::class === $gatewayClass) { - if (isset($lastResponse['recurring_id'])) { - $order = [ - 'recurring_id' => $lastResponse['recurring_id'], - ]; - } else { - $order = [ - 'id' => $lastResponse['order_id'], - ]; - } - } elseif (\Mews\Pos\Gateways\ToslaPos::class === $gatewayClass) { - $order = [ - 'id' => $lastResponse['order_id'], - 'transaction_date' => $lastResponse['transaction_time'], // odeme tarihi - 'page' => 1, // optional, default: 1 - 'page_size' => 10, // optional, default: 10 - ]; - } elseif (\Mews\Pos\Gateways\PayForPos::class === $gatewayClass) { - $order = [ - 'id' => $lastResponse['order_id'], - ]; - } elseif (\Mews\Pos\Gateways\GarantiPos::class === $gatewayClass) { - $order = [ - 'id' => $lastResponse['order_id'], - 'currency' => $lastResponse['currency'], - 'ip' => '127.0.0.1', - ]; - } elseif (\Mews\Pos\Gateways\VakifKatilimPos::class === $gatewayClass) { - /** @var \DateTimeImmutable $txTime */ - $txTime = $lastResponse['transaction_time']; - $order = [ - 'auth_code' => $lastResponse['auth_code'], - /** - * Tarih aralığı maksimum 90 gün olabilir. - */ - 'start_date' => $txTime->modify('-1 day'), - 'end_date' => $txTime->modify('+1 day'), - ]; - } - - return $order; -} - -$lastResponse = $session->get('last_response'); - -$order = createOrderHistoryOrder(get_class($pos), $lastResponse); -dump($order); - -try { - $pos->orderHistory($order); -} catch (Exception $e) { - dd($e); -} - -$response = $pos->getResponse(); - -require '../../_templates/_simple_response_dump.php'; -require '../../_templates/_footer.php'; diff --git a/examples/_common-codes/regular/status.php b/examples/_common-codes/regular/status.php index 144355b6..e74d929f 100644 --- a/examples/_common-codes/regular/status.php +++ b/examples/_common-codes/regular/status.php @@ -41,6 +41,11 @@ function createStatusOrder(string $gatewayClass, array $lastResponse, string $ip } $order = createStatusOrder(get_class($pos), $session->get('last_response'), $ip); +//$statusOrder = [ +// 'id' => 'c4dd4571-c475-4779-b559-79cc54fe8f49', // MerchantOrderId +// // 'currency' => $lastResponse['currency'], +// 'ip' => filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? $ip : '127.0.0.1', +//]; dump($order); $pos->status($order); diff --git a/examples/parampos/_payment_config.php b/examples/parampos/_payment_config.php index b9e0bfc6..5861fe4a 100644 --- a/examples/parampos/_payment_config.php +++ b/examples/parampos/_payment_config.php @@ -14,6 +14,20 @@ 'name' => 'John Doe', ], // 'visa1' => [ +// 'number' => '5421190122090656', +// 'year' => '28', +// 'month' => '04', +// 'cvv' => '916', +// 'name' => 'John Doe', +// ], +// 'visa1' => [ +// 'number' => '5406675406675403', +// 'year' => '26', +// 'month' => '12', +// 'cvv' => '000', +// 'name' => 'John Doe', +// ], +// 'visa1' => [ // 'number' => '4508034508034509', // 'year' => '26', // 'month' => '12', diff --git a/src/Crypt/ParamPosCrypt.php b/src/Crypt/ParamPosCrypt.php index 17b913e3..44298cd7 100644 --- a/src/Crypt/ParamPosCrypt.php +++ b/src/Crypt/ParamPosCrypt.php @@ -14,26 +14,11 @@ class ParamPosCrypt extends AbstractCrypt { /** - * todo remove? * {@inheritDoc} */ public function create3DHash(AbstractPosAccount $posAccount, array $formInputs): string { - $hashData = [ - $formInputs['clientid'], - $formInputs['oid'], - $formInputs['amount'], - $formInputs['okUrl'], - $formInputs['failUrl'], - $formInputs['islemtipi'], - $formInputs['taksit'], - $formInputs['rnd'], - $posAccount->getStoreKey(), - ]; - - $hashStr = \implode(static::HASH_SEPARATOR, $hashData); - - return $this->hashString($hashStr); + throw new NotImplementedException(); } /** diff --git a/src/DataMapper/RequestDataMapper/ParamPosRequestDataMapper.php b/src/DataMapper/RequestDataMapper/ParamPosRequestDataMapper.php index 69cd8484..48d0d585 100644 --- a/src/DataMapper/RequestDataMapper/ParamPosRequestDataMapper.php +++ b/src/DataMapper/RequestDataMapper/ParamPosRequestDataMapper.php @@ -96,7 +96,7 @@ public function create3DPaymentRequestData(AbstractPosAccount $posAccount, array 'Siparis_ID' => (string) $responseData['orderId'], ]; - return ['TP_WMD_Pay' => $requestData]; + return $this->wrapSoapEnvelope(['TP_WMD_Pay' => $requestData], $posAccount); } /** @@ -111,6 +111,9 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $posAccoun if (PosInterface::MODEL_3D_HOST === $paymentModel) { return $this->create3DHostEnrollmentCheckRequestData($posAccount, $order); } + if (null === $creditCard) { + throw new \InvalidArgumentException('Bu işlem için kredi kartı bilgileri gereklidir.'); + } $order = $this->preparePaymentOrder($order); $requestData = $this->getRequestAccountData($posAccount) + [ @@ -147,16 +150,16 @@ public function create3DEnrollmentCheckRequestData(AbstractPosAccount $posAccoun $requestData[$soapAction]['Islem_Hash'] = $this->crypt->createHash($posAccount, $requestData); - return $requestData; + return $this->wrapSoapEnvelope($requestData, $posAccount); } public function create3DHostEnrollmentCheckRequestData(AbstractPosAccount $posAccount, array $order): array { $order = $this->preparePaymentOrder($order); - $requestData = $this->getRequestAccountData($posAccount, PosInterface::MODEL_3D_HOST) + [ - // '@xmlns' => 'https://turkodeme.com.tr/', - '@xmlns' => 'https://turkpos.com.tr/', + $requestData = [ + '@xmlns' => 'https://turkodeme.com.tr/', + //'@xmlns' => 'https://turkpos.com.tr/', 'Borclu_Tutar' => 'r|'.$this->formatAmount($order['amount']), // Bu alan editable olsun istiyorsanız başına “e|”, readonly olsun istiyorsanız başına “r|” eklemelisiniz. 'Borclu_Odeme_Tip' => 'r|Diğer', @@ -165,6 +168,7 @@ public function create3DHostEnrollmentCheckRequestData(AbstractPosAccount $posAc 'Return_URL' => 'r|'.$order['success_url'], 'Islem_ID' => $this->crypt->generateRandomString(), 'Borclu_Kisi_TC' => '', + 'Terminal_ID' => $posAccount->getClientId(), 'Borclu_GSM' => 'r|5555555555', // = 0 ise tüm taksitler listelenir. > 0 ise sadece o taksit seçeneği listelenir. //'Taksit' => $this->mapInstallment((int) $order['installment']), @@ -192,7 +196,7 @@ public function create3DHostEnrollmentCheckRequestData(AbstractPosAccount $posAc //$soapAction = PosInterface::CURRENCY_TRY === $order['currency'] ? 'TP_WMD_UCD' : 'TP_Islem_Odeme_WD'; $soapAction = 'TO_Pre_Encrypting_OOS'; - return [$soapAction => $requestData]; + return $this->wrapSoapEnvelope([$soapAction => $requestData], $posAccount); } @@ -206,6 +210,9 @@ public function create3DHostEnrollmentCheckRequestData(AbstractPosAccount $posAc public function createNonSecurePaymentRequestData(AbstractPosAccount $posAccount, array $order, string $txType, CreditCardInterface $creditCard): array { $order = $this->preparePaymentOrder($order); + if (PosInterface::CURRENCY_TRY !== $order['currency']) { + throw new \LogicException('MODEL_NON_SECURE odeme döviz ödemeleri desteklememektedir.'); + } $requestData = $this->getRequestAccountData($posAccount) + [ '@xmlns' => 'https://turkpos.com.tr/', @@ -241,7 +248,7 @@ public function createNonSecurePaymentRequestData(AbstractPosAccount $posAccount $requestData[$soapAction]['Islem_Hash'] = $this->crypt->createHash($posAccount, $requestData); - return $requestData; + return $this->wrapSoapEnvelope($requestData, $posAccount); } //todo @@ -262,7 +269,7 @@ public function createNonSecurePostAuthPaymentRequestData(AbstractPosAccount $po 'Siparis_ID' => (string) $order['id'], ]; - return ['TP_Islem_Odeme_OnProv_Kapa' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Odeme_OnProv_Kapa' => $requestData], $posAccount); } /** @@ -277,7 +284,7 @@ public function createStatusRequestData(AbstractPosAccount $posAccount, array $o 'Siparis_ID' => $order['id'], ]; - return ['TP_Islem_Sorgulama4' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Sorgulama4' => $requestData], $posAccount); } /** @@ -294,7 +301,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o 'Siparis_ID' => $order['id'], ]; - return ['TP_Islem_Iptal_OnProv' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Iptal_OnProv' => $requestData], $posAccount); } $requestData = $this->getRequestAccountData($posAccount) + [ '@xmlns' => 'https://turkpos.com.tr/', @@ -303,7 +310,7 @@ public function createCancelRequestData(AbstractPosAccount $posAccount, array $o 'Tutar' => $order['amount'], ]; - return ['TP_Islem_Iptal_Iade_Kismi2' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Iptal_Iade_Kismi2' => $requestData], $posAccount); } @@ -321,7 +328,7 @@ public function createRefundRequestData(AbstractPosAccount $posAccount, array $o 'Tutar' => $order['amount'], ]; - return ['TP_Islem_Iptal_Iade_Kismi2' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Iptal_Iade_Kismi2' => $requestData], $posAccount); } /** @@ -352,15 +359,15 @@ public function createHistoryRequestData(AbstractPosAccount $posAccount, array $ } if (isset($data['transaction_type'])) { if (PosInterface::TX_TYPE_PAY_AUTH === $data['transaction_type']) { - $requestData['Islem_Tipi'] = 'Satış'; + $requestData['Islem_Tip'] = 'Satış'; } elseif (PosInterface::TX_TYPE_CANCEL === $data['transaction_type']) { - $requestData['Islem_Tipi'] = 'İptal'; + $requestData['Islem_Tip'] = 'İptal'; } elseif (PosInterface::TX_TYPE_REFUND === $data['transaction_type']) { - $requestData['Islem_Tipi'] = 'İade'; + $requestData['Islem_Tip'] = 'İade'; } } - return ['TP_Islem_Izleme' => $requestData]; + return $this->wrapSoapEnvelope(['TP_Islem_Izleme' => $requestData], $posAccount); } /** @@ -388,6 +395,10 @@ public function create3DFormData(?AbstractPosAccount $posAccount, ?array $order, ]; } + if ('' === $extraData['UCD_HTML']) { + throw new \RuntimeException('3D form verisi oluşturulamadı! UCD_HTML değeri boş.'); + } + return $extraData['UCD_HTML']; } @@ -399,7 +410,7 @@ public function createCustomQueryRequestData(AbstractPosAccount $posAccount, arr $soapAction = \array_key_first($requestData); $requestData[$soapAction] = $requestData[$soapAction] + $this->getRequestAccountData($posAccount); - return $requestData; + return $this->wrapSoapEnvelope($requestData, $posAccount); } /** @@ -519,4 +530,31 @@ private function formatRequestDateTime(\DateTimeInterface $dateTime): string { return $dateTime->format('d.m.Y H:i:s'); } + + private function wrapSoapEnvelope(array $data, AbstractPosAccount $posAccount): array + { + if (isset($data['TO_Pre_Encrypting_OOS'])) { + return [ + '@xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + '@xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', + '@xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'soap:Header' => [ // for soap:Header calls header must be before soap:Body + 'ServiceSecuritySoapHeader' => [ + '@xmlns' => 'https://turkodeme.com.tr/', + 'CLIENT_CODE' => $posAccount->getClientId(), + 'CLIENT_USERNAME' => $posAccount->getUsername(), + 'CLIENT_PASSWORD' => $posAccount->getPassword(), + ], + ], + 'soap:Body' => $data, + ]; + } + + return [ + '@xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + '@xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', + '@xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', + 'soap:Body' => $data, + ]; + } } diff --git a/src/DataMapper/ResponseDataMapper/AkbankPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/AkbankPosResponseDataMapper.php index 0fe67b3d..a30c7352 100644 --- a/src/DataMapper/ResponseDataMapper/AkbankPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/AkbankPosResponseDataMapper.php @@ -296,7 +296,7 @@ public function mapOrderHistoryResponse(array $rawResponseData): array } if (!$isRecurringOrder) { - \usort($transactions, static function (array $tx1, array $tx2): int { + \usort($transactions, static function (array $tx1, array $tx2): int { if (null !== $tx1['transaction_time'] && null === $tx2['transaction_time']) { return 1; } diff --git a/src/DataMapper/ResponseDataMapper/ParamPosResponseDataMapper.php b/src/DataMapper/ResponseDataMapper/ParamPosResponseDataMapper.php index a52c9a0b..fbdb1663 100644 --- a/src/DataMapper/ResponseDataMapper/ParamPosResponseDataMapper.php +++ b/src/DataMapper/ResponseDataMapper/ParamPosResponseDataMapper.php @@ -8,6 +8,7 @@ use Mews\Pos\Exceptions\NotImplementedException; use Mews\Pos\PosInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\VarExporter\VarExporter; class ParamPosResponseDataMapper extends AbstractResponseDataMapper @@ -25,14 +26,63 @@ class ParamPosResponseDataMapper extends AbstractResponseDataMapper * @var array */ protected array $orderStatusMappings = [ - 'FAIL' => PosInterface::PAYMENT_STATUS_ERROR, - 'BANK_FAIL' => PosInterface::PAYMENT_STATUS_ERROR, - 'SUCCESS' => PosInterface::PAYMENT_STATUS_PAYMENT_COMPLETED, - 'CANCEL' => PosInterface::PAYMENT_STATUS_CANCELED, - 'REFUND' => PosInterface::PAYMENT_STATUS_FULLY_REFUNDED, - 'PARTIAL_REFUND' => PosInterface::PAYMENT_STATUS_PARTIALLY_REFUNDED, + 'FAIL' => PosInterface::PAYMENT_STATUS_ERROR, + 'BANK_FAIL' => PosInterface::PAYMENT_STATUS_ERROR, + 'SUCCESS' => PosInterface::PAYMENT_STATUS_PAYMENT_COMPLETED, + 'CANCEL' => PosInterface::PAYMENT_STATUS_CANCELED, + 'REFUND' => PosInterface::PAYMENT_STATUS_FULLY_REFUNDED, + 'PARTIAL_REFUND' => PosInterface::PAYMENT_STATUS_PARTIALLY_REFUNDED, ]; + private array $statusRequestTxMappings = [ + 'SALE' => PosInterface::TX_TYPE_PAY_AUTH, + 'PRE_AUTH' => PosInterface::TX_TYPE_PAY_PRE_AUTH, + 'POST_AUTH' => PosInterface::TX_TYPE_PAY_POST_AUTH, + ]; + + private array $historyRequestTxMappings = [ + 'Satış' => PosInterface::TX_TYPE_PAY_POST_AUTH, + 'İptal' => PosInterface::TX_TYPE_CANCEL, + 'İade' => PosInterface::TX_TYPE_REFUND, + ]; + + /** + * @param array $currencyMappings + * @param array $txTypeMappings + * @param array $secureTypeMappings + * @param LoggerInterface $logger + */ + public function __construct(array $currencyMappings, array $txTypeMappings, array $secureTypeMappings, LoggerInterface $logger) + { + parent::__construct($currencyMappings, $txTypeMappings, $secureTypeMappings, $logger); + + $this->secureTypeMappings = [ + 'NONSECURE' => PosInterface::MODEL_NON_SECURE, + '3D' => PosInterface::MODEL_3D_SECURE, + ]; + + $this->currencyMappings += [ + 'TRL' => PosInterface::CURRENCY_TRY, + 'EUR' => PosInterface::CURRENCY_EUR, + 'USD' => PosInterface::CURRENCY_USD, + ]; + } + + /** + * @inheritDoc + */ + public function mapTxType($txType): ?string + { + if (isset($this->statusRequestTxMappings[$txType])) { + return $this->statusRequestTxMappings[$txType]; + } + if (isset($this->historyRequestTxMappings[$txType])) { + return $this->historyRequestTxMappings[$txType]; + } + + return parent::mapTxType($txType); + } + /** * {@inheritDoc} */ @@ -53,7 +103,6 @@ public function mapPaymentResponse(array $rawPaymentResponseData, string $txType $payResult = $rawPaymentResponseData['TP_Islem_Odeme_OnProv_KapaResponse']['TP_Islem_Odeme_OnProv_KapaResult']; } else { $payResult = $rawPaymentResponseData['TP_WMD_UCDResponse']['TP_WMD_UCDResult']; - //$payResult = $rawPaymentResponseData['TP_WMD_PayResponse']['TP_WMD_PayResult']; } $procReturnCode = $this->getProcReturnCode($payResult); @@ -67,7 +116,6 @@ public function mapPaymentResponse(array $rawPaymentResponseData, string $txType $mappedResponse = [ 'proc_return_code' => $procReturnCode, 'status' => $status, - 'status_detail' => $this->getStatusDetail($procReturnCode), 'error_code' => self::TX_APPROVED === $status ? null : $procReturnCode, 'error_message' => self::TX_APPROVED === $status ? null : ($payResult['Sonuc_Str'] ?? $payResult['Bank_HostMsg']), 'all' => $rawPaymentResponseData, @@ -76,9 +124,9 @@ public function mapPaymentResponse(array $rawPaymentResponseData, string $txType if (PosInterface::TX_TYPE_PAY_PRE_AUTH !== $txType) { $mappedResponse['ref_ret_num'] = $payResult['Bank_HostRefNum']; } - $mappedResponse['order_id'] = $payResult['Siparis_ID']; - $mappedResponse['transaction_id'] = $payResult['Bank_Trans_ID']; - $mappedResponse['auth_code'] = $payResult['Bank_AuthCode']; + $mappedResponse['order_id'] = $payResult['Siparis_ID']; + $mappedResponse['transaction_id'] = $payResult['Bank_Trans_ID']; + $mappedResponse['auth_code'] = $payResult['Bank_AuthCode']; $mappedResponse['amount'] = $order['amount']; $mappedResponse['currency'] = $order['currency']; @@ -90,9 +138,9 @@ public function mapPaymentResponse(array $rawPaymentResponseData, string $txType } /** - * @param array $rawPaymentResponseData + * @param array $rawPaymentResponseData * @param PosInterface::TX_TYPE_PAY_* $txType - * @param array $order + * @param array $order * * @return array */ @@ -118,7 +166,6 @@ private function map3DPaymentResponse(array $rawPaymentResponseData, string $txT $mappedResponse = [ 'proc_return_code' => $procReturnCode, 'status' => $status, - 'status_detail' => $this->getStatusDetail($procReturnCode), 'error_code' => self::TX_APPROVED === $status ? null : $procReturnCode, 'error_message' => self::TX_APPROVED === $status ? null : ($payResult['Sonuc_Ack'] ?? $payResult['Bank_HostMsg']), 'all' => $rawPaymentResponseData, @@ -127,6 +174,7 @@ private function map3DPaymentResponse(array $rawPaymentResponseData, string $txT $mappedResponse['order_id'] = $payResult['Siparis_ID']; $mappedResponse['transaction_id'] = $payResult['Bank_Trans_ID']; $mappedResponse['auth_code'] = $payResult['Bank_AuthCode']; + $mappedResponse['ref_ret_num'] = $payResult['Bank_HostRefNum']; $mappedResponse['currency'] = $order['currency']; $mappedResponse['transaction_time'] = new \DateTimeImmutable(); } @@ -136,9 +184,9 @@ private function map3DPaymentResponse(array $rawPaymentResponseData, string $txT } /** - * @param array $rawPaymentResponseData + * @param array $rawPaymentResponseData * @param PosInterface::TX_TYPE_PAY_* $txType - * @param array $order + * @param array $order * * @return array */ @@ -152,7 +200,7 @@ private function map3DPaymentWithForeignCurrencyResponse(array $rawPaymentRespon } $rawPaymentResponseData = $this->emptyStringsToNull($rawPaymentResponseData); - $payResult = $this->removePrefixFrom3DPaymentForeignCurrencyResponse($rawPaymentResponseData); + $payResult = $this->removePrefixFrom3DPaymentForeignCurrencyResponse($rawPaymentResponseData); $procReturnCode = $this->getProcReturnCode($payResult); $status = self::TX_DECLINED; @@ -163,15 +211,14 @@ private function map3DPaymentWithForeignCurrencyResponse(array $rawPaymentRespon $mappedResponse = [ 'proc_return_code' => $procReturnCode, 'status' => $status, - 'status_detail' => $this->getStatusDetail($procReturnCode), 'error_code' => self::TX_APPROVED === $status ? null : $procReturnCode, 'error_message' => self::TX_APPROVED === $status ? null : $payResult['Sonuc_Str'], 'all' => $rawPaymentResponseData, ]; if (self::TX_APPROVED === $status) { $mappedResponse['order_id'] = $payResult['Siparis_ID']; - $mappedResponse['amount'] = $this->formatAmount($payResult['Tahsilat_Tutari']); - $mappedResponse['currency'] = $payResult['PB']; //todo + $mappedResponse['amount'] = $this->formatAmount($payResult['Tahsilat_Tutari']); + $mappedResponse['currency'] = $this->mapCurrency($payResult['PB']); $mappedResponse['transaction_time'] = new \DateTimeImmutable($payResult['Islem_Tarih']); } $this->logger->debug('mapped payment response', $mappedResponse); @@ -187,7 +234,7 @@ private function removePrefixFrom3DPaymentForeignCurrencyResponse(array $rawPaym { $newArray = []; foreach ($rawPaymentResponseData as $key => $value) { - $newKey = \str_replace('TURKPOS_RETVAL_', '', $key); + $newKey = \str_replace('TURKPOS_RETVAL_', '', $key); $newArray[$newKey] = $value; } @@ -221,7 +268,7 @@ public function map3DPaymentData(array $raw3DAuthResponseData, ?array $rawPaymen $paymentResponseData = $this->map3DPaymentResponse($rawPaymentResponseData, $txType, $order); } - $mdStatus = $this->extractMdStatus($raw3DAuthResponseData); + $mdStatus = $this->extractMdStatus($raw3DAuthResponseData); $threeDResponse = [ 'transaction_security' => null, @@ -325,7 +372,7 @@ public function mapCancelResponse(array $rawResponseData): array $cancelResponse = $rawResponseData['TP_Islem_Iptal_Iade_Kismi2Response']['TP_Islem_Iptal_Iade_Kismi2Result'] ?? $rawResponseData['TP_Islem_Iptal_OnProvResponse']['TP_Islem_Iptal_OnProvResult']; - $procReturnCode = $this->getProcReturnCode($cancelResponse); + $procReturnCode = $this->getProcReturnCode($cancelResponse); if ($procReturnCode > 0) { $status = self::TX_APPROVED; @@ -345,8 +392,8 @@ public function mapCancelResponse(array $rawResponseData): array 'all' => $rawResponseData, ]; if (self::TX_APPROVED === $status && isset($rawResponseData['TP_Islem_Iptal_Iade_Kismi2Response'])) { - $result['auth_code'] = $cancelResponse['Bank_AuthCode']; - $result['ref_ret_num'] = $cancelResponse['Bank_HostRefNum']; + $result['auth_code'] = $cancelResponse['Bank_AuthCode']; + $result['ref_ret_num'] = $cancelResponse['Bank_HostRefNum']; $result['transaction_id'] = $cancelResponse['Bank_Trans_ID']; } @@ -362,8 +409,8 @@ public function mapStatusResponse(array $rawResponseData): array $rawResponseData = $this->emptyStringsToNull($rawResponseData); $statusResponse = $rawResponseData['TP_Islem_Sorgulama4Response']['TP_Islem_Sorgulama4Result']; - $procReturnCode = $this->getProcReturnCode($statusResponse); - $status = self::TX_DECLINED; + $procReturnCode = $this->getProcReturnCode($statusResponse); + $status = self::TX_DECLINED; if ($procReturnCode > 0) { $status = self::TX_APPROVED; } @@ -381,29 +428,35 @@ public function mapStatusResponse(array $rawResponseData): array $result = $defaultResponse; if (self::TX_APPROVED === $status) { - $result['auth_code'] = $dtBilgi['Bank_AuthCode']; - $result['ref_ret_num'] = $dtBilgi['Bank_HostRefNum']; - $result['masked_number'] = $dtBilgi['KK_No']; - $result['first_amount'] = (float) $dtBilgi['Toplam_Tutar']; - // todo Toplam_Iade_Tutar - - $result['order_status'] = $this->orderStatusMappings[$dtBilgi['Durum']] ?? null; - if ('SALE' === $dtBilgi['Islem_Tip']) { + $result['auth_code'] = $dtBilgi['Bank_AuthCode']; + $result['ref_ret_num'] = $dtBilgi['Bank_HostRefNum']; + $result['masked_number'] = $dtBilgi['KK_No']; + $result['first_amount'] = (float) $dtBilgi['Toplam_Tutar']; + + $result['order_status'] = $this->orderStatusMappings[$dtBilgi['Durum']] ?? null; + $result['transaction_type'] = $this->mapTxType($dtBilgi['Islem_Tip']); + + if (PosInterface::TX_TYPE_PAY_AUTH === $result['transaction_type']) { $result['transaction_type'] = PosInterface::TX_TYPE_PAY_AUTH; $result['capture_amount'] = $result['first_amount']; - } elseif ('PRE_AUTH' === $dtBilgi['Islem_Tip']) { - $result['transaction_type'] = PosInterface::TX_TYPE_PAY_PRE_AUTH; - $result['order_status'] = PosInterface::PAYMENT_STATUS_PRE_AUTH_COMPLETED; - } elseif ('POST_AUTH' === $dtBilgi['Islem_Tip']) { - $result['transaction_type'] = PosInterface::TX_TYPE_PAY_POST_AUTH; + } elseif ( + PosInterface::TX_TYPE_PAY_PRE_AUTH === $result['transaction_type'] + && $result['order_status'] === PosInterface::PAYMENT_STATUS_PAYMENT_COMPLETED) { + $result['order_status'] = PosInterface::PAYMENT_STATUS_PRE_AUTH_COMPLETED; } - $result['capture'] = $result['first_amount'] === $result['capture_amount']; - // todo refund_amount - $result['transaction_time'] = isset($dtBilgi['Tarih']) ? new \DateTimeImmutable($dtBilgi['Tarih']) : null; - //todo - $result['capture_time'] = isset($dtBilgi['Tarih']) ? new \DateTimeImmutable($dtBilgi['Tarih']) : null; - $result['cancel_time'] = isset($dtBilgi['Tarih']) ? new \DateTimeImmutable($dtBilgi['Tarih']) : null; + $txDate = isset($dtBilgi['Tarih']) ? new \DateTimeImmutable($dtBilgi['Tarih']) : null; + if ($dtBilgi['Toplam_Iade_Tutar'] > 0) { + $dtBilgi['refund_amount'] = $this->formatAmount($dtBilgi['Toplam_Iade_Tutar']); + $dtBilgi['refund_time'] = $txDate; + } + if (PosInterface::PAYMENT_STATUS_CANCELED === $result['order_status']) { + $result['cancel_time'] = $txDate; + } + + $result['capture'] = $result['first_amount'] === $result['capture_amount']; + $result['capture_time'] = $result['capture'] ? $txDate : null; + $result['transaction_time'] = $txDate; } return $result; @@ -417,14 +470,46 @@ public function mapOrderHistoryResponse(array $rawResponseData): array throw new NotImplementedException(); } - // todo /** * {@inheritDoc} */ public function mapHistoryResponse(array $rawResponseData): array { - throw new NotImplementedException(); + $rawResponseData = $this->emptyStringsToNull($rawResponseData); + + + $mappedTransactions = []; + $rawResult = $rawResponseData['TP_Islem_IzlemeResponse']['TP_Islem_IzlemeResult']; + $procReturnCode = $this->getProcReturnCode($rawResult); + $status = self::TX_DECLINED; + if ($procReturnCode > 0) { + $status = self::TX_APPROVED; + foreach ($rawResult['DT_Bilgi']['diffgr:diffgram']['NewDataSet']['Temp'] as $rawTx) { + $mappedTransactions[] = $this->mapSingleHistoryTransaction($rawTx); + } + } + + // sort transactions by transaction time + $mappedTransactions = \array_reverse($mappedTransactions); + + $result = [ + 'proc_return_code' => $procReturnCode, + 'error_code' => null, + 'error_message' => null, + 'status' => $status, + 'status_detail' => null, + 'trans_count' => \count($mappedTransactions), + 'transactions' => $mappedTransactions, + 'all' => $rawResponseData, + ]; + + if (null !== $procReturnCode && self::PROCEDURE_SUCCESS_CODE !== $procReturnCode) { + $result['error_code'] = $procReturnCode; + $result['error_message'] = $rawResult['Sonuc_Str']; + } + + return $result; } // todo @@ -471,78 +556,42 @@ protected function formatAmount(string $amount): float return ((float) \str_replace(',', '.', $amount)); } - // todo - /** * @param array $rawTx * * @return array */ - private function mapSingleOrderHistoryTransaction(array $rawTx): array + private function mapSingleHistoryTransaction(array $rawTx): array { $rawTx = $this->emptyStringsToNull($rawTx); $transaction = $this->getDefaultOrderHistoryTxResponse(); - $transaction['auth_code'] = $rawTx[8]; - $transaction['proc_return_code'] = $rawTx[9]; - if (self::PROCEDURE_SUCCESS_CODE === $transaction['proc_return_code']) { + $procReturnCode = $this->getProcReturnCode($rawTx); + $transaction['proc_return_code'] = $procReturnCode; + if ($procReturnCode > 0) { $transaction['status'] = self::TX_APPROVED; } - $transaction['status_detail'] = $this->getStatusDetail($transaction['proc_return_code']); - $transaction['transaction_id'] = $rawTx[10]; - /** - * S: Auth/PreAuth/PostAuth - * C: Refund - */ - $transaction['transaction_type'] = 'S' === $rawTx[0] ? PosInterface::TX_TYPE_PAY_AUTH : PosInterface::TX_TYPE_REFUND; - $transaction['order_status'] = $this->orderStatusMappings[$rawTx[1]] ?? null; - $transaction['transaction_time'] = new \DateTimeImmutable($rawTx[4]); - $transaction['first_amount'] = null === $rawTx[2] ? null : $this->formatAmount($rawTx[2]); - $transaction['capture_amount'] = null === $rawTx[3] ? null : $this->formatAmount($rawTx[3]); - $transaction['capture'] = self::TX_APPROVED === $transaction['status'] && $transaction['first_amount'] === $transaction['capture_amount']; - $transaction['ref_ret_num'] = $rawTx[7]; + $transaction['transaction_type'] = $this->txTypeMappings[$rawTx['Tip_Str']] ?? null; + if (self::TX_APPROVED === $transaction['status']) { + $transaction['currency'] = isset($rawTx['PB']) ? $this->mapCurrency($rawTx['PB']) : null; + $amount = null === $rawTx['Tutar'] ? null : $this->formatAmount($rawTx['Tutar']); + if (PosInterface::TX_TYPE_PAY_AUTH === $transaction['transaction_type']) { + $transaction['first_amount'] = $amount; + $transaction['capture_amount'] = $amount; + $transaction['capture'] = true; + } elseif (PosInterface::TX_TYPE_CANCEL === $transaction['transaction_type'] && $rawTx['Tutar'] < 0) { + $transaction['refund_amount'] = $transaction['first_amount']; + } - return $transaction; - } + if ($rawTx['Toplam_Iade_Tutar'] > 0) { + $transaction['refund_amount'] = $this->formatAmount($rawTx['Toplam_Iade_Tutar']); + } - /** - * @param array $extra - * @param int<1, max> $i - * - * @return array - */ - private function mapSingleRecurringOrderStatus(array $extra, int $i): array - { - $procReturnCode = $extra[\sprintf('PROC_RET_CD_%d', $i)] ?? null; - $status = self::TX_DECLINED; - if (self::PROCEDURE_SUCCESS_CODE === $procReturnCode) { - $status = self::TX_APPROVED; - } elseif (null === $procReturnCode) { - $status = null; } + $transaction['order_id'] = $rawTx['ORJ_ORDER_ID']; + $transaction['payment_model'] = $this->mapSecurityType($rawTx['Islem_Guvenlik']); + $transaction['transaction_time'] = new \DateTimeImmutable($rawTx['Tarih']); - $recurringOrder = [ - 'order_id' => $extra[\sprintf('ORD_ID_%d', $i)], - 'masked_number' => $extra[\sprintf('PAN_%d', $i)], - 'order_status' => $this->orderStatusMappings[$extra[\sprintf('TRANS_STAT_%d', $i)]] ?? null, - - // following fields are null until transaction is done for respective installment: - 'auth_code' => $extra[\sprintf('AUTH_CODE_%d', $i)] ?? null, - 'proc_return_code' => $procReturnCode, - 'transaction_type' => 'S' === $extra[\sprintf('CHARGE_TYPE_CD_%d', $i)] ? PosInterface::TX_TYPE_PAY_AUTH : PosInterface::TX_TYPE_REFUND, - 'status' => $status, - 'status_detail' => $this->getStatusDetail($procReturnCode), - 'transaction_time' => isset($extra[\sprintf('AUTH_DTTM_%d', $i)]) ? new \DateTimeImmutable($extra[\sprintf('AUTH_DTTM_%d', $i)]) : null, - 'capture_time' => isset($extra[\sprintf('CAPTURE_DTTM_%d', $i)]) ? new \DateTimeImmutable($extra[\sprintf('CAPTURE_DTTM_%d', $i)]) : null, - 'transaction_id' => $extra[\sprintf('TRANS_ID_%d', $i)] ?? null, - 'ref_ret_num' => $extra[\sprintf('HOST_REF_NUM_%d', $i)] ?? null, - 'first_amount' => isset($extra[\sprintf('ORIG_TRANS_AMT_%d', $i)]) ? $this->formatAmount($extra[\sprintf('ORIG_TRANS_AMT_%d', $i)]) : null, - 'capture_amount' => isset($extra[\sprintf('CAPTURE_AMT_%d', $i)]) ? $this->formatAmount($extra[\sprintf('CAPTURE_AMT_%d', $i)]) : null, - ]; - - - $recurringOrder['capture'] = $recurringOrder['first_amount'] === $recurringOrder['capture_amount']; - - return $this->mergeArraysPreferNonNullValues($this->getDefaultOrderHistoryTxResponse(), $recurringOrder); + return $transaction; } } diff --git a/src/Gateways/ParamPos.php b/src/Gateways/ParamPos.php index 2cae6344..3ccbdcf5 100644 --- a/src/Gateways/ParamPos.php +++ b/src/Gateways/ParamPos.php @@ -72,6 +72,18 @@ public function getAccount(): AbstractPosAccount return $this->account; } + /** + * @inheritDoc + */ + public function getApiURL(string $txType = null, string $paymentModel = null, ?string $orderTxType = null): string + { + if (PosInterface::MODEL_3D_HOST === $paymentModel) { + return $this->config['gateway_endpoints']['payment_api_2']; + } + + return parent::getApiURL($txType, $paymentModel, $orderTxType); + } + // todo /** * @inheritDoc @@ -251,8 +263,14 @@ protected function send($contents, string $txType, string $paymentModel, string $responseContent = $response->getBody()->getContents(); + dump('$url', $url); dump('$requestContent', $contents); dump('$responseContent', $responseContent); +// echo $responseContent; +// exit; + + + //dd($response->getStatusCode(), $responseContent); $decodedData = $this->serializer->decode($responseContent, $txType); @@ -319,6 +337,8 @@ private function registerPayment(array $order, string $paymentModel, string $txT $requestData, $txType, $paymentModel, + //'https://test-pos.param.com.tr/to.ws/Service_Odeme.asmx', + //'https://test-pos.param.com.tr/default.aspx' $this->getApiURL($txType, $paymentModel) ); } diff --git a/src/Serializer/ParamPosSerializer.php b/src/Serializer/ParamPosSerializer.php index 59b58294..7685cadc 100644 --- a/src/Serializer/ParamPosSerializer.php +++ b/src/Serializer/ParamPosSerializer.php @@ -37,20 +37,24 @@ public static function supports(string $gatewayClass): bool */ public function encode(array $data, ?string $txType = null) //todo { - $soapAction = \array_key_first($data); - // $data[$soapAction]['@xmlns'] = 'https://turkpos.com.tr/'; - //$data['@xmlns'] = 'https://turkpos.com.tr/'; - $wrapper = [ - '@xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - '@xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', - '@xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', - 'soap:Body' => $data, -// 'soap:Body' => [ -// $txType => $data, + +// $wrapper = [ +// '@xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', +// '@xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', +// '@xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/', +// 'soap:Header' => [ +// 'ServiceSecuritySoapHeader' => [ +// '@xmlns' => 'https://turkodeme.com.tr/', +// 'CLIENT_CODE' => '10738', +// 'CLIENT_USERNAME' => 'Test', +// 'CLIENT_PASSWORD' => 'Test', +// ], // ], - ]; +// 'soap:Body' => $data, +// ]; - return $this->serializer->encode($wrapper, XmlEncoder::FORMAT); + return $this->serializer->encode($data, XmlEncoder::FORMAT); + //return $this->serializer->encode($wrapper, XmlEncoder::FORMAT); } /** diff --git a/tests/Functional/ParamPosTest.php b/tests/Functional/ParamPosTest.php index e768c197..b06035fe 100644 --- a/tests/Functional/ParamPosTest.php +++ b/tests/Functional/ParamPosTest.php @@ -50,17 +50,14 @@ protected function setUp(): void $this->card = CreditCardFactory::createForGateway( $this->pos, - '5818775818772285', + '4508034508034509', '26', '12', - '001', + '000', 'John Doe' ); } - /** - * response tutarsiz, ara sira fail ediyor! - */ public function testNonSecurePaymentSuccess(): array { $order = $this->createPaymentOrder(PosInterface::MODEL_NON_SECURE); @@ -70,7 +67,7 @@ public function testNonSecurePaymentSuccess(): array function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; $this->assertSame(PosInterface::TX_TYPE_PAY_AUTH, $requestDataPreparedEvent->getTxType()); - $this->assertCount(1, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); } ); @@ -92,6 +89,93 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro return $this->pos->getResponse(); } + public function testNonSecurePaymentWithInstallment(): array + { + $order = $this->createPaymentOrder(PosInterface::MODEL_NON_SECURE); + $order['installment'] = 2; + + $this->pos->payment( + PosInterface::MODEL_NON_SECURE, + $order, + PosInterface::TX_TYPE_PAY_AUTH, + $this->card + ); + + $response = $this->pos->getResponse(); + + $this->assertTrue($this->pos->isSuccess(), $response['error_message'] ?? 'hata'); + + $this->assertIsArray($response); + $this->assertNotEmpty($response); + + return $this->pos->getResponse(); + } + + public function testNonSecurePrePaymentSuccess(): array + { + $order = $this->createPaymentOrder(PosInterface::MODEL_NON_SECURE); + + $this->eventDispatcher->addListener( + RequestDataPreparedEvent::class, + function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { + $eventIsThrown = true; + $this->assertSame(PosInterface::TX_TYPE_PAY_PRE_AUTH, $requestDataPreparedEvent->getTxType()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); + } + ); + + $this->pos->payment( + PosInterface::MODEL_NON_SECURE, + $order, + PosInterface::TX_TYPE_PAY_PRE_AUTH, + $this->card + ); + + $response = $this->pos->getResponse(); + + $this->assertTrue($this->pos->isSuccess(), $response['error_message'] ?? 'hata'); + + $this->assertIsArray($response); + $this->assertNotEmpty($response); + $this->assertTrue($eventIsThrown); + + return $this->pos->getResponse(); + } + + /** + * @depends testNonSecurePrePaymentSuccess + */ + public function testNonSecurePostPaymentSuccess(array $lastResponse): array + { + $order = $this->createPostPayOrder(\get_class($this->pos), $lastResponse); + + $this->eventDispatcher->addListener( + RequestDataPreparedEvent::class, + function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { + $eventIsThrown = true; + $this->assertSame(PosInterface::TX_TYPE_PAY_POST_AUTH, $requestDataPreparedEvent->getTxType()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); + } + ); + + $this->pos->payment( + PosInterface::MODEL_NON_SECURE, + $order, + PosInterface::TX_TYPE_PAY_POST_AUTH, + $this->card + ); + + $response = $this->pos->getResponse(); + + $this->assertTrue($this->pos->isSuccess(), $response['error_message'] ?? 'hata'); + + $this->assertIsArray($response); + $this->assertNotEmpty($response); + $this->assertTrue($eventIsThrown); + + return $this->pos->getResponse(); + } + /** * @depends testNonSecurePaymentSuccess */ @@ -105,7 +189,7 @@ public function testStatusSuccess(array $lastResponse): array function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; $this->assertSame(PosInterface::TX_TYPE_STATUS, $requestDataPreparedEvent->getTxType()); - $this->assertCount(6, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); } ); @@ -126,7 +210,7 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro */ public function testCancelSuccess(array $lastResponse): array { - $statusOrder = $this->createCancelOrder(\get_class($this->pos), $lastResponse); + $cancelOrder = $this->createCancelOrder(\get_class($this->pos), $lastResponse); $eventIsThrown = false; $this->eventDispatcher->addListener( @@ -134,11 +218,11 @@ public function testCancelSuccess(array $lastResponse): array function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; $this->assertSame(PosInterface::TX_TYPE_CANCEL, $requestDataPreparedEvent->getTxType()); - $this->assertCount(6, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); } ); - $this->pos->cancel($statusOrder); + $this->pos->cancel($cancelOrder); $this->assertTrue($this->pos->isSuccess()); $response = $this->pos->getResponse(); @@ -149,57 +233,105 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro return $lastResponse; } - /** - * @depends testCancelSuccess - */ - public function testOrderHistorySuccess(array $lastResponse): void + public function testCancelPrePay(): void { - $historyOrder = $this->createOrderHistoryOrder(\get_class($this->pos), $lastResponse); + $order = $this->createPaymentOrder(PosInterface::MODEL_NON_SECURE); + + $this->pos->payment( + PosInterface::MODEL_NON_SECURE, + $order, + PosInterface::TX_TYPE_PAY_PRE_AUTH, + $this->card + ); + + $lastResponse = $this->pos->getResponse(); + + $this->assertTrue($this->pos->isSuccess(), $response['error_message'] ?? 'hata'); + + $cancelOrder = $this->createCancelOrder(\get_class($this->pos), $lastResponse); + + $this->pos->cancel($cancelOrder); + + $this->assertTrue($this->pos->isSuccess()); + } + + public function testGet3DFormData(): void + { + $order = $this->createPaymentOrder(PosInterface::MODEL_3D_SECURE); $eventIsThrown = false; $this->eventDispatcher->addListener( RequestDataPreparedEvent::class, function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; - $this->assertSame(PosInterface::TX_TYPE_ORDER_HISTORY, $requestDataPreparedEvent->getTxType()); - $this->assertCount(9, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); + $this->assertSame(PosInterface::TX_TYPE_PAY_AUTH, $requestDataPreparedEvent->getTxType()); } ); + $formData = $this->pos->get3DFormData( + $order, + PosInterface::MODEL_3D_SECURE, + PosInterface::TX_TYPE_PAY_AUTH, + $this->card + ); - $this->pos->orderHistory($historyOrder); - - $this->assertTrue($this->pos->isSuccess()); - $response = $this->pos->getResponse(); - $this->assertIsArray($response); - $this->assertNotEmpty($response); + $this->assertIsString($formData); $this->assertTrue($eventIsThrown); } - public function testGet3DFormData(): void + public function testGet3DFormDataForeignCurrency(): void { $order = $this->createPaymentOrder(PosInterface::MODEL_3D_SECURE); + $order['currency'] = PosInterface::CURRENCY_USD; $eventIsThrown = false; $this->eventDispatcher->addListener( RequestDataPreparedEvent::class, function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; - $this->assertCount(18, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); $this->assertSame(PosInterface::TX_TYPE_PAY_AUTH, $requestDataPreparedEvent->getTxType()); } ); $formData = $this->pos->get3DFormData( $order, - PosInterface::MODEL_3D_PAY, + PosInterface::MODEL_3D_SECURE, PosInterface::TX_TYPE_PAY_AUTH, $this->card ); - $this->assertIsString($formData); + $this->assertIsArray($formData); + $this->assertNotEmpty($formData['gateway']); + $this->assertTrue($eventIsThrown); + } + + public function testGet3DHostFormData(): void + { + $order = $this->createPaymentOrder(PosInterface::MODEL_3D_HOST); + + $eventIsThrown = false; + $this->eventDispatcher->addListener( + RequestDataPreparedEvent::class, + function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { + $eventIsThrown = true; + $this->assertCount(5, $requestDataPreparedEvent->getRequestData()); + $this->assertSame(PosInterface::TX_TYPE_PAY_AUTH, $requestDataPreparedEvent->getTxType()); + } + ); + $formData = $this->pos->get3DFormData( + $order, + PosInterface::MODEL_3D_HOST, + PosInterface::TX_TYPE_PAY_AUTH, + $this->card + ); + + $this->assertIsArray($formData); + $this->assertArrayHasKey('inputs', $formData); + $this->assertNotEmpty($formData['inputs']); $this->assertTrue($eventIsThrown); } - public function testPartialRefundSuccess(): array + public function testRefundSuccess(): array { $order = $this->createPaymentOrder(PosInterface::MODEL_NON_SECURE); @@ -214,16 +346,15 @@ public function testPartialRefundSuccess(): array $lastResponse = $this->pos->getResponse(); - $refundOrder = $this->createRefundOrder(\get_class($this->pos), $lastResponse); - $refundOrder['amount'] = 0.59; + $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_PARTIAL, $requestDataPreparedEvent->getTxType()); - $this->assertCount(7, $requestDataPreparedEvent->getRequestData()); + $this->assertSame(PosInterface::TX_TYPE_REFUND, $requestDataPreparedEvent->getTxType()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); } ); @@ -241,7 +372,9 @@ function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThro public function testCustomQuery(): void { $customQuery = [ - 'bin' => 415956, + 'TP_Ozel_Oran_Liste' => [ + '@xmlns' => 'https://turkpos.com.tr/', + ], ]; $eventIsThrown = false; @@ -250,16 +383,18 @@ public function testCustomQuery(): void function (RequestDataPreparedEvent $requestDataPreparedEvent) use (&$eventIsThrown): void { $eventIsThrown = true; $this->assertSame(PosInterface::TX_TYPE_CUSTOM_QUERY, $requestDataPreparedEvent->getTxType()); - $this->assertCount(6, $requestDataPreparedEvent->getRequestData()); + $this->assertCount(4, $requestDataPreparedEvent->getRequestData()); } ); - $this->pos->customQuery($customQuery, 'https://prepentegrasyon.tosla.com/api/Payment/GetCommissionAndInstallmentInfo'); + $this->pos->customQuery($customQuery); $response = $this->pos->getResponse(); $this->assertIsArray($response); $this->assertNotEmpty($response); - $this->assertArrayHasKey('BankCode', $response); + $this->assertArrayHasKey('TP_Ozel_Oran_ListeResponse', $response); + $this->assertArrayHasKey('TP_Ozel_Oran_ListeResult', $response['TP_Ozel_Oran_ListeResponse']); + $this->assertArrayHasKey('DT_Bilgi', $response['TP_Ozel_Oran_ListeResponse']['TP_Ozel_Oran_ListeResult']); $this->assertTrue($eventIsThrown); } } diff --git a/tests/Functional/PaymentTestTrait.php b/tests/Functional/PaymentTestTrait.php index f40bfdd1..3f215f58 100644 --- a/tests/Functional/PaymentTestTrait.php +++ b/tests/Functional/PaymentTestTrait.php @@ -153,6 +153,10 @@ public function createCancelOrder(string $gatewayClass, array $lastResponse): ar if (\Mews\Pos\Gateways\GarantiPos::class === $gatewayClass) { $cancelOrder['amount'] = $lastResponse['amount']; + } elseif (\Mews\Pos\Gateways\ParamPos::class === $gatewayClass) { + $cancelOrder['amount'] = $lastResponse['amount']; + // on otorizasyon islemin iptali icin PosInterface::TX_TYPE_PAY_PRE_AUTH saglanmasi gerekiyor + $cancelOrder['transaction_type'] = $lastResponse['transaction_type'] ?? PosInterface::TX_TYPE_PAY_AUTH; } elseif (\Mews\Pos\Gateways\KuveytPos::class === $gatewayClass) { $cancelOrder['remote_order_id'] = $lastResponse['remote_order_id']; // banka tarafındaki order id $cancelOrder['auth_code'] = $lastResponse['auth_code']; diff --git a/tests/Unit/DataMapper/RequestDataMapper/ParamPosRequestDataMapperTest.php b/tests/Unit/DataMapper/RequestDataMapper/ParamPosRequestDataMapperTest.php index c1464016..359ebaf1 100644 --- a/tests/Unit/DataMapper/RequestDataMapper/ParamPosRequestDataMapperTest.php +++ b/tests/Unit/DataMapper/RequestDataMapper/ParamPosRequestDataMapperTest.php @@ -592,6 +592,17 @@ public static function orderHistoryRequestDataProvider(): array public static function threeDFormDataProvider(): array { + $threedHostFailData = [ + "TO_Pre_Encrypting_OOSResponse" => [ + "TO_Pre_Encrypting_OOSResult" => "SOAP Güvenlik Hatası.192.168.190.2", + ], + ]; + + $threedHostSuccessData = [ + "TO_Pre_Encrypting_OOSResponse" => [ + "TO_Pre_Encrypting_OOSResult" => "JHnDLmT5yierHIqsHNRU2SR7HLxOpi8o7Eb/oVSiIf35v+Z1uzteqid4wop8SAuykWNFElYyAxGWcIGvTxmhSljuLTcJ3xDMkS3O0jUboNpl5ad6roy/92lDftpV535KmpbxMxStRa+qGT7Tk4BdEIf+Jobr2o1Yl1+ZakWZ+parsTgnodyWl432Hsv2FUNLhuU7H6folMwleaZFPYdFZ+bO1T95opw5pnDWcFkrIuPfAmVRg4cg+al22FQSN/58AXxWBb8jEPrqn+/ojZ+WqncGvw+NB/Mtv9iCDuF+SNQqRig2dRILzWYwcvNxzj/OxcYuNuvO8wYI/iF1kNBBNtaExIunWZyj1tntGeb7UUaDmHD4LmSMUMpgZGugRfUpxm8WL/EE+PnUkLXE7SOG3g==", + ], + ]; return [ '3d_host_form_data' => [ 'order' => [], diff --git a/tests/Unit/DataMapper/ResponseDataMapper/ParamPosResponseDataMapperTest.php b/tests/Unit/DataMapper/ResponseDataMapper/ParamPosResponseDataMapperTest.php index f4e93e21..836333d9 100644 --- a/tests/Unit/DataMapper/ResponseDataMapper/ParamPosResponseDataMapperTest.php +++ b/tests/Unit/DataMapper/ResponseDataMapper/ParamPosResponseDataMapperTest.php @@ -135,26 +135,14 @@ public function testMap3DPaymentData(array $order, string $txType, array $threeD $this->assertSame($expectedData, $actualData); } - /** - * @dataProvider threeDPayPaymentDataProvider - */ - public function testMap3DPayResponseData(array $order, string $txType, array $responseData, array $expectedData): void + public function testMap3DPayResponseData(): void { - $actualData = $this->responseDataMapper->map3DPayResponseData($responseData, $txType, $order); - $this->assertEquals($expectedData['transaction_time'], $actualData['transaction_time']); - unset($actualData['transaction_time'], $expectedData['transaction_time']); - - $this->assertArrayHasKey('all', $actualData); - $this->assertIsArray($actualData['all']); - $this->assertNotEmpty($actualData['all']); - unset($actualData['all']); - - \ksort($expectedData); - \ksort($actualData); - $this->assertSame($expectedData, $actualData); + $this->expectException(NotImplementedException::class); + $this->responseDataMapper->map3DPayResponseData([], PosInterface::TX_TYPE_PAY_AUTH, []); } /** + * todo * @dataProvider threeDHostPaymentDataProvider */ public function testMap3DHostResponseData(array $order, string $txType, array $responseData, array $expectedData): void @@ -184,15 +172,15 @@ public function testMap3DHostResponseData(array $order, string $txType, array $r public function testMapStatusResponse(array $responseData, array $expectedData): void { $actualData = $this->responseDataMapper->mapStatusResponse($responseData); - -// $this->assertEquals($expectedData['transaction_time'], $actualData['transaction_time']); -// $this->assertEquals($expectedData['capture_time'], $actualData['capture_time']); -// $this->assertEquals($expectedData['refund_time'], $actualData['refund_time']); -// $this->assertEquals($expectedData['cancel_time'], $actualData['cancel_time']); -// unset($actualData['transaction_time'], $expectedData['transaction_time']); -// unset($actualData['capture_time'], $expectedData['capture_time']); -// unset($actualData['cancel_time'], $expectedData['cancel_time']); -// unset($actualData['refund_time'], $expectedData['refund_time']); + dump($actualData); + $this->assertEquals($expectedData['transaction_time'], $actualData['transaction_time']); + $this->assertEquals($expectedData['capture_time'], $actualData['capture_time']); + $this->assertEquals($expectedData['refund_time'], $actualData['refund_time']); + $this->assertEquals($expectedData['cancel_time'], $actualData['cancel_time']); + unset($actualData['transaction_time'], $expectedData['transaction_time']); + unset($actualData['capture_time'], $expectedData['capture_time']); + unset($actualData['cancel_time'], $expectedData['cancel_time']); + unset($actualData['refund_time'], $expectedData['refund_time']); $this->assertArrayHasKey('all', $actualData); $this->assertIsArray($actualData['all']); @@ -235,50 +223,55 @@ public function testMapCancelResponse(array $responseData, array $expectedData): $this->assertSame($expectedData, $actualData); } + public function testMapOrderHistoryResponse(): void + { + $this->expectException(NotImplementedException::class); + $this->responseDataMapper->mapOrderHistoryResponse([]); + } + /** - * @dataProvider orderHistoryTestDataProvider + * @dataProvider historyTestDataProvider */ - public function testMapOrderHistoryResponse(array $responseData, array $expectedData): void + public function testMapHistoryResponse(array $responseData, array $expectedData): void { - $actualData = $this->responseDataMapper->mapOrderHistoryResponse($responseData); - if (count($responseData['Extra']) > 0) { - 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'], - ); - } + // todo delete + error_reporting(E_ALL); + ini_set('display_errors', '1'); - foreach (array_keys($actualData['transactions']) as $key) { - $this->assertEquals($expectedData['transactions'][$key]['transaction_time'], $actualData['transactions'][$key]['transaction_time']); - $this->assertEquals($expectedData['transactions'][$key]['capture_time'], $actualData['transactions'][$key]['capture_time']); - unset($actualData['transactions'][$key]['transaction_time'], $expectedData['transactions'][$key]['transaction_time']); - \ksort($actualData['transactions'][$key]); - \ksort($expectedData['transactions'][$key]); - } + $actualData = $this->responseDataMapper->mapHistoryResponse($responseData); - $this->assertCount($actualData['trans_count'], $actualData['transactions']); + 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']); $this->assertArrayHasKey('all', $actualData); $this->assertIsArray($actualData['all']); $this->assertNotEmpty($actualData['all']); unset($actualData['all']); - \ksort($expectedData); - \ksort($actualData); $this->assertSame($expectedData, $actualData); } - public function testMapHistoryResponse(): void - { - $this->expectException(NotImplementedException::class); - $this->responseDataMapper->mapHistoryResponse([]); - } - public static function paymentTestDataProvider(): iterable { yield 'success1' => [ @@ -396,12 +389,12 @@ public static function paymentTestDataProvider(): iterable 'Prov_ID' => 'f7184b1f-c4c2-4d2e-8428-fc6014a00900', 'Dekont_ID' => '6004466311', 'Banka_Sonuc_Kod' => '0', - 'Siparis_ID' => '20250105CB05', - 'Bank_Trans_ID' => '25005RvnD11226', - 'Bank_AuthCode' => '519104', + 'Siparis_ID' => '20250105CB05', + 'Bank_Trans_ID' => '25005RvnD11226', + 'Bank_AuthCode' => '519104', 'Bank_HostRefNum' => '500517472728', - 'Bank_Extra' => 'bank-data', - 'Bank_HostMsg' => null, + 'Bank_Extra' => 'bank-data', + 'Bank_HostMsg' => null, ], ], ], @@ -533,28 +526,28 @@ public static function threeDPaymentDataProvider(): array 'transaction_time' => new \DateTimeImmutable(), ], ], - 'success_foreign_currency_payment' => [ + 'success_foreign_currency_payment' => [ 'order' => [ ], 'txType' => PosInterface::TX_TYPE_PAY_AUTH, 'threeDResponseData' => [], 'paymentData' => [ - "TURKPOS_RETVAL_Islem_ID" => "25B4E0BAAD1F3FC05D46F5B4", - "TURKPOS_RETVAL_Sonuc" => "1", - "TURKPOS_RETVAL_Sonuc_Str" => "Odeme Islemi Basarili", - "TURKPOS_RETVAL_GUID" => "0c13d406-873b-403b-9c09-a5766840d98c", - "TURKPOS_RETVAL_Islem_Tarih" => "5.01.2025 14:52:20", - "TURKPOS_RETVAL_Dekont_ID" => "3007296668", - "TURKPOS_RETVAL_Tahsilat_Tutari" => "10,01", - "TURKPOS_RETVAL_Odeme_Tutari" => "9,83", - "TURKPOS_RETVAL_Siparis_ID" => "202501053F4F", - "TURKPOS_RETVAL_Ext_Data" => "||||", - "TURKPOS_RETVAL_Banka_Sonuc_Kod" => "0", - "TURKPOS_RETVAL_PB" => "USD", - "TURKPOS_RETVAL_KK_No" => "581877******2285", - "TURKPOS_RETVAL_Taksit" => "0", - "TURKPOS_RETVAL_Hash" => "LrFgOcE6S8HzNF4tzvtORAh3C20=", - "TURKPOS_RETVAL_Islem_GUID" => "597b2fc9-df6d-40d7-861a-c4f5d0e94ed3", + "TURKPOS_RETVAL_Islem_ID" => "25B4E0BAAD1F3FC05D46F5B4", + "TURKPOS_RETVAL_Sonuc" => "1", + "TURKPOS_RETVAL_Sonuc_Str" => "Odeme Islemi Basarili", + "TURKPOS_RETVAL_GUID" => "0c13d406-873b-403b-9c09-a5766840d98c", + "TURKPOS_RETVAL_Islem_Tarih" => "5.01.2025 14:52:20", + "TURKPOS_RETVAL_Dekont_ID" => "3007296668", + "TURKPOS_RETVAL_Tahsilat_Tutari" => "10,01", + "TURKPOS_RETVAL_Odeme_Tutari" => "9,83", + "TURKPOS_RETVAL_Siparis_ID" => "202501053F4F", + "TURKPOS_RETVAL_Ext_Data" => "||||", + "TURKPOS_RETVAL_Banka_Sonuc_Kod" => "0", + "TURKPOS_RETVAL_PB" => "USD", + "TURKPOS_RETVAL_KK_No" => "581877******2285", + "TURKPOS_RETVAL_Taksit" => "0", + "TURKPOS_RETVAL_Hash" => "LrFgOcE6S8HzNF4tzvtORAh3C20=", + "TURKPOS_RETVAL_Islem_GUID" => "597b2fc9-df6d-40d7-861a-c4f5d0e94ed3", "TURKPOS_RETVAL_SanalPOS_Islem_ID" => "6021842602", ], 'expectedData' => [ @@ -717,281 +710,6 @@ public static function threeDPaymentDataProvider(): array 'transaction_time' => null, ], ], - '3d_auth_success_payment_fail_wong_cvv' => [ - 'order' => [ - 'currency' => PosInterface::CURRENCY_TRY, - 'amount' => 1.01, - ], - 'txType' => PosInterface::TX_TYPE_PAY_AUTH, - 'threeDResponseData' => [ - 'TRANID' => '', - 'PAResSyntaxOK' => 'true', - 'firmaadi' => 'John Doe', - 'islemtipi' => 'Auth', - 'lang' => 'tr', - 'merchantID' => '190100000', - 'maskedCreditCard' => '4355 08** **** 4358', - 'amount' => '1.01', - 'sID' => '1', - 'ACQBIN' => '454672', - 'Ecom_Payment_Card_ExpDate_Year' => '26', - 'Email' => 'mail@customer.com', - 'MaskedPan' => '435508***4358', - 'merchantName' => 'Ziraat 3D', - 'clientIp' => '89.244.149.137', - 'okUrl' => 'http://localhost/akbank/3d/response.php', - 'md' => '435508:9716234382F9D9B630CC01452A6F160D31A2E1DBD41706C6AF8B8E6F730FE65D:3677:##190100000', - 'taksit' => '12', - 'Ecom_Payment_Card_ExpDate_Month' => '12', - 'storetype' => '3d', - 'mdErrorMsg' => 'Y-status/Challenge authentication via ACS: https://3ds-acs.test.modirum.com/mdpayacs/creq?token=214704701.1667119495.sIHzA7ckv-0', - 'PAResVerified' => 'true', - 'cavv' => 'ABABA##################AEJI=', - 'digest' => 'digest', - 'callbackCall' => 'true', - 'failUrl' => 'http://localhost/akbank/3d/response.php', - 'xid' => '2aeoSfQde3NyV2XjSeTL0sGNYSg=', - 'encoding' => 'ISO-8859-9', - 'currency' => '949', - 'oid' => '20221030FE4C', - 'mdStatus' => '1', - 'dsId' => '1', - 'eci' => '05', - 'version' => '2.0', - 'clientid' => '190100000', - 'txstatus' => 'Y', - 'HASH' => '+NYQKADaaWWUIAIg6U77nGIK+8k=', - 'rnd' => 'IXa1XnlaOxpMCacqG/cB', - 'HASHPARAMS' => 'clientid:oid:mdStatus:cavv:eci:md:rnd:', - 'HASHPARAMSVAL' => '19010000020221030FE4C1ABABA##################AEJI=05435508:9716234382F9D9B630CC01452A6F160D31A2E1DBD41706C6AF8B8E6F730FE65D:3677:##190100000IXa1XnlaOxpMCacqG/cB', - ], - 'paymentData' => [ - 'OrderId' => '4c4', - 'GroupId' => '4aa841c4', - 'Response' => 'Declined', - 'HostRefNum' => '4139489', - 'ProcReturnCode' => '82', - 'TransId' => '24138rt2596', - 'ErrMsg' => 'CVV Hatasi veya girilen CVV gecersiz.', - 'Extra' => [ - 'KULLANILANPUAN' => '000000000000', - 'CARDBRAND' => 'VISA', - 'CARDISSUER' => 'ZİRAAT BANKASI', - 'ERRORCODE' => 'ISO8583-82', - 'TRXDATE' => '20240517 13:17:31', - 'KULLANILABILIRPUAN' => '000000000000', - 'ACQSTAN' => '769489', - 'KAZANILANPUAN' => '000000000105', - 'TRACEID' => '2c4e0abd4560418ace038267fa57f5c9', - 'NUMCODE' => '82', - ], - ], - 'expectedData' => [ - 'transaction_id' => '24138rt2596', - 'transaction_type' => 'pay', - 'transaction_time' => null, - 'transaction_security' => 'Full 3D Secure', - 'md_status' => '1', - 'masked_number' => '4355 08** **** 4358', - 'month' => '12', - 'year' => '26', - 'amount' => 1.01, - 'currency' => PosInterface::CURRENCY_TRY, - 'eci' => '05', - 'tx_status' => null, - 'cavv' => 'ABABA##################AEJI=', - 'md_error_message' => null, - 'group_id' => '4aa841c4', - 'auth_code' => null, - 'ref_ret_num' => '4139489', - 'batch_num' => null, - 'proc_return_code' => '82', - 'status' => 'declined', - 'status_detail' => null, - 'error_code' => 'ISO8583-82', - 'error_message' => 'CVV Hatasi veya girilen CVV gecersiz.', - 'recurring_id' => null, - 'installment_count' => 12, - 'order_id' => '4c4', - 'payment_model' => '3d', - ], - ], - ]; - } - - - public static function threeDPayPaymentDataProvider(): array - { - return [ - 'success1' => [ - 'order' => [ - 'currency' => PosInterface::CURRENCY_TRY, - 'amount' => 1.01, - ], - 'txType' => PosInterface::TX_TYPE_PAY_AUTH, - 'paymentData' => [ - 'ReturnOid' => '2022103030CB', - 'TRANID' => '', - 'EXTRA_MERCHANTID' => '655000200', - 'PAResSyntaxOK' => 'true', - 'EXTRA_HOSTDATE' => '1030-112244', - 'firmaadi' => 'John Doe', - 'islemtipi' => 'Auth', - 'EXTRA_TERMINALID' => '00655020', - 'lang' => 'tr', - 'merchantID' => '700655000200', - 'maskedCreditCard' => '4355 08** **** 4358', - 'amount' => '1.01', - 'sID' => '1', - 'ACQBIN' => '406456', - 'Ecom_Payment_Card_ExpDate_Year' => '26', - 'EXTRA_CARDBRAND' => 'VISA', - 'Email' => 'mail@customer.com', - 'MaskedPan' => '435508***4358', - 'acqStan' => '671764', - 'merchantName' => 'İşbank 3d_pay Store', - 'clientIp' => '89.244.149.137', - 'okUrl' => 'http://localhost/akbank/3d-pay/response.php', - 'md' => '435508:EC9CDC37975501A4B29BBD5BE1580279238BF88D888B23E7ECC293581C75EE40:4333:##700655000200', - 'ProcReturnCode' => '00', - 'payResults_dsId' => '1', - 'taksit' => '', - 'TransId' => '22303LWsA14386', - 'EXTRA_TRXDATE' => '20221030 11:22:43', - 'Ecom_Payment_Card_ExpDate_Month' => '12', - 'storetype' => '3d_pay', - 'Response' => 'Approved', - 'SettleId' => '2287', - 'mdErrorMsg' => 'Y-status/Challenge authentication via ACS: https://3ds-acs.test.modirum.com/mdpayacs/creq?token=214704511.1667118159.BUW_iXHm4_6', - 'ErrMsg' => '', - 'PAResVerified' => 'true', - 'cavv' => 'ABABByBkEgAAAABllJMDdVWUGZE=', - 'EXTRA_AVSERRORCODEDETAIL' => 'avshatali-avshatali-avshatali-avshatali-', - 'digest' => 'digest', - 'HostRefNum' => '230300671764', - 'callbackCall' => 'true', - 'AuthCode' => 'P37891', - 'failUrl' => 'http://localhost/akbank/3d-pay/response.php', - 'xid' => 'xyxZZ/eJ3eVDkqYiDOdwPfCkq5U=', - 'encoding' => 'ISO-8859-9', - 'currency' => '949', - 'oid' => '2022103030CB', - 'mdStatus' => '1', - 'dsId' => '1', - 'EXTRA_AVSAPPROVE' => 'Y', - 'eci' => '05', - 'version' => '2.0', - 'EXTRA_CARDISSUER' => 'AKBANK T.A.S.', - 'clientid' => '700655000200', - 'txstatus' => 'Y', - 'HASH' => 'FQLnGOxBBMIoMIRxehiaLtkEd34=', - 'rnd' => 'kP/2JB5ajHJt+yVhHNG9', - 'HASHPARAMS' => 'clientid:oid:AuthCode:ProcReturnCode:Response:mdStatus:cavv:eci:md:rnd:', - 'HASHPARAMSVAL' => '7006550002002022103030CBP3789100Approved1ABABByBkEgAAAABllJMDdVWUGZE=05435508:EC9CDC37975501A4B29BBD5BE1580279238BF88D888B23E7ECC293581C75EE40:4333:##700655000200kP/2JB5ajHJt+yVhHNG9', - 'NATIONALIDNO' => '', - ], - 'expectedData' => [ - 'transaction_id' => '22303LWsA14386', - 'transaction_type' => 'pay', - 'transaction_time' => new \DateTimeImmutable('2022-10-30 11:22:43'), - 'transaction_security' => 'Full 3D Secure', - 'md_status' => '1', - 'masked_number' => '4355 08** **** 4358', - 'month' => '12', - 'year' => '26', - 'amount' => 1.01, - 'currency' => PosInterface::CURRENCY_TRY, - 'tx_status' => null, - 'eci' => '05', - 'cavv' => 'ABABByBkEgAAAABllJMDdVWUGZE=', - 'md_error_message' => 'Y-status/Challenge authentication via ACS: https://3ds-acs.test.modirum.com/mdpayacs/creq?token=214704511.1667118159.BUW_iXHm4_6', - 'order_id' => '2022103030CB', - 'auth_code' => 'P37891', - 'ref_ret_num' => '230300671764', - 'batch_num' => null, - 'proc_return_code' => '00', - 'status' => 'approved', - 'status_detail' => 'approved', - 'error_code' => null, - 'error_message' => null, - 'payment_model' => '3d_pay', - 'installment_count' => 0, - ], - ], - 'authFail1' => [ - 'order' => [ - 'currency' => PosInterface::CURRENCY_TRY, - 'amount' => 1.01, - ], - 'txType' => PosInterface::TX_TYPE_PAY_AUTH, - 'paymentData' => [ - 'sID' => '1', - 'oid' => '2022103008A3', - 'encoding' => 'ISO-8859-9', - 'Ecom_Payment_Card_ExpDate_Month' => '12', - 'version' => '2.0', - 'currency' => '949', - 'dsId' => '1', - 'callbackCall' => 'true', - 'amount' => '1.01', - 'maskedCreditCard' => '4355 08** **** 4358', - 'islemtipi' => 'Auth', - 'firmaadi' => 'John Doe', - 'merchantName' => 'İşbank 3d_pay Store', - 'ACQBIN' => '406456', - 'PAResSyntaxOK' => 'true', - 'Ecom_Payment_Card_ExpDate_Year' => '26', - 'storetype' => '3d_pay', - 'mdStatus' => '0', - 'failUrl' => 'http://localhost/akbank/3d-pay/response.php', - 'clientIp' => '89.244.149.137', - 'merchantID' => '700655000200', - 'mdErrorMsg' => 'N-status/Challenge authentication via ACS: https://3ds-acs.test.modirum.com/mdpayacs/creq?token=214704541.1667118445.QQ1EjzXz8nm', - 'clientid' => '700655000200', - 'MaskedPan' => '435508***4358', - 'txstatus' => 'N', - 'digest' => 'digest', - 'PAResVerified' => 'true', - 'Email' => 'mail@customer.com', - 'taksit' => '', - 'okUrl' => 'http://localhost/akbank/3d-pay/response.php', - 'md' => '435508:44868DF53C03B6FFC4479AF5C897CC86F10D7D3D6C20859EA77277B0E954125F:4320:##700655000200', - 'lang' => 'tr', - 'xid' => 'jDiMogllA6etX+EvmM+zG+VMvo4=', - 'TRANID' => '', - 'HASH' => 'mbWDXpM1SQfYIEJ5M1KfP/hOE18=', - 'rnd' => 'I6wQZkKfEnDG1myeLBlt', - 'HASHPARAMS' => 'clientid:oid:mdStatus:cavv:eci:md:rnd:', - 'HASHPARAMSVAL' => '7006550002002022103008A30435508:44868DF53C03B6FFC4479AF5C897CC86F10D7D3D6C20859EA77277B0E954125F:4320:##700655000200I6wQZkKfEnDG1myeLBlt', - ], - 'expectedData' => [ - 'transaction_id' => null, - 'transaction_type' => 'pay', - 'transaction_time' => null, - 'transaction_security' => 'MPI fallback', - 'auth_code' => null, - 'ref_ret_num' => null, - 'batch_num' => null, - 'status_detail' => null, - 'error_code' => null, - 'error_message' => null, - 'md_status' => '0', - 'masked_number' => '4355 08** **** 4358', - 'month' => '12', - 'year' => '26', - 'amount' => 1.01, - 'currency' => PosInterface::CURRENCY_TRY, - 'tx_status' => null, - 'eci' => null, - 'cavv' => null, - 'md_error_message' => 'N-status/Challenge authentication via ACS: https://3ds-acs.test.modirum.com/mdpayacs/creq?token=214704541.1667118445.QQ1EjzXz8nm', - 'order_id' => '2022103008A3', - 'proc_return_code' => null, - 'status' => 'declined', - 'payment_model' => '3d_pay', - 'installment_count' => 0, - ], - ], ]; } @@ -1246,25 +964,24 @@ public static function statusTestDataProvider(): iterable ], ], 'expectedData' => [ - 'order_id' => '20221030FAC5', - 'auth_code' => 'P90325', - 'proc_return_code' => '00', - 'transaction_id' => '22303Md4C19254', + 'order_id' => '20250105E324', + 'auth_code' => '222905', + 'proc_return_code' => 1, + 'transaction_id' => '25005NOgE12061', 'error_message' => null, - 'ref_ret_num' => '230300671782', + 'ref_ret_num' => '500513472717', 'order_status' => 'PAYMENT_COMPLETED', 'transaction_type' => 'pay', - 'masked_number' => '4355 08** **** 4358', - 'num_code' => '0', - 'first_amount' => 1.01, - 'capture_amount' => null, + 'masked_number' => '581877******2285', + 'first_amount' => 10.01, + 'capture_amount' => 10.01, 'currency' => null, 'status' => 'approved', 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => false, - 'transaction_time' => new \DateTimeImmutable('2022-10-30 12:29:53.773'), - 'capture_time' => null, + 'status_detail' => null, + 'capture' => true, + 'transaction_time' => new \DateTimeImmutable('05.01.2025 13:14:32'), + 'capture_time' => new \DateTimeImmutable('05.01.2025 13:14:32'), 'cancel_time' => null, 'refund_amount' => null, 'refund_time' => null, @@ -1276,25 +993,24 @@ public static function statusTestDataProvider(): iterable yield 'success_pay_then_refund' => [ 'responseData' => $responseData, 'expectedData' => [ - 'order_id' => '20221030FAC5', - 'auth_code' => 'P90325', - 'proc_return_code' => '00', - 'transaction_id' => '22303Md4C19254', + 'order_id' => '20250105E324', + 'auth_code' => '222905', + 'proc_return_code' => 1, + 'transaction_id' => '25005NOgE12061', 'error_message' => null, - 'ref_ret_num' => '230300671782', + 'ref_ret_num' => '500513472717', 'order_status' => 'FULLY_REFUNDED', 'transaction_type' => 'pay', - 'masked_number' => '4355 08** **** 4358', - 'num_code' => '0', - 'first_amount' => 1.01, - 'capture_amount' => null, + 'masked_number' => '581877******2285', + 'first_amount' => 10.01, + 'capture_amount' => 10.01, 'currency' => null, 'status' => 'approved', 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => false, - 'transaction_time' => new \DateTimeImmutable('2022-10-30 12:29:53.773'), - 'capture_time' => null, + 'status_detail' => null, + 'capture' => true, + 'transaction_time' => new \DateTimeImmutable('05.01.2025 13:14:32'), + 'capture_time' => new \DateTimeImmutable('05.01.2025 13:14:32'), 'cancel_time' => null, 'refund_amount' => null, 'refund_time' => null, @@ -1306,26 +1022,25 @@ public static function statusTestDataProvider(): iterable yield 'success_pay_then_canceled' => [ 'responseData' => $responseData, 'expectedData' => [ - 'order_id' => '20221030FAC5', - 'auth_code' => 'P90325', - 'proc_return_code' => '00', - 'transaction_id' => '22303Md4C19254', + 'order_id' => '2025011251F7', + 'auth_code' => '609945', + 'proc_return_code' => 1, + 'transaction_id' => '25012UZnE17558', 'error_message' => null, - 'ref_ret_num' => '230300671782', + 'ref_ret_num' => '501220476656', 'order_status' => 'CANCELED', 'transaction_type' => 'pay', - 'masked_number' => '4355 08** **** 4358', - 'num_code' => '0', - 'first_amount' => 1.01, - 'capture_amount' => null, + 'masked_number' => '581877******2285', + 'first_amount' => 10.01, + 'capture_amount' => 10.01, 'currency' => null, 'status' => 'approved', 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => false, - 'transaction_time' => new \DateTimeImmutable('2022-10-30 12:29:53.773'), - 'capture_time' => null, - 'cancel_time' => null, + 'status_detail' => null, + 'capture' => true, + 'transaction_time' => new \DateTimeImmutable('12.01.2025 20:25:38'), + 'capture_time' => new \DateTimeImmutable('12.01.2025 20:25:38'), + 'cancel_time' => new \DateTimeImmutable('12.01.2025 20:25:38'), 'refund_amount' => null, 'refund_time' => null, 'installment_count' => null, @@ -1336,24 +1051,23 @@ public static function statusTestDataProvider(): iterable yield 'success_pre_pay' => [ 'responseData' => $responseData, 'expectedData' => [ - 'order_id' => '20221030FAC5', - 'auth_code' => 'P90325', - 'proc_return_code' => '00', - 'transaction_id' => '22303Md4C19254', + 'order_id' => '20250105F546', + 'auth_code' => '308452', + 'proc_return_code' => 1, + 'transaction_id' => '25005QOSI13750', 'error_message' => null, - 'ref_ret_num' => '230300671782', + 'ref_ret_num' => '500516472750', 'order_status' => PosInterface::PAYMENT_STATUS_PRE_AUTH_COMPLETED, 'transaction_type' => 'pre', - 'masked_number' => '4355 08** **** 4358', - 'num_code' => '0', - 'first_amount' => 1.01, + 'masked_number' => '581877******2285', + 'first_amount' => 10.01, 'capture_amount' => null, 'currency' => null, 'status' => 'approved', 'error_code' => null, - 'status_detail' => 'approved', + 'status_detail' => null, 'capture' => false, - 'transaction_time' => new \DateTimeImmutable('2022-10-30 12:29:53.773'), + 'transaction_time' => new \DateTimeImmutable('05.01.2025 16:14:18'), 'capture_time' => null, 'cancel_time' => null, 'refund_amount' => null, @@ -1420,354 +1134,6 @@ public static function statusTestDataProvider(): iterable 'installment_count' => null, ], ]; - - yield 'fail1' => [ - 'responseData' => [ - 'ErrMsg' => 'No record found for 2022103088D22', - 'ProcReturnCode' => '99', - 'Response' => 'Declined', - 'OrderId' => '', - 'TransId' => '', - 'Extra' => [ - 'NUMCODE' => '0', - 'ORDERSTATUS' => "ORD_ID:\tCHARGE_TYPE_CD:\tORIG_TRANS_AMT:\tCAPTURE_AMT:\tTRANS_STAT:\tAUTH_DTTM:\tCAPTURE_DTTM:\tAUTH_CODE:", - ], - ], - 'expectedData' => [ - 'order_id' => null, - 'auth_code' => null, - 'proc_return_code' => '99', - 'transaction_id' => null, - 'error_message' => 'No record found for 2022103088D22', - 'ref_ret_num' => null, - 'order_status' => null, - 'transaction_type' => null, - 'masked_number' => null, - 'first_amount' => null, - 'capture_amount' => null, - 'status' => 'declined', - 'error_code' => null, - 'status_detail' => 'general_error', - 'capture' => null, - 'transaction_time' => null, - 'capture_time' => null, - 'currency' => null, - 'cancel_time' => null, - 'refund_amount' => null, - 'refund_time' => null, - 'installment_count' => null, - ], - ]; - yield 'pay_order_status' => [ - 'responseData' => [ - 'ErrMsg' => 'Record(s) found for 2024010354F1', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '2024010354F1', - 'TransId' => '24003Vl7F13152', - 'Extra' => [ - 'AUTH_CODE' => 'P77974', - 'AUTH_DTTM' => '2024-01-03 21:37:57.259', - 'CAPTURE_AMT' => '101', - 'CAPTURE_DTTM' => '2024-01-03 21:37:57.259', - 'CAVV_3D' => '', - 'CHARGE_TYPE_CD' => 'S', - 'ECI_3D' => '', - 'HOSTDATE' => '0103-213757', - 'HOST_REF_NUM' => '400300744233', - 'MDSTATUS' => '', - 'NUMCODE' => '0', - 'ORDERSTATUS' => "ORD_ID:2024010354F1\tCHARGE_TYPE_CD:S\tORIG_TRANS_AMT:101\tCAPTURE_AMT:101\tTRANS_STAT:C\tAUTH_DTTM:2024-01-03 21:37:57.259\tCAPTURE_DTTM:2024-01-03 21:37:57.259\tAUTH_CODE:P77974\tTRANS_ID:24003Vl7F13152", - 'ORD_ID' => '2024010354F1', - 'ORIG_TRANS_AMT' => '101', - 'PAN' => '4546 71** **** 7894', - 'PROC_RET_CD' => '00', - 'SETTLEID' => '', - 'TRANS_ID' => '24003Vl7F13152', - 'TRANS_STAT' => 'C', - 'XID_3D' => '', - ], - ], - 'expectedData' => [ - 'auth_code' => 'P77974', - 'capture' => true, - 'capture_amount' => 1.01, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 1.01, - 'masked_number' => '4546 71** **** 7894', - 'num_code' => '0', - 'order_id' => '2024010354F1', - 'order_status' => 'PAYMENT_COMPLETED', - 'proc_return_code' => '00', - 'ref_ret_num' => '400300744233', - 'status' => 'approved', - 'status_detail' => 'approved', - 'transaction_time' => new \DateTimeImmutable('2024-01-03 21:37:57.259'), - 'capture_time' => new \DateTimeImmutable('2024-01-03 21:37:57.259'), - 'transaction_id' => '24003Vl7F13152', - 'transaction_type' => 'pay', - 'cancel_time' => null, - 'refund_amount' => null, - 'refund_time' => null, - 'installment_count' => null, - ], - ]; - yield 'pre_pay_order_status' => [ - 'responseData' => [ - 'ErrMsg' => 'Record(s) found for 202401032AF3', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '202401032AF3', - 'TransId' => '24003VqkA14152', - 'Extra' => [ - 'AUTH_CODE' => 'T87380', - 'AUTH_DTTM' => '2024-01-03 21:42:35.902', - 'CAPTURE_AMT' => '', - 'CAPTURE_DTTM' => '', - 'CAVV_3D' => '', - 'CHARGE_TYPE_CD' => 'S', - 'ECI_3D' => '', - 'HOSTDATE' => '0103-214236', - 'HOST_REF_NUM' => '400300744234', - 'MDSTATUS' => '', - 'NUMCODE' => '0', - 'ORDERSTATUS' => 'ORD_ID:202401032AF3 CHARGE_TYPE_CD:S ORIG_TRANS_AMT:205 CAPTURE_AMT: TRANS_STAT:A AUTH_DTTM:2024-01-03 21:42:35.902 CAPTURE_DTTM: AUTH_CODE:T87380 TRANS_ID:24003VqkA14152', - 'ORD_ID' => '202401032AF3', - 'ORIG_TRANS_AMT' => '205', - 'PAN' => '4546 71** **** 7894', - 'PROC_RET_CD' => '00', - 'SETTLEID' => '', - 'TRANS_ID' => '24003VqkA14152', - 'TRANS_STAT' => 'A', - 'XID_3D' => '', - ], - ], - 'expectedData' => [ - 'auth_code' => 'T87380', - 'capture' => false, - 'capture_amount' => null, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 2.05, - 'masked_number' => '4546 71** **** 7894', - 'num_code' => '0', - 'order_id' => '202401032AF3', - 'order_status' => 'PAYMENT_COMPLETED', - 'proc_return_code' => '00', - 'ref_ret_num' => '400300744234', - 'status' => 'approved', - 'status_detail' => 'approved', - 'transaction_time' => new \DateTimeImmutable('2024-01-03 21:42:35.902'), - 'capture_time' => null, - 'transaction_id' => '24003VqkA14152', - 'transaction_type' => 'pay', - 'cancel_time' => null, - 'refund_amount' => null, - 'refund_time' => null, - 'installment_count' => null, - ], - ]; - yield 'canceled_order_status' => [ - 'responseData' => [ - 'ErrMsg' => 'Record(s) found for 20240103BBF9', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '20240103BBF9', - 'TransId' => '24003VxrB15662', - 'Extra' => [ - 'AUTH_CODE' => 'P42795', - 'AUTH_DTTM' => '2024-01-03 21:49:42.929', - 'CAPTURE_AMT' => '101', - 'CAPTURE_DTTM' => '2024-01-03 21:49:42.929', - 'CAVV_3D' => '', - 'CHARGE_TYPE_CD' => 'S', - 'ECI_3D' => '', - 'HOSTDATE' => '0103-214944', - 'HOST_REF_NUM' => '400300744237', - 'MDSTATUS' => '', - 'NUMCODE' => '0', - 'ORDERSTATUS' => "ORD_ID:20240103BBF9\tCHARGE_TYPE_CD:S\tORIG_TRANS_AMT:101\tCAPTURE_AMT:101\tTRANS_STAT:V\tAUTH_DTTM:2024-01-03 21:49:42.929\tCAPTURE_DTTM:2024-01-03 21:49:42.929\tAUTH_CODE:P42795\tTRANS_ID:24003VxrB15662", - 'ORD_ID' => '20240103BBF9', - 'ORIG_TRANS_AMT' => '101', - 'PAN' => '4546 71** **** 7894', - 'PROC_RET_CD' => '00', - 'SETTLEID' => '', - 'TRANS_ID' => '24003VxrB15662', - 'TRANS_STAT' => 'V', - 'VOID_DTTM' => '2024-01-03 21:49:44.301', - 'XID_3D' => '', - ], - ], - 'expectedData' => [ - 'auth_code' => 'P42795', - 'capture' => true, - 'capture_amount' => 1.01, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 1.01, - 'masked_number' => '4546 71** **** 7894', - 'num_code' => '0', - 'order_id' => '20240103BBF9', - 'order_status' => 'CANCELED', - 'proc_return_code' => '00', - 'ref_ret_num' => '400300744237', - 'status' => 'approved', - 'status_detail' => 'approved', - 'transaction_time' => new \DateTimeImmutable('2024-01-03 21:49:42.929'), - 'capture_time' => new \DateTimeImmutable('2024-01-03 21:49:42.929'), - 'transaction_id' => '24003VxrB15662', - 'transaction_type' => 'pay', - 'cancel_time' => new \DateTimeImmutable('2024-01-03 21:49:44.301'), - 'refund_amount' => null, - 'refund_time' => null, - 'installment_count' => null, - ], - ]; - yield 'refund_order_status' => [ - 'responseData' => [ - 'ErrMsg' => 'Record(s) found for 20240128C0B7', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '20240128C0B7', - 'TransId' => '24028T8xG11980', - 'Extra' => [ - 'AUTH_CODE' => 'P93736', - 'AUTH_DTTM' => '2024-01-28 19:58:49.382', - 'CAPTURE_AMT' => '201', - 'CAPTURE_DTTM' => '2024-01-28 19:58:49.382', - 'CAVV_3D' => '', - 'CHARGE_TYPE_CD' => 'C', - 'ECI_3D' => '', - 'HOSTDATE' => '0128-195850', - 'HOST_REF_NUM' => '402800747548', - 'MDSTATUS' => '', - 'NUMCODE' => '0', - 'ORDERSTATUS' => 'ORD_ID:20240128C0B7 CHARGE_TYPE_CD:C ORIG_TRANS_AMT:201 CAPTURE_AMT:201 TRANS_STAT:C AUTH_DTTM:2024-01-28 19:58:49.382 CAPTURE_DTTM:2024-01-28 19:58:49.382 AUTH_CODE:P93736 TRANS_ID:24028T8xG11980', - 'ORD_ID' => '20240128C0B7', - 'ORIG_TRANS_AMT' => '201', - 'PAN' => '4546 71** **** 7894', - 'PROC_RET_CD' => '00', - 'SETTLEID' => '', - 'TRANS_ID' => '24028T8xG11980', - 'TRANS_STAT' => 'C', - 'XID_3D' => '', - ], - ], - 'expectedData' => [ - 'auth_code' => 'P93736', - 'capture' => true, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 2.01, - 'capture_amount' => 2.01, - 'masked_number' => '4546 71** **** 7894', - 'num_code' => '0', - 'order_id' => '20240128C0B7', - 'order_status' => 'PAYMENT_COMPLETED', - 'proc_return_code' => '00', - 'ref_ret_num' => '402800747548', - 'status' => 'approved', - 'status_detail' => 'approved', - 'transaction_time' => new \DateTimeImmutable('2024-01-28 19:58:49.382'), - 'capture_time' => new \DateTimeImmutable('2024-01-28 19:58:49.382'), - 'transaction_id' => '24028T8xG11980', - 'transaction_type' => 'refund', - 'cancel_time' => null, - 'refund_amount' => null, - 'refund_time' => null, - 'installment_count' => null, - ], - ]; - yield 'recurring_order_status' => [ - 'responseData' => [ - 'ErrMsg' => 'Record(s) found for 22303O8EA19252', - 'Extra' => [ - 'AUTH_CODE_1' => 'P34325', - 'AUTH_DTTM_1' => '2022-10-30 14:58:03.449', - 'CAPTURE_AMT_1' => '101', - 'CAPTURE_DTTM_1' => '2022-10-30 14:58:03.449', - 'CAVV_3D_1' => '', - 'CHARGE_TYPE_CD_1' => 'S', - 'CHARGE_TYPE_CD_2' => 'S', - 'ECI_3D_1' => '', - 'HOSTDATE_1' => '1030-145804', - 'HOST_REF_NUM_1' => '230300671790', - 'MDSTATUS_1' => '', - 'NUMCODE' => '0', - 'ORDERSTATUS_1' => "ORD_ID:2022103097CD\tCHARGE_TYPE_CD:S\tORIG_TRANS_AMT:101\tCAPTURE_AMT:101\tTRANS_STAT:C\tAUTH_DTTM:2022-10-30 14:58:03.449\tCAPTURE_DTTM:2022-10-30 14:58:03.449\tAUTH_CODE:P34325\tTRANS_ID:22303O8EB19253", - 'ORDERSTATUS_2' => "ORD_ID:2022103097CD-2\tCHARGE_TYPE_CD:S\tORIG_TRANS_AMT:101\tTRANS_STAT:PN\tPLANNED_START_DTTM:2023-01-30 14:58:03.449", - 'ORD_ID_1' => '2022103097CD', - 'ORD_ID_2' => '2022103097CD-2', - 'ORIG_TRANS_AMT_1' => '101', - 'ORIG_TRANS_AMT_2' => '101', - 'PAN_1' => '4355 08** **** 4358', - 'PAN_2' => '4355 08** **** 4358', - 'PLANNED_START_DTTM_2' => '2023-01-30 14:58:03.449', - 'PROC_RET_CD_1' => '00', - 'RECURRINGCOUNT' => '2', - 'RECURRINGID' => '22303O8EA19252', - 'SETTLEID_1' => '', - 'TRANS_ID_1' => '22303O8EB19253', - 'TRANS_STAT_1' => 'C', - 'TRANS_STAT_2' => 'PN', - 'XID_3D_1' => '', - ], - ], - 'expectedData' => [ - 'recurringId' => '22303O8EA19252', - 'recurringInstallmentCount' => '2', - 'status' => 'approved', - 'num_code' => '0', - 'error_message' => null, - 'recurringOrders' => [ - [ - 'auth_code' => 'P34325', - 'capture' => true, - 'capture_amount' => 1.01, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 1.01, - 'masked_number' => '4355 08** **** 4358', - 'order_id' => '2022103097CD', - 'order_status' => 'PAYMENT_COMPLETED', - 'proc_return_code' => '00', - 'ref_ret_num' => '230300671790', - 'status' => 'approved', - 'status_detail' => 'approved', - 'transaction_time' => new \DateTimeImmutable('2022-10-30 14:58:03.449'), - 'capture_time' => new \DateTimeImmutable('2022-10-30 14:58:03.449'), - 'transaction_id' => '22303O8EB19253', - 'transaction_type' => 'pay', - ], - [ - 'auth_code' => null, - 'capture' => false, - 'capture_amount' => null, - 'currency' => null, - 'error_code' => null, - 'error_message' => null, - 'first_amount' => 1.01, - 'masked_number' => '4355 08** **** 4358', - 'order_id' => '2022103097CD-2', - 'order_status' => 'PAYMENT_PENDING', - 'proc_return_code' => null, - 'ref_ret_num' => null, - 'status' => 'declined', - 'status_detail' => null, - 'transaction_id' => null, - 'transaction_time' => null, - 'capture_time' => null, - 'transaction_type' => 'pay', - ], - ], - ], - ]; } public static function cancelTestDataProvider(): iterable @@ -1970,276 +1336,78 @@ public static function refundTestDataProvider(): iterable ]; } - public static function orderHistoryTestDataProvider(): array + public static function historyTestDataProvider(): iterable { - return [ - 'success_cancel_success_refund_fail' => [ - 'responseData' => [ - 'ErrMsg' => '', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '20240102D8F1', - 'Extra' => [ - 'TERMINALID' => '00655020', - 'MERCHANTID' => '655000200', - 'NUMCODE' => '0', - 'TRX1' => "C\tD\t100\t100\t2024-01-02 21:53:02.486\t2024-01-02 21:53:02.486\t\t\t\t99\t24002V3CG19993", - 'TRX2' => "S\tV\t101\t101\t2024-01-02 21:52:59.261\t2024-01-02 21:52:59.261\t2024-01-02 21:53:01.297\t400200744059\tP78955\t00\t24002V29G19979", - 'TRXCOUNT' => '2', - ], - ], - 'expectedData' => [ - 'order_id' => '20240102D8F1', - 'proc_return_code' => '00', - 'error_message' => null, - 'num_code' => '0', - 'trans_count' => 2, - 'transactions' => [ - [ - 'auth_code' => 'P78955', - 'proc_return_code' => '00', - 'transaction_id' => '24002V29G19979', - 'error_message' => null, - 'ref_ret_num' => '400200744059', - 'order_status' => 'CANCELED', - 'transaction_type' => 'pay', - 'first_amount' => 1.01, - 'capture_amount' => 1.01, - 'status' => 'approved', - 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => true, - 'currency' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-02 21:52:59.261'), - 'capture_time' => null, - 'masked_number' => null, - ], - [ - 'auth_code' => null, - 'proc_return_code' => '99', - 'transaction_id' => '24002V3CG19993', - 'error_message' => null, - 'ref_ret_num' => null, - 'order_status' => 'ERROR', - 'transaction_type' => 'refund', - 'first_amount' => 1.0, - 'capture_amount' => 1.0, - 'status' => 'declined', - 'error_code' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-02 21:53:02.486'), - 'capture_time' => null, - 'masked_number' => null, - 'status_detail' => 'general_error', - 'capture' => false, - 'currency' => null, - ], - ], - 'status' => 'approved', - 'status_detail' => 'approved', - ], - ], - 'success_payment_then_cancel_tx' => [ - 'responseData' => [ - 'ErrMsg' => '', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '202401029F10', - 'Extra' => [ - 'TERMINALID' => '00655020', - 'MERCHANTID' => '655000200', - 'NUMCODE' => '0', - 'TRX1' => "S\tV\t101\t101\t2024-01-02 21:47:28.785\t2024-01-02 21:47:28.785\t2024-01-02 21:47:40.156\t400200744054\tP77381\t00\t24002VvdA19109", - 'TRXCOUNT' => '1', - ], - ], - 'expectedData' => [ - 'error_message' => null, - 'num_code' => '0', - 'order_id' => '202401029F10', - 'proc_return_code' => '00', - 'status' => 'approved', - 'status_detail' => 'approved', - 'trans_count' => 1, - 'transactions' => [ - [ - 'auth_code' => 'P77381', - 'proc_return_code' => '00', - 'transaction_id' => '24002VvdA19109', - 'error_message' => null, - 'ref_ret_num' => '400200744054', - 'order_status' => 'CANCELED', - 'transaction_type' => 'pay', - 'first_amount' => 1.01, - 'capture_amount' => 1.01, - 'status' => 'approved', - 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => true, - 'currency' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-02 21:47:28.785'), - 'capture_time' => null, - 'masked_number' => null, - ], - ], - ], - ], - 'success_one_payment_tx' => [ - 'responseData' => [ - 'ErrMsg' => '', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '202401010C20', - 'Extra' => [ - 'TERMINALID' => '00655020', - 'MERCHANTID' => '655000200', - 'NUMCODE' => '0', - 'TRX1' => "S\tC\t101\t101\t2024-01-01 22:15:27.511\t2024-01-01 22:15:27.511\t\t400100743898\tP14578\t00\t24001WPbH16694", - 'TRXCOUNT' => '1', - ], - ], - 'expectedData' => [ - 'error_message' => null, - 'num_code' => '0', - 'order_id' => '202401010C20', - 'proc_return_code' => '00', - 'status' => 'approved', - 'status_detail' => 'approved', - 'trans_count' => 1, - 'transactions' => [ - [ - 'auth_code' => 'P14578', - 'proc_return_code' => '00', - 'transaction_id' => '24001WPbH16694', - 'error_message' => null, - 'ref_ret_num' => '400100743898', - 'order_status' => 'PAYMENT_COMPLETED', - 'transaction_type' => 'pay', - 'first_amount' => 1.01, - 'capture_amount' => 1.01, - 'status' => 'approved', - 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => true, - 'currency' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-01 22:15:27.511'), - 'capture_time' => null, - 'masked_number' => null, - ], + yield 'fail' => [ + 'responseData' => [ + "TP_Islem_IzlemeResponse" => [ + "TP_Islem_IzlemeResult" => [ + "Sonuc" => "-1", + "Sonuc_Str" => "Başarısız", ], ], ], - 'success_one_pre_auth_tx' => [ - 'responseData' => [ - 'ErrMsg' => '', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '20240101CCCF', - 'Extra' => [ - 'TERMINALID' => '00655020', - 'MERCHANTID' => '655000200', - 'NUMCODE' => '0', - 'TRX1' => "S\tA\t205\t\t2024-01-01 22:28:30.716\t\t\t400100743899\tT56045\t00\t24001WceJ18839", - 'TRXCOUNT' => '1', - ], - ], - 'expectedData' => [ - 'error_message' => null, - 'num_code' => '0', - 'order_id' => '20240101CCCF', - 'proc_return_code' => '00', - 'status' => 'approved', - 'status_detail' => 'approved', - 'trans_count' => 1, - 'transactions' => [ - [ - 'auth_code' => 'T56045', - 'proc_return_code' => '00', - 'transaction_id' => '24001WceJ18839', - 'error_message' => null, - 'ref_ret_num' => '400100743899', - 'order_status' => 'PAYMENT_COMPLETED', - 'transaction_type' => 'pay', - 'first_amount' => 2.05, - 'capture_amount' => null, - 'status' => 'approved', - 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => false, - 'currency' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-01 22:28:30.716'), - 'capture_time' => null, - 'masked_number' => null, - ], - ], - ], + 'expectedData' => [ + 'proc_return_code' => -1, + 'error_code' => -1, + 'error_message' => 'Başarısız', + 'status' => 'declined', + 'status_detail' => null, + 'trans_count' => 0, + 'transactions' => [], ], - 'success_pre_auth_and_post_tx' => [ - 'responseData' => [ - 'ErrMsg' => '', - 'ProcReturnCode' => '00', - 'Response' => 'Approved', - 'OrderId' => '202401014456', - 'Extra' => [ - 'TERMINALID' => '00655020', - 'MERCHANTID' => '655000200', - 'NUMCODE' => '0', - 'TRX1' => "S\tC\t200\t200\t2024-01-01 22:37:53.396\t2024-01-01 22:37:53.396\t\t400100743901\tT14446\t00\t24001Wl3G10348", - 'TRXCOUNT' => '1', - ], - ], - 'expectedData' => [ - 'error_message' => null, - 'num_code' => '0', - 'order_id' => '202401014456', - 'proc_return_code' => '00', - 'status' => 'approved', - 'status_detail' => 'approved', - 'trans_count' => 1, - 'transactions' => [ - [ - 'auth_code' => 'T14446', - 'proc_return_code' => '00', - 'transaction_id' => '24001Wl3G10348', - 'error_message' => null, - 'ref_ret_num' => '400100743901', - 'order_status' => 'PAYMENT_COMPLETED', - 'transaction_type' => 'pay', - 'first_amount' => 2.0, - 'capture_amount' => 2.0, - 'status' => 'approved', - 'error_code' => null, - 'status_detail' => 'approved', - 'capture' => true, - 'currency' => null, - 'transaction_time' => new \DateTimeImmutable('2024-01-01 22:37:53.396'), - 'capture_time' => null, - 'masked_number' => null, - ], + ]; + + yield 'fail_date_range' => [ + 'responseData' => [ + "TP_Islem_IzlemeResponse" => [ + "TP_Islem_IzlemeResult" => [ + "Sonuc" => "-222", + "Sonuc_Str" => "Tarih aralığı 7 günden fazla olamaz.", ], ], ], - 'fail1' => [ - 'responseData' => [ - 'ErrMsg' => 'No record found for 20221030B3FF2', - 'ProcReturnCode' => '05', - 'Response' => 'Declined', - 'OrderId' => '20221030B3FF2', - 'Extra' => [ - 'NUMCODE' => '0', - 'TRXCOUNT' => '0', - ], - ], - 'expectedData' => [ - 'order_id' => '20221030B3FF2', - 'proc_return_code' => '05', - 'error_message' => 'No record found for 20221030B3FF2', - 'num_code' => '0', - 'trans_count' => 0, - 'transactions' => [], - 'status' => 'declined', - 'status_detail' => 'reject', - ], + 'expectedData' => [ + 'proc_return_code' => -222, + 'error_code' => -222, + 'error_message' => 'Tarih aralığı 7 günden fazla olamaz.', + 'status' => 'declined', + 'status_detail' => null, + 'trans_count' => 0, + 'transactions' => [], ], ]; + + // dd(__DIR__.'/../../../../var/param/history_response_last_7days.json'); +// +// dump(\json_decode(\file_get_contents(__DIR__.'/../../var/param/history_response_last_7days.json'), true)); +// dump(\json_decode(\file_get_contents(__DIR__.'/../../../var/param/history_response_last_7days.json'), true)); + $data = \json_decode(\file_get_contents(__DIR__.'/../../../../var/param/history_response_last_7days.json'), true); + +// $values = []; +// foreach ($data['TP_Islem_IzlemeResponse']['TP_Islem_IzlemeResult']['DT_Bilgi']['diffgr:diffgram']['NewDataSet']['Temp'] as $rawTx) { +//// if (!isset($rawTx['PB'])) { +//// continue; +//// } +//// if (((float)$rawTx['Toplam_Iade_Tutar']) <= 0) { +//// continue; +//// } +// if (($rawTx['Tip_Str']) !== 'İptal') { +// continue; +// } +// //$values[] = $rawTx['Tip_Str']; +// $values[] = $rawTx['Tutar']; +//// if ($rawTx['Tip_Str'] === 'Satış') { +//// dd($rawTx); +//// } +// } +// dump($values); +// dd(array_unique($values)); +// dump(\json_decode(\file_get_contents(__DIR__.'/../../../../../var/param/history_response_last_7days.json'), true)); + yield 'success' => [ + 'responseData' => \json_decode(\file_get_contents(__DIR__.'/../../../../var/param/history_response_last_7days.json'), true), + //'responseData' => \json_decode(\file_get_contents(__DIR__.'/../../../../var/garanti-last-2-year-history.json'), true), + 'expectedData' => [], + ]; } } diff --git a/tests/Unit/test_data/parampos/status_pay_then_cancel_response.json b/tests/Unit/test_data/parampos/status_pay_then_cancel_response.json index d7cf06bd..ac99535d 100644 --- a/tests/Unit/test_data/parampos/status_pay_then_cancel_response.json +++ b/tests/Unit/test_data/parampos/status_pay_then_cancel_response.json @@ -2,26 +2,26 @@ "TP_Islem_Sorgulama4Response": { "TP_Islem_Sorgulama4Result": { "DT_Bilgi": { - "Odeme_Sonuc": "13", - "Odeme_Sonuc_Aciklama": "\u0130ade", - "Dekont_ID": "3007296662", - "Siparis_ID": "20250105E324", - "Islem_ID": "665C5908BA1D7583BDF62D3A", - "Durum": "REFUND", - "Tarih": "05.01.2025 13:14:32", + "Odeme_Sonuc": "12", + "Odeme_Sonuc_Aciklama": "\u0130ptal", + "Dekont_ID": "3007298740", + "Siparis_ID": "2025011251F7", + "Islem_ID": "A967FAB1429FF95270AD104F", + "Durum": "CANCEL", + "Tarih": "12.01.2025 20:25:38", "Toplam_Tutar": "10.01", "Komisyon_Oran": "1.75", "Komisyon_Tutar": "0.18", "Banka_Sonuc_Aciklama": "", "Taksit": "1", "Ext_Data": "||||", - "Toplam_Iade_Tutar": "10.01", + "Toplam_Iade_Tutar": "0", "KK_No": "581877******2285", - "Bank_Extra": "\n 142436<\/AUTH_CODE>\n 2025-01-05 14:01:56.399<\/AUTH_DTTM>\n 1001<\/CAPTURE_AMT>\n 2025-01-05 14:01:56.399<\/CAPTURE_DTTM>\n <\/CAVV_3D>\n C<\/CHARGE_TYPE_CD>\n <\/ECI_3D>\n 0105-140156<\/HOSTDATE>\n 500514472735<\/HOST_REF_NUM>\n <\/MDSTATUS>\n 0<\/NUMCODE>\n ORD_ID:10126021842587\tCHARGE_TYPE_CD:C\tORIG_TRANS_AMT:1001\tCAPTURE_AMT:1001\tTRANS_STAT:C\tAUTH_DTTM:2025-01-05 14:01:56.399\tCAPTURE_DTTM:2025-01-05 14:01:56.399\tAUTH_CODE:142436\tTRANS_ID:25005OB6H12275<\/ORDERSTATUS>\n 10126021842587<\/ORD_ID>\n 1001<\/ORIG_TRANS_AMT>\n 5818 77** **** 2285<\/PAN>\n 00<\/PROC_RET_CD>\n <\/SETTLEID>\n 25005OB6H12275<\/TRANS_ID>\n C<\/TRANS_STAT>\n <\/XID_3D>\n <\/Extra>", + "Bank_Extra": "\n 609945<\/AUTH_CODE>\n 2025-01-12 20:25:39.237<\/AUTH_DTTM>\n 1001<\/CAPTURE_AMT>\n 2025-01-12 20:25:39.237<\/CAPTURE_DTTM>\n <\/CAVV_3D>\n S<\/CHARGE_TYPE_CD>\n <\/ECI_3D>\n 0112-202551<\/HOSTDATE>\n 501220476656<\/HOST_REF_NUM>\n <\/MDSTATUS>\n 0<\/NUMCODE>\n ORD_ID:10126021844746\tCHARGE_TYPE_CD:S\tORIG_TRANS_AMT:1001\tCAPTURE_AMT:1001\tTRANS_STAT:V\tAUTH_DTTM:2025-01-12 20:25:39.237\tCAPTURE_DTTM:2025-01-12 20:25:39.237\tAUTH_CODE:609945\tTRANS_ID:25012UZnE17558<\/ORDERSTATUS>\n 10126021844746<\/ORD_ID>\n 1001<\/ORIG_TRANS_AMT>\n 5818 77** **** 2285<\/PAN>\n 00<\/PROC_RET_CD>\n <\/SETTLEID>\n 25012UZnE17558<\/TRANS_ID>\n V<\/TRANS_STAT>\n 2025-01-12 20:25:51.535<\/VOID_DTTM>\n <\/XID_3D>\n <\/Extra>", "Islem_Tip": "SALE", - "Bank_Trans_ID": "25005NOgE12061", - "Bank_AuthCode": "222905", - "Bank_HostRefNum": "500513472717" + "Bank_Trans_ID": "25012UZnE17558", + "Bank_AuthCode": "609945", + "Bank_HostRefNum": "501220476656" }, "Sonuc": "1", "Sonuc_Str": "Ba\u015far\u0131l\u0131"