[Actualización] Ventas Online con Tarjetas de Crédito

Por: Josue Soriano Publicado el: 2017-07-03 14:08:26, 29382

Hace ya algún tiempo hice una publicacion en la que permitía implementar un objeto en PHP que permitiera hacer transacciones de pagos por medio de la pasarela de BAC Credomatic. Sin embargo comenzó a tener fallas puesto que las tarjetas de crédito VISA implementaron el Protocolo 3D Secure con el cual es necesario salir de la página que hacer un proceso de verificación, esto provoco que la clase desarrollada solamente funcionara con las tarjetas de crédito American Express, dejando asi Obsoleta la implementación.

Sin embargo recientemente descubrí que Credomatic tiene una implementación local que permite hacer transacciones por medio de un método Denominado "PAYCOM" el cual permite hacer las transacciones sin necesidad de dejar la aplicación que la usa. Eso me permitió actualizar la clase con el nuevo servidor. también implemente en el constructor de la clase un objeto "MySQLi" de PHP que permite que se guarden las transacciones realizadas en una tabla. Por seguridad utilizo un algoritmo que enmascara los números de tarjetas de crédito para no guardar información delicada de los clientes; para poder hacer uso de esta implementación es necesario tener una tabla dentro de nuestra base de datos MySQL, la sentencia para crear la tabla esta en los comentarios del código de la clase que comparto para quien sea de utilidad.

class.paycomcredomatic.php

Para hacer la conexión, cambie la clase original para que nos permita hacer la conexión creando un objeto "paycomcredomatic", el archivo lo guarde como class.paycomcredomatic.php:

/*
*Clase Credomatic:
*
*	Propiedades:
*		privado $data:	datos que se envian al servidor de Credomatic;
*		Privado $url:	Url del servidor que procesa la transaccion;
*	
*	Constructor:
*		Parametros:
*			$orderid:		Identificador de la orden.
*			$type:			Tipo de transaccion ["auth", "authp", "qpts"].
*			$username		Usuario registrado para PayCom
*			$key_id:		Identificador de la llave en el servidor.
*			$key:			Llave usada para autentificarse.
*			$cc_number:		Numero de la tarjeta de credito.
*			$cc_cvv:		Codigo de Verificacion den la tarjeta de credito.
*			$cc_exp:		Fecha de Expiracion de la tarjeta de credito en dormato mmAA.
*			$cc_name:		Nombre del titular de la tarjeta.
*			$amount:		Monto a procesar.
*			$mysqli:		Objeto para registrar los datos de pago, default = null;
*			$mysql_table:	Nombre de la tabla en la que se registran los pagos;
*	
*
*	Metodos:
*		procesarpago:
*			Parametros:
*				Ninguno.
*			
*			Retorna: 
*				Arreglo con la siguiette estructura:
*					response	
*					responsetext	
*					authcode 	
*					transactionid	
*					avsresponse	
*					cvvresponse	
*					orderid	
*					type	
*					response_code	
*					username
*					time	
*					amount	
*					purshamount
*					hash
*					db_response = array(
*								type
*								title
*								text
*							);
*
*	MySQL:
*		para el uso del objeto mysqli se debe tener la siguiente estructura en la tabla proporcionada en $mysql_table:
			CREATE TABLE [nombre de la tabla] (
						  idregistro int(11) NOT NULL,
						  idorden varchar(200) COLLATE utf8_bin NOT NULL,
						  tipo varchar(10) COLLATE utf8_bin NOT NULL,
						  monto double NOT NULL,
						  fecha timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
						  tarjetahabiente varchar(200) COLLATE utf8_bin NOT NULL,
						  numero_tarjeta varchar(20) COLLATE utf8_bin NOT NULL,
						  respuesta int(11) NOT NULL,
						  codigo_respuesta int(11) NOT NULL,
						  texto_respuesta varchar(200) COLLATE utf8_bin NOT NULL,
						  codigo_autorizacion bigint(20) NOT NULL,
						  idtransaccion bigint(20) NOT NULL,
						  respuesta_avs varchar(200) COLLATE utf8_bin NOT NULL,
						  respuesta_cvv varchar(200) COLLATE utf8_bin NOT NULL,
						  hash varchar(32) COLLATE utf8_bin NOT NULL,
						  direccionip varchar(15) COLLATE utf8_bin NOT NULL
			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
			ALTER TABLE [nombre de la tabla] ADD PRIMARY KEY (idregistro);
			ALTER TABLE [nombre de la tabla] MODIFY idregistro int(11) NOT NULL AUTO_INCREMENT;
*			
*/
	

