qrcommunication/viva-merchant-sdk 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

qrcommunication/viva-merchant-sdk

Composer 安装命令:

composer require qrcommunication/viva-merchant-sdk

包简介

PHP SDK for Viva Wallet Merchant API — orders, transactions, sources, webhooks

README 文档

README

Version 1.6.0 PHP 8.2+ License: MIT Packagist

SDK PHP complet pour l'intégration Viva Wallet. Couvre 10 ressources : Orders, Transactions, Sources, Wallets, BankAccounts, NativeCheckout, DataServices, Account, Webhooks et Messages (abonnements webhook).

PHP 8.2+ requis. Compatible Laravel, Symfony, ou tout projet PHP.

Ce SDK couvre les opérations marchands standard. Pour les opérations ISV (comptes connectés, composite auth), voir sdk-php-viva-isv.

Table des matières

Installation

composer require qrcommunication/viva-merchant-sdk

Prérequis : PHP 8.2+ avec ext-json et ext-curl.

Démarrage rapide

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
$order = $viva->orders->create(amount: 1500, customerDescription: 'Consultation');
// Rediriger le client vers $order['checkout_url']

// Vérifier une transaction après paiement
$txn = $viva->transactions->getV2('transaction-uuid');

// Rembourser
$viva->transactions->cancel('transaction-uuid', amount: 500);

// Capturer une pré-autorisation
$viva->transactions->capture('preauth-uuid', amount: 1500);

// Charge récurrente
$viva->transactions->recurring('initial-txn-uuid', amount: 1500);

// Apple Pay / Google Pay
$token = $viva->nativeCheckout->createChargeToken(1500, $applePayData);
$txn = $viva->nativeCheckout->createTransaction($token['chargeToken'], 1500);

// Tester la connexion
$viva->testConnection(); // true ou false

Référence des ressources

1. Orders — $viva->orders

Ordres de paiement Smart Checkout.

create() — Créer un ordre

$order = $viva->orders->create(
    amount: 1500,                         // Centimes (15,00 EUR)
    customerDescription: 'Consultation',  // Affiché au client
    merchantReference: 'session_123',     // Référence interne
    allowRecurring: true,                 // Tokeniser la carte
    preauth: false,                       // Pré-autorisation ?
    maxInstallments: 3,                   // Paiement en 3x
);

echo $order['order_code'];   // 1234567890
echo $order['checkout_url']; // https://demo.vivapayments.com/web/checkout?ref=1234567890
Paramètre Type Défaut Description
amount int requis Montant en centimes
customerDescription ?string null Texte affiché au client
merchantReference ?string null Référence interne (exports)
sourceCode ?string null Source de paiement
allowRecurring bool false Autoriser les charges récurrentes
preauth bool false Pré-autorisation uniquement
maxInstallments int 0 Nombre max de versements

Retour : array{order_code: int, checkout_url: string}

get() — Statut d'un ordre

$order = $viva->orders->get(orderCode: 1234567890);

cancel() — Annuler un ordre non payé

$viva->orders->cancel(orderCode: 1234567890);

checkoutUrl() — URL de checkout (sans appel API)

$url = $viva->orders->checkoutUrl(orderCode: 1234567890);
// 'https://demo.vivapayments.com/web/checkout?ref=1234567890'

2. Transactions — $viva->transactions

Consultation, remboursement, capture et paiements récurrents.

get() — Détails complets (Legacy API, PascalCase)

$txn = $viva->transactions->get('transaction-uuid');
echo $txn['Transactions'][0]['Amount'];
echo $txn['Transactions'][0]['StatusId'];

getV2() — Détails légers (New API, camelCase)

$txn = $viva->transactions->getV2('transaction-uuid');
echo $txn['email'];
echo $txn['amount'];      // En EUR (pas en centimes)
echo $txn['statusId'];    // 'F'
echo $txn['orderCode'];

Recommandé pour vérifier les paiements Smart Checkout.

listByDate() — Lister par date

$transactions = $viva->transactions->listByDate('2026-03-18');

