Delegación de servicios AFIP de nic.ar

1) Obtener cuil

Puede obtener cuil a través de los siguientes enlaces:
Número de cuil rápido
Constancia de cuil

2) Obtener clave fiscal

Dirigirse a una dependencia de AFIP con original y fotocopia del DNI
Para evitar demoras puede solicitar un Turno Web

3) Delegar servicio de afip: “Trámites a Distancia” y “Administración de Dominios”

Delegar servicio de afip: “Trámites a Distancia” y “Administración de Dominios”

Permitir a otra persona que reserve dominios en mi nombre

Generar nueva relación

AngularJs $q service

Introducción

Asynchronous We will get a result from an action at some point in the future.

$q service

A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.

Implementación 1
$q(function(resolve, reject, notify){
  ...
  var ok = ...
  resolve(ok);
  ...
  var error = ...
  reject(error)
  ...
  var notify = ...
  notify(error)
}
Implementación 2
var deferred = $q.defer();
...
var ok = ...
deferred.resolve(ok);
...
var error = ...
deferred.reject(error);
...
var notify = ...
deferred.notify(error);
Ejemplo Implementación 1
var app = angular.module("app", []);

app.controller("promiseController", function($scope, $q) {

  function okToGreet(name){
    return (Math.random() < 0.2) ? false : true;
  };
  
  function asyncGreet(name) {
    // perform some asynchronous operation, resolve or reject the promise when appropriate.
    return $q(function(resolve, reject) {
      setTimeout(function() {
        if (okToGreet(name)) {
          resolve('Hello, ' + name + '!');
        } else {
          reject('Greeting ' + name + ' is not allowed.');
        }
      }, 1000);
    });
  }

  var promise = asyncGreet('Robin Hood');
  promise.then(function(greeting) {
    alert('Success: ' + greeting);
  }, function(reason) {
    alert('Failed: ' + reason);
  });
});
Ejemplo Implementación 2
var app = angular.module("app", []);

app.controller("promiseController", function($scope, $q) {

  function okToGreet(name){
    return (Math.random() < 0.2) ? false : true;
  };
  
  function asyncGreet(name) {
    var deferred = $q.defer();

    setTimeout(function() {
      deferred.notify('About to greet ' + name + '.');

      if (okToGreet(name)) {
        deferred.resolve('Hello, ' + name + '!');
      } else {
        deferred.reject('Greeting ' + name + ' is not allowed.');
      }
    }, 1000);

    return deferred.promise;
  }

  var promise = asyncGreet('Robin Hood');
  promise.then(function(greeting) {
    alert('Success: ' + greeting);
  }, function(reason) {
    alert('Failed: ' + reason);
  }, function(update) {
    alert('Got notification: ' + update);
  });
});
Chaining Promises

Because calling the then method of a promise returns a new derived promise, it is easily possible to create a chain of promises:

  var promiseA = asyncGreet('Robin Hood').then(function(greeting) {
    alert('Success: ' + greeting);
    return true;
  }, function(reason) {
    alert('Failed: ' + reason);
    return false;
  });
  
  var promiseB = promiseA.then(
    function(response) { 
      if(true) alert("Welcome")
      else alert("Bye")
    },
    function(reason) { alert(reason); }
  );

Encadenamiento parámetro - respuesta
El encadenamiento de parámetros - respuesta tiene un comportamiento errático en angular, el siguiente código debería funcionar pero no me funcionó al ejecutarlo dentro de un servicio AngularJS. Me daba error de metodos no definidos.

//promesa 1
var promise1 = function(param1){
  ...
  return $q.when(response1);
}

//promesa 2
//"param2" tiene la misma estructura que "response1"
var promise2 = function(param2){
  ...
  return $q.when(response2);
}


var exec = function(){ 
  self.promise1().then(promise2).then(
    function(response2){ ... }
  );
);
$q.all

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.

* If you provide them as an array, then the values will be available as an array with the same corresponding order of the promises array.

var promises = [promiseAlpha(), promiseBeta(), promiseGamma()];

$q.all(promises).then(
  function(response){
    console.log(response[0]); // value alpha
    console.log(response[1]); // value beta
    console.log(response[2]); // value gamma
    console.log("complete");
  }
});


//if you provide an object literal to all(), the values are attached to an object with the same corresponding property names
var promises = {alpha: promiseAlpha(), beta: promiseBeta(), gamma: promiseGamma()}