class paycomcredomatic{
	private $data;
	private $cc_name;
	private $mysqli;
	private $mysql_table;
	private $url = "https://paycom.credomatic.com/PayComBackEndWeb/common/requestPaycomService.go";

	public function __construct($orderid, $type, $username, $key_id, $key, $cc_number, $cc_cvv, $cc_exp, $cc_name, $amount, $mysqli=null,$mysql_table = "") {

		$time = time();
		$this->cc_name = $cc_name;
		$this->mysqli = $mysqli;
		$this->mysql_table = $mysql_table;
		$hash = md5("$orderid|$amount|$time|$key");

		$this->data = array(
			"time"=> $time,
			"hash"=> $hash,
			"orderid"=>$orderid,
			"username"=> $username,
			"key_id"=> $key_id,
			"type"=> $type,
			"amount"=> str_replace(",","",$amount), //elimnamos las comas por si se envia en formato ejem. 2,000.00
			"avs"=>false,
			"cvv"=> $cc_cvv,
			"ccexp"=> $cc_exp,
			"ccnumber"=> $cc_number				
		);
	}

	public function procesarpago(){
		$httpquery = http_build_query($this->data);
		$navegacion = curl_init($this->url);
		curl_setopt ($navegacion, CURLOPT_POST, true);
		curl_setopt ($navegacion, CURLOPT_POSTFIELDS, $httpquery);
		curl_setopt($navegacion, CURLOPT_USERAGENT, "Negblog_Sistema_Integrado");
		curl_setopt ($navegacion, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($navegacion, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($navegacion, CURLOPT_HEADER, false);
		
		$returndata = curl_exec($navegacion);
		echo curl_error($navegacion);
		curl_close($navegacion);
		
		//echo $returndata;
		$returndata = substr($returndata, 1);
		parse_str($returndata, $response);
		$type = "error";
		$title = "Error";
		$text = "Error Desconocido";
		
		if(isset($response["response"])){
			if(!is_null($this->mysqli) && $this->mysql_table != ""){
				$tabla =  $this->mysql_table;
				$strsql = "INSERT INTO $tabla(idorden, tipo, monto, tarjetahabiente, numero_tarjeta, respuesta, codigo_respuesta, texto_respuesta, codigo_autorizacion, 
											idtransaccion, respuesta_avs, respuesta_cvv, hash, direccionip)
							VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
				
				if($stmt=$this->mysqli->prepare($strsql)){
					$idorden= $this->data["orderid"];
					$tipo=$this->data["type"];
					$monto=$this->data["amount"];
					$tarjetahabiente=$this->cc_name;
					$numero_tarjeta=$this->data["ccnumber"];
					$respuesta=$response["response"];
					$codigo_respuesta=$response["response_code"];
					$texto_respuesta=$response["responsetext"];
					$codigo_autorizacion=$response["authcode"];
					$idtransaccion=$response["transactionid"];
					$respuesta_avs=$response["avsresponse"];
					$respuesta_cvv=$response["cvvresponse"];
					$hash=$response["hash"];
					$direccionip=$_SERVER["REMOTE_ADDR"];


					$first6 = substr($numero_tarjeta,0, 6);
					$last4 = substr($numero_tarjeta, strlen($numero_tarjeta)-4);
					$mask =  substr($numero_tarjeta, 6, -4);
					$mask = preg_replace("/\d/", "*", $mask);
					
					$numero_tarjeta = $first6 . $mask . $last4;
									
		
					
					
					$stmt->bind_param('ssdssiisiissss', $idorden, $tipo, $monto, $tarjetahabiente, $numero_tarjeta, $respuesta, $codigo_respuesta, 
													   $texto_respuesta, $codigo_autorizacion, $idtransaccion, $respuesta_avs, $respuesta_cvv, $hash, $direccionip);
					$stmt->execute(); // Execute the prepared query.
					if($stmt->errno == 0){
						$stmt->close();
						unset($stmt);
						$type="success";
						$title="Exito";
						$text="Registro Guardado Exitosamente";
					}
					else{
						$mensaje="No se pudo eliminar la direccion enviada: " . $stmt->error;			
					}
				}
				else{
					$text = "No se pudo preparar la insercion del registro: ".$this->mysqli->error;
				}
			}
			else{
				$type = "warning";
				$title = "Alerta";
				$text = "No se envio informacion para guardar la transaccion en la Base de Datos";
			}
		}
		else{
			$response["response"] = NULL;
			$response["responsetext"] = "Error al conectar con Credomatic";
			$text = "No se guardo transacción en la Base de Datos.";
		}

		$response["db_response"] = array("type"=>$type, "title"=>$title, "text"=>$text);
		return $response;
	}
	
}

¿Cómo se usa?

Para poder acceder es necesario que credomatic nos de las credenciales necesarias para poder hacer las transacciones, dichas credenciales son parte de los parámetros necesarios para realizar la transacción:

