Quoi de neuf en v1.5.3
What's new in v1.5.3May 5, 2026
🐛 Bug fix critique — Wallets::list() retournait silencieusement 0 EUR au lieu du vrai solde. — Critical bug fix: Wallets::list() silently returned 0 EUR instead of the real balance.
GitHub Release v1.5.3 →
Wallets::list() — fix unwrap réponse Legacy —
L'endpoint /api/wallets peut retourner trois formes
({Wallets: [...]}, liste directe [...], objet seul
{...}). Le fallback précédent
$result['Wallets'] ?? $result['wallets'] ?? [$result] wrappait
la liste déjà-plate dans un array supplémentaire — balance()
itérait alors sur 1 élément qui était lui-même un array et tous les
soldes évaluaient silencieusement à 0. Reproduit en prod
sur merchant 0119432c-… (vrai Available:
17.89 EUR, balance() pré-v1.5.3: 0 EUR).
— Fix Wallets::list() unwrap nested response. Pre-v1.5.3 silently returned 0 EUR.
Drop-in fix — Aucun changement d'API publique. Update
via composer require qrcommunication/viva-merchant-sdk:^1.5.3.
— Drop-in fix, no public API change.
📜 Antérieur — Quoi de neuf en v1.5.2 (5 mai 2026)
📜 Earlier — What's new in v1.5.2 (May 5, 2026)
Wallets::list(), Account::wallets(), Account::info() — fix routage Legacy API —
Les trois méthodes appelaient HttpClient::get() au lieu
de legacyGet(). Conséquence : /api/wallets et
/api/accounts/{id} étaient routés vers
api.vivapayments.com avec Bearer OAuth2 au lieu de
www.vivapayments.com avec Basic Auth → HTTP 404 systématique.
— Fix Legacy API routing: 3 methods now correctly hit www.vivapayments.com with Basic Auth.
Drop-in fix, aucun changement d'API publique.
— Drop-in fix, no public API change.
📜 Antérieur — Quoi de neuf en v1.5.1 (4 mai 2026)
📜 Earlier — What's new in v1.5.1 (May 4, 2026)
Documentation-only release — aucun breaking change. Findings prod-testés + audit complet de la doc Viva.
GitHub Release v1.5.1 →
Référence skill/references/prod-findings.md —
Confirmation que TOUS les endpoints du SDK fonctionnent en production avec Basic Auth simple (testé sur compte ISV propre QR Communication).
— Confirmation that ALL SDK endpoints work in production with simple Basic Auth.
Section "Production gotchas" dans SKILL.md —
Référence rapide pour agents IA : endpoints testés, quand utiliser ce SDK vs viva-isv-sdk, handshake webhook, IPs Azure sans signature, codes d'erreur.
— Quick reference for AI agents.
EventTypeIds étendus documentés —
Au-delà des 21 trackés actuellement : 1802/1803 (POS ECR), 4865 (Order Updated), 5632/5633 (DEPRECATED Marketplace), 8448 (Transfer Created) + Sale Transactions signed.
— Extended EventTypeIds beyond the current 21 tracked.
SubTypeIds 2054 complets —
Incluant 183 IsvAcquiringCommission, 200-203 TransfersPlatform* (settlements marketplace), full ranges PayIn/PayOut/Clearance/Wallet/Obligations.
— Full SubTypeId table for event 2054.
Test amounts pour décliner —
Table complète .9905-.9996 → EventIds 10005-10096 pour tests E2E (insufficient funds, expired card, pickup, etc.).
— Full test amounts table for E2E decline testing.
Roadmap endpoints non couverts —
Data Services Search, Acquiring v1 cards/refunds, POS Cloud Terminal /ecr/v1/* self, RF Code (Greek), Issuing API.
— Roadmap of yet-uncovered Viva endpoints.
📜 Antérieur — Quoi de neuf en v1.5.0 (1er mai 2026)
📜 Earlier — What's new in v1.5.0 (May 1, 2026)
Nouvelle ressource Messages —
Enregistrement de webhooks au niveau marchand via /api/messages/config (Basic Auth simple merchantId:apiKey).
Nouveau helper WebhookRegistrar —
Enregistrement idempotent des événements banking en un seul appel (registerAll).
Constante BANKING_EVENTS = [768, 769, 2054]
Contracts HttpClientInterface + MessagesInterface —
Extraction des interfaces pour le mocking (Dependency Inversion Principle).
Alignement avec sdk-php-viva-isv —
Signature registerAll($callbackUrl, ?$events) identique.
Installation
Installez le SDK via Composer. Requiert PHP 8.2+ avec les extensions ext-json et ext-curl.
Install the SDK via Composer. Requires PHP 8.2+ with ext-json and ext-curl extensions.
Compatible avec Laravel, Symfony, ou tout projet PHP standard.
Démarrage rapideQuick Start
<?php
use QrCommunication\VivaMerchant\VivaClient;
$viva = new VivaClient(
merchantId: 'votre-merchant-uuid',
apiKey: 'votre-api-key',
clientId: 'xxx.apps.vivapayments.com',
clientSecret: 'votre-client-secret',
environment: 'demo', // ou 'production'
);
// Créer un ordre de paiement — Create a payment order
$order = $viva->orders->create(
amount: 1500,
customerDescription: 'Consultation',
);
// Rediriger le client vers $order['checkout_url']
// Vérifier une transaction après paiement — Verify a transaction after payment
$txn = $viva->transactions->getV2('transaction-uuid');
// Rembourser (partiel) — Partial refund
$viva->transactions->cancel('transaction-uuid', amount: 500);
// Capturer une pré-autorisation — Capture a pre-authorization
$viva->transactions->capture('preauth-uuid', amount: 1500);
// Charge récurrente — Recurring charge
$viva->transactions->recurring('initial-txn-uuid', amount: 1500);
// Apple Pay / Google Pay (NativeCheckout)
$token = $viva->nativeCheckout->createChargeToken(1500, $applePayData);
$txn = $viva->nativeCheckout->createTransaction($token['chargeToken'], 1500);
// Tester la connexion — Test connection
$ok = $viva->testConnection(); // true ou false
Configuration
Le constructeur VivaClient accepte 5 paramètres. L'authentification OAuth2 est gérée automatiquement — le token est mis en cache et rafraîchi avant expiration.
The VivaClient constructor accepts 5 parameters. OAuth2 authentication is handled automatically — the token is cached in memory and refreshed before expiry.
Paramètre
Type
Requis
Description
merchantId
string
Oui
UUID du marchand Viva Wallet
apiKey
string
Oui
Clé API (Legacy API — Basic Auth)
clientId
string
Oui
Client ID OAuth2 (format xxx.apps.vivapayments.com)
clientSecret
string
Oui
Secret OAuth2
environment
string|Environment
Non
'demo' (défaut) ou 'production'
Architecture d'authentification
Le SDK utilise deux mécanismes d'authentification selon la ressource utilisée :
Fix v1.5.3 — Déballage correct des 3 formes de réponse possibles.
Auparavant un double-nesting silencieux faisait retourner 0 EUR à balance() même avec des fonds réels.
Paiements natifs Apple Pay et Google Pay directement depuis votre application mobile ou web.
Native Apple Pay and Google Pay payments directly from your mobile or web application.
Le flux NativeCheckout se déroule en deux étapes : d'abord générer un chargeToken à partir des données de paiement mobile, puis créer la transaction avec ce token.
createChargeToken()
Générer un token de charge à partir des données Apple Pay ou Google Pay.
Déclencher la génération asynchrone d'un fichier pour une date donnée.
Utilisez une souscription webhook pour être notifié de la disponibilité du fichier.
$viva->dataServices->requestFile('2026-03-18');
// Génération asynchrone — attendre le webhook 'sale.transactions.file'
8
Webhooks
$viva->webhooks
Vérification et parsing des webhooks Viva Wallet. Aucun appel API — traitement entièrement local.
Viva Wallet webhook verification and parsing. No API calls — fully local processing.
Événements banking merchant-level — enregistrement via MessagesNew v1.5.0
Ces 3 événements s'enregistrent via $viva->messages->register() ou via le helper WebhookRegistrar::registerAll().
Ils utilisent l'endpoint /api/messages/config (Basic Auth), différent de l'endpoint ISV-level.
These 3 events are registered via $viva->messages->register() or the WebhookRegistrar::registerAll() helper.
Enregistrement de webhooks au niveau marchand via /api/messages/config.
Utilise le Basic Auth (merchantId:apiKey) — différent des webhooks ISV-level.
Merchant-level webhook registration via /api/messages/config.
Uses Basic Auth (merchantId:apiKey) — distinct from ISV-level webhooks.
Méthode
Signature
Retour
register
register(string $callbackUrl, int $eventTypeId)
array
list
list()
array
delete
delete(int $eventTypeId)
array
// Enregistrer un événement banking
$viva->messages->register(
callbackUrl: 'https://myapp.com/api/webhooks/viva',
eventTypeId: 768, // Command Bank Transfer Created
);
// Lister les souscriptions actives
$subscriptions = $viva->messages->list();
// Supprimer un abonnement
$viva->messages->delete(768);
use QrCommunication\VivaMerchant\Helpers\WebhookRegistrar;
// Enregistrer les 3 événements banking en un seul appel
$results = $viva->webhookRegistrar()->registerAll(
callbackUrl: 'https://app.example.com/api/webhooks/viva',
);
// [
// 'registered' => [768, 769, 2054],
// 'skipped' => [],
// 'failed' => [],
// ]
// Enregistrer un sous-ensemble
$results = $viva->webhookRegistrar()->registerAll(
callbackUrl: 'https://app.example.com/api/webhooks/viva',
events: [768],
);
// Consulter les IDs gérés
$bankingEvents = WebhookRegistrar::BANKING_EVENTS; // [768, 769, 2054]
Idempotent :
Sûr d'être appelé plusieurs fois (ex. : dans votre pipeline de déploiement ou lors de la création d'un compte).
Safe to call multiple times — e.g. in your deploy pipeline or account setup flow.
Contracts
New v1.5.0
Deux interfaces extraites du SDK pour faciliter le mocking dans les tests (Dependency Inversion Principle).
Two interfaces extracted for testability — inject them instead of concrete classes in your services.
Interface
Namespace
Description
HttpClientInterface
QrCommunication\VivaMerchant\Contracts
Contrat pour le client HTTP interne.
— Contract for the internal HTTP client.
MessagesInterface
QrCommunication\VivaMerchant\Contracts
Contrat pour la resource Messages — permet de mocker l'enregistrement webhook.
— Contract for the Messages resource — enables mocking webhook registration.
use QrCommunication\VivaMerchant\Contracts\MessagesInterface;
// Injection dans un service — testable sans appel HTTP réel
class MyOnboardingService
{
public function __construct(
private readonly MessagesInterface $messages,
) {}
public function registerWebhooks(string $callbackUrl): void
{
$this->messages->register($callbackUrl, 768);
$this->messages->register($callbackUrl, 769);
}
}
// Dans un test PHPUnit
$mockMessages = $this->createMock(MessagesInterface::class);
$mockMessages->expects($this->exactly(2))->method('register');
$service = new MyOnboardingService($mockMessages);
$service->registerWebhooks('https://example.com/webhooks/viva');
Enums
Environment
Environnement Viva Wallet. Accepté en string ou en instance d'enum.
Aller dans Settings > API Access > Webhooks, ajouter l'URL de votre endpoint et noter la clé de vérification.
2. Gérer la vérification (GET)
Viva envoie une requête GET pour vérifier la disponibilité de l'endpoint.
// Route GET /webhooks/viva
public function verify()
{
return response()->json(
$viva->webhooks->verificationResponse('votre-clé-de-vérification')
);
}
Laravel :
Exclure l'URL webhook du middleware VerifyCsrfToken dans bootstrap/app.php.
Carte de testTest Card
Pour l'environnement demo uniquement. Aucun 3DS n'est requis en mode démo.
Champ
Valeur
Numéro de carte
4111 1111 1111 1111
Expiration
Toute date future
CVV
111
3DS
Non requis en mode demo
Pièges en production (testés 2026-05)
Production gotchas (prod-tested 2026-05)v1.5.1
Ces comportements ont été observés sur un compte propre Viva production réel (Merchant ISV propre QR Communication, 0119432c-...) et complètent la doc Viva officielle.
These behaviors were observed on a real production Viva account and supplement the official Viva docs.
Endpoints confirmés fonctionnels en prod (Basic Auth simple)
Endpoint
Méthode SDK
Notes
POST /api/orders
$viva->orders->create()
OrderCode retourné, success: true
GET /api/orders/{orderCode}
$viva->orders->get()
Statut ordre
POST /api/transactions/{txnId}
$viva->transactions->capture()
Capture preauth
DELETE /api/transactions/{txnId}
$viva->transactions->cancel()
Refund/void selon date
POST /api/transactions/{initialTxnId}
$viva->transactions->recurring()
Charge récurrent
GET /api/wallets
$viva->wallets->list()
IBAN, soldes, currency code
POST /api/sources
$viva->sources->create()
Création Source Smart Checkout
POST /api/messages/config
$viva->messages->register()
Webhooks merchant-level
⚠ Distinction importante avec viva-isv-sdk —
Sur les comptes connectés ISV (sub-merchants opérés via composite auth), POST /api/messages/config retourne 404. Ce SDK fonctionne avec Basic Auth simple sur le compte propre uniquement. Pour les sub-merchants ISV, voir qrcommunication/viva-isv-sdk.
EventTypeIds étendus (au-delà des 21 actuellement trackés)
urn:viva:payments:biservices:internalapi — Data Services internal
⚠ Ne jamais passer scope=... dans /connect/token — Viva dérive les scopes des credentials utilisées. Tenter d'envoyer un scope explicite retourne invalid_scope.
Webhook signature handshake
Avant messages->register(), votre endpoint webhook DOIT répondre à un GET avec :
Before messages->register(), your webhook endpoint MUST respond to GET with:
{ "Key": "<verification-key>" }
Récupérable depuis Viva → Settings → API Access → Webhooks. La même clé sert à vérifier les signatures HMAC-SHA256 des webhooks entrants :
⚠ Pings sans signature de Viva — Viva fait des appels périodiques sur l'URL webhook sans X-Viva-Signature depuis IPs Azure (51.138.x.x, 20.54.x.x). Renvoyer 200 sur ces calls (logger en warning) sinon Viva désactive le webhook.
Roadmap des endpoints non encore couverts
Audit de la doc Viva (483 pages crawlées, 3/2026) — endpoints existants côté Viva mais pas encore exposés par ce SDK :
Data Services Search (/dataservices/v1/accounttransactions/Search) — idéal pour reconcilier sans dépendre des webhooks 768/769/2054