Guía de Inicio Rápido ===================== La compra de un producto consiste en los siguientes pasos: #. El :term:`Comercio` crea una :term:`Solicitud de pago` en la :term:`Tpaga API` por el valor, que debe ser cancelado por un :term:`Comprador`. #. La Tpaga API devuelve un :term:`Link de pago` al :term:`Comercio`. #. El :term:`Comercio` pasa el link de pago al :term:`Comprador`, quien debe realizar el pago. #. El :term:`Comprador` recibe el link de pago y lo abre en su dispositivo móvil. Al hacerlo, se le abre automáticamente :term:`Billetera Tpaga` y aparece un widget que lo invita a realizar el pago. #. El :term:`Comprador` realiza el pago dentro de la :term:`Billetera Tpaga`. #. La :term:`Billetera Tpaga` redirige al :term:`Comprador` al :term:`Link de finalización de compra`, o le notifica al :term:`Comercio` que el estado de la solicitud de pago cambio (Esta decisión depende de la configuración del :term:`Comercio`). #. El :term:`Comercio` hace una petición a la :term:`Tpaga API` para confirmar el estado de pago. #. Si el pago fue exitoso, el :term:`Comercio` entrega el producto/servicio al :term:`Comprador`, y le notifica a Tpaga que hizo la entrega al :term:`Comprador`. Miremos con más detalle algunos pasos del proceso: Autenticación contra la Tpaga API. ---------------------------------- Cada petición que el :term:`Comercio` envía a :term:`Tpaga API` debe tener el encabezado de la autenticación de acceso básica (Basic Authentication), que es basada en nombre de usuario y contraseña asignados al Comercio por Tpaga y que están codificados en Base64. Por ejemplo, si el nombre de usuario del Comercio es ``tiendaX`` y la contraseña es ``123456``, esos datos se concatenan en la siguiente cadena: ``tiendaX:123456``, se codifican en Base64: ``dGllbmRhWDoxMjM0NTY=`` y se envían dentro del encabezado ``Authorization``: .. code-block:: bash curl --header "Authorization: Basic dGllbmRhWDoxMjM0NTY=" https://stag.wallet.tpaga.co/merchants/api/v1/ Si se está haciendo una integración de aplicación a aplicación, esta autenticación va a ir unicamente entre backend y backend, no debe consumirse esta API desde una aplicación móvil, como tampoco desde un cliente web. Crear la solicitud de pago. ------------------------------ Para crear una :term:`Solicitud de pago` se debe hacer una petición `POST` a la :term:`Tpaga API` desde el servidor del comercio, no desde el navegador o webview. Los parámetros que debe tener esta petición son los siguientes: * ``cost`` - valor total de la compra; * ``purchase_details_url`` - el :term:`Link de finalización de compra`. Esta es la página en el sitio web del comercio a la cual la Billetera Tpaga enviará al Comprador una vez se haya hecho el cobro, para continuar/terminar el proceso de compra. * ``voucher_url`` - el :term:`Link de detalle de compra` (*opcional*); * ``idempotency_token`` - el :term:`Token de idempotencia`, que es un identificador de la transacción, que sirve para evitar la creación de solicitudes de pago duplicadas dentro de la :term:`Tpaga API`; * ``order_id`` - el identificador de la compra dentro del sistema de inventario del :term:`Comercio`, por ejemplo, el número de factura (no es necesario que sea único). Sirve para que el comercio pueda hacer conciliación de sus compras. * ``terminal_id`` - el identificador, definido por el :term:`Comercio`, por ejemplo, número de la caja o nombre de la sede, en la que se realizó la compra. Sirve para hacer mejor seguimiento de las compras; * ``purchase_description`` - la descripción de la compra; la Billetera le mostrará al Comprador este texto al momento de cobrarle, para comunicarle mejor qué está pagando y a quién lo hace. Por ejemplo : Pago de Servicio a Comercio X. * ``purchase_items`` - Una estructura json que le va a ayudar al comercio a saber con exactitud todo lo que está pagando (*opcional*); * ``user_ip_address`` - la dirección IP del Comprador (si existe) o de la máquina, que está haciendo la petición; * ``expires_at`` - la fecha y la hora en la que se expira el :term:`Link de pago` (en el formato ISO 8601, por ejemplo ``2018-11-05T15:10:57.549-05:00``). Después de la fecha indicada el link de pago se expira, y no está disponible para pagar. Si el Comercio tiene una aplicación para Android o iOS, puede enviar los *deep links* (o enlaces profundos) en los campos ``purchase_details_url`` y ``voucher_url`` para tener la comunicación *app-to-app* entre la aplicación de Billetera y la aplicación del Comercio. Para conocer más sobre los enlaces profundos mire el artículo `Mobile deep linking`_. .. _Mobile deep linking: https://en.wikipedia.org/wiki/Mobile_deep_linking El ejemplo de una petición para crear una solictud de pago, sería: .. code-block:: bash curl -X POST \ https://stag.wallet.tpaga.co/merchants/api/v1/payment_requests/create \ -H 'Authorization: Basic bWluaWFwcG1hLW1pbmltYWw6YWJjMTIz' \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "cost":"12000", "purchase_details_url":"https://example.com/compra/348820", "voucher_url":"https://example.com/comprobante/348820", "idempotency_token":"ea0c78c5-e85a-48c4-b7f9-24a9014a2339", "order_id":"348820", "terminal_id":"sede_45", "purchase_description":"Compra en Tienda X", "purchase_items":[ { "name":"Aceite de girasol", "value":"13.390" }, { "name":"Arroz X 80g", "value":"4.190" } ], "user_ip_address":"61.1.224.56", "expires_at":"2018-11-05T20:10:57.549653+00:00" }' Si la petición fue exitosa (es decir, no hubo errores en los datos enviados), la :term:`Tpaga API` devuelve la siguiente respuesta: .. code-block:: javascript { "miniapp_user_token": null, "cost": "12000.0", "purchase_details_url": "https://example.com/compra/348820", "voucher_url": "https://example.com/comprobante/348820", "idempotency_token": "ea0c78c5-e85a-48c4-b7f9-24a9014a2339", "order_id": "348820", "terminal_id": "sede_45", "purchase_description": "Compra en Tienda X", "purchase_items": [ { "name": "Aceite de girasol", "value": 13390 }, { "name": "Arroz X 80g", "value": 4190 } ], "user_ip_address": "61.1.224.56", "merchant_user_id": null, "token": "pr-39394abaed1d3e97d1fe67423079c36336905671bb5a77877e3b9dc032a3070c52162365", "tpaga_payment_url": "https://w.tpaga.co/eyJtIjp7Im8iOiJQUiJ9LCJkIjp7InMiOiJtaW5pbWFsLW1hIiwicHJ0IjoicHItMzkzOTRhYmFlZDFkM2U5N2QxZmU2NzQyMzA3OWMzNjMzNjkwNTY3MWJiNWE3Nzg3N2UzYjlkYzAzMmEzMDcwYzUyMTYyMzY1In19", "status": "created", "expires_at": "2018-11-05T15:10:57.549-05:00", "cancelled_at": null, "checked_by_merchant_at": null, "delivery_notification_at": null } Dentro del cuerpo de la respuesta, la Tpaga API confirma los datos de la solicitud de pago y envía el :term:`Link de pago` en el campo ``tpaga_payment_url`` junto con un identificador de la solicitud de pago creada - el campo ``token``. ``token`` es el identificador de la solicitud de pago, dentro del sistema Tpaga. Se usa para referirse a la compra al hacer peticiones a la Tpaga API (por ejemplo, para obtener información del estado de pago o para revertir de pago). ``tpaga_payment_url`` es el link de pago al cual debe redirigir la aplicación web del comercio para que el usuario pueda pagar. Abrir link de pago y pagar. ----------------------------- El link de pago lleva al :term:`Comprador` a la aplicación :term:`Billetera Tpaga`, donde se abre un widget de pago con el valor de la compra `cost` y la descripción `purchase_description` definidos por el :term:`Comercio`: .. image:: _static/payment_widget.jpg :scale: 40% :alt: Widget de pago :align: center Después de que el :term:`Comprador` realice el pago, se actualiza el estado de la :term:`Solicitud de pago` dentro de la :term:`Tpaga API` - se pasa del estado ``created`` (creado) a ``paid`` (pagado). En el caso de error al momento de pagar, el estado de la solicitud de pago se cambia a ``failed`` (pago fallido). Después de finalizar el pago en la aplicación, Tpaga Wallet cierra el widget de pago y redirige al :term:`Comprador` al :term:`Link de finalización de compra` en la página del :term:`Comercio`. Este link `purchase_details_url` fue definido por el :term:`Comercio` al momento de crear la solicitud de pago. Confirmar el estado de la solicitud de pago. -------------------------------------------- En el momento que el :term:`Comprador` llegue al :term:`Link de finalización de compra` el :term:`Comercio` debe confirmar con la :term:`Tpaga API` el estado de la :term:`Solicitud de pago` para determinar si el Comprador pudo pagar o no, antes de decidir entregar el producto. Para esto, el sistema del :term:`Comercio` debe hacer una petición al servicio de consulta de estado de pago, especificando el identificador de la solicitud de pago, que obtuvo al momento de la creación (el campo ``token``): .. code-block:: bash curl -X GET \ https://stag.wallet.tpaga.co/merchants/api/v1/payment_requests/pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd/info \ -H 'Authorization: Basic bWluaWFwcG1hLW1pbmltYWw6YWJjMTIz' \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' La Tpaga API devolverá los datos de la solicitud de pago con el estado (``status``) actualizado: .. code-block:: javascript { "miniapp_user_token": null, "cost": "12000.0", "purchase_details_url": "https://example.com/compra/348820", "voucher_url": "https://example.com/comprobante/348820", "idempotency_token": "ea0c78c5-e85a-48c4-b7f9-24a9014a2339", "order_id": "348820", "terminal_id": "sede_45", "purchase_description": "Compra en Tienda X", "purchase_items": [ { "name": "Aceite de girasol", "value": "13.390" }, { "name": "Arroz X 80g", "value": "4.190" } ], "user_ip_address": "61.1.224.56", "merchant_user_id": null, "token": "pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd", "tpaga_payment_url": "https://w.tpaga.co/eyJtIjp7Im8iOiJQUiJ9LCJkIjp7InMiOiJtaW5pbWFsLW1hIiwicHJ0IjoicHItM2Q2YTIyODkxOTNiZWM1YWRiNTA4MGRjMmU5MWNhZGViYTI5YjU4ZjA2ZWJiYmExYWJhNGM5ZWI4NWM2Nzc3ZTc2ODExZGNkIn19", "status": "paid", "expires_at": "2018-11-05T15:10:57.549-05:00", "cancelled_at": null, "checked_by_merchant_at": "2018-10-22T11:26:16.964-05:00", "delivery_notification_at": "2018-10-22T11:26:16.980-05:00" } En el caso del pago exitoso, el valor del campo ``status`` puede ser ``paid`` (pagado) o ``delivered`` (pagado y entregado) para el caso de entrega automática. Para entender más de entrega automática, ver sección :ref:`pyos-delivery-label` En el caso de ser una integración de aplicación a aplicación, una vez se hace el pago a través de la billetera y el **deep link** vuelva a abrir la aplicación del comercio, ésta consultará su propio backend para que este a su vez pueda consultar el estado de la transacción al backend de Tpaga verificando que el estado de la transacción esté en ``paid`` para poder hacer la conciliación y mostrar al usuario la confirmación del pago. .. _pyos-delivery-label: Reportar la entrega del producto. --------------------------------- Hay dos maneras de notificar a Tpaga que ya se entregó al Comprador el producto/servicio que compró: * **Explícitamente**: después del cobro exitoso, una vez el :term:`Comercio` hace la entrega, el :term:`Comercio` hace una petición a la :term:`Tpaga API`, indicando que entregó el producto/servicio. * **Implícitamente**: en este modo, Tpaga asume que, una vez el :term:`Comercio` se entera de que el pago fue exitoso, se puede considerar el producto/servicio como entregado. De forma predeterminada, todos los usuarios de este API están en modo explícito; asegúrese de comunicar a Tpaga si desea usar el modo implícito, para configurar su integración de manera acorde. El Comercio debe reportar la entrega de las compras, porque de lo contrario Tpaga devolverá el dinero a los usuarios de Billetera. Cuando el :term:`Comercio` está configurado dentro del sistema Tpaga para realizar la entrega manual, se debe llamar al servicio de la entrega: .. code-block:: bash curl -X POST \ https://stag.wallet.tpaga.co/merchants/api/v1/payment_requests/confirm_delivery \ -H 'Authorization: Basic bWluaWFwcG1hLW1pbmltYWw6YWJjMTIz' \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "payment_request_token":"pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd" }' La Tpaga API devuelve los datos de la solicitud de pago con el estado (``status``) actualizado: .. code-block:: javascript { "miniapp_user_token": null, "cost": "12000.0", "purchase_details_url": "https://example.com/compra/348820", "voucher_url": "https://example.com/comprobante/348820", "idempotency_token": "ea0c78c5-e85a-48c4-b7f9-24a9014a2339", "order_id": "348820", "terminal_id": "sede_45", "purchase_description": "Compra en Tienda X", "purchase_items": [ { "name": "Aceite de girasol", "value": "13.390" }, { "name": "Arroz X 80g", "value": "4.190" } ], "user_ip_address": "61.1.224.56", "merchant_user_id": null, "token": "pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd", "tpaga_payment_url": "https://w.tpaga.co/eyJtIjp7Im8iOiJQUiJ9LCJkIjp7InMiOiJtaW5pbWFsLW1hIiwicHJ0IjoicHItM2Q2YTIyODkxOTNiZWM1YWRiNTA4MGRjMmU5MWNhZGViYTI5YjU4ZjA2ZWJiYmExYWJhNGM5ZWI4NWM2Nzc3ZTc2ODExZGNkIn19", "status": "delivered", "expires_at": "2018-11-05T15:10:57.549-05:00", "cancelled_at": null, "checked_by_merchant_at": "2018-10-22T11:26:16.964-05:00", "delivery_notification_at": "2018-10-22T11:29:36.017-05:00" } En el caso que la entrega sea exitosa, el campo ``status`` tendrá el valor ``delivered``. Al :term:`Comprador` le llegará una notificación por medio de la :term:`Billetera Tpaga`, informando que la compra fue exitosa. En el comprobante de pago aparecerá el :term:`Link de detalle de compra` - la información contenida en el campo ``voucher_url``, especificado por el :term:`Comercio` al crear la solicitud de pago. Notificación de cambio en el estado de la solictud de pago. ----------------------------------------------------------- En caso de que el :term:`Comercio` lo desee podrá recibir una notificación vía webhook (en vez de redirigir al :term:`Comprador` al :term:`Link de finalización de compra`) cuando el usuario finaliza el proceso de pago. La idea central del webhook es que el backend de Tpaga notifica allí al backend del :term:`Comercio`, diciéndole qué solictud debe revisar, y el :term:`Comercio` consulta al backend de Tpaga para `Confirmar el estado de la solicitud de pago.`_ El webhook es una URL que ofrece el :term:`Comercio`, a la que simplemente se hace POST, sin requerir autenticación, ni datos en el cuerpo de la petición. El objetivo de la petición es hacerle saber al :term:`Comercio` que el estado de la solicitud de pago cambió; la única información que viaja en esa petición es el token del link de pago, que va en la URL. Ejemplo de la petición enviada por el backend de Tpaga: .. code-block:: bash curl -X POST \ 'https://example_merchant.com.co/payment_requests_webhook/pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd' Revertir el pago. -------------------- Tpaga ofrece el servicio de realizar una devolución de dinero al :term:`Comprador`. Para solicitar una devolución se debe enviar una petición a la Tpaga API con el identificador de la solicitud de pago, cuyo valor hay que reembolsar: .. code-block:: bash curl -X POST \ https://stag.wallet.tpaga.co/merchants/api/v1/payment_requests/refund \ -H 'Authorization: Basic bWluaWFwcG1hLW1pbmltYWw6YWJjMTIz' \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "payment_request_token":"pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd" }' La Tpaga API devuelve los datos de la solicitud de pago con el estado (``status``) actualizado: .. code-block:: javascript { "miniapp_user_token": null, "cost": "12000.0", "purchase_details_url": "https://example.com/compra/348820", "voucher_url": "https://example.com/comprobante/348820", "idempotency_token": "ea0c78c5-e85a-48c4-b7f9-24a9014a2339", "order_id": "348820", "terminal_id": "sede_45", "purchase_description": "Compra en Tienda X", "purchase_items": [ { "name": "Aceite de girasol", "value": "13.390" }, { "name": "Arroz X 80g", "value": "4.190" } ], "user_ip_address": "61.1.224.56", "merchant_user_id": null, "token": "pr-3d6a2289193bec5adb5080dc2e91cadeba29b58f06ebbba1aba4c9eb85c6777e76811dcd", "tpaga_payment_url": "https://w.tpaga.co/eyJtIjp7Im8iOiJQUiJ9LCJkIjp7InMiOiJtaW5pbWFsLW1hIiwicHJ0IjoicHItM2Q2YTIyODkxOTNiZWM1YWRiNTA4MGRjMmU5MWNhZGViYTI5YjU4ZjA2ZWJiYmExYWJhNGM5ZWI4NWM2Nzc3ZTc2ODExZGNkIn19", "status": "reverted", "expires_at": "2018-11-05T15:10:57.549-05:00", "cancelled_at": null, "checked_by_merchant_at": "2018-10-22T11:26:16.964-05:00", "delivery_notification_at": "2018-10-22T11:29:36.017-05:00" } En el caso que el reembolso sea exitoso, el campo ``status`` tendrá el valor ``reverted`` (pago revertido). Al :term:`Comprador` le llegará una notificación por medio de la :term:`Billetera Tpaga`, informado que el pago ha sido revertido. Posibles estados para una solicitud de pago. -------------------------------------------- .. https://www.planttext.com/ partition "Estados de solicitud de pago" { "CREATED" as pr_created --> "PAID" as pr_paid pr_created --> "FAILED" as pr_failed pr_paid --> "REVERTED" as pr_reverted pr_paid --> "DELIVERED" as pr_delivered pr_delivered --> pr_reverted } .. image:: _static/payment_request_status.png :alt: Estados de solicitud de pago :align: center * ``created``: solicitud de pago creada y disponible para pagar. * ``paid``: pagada por el :term:`Comprador`. * ``failed``: el pago no fue exitoso. * ``expired``: solicitud de pago se expiró y no está disponible para pagar. * ``delivered``: los productos comprados fueron entregados. * ``reverted``: el dinero fue reembolsado.