Cartera de manzana Qué es y cómo integrar su tarjeta en ella

En general, se acepta que Wallet no es el servicio más popular en la CEI. Pero ya en el segundo proyecto consecutivo, el cliente establece la tarea "Realizar integración con Wallet". Por lo tanto, decidí escribir este artículo para hablar sobre el servicio en su conjunto y mostrar cómo integrar mi producto en él.


¿Qué es una billetera? Le permite mantener varios tipos de tarjetas en su teléfono (boletos, tarjetas de descuento, etc.), facilitando la vida de los usuarios del producto. Además, es posible actualizar la información sobre el mapa a través de notificaciones push, pero este es un tema para un artículo separado. Pero si tiene una tarjeta / boleto / suscripción que se puede integrar en el teléfono, ¡entonces hay una solución! Cómo hacerlo: lea a continuación.


Como regla general, su servidor es responsable de crear el mapa. La aplicación recibe la tarjeta en forma de archivo .pkpass y, a través de la aplicación, el usuario puede agregar la tarjeta a Wallet.


Estructura del mapa


¿Cuál es el mapa desde el punto de vista del desarrollador? Un mapa es un archivo con la extensión .pkpass. Contiene todos los datos necesarios para la visualización y el funcionamiento de la tarjeta. El contenido del archivo está en la tabla a continuación.


ArchivoCita
background.pngImagen de fondo para la tarjeta.
footer.pngImagen al lado del código de barras
icon.pngÍcono para notificaciones y cartas
logo.pngLogotipo de la tarjeta Se muestra arriba a la izquierda
manifest.jsonRegistro de todos los archivos incluidos.
firmaPKCS7 firma
pass.jsonApariencia e información del mapa
strip.pngImagen ubicada detrás de la descripción principal de la tarjeta
thumbnail.pngImagen adicional (especificar)

Los siguientes tipos de tarjetas están disponibles:


  • Boleto de embarque: en avión o tren. Por lo general, el cupón funciona para un viaje;
  • Cupón: para cupones y ofertas especiales;
  • Boleto de evento: puede funcionar tanto para un evento como para una temporada completa;
  • Tarjeta de descuento: tarjetas de fidelidad, tarjetas de descuento o regalo;
  • Tarjeta de vista general: si nada de lo anterior se aplica a su caso: por ejemplo, una tarjeta para viajar en metro o un pase al gimnasio.

Considere esquemáticamente la apariencia de diferentes cartas. Las imágenes se nombran mejor como se indica en la tabla anterior.


Tarjeta de embarque



Cupón



Ticket de evento



Tarjeta comunitaria



Tarjeta de descuento



Estructura Pass.json


Campos obligatorios Contiene ID de tipo de pase, ID de equipo, nombre de la organización, etc.
Claves para aplicaciones relacionadas. Necesario para mostrar aplicaciones que necesitan estar "asociadas" con el mapa.
Claves de tarjetas de "fecha de caducidad".
Claves de relevancia. Por ejemplo, las coordenadas del área donde se puede usar el mapa, o el inicio del evento para el que está destinado.
La clave es el estilo. Al comienzo del artículo, se enumeraron 5 tipos de tarjetas para Wallet. Cada uno de ellos tiene su propio estilo. Tal clave debe ser estrictamente una.
Claves para el diseño visual de la tarjeta. Además de lo obvio, contienen información sobre el código de barras que se muestra en el mapa.
Claves de servicio web. Puede utilizar los servicios web para interactuar con el mapa, por ejemplo, actualizarlo automáticamente.
Llaves NFC Contiene información adicional para las transacciones de Apple Pay.


Ahora sobre todo con más detalle.


Campos obligatorios


Clave en JSONTipo de datosDescripción
descripciónCadena
Localizado
Una breve descripción del mapa. Localizado
formatVersionIntVersión de formato de archivo. El valor debe ser 1.
organizationNameCadena
Localizado
El nombre de la organización que emite las tarjetas.
passTypeIdentifierCadenaPase ID de tipo y cuenta de desarrollador.
serialNumberCadenaNúmero de serie de tarjeta única
teamIdentifierCadenaID del equipo del equipo de desarrollo

Claves para aplicaciones relacionadas


Clave en JSONTipo de datosDescripción
AssociatedStoreIdentifiers[Int]Opcionalmente El ID de las aplicaciones asociadas con la tarjeta. Siempre se toma el primero que es compatible con el dispositivo actual.
appLaunchURLCadenaURL que se pasa a la aplicación al abrir

Teclas de estilo


