Como implementar una pasarela de pago mediante tarjeta de crédito utilizando PHP

En este artículo vamos a ver como implementar una pasarela de pago mediante tarjeta de crédito con PHP empleando el Servidor Integrado de Redsys (Servidor del TPV Virtual) (SIS).

¿Qué es un TPV virtual?

Las siglas TPV significan Terminal de Punto de Venta y viene acompañado de la palabra virtual para indicar que se trata de un sistema de pago online que permite a las tiendas online o páginas Web aceptar el pago de sus clientes o usuarios mediante tarjetas de crédito o débito. Este sistema de pago tiene muchísimas ventajas frente a otros sistemas de pago. Acepta una gran cantidad de tipos de tarjetas (VISA, MASTERCARD, MAESTRO, etc). Es una forma de pago mucho más segura y los datos son gestionados directamente por tu banco. No hay un tercero que amplíe la comisión.

Prácticamente todos los bancos ofrecen este servicio. Pregunta en tu banco sobre las condiciones para ver si te interesa contratarlo.

Forma de integración

Aunque en la mayoría de gestores de contenido y plataformas de Ecommerce ya disponen de un plugin o módulo con esta implementación, siempre puede ser interesante realizar una pasarela de pago a medida sin necesidad de utilizar ningún gestor de contenido ni plataforma de Ecommerce. Si este es tu caso, este tutorial te puede resultar muy útil para integrar la pasarela de pago en tu página Web.

Existen varias formas de implementar una pasarela de pago con tarjeta de crédito utilizando PHP. Nos centraremos en explicar como desarrollar una forma muy sencilla utilizando una programación orientada a objetos con el objetivo de realizar una integración con el TPV Virtual mediante conexión por redirección del navegador del cliente comprador.

Esta forma de conexión permite trasladar la sesión del cliente final al TPV Virtual, de forma que la selección del medio de pago y la introducción de datos se llevan a cabo en el entorno seguro del servidor del TPV Virtual y fuera de la responsabilidad del comercio. Además de la sencillez de implementación para el comercio y la tranquilidad respecto a la responsabilidad de los datos de pago, este modo de conexión da cabida a la utilización de mecanismos de autenticación como el 3D Secure, donde el banco de la tarjeta solicita directamente al titular un dato secreto que permite dotar de más seguridad a las compras.

Requisitos para empezar

Antes de ponerte a programar, si aún no lo tienes, es necesario que contrates un servicio TPV Virtual de cualquier banco que trabaje con Redsys y el mismo banco debe facilitarte los parámetros necesario para conectar con dicho TPV.

Cuando se ha contratado el servicio de TPV Virtual nos deben facilitar la siguiente información que será imprescindible para realizar la conexión con Redsys:

  • Nombre del comercio
  • Código del comercio
  • Clave secreta SHA-256

Formulario de pago inicial

En el ejemplo en funcionamiento que hemos creado para este artículo hemos decidido crear un formulario donde el usuario decide que cantidad quiere pagar y al pulsar en el botón «pagar» se construyen los parámetros necesarios para mandar al Servidor del TPV Virtual.

Nuestro formulario inicial será tan simple como lo siguiente:

<form class="form-amount" action="index.php" method="post">
    <div class="form-group">
        <label for="amount">Cantidad</label>
        <input type="text" id="amount" name="amount" class="form-control" placeholder="Por ejemplo: 50.00">
    </div>
    <input class="btn btn-lg btn-primary btn-block" name="submitPayment" type="submit" value="Pagar">
</form>

Tan solo es un formulario con un campo para escribir la cantidad a pagar y un botón para enviar.

Controlador del formulario de pago

En el mismo fichero donde hemos agregado el formulario podemos agregar el código PHP  que recibe los datos para ser procesados.

A continuación mostramos el código que debe ejecutarse al enviar la cantidad que el usuario desea pagar:

