Transactions of connected merchants (capture, recurring, cancellation)
Composite Basic Auth — undocumented format by Viva Wallet
The format {ResellerID}:{ConnectedMerchantID} as username with {ResellerAPIKey} as password was discovered empirically during ISV certification. The SDK builds this header automatically — you only pass the connectedMerchantId to the methods of $isv->transactions.
OAuth2 token — automatic refresh
The Bearer token is obtained automatically and refreshed before expiration (60-second margin). To force a manual refresh:
$isv->invalidateToken();
Resource Reference
1
ConnectedAccounts
$isv->accounts
Management of merchant accounts connected to the ISV platform. Creation, retrieval, KYB onboarding, verification, update and deletion.
// Créer un compte connecté avec branding
$account = $isv->accounts->create(
email: 'merchant@example.com',
returnUrl: 'https://myapp.com/onboarding/complete',
partnerName: 'Ma Plateforme',
logoUrl: 'https://myapp.com/logo.png',
);
// Rediriger le marchand vers l'onboarding KYB
header('Location: ' . $account['invitation']['redirectUrl']);
// Vérifier le statut KYB
if ($isv->accounts->isVerified($account['accountId'])) {
echo 'Le marchand peut recevoir des paiements';
}
// Récupérer l'URL d'onboarding (null si déjà vérifié)
$url = $isv->accounts->onboardingUrl($account['accountId']);
// Lister tous les comptes connectés
$accounts = $isv->accounts->list();
// Consulter un compte
$details = $isv->accounts->get($account['accountId']);
// Mettre à jour
$isv->accounts->update($account['accountId'], ['email' => 'new@example.com']);
// Supprimer
$isv->accounts->delete($account['accountId']);
2
IsvAccounts
$isv->isvAccounts
ISV accounts via the /isv/v1/ namespace with custom branding options (primary color, logo).
Verification of the initial Viva Wallet GET request and parsing of POST payloads (21 event types).
Method
Signature
Return
verificationResponse
verificationResponse(string $verificationKey)
array{StatusCode, Key}
parse
parse(string $rawBody)
array{event_type, event_type_id, event_data}
isKnownEvent
Webhooks::isKnownEvent(int $eventTypeId) (static)
bool
// GET — vérification initiale
$verificationKey = config('services.viva.verification_key');
return response()->json(
$isv->webhooks->verificationResponse($verificationKey)
);
// => {"StatusCode": 0, "Key": "votre-cle"}
// POST — parsing des événements
$event = $isv->webhooks->parse(file_get_contents('php://input'));
echo $event['event_type']; // 'transaction.payment.created'
echo $event['event_type_id']; // 1796
$data = $event['event_data'];
// Pattern Laravel Controller
match ($event['event_type']) {
'transaction.payment.created' => $this->handlePayment($event['event_data']),
'transaction.refund.created' => $this->handleRefund($event['event_data']),
'account.connected' => $this->handleNewAccount($event['event_data']),
default => null,
};
// Vérifier si un eventTypeId est connu (méthode statique)
use QrCommunication\VivaIsv\Resources\Webhooks;
if (Webhooks::isKnownEvent(1796)) {
echo 'Événement reconnu';
}
Enums
EcrEventId — Cloud Terminal result codes
use QrCommunication\VivaIsv\Enums\EcrEventId;
$event = EcrEventId::tryFrom($session['eventId']);
$event->isSuccessful(); // true si SUCCESS (0)
$event->isTerminal(); // true si état final (pas IN_PROGRESS)
$event->shouldPoll(); // true si IN_PROGRESS (1100)
$event->label(); // 'Transaction successful', 'Declined', etc.
Value
Constant
Description
0
SUCCESS
Transaction successful
1003
TERMINAL_TIMEOUT
Terminal timed out
1006
DECLINED
Transaction declined
1016
ABORTED
Transaction aborted
1020
INSUFFICIENT_FUNDS
Insufficient funds
1099
GENERIC_ERROR
Generic error
1100
IN_PROGRESS
In progress — continue polling
6000
BAD_PARAMS
Invalid parameters
TransactionEventId — detailed decline codes
use QrCommunication\VivaIsv\Enums\TransactionEventId;
$decline = TransactionEventId::tryFrom($session['transactionEventId']);
echo $decline->label(); // 'Insufficient funds'
echo $decline->testAmount(); // 9951 (montant pour déclencher ce déclin en demo)
Value
Constant
Test amount (cents)
10001
REFER_TO_ISSUER
—
10003
INVALID_MERCHANT
—
10004
PICKUP_CARD
—
10005
DO_NOT_HONOR
—
10006
GENERAL_ERROR
9906
10012
INVALID_TRANSACTION
—
10013
INVALID_AMOUNT
—
10014
INVALID_CARD
9914
10030
FORMAT_ERROR
—
10041
LOST_CARD
—
10043
STOLEN_CARD
9920
10051
INSUFFICIENT_FUNDS
9951
10054
EXPIRED_CARD
9954
10055
INCORRECT_PIN
—
10057
NOT_PERMITTED_CARDHOLDER
9957
10058
NOT_PERMITTED_TERMINAL
—
10061
WITHDRAWAL_LIMIT
9961
10062
RESTRICTED_CARD
—
10063
SECURITY_VIOLATION
—
10065
ACTIVITY_LIMIT
—
10068
LATE_RESPONSE
—
10070
CALL_ISSUER
—
10075
PIN_TRIES_EXCEEDED
—
10200
UNMAPPED
—
Environment
use QrCommunication\VivaIsv\Enums\Environment;
// Pass as string or enum — both are accepted
$isv = new VivaIsvClient(..., environment: 'demo');
$isv = new VivaIsvClient(..., environment: Environment::PRODUCTION);
Error Handling
The SDK defines 3 exceptions in the QrCommunication\VivaIsv\Exceptions namespace:
The capture() and recurring() methods throw ApiException if ErrorCode !== 0 in the Viva Wallet response.
Webhook Events (21)
ID
Type
1796
transaction.payment.created
1797
transaction.refund.created
1798
transaction.payment.cancelled
1799
transaction.reversal.created
1800
transaction.preauth.created
1801
transaction.preauth.completed
1802
transaction.preauth.cancelled
1810
pos.session.created
1811
pos.session.failed
1812
transaction.price.calculated
1813
transaction.failed
1819
account.connected
1820
account.verification.status.changed
1821
account.transaction.created
1822
command.bank.transfer.created
1823
command.bank.transfer.executed
1824
transfer.created
1825
obligation.created
1826
obligation.captured
1827
order.updated
1828
sale.transactions.file
Sandbox Testing
Use environment: 'demo' to test without real transactions.
Test card
Field
Value
Number
4111 1111 1111 1111
Expiry
Any future date
CVV
111
Amounts that trigger declines in demo mode
use QrCommunication\VivaIsv\Enums\TransactionEventId;
// Obtenir le montant de test pour un type de déclin
$amount = TransactionEventId::INSUFFICIENT_FUNDS->testAmount(); // 9951
$order = $isv->orders->create('merchant-uuid', $amount);
Amount (cents)
Triggered decline
9951
Insufficient funds (INSUFFICIENT_FUNDS)
9954
Expired card (EXPIRED_CARD)
9920
Stolen card (STOLEN_CARD)
9957
Card not permitted for cardholder (NOT_PERMITTED_CARDHOLDER)