foreach ($transactions as $txn) {
    echo $txn['TransactionId'] . '' . $txn['Amount'] . "\n";
}

Retour : array<int, array<string, mixed>>

cancel() — Annuler / Rembourser

// Remboursement total
$result = $viva->transactions->cancel('transaction-uuid');

// Remboursement partiel (5,00 EUR)
$result = $viva->transactions->cancel('transaction-uuid', amount: 500);

echo $result['TransactionId']; // UUID du remboursement
Paramètre Type Défaut Description
transactionId string requis UUID de la transaction
amount ?int null Centimes (null = total)
sourceCode ?string null Source de paiement

Même jour = annulation (void). Jour passé = remboursement (refund).

capture() — Capturer une pré-autorisation

$result = $viva->transactions->capture('preauth-uuid', amount: 1500);

Lève ApiException si la capture échoue.

recurring() — Charge récurrente

$result = $viva->transactions->recurring(
    initialTransactionId: 'initial-txn-uuid',
    amount: 1500,
    sourceCode: '1234', // optionnel
);

Prérequis : l'ordre initial doit avoir été créé avec allowRecurring: true.

3. Sources — $viva->sources

Gestion des sources de paiement (domaines autorisés, URLs de redirection).

list() — Lister les sources

$sources = $viva->sources->list();

foreach ($sources as $source) {
    echo $source['Name'] . '' . $source['SourceCode'] . "\n";
}

create() — Créer une source

$source = $viva->sources->create(
    name: 'Mon site web',
    sourceCode: '1234',
    domain: 'www.example.com',
    pathSuccess: '/paiement/succes',
    pathFail: '/paiement/echec',
);
Paramètre Type Défaut Description
name string requis Nom d'affichage
sourceCode string requis Code à 4 chiffres
domain ?string null Domaine du site
pathSuccess ?string null Redirection succès
pathFail ?string null Redirection échec

4. Wallets — $viva->wallets

Portefeuilles (sous-comptes), soldes et transferts.

list() — Lister les portefeuilles

$wallets = $viva->wallets->list();

balance() — Solde agrégé

$balance = $viva->wallets->balance();
echo $balance['available'];  // 150.50
echo $balance['pending'];    // 25.00
echo $balance['reserved'];   // 0.00
echo $balance['currency'];   // 'EUR'

Retour : array{available: float, pending: float, reserved: float, currency: string}

transfer() — Transfert entre wallets

$viva->wallets->transfer(
    amount: 5000,                        // 50,00 EUR
    sourceWalletId: 'source-uuid',
    targetWalletId: 'target-uuid',
    description: 'Transfert mensuel',
);

Prérequis : « Allow transfers between accounts » dans Settings > API Access.

listDetailed() — Liste enrichie (IBAN, SWIFT)

$wallets = $viva->wallets->listDetailed();

foreach ($wallets as $wallet) {
    echo $wallet['iban'] . '' . $wallet['amount'] . "\n";
    echo $wallet['isPrimary'] ? 'Principal' : 'Secondaire';
}

create() — Créer un portefeuille

$viva->wallets->create(friendlyName: 'Compte secondaire', currencyCode: 'EUR');

update() — Renommer un portefeuille

$viva->wallets->update(walletId: 12345, friendlyName: 'Nouveau nom');

searchTransactions() — Rechercher les transactions de compte

$transactions = $viva->wallets->searchTransactions([
    'date_from' => '2026-03-01',
    'date_to' => '2026-03-18',
    'walletId' => 12345,
]);

getTransaction() — Détails d'une transaction de compte

$txn = $viva->wallets->getTransaction('transaction-uuid');

5. BankAccounts — $viva->bankAccounts

Comptes bancaires IBAN et virements SEPA.

link() — Lier un IBAN

$result = $viva->bankAccounts->link(
    iban: 'FR7630006000011234567890189',
    beneficiaryName: 'Jean Dupont',
    friendlyName: 'Compte principal',
);

echo $result['bankAccountId']; // UUID
echo $result['isVivaIban'];    // false

transferOptions() — Options de transfert

$options = $viva->bankAccounts->transferOptions('bank-account-uuid');