$q.all(promises).then(
  function(response){
    console.log(response.alpha); // value alpha
    console.log(response.beta);  // value beta
    console.log(response.gamma); // value gamma
    console.log("complete");
  }
});


//si utilizamos un array de promesas vacio se considera como resuelta
var promises = [] 
$q.all(promises).then((values) => {
  console.log("complete");
});
$q.when
var deferred = $q.defer();
deferred.resolver("respuesta");
return deferred.promise;

Es lo mismo que:

return $q.when("respuesta");
Using promises in angular views

Podemos asignar directamente la respuesta de una promesa a una variable del $scope y se mostraran los resultados en el html

angular.module('myModule', []).controller('HelloCtrl', function($timeout, $q, $scope) {
  var getMessages = function() {
    var deferred = $q.defer();
  
    $timeout(function() {
       deferred.resolve(['Hello', 'world']);
    }, 10000);
  
      return deferred.promise;
  };
   

  $scope.messages = getMessages().then(
    function(response){ return response; }
  });

<br /> <body ng-app="myModule" ng-controller="HelloCtrl"></p> <h1>Messages</h1> <ul> <li ng-repeat="message in messages">{{ message }}</li> </ul> <p></body><br />
Fuente
https://docs.angularjs.org/api/ng/service/$q
http://www.martin-brennan.com/using-q-all-to-resolve-multiple-promises/
http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/
http://taoofcode.net/promise-anti-patterns/

WordPress: Cambiar Tema

1) Apariencia -> Temas (A la izquierda)

wordpress_apariencia_temas

2) Añadir nuevo

wordpress_apariencia_anadir_nuevo

3) Seleccionar pestaña Recientes

wordpress_apariencia_recientes

4) Buscar y seleccionar tema

wordpress_apariencia_seleccionar_tema

5) Instalar tema

wordpress_apariencia_instalar_tema

6) Activar tema

wordpress_apariencia_activar_tema

7) Personalizar tema: Las opciones de personalización del tema pueden diferir entre un tema y otro.

wordpress_apariencia_personalizar_tema

Nota: La opción de personalizar puede ser accedida desde el menú a la izquierda: Apariencia -> Personalizar

wordpress_apariencia_personalizar

WordPress: Agregar nueva entrada

1) Nueva entrada (arriba a la izquierda)

wordpress_nueva_entrada

2) Escribir el título de la entrada

wordpress_entrada_titulo

3) Seleccionar la opción “Visual”

wordpress_opcion_visual

4) Seleccionar la opción “Más Herramientas”

wordpress_mas_herramientas

5) Escribir el contenido de la entrada

wordpress_contenido_entrada

6) Seleccionar Categoría (a la derecha)

wordpress_categoria

7) Opcional: Asignar Imagen Destacada (abajo a la derecha)

wordpress_imagen_destacada_entrada

8) Publicar (arriba a la derecha)

wordpress_publicar_entrada

Contratos Ágiles

 

Introducción
  • Las especificaciones nunca se entenderán completamente.
  • El usuario no sabrá lo que quiere hasta que el sistema esté en producción
  • Un sistema nunca puede ser totalmente especificado, ni totalmente testado
  • No se puede determinar el costo ni el tiempo que durará un proyecto
Contrato

Cuando un CLIENTE necesita de un SERVICIO que ofrece un PROVEEDOR para completar un PROYECTO se define un CONTRATO, que consiste en un ACUERDO entre ambas partes en el cual debe indicarse:

  • PARTES
  • CAUSA
  • SERVICIO
  • CONSENTIMIENTO (firma)
  • REGLAS: Regirán el servicio y permitirán mantener el acuerdo durante la prestación

EN TEORÍA: Las reglas se acuerdan libremente por ambas partes para crear condiciones óptimas que permitan completar con éxito el proyecto. En este acuerdo las dos partes “ganan”.

EN PRÁCTICA: Cada parte tratará de sacar ventaja.

Triángulo de Hierro

Triángulo de Hierro
* Si se modifica una variable, alguna otra también tiene que ser modificada. En caso contrario se pone en riesgo la calidad.
* En un contrato ágil el acuerdo entre las partes se tiene que poder revisar regularmente de manera ligera.
* Debe prestarse mucha atención en definir las reglas en base al alcance, costo y tiempo establecidos.

Metodología Ágil

Parte de los siguientes valores (definidos en el “Agile Manifesto”):

  • individuos y su interacción, por encima de los procesos y las herramientas.
  • software que funciona, por encima de la documentación exhaustiva.
  • Colaboración con el cliente, por encima de la negociación contractual.
  • Respuesta al cambio, por encima del seguimiento de un plan.