Clave en JSONTipo de datosDescripción
campos primarios[JSON]Información básica sobre el mapa.
campos secundarios[JSON]Información de antecedentes.
Campos auxiliares[JSON]Campos para información adicional. Opcional
headerFields[JSON]El título del mapa. Se muestra incluso cuando las tarjetas son visibles en la lista.
Campos auxiliares[JSON]Información básica sobre el mapa.
transitTypeCadenaTipo de transporte para tarjetas de boleto. Puede tomar los siguientes valores:
PK transitTypeAir,
PK transitTypeBoat,
PK transitTypeBu`,
PK transitTypeGeneric,
`PK transitTypeTrain`.
backFields[JSON]Matriz de campos responsables de la parte posterior del mapa

JSON en este caso tiene la siguiente forma:


"key" : "value1", "label" : "value2", "value" : "value3" 

El valor de la clave de valor puede ser numérico o de cadena. Sin embargo, currencyCode junto con el valor de cadena no se pueden usar. En cuanto a los campos auxiliares y los campos secundarios, puede haber varios de ellos, y debe controlar la longitud de las filas que se utilizan en ellos.


Claves para el diseño visual


Clave en JSONTipo de datosDescripción
códigos de barras[JSON]Información para el código de barras (ver abajo).
fondoColorcolor como cuerdaColor de fondo. (# Fa32e4)
primer planoColorcolor como cuerdaColor de etiqueta con valores
groupingIdentifierCadenaOpcional para boletos de eventos y boletos de transporte. Las tarjetas con el mismo estilo (passTypeIdentifier y groupingIdentifier) ​​se agruparán
labelColorcolor como cuerdaEtiquetar texto con nombres de campo
logoTextCadena localizableTexto que se muestra junto al logo

Código de barras


La parte más importante del mapa. Se le cose un número de identificación de tarjeta (por ejemplo, un número de tarjeta física o un número de boleto). Es importante que el escáner o cualquier otra herramienta pueda leer códigos en la codificación correcta.


Clave en JSONTipo de datosDescripción
altTextCadenaTexto opcional que se muestra al lado del código de barras si el código de barras no se lee.
formatearCadenaFormato de código de barras. Puede tomar valores: PKBarcodeFormatQR,
PKBarcodeFormatPDF417,
PKBarcodeFormatAztec,
PKBarcodeFormatCode128
mensajeCadenaCódigo o número de tarjeta encriptado en código de barras.
mensajeEncodingCadenaCodificación de mensajes. Generalmente iso-8859-1

Ubicación


Estas claves son responsables de la ubicación dentro de la cual se puede utilizar la tarjeta.


Clave en JSONTipo de datosDescripción
altitureCadenaTexto opcional que se muestra al lado del código de barras si el código de barras no se lee.
latitudLongitudLatitud
longitudDobleLatitud
texto relevanteCadenaTexto opcional que aparece en la pantalla de bloqueo en el momento en que el usuario ingresa al rango de la tarjeta.

Lado trasero


Se puede colocar información adicional en la parte de información inversa: términos de uso, política de actualización automática, detalles de contacto y un enlace a la aplicación a la que pertenece la tarjeta. La figura muestra la correspondencia de los campos en pass.json y la apariencia del reverso del mapa. Si hay enlaces, números de teléfono, etc. en el campo de valor, se resaltarán automáticamente.



Crea un mapa. Parte 2


Entonces, las imágenes están listas, se forma pass.json, queda por poner todo junto. Para hacer esto, complete manifest.json (consulte la tabla 1), donde debe incluir todas las imágenes y pass.json. Resulta algo como esto:


 . . . . . . "pass.json" = 303c753abc39aa732ec74643d6db28348fe8a823; "strip.png" = 736d01f84cb73d06e8a9932e43076d68f19461ff; "strip@2x.png" = 468fa7bc93e6b55342b56fda09bdce7c829d7d46; . . . . . . 

A partir de este momento, no es necesario cambiar nada, ya que el SHA será incorrecto; en caso de cambios, es necesario regenerar el SHA.


A continuación, debe crear una ID de tipo de pase en la oficina del desarrollador y hacer un certificado para ello. El procedimiento debería ser más o menos familiar si creó anteriormente, por ejemplo, los perfiles de aprovisionamiento.



A continuación, vaya al Llavero y exporte desde allí el Certificado de relación de desarrollador mundial de Apple (WWDR) como .pem.



A partir de ahí, exportamos el ID de tipo de pase creado como .p12. En este punto, el ama de llaves le pedirá que ingrese la contraseña para el certificado. En este caso, una contraseña es opcional.
Tenga en cuenta que todas las acciones adicionales deben realizarse en una carpeta, donde manifest.json, pass.json y las imágenes ya deberían estar.


Ahora necesita generar una firma, que firmaremos en el archivo. Primero, exporte la ID del tipo de pase y la clave como .pem.


 openssl pkcs12 -in certificate.p12 -clcerts -nokeys -out passcertificate.pem -passin pass: your_password 

y


 openssl pkcs12 -in certificates.p12 -nocerts -out passkey.pem -passin pass: -passout pass:new_password 

Ahora estamos listos para generar una firma. Hagámoslo un comando:


 openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:___ 

Entonces, todo está listo para nosotros, solo queda recopilar el archivo, hacemos esto con el comando:


 zip -r nameOfPass.pkpass manifest.json pass.json signature logo.png logo@2x.png logo@3x.png icon.png icon@2x.png icon@3x.png 

Le llamo la atención sobre el hecho de que todos los archivos en los que desea incluir el archivo de datos de la tarjeta (.pkpass) deben enumerarse aquí.
Como resultado, obtenemos un archivo .pkpass que se puede abrir en la computadora. Veremos una vista previa de la tarjeta, cuya apariencia puede diferir de la apariencia en el teléfono.
Todo esto se puede hacer un poco más fácil. Apple proporciona la utilidad signpass ( muestrarios de Apple Wallet ), que se encarga de todos los cálculos SHA (el archivo manifest.json se puede dejar solo) y el trabajo de crear firmas. Para usarlo, debe crear un proyecto y colocar el archivo signpass en una carpeta con todos los recursos necesarios.



En general, la estructura debería verse así:



A continuación, ejecute el comando:


 ./signpass -p wallet 

Wallet es el nombre de la carpeta en la que se encuentran todos los recursos. La salida es wallet.pkpass. Su contenido se puede ver descomprimiendo wallet.pkpass.


 unzip wallet.pkpass 

Es posible que la creación de pkpass se envíe al backend, en cuyo caso será necesario transferir a los desarrolladores del WWDR un certificado para la ID de tipo de pase en forma de .p12 y una contraseña para ello.


Integración de aplicaciones


Para que la aplicación pueda agregar tarjetas a Wallet, debe habilitar esta función en la ID de la aplicación y también habilitar esta función en Capacidades en el proyecto.




Esto es necesario para el trabajo correcto completo con Wallet. De lo contrario, no será posible leer tarjetas de Wallet y, por ejemplo, no será posible comprender si nuestra tarjeta está agregada o no. También es importante tener en cuenta que la identificación del equipo en pass.json debe coincidir con la identificación del equipo, o deberá agregarlos manualmente a los derechos y esto puede solucionar la situación, pero no lo comprobé.



Agregar una tarjeta


Agregar mapas es muy simple:


 guard let passPath = Bundle.main.path(forResource: "wallet", ofType: "pkpass") else { return } let error: ErrorPointer = ErrorPointer(nilLiteral: ()) guard let passData = NSData(contentsOfFile: passPath) else { return } let pass = PKPass(data: passData as Data, error: error) let passLibrary = PKPassLibrary() passLibrary.addPasses([pass]) { (status) in print(passLibrary.containsPass(pass)) } 

Sin embargo, una vez más, el archivo .pkpass más a menudo tendrá que descargarse de su servidor.
Vale la pena señalar que PassKit produce errores bastante legibles, por lo que puede comprender fácilmente qué se hizo exactamente mal.


Recuperando información sobre tarjetas agregadas


Para obtener información sobre las tarjetas disponibles en Wallet y relacionadas con su aplicación, debe recurrir al objeto PKPassLibrary.


 let passLibrary = PKPassLibrary() let passes = passLibrary.passes() 

Por lo tanto, puede comprender si el mapa se agrega o no, así como actualizar la interfaz. Además, a través de PKPassLibrary, los mapas se pueden actualizar y eliminar. Los mapas también se pueden actualizar a través de servicios web, pero en este artículo no consideraremos esa opción.


Verificación de unicidad


Como en su servicio, por regla general, la tarjeta está vinculada a una cuenta, en la aplicación lo más probable es que tenga que determinar de alguna manera si la tarjeta pertenece al usuario actual. Sugiero hacer esto a través de serialNumber . Por ejemplo, establezca la identificación de número de serie del usuario o número de tarjeta.


Prueba


Apple proporciona ejemplos de pkpass para diferentes tipos, puede centrarse en ellos.
Muestras de billetera de manzana
Para ver cómo se ve el mapa, puede agregar pkpass al proyecto (consulte “Agregar un mapa”). El proceso de agregar / quitar ya se discutió anteriormente, solo resta recordar que la aplicación no verá las tarjetas ya agregadas si la tarjeta para Wallet se creó en una cuenta de desarrollador, y el desarrollo en sí se realizó desde otra cuenta (relevante para las empresas de outsourcing). En este caso, puede agregar tarjetas sin problemas.
Puede verificar si la información en el código de barras está codificada correctamente utilizando cualquier escáner de código QR. Y definitivamente es necesario verificar la exactitud del trabajo con este escáner.


Conclusión


El artículo examinó el proceso de creación y diseño de un mapa, así como el proceso de integración con la aplicación y los problemas que pueden surgir. Intenté no abordar problemas de integración con servicios web y actualizaciones de mapas, y espero hacerlo en el próximo artículo.


Materiales utilizados


https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Creating.html
https://developer.apple.com/library/archive/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/TopLevel.html#//apple_ref/doc/uid/TP40012026-CH2-SW3
https://itechroof.wordpress.com/2015/11/30/apple-wallet-part-13/
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Updating.html


Un agradecimiento especial a mehdzor por la cuenta de desarrollador para las pruebas.

Source: https://habr.com/ru/post/es428437/


All Articles