feeCommand() — Calculer les frais avant virement

$fees = $viva->bankAccounts->feeCommand(
    bankAccountId: 'bank-account-uuid',
    amount: 10000,                    // 100,00 EUR
    walletId: 'source-wallet-uuid',
    isInstant: true,                  // SEPA instantané
    instructionType: 'SHA',           // Frais partagés
);

echo $fees['bankCommandId']; // À passer à send()
echo $fees['fee'];           // Frais en centimes

send() — Exécuter un virement SEPA

$result = $viva->bankAccounts->send(
    bankAccountId: 'bank-account-uuid',
    amount: 10000,
    walletId: 'source-wallet-uuid',
    bankCommandId: 'fee-command-uuid',  // Optionnel
    description: 'Virement mensuel',
);

echo $result['commandId']; // UUID du virement
echo $result['isInstant']; // true/false
echo $result['fee'];       // Frais en centimes

list() — Lister les comptes liés

$accounts = $viva->bankAccounts->list();

get() — Détails d'un compte lié

$account = $viva->bankAccounts->get('bank-account-uuid');

6. NativeCheckout — $viva->nativeCheckout

Paiements Apple Pay et Google Pay.

createChargeToken() — Générer un token de charge

$token = $viva->nativeCheckout->createChargeToken(
    amount: 1500,
    paymentData: $applePayPaymentDataString,
    paymentMethod: 'applepay', // ou 'googlepay'
    sourceCode: '1234',
);

echo $token['chargeToken'];       // Token à passer à createTransaction()
echo $token['redirectToACSForm']; // Formulaire 3DS (si applicable)
Paramètre Type Défaut Description
amount int requis Montant en centimes
paymentData string requis Données Apple Pay / Google Pay
paymentMethod string 'applepay' 'applepay' ou 'googlepay'
sourceCode ?string null Source de paiement
dynamicDescriptor ?string null Descripteur dynamique

createTransaction() — Exécuter la transaction

$txn = $viva->nativeCheckout->createTransaction(
    chargeToken: $token['chargeToken'],
    amount: 1500,
    currencyCode: 978,             // EUR (ISO 4217 numérique)
    merchantTrns: 'ref_123',
    customerTrns: 'Consultation',
);

echo $txn['transactionId']; // UUID
echo $txn['statusId'];      // 'F' = finalisée
echo $txn['amount'];        // 1500
echo $txn['orderCode'];     // Code de l'ordre
Paramètre Type Défaut Description
chargeToken string requis Token de createChargeToken()
amount int requis Montant en centimes
currencyCode int 978 ISO 4217 numérique
sourceCode ?string null Source de paiement
merchantTrns ?string null Référence interne
customerTrns ?string null Description client
preauth bool false Pré-autorisation ?
tipAmount int 0 Pourboire en centimes
installments ?int null Nombre de versements

7. DataServices — $viva->dataServices

Rapports MT940 et souscriptions webhook pour les fichiers de données.

mt940() — Rapport MT940

$report = $viva->dataServices->mt940('2026-03-18');

createSubscription() — Créer une souscription webhook

$sub = $viva->dataServices->createSubscription(
    url: 'https://example.com/webhooks/viva-files',
    eventType: 'SaleTransactionsFileGenerated',
);
echo $sub['subscriptionId'];

updateSubscription() — Mettre à jour

$viva->dataServices->updateSubscription(
    subscriptionId: 'sub-uuid',
    url: 'https://example.com/webhooks/new-url',
    eventType: null, // null = conserver l'actuel
);

deleteSubscription() — Supprimer

$viva->dataServices->deleteSubscription('sub-uuid');

listSubscriptions() — Lister

$subs = $viva->dataServices->listSubscriptions();

foreach ($subs as $sub) {
    echo $sub['subscriptionId'] . '' . $sub['url'] . "\n";
}

requestFile() — Demander la génération d'un fichier

$viva->dataServices->requestFile('2026-03-18');

Déclenche la génération asynchrone. Utilisez une souscription webhook pour être notifié.

8. Webhooks — $viva->webhooks