Se basa en el desarrollo de software iterativo. Se emplean ciclos cortos involucrando al cliente para definir y priorizar requerimientos, con el objetivo de que, a través de la colaboración con el equipo de desarrollo, se disponga de un producto potencialmente entregable al final de cada iteración.

El equipo de desarrollo es multifuncional y auto-organizado, es decir, es responsable de organizarse y gestionarse a sí mismo, siendo capaz de encontrar una solución a un problema sin que se le dictamine cómo debe resolverse.

La definición de un Contrato Agile supone un cambio de mentalidad que debe cubrir varios aspectos:

  • Colaboración estrecha y confianza mutua entre el cliente y el proveedor. La comunicación es esencial para facilitar la colaboración y creación de sinergias para obtener mejores soluciones.
  • Rápida capacidad de reacción ante imprevistos en el desarrollo
  • Flexibilidad en los requisitos del producto o servicio
  • Cobro por entrega de “valor”

Si en algún momento durante el proyecto hay que recurrir al contrato que se firmó al inicio, posiblemente esta sea una mala señal de que las cosas están empezando a ir mal y que la confianza se está deteriorando.

Desventajas de los contratos tradicionales

En el inicio del proyecto se intenta disponer de todos los requisitos detallados (abordar toda la complejidad funcional de una vez), elaborando un análisis funcional que formará parte del contrato.

Desventajas

  • Se deben plantear hipótesis antes de disponer de toda la información necesaria y de poder entender mejor el producto y contexto en que se va a desarrollar.
  • El cliente deberá pedir en el contrato todo lo que se imagine que en algún momento pueda ser necesario
  • Durante el desarrollo del proyecto aparecerán requisitos no relevantes
  • La verificación del cumplimiento de las expectativas del cliente, se deja para la última etapa, favoreciendo la imposibilidad de detectar requisitos no relevantes en etapas tempranas.
  • Las hipótesis que no hayan sido correctas y los requisitos no detectados a tiempo, llevarán a la necesidad de alterar drásticamente el triángulo de hierro, reduciendo notablemente la calidad del producto (o en el peor caso descartando al producto)
Contrato Marco

Permite incorporar anexos sin necesidad de una nueva negociación completa por las partes.

CONTENIDO:
Cláusulas comunes a cualquier contrato: Partes, fecha, dominio, etc.
Objeto del contrato: Debe especificar que las obligaciones se irán concretando a posteriori mediante la firma de anexos en los que se definirán las iteraciones.
Obligaciones de las partes: Además de las obligaciones comunes (formas y plazos de entrega, y de pago), hay que hacer hincapié en las obligaciones que derivan de trabajar con metodologías ágiles:

  • Duración del Sprint
  • Imposibilidad de modificar un sprint una vez definido
  • Periodicidad de reuniones
  • Pago por release
  • Procedimiento de cambio del product backlog, no solo para inlcuir nuevas funcionalidades sino también para priorizarlas y cuantificar en items el desarrollo de cada una de ellas

Glosario de términos Se recomienda incluir un glosario de términos
Product Backlog: El cliente es responsable de este documento y por tanto quien a definir y priorizar las funcionalidades de su producto/servicio. El proveedor establecerá el peso de cada funcionalidad. Si bien es mutable, el Product Backlog sirve como base inicial, se recomienda incluirlo como Anexo I.
Incumplimientos y sus consecuencias: Definir qué se considera incumplimiento de las obligaciones de cada una de las partes y que consecuencias tendrán. Por ejemplo se puede indicar las consecuencias que tendrá los retrasos en un sprint, o la cancelación anticipada del proyecto.
Pago inicial: Suele establecerse un pago por el asesoramiento técnico en la definición del Product Backlog y en la elaboración de presupuesto y contrato marco.
Cláusulas especificas de la prestación de servicios: Propiedad del código, mantenimiento de los desarrollos, backups, contratación de servidores, etc.

Tipos de Contrato

Contrato cerrado (AF CF)
* No ceptar cambios.
* Reducir feedback
* Descomponer el proyecto en varias fases de AC y CF.

Contrato Alcance No Vinculante (AV CF)
* Cambios sobre requisitos no desarrolldos que no modifiquen A
* Finalización anticipada (con retribución)
* Pago de tareas adicionales. Se recomienda primero completar los requisitos “baseline”
* Si se establece PF: Hacer tanto como se pueda en ese plazo

