Aperçu
Ce que c'est
Acceptez les paiements Apple Pay via MONDO
Ce dont vous avez besoin
ID de compte MONDO + Clé secrète
Ce que vous envoyez
Jeton Apple Pay + montant + devise
Ce que vous obtenez
STATUT COMPLÉTÉ ou REJETÉ
Comment ça fonctionne
Option A : Auto-hébergé
Vous affichez le bouton Apple Pay sur votre site et nous envoyez le jeton
Option B : Hébergé par MONDO
Nous gérons tout - redirigez simplement votre client vers nous
Démarrage rapide (Auto-hébergé)
POST https://server-to-server.getmondo.co/payment/
{
"company_account_id": "your_id",
"gateway_secret_key": "your_key",
"apple_pay_token": { /* from Apple Pay JS */ },
"transaction_amount": "99.99",
"transaction_currency_iso3": "EUR",
"live_or_sandbox": "sandbox"
}
À propos d'Apple Pay
Apple Pay offre un moyen rapide, sécurisé et privé pour les clients de payer. Avec MONDO comme votre fournisseur de services de paiement (PSP), vous pouvez accepter Apple Pay sans nécessiter votre propre compte de développeur Apple.
MONDO comme votre PSP
- ✓ MONDO possède l'ID marchand Apple
- ✓ MONDO gère les certificats Apple Pay
- ✓ MONDO gère la validation des marchands
- ✓ MONDO déchiffre et traite les jetons de paiement
Gestion des jetons — Qui fait quoi ?
Apple Pay utilise un cryptage de bout en bout pour protéger les données des titulaires de carte. Voici comment les responsabilités sont réparties :
| Apple (Appareil du client) | Génère un jeton de paiement crypté contenant les données de la carte, le cryptogramme et les détails d'authentification |
| Vous (Marchand) | Passez le jeton crypté directement à MONDO via le paramètre apple_pay_token — ne tentez PAS de décrypter |
| MONDO (PSP) | Déchiffre le jeton en utilisant notre certificat de traitement de paiement Apple Pay et traite le paiement avec CardCorp |
Choisissez votre méthode d'intégration
📋 Prérequis
- ✓ ID du compte partenaire - Votre identifiant unique de compte MONDO
- ✓ Clé secrète partenaire - Votre clé d'authentification API
- ✓ HTTPS - Votre site web doit utiliser HTTPS
⚠️ Vérification de domaine requise
Votre domaine doit être enregistré auprès d'Apple via MONDO. Il s'agit d'une configuration unique.
- Aller à GETMONDO.CO
- Login → Developer → Apple Pay → Add Apple Pay Domain
🔄 Flux de paiement
Sur votre site web
Interface native Apple Pay
Votre appel JS au point de validation de MONDO
Face ID / Touch ID
POST to /payment/ with apple_pay_token
Utilisateur redirigé vers l'URL de succès/échec
🔗 Point de terminaison API
Point de validation marchand
Paramètres de validation du marchand
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| validationURL | string | ✓ Oui | L'URL fournie par Apple en onvalidatemerchant événement |
| company_account_id | string | ✓ Oui | Votre identifiant de compte partenaire MONDO |
| gateway_secret_key | string | ✓ Oui | Votre clé secrète MONDO Partner |
| domain_name | string | ○ Conditionnel | Votre domaine Apple Pay (par ex. paynow.yoursite.com). Nécessaire pour les appels serveur à serveur lorsque l'en-tête Origin du navigateur n'est pas disponible. Non requis si l'appel est effectué directement depuis le navigateur. |
Si votre backend proxy l'appel de validation du marchand (c.-à-d. votre serveur appelle MONDO au lieu que le navigateur appelle directement), vous devez inclure
domain_name défini sur le domaine où votre bouton Apple Pay est affiché. Cela garantit que la session Apple Pay correspond à votre domaine de page de paiement. 📝 Paramètres requis (Traitement du paiement)
| Paramètre | Type | Description |
|---|---|---|
| company_account_id | string | Votre identifiant de compte partenaire MONDO |
| gateway_secret_key | string | Votre clé secrète MONDO Partner |
| apple_pay_token | object | Chiffré jeton de event.payment.token — passer directement à MONDO tel quel (ne pas décrypter) |
| transaction_amount | decimal | Montant du paiement (ex. : 99,99) |
| transaction_currency_iso3 | string | Code monétaire (EUR, USD, GBP) |
| cardholder_email_address | string | E-mail du client |
Paramètres optionnels
| Paramètre | Description |
|---|---|
| partner_return_url_completed | URL de redirection après paiement réussi |
| partner_return_url_rejected | URL de redirection pour paiement refusé |
| partner_webhook_url | URL pour les notifications webhook |
| live_or_sandbox | live ou sandbox |
📤 Réponse API
Les paiements Apple Pay sont traités immédiatement. La réponse contient le statut final de la transaction :
{
"status": "success",
"transaction_status": "COMPLETED",
"gateway_session_id": "73d68b79579eeaa4a1f35f667509ba19",
"transaction_id": "37819a4707f3736b6fb42148d98f05ab",
"gateway_message": "Transaction succeeded",
"redirect_url": "https://yoursite.com/success?gateway_session_id=...&payment_status=COMPLETED"
}
Champs de réponse
| Champ | Description |
|---|---|
| status | success ou error |
| transaction_status | COMPLETED ou REJECTED |
| gateway_session_id | Identifiant unique de session pour cette transaction |
| transaction_id | Identifiant de transaction unique - utilisez ceci pour corréler avec les callbacks |
| gateway_message | Message de statut lisible |
| redirect_url | URL pour rediriger l'utilisateur après le paiement (optionnel - uniquement pour l'UX) |
Contrairement aux paiements par carte qui nécessitent une redirection 3D Secure, les transactions Apple Pay sont traitées instantanément. Le paiement est déjà effectué lorsque vous recevez la réponse.
🍎 Intégration Apple Pay JS
Étape 1 : Ajouter le bouton Apple Pay
<apple-pay-button buttonstyle="black" type="plain" locale="en" onclick="startApplePayPayment()"></apple-pay-button>
Étape 2 : Vérifier la disponibilité
if (window.ApplePaySession && ApplePaySession.canMakePayments()) {
document.getElementById('apple-pay-button').style.display = 'block';
}
Étape 3 : Implémentation complète
async function startApplePayPayment() {
const paymentRequest = {
countryCode: 'US',
currencyCode: 'EUR',
merchantCapabilities: ['supports3DS'],
supportedNetworks: ['visa', 'masterCard'],
total: { label: 'Your Company', amount: '99.99', type: 'final' }
};
const session = new ApplePaySession(3, paymentRequest);
// Merchant Validation
session.onvalidatemerchant = async (event) => {
const resp = await fetch('https://server-to-server.getmondo.co/payment/apple_pay_validate_merchant.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
validationURL: event.validationURL,
company_account_id: 'YOUR_ACCOUNT_ID',
gateway_secret_key: 'YOUR_SECRET_KEY',
domain_name: 'your-domain.com' // Required for server-to-server; optional if browser calls directly
})
});
session.completeMerchantValidation(await resp.json());
};
// Payment Authorization - Apple provides ENCRYPTED token in event.payment.token
// IMPORTANT: Pass the token directly to MONDO - do NOT attempt to decrypt it
session.onpaymentauthorized = async (event) => {
const resp = await fetch('https://server-to-server.getmondo.co/payment/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
company_account_id: 'YOUR_ACCOUNT_ID',
gateway_secret_key: 'YOUR_SECRET_KEY',
apple_pay_token: event.payment.token, // Encrypted token - MONDO decrypts
transaction_amount: '99.99',
transaction_currency_iso3: 'EUR',
cardholder_email_address: 'customer@example.com',
partner_return_url_completed: 'https://yoursite.com/success',
partner_return_url_rejected: 'https://yoursite.com/failed',
live_or_sandbox: 'live'
})
});
const result = await resp.json();
if (result.transaction_status === 'COMPLETED') {
session.completePayment(ApplePaySession.STATUS_SUCCESS);
// Payment already processed - redirect is optional for user experience
if (result.redirect_url) {
window.location.href = result.redirect_url;
}
} else {
session.completePayment(ApplePaySession.STATUS_FAILURE);
if (result.redirect_url) {
window.location.href = result.redirect_url;
}
}
};
session.begin();
}
Modes de test
MONDO prend en charge deux modes de test. Comprendre la différence est crucial pour une intégration réussie.
Que se passe-t-il
- ✅ La structure du jeton est validée
- ✅ Tous les champs requis sont vérifiés
- ⏭️ Le décryptage est ignoré (données fictives renvoyées)
- ⏭️ L'appel API CardCorp est ignoré
- ✅ Le flux de paiement complet est exécuté
Que se passe-t-il
- ✅ La structure du jeton est validée
- ✅ Tous les champs requis sont vérifiés
- ✅ Décryptage cryptographique réel
- ✅ Traitement de l'API Real CardCorp
- ✅ De l'argent réel est facturé
🎯 Pourquoi SANDBOX nécessite la même structure de jeton
Ce design garantit que lorsque vous passez de SANDBOX à LIVE, votre intégration fonctionne immédiatement sans modifications de code.
⚙️ Définir le mode
Inclure le live_or_sandbox paramètre dans votre demande API :
{
"company_account_id": "your_account_id",
"gateway_secret_key": "your_secret_key",
"apple_pay_token": { ... },
"transaction_amount": "99.99",
"transaction_currency_iso3": "EUR",
"live_or_sandbox": "sandbox" // or "live" for production
}
🎭 Bac à sable : Forcer le résultat de la transaction
En mode BAC À SABLE, vous pouvez forcer un résultat de transaction spécifique pour les tests :
| Paramètre | Valeur | Résultat |
|---|---|---|
| sandbox_force_transaction_status | COMPLETED |
✅ Paiement approuvé |
| sandbox_force_transaction_status | REJECTED |
❌ Paiement refusé |
Structure du jeton Apple Pay
Le jeton Apple Pay doit avoir la structure suivante. Cela est identique pour les modes SANDBOX et LIVE.
"***") entraînera une erreur, même en mode SANDBOX. Structure de jeton requise
{
"paymentData": {
"version": "EC_v1",
"data": "BASE64_ENCRYPTED_PAYMENT_DATA",
"signature": "BASE64_SIGNATURE",
"header": {
"ephemeralPublicKey": "BASE64_EPHEMERAL_KEY",
"publicKeyHash": "BASE64_PUBLIC_KEY_HASH",
"transactionId": "UNIQUE_TRANSACTION_ID"
}
},
"paymentMethod": {
"displayName": "Visa 1234",
"network": "Visa",
"type": "debit"
},
"transactionIdentifier": "APPLE_TRANSACTION_ID"
}
Descriptions des champs
| Champ | Requis | Description |
|---|---|---|
| paymentData.version | ✓ | Toujours EC_v1 |
| paymentData.data | ✓ | Données de paiement chiffrées en Base64 d'Apple |
| paymentData.signature | ✓ | Signature Base64 pour vérification |
| paymentData.header.ephemeralPublicKey | ✓ | Clé publique éphémère Base64 |
| paymentData.header.publicKeyHash | ✓ | Clé publique du marchand en Base64 |
| paymentData.header.transactionId | ✓ | Identifiant de transaction unique |
| paymentMethod.network | ○ | Réseau de cartes (Visa, Mastercard, Amex) |
| paymentMethod.displayName | ○ | Nom affiché depuis Apple Wallet |
✓ = Requis | ○ = Recommandé
Jeton de test bac à sable
Copiez ce jeton pour les tests SANDBOX. Les valeurs cryptées ne doivent pas être réelles - seule la structure est validée.
{
"paymentData": {
"version": "EC_v1",
"data": "c2FuZGJveF9lbmNyeXB0ZWRfZGF0YV8xNzAyMjU2MDAwMDAw",
"signature": "c2FuZGJveF9zaWduYXR1cmVfMTcwMjI1NjAwMDAwMA==",
"header": {
"ephemeralPublicKey": "c2FuZGJveF9lcGhlbWVyYWxfa2V5XzE3MDIyNTYwMDAwMDA=",
"publicKeyHash": "c2FuZGJveF9wdWJsaWNfa2V5X2hhc2g=",
"transactionId": "SANDBOX_TXN_1702256000000_a1b2c3d4e5f6"
}
},
"paymentMethod": {
"displayName": "Visa 4242",
"network": "Visa",
"type": "debit"
},
"transactionIdentifier": "SANDBOX_TXN_1702256000000_a1b2c3d4e5f6"
}
Erreurs de jeton courantes
| Erreur | Cause | Solution |
|---|---|---|
| Invalid token format | Le jeton n'est pas un objet JSON | Envoyez le jeton en tant qu'objet, pas en tant que chaîne |
| Missing paymentData | Le jeton n'a pas la propriété paymentData | Inclure le jeton complet d'Apple Pay JS |
| Missing header fields | cléPubliqueÉphémère, hachageDeCléPublique, ou identifiantDeTransaction manquant | Vérifiez que tous les champs d'en-tête sont présents |
D'où vient le jeton ?
En mode DIRECT, le jeton provient de Apple Pay JS lorsque l'utilisateur autorise le paiement :
session.onpaymentauthorized = (event) => {
// This is the token you send to MONDO
const token = event.payment.token;
// Send to MONDO API
fetch('/payment/', {
body: JSON.stringify({
apple_pay_token: token, // Pass the entire token object
...
})
});
};
Statut de la transaction
Comprendre les statuts de transaction et comment les interroger est essentiel pour une intégration complète.
Statuts finaux de la transaction
Voici les statuts finaux possibles que vous recevrez via webhook ou lors de l'interrogation du point de terminaison /details :
Statut intermédiaire
La transaction a été créée mais est encore en cours de traitement. Cela peut se produire lorsque :
- L'utilisateur effectue l'authentification 3D Secure
- Le paiement est en cours de traitement par le réseau de la carte
- L'utilisateur a abandonné le processus de paiement
Quand vérifier le statut de la transaction ?
- Vous n'avez pas reçu un webhook dans le délai prévu (par ex., 5 minutes)
- Vous devez vérifier manuellement le statut de la transaction
- Votre point de terminaison webhook était temporairement indisponible
Statut de la transaction
Pour vérifier le statut d'une transaction, effectuez une requête POST sur le point de terminaison des détails :
Paramètres de requête
| Paramètre | Requis | Description |
|---|---|---|
| company_account_id | ✓ | Votre identifiant de compte partenaire MONDO |
| gateway_secret_key | ✓ | Votre clé secrète MONDO Partner |
| gateway_session_id | ✓ | L'ID de session renvoyé de la demande de paiement initiale |
Requête Exemple
curl -X POST https://server-to-server.getmondo.co/details/ \
-H "Content-Type: application/json" \
-d '{
"company_account_id": "your_account_id",
"gateway_secret_key": "your_secret_key",
"gateway_session_id": "sess_abc123xyz"
}'
Réponse Exemple
{
"success": true,
"transaction_status": "COMPLETED",
"gateway_session_id": "sess_abc123xyz",
"transaction_amount": "99.99",
"transaction_currency_iso3": "EUR",
"card_last_4_digits": "4242",
"card_brand": "VISA",
"gateway_result_code": "000.000.000",
"gateway_result_description": "Transaction succeeded",
"created_at": "2024-12-10T22:30:00Z",
"completed_at": "2024-12-10T22:31:15Z"
}
Mise à jour du statut
Il y a deux manières de recevoir le statut final de la transaction :
| Méthode | Comment ça fonctionne | Quand utiliser |
|---|---|---|
| Webhook Recommandé | MONDO envoie une requête POST à votre partner_webhook_url |
Méthode principale - automatique, en temps réel |
| Redirect URL | L'utilisateur est redirigé vers votre partner_return_url_completed ou partner_return_url_rejected |
Pour confirmation utilisateur |
| Query /details | Vous effectuez une requête POST pour vérifier le statut | Retour si webhook non reçu |
Si la transaction reste INITIÉE
Si une transaction reste en statut INITIÉE pendant plus de 15 minutes, cela signifie probablement :
- L'utilisateur a abandonné le défi 3D Secure
- L'utilisateur a fermé son navigateur pendant le paiement
- Il y a eu un problème de réseau lors du traitement
Action : Interrogez le point de terminaison /details pour obtenir le statut actuel. Ces transactions finiront par expirer et passeront au statut ÉCHOUÉ ou ANNULÉ.