<?php
if ($_POST['submitPayment']) {
    include "api/apiRedsys.php";  
    $miObj = new RedsysAPI;
 
    $amount = $_POST['amount'];    
    $url_tpv = 'https://sis.redsys.es/sis/realizarPago';
    $version = "HMAC_SHA256_V1"; 
    $clave = 'TU CLAVE DE COMERCIO'; //poner la clave SHA-256 facilitada por el banco
    $name = 'TU NOMBRE DE COMERCIO';
    $code = 'TU CODIGO DE COMERCIO';
    $terminal = '1';
    $order = date('ymdHis');
    $amount = $amount * 100;
    $currency = '978';
    $consumerlng = '001';
    $transactionType = '0';
    $urlMerchant = 'http://your-domain.com/';
    $urlweb_ok = 'http://your-domain.com/tpv_ok.php';
    $urlweb_ko = 'http://your-domain.com/tpv_ko.php';
 
    $miObj->setParameter("DS_MERCHANT_AMOUNT", $amount);
    $miObj->setParameter("DS_MERCHANT_CURRENCY", $currency);
    $miObj->setParameter("DS_MERCHANT_ORDER", $order);
    $miObj->setParameter("DS_MERCHANT_MERCHANTCODE", $code);
    $miObj->setParameter("DS_MERCHANT_TERMINAL", $terminal);
    $miObj->setParameter("DS_MERCHANT_TRANSACTIONTYPE", $transactionType);
    $miObj->setParameter("DS_MERCHANT_MERCHANTURL", $urlMerchant);
    $miObj->setParameter("DS_MERCHANT_URLOK", $urlweb_ok);      
    $miObj->setParameter("DS_MERCHANT_URLKO", $urlweb_ko);
    $miObj->setParameter("DS_MERCHANT_MERCHANTNAME", $name); 
    $miObj->setParameter("DS_MERCHANT_CONSUMERLANGUAGE", $consumerlng);    
 
    $params = $miObj->createMerchantParameters();
    $signature = $miObj->createMerchantSignature($clave);
    ?>
    <form id="realizarPago" action="<?php echo $url_tpv; ?>" method="post">
        <input type='hidden' name='Ds_SignatureVersion' value='<?php echo $version; ?>'> 
        <input type='hidden' name='Ds_MerchantParameters' value='<?php echo $params; ?>'> 
        <input type='hidden' name='Ds_Signature' value='<?php echo $signature; ?>'> 
    </form>
    <script>
    $(document).ready(function () {
        $("#realizarPago").submit();
    });
    </script>
<?php
}  
?>

En este caso, tenemos un condicional que verifica la pulsación del botón «pagar». Cuando se pulsa en este botón estamos incluyendo en nuestro script la clase de la API. En la página oficial de Redsys puedes encontrar ayuda y descargar los archivos de la API para PHP entre otros lenguajes. Creando un objeto de la API y guardando la cantidad a pagar en nuestra variable $amount.

Seguidamente estamos declarando:

  • La url del tpv en la variable $url_tpv. Para ponerlo en modo pruebas debes poner: https://sis-t.redsys.es:25443/sis/realizarPago
  • La versión de la firma en la variable $version.
  • La clave SHA-256 en la variable $clave.
  • El nombre de comercio en la variable $name, facilitado por el banco.
  • El código de comercio en la variable $code, facilitado por el banco.
  • El terminal en la variable $terminal, suele ser 1 casi siempre.
  • La fecha del pago en la variable $order con el formato específico para que el TPV Virtual lo sepa interpretar.
  • La cantidad a pagar en $amount. La cantidad que escribe el usuario se debe multiplicar por 100 para enviarla al TPV.
  • La moneda en la variable $currency con valor «978» = Euro.
  • El idioma en la variable $consumerlng. En el ejemplo estamos poniendo «001» para que aparezca el TPV en español.
  • El tipo de transacción en la variable $transactionType con valor «0».
  • La url del comerciante en la variable $urlMerchant. Debe ser la url para enviar las notificaciones desde el TPV Virtual.
  • La url para los pagos correctos en la variable $urlweb_ok. Debes crear una página para informar al usuario de que el pago se ha realizado correctamente.
  • La url para los pagos cancelados o incorrectos en la variable $urlweb_ko. Debes crear una página para informar al usuario de que su pago ha sido erróneo.

