Aitor Sánchez - Blog - Nov. 1, 2023, 5:33 p.m.
¿Quieres cobrar a tus usuario desde dentro de tu aplicación hecha en Ionic a través de PayPal? O, tal vez ya sabes cómo se hace, pero tienes algún tipo de duda sobre algún campo o función del componente PayPal Ionic ¿verdad?
Mi nombre es Aitor Sánchez, soy desarrollador de apps desde 2014 y en este artículo vas a aprender, de manera sencilla y eficaz, a realizar cobros desde tu app mediante el componente oficial de PayPal para Ionic.
Pero antes de continuar, esta es la Flutter Mafia. Es mi newsletter donde tu vas a aprender a hacer apps y a ganar dinero con ellas junto con otros genietes que ya están dentro. Y si te suscribes te regalo mi ebook "Duplica los ingreso de tus apps en 5 minutos" No es broma, quizás te interese.
Y ahora si, comenzamos. Let´s go!
Para comenzar, necesitamos ejecutar los dos siguientes comandos:
$ ionic cordova plugin add com.paypal.cordova.mobilesdk
$ npm install --save @ionic-native/paypal
El primero de ellos instalará el plugin de Cordova que nos permitirá comunicarnos desde la aplicación con la parte nativa del sistema.
Y la segunda, instalará el código Type Script que nos permitirá interactuar desde nuestro código TS con el código del plugin.
Cómo en la mayoría de los componentes externos al sistema, tenemos que agregar a los servicios de la app (providers / proveedores) el módulo para después poder inyectarlo en los constructores de nuestras clases de la siguiente manera:
Nota: En caso de que estés usando una versión de Ionic superior a la 3 y el módulo NGX, esto no es necesario que lo hagáis.
import { PayPal } from '@ionic-native/paypal';
...
providers: [
...
PayPal,
...
]
Y ya está, no es necesario incluir nada de código más, ya lo tenemos disponible para su uso. Continuemos…
Las plataformas que soportan este servicio son las móviles, por lo menos actualmente.
Aún que creo, que con el auge de las PWA deberían de sacar ya algo para poder dar soporte a estas. Quizás los hagamos nosotros en un tutorial paso a paso y así aportamos un poco más aún a la comunidad.
Continuando con el artículo, vamos a explicar un poquito como podemos poner en uso el componente. Pero primero, cómo en todos los artículos, ponemos un ejemplo y explicamos sobre él.
import { PayPal, PayPalPayment, PayPalConfiguration } from '@ionic-native/paypal/ngx';
constructor(private payPal: PayPal) { }
...
this.payPal.init({
PayPalEnvironmentProduction: 'TU_ID_DE_CLIENTE_EN_PRODUCCIÓN',
PayPalEnvironmentSandbox: 'TU_ID_DE_CLIENTE_EN_DESARROLLO' //Sandbox
}).then(() => {
// Entornos: PayPalEnvironmentNoNetwork, PayPalEnvironmentSandbox, PayPalEnvironmentProduction
this.payPal.prepareToRender('PayPalEnvironmentSandbox', new PayPalConfiguration({
// Solo lo necesitas si necesitas controlar los errores posteriores al login de paypal "Internal Service Error".
//payPalShippingAddressOption: 2 // PayPalShippingAddressOptionPayPal
})).then(() => {
let cobro = new PayPalPayment('3.33', 'USD', 'Description', 'sale');
this.payPal.renderSinglePaymentUI(cobro).then(() => {
// Se ha realizado el cobro correctamente
// En caso de estar en desarrollo, este el código de la Sandbox
//
// {
// "client": {
// "environment": "sandbox",
// "product_name": "PayPal iOS SDK",
// "paypal_sdk_version": "2.16.0",
// "platform": "iOS"
// },
// "response_type": "payment",
// "response": {
// "id": "PAY-XXXXXXXXXXXXXXXXXXXXXXXX",
// "state": "approved",
// "create_time": "2016-10-03T13:33:33Z",
// "intent": "sale"
// }
// }
}, () => {
// Ha petado el cuadro de diálogo
});
}, () => {
// Ha petado la configuración
});
}, () => {
// Ha petado la inicialización o el dispositivo no permite usar PayPal
});
En primer lugar, tendremos que realizar un import de las clases que vamos a utilizar. En este caso son 3 y son:
Ahora vamos a inyectar en el constructor una instancia de la clase “PayPal”. Ahora la podremos utilizar donde queramos dentro de nuestra clase.
Recordatorio: PPara quien no lo sepa, para poder inyectar la instancia en el constructor tenemos que agregar el servicio a nuestros providers de la clase como hemos visto al principio del artículo.
Ahora vamos a usar la función “init” de la instancia de “PayPal” que será la encarga de realizar todo el proceso de inicialización. Le pasaremos como parámetros las keys, tanto de producción como de desarrollo, en este respectivo orden.
Esta función devuelve una promesa que tendremos que controlar. A través del “then” no llegará nada pero sabremos cuando ha terminado de configurar todo. Ahora ya podremos, a través de la misma clase, preparar el checkout llamando a la función “prepareToRender”. Esta función, como primer parámetro, recibe el entorno en el que queremos procesar el pago (en la siguiente lista veremos las opciones) y una instancia de “PayPalConfiguration”.
La función mencionada devuelve una promesa que tendremos que controlar. A través del “then” ya podremos configurar todo para enviar al usuario a procesar el checkout.
Una vez realizado todo el rollo de configuración anterior, por fin vamos a efectuar un intento de cobro.
Desde la promesa que hemos controlado en el punto anterior, crearemos una instancia de la clase “PayPalPayment” en la que vamos a pasarle los parámetros que veis en el ejemplo. Esto es lo que vosotros podéis configurar a vuestra elección.
El primer parámetro será el precio que cobrar, el segundo será la moneda que queremos utilizar, el tercero será la descripción del cobro y el cuarto será la función que queramos ejecutar de PayPal, en este caso “sale”.
Para finalizar, la función “renderSiglePaymentUI”, que recibe el “PayPalPayment” que hemos creado en el punto anterior, será la que lance la UI que hará que el usuario pueda formalizar el pago. Esta función retorna una promesa que tendremos que controlar. Esta promesa trae consigo la respuesta de PayPal, que he colocado en el ejemplo para que puedas usarla directamente.
Visto todo lo anterior, ya estamos en disposición de ver más cositas avanzadas fuera del ejemplo.
Devuelve la versión del SDK de PayPal usada en la aplicación.
Retorno: Una promesa que debemos de controlar y que contiene un String con el valor de la versión del módulo.
Esta función nos permite pre-conectarnos a la api de PayPal. Esto mejora mucho la experiencia de usuario al pre-ver el uso del sistema y agilizar mucho el proceso de compra. Esta pre-conexión es válida por tiempo limitado así que hay que aprovecharlo al máximo.
Params:
clientIdsForEnvironments -> PayPalEnvironment -> Una interface que contiene los IDS de los entornos de la api.
Retorno:
Promesa -> any -> La promesa no devuelve nada, pero informa de cuando está todo listo.
Para poder usar esta función tenemos que hacerlo desde la promesa que devuelve la función “init”, que es cuando ya está conectado a la api de PayPal. Esta función mejora mucho la experiencia de usuario pero hay que tomar cuenta de que la pre-conexión dura por tiempo limitado.
Parámetros:
entorno -> String -> El entorno de ejecución donde queremos procesar el checkout. Ya vimos en el ejemplo cuales teníamos disponible y para que era cada uno.
configuracion -> PayPalConfiguration -> También lo hemos explicado en el ejemplo, pero vamos a extederlo un poco. Aquí podremos cargar, a partir de lo ya visto, el “merchantName” que es el nombre del vendedor, “merchanPrivacyPolicyURL” que es el política de privacidad del vendedor y “merchantUserAgreementURL” que son las políticas de uso del vendedor.
Retorno:
Una promesa que debemos de controlar.
Esta función llama a la interfaz de PayPal disponible dentro del módulo con los datos de cobro que le pasamos como parámetro. Básicamente lo que hará es mostrar la ventana donde el usuario puede formalizar y finalizar el cobro.
Parámetros:
payment -> PayPalPayment -> Una instancia de la clase PayPalPayment que contiene los datos del cobro, como explicamoe en el ejemplo, el precio, la moneda, etc…
Retorno:
Una promesa que tenemos que controlar. En el ejemplo puse un ejemplo de la respuesta que venía a través de esta promesa.
Una vez que el usuario a dado consentimiento para procesar futuros pagos desde la aplicación, cuando se realicen futuros pagos PayPal relacionará el dispositivo con la cuenta y con el checkout para verificarlo. Esto ayuda a disminuir el fraude y los problemas de cobor. En caso de vayamos a realizar cobros futuros en el tiempo siempre tendremos que llamar antes a esta función para saber como está la conexión del usuario con PayPal y nuestra aplicación. Es recomendable no almacenar en la cache ni guardar los valores por si cambian en algún momento por parte del usuario y desde fuera de la app. Como, por ejemplo, revocar el consentimiento directamente desde paypal.
Parametros:
No tiene
Retorno:
Una promesa que tendremos que controlar. Dentro llegan los datos necesarios para verificar la conexión.
Esta función es similar a “renderSinglePaymentUI” pero con la diferencia de que esta es para pedir el consentimiento de realizar futuros cobros en lugar de realizar uno en ese momento.
Parametros:
No tiene.
Retorno:
Una promesa que tendremos que controlar. En ella llegan los datos de si el usuario ha dado consentimiento, o no, a la solicitud. A parte de otros datos necesarios, como el token de autorización que tendremos que guardar autenticar las transacciones futuras.
Esta función lo que permite es obtener consentimiento expreso del usuario para poder obtener datos del usuario. Cómo, por ejemplo, la dirección o el nombre, email, etc…
Parámetros:
Scopes -> Array<Strings> -> Digamos que son los permisos que le solicitas al usuario para poder trackear sus datos. Las opciones posibles dentro del array son las siguientes:
Retorno:
Retornará una promesa que tenemos que controlar. Dentro de ella llegarán si el usuario ha aceptado los permisos solicitados.
En el punto anterior hemos visto los eventos y campos de la clase PayPal, pero como hemos incluido dos más en el ejemplo, y son necesarios para realizar una transacción, vamos a ponerlos también.
Esta función nos devuelve la cantidad que le hemos dado a la transacción.
Esta función nos devuelve la moneda usada, formateada en ISO 4217, con la que vamos a realizar el pago.
Nos retorna la descripción que le queremos poner al pago.
Nos devuelve la intención de checkout “Sale” por defecto. Pero puede ser suscription, recurring, etc…
Este campo es el código de seguimiento del pago. Y nos sirve para trackear como esta dentro del sistema. Por ejemplo, para comprobar el estado de una suscrición.
Nos devuelve el número de factura una vez se ha procesado la transacción.
Un texto opcional que le podemos meter al pago para luego trackearlo e identificarlo a través de este.
Un texto opcional de 22 caracteres que se asocia a la tarjeta de crédito del usuario. Por si dentro de su cuenta de PayPal tiene más de una y nosotros queremos trackear con cual paga, por ejemplo.
Retorna los items registrados en PayPal que hay dentro de la transacción.
Será la dirección de envío que nos facilite PayPal al realizar el pago. Si el usuario no la tiene registrada, no llegará nada.
Aquí nos llegan detalles de la transacción por si queremos guardarlos. Fecha, hora, etc…
Esta clase es la que se encarga de construir los “items” con su precio, descripción, cantidad, etc… dentro de la transacción. Digamos, lo que vamos a comprar.
Devuelve el nombre del “ítem”. Por ejemplo, “suscripción anual”.
Retorna la cantidad que ha adquirido el usuario. Por ejemplo, 10 para 10 imágenes de nuestro banco de imágenes a 1,5€
Devuelve el precio por unidad de cada objeto.
Retorna la moneda que está en uso en esa transacción.
En caso de que se lo hayamos puesto, devolverá el código del ítem de la transacción.
Continuamos hablando de clases asociadas a la api de PayPal. Ahora le toca el turno a PayPalPaymentDetails. Esta clase será la encargada de proveernos información del express checkout tanto antes, como después, de la transacción.
Nos devolverá el sub-total, o base imponible, de la transacción. Será una cadena de máximo 10 caracteres e incluye 2 decimales.
Retornará la cantidad que ha sido cobrada en concepto de envío. Será una cadena de 10 caracteres y tendrá 2 decimales cómo máximo.
Devolverá la cantidad abonada en concepto de impuestos en la transacción. Será una cadena de 10 caracteres y tendrá como máximo 2 caracteres.
De momento, basta con lo que acabamos de explicar con estas 3 funciones. Al fin, y al cabo, una transacción se basa en estas 3 cosas. La cantidad, los impuestos y, en caso de que lo tenga, el envío.
Esta clase nos proveerá de un acceso a la dirección de envío del usuario que nos proporciona PayPal para no tener que pedírsela al usuario. A parte, podemos rascar algo más de información, como vamos a ver ahora, que nos puede servir de mucho.
Parece que suena raro, pero es, básicamente, el nombre de la dirección que nos ha querido aportar. En caso de que tenga más de una, la que él, el usuario, haya seleccionado. Por ejemplo, “mi dirección de casa” y “mi dirección de la oficina”.
Nos devuelve la primera línea de la dirección: numero, ciudad, provincia, etc… con una longitud máxima de 100 caracteres.
Nos retorna la segunda línea de la dirección. Escalera, puerta, portal, etc…. Con una longitud máxima de 100 caracteres.
Devuelve el nombre de la ciudad del usuario en una cadena de texto de, cómo máximo, 50 caracteres.
Similar a la anterior función, pero en este caso nos devuelve el estado, o la provincia, en una cadena de texto de máximo 100 caracteres. Con la peculiaridad, de que si en determinado países se practica la nomenclatura de 2 letras, este también la usará.
Nos proveerá del código postal, o ZIP Code, o equivalente. Será de una longitud máxima de 20 caracteres.
Devolverá el código del país solicitado. Usará la nomenclatura de 2 letras y será una cadena de dos letras de longitud.
Ya hemos terminado de tratar con las cosas principales. Ahora tenemos que ver otra parte igual de importante. Las interfaces que tenemos que usar para realizar la transacción correctamente.
Estas interfaces son las que proveen los datos a las clases para no perder la estructura de los datos y que todo funcione correctamente.
Esta interface nos permitirá definir el entorno en el que queremos lanzar el sistema.
Campos:
Campos:
defaultUserEmail -> String -> En caso de que queramos sobre-escribir el campo “email” del login del usuario, lo pondremos aquí. En caso de no ponerlo, usará el que tenga el usuario puesto o ninguno.
defaultUserPhoneCountryCode -> String -> Funciona igual que la función anterior, pero permite predefinir el código del país.
defaultUserPhoneNumber -> String -> Similar a las dos anteriores, pero esta vez con el número de teléfono.
merchantName -> String -> Este será el nombre que el usuario verá cuando realiza la transacción como la persona/empresa que va recibir el dinero. En caso de que no esté definido, aparecerá el que esté configurado en la cuenta de PayPal.
merchantPrivacyPolicyURL -> Strign -> En caso de que tengamos una política de privacidad, que la deberíamos de tener, esté será el lugar donde tienes que colocar la URL de esta. Así el usuario podrá acceder a ella cuando le resulte necesario.
merchantUserAgreementURL -> String -> Este campo es similar al de la política de privacidad, pero con los términos de uso.
acceptCreditCards -> boolean -> Si queremos que el usuario pueda pagar por tarjeta de crédito, es necesario que esto sea verdadero.
payPalShippingAddressOption -> number -> Esta lista, las costantes que verás a continuación, serán las opciones que le podemos dar al usuario para la dirección de envío.
rememberUser -> boolean -> En caso de que queramos nosotros, o el mismo usuario, podemos poner esta variable en verdadero para que se recuerden los datos del usuario como, por ejemplo, el nombre de usuario o el teléfono, en futuras transacciones y no tener que estar solicitándolo todo el tiempo. La opción por defecto es “true” y en el momento que se ponga a “false” todos los datos almacenados serán borrados.
languageOrLocale -> String -> Si no se setea, o si se setea en nulo, el valor predeterminado que tomará es el predeterminado del dispositivo.
Se puede setear como un código de idioma ("en", "fr", "zh-Hans", etc.) o como un entorno local ("en_AU", "fr_FR", "zh-Hant_HK", etc.). Si la biblioteca no contiene cadenas localizadas para un entorno local específico, recurrirá al idioma. Por ejemplo, "es_CO" -> "es". Si la biblioteca no contiene cadenas localizadas para un idioma específico, recurrirá al inglés americano.
Si especifica solo un código de idioma, y ese código coincide con el idioma preferido actualmente del dispositivo, la biblioteca también intentará usar la región actual del dispositivo. Por ejemplo, especificar "en" en un dispositivo configurado en "inglés" y "Reino Unido" dará como resultado "en_GB".
disableBlurWhenBackgrounding -> boolean -> Esta opción nos permite difuminar los datos sensibles del usuario cuando está minimizada, en la pantalla de selección o cuando se toma una screen shoot de la pantalla. Es para aumentar la seguridad y por defecto su valor es “false”. Pero siempre deberías de contemplar ponerlo en true, es beneficioso para el cliente.
presentingInPopover -> boolean -> Esta función nos permite cambiar la manera de visualización de los datos de PayPal. En este caso, será mediante un popover y solo está disponible en iOS. Su valor por defecto es “false”.
forceDefaultsInSandbox -> boolean -> Esta función es para desarrollo. Como las credenciales de la sandbox son un poco pesadas de escribir en el dispositivo móvil, esta función los auto-rellena por nosotros.
sandboxUserPassword -> String -> En caso de que estemos usando “forceDefaultsInSandbox” en esta variable tendríamos que poner la contraseña.
sandboxUserPin -> String -> Similar a la anterior, pero esta vez con el código que se nos facilita para acceder a esta SandBox.
Mira, en el momento que tu mejoras el logo de una app que tengas publicada en Google Play, las descargas y los ingresos que esta aplicación genera aumentan. Esto es así. Mejor logo es igual a más dinero.
Basándonos en esto, hemos creado esta herramienta que te permite evaluar, optimizar y mejorar los logos de tus apps para que reciban más descargas. No te quiero espoilear, dentro hay un video explicativo. Entra en el enlace.
Geniete, me despido ya. Espero haber ayudado a integrar este componente en tu app y nos vemos en el siguiente artículo. Hasta entonces ¡que te vaya bien!