Contrato Objetivo (AF CV)
* Compartir ganancias y pérdidas: Fomenta que las partes colaboren y vayan mejorando.

Contrato Progresivo (AV y CV)
Dos alternativas:
* Pago fijo por iteración
* Pago por costo de iteración.

Aceptación del producto

Consta de dos pasos principales:
1) Revisión presencial.
2) Período de aceptación.

Uno de los riesgos concernientes al proceso de aceptación es que el cliente pierda la perspectiva de la globalidad del proyecto o del objetivo de la iteración, dando lugar reclamos. Se recomienda mostrar al finalizar cada iteración.
* Una visión del baseline, el trabajo ya realizado, pendiente, cambios o agregados respecto al alcance global, en forma de mapa del producto.
* La velocidad de desarrollo y la proyección de fecha estimada de finalización.

Referencias

WebService (WS)

Introducción

Concepto

Tecnología para el intercambio de información entre diferentes aplicaciones (clientes, consumidores) ejecutadas en cualquier plataforma.

Servidor

Un servidor que implementa un WS debe proveer un WSDL para que los clientes puedan obtener información de dónde y cómo conectarse.
Generalmente los lenguajes de programación permiten generar fácilmente un servidor de WS y generar automáticamente el WSDL.

Cliente

La conexión a un WS generalmente se realiza mediante el protocolo SOAP – Simple Object Access Protocol (que es una abstracción de HTTP) o directamente con HTTP, por ejemplo, a través de formularios web.
Generalmente los lenguajes de programación permiten codificar y decodificar mensajes a través del protocolo SOAP fácilmente sin la necesidad de conocer en detalle su estructura.

WebService Description Language: WSDL

Documento XML que especifica la ubicación del WS y sus métodos

Estructura del WSDL (EN CONSTRUCCIÓN)

Estructura básica

Para facilitar la visualización del árbol XML del WSDL y sus relaciones, podemos organizarlo en un diagrama correspondiente al siguiente ejemplo: http://www.w3schools.com/webservices/tempconvert.asmx?WSDL

Ver ejemplo en wsdl.xml (se recomienda abrirlo mediante un navegador porque facilita la visualización). El ejemplo se puede ver en la siguiente URL:
Descripción de los elementos principales
types: data type definitions. For maximum platform neutrality, WSDL uses XML Schema syntax to define data types.
message: Definition of the data being communicated. Each message can consist of one or more parts. The parts can be compared to the parameters of a function call in a traditional programming language.
portType: Description of a web service, the operations that can be performed, and the messages that are involved. It can be compared to a function library (or a module, or a class) in a traditional programming language.
binding: Data format and protocol for each port type.
service: Descripción del servicio y el acceso principal del webservice

WebService de Facturación Electrónica de AFIP

Introducción

¿Cómo se puede realizar la Facturación Electrónica?

1) Comprobantes en línea.
2) Web services de negocio.

¿Qué es un Web Service de Negocio y quienes pueden utilizarlo?

Ente Externo (EE) Cualquier cliente que desee utilizar el webservice y esté registrado en el servicio de autorización de la AFIP.

Cliente de Ente Externo (CEE) Cliente de Webservice desarrollado por un EE.

Webservice de Negocio de la AFIP (WSN) Herramienta utilizada para el intercambio de información entre AFIP y los EE en forma directa sin intervención de operadores.

AFIP proporciona dos entornos para uso del WSN: 1) Testing u homologación, y 2) Producción

Certificados Digitales

Para acceder a los WSN se necesita un Certificado Digital o Certificado Electrónico.
Para definir un Certificado Digital se necesita un CSR.
Para definir un CSR se necesita una PK y un DN.

Distinguished Name (DN)

Un DN, sirve como identificación única de una entidad.
A continuación se define un DN utilizando los siguientes datos:

  1. Nombre de la empresa = Supersistemas SRL
  2. Cuit de la empresa o del programador = 20-12345678-9
  3. Nombre de la aplicación = Supersistema Negriazul
  4. País = Argentina
DN = "/C=AR/O=Supersistemas SRL/CN=Supersistema Negriazul/serialNumber=CUIT 20123456789"
Definir Solicitud de Certificado Digital (Certificate Signing Request – CSR)

Tanto para el ambiente de testing u homologación como para el ambiente de producción, necesitamos un CSR; utilizar un CSR diferente para cada ambiente.