Vérification et parsing des webhooks Viva Wallet. Aucun appel API — tout est local.

verificationResponse() — Répondre au GET de vérification

public function verify()
{
    return response()->json(
        $viva->webhooks->verificationResponse('votre-verification-key')
    );
    // => {"StatusCode": 0, "Key": "votre-verification-key"}
}

parse() — Parser un webhook POST

public function handle(Request $request)
{
    $event = $viva->webhooks->parse($request->getContent());

    echo $event['event_type'];     // 'transaction.payment.created'
    echo $event['event_type_id'];  // 1796
    echo $event['event_data'];     // Données de l'événement

    match ($event['event_type']) {
        'transaction.payment.created' => $this->handlePayment($event['event_data']),
        'transaction.refund.created'  => $this->handleRefund($event['event_data']),
        default => null,
    };
}

Retour : array{event_type: string, event_type_id: int, event_data: array<string, mixed>}

Lève InvalidArgumentException si le JSON est invalide.

isKnownEvent() — Vérifier un ID d'événement

$viva->webhooks->isKnownEvent(1796); // true
$viva->webhooks->isKnownEvent(9999); // false

eventTypeIds() — Lister les IDs connus

$ids = $viva->webhooks->eventTypeIds();
// [1796, 1797, 1798, ..., 1828]

21 types d'événements supportés

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

9. Account — $viva->account

Informations du compte marchand.

info() — Informations du compte

$info = $viva->account->info();
echo $info['merchantId'];
echo $info['businessName'];
echo $info['email'];

wallets() — Portefeuilles du compte

$wallets = $viva->account->wallets();

10. Messages — $viva->messages()

Gestion des abonnements webhook via /api/messages/config (Legacy API, Basic Auth).

Utilisez $viva->webhookRegistrar()->registerAll(...) pour l'enregistrement idempotent des events banking. messages() donne un accès bas niveau si besoin.

register() — Créer un abonnement webhook

$sub = $viva->messages()->register(
    eventTypeId: 768,                                  // Bank Transfer Created
    callbackUrl: 'https://example.com/webhooks/viva',
);
// => ['Id' => 'sub-uuid', 'Active' => true]

list() — Lister les abonnements

$subscriptions = $viva->messages()->list();
foreach ($subscriptions as $sub) {
    echo $sub['Id'] . ' → EventTypeId: ' . $sub['EventTypeId'];
}

delete() — Supprimer un abonnement

$viva->messages()->delete('sub-uuid-here');

Enregistrement des webhooks banking

Les events 768 (Bank Transfer Created), 769 (Bank Transfer Executed) et 2054 (Account Transaction Created) doivent être enregistrés par chaque merchant via /api/messages/config (pas via les webhooks ISV).

Utilisez WebhookRegistrar pour un enregistrement idempotent : les erreurs "duplicate" sont silencieusement transformées en already_exists.

// Enregistrer les 3 events banking en une ligne
$results = $viva->webhookRegistrar()->registerAll(
    callbackUrl: 'https://example.com/webhooks/viva',
);
// => ['768' => 'registered', '769' => 'registered', '2054' => 'already_exists']

// Ou un sous-ensemble d'events
$results = $viva->webhookRegistrar()->registerAll(
    callbackUrl: 'https://example.com/webhooks/viva',
    events: [768, 769],
);

Statuts possibles dans le tableau retourné :

Statut Signification
registered Abonnement créé avec succès
already_exists Déjà enregistré (Viva a retourné 400 duplicate)
error:{message} Échec inattendu (503, réseau, etc.)

Convention cross-SDK : WebhookRegistrar::BANKING_EVENTS et registerAll() ont les mêmes noms dans sdk-php-viva-isv. La différence est l'absence de $connectedMerchantId — ce SDK parle au nom du merchant lui-même.

Architecture