	header("Content-Type: text/plain");
	//Parametros para poder guardar las transacciones en la DB
	define("SERVIDOR", "localhost"); //Direccion IP del servidor de BD
	define("USUARIO", "mi_dbuse"); //Usuario designado para la conexion de la DB
	define("PASSWORD", "mipassw"); //Constraseña del Usuario
	define("BASEDATOS", "trans_db"); //nombre de la base de Datos
	
	$mysqli = new mysqli(SERVIDOR, USUARIO, PASSWORD, BASEDATOS); //declaracion de mysqli
	mysqli_set_charset($mysqli, "utf8"); //definir para poder hacer uso de carateres especiales

	require 'class.paycomcredomatic.php';
	$orderid = "123455"; //Numero de la transaccion realizada (usualmete el numero de orden o numero de factura
	$keyid = "12345678"; //identificador de la Llave Generada por el panel del banco
	$key = "dasLKJANlkjvnasdklcnlkanlkJclkjsdnasdlkjn"; //llave generada por el panel del banco
	$username = "usuario"; //usuario brindado por Credomatic
	$cc_num="4555500000000000"; //Numero de tarjeta de credito (Este es un ejemplo)
	$cc_cvv="1234"; //Codigo de Verificacion de la tarjeta
	$cc_exp="0617"; //Fecha de vencimiento en formato MMdd
	$cc_name="Monkey D. Luffy"; //primer nombre del titular de la tarjeta
	$montototal = "2000.00"; //Monto de la transacción (importante que no lleve comas
	$tipo = "auth"; //tipo de transaccion el Banco especifica que otras transacciones se pueden hacer

	//Creamos el Objeto con los parametros necesarios
	$pago = new paycomcredomatic($orderid, $tipo, $username, $keyid, $key, $cc_num, $cc_cvv, $cc_exp, $cc_name, $montototal, $mysqli, "web_creditcardtransactions");

	//Llamamos el metodo procesarpago que se encarga de realizar la transaccion
	$respuesta = $pago->procesarpago();

	//Genera un JSON con la respuesta dada.
	echo json_encode($respuesta, JSON_PRETTY_PRINT);

 

Si te Gusto compartelo:

Comentar

Debes ingresar para poder comentar, accede AQUI. Registrate AQUI

Comentarios

consultoria

Hola, Josue. Muy interesante su articulo. Estoy implementando un carrito para compra de un unico articulo usando Bootstrap. Tengo todas las credenciales de Credomatic, para usar el sistema Cardinal (con 3D Secure). Ya lo tengo bastante encaminado, pero quisiera saber si Ud. le interesaría brindar una asesoría tipo freelance? Saludos desde Costa Rica. 28 de noviembre 2017. Eric ejfullmer@hotmail.com

consultoria

Hola, Josue. Muy interesante su articulo. Estoy implementando un carrito para compra de un unico articulo usando Bootstrap. Tengo todas las credenciales de Credomatic, para usar el sistema Cardinal (con 3D Secure). Ya lo tengo bastante encaminado, pero quisiera saber si Ud. le interesaría brindar una asesoría tipo freelance? Saludos desde Costa Rica. 28 de noviembre 2017. Eric ejfullmer@hotmail.com