'approved', '01' => 'bank_call', '02' => 'bank_call', '05' => 'reject', '09' => 'try_again', '12' => 'invalid_transaction', '28' => 'reject', '51' => 'insufficient_balance', '54' => 'expired_card', '57' => 'does_not_allow_card_holder', '62' => 'restricted_card', '77' => 'request_rejected', '99' => 'general_error', ]; /** * Transaction Types * * @var array */ public $types = [ 'pay' => 'Auth', 'pre' => 'PreAuth', 'post' => 'PostAuth', ]; /** * Currencies * * @var array */ public $currencies = []; /** * Transaction Type * * @var string */ public $type; /** * API Account * * @var array */ protected $account = []; /** * Order Details * * @var array */ protected $order = []; /** * Credit Card * * @var object */ protected $card; /** * Request * * @var Request */ protected $request; /** * Response Raw Data * * @var object */ protected $data; /** * Processed Response Data * * @var mixed */ public $response; /** * Configuration * * @var array */ protected $config = []; /** * Response Raw Data * * @var object */ protected $mbrId = 5; /** * EstPos constructor. * * @param array $config * @param mixed $account * @param array $currencies */ public function __construct($config, $account, array $currencies) { $this->config = $config; $this->account = $account; $this->currencies = $currencies; $this->url = isset($this->config['urls'][$this->account->env]) ? $this->config['urls'][$this->account->env] : $this->config['urls']['production']; $this->gateway = isset($this->config['urls']['gateway'][$this->account->env]) ? $this->config['urls']['gateway'][$this->account->env] : $this->config['urls']['gateway']['production']; return $this; } /** * Create Regular Payment XML * * @return string */ protected function createRegularPaymentXML() { $nodes = [ 'CC5Request' => [ 'Name' => $this->account->username, 'Password' => $this->account->password, 'ClientId' => $this->account->client_id, 'Type' => $this->type, 'IPAddress' => $this->order->ip, 'Email' => $this->order->email, 'OrderId' => $this->order->id, 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, 'Total' => $this->order->amount, 'Currency' => $this->order->currency, 'Taksit' => $this->order->installment, 'CardType' => isset($this->card->type) ? $this->card->type : null, 'Number' => $this->card->number, 'Expires' => $this->card->month . '/' . $this->card->year, 'Cvv2Val' => $this->card->cvv, 'Mode' => 'P', 'GroupId' => '', 'TransId' => '', 'BillTo' => [ 'Name' => $this->order->name ? $this->order->name : null, ] ] ]; return $this->createXML($nodes, 'ISO-8859-9'); } /** * Create Regular Payment Post XML * * @return string */ protected function createRegularPostXML() { $nodes = [ 'CC5Request' => [ 'Name' => $this->account->username, 'Password' => $this->account->password, 'ClientId' => $this->account->client_id, 'Type' => $this->types[$this->order->transaction], 'OrderId' => $this->order->id, ] ]; return $this->createXML($nodes, 'ISO-8859-9'); } /** * Create 3D Payment XML * @return string */ protected function create3DPaymentXML() { $nodes = [ 'CC5Request' => [ 'Name' => $this->account->username, 'Password' => $this->account->password, 'ClientId' => $this->account->client_id, 'Type' => $this->type, 'IPAddress' => $this->order->ip, 'Email' => $this->order->email, 'OrderId' => $this->order->id, 'UserId' => isset($this->order->user_id) ? $this->order->user_id : null, 'Total' => $this->order->amount, 'Currency' => $this->order->currency, 'Taksit' => $this->order->installment, 'Number' => $this->request->get('md'), 'Expires' => '', 'Cvv2Val' => '', 'PayerTxnId' => $this->request->get('xid'), 'PayerSecurityLevel' => $this->request->get('eci'), 'PayerAuthenticationCode' => $this->request->get('cavv'), 'CardholderPresentCode' => '13', 'Mode' => 'P', 'GroupId' => '', 'TransId' => '', ] ]; if ($this->order->name) { $nodes['BillTo'] = [ 'Name' => $this->order->name, ]; } return $this->createXML($nodes, 'ISO-8859-9'); } /** * Get ProcReturnCode * * @return string|null */ protected function getProcReturnCode() { return isset($this->data->ProcReturnCode) ? (string)$this->data->ProcReturnCode : null; } /** * Get Status Detail Text * * @return string|null */ protected function getStatusDetail() { $proc_return_code = $this->getProcReturnCode(); return $proc_return_code ? (isset($this->codes[$proc_return_code]) ? (string)$this->codes[$proc_return_code] : null) : null; } /** * Create 3D Hash * * @return string */ public function create3DHash() { $hash_str = ''; $hash_str = $this->mbrId . $this->order->id . $this->order->amount . $this->order->success_url . $this->order->fail_url . $this->type . $this->order->installment . $this->order->rand . $this->account->merchant_pass; return base64_encode(pack('H*', sha1($hash_str))); } /** * Check 3D Hash * * @param array $data * @return bool */ public function check3DHash($data) { $return = false; $responseHash = $data['ResponseHash']; //MerchantID + MerchantPass + OrderId + AuthCode + ProcReturnCode + 3DStatus + ResponseRnd + UserCode $generatedHash = $this->account->merchant_id . $this->account->merchant_pass . $data['OrderId'] . $data['AuthCode'] . $data['ProcReturnCode'] . $data['3DStatus'] . $data['ResponseRnd'] . $this->account->user_code; $generatedHash = base64_encode(pack('H*', sha1($generatedHash))); if ($generatedHash == $responseHash) { $return = true; } return $return; } /** * Regular Payment * * @return $this * @throws GuzzleException */ public function makeRegularPayment() { return false; } /** * Make 3D Payment * * @return $this * @throws GuzzleException */ public function make3DPayment() { return false; } /** * Make 3D Pay Payment * * @return $this */ public function make3DPayPayment() { $this->request = Request::createFromGlobals(); $status = 'declined'; if ($this->check3DHash($this->request->request->all()) && (string)$this->request->get('ProcReturnCode') == '00') { if (in_array($this->request->get('3DStatus'), [1])) { $status = 'approved'; } } $transaction_security = 'MPI fallback'; if ($status == 'approved') { if ($this->request->get('3DStatus') == '1') { $transaction_security = 'Full 3D Secure'; } elseif (in_array($this->request->get('3DStatus'), [2, 3, 4])) { $transaction_security = 'Half 3D Secure'; } } $this->response = (object)[ 'id' => (string)$this->request->get('RequestGuid'), 'trans_id' => (string)$this->request->get('HostRefNum'), 'auth_code' => (string)$this->request->get('AuthCode'), 'host_ref_num' => (string)$this->request->get('HostRefNum'), //'response' => (string)$this->request->get('Response'), 'order_id' => (string)$this->request->get('OrderId'), 'transaction_type' => $this->type, 'transaction' => $this->order->transaction, 'transaction_security' => $transaction_security, 'code' => (string)$this->request->get('ProcReturnCode'), 'md_status' => $this->request->get('3DStatus'), 'status' => $status, 'status_detail' => isset($this->codes[$this->request->get('ProcReturnCode')]) ? (string)$this->request->get('ProcReturnCode') : null, 'hash' => (string)$this->request->get('ResponseHash'), 'rand' => (string)$this->request->get('Rnd'), //'hash_params' => (string)$this->request->get('HASHPARAMS'), //'hash_params_val' => (string)$this->request->get('HASHPARAMSVAL'), 'masked_number' => (string)$this->request->get('CardMask'), //'month' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Month'), //'year' => (string)$this->request->get('Ecom_Payment_Card_ExpDate_Year'), 'amount' => (string)$this->request->get('PurchAmount'), 'currency' => (string)$this->request->get('Currency'), 'tx_status' => (string)$this->request->get('TxnStatus'), 'eci' => (string)$this->request->get('Eci'), 'cavv' => (string)$this->request->get('CavvResult'), //'xid' => (string)$this->request->get('xid'), //'error_code' => (string)$this->request->get('ErrCode'), 'error_message' => (string)$this->request->get('ErrMsg'), //'md_error_message' => (string)$this->request->get('mdErrorMsg'), 'name' => (string)$this->request->get('MrcName'), //'email' => (string)$this->request->get('Email'), 'extra' => $this->request->get('Extra'), 'response_rnd' => $this->request->get('ResponseRnd'), 'all' => $this->request->request->all(), ]; return $this; } /** * Get 3d Form Data * * @return array */ public function get3DFormData() { $data = []; if ($this->order) { $this->order->hash = $this->create3DHash(); $inputs = [ 'MbrId' => $this->mbrId, 'MerchantID' => $this->account->merchant_id, 'UserCode' => $this->account->user_code, 'UserPass' => $this->account->user_pass, 'SecureType' => $this->account->model == '3d_pay' ? '3DPay' : '3D', 'TxnType' => $this->type, 'InstallmentCount' => $this->order->installment, 'Currency' => $this->order->currency, 'OkUrl' => $this->order->success_url, 'FailUrl' => $this->order->fail_url, 'OrderId' => $this->order->id, 'PurchAmount' => $this->order->amount, 'Lang' => $this->order->lang, 'Rnd' => $this->order->rand, 'Hash' => $this->order->hash, 'Pan' => $this->card->number, 'Cvv2' => $this->card->cvv, 'Expiry' => $this->getCardExpDate(), ]; $data = [ 'gateway' => $this->gateway, 'success_url' => $this->order->success_url, 'fail_url' => $this->order->fail_url, 'rand' => $this->order->rand, 'hash' => $this->order->hash, 'inputs' => $inputs, ]; } return $data; } /** * Send contents to WebService * * @param $contents * @return $this * @throws GuzzleException */ public function send($contents) { $client = new Client(); $response = $client->request('POST', $this->url, [ 'body' => $contents ]); $this->data = $this->XMLStringToObject($response->getBody()->getContents()); return $this; } /** * Prepare Order * * @param object $order * @param object null $card * @return mixed * @throws UnsupportedTransactionTypeException */ public function prepare($order, $card = null) { $this->type = $this->types['pay']; if (isset($order->transaction)) { if (array_key_exists($order->transaction, $this->types)) { $this->type = $this->types[$order->transaction]; } else { throw new UnsupportedTransactionTypeException('Unsupported transaction type!'); } } $this->order = $order; $this->card = $card; $this->order->installment = $this->order->installment == 0 ? 0 : $this->order->installment; } /** * Make Payment * * @param object $card * @return mixed * @throws UnsupportedPaymentModelException * @throws GuzzleException */ public function payment($card) { $this->card = $card; $model = 'regular'; if (isset($this->account->model) && $this->account->model) { $model = $this->account->model; } if ($model == 'regular') { $this->makeRegularPayment(); } elseif ($model == '3d') { $this->make3DPayment(); } elseif ($model == '3d_pay') { $this->make3DPayPayment(); } else { throw new UnsupportedPaymentModelException(); } return $this; } /** * Refund Order * * @param array $meta * @return $this * @throws GuzzleException */ public function refund(array $meta) { return false; } /** * Cancel Order * * @param array $meta * @return $this * @throws GuzzleException */ public function cancel(array $meta) { return false; } /** * Order Status * * @param array $meta * @return $this * @throws GuzzleException */ public function status(array $meta) { return false; } /** * Order History * * @param array $meta * @return $this * @throws GuzzleException */ public function history(array $meta) { return false; } /** * @return array */ public function getConfig() { return $this->config; } /** * @return mixed */ public function getAccount() { return $this->account; } /** * @return array */ public function getCurrencies() { return $this->currencies; } /** * @return mixed */ public function getOrder() { return $this->order; } /** * @return mixed */ public function getCard() { return $this->card; } /** * @return string|null */ public function getCardCode() { $card_type = null; if (isset($this->card->type)) { if ($this->card->type == 'visa') { $card_type = '0'; } elseif ($this->card->type == 'master') { $card_type = '1'; } elseif ($this->card->type == '1' || $this->card->type == '2') { $card_type = $this->card->type; } } return $card_type; } protected function getCardExpDate() { $year = (string)substr($this->card->year, 2, 2); $month = (string)substr($this->card->month, 0, 2); return (string)$month . $year; } }