src/
├── VivaClient.php          # Point d'entrée — instancie les 10 ressources + 1 helper
├── Config.php              # Configuration (URLs par environnement)
├── HttpClient.php          # Client HTTP Guzzle (OAuth2 auto, Basic Auth)
├── Contracts/
│   ├── HttpClientInterface.php   # Interface pour HttpClient (mocking)
│   └── MessagesInterface.php     # Interface pour Messages (mocking)
├── Enums/
│   ├── Environment.php     # demo | production
│   ├── Currency.php        # Codes ISO 4217 numériques
│   └── TransactionStatus.php  # F, A, C, E, M, X, R
├── Exceptions/
│   ├── VivaException.php          # Classe de base (RuntimeException)
│   ├── ApiException.php           # Erreur API (4xx, 5xx)
│   ├── AuthenticationException.php # Échec OAuth2 (401)
│   └── ValidationException.php    # Validation (422)
├── Helpers/
│   └── WebhookRegistrar.php  # Enregistrement idempotent des events banking
└── Resources/
    ├── Orders.php           # Smart Checkout
    ├── Transactions.php     # Get, list, cancel, capture, recurring
    ├── Sources.php          # Sources de paiement
    ├── Wallets.php          # Portefeuilles, soldes, transferts
    ├── BankAccounts.php     # IBAN, virements SEPA
    ├── NativeCheckout.php   # Apple Pay, Google Pay
    ├── DataServices.php     # MT940, souscriptions webhook
    ├── Webhooks.php         # Vérification et parsing local
    ├── Account.php          # Infos du compte
    └── Messages.php         # Abonnements webhook (/api/messages/config)

L'authentification est gérée automatiquement par HttpClient :

  • Legacy API (Basic Auth) — utilisée par Orders, Transactions, Sources
  • New API (Bearer OAuth2) — utilisée par Wallets, BankAccounts, NativeCheckout, DataServices, Account

Le token OAuth2 est mis en cache en mémoire et rafraîchi automatiquement avant expiration.

Enums

Environment

use QrCommunication\VivaMerchant\Enums\Environment;

$env = Environment::DEMO;
$env = Environment::PRODUCTION;
$env = Environment::from('demo');

$env->value;         // 'demo'
$env->apiUrl();      // 'https://demo-api.vivapayments.com'
$env->legacyUrl();   // 'https://demo.vivapayments.com'
$env->checkoutUrl(); // 'https://demo.vivapayments.com/web/checkout'
$env->accountsUrl(); // 'https://demo-accounts.vivapayments.com'

Currency

use QrCommunication\VivaMerchant\Enums\Currency;

Currency::EUR->value;     // 978
Currency::EUR->iso();     // 'EUR'
Currency::fromIso('GBP'); // Currency::GBP (826)

Devises supportées : EUR (978), GBP (826), USD (840), PLN (985), RON (946), BGN (975), CZK (203), HRK (191), HUF (348), DKK (208), SEK (752), NOK (578).

TransactionStatus

use QrCommunication\VivaMerchant\Enums\TransactionStatus;

$status = TransactionStatus::from('F');
$status->isSuccessful();  // true
$status->isPending();     // false
$status->isFailed();      // false
$status->label();         // 'Finalized'
Valeur Constante isSuccessful() isPending() isFailed()
F FINALIZED oui
A PENDING oui
C CLEARING oui
E ERROR oui
M MANUALLY_REVERSED oui
X REQUIRES_ACTION
R REFUNDED

Gestion d'erreurs

Toutes les exceptions héritent de VivaException qui étend RuntimeException.

RuntimeException
└── VivaException
    ├── ApiException
    ├── AuthenticationException
    └── ValidationException
use QrCommunication\VivaMerchant\Exceptions\ApiException;
use QrCommunication\VivaMerchant\Exceptions\AuthenticationException;
use QrCommunication\VivaMerchant\Exceptions\ValidationException;
use QrCommunication\VivaMerchant\Exceptions\VivaException;

try {
    $order = $viva->orders->create(amount: 1500);
} catch (AuthenticationException $e) {
    // Identifiants invalides — httpStatus = 401
    echo $e->getMessage();
} catch (ValidationException $e) {
    // Erreur de validation — httpStatus = 422
    foreach ($e->errors as $field => $messages) {
        echo "$field: " . implode(', ', $messages);
    }
} catch (ApiException $e) {
    // Erreur API générale — 400, 404, 500, etc.
    echo $e->httpStatus;
    echo $e->getErrorCode();
    echo $e->getErrorText();
    print_r($e->responseBody);
} catch (VivaException $e) {
    // Toute autre erreur SDK
}

