Formulario directo de integración

La integración con formulario directo se recomienda para aquellas tiendas online que tengan mayor control sobre el código de programación. Para un webmaster o programador, las siguientes instrucciones deberían ser suficientes para que puedas empezar con la integración.

Para ofrecer Paga+tarde a tus clientes, deberás incluir un método de pago más en el proceso de checkout de tu tienda online. Utiliza el siguiente formulario, apuntando a la URL https://pmt.pagantis.com/v1/installments:

  <form action="https://pmt.pagantis.com/v1/installments" method="post">

    <!--Parámetros de Configuración -->
    <input name="account_id" type="hidden" value="CLAVE DE LA CUENTA" />
    <input name="order_id" type="hidden" value="ID_PEDIDO_EN_TU_SISTEMA" />
    <input name="amount" type="hidden" value="IMPORTE" />
    <input name="currency" type="hidden" value="DIVISA" />
    <input name="description" type="hidden" value="DESC" />
    <input name="ok_url" type="hidden" value="URL_OK" />
    <input name="nok_url" type="hidden" value="URL_NOK" />
    <input name="cancelled_url" type="hidden" value="CANCELLED_URL">
    <input name="callback_url" type="hidden" value="CALLBACK_URL">
    <input name="locale" type="hidden" value="IDIOMA_DE_LA_PAGINA_DE_PAGO" />
    <input name="iframe" type="hidden" value="IFRAME_FLAG" />
    <input name="discount[full]" type="hidden" value="[true|false]">
    <input name="signature" type="hidden" value="FIRMA" />

    <!--Datos para autorellenar el formulario -->
    <input name="full_name" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="email" type="hidden" value="EMAIL_DEL_USUARIO">
    <input name="dni" type="hidden" value="DNI_DEL_USUARIO">
    <input name="mobile_phone" type="hidden" value="NUM_TELEFONO">
    <input name="dob" type="hidden" value="YYYY/MM/DD">
    <input name="address[street]" type="hidden" value="DIRECCION">
    <input name="address[city]" type="hidden" value="CIUDAD">
    <input name="address[zipcode]" type="hidden" value="CODIGO_CIUDAD">

    <!--Información del cliente suscrito a la tienda, opcional -->
    <input name="loginCustomer[gender]" type="hidden" value="[male|female]">
    <input name="loginCustomer[email]" type="hidden" value="EMAIL_DEL_USUARIO">
    <input name="loginCustomer[dob]" type="hidden" value="YYYY/MM/DD">
    <input name="loginCustomer[full_name]" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="loginCustomer[is_guest]" type="hidden" value="[true|false]">
    <input name="metadata[member_since]" type="hidden" value="YYYY/MM/DD">
    <input name="loginCustomer[num_orders]" type="hidden" value="123">
    <input name="loginCustomer[amount_orders]" type="hidden" value="4321.98">
    <input name="loginCustomer[num_partial_refunds]" type="hidden" value="0">
    <input name="loginCustomer[amount_refunded]" type="hidden" value="4321.98">
    <input name="loginCustomer[num_full_refunds]" type="hidden" value="1">

    <!--direccion de envio, opcional -->
    <input name="shipping[street]" type="hidden" value="DIRECCION">
    <input name="shipping[city]" type="hidden" value="CIUDAD">
    <input name="shipping[province]" type="hidden" value="PROVINCIA">
    <input name="shipping[zipcode]" type="hidden" value="CODIGO_CIUDAD">
    <input name="shipping[full_name]" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="shipping[mobile_phone]" type="hidden" value="NUM_TELEFONO">
    <input name="shipping[dni]" type="hidden" value="DNI_DEL_USUARIO">

    <!--direccion de facturación, opcional -->
    <input name="billing[street]" type="hidden" value="DIRECCION">
    <input name="billing[city]" type="hidden" value="CIUDAD">
    <input name="billing[province]" type="hidden" value="PROVINCIA">
    <input name="billing[zipcode]" type="hidden" value="CODIGO_CIUDAD">
    <input name="billing[full_name]" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="billing[mobile_phone]" type="hidden" value="NUM_TELEFONO">
    <input name="billing[dni]" type="hidden" value="DNI_DEL_USUARIO">

    <!--carito del usuario, opcional -->
    <input name="items[0][description]" type="hidden" value="DESCRIPCION_PRIMERO_PRODUCTO">
    <input name="items[0][quantity]" type="hidden" value="CANTIDA_PRIMERO_PRODUCTO">
    <input name="items[0][amount]" type="hidden" value="IMPORTE_PRIMERO_PRODUCTO">
    <input name="items[1][description]" type="hidden" value="DESCRIPCION_SEGUNDO_PRODUCTO">
    <input name="items[1][quantity]" type="hidden" value="CANTIDA_SEGUNDO_PRODUCTO">
    <input name="items[1][amount]" type="hidden" value="IMPORTE_SEGUNDO_PRODUCTO">
    ....
    <input name="items[n][description]" type="hidden" value="DESCRIPCION_ULTIMO_PRODUCTO">
    <input name="items[n][quantity]" type="hidden" value="CANTIDA_ULTIMO_PRODUCTO">
    <input name="items[n][amount]" type="hidden" value="IMPORTE_ULTIMO_PRODUCTO">

    <!--usuarios (espectadores, pasajeros, ... ),  opcional -->
    <input name="users[0][full_name]" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="users[0][email]" type="hidden" value="EMAIL_DEL_USUARIO">
    <input name="users[0][dob]" type="hidden" value="FECHA DE NACIMIENO YYYY/MM/DD">
    <input name="users[0][mobile_phone]" type="hidden" value="NUM_TELEFONO">
    <input name="users[0][nationality]" type="hidden" value="NACIONALIDAD DEL USUARIO">
    <input name="users[0][document_type]" type="hidden" value="TIPO DE DOCUMENTO">
    <input name="users[0][document_number]" type="hidden" value="NUMERACIÓN DEL DOCUMENTO">
    <input name="users[0][expiration_date]" type="hidden" value="FECHA DE CADUCIDAD DEL DOCUMENTO">
    ....
    <input name="users[n][full_name]" type="hidden" value="NOMBRE_DEL_USUARIO">
    <input name="users[n][email]" type="hidden" value="EMAIL_DEL_USUARIO">
    <input name="users[n][dob]" type="hidden" value="FECHA DE NACIMIENO YYYY/MM/DD">
    <input name="users[n][mobile_phone]" type="hidden" value="NUM_TELEFONO">
    <input name="users[n][nationality]" type="hidden" value="NACIONALIDAD DEL USUARIO">
    <input name="users[n][document_type]" type="hidden" value="TIPO DE DOCUMENTO">
    <input name="users[n][document_number]" type="hidden" value="NUMERACIÓN DEL DOCUMENTO">
    <input name="users[n][expiration_date]" type="hidden" value="FECHA DE CADUCIDAD DEL DOCUMENTO">

    <!--metadata, opcional -->
    <input name="metadata[key_1]" type="hidden" value="value_1">
    <input name="metadata[key_2]" type="hidden" value="value_2">
    ....
    <input name="metadata[key_n]" type="hidden" value="value_n">

    <!--botón de envio del formulario -->
    <input type="submit" value="Realizar pago"/>
  </form>

