Integrations Apple
Tirez parti de l'ecosysteme Apple : Pay, Wallet, WidgetKit, Siri et plus. YaniPay s'integre nativement avec les services Apple pour une experience fintech fluide et intuitive.
Overview
YaniPay exploite en profondeur l'ecosysteme Apple pour offrir une experience fintech sans couture. De Apple Pay pour les paiements tokenises a WidgetKit pour les widgets interactifs, en passant par Siri Shortcuts pour les commandes vocales et App Clips pour les paiements instantanes sans installation.
Chaque integration utilise les APIs natives d'Apple et suit les Human Interface Guidelines pour garantir une experience coherente et performante sur chaque plateforme.
Integrations Natives
Toutes les integrations Apple de YaniPay sont implementees via les frameworks natifs (PassKit, WidgetKit, Intents, AppClip). Aucune dependance tierce n'est utilisee, garantissant compatibilite et performance optimales.
Apple Pay
YaniPay supporte Apple Pay pour des paiements tokenises securises. Les numeros de carte ne sont jamais partages avec les marchands. A la place, un Device Account Numberunique est utilise, stocke dans le Secure Element de l'appareil.
import PassKit
class ApplePayManager: NSObject, ObservableObject {
@Published var paymentStatus: PaymentStatus = .idle
/// Check if Apple Pay is available on this device
var isAvailable: Bool {
PKPaymentAuthorizationController.canMakePayments(
usingNetworks: supportedNetworks
)
}
private let supportedNetworks: [PKPaymentNetwork] = [
.visa, .masterCard, .amex, .discover
]
/// Process a payment through Apple Pay
func processPayment(
amount: Decimal,
currency: String = "EUR",
merchantName: String = "YaniPay"
) async throws -> PKPaymentToken {
let request = PKPaymentRequest()
// Merchant configuration
request.merchantIdentifier = "merchant.com.yanipay"
request.supportedNetworks = supportedNetworks
request.merchantCapabilities = [.threeDSecure, .debit, .credit]
request.countryCode = "FR"
request.currencyCode = currency
// Payment summary
request.paymentSummaryItems = [
PKPaymentSummaryItem(
label: merchantName,
amount: NSDecimalNumber(decimal: amount)
)
]
// Required billing/shipping fields
request.requiredBillingContactFields = [.postalAddress]
// Present payment sheet
let controller = PKPaymentAuthorizationController(
paymentRequest: request
)
controller.delegate = self
guard let presented = try? await controller.present() else {
throw PaymentError.presentationFailed
}
return try await withCheckedThrowingContinuation { continuation in
self.paymentContinuation = continuation
}
}
}Paiement Tokenise
Aucun numero de carte reel n'est partage. Un token unique est genere pour chaque transaction.
Tap-to-Pay NFC
Paiement sans contact en approchant l'iPhone ou l'Apple Watch du terminal de paiement.
3D Secure
Authentification forte integree pour les paiements en ligne via Safari et les applications.
Apple Wallet
YaniPay genere des passes .pkpasspour Apple Wallet, permettant aux utilisateurs d'acceder a leur carte de fidelite, coupons et cartes virtuelles directement depuis l'application Wallet native. Les passes sont signes cryptographiquement et mis a jour automatiquement via push.
import PassKit
class PassKitGenerator {
static let shared = PassKitGenerator()
/// Generate a loyalty pass for Apple Wallet
func generateLoyaltyPass(card: LoyaltyCard) throws -> PKPass {
// Build pass JSON structure
let passData: [String: Any] = [
"formatVersion": 1,
"passTypeIdentifier": "pass.com.yanipay.loyalty",
"serialNumber": card.id.uuidString,
"teamIdentifier": "YANIPAY_TEAM",
"organizationName": "YaniPay",
"description": "Carte de fidelite YaniPay",
"logoText": "YaniPay",
"foregroundColor": "rgb(255, 255, 255)",
"backgroundColor": "rgb(16, 185, 129)",
"storeCard": [
"primaryFields": [
[
"key": "balance",
"label": "SOLDE POINTS",
"value": card.points
]
],
"secondaryFields": [
[
"key": "level",
"label": "NIVEAU",
"value": card.tier.rawValue
],
[
"key": "member-since",
"label": "MEMBRE DEPUIS",
"value": card.createdAt.formatted(.dateTime.year())
]
],
"backFields": [
[
"key": "terms",
"label": "Conditions",
"value": "Programme fidelite YaniPay..."
]
]
],
"barcode": [
"format": "PKBarcodeFormatQR",
"message": card.id.uuidString,
"messageEncoding": "iso-8859-1"
]
]
// Sign with CryptoKit and bundle as .pkpass
let signedData = try PassSigner.sign(passData)
return try PKPass(data: signedData)
}
/// Add pass to user's Apple Wallet
func addToWallet(pass: PKPass) async throws {
let library = PKPassLibrary()
guard !library.containsPass(pass) else { return }
library.addPasses([pass]) { status in
// Handle add result
}
}
}Mise a Jour Automatique
Les passes Apple Wallet supportent les mises a jour push. Lorsqu'un utilisateur gagne des points ou change de niveau, le pass est automatiquement mis a jour sur son appareil via les Push Notifications for Passes.
WidgetKit & ActivityKit
YaniPay propose des widgets interactifs pour l'ecran d'accueil, l'ecran de verrouillage et la Dynamic Island. Les widgets se mettent a jour automatiquement toutes les 15 minutes et les Live Activities offrent un suivi en temps reel des transactions.
Lock Screen Widgets
Consultez votre solde et effectuez des actions rapides directement depuis l'ecran de verrouillage. Support des tailles accessoryCircular et accessoryRectangular.
Home Screen Widgets
Widgets interactifs sur l'ecran d'accueil affichant le revenu, les transactions recentes et le statut de fidelite. Jusqu'a 3 tailles disponibles.
Live Activities
Suivez le statut de vos paiements en temps reel dans la Dynamic Island et sur l'ecran de verrouillage. Mises a jour push instantanees.
import WidgetKit
import SwiftUI
// MARK: - Timeline Provider
struct BalanceProvider: TimelineProvider {
func placeholder(in context: Context) -> BalanceEntry {
BalanceEntry(date: .now, balance: 1234.56, currency: "EUR")
}
func getSnapshot(in context: Context, completion: @escaping (BalanceEntry) -> Void) {
let entry = BalanceEntry(date: .now, balance: 1234.56, currency: "EUR")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<BalanceEntry>) -> Void) {
Task {
let balance = try await YaniPayAPI.shared.fetchBalance()
let entry = BalanceEntry(
date: .now,
balance: balance.amount,
currency: balance.currency
)
// Refresh every 15 minutes
let nextUpdate = Calendar.current.date(
byAdding: .minute, value: 15, to: .now
)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
}
// MARK: - Widget Configuration
struct YaniPayWidget: Widget {
let kind: String = "com.yanipay.balance"
var body: some WidgetConfiguration {
StaticConfiguration(
kind: kind,
provider: BalanceProvider()
) { entry in
BalanceWidgetView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
.configurationDisplayName("Solde YaniPay")
.description("Consultez votre solde en un coup d'oeil")
.supportedFamilies([
.systemSmall,
.systemMedium,
.accessoryCircular,
.accessoryRectangular
])
}
}
// MARK: - Widget View
struct BalanceWidgetView: View {
let entry: BalanceEntry
var body: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("yanipay-icon")
.resizable()
.frame(width: 24, height: 24)
Text("YaniPay")
.font(.caption)
.foregroundStyle(.secondary)
}
Text(entry.formattedBalance)
.font(.title.bold())
.foregroundStyle(.primary)
Text("Mis a jour \(entry.date.formatted(.relative(presentation: .named)))")
.font(.caption2)
.foregroundStyle(.tertiary)
}
.padding()
}
}import ActivityKit
// MARK: - Live Activity for Payment Tracking
struct PaymentAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var status: PaymentStatus
var amount: Decimal
var recipientName: String
var progress: Double // 0.0 to 1.0
}
var transactionId: String
var currency: String
}
class LiveActivityManager {
static let shared = LiveActivityManager()
/// Start a Live Activity for a payment in progress
func startPaymentTracking(
transactionId: String,
amount: Decimal,
recipient: String
) throws -> Activity<PaymentAttributes> {
let attributes = PaymentAttributes(
transactionId: transactionId,
currency: "EUR"
)
let initialState = PaymentAttributes.ContentState(
status: .processing,
amount: amount,
recipientName: recipient,
progress: 0.25
)
let content = ActivityContent(
state: initialState,
staleDate: .now.addingTimeInterval(300)
)
return try Activity<PaymentAttributes>.request(
attributes: attributes,
content: content,
pushType: .token // Enable push updates
)
}
/// Update Live Activity with new status
func updatePaymentStatus(
activity: Activity<PaymentAttributes>,
status: PaymentStatus,
progress: Double
) async {
var state = activity.content.state
state.status = status
state.progress = progress
let content = ActivityContent(
state: state,
staleDate: .now.addingTimeInterval(300)
)
await activity.update(content)
}
}Siri Shortcuts
YaniPay expose des App Intentspour Siri, permettant aux utilisateurs d'interagir avec leur compte par commandes vocales. Les intents sont automatiquement suggeres par iOS en fonction des habitudes de l'utilisateur.
| Commande vocale | Action |
|---|---|
| "Hey Siri, consulte mon solde YaniPay" | Affiche le solde du compte principal |
| "Hey Siri, envoie 50 euros avec YaniPay" | Ouvre un transfert pre-rempli de 50 EUR |
| "Hey Siri, mes dernieres transactions YaniPay" | Liste les 5 dernieres transactions |
| "Hey Siri, combien de points YaniPay ?" | Affiche le solde de points fidelite |
| "Hey Siri, payer avec YaniPay" | Active Apple Pay avec la carte YaniPay |
import AppIntents
import Intents
// MARK: - App Intent (iOS 16+)
struct CheckBalanceIntent: AppIntent {
static var title: LocalizedStringResource = "Consulter mon solde"
static var description: IntentDescription = "Affiche le solde de votre compte YaniPay"
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & ProvidesDialog {
let balance = try await YaniPayAPI.shared.fetchBalance()
let formatted = balance.formatted(.currency(code: "EUR"))
return .result(dialog: "Votre solde YaniPay est de \(formatted)")
}
}
struct SendMoneyIntent: AppIntent {
static var title: LocalizedStringResource = "Envoyer de l'argent"
static var description: IntentDescription = "Envoyez de l'argent via YaniPay"
@Parameter(title: "Montant")
var amount: Double
@Parameter(title: "Destinataire")
var recipient: String
func perform() async throws -> some IntentResult & ProvidesDialog {
// Open app with pre-filled transfer
return .result(dialog: "Ouverture du transfert de \(amount) EUR vers \(recipient)")
}
}
// MARK: - Shortcuts Provider
struct YaniPayShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: CheckBalanceIntent(),
phrases: [
"Consulte mon solde \(.applicationName)",
"Quel est mon solde \(.applicationName)",
"Mon solde \(.applicationName)"
],
shortTitle: "Solde",
systemImageName: "creditcard"
)
AppShortcut(
intent: SendMoneyIntent(),
phrases: [
"Envoie \(\$amount) euros avec \(.applicationName)",
"Transfere \(\$amount) via \(.applicationName)"
],
shortTitle: "Envoyer",
systemImageName: "arrow.right.circle"
)
}
}
// MARK: - Intent Donation for Siri Suggestions
class SiriShortcutsManager {
static let shared = SiriShortcutsManager()
/// Donate intent for Siri suggestions based on user actions
func donateIntent(for action: YaniPayAction) {
switch action {
case .checkBalance:
let intent = CheckBalanceIntent()
// iOS learns from donations and suggests at relevant times
IntentDonationManager.shared.donate(intent: intent)
case .sendMoney(let amount, let recipient):
let intent = SendMoneyIntent()
intent.amount = amount
intent.recipient = recipient
IntentDonationManager.shared.donate(intent: intent)
}
}
}Apple Intelligence
Avec iOS 18+, YaniPay exploite Apple Intelligence pour des notifications proactives, des suggestions contextuelles et une classification intelligente des transactions. Le traitement ML s'effectue entierement on-device pour garantir la confidentialite.
Notifications Proactives
iOS prioritise les notifications YaniPay en fonction du contexte : heure, lieu, habitudes de paiement et montants. Les alertes de securite sont toujours prioritaires.
Suggestions Intelligentes
Apple Intelligence suggere des actions YaniPay au bon moment : payer le loyer en debut de mois, envoyer de l'argent a un contact frequent, recharger avant un voyage.
Classification ML
15 intents Core ML categorisent automatiquement les transactions (alimentation, transport, loisirs) sans envoyer de donnees aux serveurs.
On-Device Processing
Tout le traitement ML s'effectue localement sur l'appareil. Aucune donnee financiere n'est envoyee a Apple ou a des serveurs tiers pour l'intelligence.
App Clips
Les App ClipsYaniPay permettent aux utilisateurs d'effectuer un paiement instantane sans telecharger l'application complete. Il suffit de scanner un QR code ou de toucher un tag NFC pour lancer une experience de paiement legere (<15 MB).
1. Toucher NFC
L'utilisateur touche un tag NFC ou scanne un QR code chez un commercant.
2. App Clip Charge
L'App Clip se charge instantanement (<15 MB). Aucune installation requise.
3. Paiement Instantane
L'utilisateur paye avec Apple Pay en un tap. Transition fluide vers l'app complete.
import SwiftUI
import AppClip
// MARK: - App Clip Entry Point
@main
struct YaniPayAppClipApp: App {
@StateObject private var paymentManager = AppClipPaymentManager()
var body: some Scene {
WindowGroup {
AppClipPaymentView()
.environmentObject(paymentManager)
.onContinueUserActivity(
NSUserActivityTypeBrowsingWeb
) { activity in
// Handle App Clip invocation URL
guard let url = activity.webpageURL else { return }
paymentManager.handleInvocation(url: url)
}
}
}
}
// MARK: - App Clip Payment View
struct AppClipPaymentView: View {
@EnvironmentObject var paymentManager: AppClipPaymentManager
var body: some View {
VStack(spacing: 24) {
// YaniPay branding
Image("yanipay-logo")
.resizable()
.scaledToFit()
.frame(height: 48)
// Amount display
Text(paymentManager.formattedAmount)
.font(.system(size: 48, weight: .bold, design: .rounded))
Text(paymentManager.merchantName)
.font(.title3)
.foregroundStyle(.secondary)
Spacer()
// Apple Pay button
PayWithApplePayButton(.pay, action: {
Task {
try await paymentManager.processPayment()
}
})
.frame(height: 50)
.padding(.horizontal)
// Full app promotion
AppStoreOverlayModifier(
isPresented: $paymentManager.showFullAppPromo
)
}
.padding()
}
}
// MARK: - Shared Data with Main App
class AppClipPaymentManager: ObservableObject {
@Published var amount: Decimal = 0
@Published var merchantName: String = ""
@Published var showFullAppPromo = false
/// Handle invocation URL from NFC/QR code
func handleInvocation(url: URL) {
// Parse payment parameters from URL
// e.g., https://yanipay.com/pay?amount=25.00&merchant=CafeParisien
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
amount = Decimal(
string: components?.queryItems?
.first(where: { $0.name == "amount" })?.value ?? "0"
) ?? 0
merchantName = components?.queryItems?
.first(where: { $0.name == "merchant" })?.value ?? "Commercant"
}
/// Process payment via Apple Pay
func processPayment() async throws {
let token = try await ApplePayManager().processPayment(
amount: amount,
merchantName: merchantName
)
// Send token to YaniPay backend
try await YaniPayAPI.shared.processAppClipPayment(token: token)
// Prompt to download full app
await MainActor.run { showFullAppPromo = true }
}
}Donnees Partagees
Les App Clips partagent les donnees Core Data avec l'application principale via un App Group. Les utilisateurs peuvent commencer avec un App Clip et passer a l'app complete sans perdre leurs donnees. L'historique de paiement, les preferences et les informations de fidelite sont automatiquement transferes.
Matrice de Compatibilite
Chaque integration Apple n'est pas disponible sur toutes les plateformes. Ce tableau recapitule la compatibilite de chaque fonctionnalite par plateforme Apple.
| Integration | iOS | iPadOS | macOS | watchOS | visionOS |
|---|---|---|---|---|---|
| Apple Pay | ✓ | ✓ | ✓ | ✓ | — |
| Apple Wallet | ✓ | — | — | ✓ | — |
| WidgetKit | ✓ | ✓ | ✓ | ✓ | — |
| Live Activities | ✓ | ✓ | — | — | — |
| Siri Shortcuts | ✓ | ✓ | ✓ | ✓ | ✓ |
| App Clips | ✓ | ✓ | — | — | — |
| Apple Intelligence | ✓ | ✓ | ✓ | — | — |
| NFC / Tap-to-Pay | ✓ | — | — | ✓ | — |
visionOS en Developpement
Les integrations visionOS sont actuellement limitees a Siri Shortcuts. Le support Apple Pay et WidgetKit pour Vision Pro sera ajoute dans une mise a jour future en fonction des APIs Apple disponibles.