Seguidamente usamos la función setParameter() de la clase de la API Redys para establecer los parámetros necesarios para que la conexión con el TPV Virtual tenga éxito. Se crean los parámetros utilizando la función createMerchantParameters(). Y finalmente se genera la firma con la clave SHA-256.

Toda esta información se deposita en los correspondientes inputs ocultos dentro de otro formulario que se envía automáticamente al TPV Virtual con JavaScript.

En principio debe funcionar con cualquier banco que disponga del servicio de TPV Virtual con Redsys. Actualmente, en el ejemplo estamos trabajando con CAIXABANK.

Esta entrada ha sido actualizada el 28/08/2018.

Ver demo Descargar

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(18 votos, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

39 respuestas a “Como implementar una pasarela de pago mediante tarjeta de crédito utilizando PHP”

  1. Carlos IBañez dice:

    Hola se puede usar con tarjetas de DEBITO??

  2. Fernando Cortés dice:

    Buenas tardes, lo probado y funciona correctamente pero he detectado algunos importes con los que da error es algo raro, lo he probado en tu demo (https://www.jose-aguilar.com/scripts/php/redsys-pago-con-tarjeta/) con el mismo resultado. Intenta pagar un importe de 36.20, verás que da error. Pero es raro porque es sólo con algunos importes concretos.

    Un saludo.

    • Jose Aguilar dice:

      Hola buenas tardes,

      No se si pudiste resolver este asunto. Espero que si.

      De igual modo te doy mi punto de vista a tu pregunta.

      Diría que este tutorial se ha quedado desfasado y ha habido algunos cambios importantes en la plataforma Redsys que quizá se deben considerar.

      Saludos

  3. bpiris dice:

    Hola, buenas. Estoy probando el código para permitir el pago. Pero estoy teniendo problemas a la hora de ponerlo en funcionamiento. He cambiado los valores relativos al comercio y al insertar la cantidad, Redsys muestra este error:

    Importe 0 Sin Asignar
    Código Comercio 1******4
    Terminal 1
    Número pedido
    Error en datos enviados. Contacte con su comercio.

    He añadido la versión para php 7.0 y he modificado la función mcrypt_encrypt() que está deprecada.

    Alguien sabe que puede estar pasando?

    • Jose Aguilar dice:

      Hola,

      Creo que ha habido cambios importantes en relación a los pagos después de la creación de este tutorial. Tendrás que darle un vistazo a las nuevas indicaciones de redsys.

      Saludos

  4. dante dice:

    como se haria para registrar en una db si el pago tubo exito o no? o ke deberia hacer redsys para que apenas se realice el pago me envie algun token o algo parecido para guardar que el pago se realizo con exito?

    • Jose Aguilar dice:

      Eso puedes controlarlo con tu páginas de ok y no ok:

      $urlweb_ok = ‘http://your-domain.com/tpv_ok.php’;
      $urlweb_ko = ‘http://your-domain.com/tpv_ko.php’;

  5. Antonio L. dice:

    Buenas tardes, me parece muy interesante la aportación ya que era lo que estaba buscando hace tiempo. Pero algo estaré haciendo mal porque he descargado el código y al integrarlo en mi web cambiando los datos de mi negocio, ahora en localhost porque aun no la he publicado, lo unico que consigo es que me lleve a mi pagina de inicio pero no me abre la web para el pago. Alguien me podría ayudar. Gracias.

  6. Juan dice:

    Hola Jose, muy buen código, funciona correctamente, lo único que la página del tpv para poner la tarjeta sale bien y cuando le doy a pagar no me redirige a la autenticación 3DS como a ti, sino que me sale otra con opciones. No sé si es porque tengo que tocar algo o porque no has subido la totalidad del código, cosa que si fuera así no entiendo ya que si lo compartes, se puede subir todo. Muchas gracias.

  7. Brayan YS dice:

    Se pueden pasar los datos mediante método GET, en la variable

    $urlweb_ok = ‘https://web.com/?v=datos_a_pasar

    Un saludo.

  8. Simon Chacon dice:

    Hola! En mi caso hice la instalación del plugin de wordpress «Redsys Insite» pero el iframe con la pasarela no aparece en la página del checkout (finalizar compra) que es la página donde el cliente coloca sus datos y decide si quiere pagar con paypal o con tarjeta. Los de redsys me mandan el enlace con la explicación de los códigos https://pagosonline.redsys.es/modelos-de-integracion.html#flujo-insite pero no se donde debo colocar ese codigo Javascript ni el resto de lineas que ahi colocan (no soy programador ni desarrollador web). Debo crear un fichero nuevo .php? puedo crear un snippet code con el codigo que colocas tu? porque probe hacerlo con el de Redsys y no funciona 🙁

  9. angeles dice:

    Disculpe. obvie el mensaje que le enviado. Ya he solventado el problema. muchas gracias

  10. Angeles dice:

    Hola,
    En primer lugar darte las gracias por tu código y tu ayuda.
    Tengo una consulta. Mi código es php, html5 y css3 puro y duro. He implementado el código que usted ha pasado, con las modificaciones oportunas para mi negocio, pero al finalizar el paso nr 4, y confirmar siempre me salta: ESTA PÁGINA NO FUNCIONA, ERROR HTTP 500, Y por suspuesto en redsys se lavan un poco las manos, ya que dicen que es error de programación….
    Alguna sugerencia… muchas gracias

  11. Ignacio dice:

    Hola, he descargado el código y lo he adaptado para poder utilizarlo en mi web, todo ok. Mi pregunta es como podría recuperar en una variable el valor numero de pedido que se refleja en la compra bancaria y que vemos también en el pequeño resumen que nos ofrece resys antes de insertar los datos de la tarjeta. he Supuesto que quizás a través de los parámetros que se le pasa a la función (DS_MERCHANT). Espero puedan ayudarme Saludos

  12. Elena dice:

    Hola,
    Muhas gracias por este post. Quería hacerte una pregunta. En mi banco me han dicho que para ponerme su pasarela de pago tengo que poner un botón (por ejemplo PAGAR CON TARJETA), en el cual ellos puedan poner ahí el enlace de su pasarela de pago que redireccione a pagar. ¿Cómo podría ponerlo correctamente? ¿con el primer código que has puesto en este artículo?
    La tienda online la he creado con Prestashop 1.7, y acabo de instalar el módulo de Redsys (a falta de configurar por que me pide el número y clave que facilita el banco). Pensaba que yo no tenía que poner ningún botón y que ya venía con la plataforma o con el módulo.
    Muchas garcias por tu ayuda.

    • Jose Aguilar dice:

      Hola,

      En PrestaShop instalando el módulo de redsys y configurándolo correctamente ya debería aparecer la opción de pago con tarjeta en la pasarela de tu tienda. No es necesario implementarla ni agregar un botón. El módulo redsys ya lo hace.

      Saludos

  13. Insigpol dice:

    ¿alguien puede recomendarme a alguna empresa o freelance que sea capaz de instalar una pasarela de pago en una zencart?

  14. efren dice:

    hola jose siempre sigo tus turoriales, este tengo una consulta, como proceso datos a la BD mysql si el pago es correcto?
    se que esta la url= $urlweb_ok

    pero como obtengo las variables para saber que el pago fue exitoso y de esa manera insertar a la BD

    • Jose Aguilar dice:

      Hola,

      No lo he probado pero quizá puedes recoger la información que retorna el tpv usando la variable $_POST en el archivo que se ejecuta en $urlMerchant.

      Saludos

  15. Guillermo dice:

    Un artículo excelente. Muchas gracias.

  16. manuel dice:

    hola estoy en contacto con un banco y me dice que su pasarela de pago no tienen modulo que lo que facilitan es una API de integracion o algo asi, y una documentacion que no me entero de nada.
    mi pregunta es:
    como se integraria una pasarela depago mediante una API facilitada por el banco?

    gracias

  17. yo dice:

    Hola!

    Estoy probando a crear un formulario con tu código y me aparece el siguiente error:

    Deprecated: Function mcrypt_encrypt() is deprecated in /******/redsys/apiRedsys.php on line 54

    Warning: mcrypt_encrypt(): Key of size 6 not supported by this algorithm. Only keys of size 24 supported in /********/redsys/apiRedsys.php on line 54

    ¿Sabes como debo corregirlo?

  18. tatuajes para parejas dice:

    Amazing things here. I am very satisfied to see your post.
    Thanks so much and I’m taking a look forward to contact you.
    Will you kindly drop me a e-mail?

  19. Javier dice:

    muy bien tutorial este, pero me gustaria saber como se podria mandar el enlace de pago mediante correo electronico.

    La verdad que seria muy util poner el precio, el e-mail y nombre del destinataria, y la otra persona solo pulsar en el enlace y hacer el pago.

    Espero alguna solucion.

    Gracias.

  20. Rafa dice:

    Muy buen tutorial, como enviar datos como nombre, email, etc de vuelta a la pagina de OK?, para desde aqui avisar de que se ha abonado el importe con esos datos

    • Jose Aguilar dice:

      Hola buenos días,

      Quizás una solución sea registrar toda esa información en la base de datos con un identificador del pago que se debería recibir en la vuelta del tpv.

      Saludos

  21. Hola Jose.
    Implemento lo que me dices, pero a la hora de ejecutar, se me va a: http://midominio.com/pago-con-tarjeta-2/index.php y por tanto es un error 404.
    He cargado la api de redsis en el directorio /api/apiredsys.php pero nada, no se que puede estar saliendo mal.
    Saludos y gracias de antemano

    • Jose Aguilar dice:

      Hola,

      Si nos facilitas la url de tu página quizá podamos ver que ocurre. Así a cientas tan solo puedo suponer que la url del formulario no es correcta.

      Saludos

  22. aDesigns dice:

    Justo me viene perfecto este artículo, pues en una pagina que tengo lo tenia con el viejo cifrado SHA-1 y me enviaron un aviso del banco de que habia que actualizarlo antes de octubre por que habia cambiado el cifrado a SHA256. ¿Los archivos de la API en php que hay en la pagina de redsys hay que descargarlos para que funcione o simplemente con lo que has puesto aqui funcionaria sin necesidad de esos archivos?

    Un saludo y gracias de antemano!

    • Jose Aguilar dice:

      Hola,

      Los archivos de la API se deben descargar e incluir en el proyecto para usarlos.

      Saludos

      • aDesigns dice:

        He estado probando, tanto de la forma que lo haces aqui, como en el ejemplo de la api (con el archivo ejemploGeneraPet.php) pero no lo he conseguido de ninguna de las maneras, he heho un print_r a $miObj para ver si enviaba los datos, y si que los envia (esto son parte de los datos del print_r RedsysAPI Object ( [vars_pay] => Array ( [DS_MERCHANT_AMOUNT] => 145 [DS_MERCHANT_ORDER] => ) la cuestion es que en cambio me sale como que no se ha enviado el importe, he probado de varias maneras a ver, y sinceramente no se donde puede estar el fallo (adjunto captura de pantalla de lo que me sale en la pagina de realizar el pago http://prnt.sc/cjw6uq ) ¿Alguna idea de que podria estar mal? (el codigo como ya he dicho antes es el del ejemplo que viene en la api en el archivo ejemploGeneraPet.php )

        Muchas gracias por adelantado

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ver más sobre