Repasemos los campos input del formulario mencionado arriba. Los parámetros que se envían son:

  • Parámetros de Configuración
  • Nombre
  • Tipo
  • Descripción
  • account_id
  • Obligatorio
  • ObligatorioLa Public Key de tu cuenta en Paga+Tarde. Lo puedes encontrar en la sección Tu cuenta > Datos de la tienda de nuestro back office.
  • currency
  • Obligatorio
  • ObligatorioDivisa del cobro: EUR.
  • order_id
  • Obligatorio
  • ObligatorioEl identificador del pedido en tu sistema. Lo necesitarás cuando recibas las notificaciones de que se ha realizado el cobro.
  • amount
  • Obligatorio
  • ObligatorioImporte, como número entero, dónde las dos últimas cifras son los decimales. Ej: 999 = 9,99 o 1000 = 10,00.
  • description
  • Opcional
  • OpcionalDescripción del pedido que aparecerá en el formulario de pago. De no enviarse se usará el número de pedido (order_id).
  • ok_url
  • Obligatorio
  • ObligatorioURL a la que redirigiremos al cliente tras completar el pago satisfactoriamente.
  • nok_url
  • Obligatorio
  • ObligatorioURL a la que redirigiremos al cliente en caso de que no se haya podido completar el pago. Idealmente esta url es la página de checkout.
  • callback_url
  • Opcional
  • OpcionalURL de notificación donde se informa sobre el estatus después de hacer la venta. Esta notificación se envía independientemente de la configuración de los webhooks.
  • cancelled_url
  • Opcional
  • OpcionalURL donde redirigir al usuario en caso de que quiera interrumpir el proceso de pago.
  • discount[full]
  • Opcional
  • Opcionaltrue, si el comercio quiere pagar los intereses de la venta, false en caso contrario. false por defecto.
  • iframe
  • Opcional
  • OpcionalIndicando si la página de Paga+Tarde se crea para integrarlo como iframe en la página de comercio ó se enseña en modo standalone. Opciones: true y false. Por defecto, se crea el formulario en modo standalone.
  • locale
  • Opcional
  • OpcionalFuerza el idioma en lugar de usar el detector automático de Paga+Tarde.
  • signature
  • Obligatorio
  • ObligatorioFirma que utilizamos para verificar la autenticidad de la petición. La definición de la firma la puedes encontrar aquí.
  • Datos para autorellenar el formulario
  • Información del cliente suscrito a la tienda
  • Datos de facturación
  • Datos de envio
  • Items del carrito
  • Otros parámetros
 

Generación de la firma

La firma se realiza concatenando los siguientes campos y generando su hash con la función SHA1 (los valores de los campos callback_url y discount[full] son opcionales):

    clave_de_firma + account_id + order_id + amount + currency + ok_url + nok_url
    [ + callback_url  + discount[full] + cancelled_url ]