Para generar el CSR se utiliza el sistema RSA y librerías OpenSSL
RSA Sistema criptográfico de clave pública
OpenSSL Proyecto de software libre que implementa protocolos de seguridad y criptografía.

En forma sintética, el procedimiento de generación de CSR es:

1) Generar una clave privada (será llamada también firma electrónica) utilizando RSA, de longitud 2048 bits, utilizando el algoritmo sha1

2) Generar CSR utilizando la clave privada del paso 1 y el DN.

Ejemplo: Terminal linux o windows (forma que enseñan en AFIP)

openssl genrsa -out pk.key 2048 #generar clave privada y almacenarla en archivo pk

openssl req -new -key pk.key -subj "/C=AR/O=Supersistemas SRL/CN=Supersistema Negriazul/serialNumber=CUIT 20123456789" -out csr.crt
 #generar CSR y almacenarlo en el archivo csr.crt
Extensión “.crt” y backup de los archivos generados

Conviene almacenar los CSR y posteriormente los certificados con extensión “.crt”, el SO proporciona una interfaz amigable para visualizar este tipo de extensión. Se podrá visualizar entre otras cosas el DN del CSR y del certificado digital.

Hacer backup de los archivos generados y de la clave privada, porque serán vueltos a utilizar!!!

Generar Certificados en el Ambiente de Homologación (Testing)

Introducción

Para definir un Certificado Digital en el ambiente de homologación, se dispone de una servicio AFIP denominado “WSASS – Autogestión Certificados Homologación”.

Sea R el representante de la empresa E, en homologación se trabaja con los datos de R, el DN debe definirse con el CUIT de R.

Activar servicio WSASS
  1. Configurar el navegador para permitir ventanas emergentes en el sitio de AFIP
  2. Ingresar al sitio de www.afip.gob.ar autenticándose con clave fiscal (mínimo nivel 2)
  3. Ingresar a “Administrador de Relaciones de Clave Fiscal”.

    Se nos mostrará una interfaz similar a la siguiente (en la cabecera, seguramente se actuará en representación de sí mismo)

  4. Seleccionar opción “Adherir Servicio”
  5. Buscar servicio: Servicios interactivos -> WSASS – Autogestión Certificados Homologación
  6. Cerrar la sesión y acceder nuevamente, ya tendremos habilitado el servicio.
  7. En caso de no visualizar el servicio en la lista, debe aceptar la relación utilizando el servicio “Aceptación de Designación”.
Definición del Certificado Digital (este paso es muy fácil, se entiende mejor directamente jugando con el WSASS)

Para obtener el certificado, distinguimos dos casos según si el DN ya fue dado de alta (DN existente) o si aún no existe. Según sea el caso, se debe completar alguno de los formularios on line:

Acceso a Formulario para obtener el certificado por primera vez: Se solicitará un nombre simbólico para identificar al DN que puede ser por ejemplo un string que identifique a la empresa y el CSR definido anteriormente

Formulario para obtener otro certificado adicional (para un DN existente): Se deberá seleccionar el DN existente que será identificado con un alias.

Una vez completo el formulario se definirá un string con el certificado digital que deberá copiarse y almacenarse con extensión “.crt”. Por ejemplo “ghf.crt”.

Gestión de acceso a servicios (este paso es muy fácil, se entiende mejor directamente jugando con el WSASS)

Una vez generado el DN y obtenido el certificado, se puede solicitar autorización de acceso a los servicios de AFIP. Lo primero que debemos hacer es seleccionar el servicio del catálogo y una vez seleccionado, completar el formulario de autorización.

En el formulario de autorización deben completarse los siguientes datos:

* Alias del DN del CSR (se selecciona a través de un select html)
* CUIT representado
* CUIT de quien genera la autorización

Se denomina Computador Fiscal al certificado digital delegado a un determinado servicio.

Ver el catálogo de servicios disponibles

Formulario de autorización de acceso a servicio

Generar Certificado Digital (Producción)

Introducción

Para definir un Certificado Digital en el ambiente de producción, se dispone de una servicio AFIP denominado “Administrador de Certificados Digitales”

Sea R el representante de la empresa E, en producción se trabaja con los datos de E, el DN debe definirse con el CUIT de E.