Propriétés et méthodes de VivaException

Membre Type Description
$httpStatus int Code HTTP de la réponse
$responseBody ?array Corps JSON décodé de la réponse
getErrorCode() ?int Code d'erreur Viva (ErrorCode)
getErrorText() ?string Message d'erreur Viva (ErrorText, message, ou detail)

Webhooks — Guide d'intégration

1. Configurer le webhook dans le Dashboard Viva

  1. Aller dans Settings > API Access > Webhooks
  2. Ajouter l'URL de votre endpoint
  3. Noter la clé de vérification

2. Gérer la vérification (GET)

// Route GET /webhooks/viva
public function verify()
{
    return response()->json(
        $viva->webhooks->verificationResponse('votre-clé')
    );
}

3. Recevoir les événements (POST)

// Route POST /webhooks/viva
public function handle(Request $request)
{
    $event = $viva->webhooks->parse($request->getContent());

    match ($event['event_type']) {
        'transaction.payment.created'   => $this->onPayment($event['event_data']),
        'transaction.refund.created'    => $this->onRefund($event['event_data']),
        'transaction.preauth.created'   => $this->onPreauth($event['event_data']),
        'transaction.preauth.completed' => $this->onCapture($event['event_data']),
        default => logger()->info('Webhook ignoré : ' . $event['event_type']),
    };

    return response()->json(['status' => 'ok']);
}

4. Enregistrement des webhooks banking par API (optionnel)

Les events 768, 769 et 2054 (virements et transactions de compte) ne peuvent pas être configurés depuis le Dashboard Viva pour les marchands standard. Ils doivent être enregistrés par API via /api/messages/config.

// Enregistrement idempotent au démarrage de l'application
$results = $viva->webhookRegistrar()->registerAll(
    callbackUrl: config('services.viva.webhook_url'),
);

// $results = ['768' => 'registered', '769' => 'registered', '2054' => 'already_exists']
// Les 'already_exists' sont silencieux — safe à relancer à chaque boot.

Distinction ISV vs merchant : dans le SDK ISV (sdk-php-viva-isv), ces events sont enregistrés au niveau de l'ISV pour un connectedMerchantId. Ici, ils s'appliquent directement au compte marchand authentifié.

Carte de test

Pour l'environnement demo :

Champ Valeur
Numéro de carte 4111 1111 1111 1111
Expiration Toute date future
CVV 111
3DS Pas de 3DS en demo

Documentation interactive

La documentation interactive (ReDoc) est disponible en ligne :

https://qrcommunication.github.io/sdk-php-viva-merchant/

Elle détaille chaque classe, méthode, paramètre et type de retour du SDK.

Intégration IA

Ce SDK inclut un skill détaillé (skill/SKILL.md) automatiquement détecté par les assistants IA. Il fournit la référence complète des 9 resources, 34+ méthodes, enums, exceptions et patterns d'implémentation.

Outil Fichier Détection
Claude Code CLAUDE.md + skill/SKILL.md Automatique
Cursor .cursorrules Automatique
GitHub Copilot .github/copilot-instructions.md Automatique
OpenAI Codex AGENTS.md Automatique
// Un agent IA peut construire cet appel à partir de :
// "Crée un paiement de 25 EUR pour une consultation"
$order = $viva->orders->create(
    amount: 2500,
    customerDescription: 'Consultation',
);

Licence

MIT — QrCommunication

qrcommunication/viva-merchant-sdk 适用场景与选型建议

qrcommunication/viva-merchant-sdk 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 927 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「payment」 「sdk」 「merchant」 「viva」 「VivaWallet」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 qrcommunication/viva-merchant-sdk 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 qrcommunication/viva-merchant-sdk 我们能提供哪些服务?
定制开发 / 二次开发

基于 qrcommunication/viva-merchant-sdk 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 927
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 8
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-18