File: /var/www/vhost/disk-apps/comfama.sports-crowd.com/app/Http/Controllers/NmiController.php
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Interfaces\PaymentGatewayControllerInterface;
use Exception;
use Illuminate\Http\Request;
use App\Http\Controllers\PaymentGatewayBridgeController;
class NmiController extends PaymentGatewayBridgeController implements PaymentGatewayControllerInterface
{
public function index($order)
{
if ($order->gw_state == 'CONFIRMED') {
return $this->webcheckoutDone($order);
}
$this->updatePendingStatus($order, false, false);
return $this->generateWebcheckout($order->total_price, $order->gw_code_transaction, 'order');
}
public function ticketIndex($ticket)
{
if ($ticket->payment_state == 'CONFIRMED') {
return $this->webcheckoutDone($ticket);
}
$this->updatePendingStatus($ticket, false, false);
return $this->generateWebcheckout($ticket->total, $ticket->payment_reference, 'ticket');
}
public function genericIndex($paymentTransaction, $price, $origin, $clientId, $description)
{
if ($paymentTransaction->state == 'CONFIRMED') {
return $this->webcheckoutDone(null, $paymentTransaction);
}
$this->updatePendingStatus($paymentTransaction, false, false);
return $this->generateWebcheckout($price, $paymentTransaction->reference, $origin);
}
private function generateWebcheckout($price, $reference, $origin)
{
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$domain = $protocol . $_SERVER['HTTP_HOST'];
$redirectUrl = $domain . '/store/payment?origin=' . $origin . '&paymentGatewayId=' . $this->gatewayData->id;
$xmlRequest = new \DOMDocument('1.0', 'utf-8');
$xmlRequest->preserveWhiteSpace = false;
$xmlRequest->formatOutput = true;
$sales = $xmlRequest->createElement('sale');
$apikey = $xmlRequest->createElement('api-key', $this->apiKey);
$redirect = $xmlRequest->createElement('redirect-url', htmlspecialchars($redirectUrl));
$amount = $xmlRequest->createElement('amount', $price);
$address = $xmlRequest->createElement('ip-address', $_SERVER["REMOTE_ADDR"]);
$currency = $xmlRequest->createElement('currency', $this->currency);
$order_id = $xmlRequest->createElement('order-id', $reference);
$sales->appendChild($apikey);
$sales->appendChild($redirect);
$sales->appendChild($amount);
$sales->appendChild($address);
$sales->appendChild($currency);
$sales->appendChild($order_id);
$xmlRequest->appendChild($sales);
$data = $this->sendXMLviaCurl($xmlRequest, $this->urlApi);
// Parse Step One's XML response
$gwResponse = @new \SimpleXMLElement($data);
if ((string)$gwResponse->result == 1) {
// The form url for used in Step Two below
$formURL = $gwResponse->{'form-url'};
} else {
throw new Exception(print " Error, received " . $data);
}
return view("nmi_payment_gateway.webcheckout")
->with('gatewayData', $this->gatewayData)
->with('team', $this->team)
->with('total_price', $this->fmt->formatCurrency($price, $this->currency))
->with('reference', $reference)
->with("order_id", $reference)
->with('formURL', $formURL);
}
public function sendXMLviaCurl($xmlRequest, $gatewayURL)
{
// helper function demonstrating how to send the xml with curl
$ch = curl_init(); // Initialize curl handle
curl_setopt($ch, CURLOPT_URL, $gatewayURL); // Set POST URL
$headers = array();
$headers[] = "Content-type: text/xml";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Add http headers to let it know we're sending XML
$xmlString = $xmlRequest->saveXML();
curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // Allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Return into a variable
curl_setopt($ch, CURLOPT_PORT, 443); // Set the port number
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Times out after 30s
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlString); // Add XML directly in POST
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// This should be unset in production use. With it on, it forces the ssl cert to be valid
// before sending info.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
if (!($data = curl_exec($ch))) {
print "curl error =>" . curl_error($ch) . "\n";
throw new Exception(" CURL ERROR :" . curl_error($ch));
}
curl_close($ch);
return $data;
}
public function payment(Request $request)
{
if (!empty($_GET['token-id'])) {
$tokenId = $_GET['token-id'];
$xmlRequest = new \DOMDocument('1.0', 'utf-8');
$xmlRequest->preserveWhiteSpace = false;
$xmlRequest->formatOutput = true;
$xmlCompleteTransaction = $xmlRequest->createElement('complete-action');
$apikey = $xmlRequest->createElement('api-key', $this->apiKey);
$tokenID = $xmlRequest->createElement('token-id', $tokenId);
$xmlCompleteTransaction->appendChild($apikey);
$xmlCompleteTransaction->appendChild($tokenID);
$xmlRequest->appendChild($xmlCompleteTransaction);
$data = $this->sendXMLviaCurl($xmlRequest, $this->urlApi);
// Process Step Three
$gwResponse = @new \SimpleXMLElement((string)$data);
switch ((string)$gwResponse->result) {
case '1':
$this->updatePayment(
(string)$gwResponse->{'order-id'},
'CONFIRMED',
2,
'Transacción confirmada por url',
(string)$gwResponse->{'transaction-id'}
);
$webcheckoutConfirmData = [
'state' => 'CONFIRMED',
'comment' => 'Transacción confirmada por url',
'origin' => $request['origin']
];
break;
case '3':
$this->updatePayment(
(string)$gwResponse->{'order-id'},
'REJECTED',
7,
(string)$gwResponse->{'result-text'},
(string)$gwResponse->{'transaction-id'}
);
$webcheckoutConfirmData = [
'state' => 'REJECTED',
'comment' => (string)$gwResponse->{'result-text'},
'origin' => $request['origin']
];
break;
}
return $this->webcheckoutConfirm($webcheckoutConfirmData);
}
}
public function webhooksListener(Request $request)
{
$utilController = new UtilController();
$utilController->logFile($request);
$requestContent = json_decode($request->getContent(), true);
$data = $requestContent['event_body'];
$paymentReference = $data['order_id'];
$paymentTransactionId = $data['transaction_id'];
switch ($requestContent['event_type']) {
case 'transaction.sale.success':
$this->updatePayment($paymentReference, 'CONFIRMED', 2, 'Venta exitosa', $paymentTransactionId);
break;
case 'transaction.sale.failure':
$this->updatePayment($paymentReference, 'REJECTED', 7, 'Venta fallida', $paymentTransactionId);
break;
}
return response(array('r' => true, 'm' => "Recibido", 'd' => null));
}
public function getTransactionByReference(Request $request)
{
return response()->json(array(
'r' => true,
'm' => 'Transacción obtenida con éxito',
'd' => $this->getTransactionFromPaymentGateway($request["refTransaction_value"])
));
}
private function getTransactionFromPaymentGateway($reference)
{
$httpClient = new \GuzzleHttp\Client();
$response = $httpClient->post(
'https://secure.nmi.com/api/query.php?security_key=' . $this->gatewayData->api_key . '&order_id=' . $reference,
['headers' => ['Accept' => 'application/xml'],]
)->getBody()->getContents();
return json_decode(json_encode(simplexml_load_string($response)));
}
public function validatePayment($transactionId, $reference)
{
$payment = $this->getTransactionFromPaymentGateway($reference);
if (!isset($payment->transaction)) {
return;
}
$transaction = $payment->transaction;
if (is_array($transaction)) {
$transaction = end($transaction);
}
$action = $transaction->action;
$action = is_array($action) ? end($action) : $action;
switch ($transaction->condition) {
case 'complete':
$this->updatePayment(
$transaction->order_id,
'CONFIRMED',
2,
'Transacción confirmada por validación',
$transaction->transaction_id
);
break;
case 'abandoned':
$this->updatePayment(
$transaction->order_id,
'ABANDONED',
7,
'Transacción abandonada',
$transaction->transaction_id
);
break;
case 'failed':
$this->updatePayment(
$transaction->order_id,
'FAILED',
7,
$action->response_text,
$transaction->transaction_id
);
break;
case 'pendingsettlement':
case 'in_progress':
break;
default:
break;
}
}
/**
* @param Request $request
* @return mixed
*/
public function responseTransaction(Request $request) {
}
}