Activar servicio Administrador de Certificados Digitales
  1. Configurar el navegador para permitir ventanas emergentes en el sitio de AFIP
  2. Ingresar al sitio de www.afip.gob.ar autenticándose con clave fiscal (mínimo nivel 3)
  3. Ingresar a “Administrador de Relaciones de Clave Fiscal”.

    Se nos mostrará una interfaz similar a la siguiente

    ejemplo_administrador_relaciones2

  4. Seleccionar opción “Adherir Servicio”
  5. Buscar servicio: Servicios interactivos -> WSASS – Administración de Certificados Digitales
  6. Cerrar la sesión y acceder nuevamente, ya tendremos habilitado el servicio.
  7. En caso de no visualizar el servicio en la lista, debe aceptar la relación utilizando el servicio “Aceptación de Designación”.
Generación de Certificado digital
  1. Configurar el navegador para permitir ventanas emergentes en el sitio de AFIP.
  2. Ingresar al sitio de www.afip.gob.ar autenticándose con clave fiscal. (nivel 3)
  3. Acceso a “Administración de Certificados Digitales” (opcional: seleccionar la empresa representada, solo si se tiene más de una empresa delegada)
  4. Para solicitar un nuevo certificado digital, deberá presionar el botón “Agregar Alias”. Se proporciona un formulario donde se indica el CUIT de la empresa (que es la que solicita el certificado), un campo para completar el alias (que es un string que identifica al certificado) y un campo para subir el CSR.
  5. Cliquear en “Ver” para poder visualizar y descargar a su PC el certificado.
    alias_ver

Los certificados emitidos por AFIP tienen una vigencia de 2 años. Una vez vencido, deberá repetir el proceso utilizando el mismo alias pero con nuevos CSR y PK. Se sugiere verificar la fecha de vigencia del certificado emitido para planificar su renovación con
anticipación.

Generar Computador Fiscal: Asociar alias a WSN

Se denomina Computador Fiscal al certificado digital delegado a un determinado servicio.

  1. Configurar el navegador para permitir ventanas emergentes en el sitio de AFIP
  2. Ingresar al sitio de www.afip.gob.ar autenticándose con clave fiscal (nivel 3)
  3. Seleccionar el servicio “Administrador de Relaciones de Clave Fiscal”
  4. Seleccionar “Nueva Relación”
  5. Buscar y seleccionar el WSN deseado, por ejemplo “ws – Facturación Electrónica”
  6. Buscar y seleccionar el representante: Debe seleccionar el nombre del alias que utilizó cuando generó el certificado digital
  7. CONFIRMAR

Ejemplo:


Punto de venta electrónico

Para facturar electrónicamente se debe definir un punto de venta electrónico

En testing u homologación no hace falta definir un punto de venta electrónico, se puede utilizar cualquier número que será aceptado.

En producción el punto de venta electrónico se da de alta a través del sitio de la AFIP ingresando con cuit y clave, accediendo al servicio de puntos de venta.

Configuración del WebService de Facturación Electrónica de AFIP

Introducción

Para acceder a WSFE se necesitan, por cada HOST las siguientes constantes:
* Punto de venta //exclusivo de cada HOST
* Certificado //exclusivo de cada HOST
* Clave privada //exclusivo de cada HOST
* CUIL de la empresa
* WSDL del WSFE
* WSDL del WSAA
* Path al archivo del TRA
* Path al archivo del TA

Para acceder a WSFE se necesita un TOKEN y un SIGN
El TOKEN y el SIGN se extraen del TA
Ejemplo PHP
define("CUIT",  231234567890); //testing
//define("CUIT",  301234567890); //produccion

