Referencia API SOAP Webpay Transbank S.A.

Transcripción

Referencia API SOAP Webpay Transbank S.A.
Referencia API
SOAP Webpay
Transbank S.A.
D OCUMENTO DE ESPECIFI CACIONES TRANSACCIÓN C OMPLETA
( V 1.3)
Transbank S.A.
10/10/2012
0
Contenido
1
Control de cambios ..................................................................................................................... 2
2
Prefacio ....................................................................................................................................... 2
3
4
2.1
Acerca de esta guía ............................................................................................................. 2
2.2
Audiencia ............................................................................................................................. 2
2.3
Feedback para esta documentación ................................................................................... 3
Transacción de Autorización Completa....................................................................................... 4
3.1
Descripción de la Transacción de Autorización Completa .................................................. 4
3.2
Secuencia de pago en una transacción de autorización completa ..................................... 5
3.3
Descripción de métodos del Servicio Web de Transacción de Autorización Completa ...... 7
3.3.1
Operación initCompleteTransaction .......................................................................... 7
3.3.2
Operación queryShare................................................................................................ 9
3.3.3
Operación autorize ................................................................................................... 11
3.3.4
Operación acknowledgeCompleteTransaction ........................................................ 14
Anexo C: Ejemplos de integración con API SOAP Webpay ....................................................... 15
4.1
Ejemplo Java ...................................................................................................................... 16
4.2
Ejemplos PHP .................................................................................................................... 21
4.3
Ejemplos .Net .................................................................................................................... 27
Página 1
1 Control de cambios
Fecha
12-12-12
Version
1.0
19-12-12
28-01-12
14-02-13
1.1
1.2
1.3
Descripción del cambio
Liberación inicial de documento general de API de integración con WS
Transacción Completa.
Futuros Release:
Ejemplos de integración PHP, .NET.
Se agrega ejemplo de integración PHP
Se agrega ejemplo C# .Net
Se modifica formato de fecha de expiración de tarjeta de crédito de
YYMM a YY/MM.
2 Prefacio
2.1 Acerca de esta guía
Esta guía describe los aspectos técnicos que deben ser considerados en la integración con Webpay
utilizando API SOAP, describe el servicio Web para Transacción de Autorización Completa, sus
operaciones y cómo estas deben ser utilizadas en un flujo de pago. Se incluyen ejemplos para cada
tipo de transacción Webpay que sirven como guía al utilizar lenguajes Java, C# y PHP.
2.2 Audiencia
Esta guía está dirigida a implementadores que realizan la integración de Webpay en comercios
utilizando la API SOAP para soportar en estos el pago con tarjetas bancarias tipo transacción
completa..
Se recomienda que quién realice la integración posea conocimiento técnico de al menos en los
siguientes temas:
Servicios Web
WS-Security
Firma digital, generación y validación.
Página 2
2.3 Feedback para esta documentación
Ayúdanos a mejorar esta información enviándonos comentarios a [email protected]
Página 3
3 Transacción de Autorización Completa
3.1 Descripción de la Transacción de Autorización Completa
Una transacción completa de Webpay corresponde a una solicitud de autorización financiera de
un pago con tarjetas de crédito, en donde quién realiza el pago ingresa al sitio del comercio,
selecciona productos o servicio, y el ingreso asociado a los datos de la tarjeta de crédito lo realiza
directamente en el sitio del comercio. Es responsabilidad del comercio proveer de un ambiente
seguro para realizar la captura de la información asociada a la tarjeta de crédito, y eliminar dicha
información una vez finalizada la transacción.
El flujo de páginas para la transacción es el siguiente, notar que todas las páginas son generadas
por el comercio:
Selección de
productos /
servicios
Ingreso de
tarjeta de
crédito
Selección de
cuotas
Resultado de
transacción
…….
Resumen de los métodos del servicio Web de Transacción Completa1
Método
initCompleteTransaction
queryShare
authorize
acknowledgeCompleteTr
ansaction
Descripción general
Permite inicializar una transacción en Webpay, como respuesta a
la invocación se genera un token que representa en forma única
una transacción.
Es importante considerar que una vez invocado este método, el
token que es entregado tiene un periodo reducido de vida de 5
minutos, posterior a esto el token es caducado y no podrá ser
utilizado en un pago (la transacción saldrá rechazada).
Permite realizar consultas del valor de cuotas (producto nuevas
cuotas).
Ejecuta la solicitud de autorización, esta puede ser realizada con o
sin cuotas. La respuesta entrega el resultado de la transacción.
Permite indicar a Webpay que se ha recibido conforme el
resultado de la transacción.
El método acknowledgeCompleteTrasaction debe ser
invocado siempre, independientemente del resultado
entregado por el método authorize. Si la invocación
1
El detalle de los métodos se encuentra en la sección 3.3
Página 4
no se realiza en un período de 40 segundos, Webpay reversará
la transacción, asumiendo que el comercio no pudo informarse
de su resultado, evitando así el cargo al tarjetahabiente.
3.2 Secuencia de pago en una transacción de autorización completa
El siguiente diagrama ilustra la secuencia de pago y cómo participan los distintos actores en una
transacción completa.
sd Secuencia pago completa
Comercio
Webpay
1. initCompleteTransaction()
2. Response() :token...
loop
3. queryShare(token, buyOrder, sharesNumber)
[opcional]
4. Response(queryShareResponse)
5. authorize(token, <List>paymentType)
6. Response()
7. acknowledgeCompleteTransaction(token)
8. Response()
Diagrama de secuencia de Transacción Completa
Página 5
Descripción de la secuencia:
1. Una vez seleccionado los bienes o servicios en el sitio del comercio, el tarjetahabiente
decide pagar a través de Webpay, para lo cual el comercio, en una página segura, solicita
al tarjetahabiente los datos asociados a su tarjeta de crédito, e invoca el método
initCompleteTransaction(…).
2. Webpay procesa el requerimiento y entrega como resultado de la operación el token de la
transacción.
3. El comercio debe preguntar a tarjetahabiente el número de cuotas con el cual requiere
realizar el pago, si este opta por realizarlo en cuotas, se deberá consultar el valor de la
cuota por medio del método queryShare(…).
4. Webpay responde el resultado de la consulta de cuota, entregando el valor de la cuota y si
cuenta con la posibilidad de diferir el pago.
Nota. Los puntos 3 y 4 pueden repetirse tantas veces como el tarjetahabiente lo desee,
hasta que encuentre un número y valor de cuota que le acomode para realizar el pago. La
solicitud de autorización debe realizarse con la opción elegida por el tarjetahabiente.
5. El comercio solicita autorización de la transacción, utilizando el método autohrize(…), con
la opción de pago en cuotas seleccionada por el tarjetahabiente (pasos 3 y 4).
6. Como respuesta a la invocación del método authorize(), Webpay retorna el resultado de la
autorización, la cual puede ser autorizada o rechazada.
7. Para informar a Webpay que el resultado de la transacción se ha recibido sin problemas, el
sistema
del
comercio
debe
consumir
el
tercer
método
acknowledgeCompleteTrasaction().
NOTA: De no ser consumido ó demorar más de 30 segundos en su consumo, Webpay
realizará la reversa de la transacción, asumiendo que existieron problemas de
comunicación.
8. El sitio del comercio despliega al tarjeta habiente la página final del pago, donde debe
estar incluida la información detallada en el Anexo A del manual “Referencia API SOAP
Webpay General”.
Página 6
3.3 Descripción de métodos del Servicio Web de Transacción de
Autorización Completa
A continuación se describen cada uno de las operaciones que deben ser utilizadas en una
Transacción Completa.
3.3.1
Operación initCompleteTransaction
Método que permite iniciar una transacción de pago Webpay.
Parámetro de entrada: type wsCompleteInitTransactionInput
Nombre
transactionType
Descripción
xs:wsTransactionType
sessionId
(Obligatorio) Indica el tipo de transacción, su valor debe ser siempre
TR_COMPLETA_WS
xs:string
(Opcional) Identificador de sesión, uso interno de comercio, este valor es
devuelto al final de la transacción.
cardDetails
Largo máximo: 61
tns:cardDetails
(Obligatorio) Objeto del tipo wsTransactionDetail que contiene información
asociada a la tarjeta de crédito.
transactionDetails
tns:wsTransactionDetail
(Obligatorio) Lista de objetos del tipo wsTransactionDetail, el cual
contiene datos de la transacción. Máxima cantidad de repeticiones es de 1 para
este tipo de transacción.
Página 7
WS T RANSACTION D ETAIL
Descripción: Tipo de dato que contiene detalles de la transacción
Campo
amount
Descripción
xs:decimal
Monto de la transacción.
buyOrder
Largo máximo: 10
xs:string
Orden de compra del comercio.
commerceCode
Largo máximo: 26
xs:string
Código comercio de la tienda
Largo: 12
CARD D ETAILS
Descripción: Tipo de dato que contiene detalles tarjeta de crédito
Campo
cardNumber
Descripción
xs:string
Número de la tarjeta.
cardExpirationDate
Largo máximo: 16
xs:string
Fecha de expiración de tarjeta, formato YY/MM.
cvv
Largo: 5
xs:string
Código de verificación de la tarjeta.
Largo máximo: 4
Página 8
Parámetros de salida: type wsCompleteInitTransactionOutput
Campo
Token
Descripción
xs:string
Token de la transacción.
Largo: 64
3.3.2
Operación queryShare
Método que permite realizar la consulta del valor de una cuota dado el número de cuotas.
Parámetros de entrada: queryShareInput
Campo
Token
Descripción
xs:string
Token de la transacción.
buyOrder
Largo: 64
xs:string
Orden de compra de la transacción.
shareNumber
Largo: 26
xs:int
Número de cuotas.
Largo: 2
Página 9
Parámetros de salida: queryShareOutput
Campo
buyOrder
Descripción
xs:string
Orden de compra de la tienda.
deferredPeriods
Largo máximo: 26
xs:completeDeferredPeriod
Lista de contiene los meses en los cuales se puede diferir el pago, y el
monto asociado a cada periodo.
queryId
xs:long
Identificador de la consulta de cuota.
shareAmount
xs:decimal
Monto de la cuota.
Largo máximo: 10
xs:string
Token
Orden de compra de la tienda.
Largo máximo: 64
COMPLETE D EFERRED P ERIOD
Descripción: Corresponde a un elemento opcional en la respuesta, que dependiendo del
tipo de contrato que tenga el comercio podría o no ser retornado. Informa los posibles
meses en los cuales se puede diferir un pago y el monto asociado para cada uno.
Campo
amount
Descripción
xs:decimal
Monto de la cuota con meses diferido.
period
Largo máximo: 10
xs:int
Número de meses en que se difiere el pago.
Largo máximo: 1
Página 10
3.3.3
Operación autorize
Método que permite solicitar la autorización de una transacción.
Parámetros de entrada: authorize
Campo
token
Descripción
xs:string
Token de la transacción.
paymentTypeList
Largo: 64
tns:wsCompletePaymentTypeInput
(Opcional) Específica para la transacción el número de cuotas con el
cual se realizará, si aplicará meses de pago diferido o mes de gracia.
Para este caso la lista va con un sólo elemento.
WS C OMPLETE P AYMENT T YPE I NPUT
Descripción: Corresponde a un elemento opcional, específica para la transacción el
número de cuotas con el cual se realizará y si aplicará meses de pago diferido.
Campo
commerceCode
Descripción
xs:decimal
Monto de la cuota con meses diferido.
buyOrder
Largo máximo: 10
xs:int
Número de meses en que se difiere el pago.
queryShareInput
Largo máximo: 1
tns:wsCompleteQueryShareInput
gracePeriod
Indica con qué opción de valor de cuota consultada se realizará la
transacción.
xs:boolean
Flag que indica si aplica o no periodo de gracia, valor en true indica
que aplica, en false indica que no aplica. Este flag es válido solamente
para ventas sin cuota.
Página 11
WS C OMPLETE Q UERY S HARE I NPUT
Descripción: Corresponde a un elemento opcional, específica para la transacción el
número de cuotas con el cual se realizará y si aplicará meses de pago diferido.
Campo
idQueryShare
Descripción
xs:long
Identificador de la consulta de cuotas. Este dato es el entregado por el
método de consulta de cuotas.
deferredPeriodIndex
xs:int
(Opcional) Identificador del período diferido con el cual se desea
realizar el pago. (Número del período)(Campo period del objeto
completeDeferredPeriod)
Parámetros de salida: wsCompleteAuthorizeOutput
Campo
accountingDate
Descripción
xs:string
Fecha contable de la autorización de la transacción, la cual más el
desfase de abono indica al comercio la fecha en que Transbank
abonará al comercio.
buyOrder
Largo: 4, formato MMDD
xs:string
Orden de compra de la tienda.
detailsOutput
Largo máximo: 26
tns:wsTransactionDetailOutput
sessionId
Contiene los detalles de la transacción
xs:string
Identificador de sesión, uso interno de comercio, este valor es
devuelto al final de la transacción. Un uso posible puede ser la
representación del intento de pago.
transactionDate
Largo máximo: 61
xs:string
Fecha y hora de la autorización.
Largo: 8
Página 12
WS T RANSACTION D ETAIL O UTPUT
Campo
authorizationCode
Descripción
xs:string
Código de autorización de la transacción
paymentTypeCode
responseCode
amount
Largo máximo: 6
xs:string
Tipo de pago de la transacción.
xs:string
Código de respuesta de la autorización. Valores posibles:
0 Transacción aprobada.
-1 Rechazo de transacción.
-2 Transacción debe reintentarse.
-3 Error en transacción.
-4 Rechazo de transacción.
-5 Rechazo por error de tasa.
-6 Excede cupo máximo mensual.
-7 Excede límite diario por transacción.
-8 Rubro no autorizado.
xs:decimal
Monto de la transacción.
sharesAmount
Largo máximo: 10
xs:decimal
Valor de la cuota.
sharesNumber
Largo máximo: 9
xs:int
Cantidad de cuotas
commerceCode
Largo máximo: 2
xs:string
Código comercio de la tienda
buyOrder
Largo: 12
xs:string
Orden de compra de la tienda.
Largo máximo: 26
Página 13
3.3.4
Operación acknowledgeCompleteTransaction
Método que permite informar a Webpay la correcta recepción del resultado de la transacción.
Parámetros de entrada:
Campo
tokenInput
Descripción
xs:string
Token de la transacción.
Largo: 64
Página 14
4 Anexo C: Ejemplos de integración con API SOAP Webpay
Los siguientes ejemplos tienen por objetivo exponer una forma factible de integración con API
SOAP Webpay para resolver los siguientes puntos asociados a la integración:
1. Generación de cliente o herramienta para consumir los servicios Web, lo cual permite
abstraerse de la complejidad de mensajería SOAP asociada a los Webservice y hacer uso
de las operaciones del servicio.
2. Firma del mensaje y validación de firma en la respuesta, existen frameworks y
herramientas asociadas a cada lenguaje de programación que implementan el estándar
WS Security, lo que se requiere es utilizar una de estas, configurarla y que realice el
proceso de firma digital del mensaje.
Página 15
4.1 Ejemplo Java
Este ejemplo hará uso de los siguientes frameworks para consumir los servicios Web de Webpay
utilizando WS Security:
Apache CXF, es un framewok open source que ayuda a construir y consumir servicios
Web en Java. En este ejemplo se utilizará para:
o
Generar el cliente del Webservice o STUBS.
o
Consumir los servicios Web
Apache WSS4J, proporciona la implementación del estándar WS Security, nos
permitirá:
o
Firmar los mensajes SOAP antes de enviarlo a Webpay.
o
Validar la firma de la respuesta del servicio Web de Webpay.
Spring framewok 3.0, permite que CXF y WSS4J trabajen en conjunto, también se
utiliza para configurar WS Security en la firma del mensaje SOAP.
Pasos a seguir:
1. Generación de cliente del Webservice.
Para generar el código Java que implementará el cliente SOAP se utilizará wsdl2java de
CXF, el cual toma el WSDL del servicio y genera todas las clases necesarias para invocar el
servicio Web. Más información en http://cxf.apache.org/docs/wsdl-to-java.html
wsdl2java -autoNameResolution <URL del wsdl>
Página 16
2. Configuración de WS Security
Para configurar WS Security en CXF se deben habilitar y configurar los interceptores que
realizaran el trabajo de firmado del mensaje. La configuración de los interceptores se
puede realizar a través de la API de servicios Web o a través del XML de configuración de
Spring, en este caso se realizará a través de Spring en el archivo applicationContext.xml de
la aplicación.
Se deben habilitar y configurar 2 interceptores, uno para realizar la firma de los mensajes
enviados al invocar una operación del servicio Web de Webpay y otro para validar la firma
de la respuesta del servicio Web.
Interceptor de salida
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
id="signOutRequestInterceptor">
<constructor-arg>
<map>
<entry key="signaturePropFile" value="signatureOut.properties"/>
<entry key="user" value="${alias.client}"/>
<entry key="action" value="Signature"/>
<entry key="passwordCallbackClass"
value="com.transbank.webpay.wsse.ClientCallBack"/>
<entry key="signatureParts"
value="{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
</map>
</constructor-arg>
</bean>
Interceptor de entrada
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
id="signInRequestInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature" />
<entry key="signaturePropFile" value="signatureIn.properties"/>
<entry key="passwordCallbackClass"
value="com.transbank.webpay.wsse.ServerCallBack"/>
<entry key="signatureParts"
value="{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
</map>
</constructor-arg>
</bean>
Las
interfaz
javax.security.auth.callback.CallbackHandler, su implementación permite al
framework de seguridad recuperar la contraseña para acceder al almacen de llaves de la
aplicación (Java Key Store) que almacena los certificados digitales.
Página 17
clases
ClientCallback
y
ServerCallBack
implementan
la
3. Llamada a operaciones del Webservice
Operación initCompleteTransaction
private WSCompleteWebpayService service;
private WsTransactionDetailOutput detailOutput;
WsCompleteInitTransactionInput input = new WsCompleteInitTransactionInput();
input.setSessionId(“1234567”);
input.setTransactionType(WsCompleteTransactionType.TR_COMPLETA_WS);
WsCompleteTransactionDetail detail = new WsCompleteTransactionDetail();
detail.setAmount(100);
detail.setBuyOrder(“OC_PRUEBA”);
detail.setCommerceCode(“59702512345”);
input.getTransactionDetails().add(detail);
CompleteCardDetail cardDetail = new CompleteCardDetail();
cardDetail.setCardExpirationDate(“13/04”);
cardDetail.setCvv(“123”);
cardDetail.setCardNumber(“4051885600446623”);
input.setCardDetail(cardDetail);
WsCompleteInitTransactionOutput output = service.initCompleteTransaction(input);
token = output.getToken();
Operación queryShare
private WSCompleteWebpayService service;
WsCompleteQuerySharesOutput output = service.queryShare(token, “OC_PRUEBA”, 7);
queryId = output.getQueryId();
shareAmount = output.getShareAmount();
deferredPeriods = output.getDeferredPeriods();
Operación authorize (Sin cuotas)
WsCompletePaymentTypeInput paymentType = new WsCompletePaymentTypeInput();
paymentType.setBuyOrder(“OC_PRUEBA”);
paymentType.setCommerceCode(“59702512345”);
//Si se quiere período de gracia dejar en true
paymentType.setGracePeriod(false);
List<WsCompletePaymentTypeInput> paymentTypeList =
new ArrayList<WsCompletePaymentTypeInput>();
paymentTypeList.add(paymentType);
WsCompleteAuthorizeOutput authorizeOutput =
Página 18
service.authorize(token, paymentTypeList);
accountingDate = authorizeOutput.getAccountingDate();
transactionDate = authorizeOutput.getTransactionDate();
detailOutput = authorizeOutput.getDetailsOutput().get(0);
Página 19
Operación authorize (Usando cuotas)
WsCompletePaymentTypeInput paymentType = new WsCompletePaymentTypeInput();
paymentType.setBuyOrder("OC_PRUEBA");
paymentType.setCommerceCode("59702512345");
WsCompleteQueryShareInput queryShareInput = new WsCompleteQueryShareInput();
queryShareInput.setIdQueryShare(queryId);
queryShareInput.setDeferredPeriodIndex(1);
paymentType.setQueryShareInput(queryShareInput);
List<WsCompletePaymentTypeInput> paymentTypeList =
new ArrayList<WsCompletePaymentTypeInput>();
paymentTypeList.add(paymentType);
WsCompleteAuthorizeOutput authorizeOutput =
service.authorize(token,paymentTypeList);
accountingDate = authorizeOutput.getAccountingDate();
transactionDate = authorizeOutput.getTransactionDate();
detailOutput = authorizeOutput.getDetailsOutput().get(0);
Operación acknowledgeCompleteTransaction
private WSCompleteWebpayService service;
service.acknowledgeCompleteTransaction(token);
URL:
http://cxf.apache.org/docs/ws-security.html
http://ws.apache.org/wss4j/
http://cxf.apache.org/docs/wsdl-to-java.html
Página 20
4.2 Ejemplos PHP
El siguiente ejemplo está basado en PHP versión 5, sobre el cual se utilizaron las siguientes
bibliotecas de software para realizar la invocación de los servicios web de Webpay bajo el estándar
WSS:
Biblioteca de seguridad: archivo compuesto de tres clases que integran librerías nativas
PHP de validación y verificación. Estas clases nos permitirán generar la seguridad
suficiente a través de métodos de encriptación y desencriptación.
WSSE-PHP: integra las librerías de seguridad XML y genera un documento XML-SOAP
seguro. Depende de las librerías de seguridad XML.
SOAP-VALIDATION: clase encargada de la validación de mensajes SOAP seguros de
respuesta. Verifica la autenticidad e integridad del mensaje. Depende de WSSE-PHP.
Los fuentes pueden ser descargados desde https://github.com/OrangePeople/php-wss-validation
Pasos a seguir:
1. Generación de cliente del Servicio Web:
Antes de la integración se debe tener instalado y funcionando un servidor HTTP Apache y
configurar el directorio para generar una salida a través del navegador web. Si se quiere optar
por una alternativa más sencilla, Apache provee un directorio por omisión, que varía según el
sistema operativo. Generalmente en plataformas Linux es “/var/www” y en Windows
“C:\<directorio hacia Apache>/htdocs”.
A continuación, para generar las clases necesarias que conectan a los servicios Web, se puede
utilizar la herramienta Easy WSDL2PHP. La documentación necesaria e información de
descarga se encuentra en http://sourceforge.net/projects/easywsdl2php/.
Una vez descargados los fuentes, se deben copiar en el directorio de apache que posee la
salida por navegador.
Se hace la llamada por navegador del archivo wsdl2php.php y se obtiene la siguiente pantalla:
Página 21
Se escribe la URL del archivo wsdl al se quiere conectar, un nombre de clase y luego se
presiona el botón Generate Code. Luego de esto se muestra una pantalla como la siguiente:
Una vez que se obtiene el resultado mostrado en la imagen se copia el código PHP generado y se
guarda en un archivo, el cual representará el stub del servicio Web. Una vez realizado este proceso
ya se tienen las clases necesarias para poder integrarse con los servicios web de Webpay.
Página 22
2. Crear una clase que extienda de SoapClient (SoapClient es la clase nativa que provee PHP para
utilización de servicios Web)(En el ejemplo se denominará MySoap)
//Notar que se incluyen dos archivos que se proveen en la librería de encriptación
require_once('xmlseclibs.php');
require_once('soap-wsse.php');
class MySoap extends SoapClient {
function __doRequest($request, $location, $saction, $version) {
$doc = new DOMDocument('1.0');
$doc->loadXML($request);
$objWSSE = new WSSESoap($doc);
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1,array('type' =>
'private'));
$objKey->loadKey(PRIVATE_KEY, TRUE);
$options = array("insertBefore" => TRUE);
$objWSSE->signSoapDoc($objKey, $options);
$objWSSE->addIssuerSerial(CERT_FILE);
$objKey = new XMLSecurityKey(XMLSecurityKey::AES256_CBC);
$objKey->generateSessionKey();
$retVal = parent::__doRequest($objWSSE->saveXML(), $location, $saction,
$version);
$doc = new DOMDocument();
$doc->loadXML($retVal);
return $doc->saveXML();
}
}
Las constantes PRIVATE_KEY Y CERT_FILE son las rutas de la llave privada y certificado del
comercio, respectivamente.
3. Incluir la clase generada en el paso anterior en el archivo principal de los servicios.
Se debe incluir con la sentencia require_once la clase generada en el paso anterior.
Ejemplo:
require_once(“mysoap.php”);
Página 23
4. Editar el archivo stub creado en el paso 1
Se debe editar el método __contruct del stub tal como se muestra en el ejemplo:
Donde dice:
$this->soapClient = new SoapClient($url, array("classmap" => self::$classmap,
"trace" => true, "exceptions" => true));
Debe quedar: (utilizando el nombre de clase del paso 2)
$this->soapClient = new MySoap($url, array("classmap" => self::$classmap, "trace"
=> true, "exceptions" => true));
5. Invocación de operaciones del servicio web de Webpay.
Para todos los ejemplos se debe hacer referencia a los archivos de la librería descargada
require_once('soap-wsse.php');
require_once('soap-validation.php');
require_once('<archivo que contiene la clase stub creado en el paso 1>');
Operación initCompleteTransaction:
$wsCompleteInitTransactionInput = new wsCompleteInitTransactionInput();
$completeCardDetail = new completeCardDetail();
$wsCompleteTransactionDetail = new wsCompleteTransactionDetail();
$wsCompleteInitTransactionInput->transactionType = $transactionType;
$wsCompleteInitTransactionInput->sessionId = $sessionId;
$wsCompleteTransactionDetail->amount = $amount;
$wsCompleteTransactionDetail->buyOrder = $buyOrder;
$wsCompleteTransactionDetail->commerceCode = $commerceCode;
$completeCardDetail->cardExpirationDate = $cardExpirationDate;
$completeCardDetail->cvv = $cvv;
$completeCardDetail->cardNumber = $cardNumber;
$wsCompleteInitTransactionInput->commerceId = $commerceCode;
$wsCompleteInitTransactionInput->buyOrder = $wsCompleteTransactionDetail>buyOrder;
$wsCompleteInitTransactionInput->cardDetail = $completeCardDetail;
$wsCompleteInitTransactionInput->transactionDetails =
$wsCompleteTransactionDetail;
$webpayCompleteService = new WSCompleteWebpayService($url_wsdl_complete);
$initCompleteTransaction = new initCompleteTransaction();
Página 24
$initCompleteTransaction->wsCompleteInitTransactionInput =
$wsCompleteInitTransactionInput;
$initCompleteTransactionResponse = $webpayCompleteService>initCompleteTransaction(
$initCompleteTransaction
);
$xmlResponse = $webpayCompleteService->soapClient->__getLastResponse();
$soapValidation = new SoapValidation($xmlResponse, SERVER_CERT);
$validationResult = $soapValidation->getValidationResult();
$wsCompleteInitTransactionOutput = $initCompleteTransactionResponse->return;
Operación queryShare:
$webpayCompleteService = new WSCompleteWebpayService($url_wsdl_complete);
$queryShare = new queryShare();
$queryShare->token = $_POST['token_ws'];
$queryShare->buyOrder = $buyOrder;
$queryShare->shareNumber = $shareNumber;
$queryShareResponse = $webpayCompleteService->queryShare($queryShare);
$xmlResponse = $webpayCompleteService->soapClient->__getLastResponse();
$soapValidation = new SoapValidation($xmlResponse, SERVER_CERT);
$validationResult = $soapValidation->getValidationResult();
$queryShareOutput = $queryShareResponse->return;
Página 25
Operación authorize:
$webpayCompleteService = new WSCompleteWebpayService($url_wsdl_complete);
$authorize = new authorize();
$wsCompletePaymentTypeInput = new wsCompletePaymentTypeInput();
$wsCompleteQueryShareInput = new wsCompleteQueryShareInput();
$authorize->token = $_POST['token_ws'];
$wsCompletePaymentTypeInput->buyOrder = $buyOrder;
$wsCompletePaymentTypeInput->commerceCode = $commerceCode;
$wsCompletePaymentTypeInput->gracePeriod = $gracePeriod;
$wsCompleteQueryShareInput->idQueryShare = $idQueryShare;
$wsCompleteQueryShareInput->deferredPeriodIndex = $deferredPeriodIndex;
$wsCompletePaymentTypeInput->queryShareInput = $wsCompleteQueryShareInput;
$authorize->paymentTypeList = $wsCompletePaymentTypeInput;
$authorizeResponse = $webpayCompleteService->authorize($authorize);
$xmlResponse = $webpayCompleteService->soapClient->__getLastResponse();
$soapValidation = new SoapValidation($xmlResponse, SERVER_CERT);
$validationResult = $soapValidation->getValidationResult();
$authorizeOutput = $authorizeResponse->return;
Operación acknowledgeCompleteTransaction:
$webpayCompleteService = new WSCompleteWebpayService($url_wsdl_complete);
$acknowledgeCompleteTransaction = new acknowledgeCompleteTransaction();
$acknowledgeCompleteTransaction->tokenInput = $token;
$acknowledgeTransactionResponse=$webpayCompleteService>acknowledgeCompleteTransaction(
$acknowledgeCompleteTransaction
);
$xmlResponse = $webpayCompleteService->soapClient->__getLastResponse();
$soapValidation = new SoapValidation($xmlResponse, SERVER_CERT);
$validationResult = $soapValidation->getValidationResult();
Página 26
4.3 Ejemplos .Net
Este ejemplo hará uso de los siguientes frameworks y componentes para consumir los servicios
Web de Webpay utilizando WS Security:
Microsoft .NET 4.0, es un framework de Microsoft que permite la independencia de
hardware e integra todos sus productos desde el sistema operativo hasta las
herramientas de mercado.
o
Soporte y Core para el desarrollo e implementación
Web Services Enhancements 3.0, proporciona la implementación para desarrollo de
Web Service e interoperabilidad con otros sistemas.
o
Generar el cliente del WebService o Proxy
o
Consumir los servicios Web
Componente Intergrup.Core4.Soap.dll Componente para validación y firma digital
para WS Security. Estos componentes representan una posible solución al problema
del no soporte nativo de WSS en .Net
IMPORTANTE. Se debe tener presente que el framework WSE 3.0 no es compatible en su
totalidad con WS Security, requiere de algunas adaptaciones. Entre estas adaptaciones se
encuentra la validación de firma digital sobre el XML de SOAP del WSE. La firma que se
exige en el consumo del servicio Web se debe realizar sobre el body del XML, el cual debe
ser marcado con un ID, es este caso el ID lleva un prefijo impuesto por la definición de WSS,
WSE 3.0 no permite validar la firma sobre elementos cuyo identificado de referencia
presenta un prefijo. Una posible solución se presenta en el sitio StackOverflow, en donde se
plantea una forma de sobrescribir el método GetIdElement de la subclase
System.Security.Cryptography.Xml.SignedXml, que es utilizada al momento de
firmar y validar firmas digitales con el método nativo ComputeSignature.
Nota: WSE 3.0 puede ser utilizado también con Framework .NET 2.0 y 3.5 respectivamente
Página 27
Pasos a seguir:
1. Generación de cliente del Webservice.
Para generar el código .NET que implementará el cliente SOAP se utilizará wsewsdl3 de
WSE 3.0, el cual toma el WSDL del servicio y genera todas las clases necesarias para
invocar el servicio Web.
wsewsdl3 <URL del wsdl> /language:c# /namespace:<Opcional> /type:webClient
Nota: Una vez instalado WSE 3.0 en Windows puede ser encontrado en C:\Program
Files\Microsoft WSE\v3.0\Tools
2. Configuración de WS Security
Para configurar WS Security en WSE 3.0 se implementó un conjunto de clases para definir
y personalizar clases que entreguen el soporte para WS Security.
Nota: La personalización de clases está definido dentro de WSE 3.0 para lograr la
interoperabilidad entre sistemas.
o
Página 28
CustomPolicyAssertion: esta clase permite crear una Política para Assertion,
donde podemos capturar el Mensaje SOAP de Request y Response respectivamente.
Esto realizado a través de filtros:
o
ClientOutputFilter (Interceptor Salida): permite definir y personalizar el mensaje
de Response hacia el servicio. Dentro de esta clase es interceptado el mensaje
Soap y se realiza la firma digital.
o
ClientInputFilter (Interceptor de Entrada): permite definir y personalizar el
mensaje de Request hacia el servicio. Dentro de esta clase es interceptado el
mensaje SOAP y se realiza la validación de firma digital con la llave pública del
certificado.
Definición de política de proceso
public class CustomPolicyAssertion : PolicyAssertion
{
private String issuerNameCertificate = null;
public CustomPolicyAssertion(String issuerNameCertificate)
: base()
{
this.issuerNameCertificate = issuerNameCertificate;
}
public override SoapFilter CreateClientInputFilter(
FilterCreationContext context)
{
return new ClientInputFilter();
}
public override SoapFilter CreateClientOutputFilter(
FilterCreationContext context)
{
return new ClientOutputFilter(this.issuerNameCertificate);
}
public override SoapFilter CreateServiceInputFilter(
FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceOutputFilter(
FilterCreationContext context)
{
return null;
}
public override IEnumerable< KeyValuePair<string, Type>> GetExtensions()
{
return new KeyValuePair<string, Type>[] { new KeyValuePair<string,
Type>("CustomPolicyAssertion", this.GetType()) };
}
public override void ReadXml(XmlReader reader, IDictionary<string, Type>
extensions)
{
reader.ReadStartElement("CustomPolicyAssertion");
}
}
La creación de una política permite definir al stub o proxy cómo activar los interceptores
para envió o recepción de mensaje SOAP al consumir un WebService. Esto es permite en
WSE 3.0 a modo de Custom de los objetos para lograr la interoperabilidad.
Página 29
Interceptor de salida
public class ClientOutputFilter : SoapFilter
{
private String issuerNameCertificate = null;
public ClientOutputFilter(String issuerNameCertificate)
: base()
{
this.issuerNameCertificate = issuerNameCertificate;
}
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
WSSecuritySignature<SoapEnvelope, X509Certificate2> signed = new
WSSecuritySignature<SoapEnvelope, X509Certificate2>();
String issuerName = HelperSetting.GetSetting(this.issuerNameCertificate);
X509Certificate2 certificate =
HelperCertificate.GetCertificate(issuerName);
signed.Signature(envelope, certificate);
return SoapFilterResult.Continue;
}
}
Se rescata el certificado digital del comercio y se procede a la firma digital. El componente
de firma digital para WS Security se encuentra en la clase WSSecuritySignature.
Página 30
Interceptor de Entrada
public class ClientInputFilter:SoapFilter
{
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
WSSecuritySignature<SoapEnvelope, X509Certificate2> signed = new
WSSecuritySignature<SoapEnvelope, X509Certificate2>();
String issuerName =
HelperSetting.GetSetting(Constant.ISSUER_NAME_CERTIFICATE_SERVER);
X509Certificate2 certificate =
HelperCertificate.GetCertificate(issuerName);
if (signed.CheckSignature(envelope, certificate))
{
return SoapFilterResult.Continue;
}
return SoapFilterResult.Terminate;
}
}
Se rescata el certificado digital del servidor (llave pública) y se procede a la validación de
firma digital.
Nota: los certificados digitales son almacenados en el Store de Windows para certificados
digital y desde este repositorio son obtenidos mediante IssuerName o número del
comercio.
Página 31
Llamada a operaciones del Webservice
Operación initCompleteTransaction
wsCompleteInitTransactionInput initTransaction = new
wsCompleteInitTransactionInput();
initTransaction.transactionType = wsCompleteTransactionType.TR_COMPLETA_WS;
initTransaction.sessionId = “1234567”;
initTransaction.buyOrder = “OC123456789”;
initTransaction.commerceId = “597000000000”;
initTransaction.cardDetail = new completeCardDetail
{
cardExpirationDate=”13/06”,
cardNumber=”4051885600446623”,
cvv=”1234”
};
initTransaction.transactionDetails = new wsCompleteTransactionDetail[] { new
wsCompleteTransactionDetail() };
wsCompleteTransactionDetail
transactionDetail=initTransaction.transactionDetails[0] as
wsCompleteTransactionDetail;
transactionDetail.amount=Convert.ToDecimal(txtAmount.Text);
transactionDetail.buyOrder = txtBuyOrder.Text;
transactionDetail.commerceCode = txtCommerceCode.Text;
wsCompleteInitTransactionOutput result = null;
using (WSWebpayServiceImplService proxy = new WSWebpayServiceImplService())
{
/*Define el ENDPOINT del Web Service Webpay*/
proxy.Url =
“http://localhost/WSWebpayTransaction/cxf/WSCompleteWebpayService”;
Policy myPolicy = new Policy();
CustomPolicyAssertion customPolicty = new CustomPolicyAssertion();
myPolicy.Assertions.Add(customPolicty);
proxy.SetPolicy(myPolicy);
proxy.Timeout = 60000;
proxy.UseDefaultCredentials = false;
result = proxy.initCompleteTransaction(initTransaction);
}
/*Token de resultado*/
String token=result.token;
Página 32
Operación queryShare
wsCompleteQuerySharesOutput result = null;
String token=””; // Definir Token
String buyOrder=”OC_PRUEBA”;
Int shareNumber=7;
using (WSWebpayServiceImplService proxy = new WSWebpayServiceImplService())
{
/*Define el ENDPOINT del Web Service Webpay*/
proxy.Url =
“http://localhost/WSWebpayTransaction/cxf/WSCompleteWebpayService”;
Policy myPolicy = new Policy();
CustomPolicyAssertion customPolicty = new CustomPolicyAssertion();
myPolicy.Assertions.Add(customPolicty);
proxy.SetPolicy(myPolicy);
proxy.Timeout = 60000;
proxy.UseDefaultCredentials = false;
result = proxy.queryShare(token, buyOrder, shareNumber);
}
/*Resultado*/
Int64 queryId = result. queryId;
Decimal shareAmount = result.shareAmount;
completeDeferredPeriod[] deferredPeriods = result.deferredPeriods;
Página 33
Operación authorize (Sin cuotas)
String token=””;
wsCompletePaymentTypeInput paymentType = new wsCompletePaymentTypeInput();
paymentType.buyOrder=”OC123”;
paymentType.commerceCode="597000000000";
//Si se quiere período de gracia dejar en true
paymentType.gracePeriod=false;
wsCompletePaymentTypeInput[] payments = new wsCompletePaymentTypeInput[]
{ paymentType };
using (WSWebpayServiceImplService proxy = new WSWebpayServiceImplService())
{
/*Define el ENDPOINT del Web Service Webpay*/
proxy.Url =
“http://localhost/WSWebpayTransaction/cxf/WSCompleteWebpayService”;
Policy myPolicy = new Policy();
CustomPolicyAssertion customPolicty = new CustomPolicyAssertion();
myPolicy.Assertions.Add(customPolicty);
proxy.SetPolicy(myPolicy);
proxy.Timeout = 60000;
proxy.UseDefaultCredentials = false;
result = proxy.authorize(token, payments);
}
/*Resultado*/
accountingDate = authorizeOutput.accountingDate;
transactionDate = authorizeOutput.transactionDate;
detailOutput = authorizeOutput.detailsOutput[0];
Página 34
Operación authorize (Usando cuotas)
String token=””;
wsCompletePaymentTypeInput paymentType = new wsCompletePaymentTypeInput();
paymentType.buyOrder=”OC123”;
paymentType.commerceCode="597000000000";
wsCompleteQueryShareInput queryShareInput = new
wsCompleteQueryShareInput();
queryShareInput.idQueryShare=Convert.ToInt64(“12345678”);
queryShareInput.deferredPeriodIndex=1;
paymentType.queryShareInput=queryShareInput;
wsCompletePaymentTypeInput[] payments = new wsCompletePaymentTypeInput[]
{ paymentType };
using (WSWebpayServiceImplService proxy = new WSWebpayServiceImplService())
{
/*Define el ENDPOINT del Web Service Webpay*/
proxy.Url =
“http://localhost/WSWebpayTransaction/cxf/WSCompleteWebpayService”;
Policy myPolicy = new Policy();
CustomPolicyAssertion customPolicty = new CustomPolicyAssertion();
myPolicy.Assertions.Add(customPolicty);
proxy.SetPolicy(myPolicy);
proxy.Timeout = 60000;
proxy.UseDefaultCredentials = false;
result = proxy.authorize(token, payments);
}
/*Resultado*/
accountingDate = authorizeOutput.accountingDate;
transactionDate = authorizeOutput.transactionDate;
detailOutput = authorizeOutput.detailsOutput[0];
Página 35
Operación acknowledgeCompleteTransaction
String token=”Valor Token”;
using (WSWebpayServiceImplService proxy = new WSWebpayServiceImplService())
{
/*Define el ENDPOINT del Web Service Webpay*/
proxy.Url =
“http://localhost/WSWebpayTransaction/cxf/WSCompleteWebpayService”;
Policy myPolicy = new Policy();
CustomPolicyAssertion customPolicty = new CustomPolicyAssertion();
myPolicy.Assertions.Add(customPolicty);
proxy.SetPolicy(myPolicy);
proxy.Timeout = 60000;
proxy.UseDefaultCredentials = false;
proxy.acknowledgeCompleteTransaction(token);
}
Referencias:
WSE 3.0: http://www.microsoft.com/en-us/download/details.aspx?id=14089
Framework .NET 4.0: http://www.microsoft.com/en-us/download/details.aspx?id=17851
Herramienta wsewsdl3 para generación de proxy http://www.microsoft.com/enus/download/details.aspx?id=14089
Componente Intergrup.Core4.Soap.dll http://www.intergrup.cl/software/ws-security.html
Web Services Security X.509 Certificate Token Profile 1.1. https://www.oasisopen.org/committees/download.php/16785/wss-v1.1-spec-os-x509TokenProfile.pdf
StackOverflow, firma en elementos con ID que utilizan prefijos.
http://stackoverflow.com/questions/5099156/malformed-reference-element-whenadding-a-reference-based-on-an-id-attribute-w
Página 36

Documentos relacionados