Esta clave de firma y código de cuenta lo puedes obtener en Tu cuenta > Datos de la tienda.

Si quieres saber algo más sobre generar firmas, lo puedes consultar aquí.

Notificaciones

De forma asíncrona le llegará a tu servidor una notificación del evento en la que se indicará el resultado de la operación y toda la información relativa al pago. Estas notificaciones se pueden enviar a todos los sistemas que necesites, no únicamente a uno. De esta forma, puedes enviar la notificación a tu página web y, por ejemplo, a tu sistema de facturación.

Esta notificación consiste de una petición POST a las URLs que nos hayas indicado en Tu cuenta > Datos de la tienda con el siguiente mensaje en formato JSON en el cuerpo de la petición.

Para pagos únicos, el evento que se notificará será charge.created o charge.failed en función del resultado de la misma.

Estas notificaciones incluyen un campo firma también, de manera que se pueden validar sin necesidad de hacer una llamada por API si no se desea. En caso de que los requisitos de seguridad sean mayores, se debería hacer una petición por API al ID de cargo indicado en la notificación.

Puedes saber más sobre notificaciones en esta página.

Notificación charge.created

se puede identificar un pago cobrado por el campo “paid”:true.

  {
    "id":"cha_7b0eb74cda6926e1790094431debbf02",
    "amount":1998,
    "error_code":null,
    "error_message":null,
    "order_id":"21",
    "description":"Faded Short Sleeves T-shirt (1)",
    "paid":true,
    "created_at":"2016-05-04T12:41:45.000+02:00",
    "status":"refunded",
    "commission":20,
    "amount_to_settle":1978,
    "discount":0,
    "metadata":{  
       "phone":"673190205",
       "address":"Avenida Diagonal 579 ",
       "city":"Barcelona",
       "province":"Barcelona",
       "user_email":"ecompanys@digitalorigin.com"
    },
    "closed_at":"2016-05-04T12:41:47.000+02:00",
    "payment_date":"2016-05-04",
    "card":{  
       "id":"car_bdb945f1cba2243a0ee8e27d62c093f9",
       "bin":"459985",
       "brand":"VISA ",
       "type":"debit",
       "category":"ELECTRON",
       "country_code":"ES",
       "last4":"2013",
       "expiration_year":2016,
       "expiration_month":12
    },
    "refunds":[  
       {  
          "id":"ref_2cfca33d3c7c33404058237556ffc054",
          "amount":1998,
          "created_at":"2016-05-04T14:55:13.000+02:00",
          "charge":{  
             "id":"cha_7b0eb74cda6926e1790094431debbf02",
             "created_at":"2016-05-04T12:41:45.000+02:00",
             "amount":1998
          },
          "amount_to_settle":-1978,
          "commission":-20,
          "discount":0,
          "discount_applied":false
       }
    ]
 }

Notificación charge.failed

se puede identificar un pago fallido por el campo “paid”:false.

{  
    "id":"cha_dd10be5f680c7744037024a00083ff15",
    "amount":5988,
    "error_code": "undefined_error",
    "error_message": "\nERROR. El comercio tiene un filtro que no permite esta operacin.[Bines por pases]\n",
    "order_id":"21",
    "description":"Faded Short Sleeves T-shirt (1)",
    "paid":false,
    "created_at":"2016-05-04T12:41:45.000+02:00",
    "status":"error",
    "commission":599,
    "amount_to_settle":5389,
    "discount":0,
    "metadata":{  
       "phone":"673190205",
       "address":"Avenida Diagonal 579 ",
       "city":"Barcelona",
       "province":"Barcelona",
       "user_email":"soporte@pagamastarde.com"
    },
    "closed_at":"2016-05-04T12:41:47.000+02:00",
    "payment_date":null,
    "card":{  
       "id":"car_bdb945f1cba2243a0ee8e27d62c093f9",
       "bin":"459985",
       "brand":"VISA ",
       "type":"debit",
       "category":"ELECTRON",
       "country_code":"ES",
       "last4":"2013",
       "expiration_year":2016,
       "expiration_month":12
    },
    "refunds":[  

    ]
 }

Página de OK/KO

Si todo ha ido bien, ¡felicidades! En la página de OK infórmale al usuario todo lo que deba saber (datos del pedido, cambios en su cuenta, etc) y asegúrate de agradecerle su confianza en tu empresa.

Si por el contrario ha ocurrido algún error, indícale al usuario lo que ha sucedido y ofrécele maneras de solucionarlo, ya sea volviendo a intentarlo, ofreciéndole un medio de pago alternativo y siempre ponle maneras de ponerse en contacto contigo.

Cambio de entornos

Recuerda que en Paga+Tarde dispones de dos entornos que funcionan en paralelo y que tienen datos diferentes de configuración. Al empezar a utilizar el servicio, utiliza las llaves del entorno test. Y cuando quieras empezar a procesar operaciones reales, asegúrate de que hayas configurado tu aplicación con los datos de conexión del entorno real. Puedes ver dicha información en la sección Tu cuenta > Datos de la tienda de nuestro back office.