define("CERT" , $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/config/test/cert.crt");     //certificado testing
//define("CERT" , $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/config/prod/cert.crt");     //certificado produccion

define("PRIVATEKEY" , $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/config/test/pk.key"); //clave privada testing
//define("PRIVATEKEY" , $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/config/prod/pk.key"); //clave privada produccion
define("PASSPHRASE" , ""); //frase asociada a la clave privada

define("WSAA", "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl"); //wsdl wsaa testing
//define("WSAA", "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"); //wsdl wsaa prod

define("WSFE_WSDL", "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL"); //wsdl wsfe testing
//define("WSFE_WSDL", "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL"); //wsdl wsfe produccion

//***** INDENTIFICACION DE ARCHIVOS GENERADOS *****
define("WSFE_TRA", $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/files/TRA_wsfe_test.xml"); //wsfe tra testing
//define("WSFE_TRA", $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/files/TRA_wsfe.xml"); //wsfe tra produccion
define("WSFE_TA", $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/files/TA_wsfe_test.xml"); //wsdl wsfe testing
//define("WSFE_TA", $_SERVER["DOCUMENT_ROOT"] . "/" . PATH_SYS . "/lib/afip/files/TA_wsfe.xml"); //wsdl wsfe produccion

//***** CONSTANTES DEL WSFE (FACTURACION ELECTRONICA) *****
define("WSFE_PUNTOVENTA", 4); //punto de venta RECE

Información Adicional

Comprobantes en línea

Para los comprobantes en línea simplemente se debe acceder con clave fiscal en la web de la AFIP y acceder al servicio “Comprobantes en línea”. Los detalles se encuentran especificados en el siguiente enlace http://www.afip.gov.ar/genericos/guiaDeTramites/guia/documentos/PasoaPasoServiciosCF.pdf o en el documento acceso_comprobantes_linea_monotributistas.pdf.

Generar CSR a través de PHP
$config = array( 
    "digest_alg" => "sha1", 
    "private_key_bits" => 4096, 
    "private_key_type" => OPENSSL_KEYTYPE_RSA, 
); 
 
// Create the private and public key 
$res = openssl_pkey_new($config); 

// Extract the private key from $res to $privKey 
openssl_pkey_export($res, $privKey); 

$dn = array( 
    "countryName" => "AR", 
    "organizationName" => "Supersistemas SRL", 
    "commonName" => "Supersistema Negriazul", 
    "serialNumber" => "CUIT 20123456789" 
); 

// Generate a certificate signing request 
$csr = openssl_csr_new($dn, $privkey); 

openssl_csr_export($csr, $csrout) and var_dump($csrout); 

Comandos adicionales PHP interesantes
// You will usually want to create a self-signed certificate at this 
// point until your CA fulfills your request. 
// This creates a self-signed cert that is valid for 365 days 
$sscert = openssl_csr_sign($csr, null, $privkey, 365); 

// Now you will want to preserve your private key, CSR and self-signed 
// cert so that they can be installed into your web server, mail server 
// or mail client (depending on the intended use of the certificate). 
// This example shows how to get those things into variables, but you 
// can also store them directly into files. 
// Typically, you will send the CSR on to your CA who will then issue 
// you with the "real" certificate. 
openssl_csr_export($csr, $csrout) and var_dump($csrout); 
openssl_x509_export($sscert, $certout) and var_dump($certout); 
openssl_pkey_export($privkey, $pkeyout, "mypassword") and var_dump($pkeyout); 

// Show any errors that occurred here 
while (($e = openssl_error_string()) !== false) { 
    echo $e . "\n"; 
}
Detalle del DN
"countryName" (c) DEBE representar el país en el cual está constituida la Persona Jurídica, codificado según el estándar [ISO3166].
"stateOrProvinceName"
"localityName"
"organizationName" (o) DEBE coincidir con el nombre de la Persona Jurídica Pública o Privada.
"organizationalUnitName" (ou)
"commonName" (cn) DEBE corresponder al nombre del servicio o aplicación (ej. Sistema de Consulta) o al nombre de la unidad operativa responsable del servicio (ej. Gerencia de Compras)
"emailAddress"
"serialNumber" DEBE contener el número de identificación de la Persona Jurídica Pública o Privada, expresado como texto y respetando el siguiente formato y codificación: "CUIT numero_de_cuit" (ej: “CUIT 20123456780”)
Formato pkcs 12

Según la tecnología que elija utilizar para llevar a cabo el desarrollo puede llegar a necesitar el certificado en formato pkcs12 (certificado x509 + clave privada). Por ejemplo, con el cliente en .NET contribuido. Para generarlo debe ejecutar desde la línea de comando:

openssl pkcs12 -export -inkey privada -in certificado.crt -out alias.p12
Error windows “La contraseña de red especificada no es válida”

En algunos equipos Windows al invocar al WSAA para obtener su ticket de acceso puede llegar a obtener el siguiente mensaje de error: “La contraseña de red especificada no es válida”.

Este error tiene que ver con el problema de que Windows parece no entender que el pkcs#12 generado con openssl no tiene password. La solución es importar el certificado al repositorio de Windows (Control panel/Internet Options/Contents/Certificates). Luego volver a exportarlo (hasta la versión 7 de Internet Explorer no es obligatorio ponerle password). Tener en cuenta que debe tildar la opción “Marcar esta clave como exportable”.

Detalle de los certificados digitales

Los Certificados Digitales emitidos por la AFIP están basados en el estándar X.509v3

X.509 es un estándar para infraestructuras de claves públicas (Public Key Infrastructure o PKI). Los formatos de codificación más comunes utilizados en el estándar X.509 son DER (Distinguish Encoding Rules) o PEM (Privacy Enhanced Mail).

Opciones del WSASS
A continuación se listan las opciones provistas por el WSASS, todas ellas pueden ser accedidas a través del menú:
* Formulario para obtener el certificado por primera vez: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/crearcomputador.aspx
* Formulario para obtener otro certificado adicional (para un DN existente): https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/crearcomputador.aspx
* Ver los certificados emitidos para una CUIT: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/certificadosdecuit.aspx 
* Formulario para eliminar un DN y su certificado: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/eliminarcomputador.aspx
* Ver el catálogo de servicios disponibles: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/servicios.aspx
* Formulario de autorización de acceso a servicio: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/crearautorizacion.aspx
* Ver autorizaciones a servicios: https://wsass-homo.afip.gob.ar/wsass/portal/Autoservicio/autorizacionesdecuit.aspx

Fuente

Enlaces

Página Principal
Paso a paso servicios
X.509 (wikipedia)
OpenSSL (wikipedia)
OpenSSL (oficial)
RSA (wikipedia)
PHP OPENSSL create private key
PHP OPENSSL create CSR

OpenSSL

Si tiene acceso a un servidor Unix/Linux, seguramente, ya lo tiene instalado. Si sólo tiene acceso a equipos Windows, puede bajar openSSL de:
http://www.slproweb.com/products/Win32OpenSSL.html
http://www.openssl.org

Contacto

Para consultas de programadores usando el Entorno de Testing: Enviar su consulta directamente desde la aplicación WSASS (Autoservicio de Acceso a WebServices en Homologación), menú: “Contáctenos”. Alternativamente enviar un correo electrónico a webservices-desa@afip.gob.ar
Para consultas del Entorno de Producción: Enviar un correo electrónico a sri@afip.gob.ar
En caso de tener otras dudas genéricas acerca de la información de este micrositio, comunicarse accediendo a www.afip.gob.ar/consultas

Seguridad en PHP

Diccionario de datos

Usuario: Datos de usuario

nombre nombre del usuario
clave clave del usuario
intentos cantidad de intentos de acceso erroneos
bloqueado flag para indicar si esta bloqueado el usuario
activo flag para indicar si esta activo el usuario
alta fecha de alta de usuario

Ip: Datos de las ip de acceso

numero numero de ip
intentos cantidad de intentos de una determinada ip
bloqueada flag para indicar si esta bloqueada la ip
alta fecha de alta de ip

Sessión

Variables principales de identificacion de sesion
$_SESSION["userid"] //identificacion de usuario
$_SESSION["loggedin"] //flag para identificar si el usuario se encuentra logeado
Asignación de tiempos de sesión
//***** Asignar tiempo de expiracion *****
$_SESSION['start'] = time();
$_SESSION['expire'] = $_SESSION['start'] + (5 * 60);

//***** Controlar tiempo de expiracion *****
$now = time();
if($now > $_SESSION['expire']) session_destroy();

Información adicional

Protección de la base de datos

* mecanismo de autorización de Apache
* modelos de acceso de diseño propio usando LDAP, archivos .htaccess, etc.

open_basedir

Mediante el uso de open_basedir se puede controlar y restringir qué directorios pueden ser usados por PHP. También se pueden definir áreas solo-Apache, para restringir todas las actividades basadas en web a archivos que no son de usuarios o del sistema.

Escapar caracteres al acceder a la base de datos
$username = mysqli_real_escape_string($db,$_POST['username']);
$password = mysqli_real_escape_string($db,$_POST['password']);  

$username = pg_escape_string($db,$_POST['username']);
$password = pg_escape_string($db,$_POST['password']);  
Registrar la cantidad de intentos de acceso
//en construcción
Bloquear ip
//**** Funcion para obtener la ip ******
function ip() {
    if (getenv('HTTP_CLIENT_IP')) return getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR')) return getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED')) return  getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR')) return getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED')) return getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR')) return getenv('REMOTE_ADDR');
    else return null;
}

//**** Funcion alternativa para obtener la ip ******
// Function to get the client IP address
function ip() {
    if (isset($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED'])) return $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) return $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED'])) return $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR'])) return $_SERVER['REMOTE_ADDR'];
    else return null;
}