Compare commits

...

3 Commits

Author SHA1 Message Date
andrewrowanwallee e732454683 Release 6.2.1 2026-02-12 13:13:32 +01:00
andrewrowanwallee 57246e23ce Release 6.2.0 2026-01-15 09:20:03 +01:00
andrewrowanwallee 68592a9409 Release 6.1.17 2025-11-03 13:29:47 +01:00
50 changed files with 1943 additions and 653 deletions
+12
View File
@@ -1,3 +1,15 @@
# 6.2.1
- Fixed issue with multiple discount codes
# 6.2.0
- Renamed database table to avoid a naming conflict with legacy plugins
- Fixed issue with refunds failing for payments using Invoice
# 6.1.17
- Sales channels now support different spaces
- Upgraded SDK to include latest fallback CA Bundle
- Fixed error screen when returning from portal on failed payment
# 6.1.16 # 6.1.16
- Fixed issue with pending orders remaining open - Fixed issue with pending orders remaining open
+12
View File
@@ -1,3 +1,15 @@
# 6.2.1
- Problem mit mehreren Rabattcodes behoben
# 6.2.0
- Datenbanktabelle umbenannt, um Namenskonflikte mit älteren Plugins zu vermeiden.
- Problem mit fehlgeschlagenen Rückerstattungen bei Zahlungen mit Rechnungen behoben.
# 6.1.17
- Vertriebskanäle unterstützen jetzt verschiedene Bereiche
- SDK aktualisiert und enthält nun das neueste CA-Fallback-Bundle
- Fehlerbildschirm beim Zurückkehren vom Portal nach fehlgeschlagener Zahlung behoben
# 6.1.16 # 6.1.16
- Problem behoben, bei dem die Versandkosten nicht korrekt verarbeitet wurden - Problem behoben, bei dem die Versandkosten nicht korrekt verarbeitet wurden
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2025 VR Payment GmbH Copyright 2026 VR Payment GmbH
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
+20 -5
View File
@@ -13,11 +13,10 @@ The VR Payment Payment Plugin integrates modern payment processing into Shopware
- **VR Payment Account:** Obtain `Space ID`, `User ID`, and `API Key` from the [VR Payment Dashboard](https://gateway.vr-payment.de/). - **VR Payment Account:** Obtain `Space ID`, `User ID`, and `API Key` from the [VR Payment Dashboard](https://gateway.vr-payment.de/).
## Documentation ## Documentation
- For English documentation click [here](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/en/documentation.html)
- For English documentation click [here](@WalleeDocPath(/docs/en/documentation.html)) - Für die deutsche Dokumentation klicken Sie [hier](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/de/documentation.html)
- Für die deutsche Dokumentation klicken Sie [hier](@WalleeDocPath(/docs/de/documentation.html)) - Pour la documentation Française, cliquez [ici](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/fr/documentation.html)
- Pour la documentation Française, cliquez [ici](@WalleeDocPath(/docs/fr/documentation.html)) - Per la documentazione in tedesco, clicca [qui](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/it/documentation.html)
- Per la documentazione in tedesco, clicca [qui](@WalleeDocPath(/docs/it/documentation.html))
## Installation ## Installation
@@ -43,6 +42,22 @@ bin/console plugin:refresh
bin/console plugin:install --activate --clearCache VRPaymentPayment bin/console plugin:install --activate --clearCache VRPaymentPayment
``` ```
## Update
### Via Administration
1. Go to Shopware Admin > Extensions > My extensions.
2. Find VRPaymentPayment.
3. Click Update.
### Via CLI
1. Deploy the new plugin files (replace the folder in custom/plugins/VRPaymentPayment or upload/install a new ZIP).
2. Run:
```bash
bin/console plugin:refresh
bin/console plugin:update --clearCache VRPaymentPayment
bin/console cache:clear
```
## Configuration ## Configuration
### API Credentials ### API Credentials
+1 -1
View File
@@ -59,5 +59,5 @@
"vrpayment/sdk": "^4.0.0" "vrpayment/sdk": "^4.0.0"
}, },
"type": "shopware-platform-plugin", "type": "shopware-platform-plugin",
"version": "6.1.16" "version": "6.2.1"
} }
+112 -46
View File
@@ -178,10 +178,59 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</ol> </ol>
</div> </div> </div> </div>
</div> </div> </div> </div>
</div> <div class="chapter" id="_update">
<div class="chapter-title">
<h1>
<span class="title-number">5</span>Update </h1>
</div>
<div class="chapter-body">
<div class="section" id="_via_administration">
<div class="section-title">
<h2>
<span class="title-number">5.1</span>Via Administration </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Gehe zu Shopware Admin &gt; Erweiterungen &gt; Meine Erweiterungen.</p>
</li>
<li>
<p>Suche nach VRPaymentPayment.</p>
</li>
<li>
<p>Klicke auf Aktualisieren.</p>
</li>
</ol>
</div> </div>
</div> <div class="section" id="_via_cli">
<div class="section-title">
<h2>
<span class="title-number">5.2</span>Via CLI </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Stelle die neuen Plugin-Dateien bereit (ersetze den Ordner <code>custom/plugins/VRPaymentPayment</code> oder lade ein neues ZIP hoch/installiere es).</p>
</li>
<li>
<p>Führe aus:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">bin/console plugin:refresh
bin/console plugin:update --clearCache VRPaymentPayment
bin/console cache:clear</code></pre>
</div>
</div>
</li>
</ol>
</div> </div>
</div> </div>
</div> <div class="chapter" id="portal-startup-guide"> </div> <div class="chapter" id="portal-startup-guide">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">5</span>Portal-Startanleitung </h1> <span class="title-number">6</span>Portal-Startanleitung </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -200,7 +249,7 @@ Wählen Sie das passende Abo aus es sollte E-Commerce-Transaktionen unterst
</div> <div class="section" id="_erstellen_sie_den_api_schlüssel"> </div> <div class="section" id="_erstellen_sie_den_api_schlüssel">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.1</span>Erstellen Sie den API-Schlüssel: </h2> <span class="title-number">6.1</span>Erstellen Sie den API-Schlüssel: </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -286,7 +335,7 @@ Bitte beachten Sie, dass das Laden der Rollen einige Sekunden dauern kann.
</div> <div class="section" id="_zahlungsmethoden_einrichten"> </div> <div class="section" id="_zahlungsmethoden_einrichten">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.2</span>Zahlungsmethoden einrichten </h2> <span class="title-number">6.2</span>Zahlungsmethoden einrichten </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -348,7 +397,7 @@ Bitte beachten Sie, dass die Konnektoren doppelt erscheinen, da einer für Zahlu
</div> <div class="chapter" id="_shop_startanleitung"> </div> <div class="chapter" id="_shop_startanleitung">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">6</span>Shop-Startanleitung </h1> <span class="title-number">7</span>Shop-Startanleitung </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -487,7 +536,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="chapter" id="_transaktionszustandsdiagramm"> </div> <div class="chapter" id="_transaktionszustandsdiagramm">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">7</span>Transaktionszustandsdiagramm </h1> <span class="title-number">8</span>Transaktionszustandsdiagramm </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -497,7 +546,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_zustandsabbildung_von_shopware_bestellungen"> </div> <div class="section" id="_zustandsabbildung_von_shopware_bestellungen">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.1</span>Zustandsabbildung von Shopware-Bestellungen </h2> <span class="title-number">8.1</span>Zustandsabbildung von Shopware-Bestellungen </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -505,7 +554,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_allgemeine_anmerkungen_zu_bestellstatus"> </div> <div class="section" id="_allgemeine_anmerkungen_zu_bestellstatus">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.1.1</span>Allgemeine Anmerkungen zu Bestellstatus </h3> <span class="title-number">8.1.1</span>Allgemeine Anmerkungen zu Bestellstatus </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -515,7 +564,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_zustandsabbildung_des_shopware_zahlungsstatus"> </div> <div class="section" id="_zustandsabbildung_des_shopware_zahlungsstatus">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.2</span>Zustandsabbildung des Shopware-Zahlungsstatus </h2> <span class="title-number">8.2</span>Zustandsabbildung des Shopware-Zahlungsstatus </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -542,7 +591,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_allgemeine_anmerkungen_zu_zahlungsstatus"> </div> <div class="section" id="_allgemeine_anmerkungen_zu_zahlungsstatus">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.2.1</span>Allgemeine Anmerkungen zu Zahlungsstatus </h3> <span class="title-number">8.2.1</span>Allgemeine Anmerkungen zu Zahlungsstatus </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -552,7 +601,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_zustandsabbildung_des_shopware_lieferstatus"> </div> <div class="section" id="_zustandsabbildung_des_shopware_lieferstatus">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.3</span>Zustandsabbildung des Shopware-Lieferstatus </h2> <span class="title-number">8.3</span>Zustandsabbildung des Shopware-Lieferstatus </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -578,7 +627,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="chapter" id="_transaktionsverwaltung"> </div> <div class="chapter" id="_transaktionsverwaltung">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">8</span>Transaktionsverwaltung </h1> <span class="title-number">9</span>Transaktionsverwaltung </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -586,7 +635,7 @@ Bitte beachten Sie, dass diese Option leer bleiben sollte, wenn Sie die Space Vi
</div> <div class="section" id="_bestellung_abschließen_erfassen"> </div> <div class="section" id="_bestellung_abschließen_erfassen">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.1</span>Bestellung abschließen (erfassen) </h2> <span class="title-number">9.1</span>Bestellung abschließen (erfassen) </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -614,7 +663,7 @@ Wenn der Abschluss in VR Payment ausstehend ist, bleibt die Bestellung im Status
</div> <div class="section" id="_transaktion_stornieren"> </div> <div class="section" id="_transaktion_stornieren">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.2</span>Transaktion stornieren </h2> <span class="title-number">9.2</span>Transaktion stornieren </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -638,7 +687,7 @@ Sie können nur Transaktionen stornieren, die noch nicht abgeschlossen sind.
</div> <div class="section" id="_rückerstattung_einer_transaktion"> </div> <div class="section" id="_rückerstattung_einer_transaktion">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.3</span>Rückerstattung einer Transaktion </h2> <span class="title-number">9.3</span>Rückerstattung einer Transaktion </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -664,7 +713,7 @@ Es kann einige Zeit dauern, bis Sie die Rückerstattung in Shopware sehen. Rück
</div> <div class="section" id="_bestellungen_auf_on_hold"> </div> <div class="section" id="_bestellungen_auf_on_hold">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.4</span>Bestellungen auf On Hold </h2> <span class="title-number">9.4</span>Bestellungen auf On Hold </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -686,7 +735,7 @@ Es kann einige Zeit dauern, bis Sie die Rückerstattung in Shopware sehen. Rück
</div> <div class="section" id="_einschränkungen_der_synchronisierung_zwischen_whitelabelname_und_shopware"> </div> <div class="section" id="_einschränkungen_der_synchronisierung_zwischen_whitelabelname_und_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.5</span>Einschränkungen der Synchronisierung zwischen VR Payment und Shopware </h2> <span class="title-number">9.5</span>Einschränkungen der Synchronisierung zwischen VR Payment und Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -697,7 +746,7 @@ Es kann einige Zeit dauern, bis Sie die Rückerstattung in Shopware sehen. Rück
</div> <div class="section" id="_tokenisierung"> </div> <div class="section" id="_tokenisierung">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.6</span>Tokenisierung </h2> <span class="title-number">9.6</span>Tokenisierung </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -717,7 +766,7 @@ Die Tokenisierung ist für Gast-Checkouts nicht verfügbar
</div> <div class="section" id="_hauptfunktionen"> </div> <div class="section" id="_hauptfunktionen">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.7</span>Hauptfunktionen </h2> <span class="title-number">9.7</span>Hauptfunktionen </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -739,7 +788,7 @@ Die Tokenisierung ist für Gast-Checkouts nicht verfügbar
</div> <div class="section" id="_fehlerbehebung"> </div> <div class="section" id="_fehlerbehebung">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.8</span>Fehlerbehebung </h2> <span class="title-number">9.8</span>Fehlerbehebung </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -771,7 +820,7 @@ tail -f var/log/whitelabelname_payment*.log</code></pre>
</div> <div class="section" id="_faqs"> </div> <div class="section" id="_faqs">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.9</span>FAQs </h2> <span class="title-number">9.9</span>FAQs </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -800,7 +849,7 @@ A: Ja, das Plugin unterstützt Wallets wie Apple Pay.</p>
</div> <div class="chapter" id="_änderungsprotokoll"> </div> <div class="chapter" id="_änderungsprotokoll">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">9</span>Änderungsprotokoll </h1> <span class="title-number">10</span>Änderungsprotokoll </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -809,7 +858,7 @@ A: Ja, das Plugin unterstützt Wallets wie Apple Pay.</p>
</div> <div class="chapter" id="_mitwirken"> </div> <div class="chapter" id="_mitwirken">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">10</span>Mitwirken </h1> <span class="title-number">11</span>Mitwirken </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -820,7 +869,7 @@ A: Ja, das Plugin unterstützt Wallets wie Apple Pay.</p>
</div> <div class="chapter" id="_support"> </div> <div class="chapter" id="_support">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">11</span>Support </h1> <span class="title-number">12</span>Support </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -871,128 +920,145 @@ A: Ja, das Plugin unterstützt Wallets wie Apple Pay.</p>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#portal-startup-guide"> <a href="#_update">
<span class="item-number">5</span> <span class="item-number">5</span>
<span class="item-title">Update</span>
</a>
<ul class="nav">
<li class="nav-level-2">
<a href="#_via_administration">
<span class="item-number">5.1</span>
<span class="item-title">Via Administration</span>
</a>
</li> <li class="nav-level-2">
<a href="#_via_cli">
<span class="item-number">5.2</span>
<span class="item-title">Via CLI</span>
</a>
</li> </ul>
</li> <li class="nav-level-1">
<a href="#portal-startup-guide">
<span class="item-number">6</span>
<span class="item-title">Portal-Startanleitung</span> <span class="item-title">Portal-Startanleitung</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_erstellen_sie_den_api_schlüssel"> <a href="#_erstellen_sie_den_api_schlüssel">
<span class="item-number">5.1</span> <span class="item-number">6.1</span>
<span class="item-title">Erstellen Sie den API-Schlüssel:</span> <span class="item-title">Erstellen Sie den API-Schlüssel:</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_zahlungsmethoden_einrichten"> <a href="#_zahlungsmethoden_einrichten">
<span class="item-number">5.2</span> <span class="item-number">6.2</span>
<span class="item-title">Zahlungsmethoden einrichten</span> <span class="item-title">Zahlungsmethoden einrichten</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_shop_startanleitung"> <a href="#_shop_startanleitung">
<span class="item-number">6</span> <span class="item-number">7</span>
<span class="item-title">Shop-Startanleitung</span> <span class="item-title">Shop-Startanleitung</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_transaktionszustandsdiagramm"> <a href="#_transaktionszustandsdiagramm">
<span class="item-number">7</span> <span class="item-number">8</span>
<span class="item-title">Transaktionszustandsdiagramm</span> <span class="item-title">Transaktionszustandsdiagramm</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_zustandsabbildung_von_shopware_bestellungen"> <a href="#_zustandsabbildung_von_shopware_bestellungen">
<span class="item-number">7.1</span> <span class="item-number">8.1</span>
<span class="item-title">Zustandsabbildung von Shopware-Bestellungen</span> <span class="item-title">Zustandsabbildung von Shopware-Bestellungen</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_allgemeine_anmerkungen_zu_bestellstatus"> <a href="#_allgemeine_anmerkungen_zu_bestellstatus">
<span class="item-number">7.1.1</span> <span class="item-number">8.1.1</span>
<span class="item-title">Allgemeine Anmerkungen zu Bestellstatus</span> <span class="item-title">Allgemeine Anmerkungen zu Bestellstatus</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_zustandsabbildung_des_shopware_zahlungsstatus"> <a href="#_zustandsabbildung_des_shopware_zahlungsstatus">
<span class="item-number">7.2</span> <span class="item-number">8.2</span>
<span class="item-title">Zustandsabbildung des Shopware-Zahlungsstatus</span> <span class="item-title">Zustandsabbildung des Shopware-Zahlungsstatus</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_allgemeine_anmerkungen_zu_zahlungsstatus"> <a href="#_allgemeine_anmerkungen_zu_zahlungsstatus">
<span class="item-number">7.2.1</span> <span class="item-number">8.2.1</span>
<span class="item-title">Allgemeine Anmerkungen zu Zahlungsstatus</span> <span class="item-title">Allgemeine Anmerkungen zu Zahlungsstatus</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_zustandsabbildung_des_shopware_lieferstatus"> <a href="#_zustandsabbildung_des_shopware_lieferstatus">
<span class="item-number">7.3</span> <span class="item-number">8.3</span>
<span class="item-title">Zustandsabbildung des Shopware-Lieferstatus</span> <span class="item-title">Zustandsabbildung des Shopware-Lieferstatus</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_transaktionsverwaltung"> <a href="#_transaktionsverwaltung">
<span class="item-number">8</span> <span class="item-number">9</span>
<span class="item-title">Transaktionsverwaltung</span> <span class="item-title">Transaktionsverwaltung</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_bestellung_abschließen_erfassen"> <a href="#_bestellung_abschließen_erfassen">
<span class="item-number">8.1</span> <span class="item-number">9.1</span>
<span class="item-title">Bestellung abschließen (erfassen)</span> <span class="item-title">Bestellung abschließen (erfassen)</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_transaktion_stornieren"> <a href="#_transaktion_stornieren">
<span class="item-number">8.2</span> <span class="item-number">9.2</span>
<span class="item-title">Transaktion stornieren</span> <span class="item-title">Transaktion stornieren</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_rückerstattung_einer_transaktion"> <a href="#_rückerstattung_einer_transaktion">
<span class="item-number">8.3</span> <span class="item-number">9.3</span>
<span class="item-title">Rückerstattung einer Transaktion</span> <span class="item-title">Rückerstattung einer Transaktion</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_bestellungen_auf_on_hold"> <a href="#_bestellungen_auf_on_hold">
<span class="item-number">8.4</span> <span class="item-number">9.4</span>
<span class="item-title">Bestellungen auf On Hold</span> <span class="item-title">Bestellungen auf On Hold</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_einschränkungen_der_synchronisierung_zwischen_whitelabelname_und_shopware"> <a href="#_einschränkungen_der_synchronisierung_zwischen_whitelabelname_und_shopware">
<span class="item-number">8.5</span> <span class="item-number">9.5</span>
<span class="item-title">Einschränkungen der Synchronisierung zwischen VR Payment und Shopware</span> <span class="item-title">Einschränkungen der Synchronisierung zwischen VR Payment und Shopware</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_tokenisierung"> <a href="#_tokenisierung">
<span class="item-number">8.6</span> <span class="item-number">9.6</span>
<span class="item-title">Tokenisierung</span> <span class="item-title">Tokenisierung</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_hauptfunktionen"> <a href="#_hauptfunktionen">
<span class="item-number">8.7</span> <span class="item-number">9.7</span>
<span class="item-title">Hauptfunktionen</span> <span class="item-title">Hauptfunktionen</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_fehlerbehebung"> <a href="#_fehlerbehebung">
<span class="item-number">8.8</span> <span class="item-number">9.8</span>
<span class="item-title">Fehlerbehebung</span> <span class="item-title">Fehlerbehebung</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_faqs"> <a href="#_faqs">
<span class="item-number">8.9</span> <span class="item-number">9.9</span>
<span class="item-title">FAQs</span> <span class="item-title">FAQs</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_änderungsprotokoll"> <a href="#_änderungsprotokoll">
<span class="item-number">9</span> <span class="item-number">10</span>
<span class="item-title">Änderungsprotokoll</span> <span class="item-title">Änderungsprotokoll</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_mitwirken"> <a href="#_mitwirken">
<span class="item-number">10</span> <span class="item-number">11</span>
<span class="item-title">Mitwirken</span> <span class="item-title">Mitwirken</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_support"> <a href="#_support">
<span class="item-number">11</span> <span class="item-number">12</span>
<span class="item-title">Support</span> <span class="item-title">Support</span>
</a> </a>
</li> </ul> </li> </ul>
+112 -46
View File
@@ -172,10 +172,59 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</ol> </ol>
</div> </div> </div> </div>
</div> </div> </div> </div>
</div> <div class="chapter" id="_update">
<div class="chapter-title">
<h1>
<span class="title-number">5</span>Update </h1>
</div>
<div class="chapter-body">
<div class="section" id="_via_administration">
<div class="section-title">
<h2>
<span class="title-number">5.1</span>Via Administration </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Go to Shopware Admin &gt; Extensions &gt; My extensions.</p>
</li>
<li>
<p>Find VRPaymentPayment.</p>
</li>
<li>
<p>Click Update.</p>
</li>
</ol>
</div> </div>
</div> <div class="section" id="_via_cli">
<div class="section-title">
<h2>
<span class="title-number">5.2</span>Via CLI </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Deploy the new plugin files (replace the folder in <code>custom/plugins/VRPaymentPayment</code> or upload/install a new ZIP).</p>
</li>
<li>
<p>Run:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">bin/console plugin:refresh
bin/console plugin:update --clearCache VRPaymentPayment
bin/console cache:clear</code></pre>
</div>
</div>
</li>
</ol>
</div> </div>
</div> </div>
</div> <div class="chapter" id="portal-startup-guide"> </div> <div class="chapter" id="portal-startup-guide">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">5</span>Portal Startup Guide </h1> <span class="title-number">6</span>Portal Startup Guide </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -194,7 +243,7 @@ Please select the proper subscription plan - it should support ecommerce transac
</div> <div class="section" id="_create_the_api_key"> </div> <div class="section" id="_create_the_api_key">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.1</span>Create the API key: </h2> <span class="title-number">6.1</span>Create the API key: </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -280,7 +329,7 @@ Please note that Roles might be loading for few seconds
</div> <div class="section" id="_setup_payment_methods"> </div> <div class="section" id="_setup_payment_methods">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.2</span>Setup Payment Methods </h2> <span class="title-number">6.2</span>Setup Payment Methods </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -342,7 +391,7 @@ Please note that the connectors seems duplicated but it because one is for Physi
</div> <div class="chapter" id="_shop_startup_guide"> </div> <div class="chapter" id="_shop_startup_guide">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">6</span>Shop Startup Guide </h1> <span class="title-number">7</span>Shop Startup Guide </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -481,7 +530,7 @@ Please note that if you do not use the Space View Id; this option should stay em
</div> <div class="chapter" id="_transaction_state_graph"> </div> <div class="chapter" id="_transaction_state_graph">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">7</span>Transaction State graph </h1> <span class="title-number">8</span>Transaction State graph </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -493,7 +542,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="section" id="_state_mapping_of_shopware_orders"> </div> <div class="section" id="_state_mapping_of_shopware_orders">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.1</span>State mapping of Shopware orders </h2> <span class="title-number">8.1</span>State mapping of Shopware orders </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -501,7 +550,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="section" id="_general_remarks_regarding_order_statuses"> </div> <div class="section" id="_general_remarks_regarding_order_statuses">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.1.1</span>General remarks regarding order statuses </h3> <span class="title-number">8.1.1</span>General remarks regarding order statuses </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -511,7 +560,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="section" id="_state_mapping_of_shopware_payment_status"> </div> <div class="section" id="_state_mapping_of_shopware_payment_status">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.2</span>State mapping of Shopware payment status </h2> <span class="title-number">8.2</span>State mapping of Shopware payment status </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -538,7 +587,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="section" id="_general_remarks_regarding_payment_statuses"> </div> <div class="section" id="_general_remarks_regarding_payment_statuses">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.2.1</span>General remarks regarding payment statuses </h3> <span class="title-number">8.2.1</span>General remarks regarding payment statuses </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -548,7 +597,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="section" id="_state_mapping_of_shopware_delivery_status"> </div> <div class="section" id="_state_mapping_of_shopware_delivery_status">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.3</span>State mapping of Shopware delivery status </h2> <span class="title-number">8.3</span>State mapping of Shopware delivery status </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -574,7 +623,7 @@ can be found in the <a href="https://gateway.vr-payment.de/en-us/doc/payment/tra
</div> <div class="chapter" id="_transaction_management"> </div> <div class="chapter" id="_transaction_management">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">8</span>Transaction management </h1> <span class="title-number">9</span>Transaction management </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -584,7 +633,7 @@ Shopware. However, there are some limitations (see below).</p>
</div> <div class="section" id="_complete_capture_an_order"> </div> <div class="section" id="_complete_capture_an_order">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.1</span>Complete (capture) an order </h2> <span class="title-number">9.1</span>Complete (capture) an order </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -618,7 +667,7 @@ the fulfill state is reached. Initially the transaction will be in the <code>Aut
</div> <div class="section" id="_void_a_transaction"> </div> <div class="section" id="_void_a_transaction">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.2</span>Void a transaction </h2> <span class="title-number">9.2</span>Void a transaction </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -642,7 +691,7 @@ You can only void transactions that are not yet completed.
</div> <div class="section" id="_refund_of_a_transaction"> </div> <div class="section" id="_refund_of_a_transaction">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.3</span>Refund of a transaction </h2> <span class="title-number">9.3</span>Refund of a transaction </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -669,7 +718,7 @@ It can take some time until you see the refund in Shopware. Refunds will only be
</div> <div class="section" id="_on_hold_orders"> </div> <div class="section" id="_on_hold_orders">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.4</span>On hold orders </h2> <span class="title-number">9.4</span>On hold orders </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -693,7 +742,7 @@ within the defined time frame, VR Payment will generate a manual task which you
</div> <div class="section" id="_limitations_of_the_synchronization_between_whitelabelname_and_shopware"> </div> <div class="section" id="_limitations_of_the_synchronization_between_whitelabelname_and_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.5</span>Limitations of the synchronization between VR Payment and Shopware </h2> <span class="title-number">9.5</span>Limitations of the synchronization between VR Payment and Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -709,7 +758,7 @@ your Shopware backend.</p>
</div> <div class="section" id="_tokenization"> </div> <div class="section" id="_tokenization">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.6</span>Tokenization </h2> <span class="title-number">9.6</span>Tokenization </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -730,7 +779,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="section" id="_key_features"> </div> <div class="section" id="_key_features">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.7</span>Key Features </h2> <span class="title-number">9.7</span>Key Features </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -752,7 +801,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="section" id="_troubleshooting"> </div> <div class="section" id="_troubleshooting">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.8</span>Troubleshooting </h2> <span class="title-number">9.8</span>Troubleshooting </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -783,7 +832,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="section" id="_faqs"> </div> <div class="section" id="_faqs">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.9</span>FAQs </h2> <span class="title-number">9.9</span>FAQs </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -815,7 +864,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="chapter" id="_changelog"> </div> <div class="chapter" id="_changelog">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">9</span>Changelog </h1> <span class="title-number">10</span>Changelog </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -824,7 +873,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="chapter" id="_contributing"> </div> <div class="chapter" id="_contributing">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">10</span>Contributing </h1> <span class="title-number">11</span>Contributing </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -835,7 +884,7 @@ Tokenization is not available for guest checkouts.
</div> <div class="chapter" id="_support"> </div> <div class="chapter" id="_support">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">11</span>Support </h1> <span class="title-number">12</span>Support </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -886,128 +935,145 @@ Tokenization is not available for guest checkouts.
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#portal-startup-guide"> <a href="#_update">
<span class="item-number">5</span> <span class="item-number">5</span>
<span class="item-title">Update</span>
</a>
<ul class="nav">
<li class="nav-level-2">
<a href="#_via_administration">
<span class="item-number">5.1</span>
<span class="item-title">Via Administration</span>
</a>
</li> <li class="nav-level-2">
<a href="#_via_cli">
<span class="item-number">5.2</span>
<span class="item-title">Via CLI</span>
</a>
</li> </ul>
</li> <li class="nav-level-1">
<a href="#portal-startup-guide">
<span class="item-number">6</span>
<span class="item-title">Portal Startup Guide</span> <span class="item-title">Portal Startup Guide</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_create_the_api_key"> <a href="#_create_the_api_key">
<span class="item-number">5.1</span> <span class="item-number">6.1</span>
<span class="item-title">Create the API key:</span> <span class="item-title">Create the API key:</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_setup_payment_methods"> <a href="#_setup_payment_methods">
<span class="item-number">5.2</span> <span class="item-number">6.2</span>
<span class="item-title">Setup Payment Methods</span> <span class="item-title">Setup Payment Methods</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_shop_startup_guide"> <a href="#_shop_startup_guide">
<span class="item-number">6</span> <span class="item-number">7</span>
<span class="item-title">Shop Startup Guide</span> <span class="item-title">Shop Startup Guide</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_transaction_state_graph"> <a href="#_transaction_state_graph">
<span class="item-number">7</span> <span class="item-number">8</span>
<span class="item-title">Transaction State graph</span> <span class="item-title">Transaction State graph</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_state_mapping_of_shopware_orders"> <a href="#_state_mapping_of_shopware_orders">
<span class="item-number">7.1</span> <span class="item-number">8.1</span>
<span class="item-title">State mapping of Shopware orders</span> <span class="item-title">State mapping of Shopware orders</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_general_remarks_regarding_order_statuses"> <a href="#_general_remarks_regarding_order_statuses">
<span class="item-number">7.1.1</span> <span class="item-number">8.1.1</span>
<span class="item-title">General remarks regarding order statuses</span> <span class="item-title">General remarks regarding order statuses</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_state_mapping_of_shopware_payment_status"> <a href="#_state_mapping_of_shopware_payment_status">
<span class="item-number">7.2</span> <span class="item-number">8.2</span>
<span class="item-title">State mapping of Shopware payment status</span> <span class="item-title">State mapping of Shopware payment status</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_general_remarks_regarding_payment_statuses"> <a href="#_general_remarks_regarding_payment_statuses">
<span class="item-number">7.2.1</span> <span class="item-number">8.2.1</span>
<span class="item-title">General remarks regarding payment statuses</span> <span class="item-title">General remarks regarding payment statuses</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_state_mapping_of_shopware_delivery_status"> <a href="#_state_mapping_of_shopware_delivery_status">
<span class="item-number">7.3</span> <span class="item-number">8.3</span>
<span class="item-title">State mapping of Shopware delivery status</span> <span class="item-title">State mapping of Shopware delivery status</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_transaction_management"> <a href="#_transaction_management">
<span class="item-number">8</span> <span class="item-number">9</span>
<span class="item-title">Transaction management</span> <span class="item-title">Transaction management</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_complete_capture_an_order"> <a href="#_complete_capture_an_order">
<span class="item-number">8.1</span> <span class="item-number">9.1</span>
<span class="item-title">Complete (capture) an order</span> <span class="item-title">Complete (capture) an order</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_void_a_transaction"> <a href="#_void_a_transaction">
<span class="item-number">8.2</span> <span class="item-number">9.2</span>
<span class="item-title">Void a transaction</span> <span class="item-title">Void a transaction</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_refund_of_a_transaction"> <a href="#_refund_of_a_transaction">
<span class="item-number">8.3</span> <span class="item-number">9.3</span>
<span class="item-title">Refund of a transaction</span> <span class="item-title">Refund of a transaction</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_on_hold_orders"> <a href="#_on_hold_orders">
<span class="item-number">8.4</span> <span class="item-number">9.4</span>
<span class="item-title">On hold orders</span> <span class="item-title">On hold orders</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_limitations_of_the_synchronization_between_whitelabelname_and_shopware"> <a href="#_limitations_of_the_synchronization_between_whitelabelname_and_shopware">
<span class="item-number">8.5</span> <span class="item-number">9.5</span>
<span class="item-title">Limitations of the synchronization between VR Payment and Shopware</span> <span class="item-title">Limitations of the synchronization between VR Payment and Shopware</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_tokenization"> <a href="#_tokenization">
<span class="item-number">8.6</span> <span class="item-number">9.6</span>
<span class="item-title">Tokenization</span> <span class="item-title">Tokenization</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_key_features"> <a href="#_key_features">
<span class="item-number">8.7</span> <span class="item-number">9.7</span>
<span class="item-title">Key Features</span> <span class="item-title">Key Features</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_troubleshooting"> <a href="#_troubleshooting">
<span class="item-number">8.8</span> <span class="item-number">9.8</span>
<span class="item-title">Troubleshooting</span> <span class="item-title">Troubleshooting</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_faqs"> <a href="#_faqs">
<span class="item-number">8.9</span> <span class="item-number">9.9</span>
<span class="item-title">FAQs</span> <span class="item-title">FAQs</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_changelog"> <a href="#_changelog">
<span class="item-number">9</span> <span class="item-number">10</span>
<span class="item-title">Changelog</span> <span class="item-title">Changelog</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_contributing"> <a href="#_contributing">
<span class="item-number">10</span> <span class="item-number">11</span>
<span class="item-title">Contributing</span> <span class="item-title">Contributing</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_support"> <a href="#_support">
<span class="item-number">11</span> <span class="item-number">12</span>
<span class="item-title">Support</span> <span class="item-title">Support</span>
</a> </a>
</li> </ul> </li> </ul>
+112 -46
View File
@@ -165,10 +165,59 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</div> </div>
</div> </div> </div> </div>
</div> </div> </div> </div>
</div> <div class="chapter" id="_mise_à_jour">
<div class="chapter-title">
<h1>
<span class="title-number">5</span>Mise à jour </h1>
</div>
<div class="chapter-body">
<div class="section" id="_via_l_administration">
<div class="section-title">
<h2>
<span class="title-number">5.1</span>Via ladministration </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Allez dans Shopware Admin &gt; Extensions &gt; Mes extensions.</p>
</li>
<li>
<p>Recherchez VRPaymentPayment.</p>
</li>
<li>
<p>Cliquez sur Mettre à jour.</p>
</li>
</ol>
</div> </div>
</div> <div class="section" id="_via_la_cli">
<div class="section-title">
<h2>
<span class="title-number">5.2</span>Via la CLI </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Déployez les nouveaux fichiers du plugin (remplacez le dossier <code>custom/plugins/VRPaymentPayment</code> ou téléversez/installez un nouveau ZIP).</p>
</li>
<li>
<p>Exécutez :</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">bin/console plugin:refresh
bin/console plugin:update --clearCache VRPaymentPayment
bin/console cache:clear</code></pre>
</div>
</div>
</li>
</ol>
</div> </div>
</div> </div>
</div> <div class="chapter" id="portal-startup-guide"> </div> <div class="chapter" id="portal-startup-guide">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">5</span>Guide de démarrage pour le Portail </h1> <span class="title-number">6</span>Guide de démarrage pour le Portail </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -187,7 +236,7 @@ Veuillez sélectionner le plan d&#8217;abonnement approprié - il doit prendre e
</div> <div class="section" id="_créez_la_clé_api"> </div> <div class="section" id="_créez_la_clé_api">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.1</span>Créez la clé API: </h2> <span class="title-number">6.1</span>Créez la clé API: </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -273,7 +322,7 @@ Veuillez noter que le chargement des rôles peut durer quelques secondes.
</div> <div class="section" id="_configurer_les_modes_de_paiement"> </div> <div class="section" id="_configurer_les_modes_de_paiement">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.2</span>Configurer les modes de paiement </h2> <span class="title-number">6.2</span>Configurer les modes de paiement </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -335,7 +384,7 @@ Veuillez noter que les connecteurs semblent faire double emploi, mais c&#8217;es
</div> <div class="chapter" id="_guide_de_démarrage_pour_shopware"> </div> <div class="chapter" id="_guide_de_démarrage_pour_shopware">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">6</span>Guide de démarrage pour Shopware </h1> <span class="title-number">7</span>Guide de démarrage pour Shopware </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -474,7 +523,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="chapter" id="_différents_etats_pour_une_transaction"> </div> <div class="chapter" id="_différents_etats_pour_une_transaction">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">7</span>Différents Etats pour une Transaction </h1> <span class="title-number">8</span>Différents Etats pour une Transaction </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -484,7 +533,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_cartographie_des_différents_états_d_une_commande_de_shopware"> </div> <div class="section" id="_cartographie_des_différents_états_d_une_commande_de_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.1</span>Cartographie des différents états dune commande de Shopware </h2> <span class="title-number">8.1</span>Cartographie des différents états dune commande de Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -492,7 +541,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_remarque_générales_concernant_les_status_des_commandes"> </div> <div class="section" id="_remarque_générales_concernant_les_status_des_commandes">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.1.1</span>Remarque générales concernant les status des commandes </h3> <span class="title-number">8.1.1</span>Remarque générales concernant les status des commandes </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -502,7 +551,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_cartographie_des_différents_états_du_paiement_de_shopware"> </div> <div class="section" id="_cartographie_des_différents_états_du_paiement_de_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.2</span>Cartographie des différents états du paiement de Shopware </h2> <span class="title-number">8.2</span>Cartographie des différents états du paiement de Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -529,7 +578,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_remarques_générales_concernant_les_différents_status_pour_les_paiements"> </div> <div class="section" id="_remarques_générales_concernant_les_différents_status_pour_les_paiements">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.2.1</span>Remarques générales concernant les différents status pour les paiements </h3> <span class="title-number">8.2.1</span>Remarques générales concernant les différents status pour les paiements </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -539,7 +588,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_carthographie_des_différents_états_de_livraison_chez_shopware"> </div> <div class="section" id="_carthographie_des_différents_états_de_livraison_chez_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.3</span>Carthographie des différents états de livraison chez Shopware </h2> <span class="title-number">8.3</span>Carthographie des différents états de livraison chez Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -565,7 +614,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="chapter" id="_gestion_des_transactions"> </div> <div class="chapter" id="_gestion_des_transactions">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">8</span>Gestion des Transactions </h1> <span class="title-number">9</span>Gestion des Transactions </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -573,7 +622,7 @@ Veuillez noter que si vous n&#8217;utilisez pas Space View Id, cette option doit
</div> <div class="section" id="_complete_capture_an_order"> </div> <div class="section" id="_complete_capture_an_order">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.1</span>Complete (capture) an order </h2> <span class="title-number">9.1</span>Complete (capture) an order </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -605,7 +654,7 @@ Lorsque le paiement est en attente dans wallee, la commande reste en attente.
</div> <div class="section" id="_annuler_une_transaction"> </div> <div class="section" id="_annuler_une_transaction">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.2</span>Annuler une transaction </h2> <span class="title-number">9.2</span>Annuler une transaction </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -629,7 +678,7 @@ Vous ne pouvez annuler que les transactions qui ne sont pas encore complétée..
</div> <div class="section" id="_remboursement_d_une_transaction"> </div> <div class="section" id="_remboursement_d_une_transaction">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.3</span>Remboursement d&#8217;une transaction </h2> <span class="title-number">9.3</span>Remboursement d&#8217;une transaction </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -655,7 +704,7 @@ Il peut s&#8217;écouler un certain temps avant que vous ne voyiez le remboursem
</div> <div class="section" id="_commandes_en_attente"> </div> <div class="section" id="_commandes_en_attente">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.4</span>Commandes en attente </h2> <span class="title-number">9.4</span>Commandes en attente </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -677,7 +726,7 @@ Il peut s&#8217;écouler un certain temps avant que vous ne voyiez le remboursem
</div> <div class="section" id="_limites_de_la_synchronisation_entre_wallee_et_shopware"> </div> <div class="section" id="_limites_de_la_synchronisation_entre_wallee_et_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.5</span>Limites de la synchronisation entre wallee et Shopware </h2> <span class="title-number">9.5</span>Limites de la synchronisation entre wallee et Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -688,7 +737,7 @@ Il peut s&#8217;écouler un certain temps avant que vous ne voyiez le remboursem
</div> <div class="section" id="_tokenisation"> </div> <div class="section" id="_tokenisation">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.6</span>Tokenisation </h2> <span class="title-number">9.6</span>Tokenisation </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -708,7 +757,7 @@ La tokenisation n&#8217;est pas disponible pour les paiements par les invités.
</div> <div class="section" id="_caractéristiques_pricinpales"> </div> <div class="section" id="_caractéristiques_pricinpales">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.7</span>Caractéristiques Pricinpales </h2> <span class="title-number">9.7</span>Caractéristiques Pricinpales </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -730,7 +779,7 @@ La tokenisation n&#8217;est pas disponible pour les paiements par les invités.
</div> <div class="section" id="_troubleshooting"> </div> <div class="section" id="_troubleshooting">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.8</span>Troubleshooting </h2> <span class="title-number">9.8</span>Troubleshooting </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -761,7 +810,7 @@ La tokenisation n&#8217;est pas disponible pour les paiements par les invités.
</div> <div class="section" id="_faqs"> </div> <div class="section" id="_faqs">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.9</span>FAQs </h2> <span class="title-number">9.9</span>FAQs </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -789,7 +838,7 @@ A: Oui, le plugin prend en charge les portefeuilles comme Apple Pay.</p>
</div> <div class="chapter" id="_changelog"> </div> <div class="chapter" id="_changelog">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">9</span>Changelog </h1> <span class="title-number">10</span>Changelog </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -798,7 +847,7 @@ A: Oui, le plugin prend en charge les portefeuilles comme Apple Pay.</p>
</div> <div class="chapter" id="_contribuer"> </div> <div class="chapter" id="_contribuer">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">10</span>Contribuer </h1> <span class="title-number">11</span>Contribuer </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -809,7 +858,7 @@ A: Oui, le plugin prend en charge les portefeuilles comme Apple Pay.</p>
</div> <div class="chapter" id="_support"> </div> <div class="chapter" id="_support">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">11</span>Support </h1> <span class="title-number">12</span>Support </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -860,128 +909,145 @@ A: Oui, le plugin prend en charge les portefeuilles comme Apple Pay.</p>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#portal-startup-guide"> <a href="#_mise_à_jour">
<span class="item-number">5</span> <span class="item-number">5</span>
<span class="item-title">Mise à jour</span>
</a>
<ul class="nav">
<li class="nav-level-2">
<a href="#_via_l_administration">
<span class="item-number">5.1</span>
<span class="item-title">Via ladministration</span>
</a>
</li> <li class="nav-level-2">
<a href="#_via_la_cli">
<span class="item-number">5.2</span>
<span class="item-title">Via la CLI</span>
</a>
</li> </ul>
</li> <li class="nav-level-1">
<a href="#portal-startup-guide">
<span class="item-number">6</span>
<span class="item-title">Guide de démarrage pour le Portail</span> <span class="item-title">Guide de démarrage pour le Portail</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_créez_la_clé_api"> <a href="#_créez_la_clé_api">
<span class="item-number">5.1</span> <span class="item-number">6.1</span>
<span class="item-title">Créez la clé API:</span> <span class="item-title">Créez la clé API:</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_configurer_les_modes_de_paiement"> <a href="#_configurer_les_modes_de_paiement">
<span class="item-number">5.2</span> <span class="item-number">6.2</span>
<span class="item-title">Configurer les modes de paiement</span> <span class="item-title">Configurer les modes de paiement</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_guide_de_démarrage_pour_shopware"> <a href="#_guide_de_démarrage_pour_shopware">
<span class="item-number">6</span> <span class="item-number">7</span>
<span class="item-title">Guide de démarrage pour Shopware</span> <span class="item-title">Guide de démarrage pour Shopware</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_différents_etats_pour_une_transaction"> <a href="#_différents_etats_pour_une_transaction">
<span class="item-number">7</span> <span class="item-number">8</span>
<span class="item-title">Différents Etats pour une Transaction</span> <span class="item-title">Différents Etats pour une Transaction</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_cartographie_des_différents_états_d_une_commande_de_shopware"> <a href="#_cartographie_des_différents_états_d_une_commande_de_shopware">
<span class="item-number">7.1</span> <span class="item-number">8.1</span>
<span class="item-title">Cartographie des différents états dune commande de Shopware</span> <span class="item-title">Cartographie des différents états dune commande de Shopware</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_remarque_générales_concernant_les_status_des_commandes"> <a href="#_remarque_générales_concernant_les_status_des_commandes">
<span class="item-number">7.1.1</span> <span class="item-number">8.1.1</span>
<span class="item-title">Remarque générales concernant les status des commandes</span> <span class="item-title">Remarque générales concernant les status des commandes</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_cartographie_des_différents_états_du_paiement_de_shopware"> <a href="#_cartographie_des_différents_états_du_paiement_de_shopware">
<span class="item-number">7.2</span> <span class="item-number">8.2</span>
<span class="item-title">Cartographie des différents états du paiement de Shopware</span> <span class="item-title">Cartographie des différents états du paiement de Shopware</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_remarques_générales_concernant_les_différents_status_pour_les_paiements"> <a href="#_remarques_générales_concernant_les_différents_status_pour_les_paiements">
<span class="item-number">7.2.1</span> <span class="item-number">8.2.1</span>
<span class="item-title">Remarques générales concernant les différents status pour les paiements</span> <span class="item-title">Remarques générales concernant les différents status pour les paiements</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_carthographie_des_différents_états_de_livraison_chez_shopware"> <a href="#_carthographie_des_différents_états_de_livraison_chez_shopware">
<span class="item-number">7.3</span> <span class="item-number">8.3</span>
<span class="item-title">Carthographie des différents états de livraison chez Shopware</span> <span class="item-title">Carthographie des différents états de livraison chez Shopware</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_gestion_des_transactions"> <a href="#_gestion_des_transactions">
<span class="item-number">8</span> <span class="item-number">9</span>
<span class="item-title">Gestion des Transactions</span> <span class="item-title">Gestion des Transactions</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_complete_capture_an_order"> <a href="#_complete_capture_an_order">
<span class="item-number">8.1</span> <span class="item-number">9.1</span>
<span class="item-title">Complete (capture) an order</span> <span class="item-title">Complete (capture) an order</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_annuler_une_transaction"> <a href="#_annuler_une_transaction">
<span class="item-number">8.2</span> <span class="item-number">9.2</span>
<span class="item-title">Annuler une transaction</span> <span class="item-title">Annuler une transaction</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_remboursement_d_une_transaction"> <a href="#_remboursement_d_une_transaction">
<span class="item-number">8.3</span> <span class="item-number">9.3</span>
<span class="item-title">Remboursement d&amp;#8217;une transaction</span> <span class="item-title">Remboursement d&amp;#8217;une transaction</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_commandes_en_attente"> <a href="#_commandes_en_attente">
<span class="item-number">8.4</span> <span class="item-number">9.4</span>
<span class="item-title">Commandes en attente</span> <span class="item-title">Commandes en attente</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_limites_de_la_synchronisation_entre_wallee_et_shopware"> <a href="#_limites_de_la_synchronisation_entre_wallee_et_shopware">
<span class="item-number">8.5</span> <span class="item-number">9.5</span>
<span class="item-title">Limites de la synchronisation entre wallee et Shopware</span> <span class="item-title">Limites de la synchronisation entre wallee et Shopware</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_tokenisation"> <a href="#_tokenisation">
<span class="item-number">8.6</span> <span class="item-number">9.6</span>
<span class="item-title">Tokenisation</span> <span class="item-title">Tokenisation</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_caractéristiques_pricinpales"> <a href="#_caractéristiques_pricinpales">
<span class="item-number">8.7</span> <span class="item-number">9.7</span>
<span class="item-title">Caractéristiques Pricinpales</span> <span class="item-title">Caractéristiques Pricinpales</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_troubleshooting"> <a href="#_troubleshooting">
<span class="item-number">8.8</span> <span class="item-number">9.8</span>
<span class="item-title">Troubleshooting</span> <span class="item-title">Troubleshooting</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_faqs"> <a href="#_faqs">
<span class="item-number">8.9</span> <span class="item-number">9.9</span>
<span class="item-title">FAQs</span> <span class="item-title">FAQs</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_changelog"> <a href="#_changelog">
<span class="item-number">9</span> <span class="item-number">10</span>
<span class="item-title">Changelog</span> <span class="item-title">Changelog</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_contribuer"> <a href="#_contribuer">
<span class="item-number">10</span> <span class="item-number">11</span>
<span class="item-title">Contribuer</span> <span class="item-title">Contribuer</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_support"> <a href="#_support">
<span class="item-number">11</span> <span class="item-number">12</span>
<span class="item-title">Support</span> <span class="item-title">Support</span>
</a> </a>
</li> </ul> </li> </ul>
+112 -46
View File
@@ -172,10 +172,59 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</ol> </ol>
</div> </div> </div> </div>
</div> </div> </div> </div>
</div> <div class="chapter" id="_aggiornamento">
<div class="chapter-title">
<h1>
<span class="title-number">5</span>Aggiornamento </h1>
</div>
<div class="chapter-body">
<div class="section" id="_tramite_amministrazione">
<div class="section-title">
<h2>
<span class="title-number">5.1</span>Tramite Amministrazione </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Vai su Shopware Admin &gt; Estensioni &gt; Le mie estensioni.</p>
</li>
<li>
<p>Trova VRPaymentPayment.</p>
</li>
<li>
<p>Clicca su Aggiorna.</p>
</li>
</ol>
</div> </div>
</div> <div class="section" id="_tramite_cli">
<div class="section-title">
<h2>
<span class="title-number">5.2</span>Tramite CLI </h2>
</div>
<div class="section-body">
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Distribuisci i nuovi file del plugin (sostituisci la cartella <code>custom/plugins/VRPaymentPayment</code> oppure carica/installa un nuovo ZIP).</p>
</li>
<li>
<p>Esegui:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">bin/console plugin:refresh
bin/console plugin:update --clearCache VRPaymentPayment
bin/console cache:clear</code></pre>
</div>
</div>
</li>
</ol>
</div> </div>
</div> </div>
</div> <div class="chapter" id="portal-startup-guide"> </div> <div class="chapter" id="portal-startup-guide">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">5</span>Guida Rapida al Portale </h1> <span class="title-number">6</span>Guida Rapida al Portale </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -194,7 +243,7 @@ Selezionate il piano di abbonamento appropriato: dovrebbe supportare le transazi
</div> <div class="section" id="_create_la_chiave_api"> </div> <div class="section" id="_create_la_chiave_api">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.1</span>Create la chiave API: </h2> <span class="title-number">6.1</span>Create la chiave API: </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -280,7 +329,7 @@ Si prega di notare che il caricamento dei ruoli potrebbe richiedere alcuni secon
</div> <div class="section" id="_configurate_i_metodi_di_pagamento"> </div> <div class="section" id="_configurate_i_metodi_di_pagamento">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">5.2</span>Configurate i Metodi di Pagamento </h2> <span class="title-number">6.2</span>Configurate i Metodi di Pagamento </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -342,7 +391,7 @@ Si prega di notare che i connettori sembrano duplicati, ma è perché uno è per
</div> <div class="chapter" id="_guida_rapida_al_shop"> </div> <div class="chapter" id="_guida_rapida_al_shop">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">6</span>Guida Rapida al Shop </h1> <span class="title-number">7</span>Guida Rapida al Shop </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="olist arabic"> <div class="olist arabic">
@@ -481,7 +530,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="chapter" id="_grafico_dello_stato_della_transazione"> </div> <div class="chapter" id="_grafico_dello_stato_della_transazione">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">7</span>Grafico dello Stato della Transazione </h1> <span class="title-number">8</span>Grafico dello Stato della Transazione </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -491,7 +540,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_mappatura_degli_stati_degli_ordini_di_shopware"> </div> <div class="section" id="_mappatura_degli_stati_degli_ordini_di_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.1</span>Mappatura degli Stati degli Ordini di Shopware </h2> <span class="title-number">8.1</span>Mappatura degli Stati degli Ordini di Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -499,7 +548,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_osservazioni_generali_riguardo_agli_stati_degli_ordini"> </div> <div class="section" id="_osservazioni_generali_riguardo_agli_stati_degli_ordini">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.1.1</span>Osservazioni Generali Riguardo agli Stati degli Ordini </h3> <span class="title-number">8.1.1</span>Osservazioni Generali Riguardo agli Stati degli Ordini </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -509,7 +558,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_mappatura_dello_stato_di_pagamento_di_shopware"> </div> <div class="section" id="_mappatura_dello_stato_di_pagamento_di_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.2</span>Mappatura dello Stato di Pagamento di Shopware </h2> <span class="title-number">8.2</span>Mappatura dello Stato di Pagamento di Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -536,7 +585,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_osservazioni_generali_riguardo_agli_stati_di_pagamento"> </div> <div class="section" id="_osservazioni_generali_riguardo_agli_stati_di_pagamento">
<div class="section-title"> <div class="section-title">
<h3> <h3>
<span class="title-number">7.2.1</span>Osservazioni Generali Riguardo agli Stati di Pagamento </h3> <span class="title-number">8.2.1</span>Osservazioni Generali Riguardo agli Stati di Pagamento </h3>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -546,7 +595,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_mappatura_dello_stato_di_spedizione_di_shopware"> </div> <div class="section" id="_mappatura_dello_stato_di_spedizione_di_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">7.3</span>Mappatura dello Stato di Spedizione di Shopware </h2> <span class="title-number">8.3</span>Mappatura dello Stato di Spedizione di Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -572,7 +621,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="chapter" id="_gestione_delle_transazioni"> </div> <div class="chapter" id="_gestione_delle_transazioni">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">8</span>Gestione delle Transazioni </h1> <span class="title-number">9</span>Gestione delle Transazioni </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -580,7 +629,7 @@ Si prega di notare che se non utilizzate lo Space View Id, questa opzione dovreb
</div> <div class="section" id="_completare_acquisire_un_ordine"> </div> <div class="section" id="_completare_acquisire_un_ordine">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.1</span>Completare (Acquisire) un Ordine </h2> <span class="title-number">9.1</span>Completare (Acquisire) un Ordine </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -612,7 +661,7 @@ Quando il completamento è in sospeso in Wallee, l&#8217;ordine rimarrà nello s
</div> <div class="section" id="_annullare_una_transazione"> </div> <div class="section" id="_annullare_una_transazione">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.2</span>Annullare una transazione </h2> <span class="title-number">9.2</span>Annullare una transazione </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -636,7 +685,7 @@ Puoi annullare solo le transazioni che non sono ancora state completate
</div> <div class="section" id="_rimborso_di_una_transazione"> </div> <div class="section" id="_rimborso_di_una_transazione">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.3</span>Rimborso di una Transazione </h2> <span class="title-number">9.3</span>Rimborso di una Transazione </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -662,7 +711,7 @@ Potrebbe volerci un po' di tempo prima che vediate il rimborso in Shopware. I ri
</div> <div class="section" id="_ordini_in_attesa"> </div> <div class="section" id="_ordini_in_attesa">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.4</span>Ordini in Attesa </h2> <span class="title-number">9.4</span>Ordini in Attesa </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -684,7 +733,7 @@ Potrebbe volerci un po' di tempo prima che vediate il rimborso in Shopware. I ri
</div> <div class="section" id="_limitazioni_della_sincronizzazione_tra_wallee_e_shopware"> </div> <div class="section" id="_limitazioni_della_sincronizzazione_tra_wallee_e_shopware">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.5</span>Limitazioni della Sincronizzazione tra Wallee e Shopware </h2> <span class="title-number">9.5</span>Limitazioni della Sincronizzazione tra Wallee e Shopware </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -695,7 +744,7 @@ Potrebbe volerci un po' di tempo prima che vediate il rimborso in Shopware. I ri
</div> <div class="section" id="_tokenization"> </div> <div class="section" id="_tokenization">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.6</span>Tokenization </h2> <span class="title-number">9.6</span>Tokenization </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -715,7 +764,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="section" id="_key_features"> </div> <div class="section" id="_key_features">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.7</span>Key Features </h2> <span class="title-number">9.7</span>Key Features </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -737,7 +786,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="section" id="_risoluzione_dei_problemi"> </div> <div class="section" id="_risoluzione_dei_problemi">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.8</span>Risoluzione dei Problemi </h2> <span class="title-number">9.8</span>Risoluzione dei Problemi </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="ulist"> <div class="ulist">
@@ -768,7 +817,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="section" id="_faqs"> </div> <div class="section" id="_faqs">
<div class="section-title"> <div class="section-title">
<h2> <h2>
<span class="title-number">8.9</span>FAQs </h2> <span class="title-number">9.9</span>FAQs </h2>
</div> </div>
<div class="section-body"> <div class="section-body">
<div class="paragraph"> <div class="paragraph">
@@ -800,7 +849,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="chapter" id="_changelog"> </div> <div class="chapter" id="_changelog">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">9</span>Changelog </h1> <span class="title-number">10</span>Changelog </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -809,7 +858,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="chapter" id="_contribuzione"> </div> <div class="chapter" id="_contribuzione">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">10</span>Contribuzione </h1> <span class="title-number">11</span>Contribuzione </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -820,7 +869,7 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</div> <div class="chapter" id="_support"> </div> <div class="chapter" id="_support">
<div class="chapter-title"> <div class="chapter-title">
<h1> <h1>
<span class="title-number">11</span>Support </h1> <span class="title-number">12</span>Support </h1>
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
@@ -871,128 +920,145 @@ La tokenizzazione non è disponibile per i checkout degli ospiti.
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#portal-startup-guide"> <a href="#_aggiornamento">
<span class="item-number">5</span> <span class="item-number">5</span>
<span class="item-title">Aggiornamento</span>
</a>
<ul class="nav">
<li class="nav-level-2">
<a href="#_tramite_amministrazione">
<span class="item-number">5.1</span>
<span class="item-title">Tramite Amministrazione</span>
</a>
</li> <li class="nav-level-2">
<a href="#_tramite_cli">
<span class="item-number">5.2</span>
<span class="item-title">Tramite CLI</span>
</a>
</li> </ul>
</li> <li class="nav-level-1">
<a href="#portal-startup-guide">
<span class="item-number">6</span>
<span class="item-title">Guida Rapida al Portale</span> <span class="item-title">Guida Rapida al Portale</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_create_la_chiave_api"> <a href="#_create_la_chiave_api">
<span class="item-number">5.1</span> <span class="item-number">6.1</span>
<span class="item-title">Create la chiave API:</span> <span class="item-title">Create la chiave API:</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_configurate_i_metodi_di_pagamento"> <a href="#_configurate_i_metodi_di_pagamento">
<span class="item-number">5.2</span> <span class="item-number">6.2</span>
<span class="item-title">Configurate i Metodi di Pagamento</span> <span class="item-title">Configurate i Metodi di Pagamento</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_guida_rapida_al_shop"> <a href="#_guida_rapida_al_shop">
<span class="item-number">6</span> <span class="item-number">7</span>
<span class="item-title">Guida Rapida al Shop</span> <span class="item-title">Guida Rapida al Shop</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_grafico_dello_stato_della_transazione"> <a href="#_grafico_dello_stato_della_transazione">
<span class="item-number">7</span> <span class="item-number">8</span>
<span class="item-title">Grafico dello Stato della Transazione</span> <span class="item-title">Grafico dello Stato della Transazione</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_mappatura_degli_stati_degli_ordini_di_shopware"> <a href="#_mappatura_degli_stati_degli_ordini_di_shopware">
<span class="item-number">7.1</span> <span class="item-number">8.1</span>
<span class="item-title">Mappatura degli Stati degli Ordini di Shopware</span> <span class="item-title">Mappatura degli Stati degli Ordini di Shopware</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_osservazioni_generali_riguardo_agli_stati_degli_ordini"> <a href="#_osservazioni_generali_riguardo_agli_stati_degli_ordini">
<span class="item-number">7.1.1</span> <span class="item-number">8.1.1</span>
<span class="item-title">Osservazioni Generali Riguardo agli Stati degli Ordini</span> <span class="item-title">Osservazioni Generali Riguardo agli Stati degli Ordini</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_mappatura_dello_stato_di_pagamento_di_shopware"> <a href="#_mappatura_dello_stato_di_pagamento_di_shopware">
<span class="item-number">7.2</span> <span class="item-number">8.2</span>
<span class="item-title">Mappatura dello Stato di Pagamento di Shopware</span> <span class="item-title">Mappatura dello Stato di Pagamento di Shopware</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-3"> <li class="nav-level-3">
<a href="#_osservazioni_generali_riguardo_agli_stati_di_pagamento"> <a href="#_osservazioni_generali_riguardo_agli_stati_di_pagamento">
<span class="item-number">7.2.1</span> <span class="item-number">8.2.1</span>
<span class="item-title">Osservazioni Generali Riguardo agli Stati di Pagamento</span> <span class="item-title">Osservazioni Generali Riguardo agli Stati di Pagamento</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_mappatura_dello_stato_di_spedizione_di_shopware"> <a href="#_mappatura_dello_stato_di_spedizione_di_shopware">
<span class="item-number">7.3</span> <span class="item-number">8.3</span>
<span class="item-title">Mappatura dello Stato di Spedizione di Shopware</span> <span class="item-title">Mappatura dello Stato di Spedizione di Shopware</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_gestione_delle_transazioni"> <a href="#_gestione_delle_transazioni">
<span class="item-number">8</span> <span class="item-number">9</span>
<span class="item-title">Gestione delle Transazioni</span> <span class="item-title">Gestione delle Transazioni</span>
</a> </a>
<ul class="nav"> <ul class="nav">
<li class="nav-level-2"> <li class="nav-level-2">
<a href="#_completare_acquisire_un_ordine"> <a href="#_completare_acquisire_un_ordine">
<span class="item-number">8.1</span> <span class="item-number">9.1</span>
<span class="item-title">Completare (Acquisire) un Ordine</span> <span class="item-title">Completare (Acquisire) un Ordine</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_annullare_una_transazione"> <a href="#_annullare_una_transazione">
<span class="item-number">8.2</span> <span class="item-number">9.2</span>
<span class="item-title">Annullare una transazione</span> <span class="item-title">Annullare una transazione</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_rimborso_di_una_transazione"> <a href="#_rimborso_di_una_transazione">
<span class="item-number">8.3</span> <span class="item-number">9.3</span>
<span class="item-title">Rimborso di una Transazione</span> <span class="item-title">Rimborso di una Transazione</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_ordini_in_attesa"> <a href="#_ordini_in_attesa">
<span class="item-number">8.4</span> <span class="item-number">9.4</span>
<span class="item-title">Ordini in Attesa</span> <span class="item-title">Ordini in Attesa</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_limitazioni_della_sincronizzazione_tra_wallee_e_shopware"> <a href="#_limitazioni_della_sincronizzazione_tra_wallee_e_shopware">
<span class="item-number">8.5</span> <span class="item-number">9.5</span>
<span class="item-title">Limitazioni della Sincronizzazione tra Wallee e Shopware</span> <span class="item-title">Limitazioni della Sincronizzazione tra Wallee e Shopware</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_tokenization"> <a href="#_tokenization">
<span class="item-number">8.6</span> <span class="item-number">9.6</span>
<span class="item-title">Tokenization</span> <span class="item-title">Tokenization</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_key_features"> <a href="#_key_features">
<span class="item-number">8.7</span> <span class="item-number">9.7</span>
<span class="item-title">Key Features</span> <span class="item-title">Key Features</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_risoluzione_dei_problemi"> <a href="#_risoluzione_dei_problemi">
<span class="item-number">8.8</span> <span class="item-number">9.8</span>
<span class="item-title">Risoluzione dei Problemi</span> <span class="item-title">Risoluzione dei Problemi</span>
</a> </a>
</li> <li class="nav-level-2"> </li> <li class="nav-level-2">
<a href="#_faqs"> <a href="#_faqs">
<span class="item-number">8.9</span> <span class="item-number">9.9</span>
<span class="item-title">FAQs</span> <span class="item-title">FAQs</span>
</a> </a>
</li> </ul> </li> </ul>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_changelog"> <a href="#_changelog">
<span class="item-number">9</span> <span class="item-number">10</span>
<span class="item-title">Changelog</span> <span class="item-title">Changelog</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_contribuzione"> <a href="#_contribuzione">
<span class="item-number">10</span> <span class="item-number">11</span>
<span class="item-title">Contribuzione</span> <span class="item-title">Contribuzione</span>
</a> </a>
</li> <li class="nav-level-1"> </li> <li class="nav-level-1">
<a href="#_support"> <a href="#_support">
<span class="item-number">11</span> <span class="item-number">12</span>
<span class="item-title">Support</span> <span class="item-title">Support</span>
</a> </a>
</li> </ul> </li> </ul>
BIN
View File
Binary file not shown.
@@ -251,9 +251,9 @@ class PaymentMethodConfigurationService {
{ {
$data = []; $data = [];
$paymentMethodData = []; $paymentMethodData = [];
$salesChannelPaymentMethodData = [];
$criteria = (new Criteria())->addFilter(new EqualsFilter('state', 'ACTIVE')); $criteria = (new Criteria())->addFilter(new EqualsFilter('state', 'ACTIVE'))
->addFilter(new EqualsFilter('spaceId', $this->getSpaceId()));
/** /**
* @var $vRPaymentPMConfigurationRepository * @var $vRPaymentPMConfigurationRepository
@@ -276,7 +276,7 @@ class PaymentMethodConfigurationService {
]; ];
$paymentMethodData[] = [ $paymentMethodData[] = [
'id' => $paymentMethodConfigurationEntity->getId(), 'id' => $paymentMethodConfigurationEntity->getPaymentMethodId(),
'active' => false, 'active' => false,
]; ];
} }
@@ -349,35 +349,68 @@ class PaymentMethodConfigurationService {
*/ */
foreach ($paymentMethodConfigurations as $paymentMethodConfiguration) { foreach ($paymentMethodConfigurations as $paymentMethodConfiguration) {
$paymentMethodConfigurationEntity = $this->getPaymentMethodConfigurationEntity( $entity = $this->getPaymentMethodConfigurationEntity(
$paymentMethodConfiguration->getSpaceId(), $paymentMethodConfiguration->getSpaceId(),
$paymentMethodConfiguration->getId(), $paymentMethodConfiguration->getId(),
$context $context
); );
$id = is_null($paymentMethodConfigurationEntity) ? Uuid::randomHex() : $paymentMethodConfigurationEntity->getId();
$configId = $entity ? $entity->getId() : Uuid::randomHex();
$technicalName = $paymentMethodConfiguration->getName();
$paymentMethodId = $this->getOrCreatePaymentMethodId(
$technicalName,
VRPaymentPaymentHandler::class,
$context
);
$data = [ $data = [
'id' => $id, 'id' => $configId,
'paymentMethodConfigurationId' => $paymentMethodConfiguration->getId(), 'paymentMethodConfigurationId' => $paymentMethodConfiguration->getId(),
'paymentMethodId' => $id, 'paymentMethodId' => $paymentMethodId,
'data' => json_decode(strval($paymentMethodConfiguration), true), 'data' => json_decode(strval($paymentMethodConfiguration), true),
'sortOrder' => $paymentMethodConfiguration->getSortOrder(), 'sortOrder' => $paymentMethodConfiguration->getSortOrder(),
'spaceId' => $paymentMethodConfiguration->getSpaceId(), 'spaceId' => $paymentMethodConfiguration->getSpaceId(),
'state' => CreationEntityState::ACTIVE, 'state' => CreationEntityState::ACTIVE,
]; ];
$this->upsertPaymentMethod($id, $paymentMethodConfiguration, $context);
try {
$this->container->get(PaymentMethodConfigurationEntityDefinition::ENTITY_NAME . '.repository')->upsert([$data], $context);
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), [$e->getTraceAsString()]);
}
try {
$this->upsertPaymentMethod($paymentMethodId, $paymentMethodConfiguration, $context);
$this->container
->get(PaymentMethodConfigurationEntityDefinition::ENTITY_NAME . '.repository')
->upsert([$data], $context);
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), [$e->getTraceAsString()]);
}
} }
} }
private function getOrCreatePaymentMethodId(string $technicalName, string $handlerIdentifier, Context $context): string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('technicalName', $technicalName));
$criteria->setLimit(1);
$existing = $this->paymentMethodRepository->search($criteria, $context)->first();
if ($existing !== null) {
return $existing->getId();
}
$paymentMethodId = Uuid::randomHex();
$this->paymentMethodRepository->upsert([[
'id' => $paymentMethodId,
'handlerIdentifier' => $handlerIdentifier,
'technicalName' => $technicalName,
'name' => $technicalName,
'active' => false,
]], $context);
return $paymentMethodId;
}
/** /**
* Fetch active merchant payment methods from VRPayment API * Fetch active merchant payment methods from VRPayment API
* *
@@ -479,38 +512,38 @@ class PaymentMethodConfigurationService {
* @throws \VRPayment\Sdk\VersioningException * @throws \VRPayment\Sdk\VersioningException
*/ */
protected function upsertPaymentMethod( protected function upsertPaymentMethod(
string $id, string $id,
PaymentMethodConfiguration $paymentMethodConfiguration, PaymentMethodConfiguration $paymentMethodConfiguration,
Context $context Context $context
): void ): void {
{
/** @var PluginIdProvider $pluginIdProvider */ /** @var PluginIdProvider $pluginIdProvider */
$pluginIdProvider = $this->container->get(PluginIdProvider::class); $pluginIdProvider = $this->container->get(PluginIdProvider::class);
$pluginId = $pluginIdProvider->getPluginIdByBaseClass( $pluginId = $pluginIdProvider->getPluginIdByBaseClass(
VRPaymentPayment::class, VRPaymentPayment::class,
$context $context
); );
$data = [ $data = [
'id' => $id, 'id' => $id,
'handlerIdentifier' => VRPaymentPaymentHandler::class, 'handlerIdentifier' => VRPaymentPaymentHandler::class,
'pluginId' => $pluginId, 'pluginId' => $pluginId,
'position' => $paymentMethodConfiguration->getSortOrder() - 100, 'position' => $paymentMethodConfiguration->getSortOrder() - 100,
'afterOrderEnabled' => true, 'afterOrderEnabled' => true,
'active' => true, 'active' => true,
'translations' => $this->getPaymentMethodConfigurationTranslation($paymentMethodConfiguration, $context), 'translations' => $this->getPaymentMethodConfigurationTranslation($paymentMethodConfiguration, $context),
'technicalName' => $paymentMethodConfiguration->getName(),
]; ];
$data['mediaId'] = $this->upsertMedia($id, $paymentMethodConfiguration, $context); $mediaId = $this->upsertMedia($id, $paymentMethodConfiguration, $context);
if ($mediaId) {
$data = array_filter($data); $data['mediaId'] = $mediaId;
}
try {
$this->paymentMethodRepository->upsert([$data], $context);
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), [$e->getTraceAsString()]);
}
try {
$this->paymentMethodRepository->upsert([$data], $context);
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), [$e->getTraceAsString()]);
}
} }
/** /**
@@ -612,46 +645,58 @@ class PaymentMethodConfigurationService {
* *
* @return string|null * @return string|null
*/ */
/**
* Upload or update Payment Method icons
*/
protected function upsertMedia(string $id, PaymentMethodConfiguration $paymentMethodConfiguration, Context $context): ?string protected function upsertMedia(string $id, PaymentMethodConfiguration $paymentMethodConfiguration, Context $context): ?string
{ {
try { try {
$existingRecord = $this->getMediaDefaultFolderForPaymentMethod($paymentMethodConfiguration, $context); $folderKey = 'payment_method_' . $paymentMethodConfiguration->getId();
if ($existingRecord->count() > 0) { // Check existing default folder
$id = $existingRecord->first()->getId(); $criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('entity', $folderKey));
$existingFolder = $this->mediaDefaultFolderRepository->search($criteria, $context);
$folderId = $id;
if ($existingFolder->count() > 0) {
$folderId = $existingFolder->first()->getId();
} }
// Ensure default folder
$this->mediaDefaultFolderRepository->upsert([ $this->mediaDefaultFolderRepository->upsert([
[ [
'id' => $id, 'id' => $folderId,
'associationFields' => [], 'associationFields' => [],
'entity' => 'payment_method_' . $paymentMethodConfiguration->getId(), 'entity' => $folderKey,
], ],
], $context); ], $context);
// Ensure media folder
$this->mediaFolderRepository->upsert([ $this->mediaFolderRepository->upsert([
[ [
'id' => $id, 'id' => $folderId,
'defaultFolderId' => $id, 'defaultFolderId' => $folderId,
'name' => $paymentMethodConfiguration->getName(), 'name' => $paymentMethodConfiguration->getName(),
'useParentConfiguration' => false, 'useParentConfiguration' => false,
'configuration' => [], 'configuration' => [],
], ],
], $context); ], $context);
/** // Media insert/update
* @var \Shopware\Core\Content\Media\MediaDefinition
*/
$mediaDefinition = $this->container->get(MediaDefinition::class); $mediaDefinition = $this->container->get(MediaDefinition::class);
$this->mediaSerializer->setRegistry($this->serializerRegistry); $this->mediaSerializer->setRegistry($this->serializerRegistry);
$data = [ $data = [
'id' => $id, 'id' => $id,
'title' => $paymentMethodConfiguration->getName(), 'title' => $paymentMethodConfiguration->getName(),
'url' => $paymentMethodConfiguration->getResolvedImageUrl(), 'url' => $paymentMethodConfiguration->getResolvedImageUrl(),
'mediaFolderId' => $id, 'mediaFolderId' => $folderId,
]; ];
$data = $this->mediaSerializer->deserialize(new Config([], [], []), $mediaDefinition, $data); $data = $this->mediaSerializer->deserialize(new Config([], [], []), $mediaDefinition, $data);
$this->mediaRepository->upsert([$data], $context); $this->mediaRepository->upsert([$data], $context);
return $id; return $id;
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->critical($e->getMessage(), [$e->getTraceAsString()]); $this->logger->critical($e->getMessage(), [$e->getTraceAsString()]);
@@ -13,7 +13,9 @@ use Symfony\Component\{
}; };
use VRPaymentPayment\Core\{ use VRPaymentPayment\Core\{
Api\Refund\Service\RefundService, Api\Refund\Service\RefundService,
Settings\Service\SettingsService Api\Transaction\Service\TransactionService,
Settings\Service\SettingsService,
Util\Exception\RefundNotSupportedException
}; };
/** /**
@@ -41,16 +43,23 @@ class RefundController extends AbstractController
*/ */
protected $logger; protected $logger;
/**
* @var \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService
*/
protected $transactionService;
/** /**
* RefundController constructor. * RefundController constructor.
* *
* @param \VRPaymentPayment\Core\Api\Refund\Service\RefundService $refundService * @param \VRPaymentPayment\Core\Api\Refund\Service\RefundService $refundService
* @param \VRPaymentPayment\Core\Settings\Service\SettingsService $settingsService * @param \VRPaymentPayment\Core\Settings\Service\SettingsService $settingsService
* @param \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService $transactionService
*/ */
public function __construct(RefundService $refundService, SettingsService $settingsService) public function __construct(RefundService $refundService, SettingsService $settingsService, TransactionService $transactionService)
{ {
$this->settingsService = $settingsService; $this->settingsService = $settingsService;
$this->refundService = $refundService; $this->refundService = $refundService;
$this->transactionService = $transactionService;
} }
/** /**
@@ -82,11 +91,28 @@ class RefundController extends AbstractController
$quantity = (int)$request->request->get('quantity'); $quantity = (int)$request->request->get('quantity');
$lineItemId = $request->request->get('lineItemId'); $lineItemId = $request->request->get('lineItemId');
if ($quantity === null || $quantity <= 0) {
return new Response('refundQuantityZero', Response::HTTP_BAD_REQUEST);
}
$settings = $this->settingsService->getSettings($salesChannelId); $settings = $this->settingsService->getSettings($salesChannelId);
$apiClient = $settings->getApiClient(); $apiClient = $settings->getApiClient();
$transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId); $transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId);
$refund = $this->refundService->create($transaction, $context, $lineItemId, $quantity);
$maxQuantity = $this->refundService->getMaxRefundableQuantity($transaction, $context, $lineItemId);
if ($quantity > $maxQuantity) {
return new Response('refundExceedsQuantity', Response::HTTP_BAD_REQUEST);
}
try {
$refund = $this->refundService->create($transaction, $context, $lineItemId, $quantity);
} catch (RefundNotSupportedException $exception) {
$this->logger->info('Payment method does not support online refunds for transaction: ' . $transactionId);
return new Response('methodDoesNotSupportRefund', Response::HTTP_BAD_REQUEST);
}
if ($refund === null) { if ($refund === null) {
return new Response('Refund was not created. Please check the refund amound or if the item was not refunded before', Response::HTTP_BAD_REQUEST); return new Response('Refund was not created. Please check the refund amound or if the item was not refunded before', Response::HTTP_BAD_REQUEST);
} }
@@ -111,11 +137,33 @@ class RefundController extends AbstractController
$transactionId = $request->request->get('transactionId'); $transactionId = $request->request->get('transactionId');
$refundableAmount = $request->request->get('refundableAmount'); $refundableAmount = $request->request->get('refundableAmount');
if ($refundableAmount === null || $refundableAmount <= 0.0) {
return new Response('refundAmountZero', Response::HTTP_BAD_REQUEST);
}
$settings = $this->settingsService->getSettings($salesChannelId); $settings = $this->settingsService->getSettings($salesChannelId);
$apiClient = $settings->getApiClient(); $apiClient = $settings->getApiClient();
$transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId); $transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId);
$this->refundService->createRefundByAmount($transaction, $refundableAmount, $context);
$completed = (float) $transaction->getCompletedAmount();
$refunded = (float) $transaction->getRefundedAmount();
$maxRefund = round($completed - $refunded, 2);
if ($refundableAmount > $maxRefund) {
return new Response('refundExceedsAmount', Response::HTTP_BAD_REQUEST);
}
try {
$refund = $this->refundService->createRefundByAmount($transaction, $refundableAmount, $context);
} catch (RefundNotSupportedException $exception) {
$this->logger->info('Payment method does not support online refunds for transaction: ' . $transactionId);
return new Response('methodDoesNotSupportRefund', Response::HTTP_BAD_REQUEST);
}
if ($refund === null) {
return new Response(null, Response::HTTP_BAD_REQUEST);
}
return new Response(null, Response::HTTP_NO_CONTENT); return new Response(null, Response::HTTP_NO_CONTENT);
} }
@@ -142,7 +190,13 @@ class RefundController extends AbstractController
$apiClient = $settings->getApiClient(); $apiClient = $settings->getApiClient();
$transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId); $transaction = $apiClient->getTransactionService()->read($settings->getSpaceId(), $transactionId);
$this->refundService->createPartialRefund($transaction, $context, $lineItemId, $refundableAmount);
try {
$refund = $this->refundService->createPartialRefund($transaction, $context, $lineItemId, $refundableAmount);
} catch (RefundNotSupportedException $exception) {
$this->logger->info('Payment method does not support online refunds for transaction: ' . $transactionId);
return new Response('methodDoesNotSupportRefund', Response::HTTP_BAD_REQUEST);
}
return new Response(null, Response::HTTP_NO_CONTENT); return new Response(null, Response::HTTP_NO_CONTENT);
} }
+89 -2
View File
@@ -12,14 +12,20 @@ use Shopware\Core\{
}; };
use VRPayment\Sdk\{ use VRPayment\Sdk\{
Model\Refund, Model\Refund,
Model\Transaction Model\Transaction,
Model\CriteriaOperator,
Model\EntityQueryFilter,
Model\EntityQueryFilterType,
Model\EntityQuery,
ApiException
}; };
use VRPaymentPayment\Core\{ use VRPaymentPayment\Core\{
Api\Refund\Entity\RefundEntity, Api\Refund\Entity\RefundEntity,
Api\Transaction\Entity\TransactionEntity, Api\Transaction\Entity\TransactionEntity,
Api\Transaction\Entity\TransactionEntityDefinition, Api\Transaction\Entity\TransactionEntityDefinition,
Settings\Service\SettingsService, Settings\Service\SettingsService,
Util\Payload\RefundPayload Util\Payload\RefundPayload,
Util\Exception\RefundNotSupportedException
}; };
/** /**
@@ -99,6 +105,12 @@ class RefundService
$this->upsert($refund, $context); $this->upsert($refund, $context);
return $refund; return $refund;
} }
} catch (ApiException $exception) {
$message = $exception->getMessage();
$this->logger->critical($message);
if ($exception->getCode() === 442 && str_contains($message, 'does not support online refunds')) {
throw new RefundNotSupportedException($message, 0, $exception);
}
} catch (\Exception $exception) { } catch (\Exception $exception) {
$this->logger->critical($exception->getMessage()); $this->logger->critical($exception->getMessage());
} }
@@ -134,6 +146,12 @@ class RefundService
$this->upsert($refund, $context); $this->upsert($refund, $context);
return $refund; return $refund;
} }
} catch (ApiException $exception) {
$message = $exception->getMessage();
$this->logger->critical($message);
if ($exception->getCode() === 442 && str_contains($message, 'does not support online refunds')) {
throw new RefundNotSupportedException($message, 0, $exception);
}
} catch (\Exception $exception) { } catch (\Exception $exception) {
$this->logger->critical($exception->getMessage()); $this->logger->critical($exception->getMessage());
} }
@@ -170,6 +188,12 @@ class RefundService
$this->upsert($refund, $context); $this->upsert($refund, $context);
return $refund; return $refund;
} }
} catch (ApiException $exception) {
$message = $exception->getMessage();
$this->logger->critical($message);
if ($exception->getCode() === 442 && str_contains($message, 'does not support online refunds')) {
throw new RefundNotSupportedException($message, 0, $exception);
}
} catch (\Exception $exception) { } catch (\Exception $exception) {
$this->logger->critical($exception->getMessage()); $this->logger->critical($exception->getMessage());
} }
@@ -241,4 +265,67 @@ class RefundService
->first(); ->first();
} }
/**
* Get total refunded quantity for transaction's line item by lineItemId.
*
* @param \VRPayment\Sdk\Model\Transaction $transaction
* @param \Shopware\Core\Framework\Context $context
* @param string $lineItemId
*
* @return int
*/
public function getRefundedQuantity(Transaction $transaction, Context $context, string $lineItemId): int {
$transactionEntity = $this->getTransactionEntityByTransactionId($transaction->getId(), $context);
$settings = $this->settingsService->getSettings($transactionEntity->getSalesChannel()->getId());
$apiClient = $settings->getApiClient();
$entityQueryFilter = (new EntityQueryFilter())
->setType(EntityQueryFilterType::LEAF)
->setOperator(CriteriaOperator::EQUALS)
->setFieldName('transaction.id')
->setValue($transaction->getId());
$query = (new EntityQuery())->setFilter($entityQueryFilter);
$refunds = $apiClient->getRefundService()->search($settings->getSpaceId(), $query);
$refundedQuantity = 0;
foreach ($refunds as $refund) {
foreach ($refund->getReductions() as $reduction) {
if ($reduction->getLineItemUniqueId() === $lineItemId) {
$refundedQuantity += (int) $reduction->getQuantityReduction();
}
}
}
return $refundedQuantity;
}
/**
* Get maximum quantity of available items to refund for line item.
*
* @param \VRPayment\Sdk\Model\Transaction $transaction
* @param \Shopware\Core\Framework\Context $context
* @param string $lineItemId
*
* @return int
*/
public function getMaxRefundableQuantity(Transaction $transaction, Context $context, string $lineItemId): int {
$originalQuantity = 0;
foreach ($transaction->getLineItems() as $lineItem) {
if ($lineItem->getUniqueId() === $lineItemId) {
$originalQuantity = (int) $lineItem->getQuantity();
break;
}
}
$refundedQuantity = $this->getRefundedQuantity($transaction, $context, $lineItemId);
$maxQuantity = $originalQuantity - $refundedQuantity;
return $maxQuantity;
}
} }
@@ -32,7 +32,7 @@ use VRPaymentPayment\Core\Api\Refund\Entity\RefundEntityDefinition;
*/ */
class TransactionEntityDefinition extends EntityDefinition { class TransactionEntityDefinition extends EntityDefinition {
public const ENTITY_NAME = 'vrpayment_transaction'; public const ENTITY_NAME = 'vrpayment_transaction_data';
/** /**
* @return string * @return string
@@ -15,6 +15,7 @@ use Shopware\Core\{
System\SalesChannel\SalesChannelContext System\SalesChannel\SalesChannelContext
}; };
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent; use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use VRPayment\Sdk\{ use VRPayment\Sdk\{
Model\AddressCreate, Model\AddressCreate,
@@ -46,6 +47,9 @@ use VRPaymentPayment\Core\{
Util\Payload\TransactionPayload Util\Payload\TransactionPayload
}; };
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Framework\Struct\ArrayEntity;
/** /**
* Class TransactionService * Class TransactionService
* *
@@ -180,10 +184,19 @@ class TransactionService
$transaction->getOrderTransaction()->getPaymentMethodId(), $transaction->getOrderTransaction()->getPaymentMethodId(),
$transaction->getOrder()->getSalesChannelId() $transaction->getOrder()->getSalesChannelId()
); );
$_SESSION['transactionId'] = null; $salesChannelContext->getContext()->addExtension(
$_SESSION['arrayOfPossibleMethods'] = null; 'checkoutState',
$_SESSION['addressCheck'] = null; new ArrayEntity([
$_SESSION['currencyCheck'] = null; 'transactionId' => null,
'addressHash' => null,
'currency' => null,
])
);
$salesChannelContext->getContext()->addExtension(
'possibleMethods',
new ArrayEntity(['ids' => []])
);
$this->holdDelivery($transaction->getOrder()->getId(), $salesChannelContext->getContext()); $this->holdDelivery($transaction->getOrder()->getId(), $salesChannelContext->getContext());
@@ -478,14 +491,18 @@ class TransactionService
/** /**
* @param SalesChannelContext $salesChannelContext * @param SalesChannelContext $salesChannelContext
* @param CheckoutConfirmPageLoadedEvent|null $event * @param $event
* @return int * @return int
*/ */
public function createPendingTransaction(SalesChannelContext $salesChannelContext, ?CheckoutConfirmPageLoadedEvent $event = null): int
{ public function createPendingTransaction(SalesChannelContext $salesChannelContext, $event = null): int
{
$expiredTransaction = true; $expiredTransaction = true;
$transactionId = $_SESSION['transactionId'] ?? null; $transactionId = $_SESSION['transactionId'] ?? null;
$settings = $this->settingsService->getValidSettings($salesChannelContext->getSalesChannel()->getId()); $settings = $this->settingsService->getValidSettings($salesChannelContext->getSalesChannel()->getId());
if (!$settings) {
throw new \Exception('Space settings not configured');
}
if ($transactionId) { if ($transactionId) {
$transactionService = $settings->getApiClient()->getTransactionService(); $transactionService = $settings->getApiClient()->getTransactionService();
@@ -494,6 +511,7 @@ class TransactionService
TransactionState::DECLINE, TransactionState::DECLINE,
TransactionState::FAILED, TransactionState::FAILED,
TransactionState::VOIDED, TransactionState::VOIDED,
null
]; ];
if (!in_array($pendingTransaction->getState(), $failedStates)) { if (!in_array($pendingTransaction->getState(), $failedStates)) {
$expiredTransaction = false; $expiredTransaction = false;
@@ -567,13 +585,20 @@ class TransactionService
$lineItems = []; $lineItems = [];
if ($event) { if ($event) {
$cartLineItems = $event->getPage()->getCart()->getLineItems()->getElements(); if ($event instanceof CheckoutConfirmPageLoadedEvent) {
foreach ($cartLineItems as $cartLineItem) { $cartLineItems = $event->getPage()->getCart()->getLineItems()->getElements();
if ($cartLineItem->getType() === CustomProductsLineItemTypes::LINE_ITEM_TYPE_CUSTOMIZED_PRODUCTS) { foreach ($cartLineItems as $cartLineItem) {
continue; if ($cartLineItem->getType() === CustomProductsLineItemTypes::LINE_ITEM_TYPE_CUSTOMIZED_PRODUCTS) {
} continue;
$lineItems[] = $this->createTempLineItem($cartLineItem); }
} $lineItems[] = $this->createTempLineItem($cartLineItem);
}
} elseif ($event instanceof AccountEditOrderPageLoadedEvent) {
$order = $event->getPage()->getOrder();
foreach ($order->getLineItems() as $orderLineItem) {
$lineItems[] = $this->createTempLineItem($orderLineItem);
}
}
} }
$customerId = ""; $customerId = "";
@@ -731,16 +756,28 @@ class TransactionService
* @param LineItem $productData * @param LineItem $productData
* @return LineItemCreate * @return LineItemCreate
*/ */
private function createTempLineItem(LineItem $productData): LineItemCreate private function createTempLineItem($productData): LineItemCreate
{ {
$lineItem = new LineItemCreate(); $lineItem = new LineItemCreate();
$lineItem->setName($productData->getLabel());
$lineItem->setUniqueId($productData->getId());
$lineItem->setSku($productData->getId());
$lineItem->setQuantity($productData->getQuantity());
$lineItem->setAmountIncludingTax($productData->getPrice()->getUnitPrice());
$lineItem->setType(LineItemType::PRODUCT);
return $lineItem; if ($productData instanceof LineItem) {
} $lineItem->setName($productData->getLabel());
$lineItem->setUniqueId($productData->getId());
$lineItem->setSku($productData->getReferencedId() ?? $productData->getId());
$lineItem->setQuantity($productData->getQuantity());
$lineItem->setAmountIncludingTax($productData->getPrice()->getUnitPrice());
} elseif ($productData instanceof OrderLineItemEntity) {
$lineItem->setName($productData->getLabel());
$lineItem->setUniqueId($productData->getId());
$lineItem->setSku($productData->getProductId() ?? $productData->getIdentifier() ?? $productData->getId());
$lineItem->setQuantity($productData->getQuantity());
$lineItem->setAmountIncludingTax($productData->getUnitPrice());
} else {
throw new \InvalidArgumentException('Unsupported line item type: ' . get_class($productData));
}
$lineItem->setType(LineItemType::PRODUCT);
return $lineItem;
}
} }
@@ -226,6 +226,14 @@ class WebHookController extends AbstractController {
$this->settings = $this->settingsService->getSettings($salesChannelId); $this->settings = $this->settingsService->getSettings($salesChannelId);
$signature = $request->server->get('HTTP_X_SIGNATURE'); $signature = $request->server->get('HTTP_X_SIGNATURE');
$requestJson = json_decode($request->getContent(), true); $requestJson = json_decode($request->getContent(), true);
if ($requestJson['eventId'] == null && $requestJson['entityId'] == null && $requestJson['listenerEntityId'] == null && $requestJson['listenerEntityId'] == null && $requestJson['listenerEntityTechnicalName'] == null && $requestJson['spaceId'] == null) {
throw new \InvalidArgumentException('Empty webhook');
}
if (!$this->settings->getSpaceId() || !$this->settings->getUserId() || !$this->settings->getApplicationKey()) {
throw new \InvalidArgumentException('Not correct webhook configuration for salesChannelId: ' . $salesChannelId . ' Debug: ' . var_dump($requestJson));
}
$apiClient = $this->settings->getApiClient(); $apiClient = $this->settings->getApiClient();
$callBackData->assign($requestJson); $callBackData->assign($requestJson);
@@ -2,8 +2,12 @@
namespace VRPaymentPayment\Core\Storefront\Checkout\Controller; namespace VRPaymentPayment\Core\Storefront\Checkout\Controller;
use Psr\Log\LoggerInterface; use Psr\{
Log\LoggerInterface,
Cache\CacheItemPoolInterface
};
use Shopware\Core\{ use Shopware\Core\{
Checkout\Payment\PaymentException,
Checkout\Cart\Cart, Checkout\Cart\Cart,
Checkout\Cart\CartException, Checkout\Cart\CartException,
Checkout\Cart\LineItemFactoryRegistry, Checkout\Cart\LineItemFactoryRegistry,
@@ -35,9 +39,13 @@ use Shopware\Storefront\{
use Symfony\Component\{ use Symfony\Component\{
HttpFoundation\Request, HttpFoundation\Request,
HttpFoundation\Response, HttpFoundation\Response,
HttpFoundation\RedirectResponse,
Routing\Attribute\Route, Routing\Attribute\Route,
Routing\Generator\UrlGeneratorInterface Routing\Generator\UrlGeneratorInterface,
Cache\Adapter\FilesystemAdapter,
DependencyInjection\ParameterBag\ParameterBagInterface
}; };
use Symfony\Contracts\Cache\ItemInterface;
use VRPayment\Sdk\{ use VRPayment\Sdk\{
Model\Transaction, Model\Transaction,
Model\TransactionState Model\TransactionState
@@ -51,7 +59,6 @@ use VRPaymentPayment\Core\{
Util\Payload\TransactionPayload Util\Payload\TransactionPayload
}; };
/** /**
* Class CheckoutController * Class CheckoutController
* *
@@ -114,6 +121,11 @@ class CheckoutController extends StorefrontController {
*/ */
private $orderRoute; private $orderRoute;
/**
* @var \Psr\Cache\CacheItemPoolInterface
*/
private CacheItemPoolInterface $cache;
/** /**
* PaymentController constructor. * PaymentController constructor.
* *
@@ -124,7 +136,8 @@ class CheckoutController extends StorefrontController {
* @param \Shopware\Storefront\Page\GenericPageLoaderInterface $genericLoader * @param \Shopware\Storefront\Page\GenericPageLoaderInterface $genericLoader
* @param \Shopware\Core\Checkout\Order\SalesChannel\AbstractOrderRoute $orderRoute * @param \Shopware\Core\Checkout\Order\SalesChannel\AbstractOrderRoute $orderRoute
* @param \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler $orderTransactionStateHandler * @param \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler $orderTransactionStateHandler
* @param \Shopware\Core\System\StateMachine\StateMachineRegistry $stateMachineRegistry * @param \Shopware\Core\System\StateMachine\StateMachineRegistry $stateMachineRegistry
* @param Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $params
*/ */
public function __construct( public function __construct(
LineItemFactoryRegistry $lineItemFactoryRegistry, LineItemFactoryRegistry $lineItemFactoryRegistry,
@@ -134,7 +147,8 @@ class CheckoutController extends StorefrontController {
GenericPageLoaderInterface $genericLoader, GenericPageLoaderInterface $genericLoader,
AbstractOrderRoute $orderRoute, AbstractOrderRoute $orderRoute,
OrderTransactionStateHandler $orderTransactionStateHandler, OrderTransactionStateHandler $orderTransactionStateHandler,
StateMachineRegistry $stateMachineRegistry StateMachineRegistry $stateMachineRegistry,
ParameterBagInterface $params
) )
{ {
$this->cartService = $cartService; $this->cartService = $cartService;
@@ -145,6 +159,7 @@ class CheckoutController extends StorefrontController {
$this->orderRoute = $orderRoute; $this->orderRoute = $orderRoute;
$this->orderTransactionStateHandler = $orderTransactionStateHandler; $this->orderTransactionStateHandler = $orderTransactionStateHandler;
$this->stateMachineRegistry = $stateMachineRegistry; $this->stateMachineRegistry = $stateMachineRegistry;
$this->cache = new FilesystemAdapter('vrpayment', 0, rtrim($params->get('kernel.cache_dir'), '/') . '/vrpayment-cache');
} }
/** /**
@@ -386,6 +401,32 @@ class CheckoutController extends StorefrontController {
if($orderEntity->getSalesChannelId() !== $salesChannelContext->getSalesChannelId()) { if($orderEntity->getSalesChannelId() !== $salesChannelContext->getSalesChannelId()) {
$this->settings = $this->settingsService->getSettings($orderEntity->getSalesChannelId()); $this->settings = $this->settingsService->getSettings($orderEntity->getSalesChannelId());
$trans = $this->getTransaction($orderId, $salesChannelContext->getContext()); $trans = $this->getTransaction($orderId, $salesChannelContext->getContext());
// Adoption in case of duplicate requests
// Get order specific value from cache
$cacheKey = 'vrpayment_recreate_order_' . $orderId;
$isFound = $this->cache->get($cacheKey, function (ItemInterface $item) {
$item->expiresAfter(10);
return false;
});
// If value is found in cache - send user directly to successful checkout confirmation page for unpaid transactions
if ($isFound === true && in_array($trans->getState(), [TransactionState::FAILED])) {
$unpaidUrl = $this->getUnpaidUrlFromToken($trans->getSuccessUrl())
?? $this->buildUnpaidUrl($orderEntity->getSalesChannelId(), $salesChannelContext, $orderId);
if ($unpaidUrl) {
return new RedirectResponse(
$unpaidUrl . (parse_url($unpaidUrl, \PHP_URL_QUERY) ? '&' : '?') . 'error-code=' . PaymentException::PAYMENT_CUSTOMER_CANCELED_EXTERNAL
);
}
}
// Cache order specific value for some time on first request
$this->cache->delete($cacheKey);
$this->cache->get($cacheKey, function (ItemInterface $item) {
$item->expiresAfter(10);
return true;
});
return $this->redirect($trans->getSuccessUrl()); return $this->redirect($trans->getSuccessUrl());
} }
// End Adoption for Headless Storefronts // End Adoption for Headless Storefronts
@@ -459,6 +500,74 @@ class CheckoutController extends StorefrontController {
return $this->redirectToRoute('frontend.checkout.confirm.page'); return $this->redirectToRoute('frontend.checkout.confirm.page');
} }
/**
* Tries to return successful checkout confirmation url for unpaid transactions.
*
* It achieves that by getting payment token from successUrl, parsing and decoding
* it, and finally reading the claims.
*
* @param string $successUrl
*
* @return string|null
*/
private function getUnpaidUrlFromToken(string $successUrl): ?string {
$query = [];
parse_str((string) parse_url($successUrl, PHP_URL_QUERY), $query);
$jwt = $query['_sw_payment_token'] ?? null;
if (!$jwt) {
return null;
}
$data = explode('.', $jwt, 3);
if (count($data) !== 3) {
return null;
}
[, $c, ] = $data;
try {
$urlSafeData = strtr($c, '-_', '+/');
$paddedData = str_pad($urlSafeData, \strlen($urlSafeData) % 4, '=');
$decoded = base64_decode($paddedData, true);
if (!$decoded) {
return null;
}
$claims = json_decode(json: $decoded, associative: true, flags: JSON_THROW_ON_ERROR);
$unpaidUrl = $claims['eul'] ?? null;
return $unpaidUrl;
} catch (\Throwable $e) {
$this->logger->warning("CheckoutController::getUnpaidUrlFromToken - JWT parse failed: {errorMessage}", [
'errorMessage' => $e->getMessage(),
]);
return null;
}
}
/**
* Tries to return successful checkout confirmation url for unpaid transactions.
*
* It achieves that by fetching headless storefront's base url,
* and building custom url.
*
* @param string $salesChannelId
* @param SalesChannelContext $salesChannelContext
* @param string $orderId
*
* @return string|null
*/
private function buildUnpaidUrl(string $salesChannelId, SalesChannelContext $salesChannelContext, string $orderId): ?string {
$salesChannelDomainRepo = $this->container->get('sales_channel_domain.repository');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('salesChannelId', $salesChannelId))->setLimit(10);
$domain = $salesChannelDomainRepo->search($criteria, $salesChannelContext->getContext())->first();
if(!$domain) {
return null;
}
$baseUrl = rtrim($domain->getUrl(), '/');
return sprintf('%s/checkout/success/%s/unpaid', $baseUrl, $orderId);
}
/** /**
* @param OrderLineItemCollection $orderItems * @param OrderLineItemCollection $orderItems
* *
@@ -4,33 +4,42 @@ namespace VRPaymentPayment\Core\Storefront\Checkout\Subscriber;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shopware\Core\{Checkout\Order\Aggregate\OrderTransaction\OrderTransactionCollection, use Shopware\Core\{Checkout\Order\Aggregate\OrderTransaction\OrderTransactionCollection,
Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStates, Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStates,
Checkout\Order\OrderEntity, Checkout\Order\OrderEntity,
Content\MailTemplate\Service\Event\MailBeforeValidateEvent}; Content\MailTemplate\Service\Event\MailBeforeValidateEvent};
use Shopware\Core\Checkout\Payment\PaymentMethodCollection;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
use Shopware\Storefront\Page\Account\PaymentMethod\AccountPaymentMethodPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent; use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use VRPaymentPayment\Core\{Api\Transaction\Service\OrderMailService, use VRPaymentPayment\Core\{Api\Transaction\Service\TransactionService,
Api\Transaction\Service\TransactionService, Checkout\PaymentHandler\VRPaymentPaymentHandler,
Checkout\PaymentHandler\VRPaymentPaymentHandler, Settings\Service\SettingsService,
Settings\Service\SettingsService, Settings\Struct\Settings,
Settings\Struct\Settings, Util\PaymentMethodUtil};
Util\PaymentMethodUtil};
use VRPaymentPayment\Core\Api\PaymentMethodConfiguration\Service\PaymentMethodConfigurationService; use VRPaymentPayment\Core\Api\PaymentMethodConfiguration\Service\PaymentMethodConfigurationService;
use VRPaymentPayment\Sdk\{Model\AddressCreate, use VRPaymentPayment\Sdk\{Model\AddressCreate,
Model\ChargeAttempt, Model\ChargeAttempt,
Model\CreationEntityState, Model\CreationEntityState,
Model\CriteriaOperator, Model\CriteriaOperator,
Model\EntityQuery, Model\EntityQuery,
Model\EntityQueryFilter, Model\EntityQueryFilter,
Model\EntityQueryFilterType, Model\EntityQueryFilterType,
Model\LineItemAttributeCreate, Model\LineItemAttributeCreate,
Model\LineItemCreate, Model\LineItemCreate,
Model\LineItemType, Model\LineItemType,
Model\TaxCreate, Model\TaxCreate,
Model\Transaction, Model\Transaction,
Model\TransactionCreate, Model\TransactionCreate,
Model\TransactionPending}; Model\TransactionPending};
use Shopware\Core\Framework\Struct\ArrayEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
/** /**
* Class CheckoutSubscriber * Class CheckoutSubscriber
@@ -65,6 +74,9 @@ class CheckoutSubscriber implements EventSubscriberInterface
*/ */
private $paymentMethodUtil; private $paymentMethodUtil;
/** @var EntityRepository */
private EntityRepository $paymentMethodRepository;
/** /**
* CheckoutSubscriber constructor. * CheckoutSubscriber constructor.
* *
@@ -73,12 +85,13 @@ class CheckoutSubscriber implements EventSubscriberInterface
* @param \VRPaymentPayment\Core\Settings\Service\SettingsService $settingsService * @param \VRPaymentPayment\Core\Settings\Service\SettingsService $settingsService
* @param \VRPaymentPayment\Core\Util\PaymentMethodUtil $paymentMethodUtil * @param \VRPaymentPayment\Core\Util\PaymentMethodUtil $paymentMethodUtil
*/ */
public function __construct(PaymentMethodConfigurationService $paymentMethodConfigurationService, TransactionService $transactionService, SettingsService $settingsService, PaymentMethodUtil $paymentMethodUtil) public function __construct(PaymentMethodConfigurationService $paymentMethodConfigurationService, TransactionService $transactionService, SettingsService $settingsService, PaymentMethodUtil $paymentMethodUtil, EntityRepository $paymentMethodRepository)
{ {
$this->paymentMethodConfigurationService = $paymentMethodConfigurationService; $this->paymentMethodConfigurationService = $paymentMethodConfigurationService;
$this->transactionService = $transactionService; $this->transactionService = $transactionService;
$this->settingsService = $settingsService; $this->settingsService = $settingsService;
$this->paymentMethodUtil = $paymentMethodUtil; $this->paymentMethodUtil = $paymentMethodUtil;
$this->paymentMethodRepository = $paymentMethodRepository;
} }
/** /**
@@ -99,8 +112,10 @@ class CheckoutSubscriber implements EventSubscriberInterface
public static function getSubscribedEvents(): array public static function getSubscribedEvents(): array
{ {
return [ return [
CheckoutConfirmPageLoadedEvent::class => ['onConfirmPageLoaded', 1], CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmLoaded',
MailBeforeValidateEvent::class => ['onMailBeforeValidate', 1], AccountEditOrderPageLoadedEvent::class => 'onAccountOrderEditLoaded',
AccountPaymentMethodPageLoadedEvent::class => 'onAccountPaymentMethodLoaded',
MailBeforeValidateEvent::class => ['onMailBeforeValidate', 1],
]; ];
} }
@@ -152,109 +167,233 @@ class CheckoutSubscriber implements EventSubscriberInterface
} }
} }
/** /**
* @param \Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent $event * @param CheckoutConfirmPageLoadedEvent $event
*/ * @return void
public function onConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void */
{ public function onCheckoutConfirmLoaded(CheckoutConfirmPageLoadedEvent $event): void
try { {
$salesChannelContext = $event->getSalesChannelContext(); try {
$settings = $this->settingsService->getValidSettings($salesChannelContext->getSalesChannel()->getId()); $salesChannelContext = $event->getSalesChannelContext();
if (is_null($settings)) { $settings = $this->settingsService->getValidSettings($salesChannelContext->getSalesChannel()->getId());
$this->logger->notice('Removing payment methods because settings are invalid'); if (is_null($settings)) {
$this->removeVRPaymentPaymentMethodFromConfirmPage($event); $this->logger->notice('Removing payment methods because settings are invalid');
} $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
}
$createdTransactionId = $this->transactionService->createPendingTransaction($salesChannelContext, $event); $createdTransactionId = $this->transactionService->createPendingTransaction($salesChannelContext, $event);
$this->updateTempTransactionIfNeeded($salesChannelContext, $createdTransactionId); $this->updateTempTransactionIfNeeded($salesChannelContext, $createdTransactionId);
$this->getAvailablePaymentMethods($settings, $createdTransactionId); $this->getAvailablePaymentMethods($settings, $createdTransactionId, $salesChannelContext);
$this->setPossiblePaymentMethods($settings->getSpaceId(), $event); $this->setPossiblePaymentMethods($settings->getSpaceId(), $event);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
$this->removeVRPaymentPaymentMethodFromConfirmPage($event); $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
} }
} }
/** /**
* @param \Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent $event * @param AccountEditOrderPageLoadedEvent $event
*/ * @return void
private function removeVRPaymentPaymentMethodFromConfirmPage(CheckoutConfirmPageLoadedEvent $event): void */
{ public function onAccountOrderEditLoaded(AccountEditOrderPageLoadedEvent $event): void
$paymentMethodCollection = $event->getPage()->getPaymentMethods(); {
$paymentMethodIds = $this->paymentMethodUtil->getVRPaymentPaymentMethodIds($event->getContext()); try {
foreach ($paymentMethodIds as $paymentMethodId) { $this->handlePaymentMethodFiltering($event);
$paymentMethodCollection->remove($paymentMethodId); } catch (\Throwable $e) {
} $this->logger->error($e->getMessage());
} $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
}
}
/** /**
* @param Settings $settings * @param AccountPaymentMethodPageLoadedEvent $event
* @param int $createdTransactionId * @return void
* @return void */
*/ public function onAccountPaymentMethodLoaded(AccountPaymentMethodPageLoadedEvent $event): void
private function getAvailablePaymentMethods(Settings $settings, int $createdTransactionId): void {
{ try {
$transactionService = $settings->getApiClient()->getTransactionService(); $this->handlePaymentMethodFiltering($event);
$possiblePaymentMethods = $transactionService->fetchPaymentMethods( } catch (\Throwable $e) {
$settings->getSpaceId(), $this->logger->error($e->getMessage());
$createdTransactionId, $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
$settings->getIntegration() }
); }
$arrayOfPossibleMethods = [];
foreach ($possiblePaymentMethods as $possiblePaymentMethod) {
$arrayOfPossibleMethods[] = $possiblePaymentMethod->getid();
}
$_SESSION['arrayOfPossibleMethods'] = $arrayOfPossibleMethods;
}
/** /**
* @param int $spaceId * @param \Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent $event
* @param CheckoutConfirmPageLoadedEvent $event */
* @return void public function onConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event): void
*/ {
private function setPossiblePaymentMethods(int $spaceId, CheckoutConfirmPageLoadedEvent $event): void try {
{ $this->handlePaymentMethodFiltering($event);
$localPaymentMethods = []; } catch (\Throwable $e) {
$paymentMethodConfigurations = $this->paymentMethodConfigurationService->getAllPaymentMethodConfigurations($spaceId, $event->getSalesChannelContext()->getContext()); $this->logger->error($e->getMessage());
foreach ($paymentMethodConfigurations as $paymentMethodConfiguration) { $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
$localPaymentMethods[$paymentMethodConfiguration->getId()] = $paymentMethodConfiguration->getPaymentMethodConfigurationId(); }
} }
$paymentMethodCollection = $event->getPage()->getPaymentMethods(); /**
foreach ($paymentMethodCollection as $paymentMethodCollectionItem) { * @param $event
$isVRPaymentPM = VRPaymentPaymentHandler::class == $paymentMethodCollectionItem->getHandlerIdentifier(); * @return void
if (!$isVRPaymentPM) { */
continue; private function handlePaymentMethodFiltering($event): void
} {
$salesChannelContext = $event->getSalesChannelContext();
$settings = $this->settingsService->getValidSettings($salesChannelContext->getSalesChannel()->getId());
$paymentMethodConfigurationId = $localPaymentMethods[$paymentMethodCollectionItem->getId()]; if (is_null($settings)) {
if (!\in_array($paymentMethodConfigurationId, $_SESSION['arrayOfPossibleMethods'])) { $this->logger->notice('Removing payment methods because settings are invalid');
$paymentMethodCollection->remove($paymentMethodCollectionItem->getId()); $this->removeVRPaymentPaymentMethodFromConfirmPage($event);
} return;
} }
}
/** $createdTransactionId = $this->transactionService->createPendingTransaction($salesChannelContext, $event);
* @param SalesChannelContext $salesChannelContext $this->updateTempTransactionIfNeeded($salesChannelContext, $createdTransactionId);
* @param int $createdTransactionId
* @return void
*/
private function updateTempTransactionIfNeeded(SalesChannelContext $salesChannelContext, int $createdTransactionId): void
{
$addressCheck = $_SESSION['addressCheck'] ?? null;
$currencyCheck = $_SESSION['currencyCheck'] ?? null;
$customer = $salesChannelContext->getCustomer(); $this->getAvailablePaymentMethods($settings, $createdTransactionId, $salesChannelContext);
$addressHash = md5(json_encode((array)$customer)); $this->setPossiblePaymentMethods($settings->getSpaceId(), $event);
$currency = $salesChannelContext->getCurrency()->getIsoCode(); }
if (($addressCheck && $currencyCheck) && $addressCheck !== $addressHash || $currencyCheck !== $currency) {
if ($createdTransactionId) { /**
$this->transactionService->updateTempTransaction($salesChannelContext, $createdTransactionId); * @param $event
} * @return void
$_SESSION['arrayOfPossibleMethods'] = null; */
$_SESSION['addressCheck'] = $addressHash; private function removeVRPaymentPaymentMethodFromConfirmPage($event): void
$_SESSION['currencyCheck'] = $currency; {
} $paymentMethodCollection = $event->getPage()->getPaymentMethods();
} $paymentMethodIds = $this->paymentMethodUtil->getVRPaymentPaymentMethodIds($event->getContext());
foreach ($paymentMethodIds as $paymentMethodId) {
$paymentMethodCollection->remove($paymentMethodId);
}
}
/**
* @param Settings $settings
* @param int $createdTransactionId
* @return void
*/
private function getAvailablePaymentMethods(Settings $settings, int $createdTransactionId, SalesChannelContext $salesChannelContext): void
{
$transactionService = $settings->getApiClient()->getTransactionService();
$possiblePaymentMethods = $transactionService->fetchPaymentMethods(
$settings->getSpaceId(),
$createdTransactionId,
$settings->getIntegration()
);
$arrayOfPossibleMethods = [];
foreach ($possiblePaymentMethods as $possiblePaymentMethod) {
$arrayOfPossibleMethods[] = $possiblePaymentMethod->getId();
}
$salesChannelContext->getContext()->addExtension(
'possibleMethods',
new ArrayEntity(['ids' => $arrayOfPossibleMethods])
);
}
/**
* @param int $spaceId
* @param CheckoutConfirmPageLoadedEvent $event
* @return void
*/
private function setPossiblePaymentMethods(int $spaceId, $event): void
{
$paymentIds = [];
$paymentMethodCollection = $event->getPage()->getPaymentMethods();
foreach ($paymentMethodCollection as $paymentMethodCollectionItem) {
$isVRPaymentPM = VRPaymentPaymentHandler::class === $paymentMethodCollectionItem->getHandlerIdentifier();
if (!$isVRPaymentPM) {
$paymentIds[] = $paymentMethodCollectionItem->getId();
}
}
$allowedWLMethods = [];
$paymentMethodConfigurations = $this->paymentMethodConfigurationService
->getAllPaymentMethodConfigurations($spaceId, $event->getSalesChannelContext()->getContext());
foreach ($paymentMethodConfigurations as $paymentMethodConfiguration) {
if ($paymentMethodConfiguration->getPaymentMethod() === null) {
continue;
}
$pmId = $paymentMethodConfiguration->getPaymentMethod()->getId();
$pmConfigId = $paymentMethodConfiguration->getPaymentMethodConfigurationId();
$allowedIds = $this->getAllowedPaymentMethodIds($event->getSalesChannelContext());
if ($paymentMethodConfiguration->getSpaceId() === $spaceId
&& \in_array($pmConfigId, $allowedIds, true)) {
$allowedWLMethods[] = $pmId;
}
}
$allPaymentIds = array_unique(array_merge($paymentIds, $allowedWLMethods));
$collection = new PaymentMethodCollection();
if (!empty($allPaymentIds)) {
$criteria = new Criteria($allPaymentIds);
$criteria->addFilter(new EqualsFilter('active', true));
$criteria->addFilter(
new EqualsFilter('salesChannels.id', $event->getSalesChannelContext()->getSalesChannelId())
);
$criteria->addSorting(new FieldSorting('position', FieldSorting::ASCENDING));
$criteria->addAssociation('media');
$result = $this->paymentMethodRepository->search($criteria, $event->getContext());
foreach ($result->getEntities() as $method) {
if (!$collection->has($method->getId())) {
$collection->add($method);
}
}
}
$event->getPage()->setPaymentMethods($collection);
}
/**
* @param SalesChannelContext $salesChannelContext
* @param int $createdTransactionId
* @return void
*/
private function updateTempTransactionIfNeeded(SalesChannelContext $salesChannelContext, int $createdTransactionId): void
{
$ctx = $salesChannelContext->getContext();
/** @var ArrayEntity|null $ext */
$ext = $ctx->getExtension('checkoutState');
$oldAddressHash = $ext instanceof ArrayEntity ? $ext->get('addressHash') : null;
$oldCurrency = $ext instanceof ArrayEntity ? $ext->get('currency') : null;
$customer = $salesChannelContext->getCustomer();
$addressHash = md5(json_encode((array) $customer));
$currency = $salesChannelContext->getCurrency()->getIsoCode();
$needsUpdate = ($oldAddressHash !== $addressHash) || ($oldCurrency !== $currency);
if ($needsUpdate) {
if ($createdTransactionId) {
$this->transactionService->updateTempTransaction($salesChannelContext, $createdTransactionId);
}
$ctx->addExtension('possibleMethods', new ArrayEntity(['ids' => []]));
$ctx->addExtension(
'checkoutState',
new ArrayEntity([
'addressHash' => $addressHash,
'currency' => $currency,
])
);
}
}
/**
* @param SalesChannelContext $salesChannelContext
* @return array
*/
private function getAllowedPaymentMethodIds(SalesChannelContext $salesChannelContext): array
{
$ext = $salesChannelContext->getContext()->getExtension('possibleMethods');
return $ext instanceof ArrayEntity ? ($ext->get('ids') ?? []) : [];
}
} }
+60 -7
View File
@@ -3,6 +3,7 @@
namespace VRPaymentPayment\Core\Util\Analytics; namespace VRPaymentPayment\Core\Util\Analytics;
use VRPayment\Sdk\ApiClient; use VRPayment\Sdk\ApiClient;
use Shopware\Core\Kernel;
/** /**
* Class Analytics * Class Analytics
@@ -19,26 +20,78 @@ class Analytics {
/** /**
* @return array * @return array
*/ */
public static function getDefaultData() public static function getDefaultData(): array
{ {
$shopwareVersion = self::getShopwareVersion();
return [ return [
self::SHOP_SYSTEM => 'shopware', self::SHOP_SYSTEM => 'shopware',
self::SHOP_SYSTEM_VERSION => '6', self::SHOP_SYSTEM_VERSION => $shopwareVersion,
self::SHOP_SYSTEM_AND_VERSION => 'shopware-6', self::SHOP_SYSTEM_AND_VERSION => 'shopware-' . $shopwareVersion,
self::PLUGIN_SYSTEM_VERSION => '6.1.16', self::PLUGIN_SYSTEM_VERSION => '6.2.1',
]; ];
} }
/** /**
* @param \VRPayment\Sdk\ApiClient $apiClient * @param \VRPayment\Sdk\ApiClient $apiClient
*/ */
public static function addHeaders(ApiClient &$apiClient) public static function addHeaders(ApiClient &$apiClient): void
{ {
$data = self::getDefaultData(); $data = self::getDefaultData();
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$apiClient->addDefaultHeader($key, $value); $apiClient->addDefaultHeader($key, $value);
} }
} }
/**
* Reads Shopware version and caches it for performance.
*
* @return string
*/
public static function getShopwareVersion(): string
{
static $cachedVersion = null;
if ($cachedVersion !== null) {
return $cachedVersion;
}
$basePath = dirname(__DIR__, 7);
$installedFile = $basePath . '/vendor/composer/installed.php';
if (is_file($installedFile)) {
$installed = include $installedFile;
$packages = [];
if (isset($installed['versions'])) {
$packages = $installed['versions'];
} elseif (is_array($installed)) {
foreach ($installed as $section) {
if (isset($section['versions'])) {
$packages = $section['versions'];
break;
}
}
}
if (isset($packages['shopware/core']['pretty_version'])) {
return $cachedVersion = ltrim($packages['shopware/core']['pretty_version'], 'v');
}
}
$lockFile = $basePath . '/composer.lock';
if (is_file($lockFile)) {
$data = json_decode((string) file_get_contents($lockFile), true);
if (!empty($data['packages'])) {
foreach ($data['packages'] as $package) {
if (($package['name'] ?? '') === 'shopware/core') {
return $cachedVersion = ltrim($package['version'], 'v');
}
}
}
}
return $cachedVersion = Kernel::SHOPWARE_FALLBACK_VERSION;
}
} }
@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace VRPaymentPayment\Core\Util\Exception;
class RefundNotSupportedException extends \LogicException{
}
+28 -18
View File
@@ -12,6 +12,7 @@ use Shopware\Core\{Checkout\Cart\Tax\Struct\CalculatedTaxCollection,
Framework\DataAbstractionLayer\Search\Criteria, Framework\DataAbstractionLayer\Search\Criteria,
System\SalesChannel\SalesChannelContext System\SalesChannel\SalesChannelContext
}; };
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use VRPayment\Sdk\{Model\AddressCreate, use VRPayment\Sdk\{Model\AddressCreate,
@@ -193,10 +194,16 @@ class TransactionPayload extends AbstractPayload
->setShippingAddress($shippingAddress) ->setShippingAddress($shippingAddress)
->setShippingMethod($transactionData['shipping_method']); ->setShippingMethod($transactionData['shipping_method']);
$paymentConfiguration = $this->getPaymentConfiguration($this->salesChannelContext->getPaymentMethod()->getId()); $paymentConfiguration = $this->getPaymentConfiguration(
$this->salesChannelContext->getPaymentMethod()->getId(),
$transactionPayload->setAllowedPaymentMethodConfigurations([$paymentConfiguration->getPaymentMethodConfigurationId()]); $this->settings->getSpaceId()
);
if ($paymentConfiguration) {
$transactionPayload->setAllowedPaymentMethodConfigurations([
$paymentConfiguration->getPaymentMethodConfigurationId()
]);
}
$successUrl = $this->transaction->getReturnUrl() . '&status=paid'; $successUrl = $this->transaction->getReturnUrl() . '&status=paid';
$failedUrl = $this->getFailUrl($this->transaction->getOrder()->getId()) . '&status=fail'; $failedUrl = $this->getFailUrl($this->transaction->getOrder()->getId()) . '&status=fail';
$transactionPayload->setSuccessUrl($successUrl) $transactionPayload->setSuccessUrl($successUrl)
@@ -210,6 +217,23 @@ class TransactionPayload extends AbstractPayload
return $transactionPayload; return $transactionPayload;
} }
/**
* @param string $paymentMethodId
* @param int $spaceId
* @return PaymentMethodConfigurationEntity|null
*/
protected function getPaymentConfiguration(string $paymentMethodId, int $spaceId): ?PaymentMethodConfigurationEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('paymentMethodId', $paymentMethodId));
$criteria->addFilter(new EqualsFilter('spaceId', $spaceId));
return $this->container->get('vrpayment_payment_method_configuration.repository')
->search($criteria, $this->salesChannelContext->getContext())
->first();
}
/** /**
* Get transaction line items * Get transaction line items
* *
@@ -321,7 +345,7 @@ class TransactionPayload extends AbstractPayload
->setShippingRequired(false) ->setShippingRequired(false)
->setSku('sku-discount-' . $rate . '-' . $discountName, 200) ->setSku('sku-discount-' . $rate . '-' . $discountName, 200)
->setType(LineItemType::DISCOUNT) ->setType(LineItemType::DISCOUNT)
->setUniqueId('coupon-sku-discount-' . $rate . '-' . $rate . '-' . $discountName); ->setUniqueId('coupon-sku-discount-' . $rate . '-' . $rate . '-' . $discountName . '-' . $discount->getId());
$taxRate = new TaxCreate(['title' => 'Discount Tax: ' . $rate, 'rate' => $rate]); $taxRate = new TaxCreate(['title' => 'Discount Tax: ' . $rate, 'rate' => $rate]);
$lineItem->setTaxes([$taxRate]); $lineItem->setTaxes([$taxRate]);
@@ -792,20 +816,6 @@ class TransactionPayload extends AbstractPayload
return $addressPayload; return $addressPayload;
} }
/**
* @param string $id
*
* @return \VRPaymentPayment\Core\Api\PaymentMethodConfiguration\Entity\PaymentMethodConfigurationEntity
*/
protected function getPaymentConfiguration(string $id): PaymentMethodConfigurationEntity
{
$criteria = (new Criteria([$id]));
return $this->container->get('vrpayment_payment_method_configuration.repository')
->search($criteria, $this->salesChannelContext->getContext())
->getEntities()->first();
}
/** /**
* Get failure URL * Get failure URL
* *
@@ -31,7 +31,7 @@ class Migration1590156974TransactionEntity extends MigrationStep {
public function update(Connection $connection): void public function update(Connection $connection): void
{ {
$connection->executeStatement(' $connection->executeStatement('
CREATE TABLE IF NOT EXISTS `vrpayment_transaction` ( CREATE TABLE IF NOT EXISTS `vrpayment_transaction_tmp` (
`id` BINARY(16) NOT NULL, `id` BINARY(16) NOT NULL,
`data` JSON NOT NULL, `data` JSON NOT NULL,
`payment_method_id` BINARY(16) NOT NULL, `payment_method_id` BINARY(16) NOT NULL,
@@ -42,7 +42,7 @@ class Migration1590646356RefundEntity extends MigrationStep {
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `refund_id_UNIQUE` (`refund_id`), UNIQUE KEY `refund_id_UNIQUE` (`refund_id`),
KEY `fk.vrp_refund.transaction_id` (`transaction_id`), KEY `fk.vrp_refund.transaction_id` (`transaction_id`),
CONSTRAINT `fk.vrp_refund.transaction_id` FOREIGN KEY (`transaction_id`) REFERENCES `vrpayment_transaction` (`transaction_id`) ON DELETE CASCADE CONSTRAINT `fk.vrp_refund.transaction_id` FOREIGN KEY (`transaction_id`) REFERENCES `vrpayment_transaction_tmp` (`transaction_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
'); ');
} }
@@ -30,7 +30,7 @@ class Migration1590646356TransactionEntity extends MigrationStep {
public function update(Connection $connection): void public function update(Connection $connection): void
{ {
try { try {
$connection->executeStatement('ALTER TABLE `vrpayment_transaction` ADD COLUMN `confirmation_email_sent` TINYINT(1) NOT NULL DEFAULT 0 AFTER `id`;'); $connection->executeStatement('ALTER TABLE `vrpayment_transaction_tmp` ADD COLUMN `confirmation_email_sent` TINYINT(1) NOT NULL DEFAULT 0 AFTER `id`;');
}catch (\Exception $exception){ }catch (\Exception $exception){
// column probably exists // column probably exists
} }
@@ -33,19 +33,19 @@ class Migration1605701048TransactionEntity extends MigrationStep
try { try {
$connection->executeStatement(' $connection->executeStatement('
ALTER TABLE `vrpayment_transaction` ALTER TABLE `vrpayment_transaction_tmp`
ADD `order_version_id` binary(16) NOT NULL AFTER `transaction_id`; ADD `order_version_id` binary(16) NOT NULL AFTER `transaction_id`;
'); ');
$connection->executeStatement(' $connection->executeStatement('
UPDATE `vrpayment_transaction` t1 UPDATE `vrpayment_transaction_tmp` t1
INNER JOIN `order` t2 INNER JOIN `order` t2
ON t1.order_id = t2.id ON t1.order_id = t2.id
SET t1.order_version_id = t2.version_id; SET t1.order_version_id = t2.version_id;
'); ');
$connection->executeStatement(' $connection->executeStatement('
ALTER TABLE `vrpayment_transaction` ALTER TABLE `vrpayment_transaction_tmp`
DROP FOREIGN KEY `fk.vrp_transaction.order_id`, DROP FOREIGN KEY `fk.vrp_transaction.order_id`,
DROP FOREIGN KEY `fk.vrp_transaction.order_transaction_id`, DROP FOREIGN KEY `fk.vrp_transaction.order_transaction_id`,
DROP FOREIGN KEY `fk.vrp_transaction.payment_method_id`, DROP FOREIGN KEY `fk.vrp_transaction.payment_method_id`,
@@ -53,7 +53,7 @@ class Migration1605701048TransactionEntity extends MigrationStep
'); ');
$connection->executeStatement(' $connection->executeStatement('
ALTER TABLE `vrpayment_transaction` ALTER TABLE `vrpayment_transaction_tmp`
ADD CONSTRAINT `fk.vrp_transaction_order_id` FOREIGN KEY (`order_id`, `order_version_id`) ADD CONSTRAINT `fk.vrp_transaction_order_id` FOREIGN KEY (`order_id`, `order_version_id`)
REFERENCES `order` (`id`, `version_id`) ON DELETE CASCADE ON UPDATE CASCADE, REFERENCES `order` (`id`, `version_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk.vrp_transaction_payment_method_id` FOREIGN KEY (`payment_method_id`) ADD CONSTRAINT `fk.vrp_transaction_payment_method_id` FOREIGN KEY (`payment_method_id`)
@@ -30,7 +30,7 @@ class Migration1684240994TransactionEntity extends MigrationStep {
public function update(Connection $connection): void public function update(Connection $connection): void
{ {
try { try {
$connection->executeStatement('ALTER TABLE `vrpayment_transaction` ADD COLUMN `erp_merchant_id` VARCHAR(255) DEFAULT NULL AFTER `confirmation_email_sent`;'); $connection->executeStatement('ALTER TABLE `vrpayment_transaction_tmp` ADD COLUMN `erp_merchant_id` VARCHAR(255) DEFAULT NULL AFTER `confirmation_email_sent`;');
}catch (\Exception $exception){ }catch (\Exception $exception){
// column probably exists // column probably exists
} }
@@ -0,0 +1,324 @@
<?php declare(strict_types=1);
namespace VRPaymentPayment\Migration;
use Doctrine\DBAL\Connection;
use Shopware\Core\Framework\Migration\MigrationStep;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
/**
* Class Migration1766067106TransactionEntity
*
* @package VRPaymentPayment\Migration
*/
class Migration1766067106TransactionEntity extends MigrationStep
{
/**
* get creation timestamp
*
* @return int
*/
public function getCreationTimestamp(): int
{
return 1766067106;
}
/**
* update non-destructive changes
*
* @param \Doctrine\DBAL\Connection $connection
*/
public function update(Connection $connection): void
{
$oldTableName = 'vrpayment_transaction';
$tempTableName = 'vrpayment_transaction_tmp';
$realTableName = 'vrpayment_transaction_data';
$logger = new Logger('vrpayment_migration');
$logger->pushHandler(new StreamHandler(dirname(__DIR__, 5) . '/var/log/vrpayment-migration.log'));
$logger->info(
'Migration start', [
'old_table_exists' => $this->tableExists($connection, $oldTableName),
'temp_table_exists' => $this->tableExists($connection, $tempTableName),
'real_table_exists' => $this->tableExists($connection, $realTableName),
]
);
if ($this->tableExists($connection, $tempTableName)) {
// If _temp table exists, it means that this is a fresh installation.
$logger->info('Fresh installation detected.');
$connection->executeStatement(
sprintf('RENAME TABLE `%s` TO `%s`', $tempTableName, $realTableName)
);
$logger->info('Fresh installation finished.');
} else {
// If _temp does not exist, it means that this could be a version upgrade.
$logger->info('Possible plugin upgrade detected.');
if ($this->tableExists($connection, $oldTableName) && !$this->isOldPluginTable($connection, $oldTableName)) {
$logger->info('Old vrpayment_transaction table detected.');
// If vrpayment_transaction already exists and does not belong to old plugin,
// it means that this is indeed a version update.
$this->syncTransactionTable($connection, $oldTableName);
$logger->info('Old vrpayment_transaction table sync finished.');
$this->syncRefundTable($connection, $oldTableName);
$logger->info('Old vrpayment_refund table sync finished.');
$connection->executeStatement(
sprintf('RENAME TABLE `%s` TO `%s`', $oldTableName, $realTableName)
);
$logger->info('Old vrpayment_transaction table renaming completed.');
}
$logger->info('Possible plugin upgrade finished.');
// If vrpayment_transaction exists and it does belong to old plugin,
// it means we must run it in parallel.
}
$logger->info('Migration finished.');
return;
}
/**
* Check if table exists.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
*
* @return bool
*/
public function tableExists(Connection $connection, string $table): bool {
$result = $connection->fetchOne('SHOW TABLES LIKE :table', ['table' => $table]);
return $result !== false && $result !== null;
}
/**
* Check if table belongs to old plugin.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
*
* @return bool
*/
public function isOldPluginTable(Connection $connection, string $table): bool {
$oldTableExclusiveColumns = [
'finalized_at' => 'datetime',
'refunded_at' => 'datetime',
'initial_transaction_mode' => 'varchar',
'manual_capture' => 'tinyint',
'partial_refunded_at' => 'datetime',
'refunded_amount' => 'double',
'amount_to_refund' => 'double',
];
$resultColumns = $connection->fetchAllAssociative(
'SELECT LOWER(COLUMN_NAME) AS column_name, LOWER(DATA_TYPE) AS data_type
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = :table',
['table' => $table]
);
$dbColumns = [];
foreach($resultColumns as $column) {
$dbColumns[$column['column_name']] = $column['data_type'];
}
$oldPluginTable = true;
foreach($oldTableExclusiveColumns as $columnName => $columnType) {
if(!isset($dbColumns[$columnName])) {
$oldPluginTable = false;
break;
}
if ($dbColumns[$columnName] !== $columnType) {
$oldPluginTable = false;
break;
}
}
return $oldPluginTable;
}
/**
* Synchronizes the transaction table with the current/latest version.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
*/
private function syncTransactionTable(Connection $connection, string $table): void {
$this->addColumnIfMissing($connection, $table, 'confirmation_email_sent', "TINYINT(1) NOT NULL DEFAULT 0 AFTER `id`");
$this->addColumnIfMissing($connection, $table, 'erp_merchant_id', "VARCHAR(255) DEFAULT NULL AFTER `confirmation_email_sent`");
$this->addColumnIfMissing($connection, $table, 'data', "LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`data`)) AFTER `erp_merchant_id`");
$this->addColumnIfMissing($connection, $table, 'payment_method_id', "BINARY(16) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'order_id', "BINARY(16) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'order_transaction_id', "BINARY(16) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'space_id', "INT(10) UNSIGNED NOT NULL");
$this->addColumnIfMissing($connection, $table, 'state', "VARCHAR(255) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'sales_channel_id', "BINARY(16) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'transaction_id', "INT(10) UNSIGNED NOT NULL");
$this->addColumnIfMissing($connection, $table, 'order_version_id', "BINARY(16) NOT NULL AFTER `transaction_id`");
$this->addColumnIfMissing($connection, $table, 'created_at', "DATETIME(3) NOT NULL");
$this->addColumnIfMissing($connection, $table, 'updated_at', "DATETIME(3) DEFAULT NULL");
$this->ensureIndexBySql($connection, $table, 'fk.vrp_transaction.order_id', "KEY `fk.vrp_transaction.order_id` (`order_id`)");
$this->ensureIndexBySql($connection, $table, 'fk.vrp_transaction.order_transaction_id', "KEY `fk.vrp_transaction.order_transaction_id` (`order_transaction_id`)");
$this->ensureIndexBySql($connection, $table, 'fk.vrp_transaction.payment_method_id', "KEY `fk.vrp_transaction.payment_method_id` (`payment_method_id`)");
$this->ensureIndexBySql($connection, $table, 'fk.vrp_transaction.sales_channel_id', "KEY `fk.vrp_transaction.sales_channel_id` (`sales_channel_id`)");
$this->ensureIndexBySql($connection, $table, 'fk.vrp_transaction', "KEY `fk.vrp_transaction` (`order_id`,`order_version_id`)");
$this->ensureForeignKey(
$connection,
$table,
'fk.vrp_transaction_order_id',
['order_id', 'order_version_id'],
'order',
['id', 'version_id'],
'CASCADE',
'CASCADE'
);
$this->ensureForeignKey(
$connection,
$table,
'fk.vrp_transaction_payment_method_id',
['payment_method_id'],
'payment_method',
['id'],
'RESTRICT',
'CASCADE'
);
$this->ensureForeignKey(
$connection,
$table,
'fk.vrp_transaction_sales_channel_id',
['sales_channel_id'],
'sales_channel',
['id'],
'RESTRICT',
'CASCADE'
);
}
/**
* Synchronizes the parts of the refund table related to transactions with the current/latest version.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
*/
private function syncRefundTable(Connection $connection, string $table): void {
$refundTable = 'vrpayment_refund';
$this->ensureIndexBySql($connection, $refundTable, 'fk.vrp_refund.transaction_id', "KEY `fk.vrp_refund.transaction_id` (`transaction_id`)");
$this->ensureForeignKey(
$connection,
$refundTable,
'fk.vrp_refund.transaction_id',
['transaction_id'],
$table,
['transaction_id'],
'CASCADE',
null
);
}
/**
* Adds column to the table if it's missing.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
* @param string $column
* @param string $sqlFragment
*/
private function addColumnIfMissing(Connection $connection, string $table, string $column, string $sqlFragment): void {
if ($this->columnExists($connection, $table, $column)) {
return;
}
$connection->executeStatement(
sprintf("ALTER TABLE `%s` ADD COLUMN `%s` %s", $table, $column, $sqlFragment)
);
}
/**
* Adds index to the table if it's missing.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
* @param string $indexName
* @param string $sqlFragment
*/
private function ensureIndexBySql(Connection $connection, string $table, string $indexName, string $sqlFragment): void {
if ($this->indexExists($connection, $table, $indexName)) {
return;
}
$connection->executeStatement(
sprintf("ALTER TABLE `%s` ADD %s", $table, $sqlFragment)
);
}
/**
* Adds foreign key constraint to the table if it's missing.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
* @param string $constraintName
* @param string $columns
* @param string $refTable
* @param string $refColumns
* @param string|null $onDelete
* @param string|null $onUpdate
*/
private function ensureForeignKey(
Connection $connection,
string $table,
string $constraintName,
array $columns,
string $refTable,
array $refColumns,
?string $onDelete,
?string $onUpdate
): void {
if ($this->foreignKeyExists($connection, $table, $constraintName)) {
return;
}
$columnsList = '`' . implode('`,`', $columns) . '`';
$refColumnsList = '`' . implode('`,`', $refColumns) . '`';
$connection->executeStatement(
sprintf(
"ALTER TABLE `%s`
ADD CONSTRAINT `%s` FOREIGN KEY (%s)
REFERENCES `%s` (%s)%s%s",
$table,
$constraintName,
$columnsList,
$refTable,
$refColumnsList,
$onDelete ? " ON DELETE {$onDelete}" : "",
$onUpdate ? " ON UPDATE {$onUpdate}" : ""
)
);
}
/**
* Check if foreign key constraint exists.
*
* @param \Doctrine\DBAL\Connection $connection
* @param string $table
* @param string $constraintName
*
* @return bool
*/
private function foreignKeyExists(Connection $connection, string $table, $constraintName): bool {
$result = $connection->fetchOne(
"SELECT 1 FROM information_schema.referential_constraints
WHERE constraint_schema = DATABASE()
AND table_name = ?
AND constraint_name = ?
LIMIT 1",
[$table,$constraintName]
);
return $result !== false && $result !== null;
}
/**
* update destructive changes
*
* @param \Doctrine\DBAL\Connection $connection
*/
public function updateDestructive(Connection $connection): void
{
// implement update destructive
}
}
BIN
View File
Binary file not shown.
@@ -70,9 +70,24 @@ Component.register('vrpayment-order-action-refund-by-amount', {
}); });
}).catch((errorResponse) => { }).catch((errorResponse) => {
try { try {
var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
var errorMessage;
switch(errorResponse.response.data) {
case 'refundAmountZero':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messageRefundAmountIsZero');
break;
case 'refundExceedsAmount':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messageRefundAmountExceedsAvailableBalance');
break;
case 'methodDoesNotSupportRefund':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({ this.createNotificationError({
title: errorResponse.response.data.errors[0].title, title: errorTitle,
message: errorResponse.response.data.errors[0].detail, message: errorMessage,
autoClose: false autoClose: false
}); });
} catch (e) { } catch (e) {
@@ -69,9 +69,18 @@ Component.register('vrpayment-order-action-refund-partial', {
}); });
}).catch((errorResponse) => { }).catch((errorResponse) => {
try { try {
var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
var errorMessage;
switch(errorResponse.response.data) {
case 'methodDoesNotSupportRefund':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({ this.createNotificationError({
title: errorResponse.response.data.errors[0].title, title: errorTitle,
message: errorResponse.response.data.errors[0].detail, message: errorMessage,
autoClose: false autoClose: false
}); });
} catch (e) { } catch (e) {
@@ -70,9 +70,18 @@ Component.register('vrpayment-order-action-refund-selected', {
}); });
}).catch((errorResponse) => { }).catch((errorResponse) => {
try { try {
var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
var errorMessage;
switch(errorResponse.response.data) {
case 'methodDoesNotSupportRefund':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({ this.createNotificationError({
title: errorResponse.response.data.errors[0].title, title: errorTitle,
message: errorResponse.response.data.errors[0].detail, message: errorMessage,
autoClose: false autoClose: false
}); });
} catch (e) { } catch (e) {
@@ -9,6 +9,7 @@
:max="this.$parent.$parent.itemRefundableQuantity" :max="this.$parent.$parent.itemRefundableQuantity"
:min="0" :min="0"
v-model:value="refundQuantity" v-model:value="refundQuantity"
number-type="int"
:label="$tc('vrpayment-order.refund.refundQuantity.label')"> :label="$tc('vrpayment-order.refund.refundQuantity.label')">
</sw-number-field> </sw-number-field>
@@ -68,9 +68,24 @@ Component.register('vrpayment-order-action-refund', {
}); });
}).catch((errorResponse) => { }).catch((errorResponse) => {
try { try {
var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
var errorMessage;
switch(errorResponse.response.data) {
case 'refundQuantityZero':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messageRefundQuantityIsZero');
break;
case 'refundExceedsQuantity':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messageRefundQuantityExceedsAvailableBalance');
break;
case 'methodDoesNotSupportRefund':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({ this.createNotificationError({
title: errorResponse.response.data.errors[0].title, title: errorTitle,
message: errorResponse.response.data.errors[0].detail, message: errorMessage,
autoClose: false autoClose: false
}); });
} catch (e) { } catch (e) {
@@ -98,7 +98,7 @@
<template #actions="{ item }"> <template #actions="{ item }">
<sw-context-menu-item <sw-context-menu-item
:disabled="transaction.state != 'FULFILL' || item.refundableQuantity != item.quantity || item.refundableAmount == 0 || item.itemRefundedAmount > 0 || item.itemRefundedQuantity > 0" :disabled="transaction.state != 'FULFILL' || item.refundableQuantity != item.quantity || item.refundableAmount == 0 || item.itemRefundedAmount > 0 || item.itemRefundedQuantity > 0"
@click="lineItemRefund(item.uniqueId)"> @click="lineItemRefund(item.uniqueId, item.quantity)">
{{ $tc('vrpayment-order.buttons.label.refund-whole-line-item') }} {{ $tc('vrpayment-order.buttons.label.refund-whole-line-item') }}
</sw-context-menu-item> </sw-context-menu-item>
@@ -332,12 +332,12 @@ Component.register('vrpayment-order-detail', {
this.modalType = ''; this.modalType = '';
}, },
lineItemRefund(lineItemId) { lineItemRefund(lineItemId, itemQuantity) {
this.isLoading = true; this.isLoading = true;
this.VRPaymentRefundService.createRefund( this.VRPaymentRefundService.createRefund(
this.transactionData.transactions[0].metaData.salesChannelId, this.transactionData.transactions[0].metaData.salesChannelId,
this.transactionData.transactions[0].id, this.transactionData.transactions[0].id,
0, itemQuantity,
lineItemId lineItemId
).then(() => { ).then(() => {
this.createNotificationSuccess({ this.createNotificationSuccess({
@@ -351,9 +351,18 @@ Component.register('vrpayment-order-detail', {
}); });
}).catch((errorResponse) => { }).catch((errorResponse) => {
try { try {
var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
var errorMessage;
switch(errorResponse.response.data) {
case 'methodDoesNotSupportRefund':
errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({ this.createNotificationError({
title: errorResponse.response.data.errors[0].title, title: errorTitle,
message: errorResponse.response.data.errors[0].detail, message: errorMessage,
autoClose: false autoClose: false
}); });
} catch (e) { } catch (e) {
@@ -385,7 +394,7 @@ Component.register('vrpayment-order-detail', {
// Force the DOM to update before proceeding with the asynchronous operations // Force the DOM to update before proceeding with the asynchronous operations
this.$nextTick(() => { this.$nextTick(() => {
const refundPromises = this.selectedItems.map((item) => { const refundPromises = this.selectedItems.map((item) => {
return this.lineItemRefundBulk(item.uniqueId); // Simulated refund action with delay return this.lineItemRefundBulk(item.uniqueId, item.quantity); // Simulated refund action with delay
}); });
// Wait for all refund promises to complete // Wait for all refund promises to complete
@@ -410,7 +419,7 @@ Component.register('vrpayment-order-detail', {
}); });
} }
}, },
lineItemRefundBulk(lineItemId) { lineItemRefundBulk(lineItemId, itemQuantity) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.VRPaymentRefundService.createRefund( this.VRPaymentRefundService.createRefund(
this.transactionData.transactions[0].metaData.salesChannelId, this.transactionData.transactions[0].metaData.salesChannelId,
@@ -427,11 +436,20 @@ Component.register('vrpayment-order-detail', {
}) })
.catch((errorResponse) => { .catch((errorResponse) => {
try { try {
this.createNotificationError({ var errorTitle = errorResponse?.response?.data?.errors?.[0]?.title ?? this.$tc('vrpayment-order.refundAction.refundCreateError.errorTitle')
title: errorResponse.response.data.errors[0].title, var errorMessage;
message: errorResponse.response.data.errors[0].detail, switch(errorResponse.response.data) {
autoClose: false case 'methodDoesNotSupportRefund':
}); errorMessage = this.$tc('vrpayment-order.refundAction.refundCreateError.messagePaymentMethodDoesNotSupportRefund');
break;
default:
errorMessage = errorResponse.response.data.errors[0].detail;
}
this.createNotificationError({
title: errorTitle,
message: errorMessage,
autoClose: false
});
} catch (e) { } catch (e) {
this.createNotificationError({ this.createNotificationError({
title: errorResponse.title, title: errorResponse.title,
@@ -77,7 +77,15 @@
"successMessage": "Ihre Rückerstattung war erfolgreich", "successMessage": "Ihre Rückerstattung war erfolgreich",
"successTitle": "Erfolg", "successTitle": "Erfolg",
"maxAvailableItemsToRefund": "Maximal Verfügbare Artikel zum Erstatten", "maxAvailableItemsToRefund": "Maximal Verfügbare Artikel zum Erstatten",
"maxAvailableAmountToRefund": "Maximal verfügbarer Erstattungsbetrag" "maxAvailableAmountToRefund": "Maximal verfügbarer Erstattungsbetrag",
"refundCreateError": {
"errorTitle": "Fehler beim Erstellen der Rückerstattung.",
"messageRefundAmountExceedsAvailableBalance": "Der Rückerstattungsbetrag übersteigt das verfügbare Guthaben.",
"messageRefundAmountIsZero": "Der Rückerstattungsbetrag muss größer als 0 sein.",
"messageRefundQuantityExceedsAvailableBalance": "Rückerstattung nach Menge überschreitet die maximal verfügbare Anzahl an Artikeln zur Rückerstattung.",
"messageRefundQuantityIsZero": "Rückerstattung nach Menge muss größer als 0 sein.",
"messagePaymentMethodDoesNotSupportRefund": "Die Zahlungsmethode unterstützt keine Online-Rückerstattungen."
}
}, },
"transactionHistory": { "transactionHistory": {
"cardTitle": "Einzelheiten", "cardTitle": "Einzelheiten",
@@ -9,7 +9,6 @@
"void": "Cancel authorization", "void": "Cancel authorization",
"refund-whole-line-item": "Refund whole line item", "refund-whole-line-item": "Refund whole line item",
"refund-line-item-by-quantity": "Refund by quantity", "refund-line-item-by-quantity": "Refund by quantity",
"refund-line-item-selected": "Rembourser sélectionnés",
"refund-line-item-selected": "Refund selected", "refund-line-item-selected": "Refund selected",
"refund-line-item-parial": "Partial refund" "refund-line-item-parial": "Partial refund"
} }
@@ -78,7 +77,15 @@
"successMessage": "Your refund was successful.", "successMessage": "Your refund was successful.",
"successTitle": "Success", "successTitle": "Success",
"maxAvailableItemsToRefund": "Maximum available items to refund", "maxAvailableItemsToRefund": "Maximum available items to refund",
"maxAvailableAmountToRefund": "Maximum available amount to refund" "maxAvailableAmountToRefund": "Maximum available amount to refund",
"refundCreateError": {
"errorTitle": "Error while creating the refund.",
"messageRefundAmountExceedsAvailableBalance": "Refund amount exceeds available balance.",
"messageRefundAmountIsZero": "Refund amount must be greater than 0.",
"messageRefundQuantityExceedsAvailableBalance": "Refund by quantity exceeds maximum available items to refund.",
"messageRefundQuantityIsZero": "Refund by quantity must be greater than 0.",
"messagePaymentMethodDoesNotSupportRefund": "Payment method does not support online refunds."
}
}, },
"transactionHistory": { "transactionHistory": {
"cardTitle": "Details", "cardTitle": "Details",
@@ -77,7 +77,15 @@
"successMessage": "Votre remboursement a été effectué avec succès.", "successMessage": "Votre remboursement a été effectué avec succès.",
"successTitle": "Succès", "successTitle": "Succès",
"maxAvailableItemsToRefund": "Nombre maximum d'articles disponibles pour le remboursement", "maxAvailableItemsToRefund": "Nombre maximum d'articles disponibles pour le remboursement",
"maxAvailableAmountToRefund": "Montant maximal disponible pour le remboursement" "maxAvailableAmountToRefund": "Montant maximal disponible pour le remboursement",
"refundCreateError": {
"errorTitle": "Erreur lors de la création du remboursement.",
"messageRefundAmountExceedsAvailableBalance": "Le montant du remboursement dépasse le solde disponible.",
"messageRefundAmountIsZero": "Le montant du remboursement doit être supérieur à 0.",
"messageRefundQuantityExceedsAvailableBalance": "Le remboursement par quantité dépasse le nombre maximal darticles remboursables.",
"messageRefundQuantityIsZero": "Le remboursement par quantité doit être supérieur à 0.",
"messagePaymentMethodDoesNotSupportRefund": "Le mode de paiement ne prend pas en charge les remboursements en ligne."
}
}, },
"transactionHistory": { "transactionHistory": {
"cardTitle": "Détails", "cardTitle": "Détails",
@@ -77,7 +77,15 @@
"successMessage": "Il tuo rimborso è andato a buon fine.", "successMessage": "Il tuo rimborso è andato a buon fine.",
"successTitle": "Successo", "successTitle": "Successo",
"maxAvailableItemsToRefund": "Numero massimo di articoli disponibili da rimborsare", "maxAvailableItemsToRefund": "Numero massimo di articoli disponibili da rimborsare",
"maxAvailableAmountToRefund": "Importo massimo disponibile per il rimborso" "maxAvailableAmountToRefund": "Importo massimo disponibile per il rimborso",
"refundCreateError": {
"errorTitle": "Errore durante la creazione del rimborso.",
"messageRefundAmountExceedsAvailableBalance": "LL'importo del rimborso supera il saldo disponibile.",
"messageRefundAmountIsZero": "L'importo del rimborso deve essere superiore a 0.",
"messageRefundQuantityExceedsAvailableBalance": "Il rimborso per quantità supera il numero massimo di articoli rimborsabili.",
"messageRefundQuantityIsZero": "Il rimborso per quantità deve essere maggiore di 0.",
"messagePaymentMethodDoesNotSupportRefund": "Il metodo di pagamento non supporta i rimborsi online."
}
}, },
"transactionHistory": { "transactionHistory": {
"cardTitle": "Dettagli", "cardTitle": "Dettagli",
@@ -14,7 +14,7 @@
{% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_space_id %} {% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_space_id %}
<sw-inherit-wrapper <sw-inherit-wrapper
v-model:value="actualConfigData[CONFIG_SPACE_ID]" v-model:value="actualConfigData[CONFIG_SPACE_ID]"
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_SPACE_ID]" :inheritedValue="getInheritedValue(CONFIG_SPACE_ID)"
:customInheritationCheckFunction="checkNumberFieldInheritance"> :customInheritationCheckFunction="checkNumberFieldInheritance">
<template #content="props"> <template #content="props">
<sw-number-field <sw-number-field
@@ -23,7 +23,7 @@
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.credentials.spaceId.label')" :label="$tc('vrpayment-settings.settingForm.credentials.spaceId.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.spaceId.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.spaceId.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="!acl.can('vrpayment.editor')"
:value="props.currentValue" :value="props.currentValue"
:error="spaceIdErrorState" :error="spaceIdErrorState"
@update:value="props.updateCurrentValue"> @update:value="props.updateCurrentValue">
@@ -35,7 +35,7 @@
{% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_user_id %} {% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_user_id %}
<sw-inherit-wrapper <sw-inherit-wrapper
v-model:value="actualConfigData[CONFIG_USER_ID]" v-model:value="actualConfigData[CONFIG_USER_ID]"
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_USER_ID]" :inheritedValue="getInheritedValue(CONFIG_USER_ID)"
:customInheritationCheckFunction="checkNumberFieldInheritance"> :customInheritationCheckFunction="checkNumberFieldInheritance">
<template #content="props"> <template #content="props">
<sw-number-field <sw-number-field
@@ -44,7 +44,7 @@
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.credentials.userId.label')" :label="$tc('vrpayment-settings.settingForm.credentials.userId.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.userId.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.userId.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="!acl.can('vrpayment.editor')"
:value="props.currentValue" :value="props.currentValue"
:error="userIdErrorState" :error="userIdErrorState"
@update:value="props.updateCurrentValue"> @update:value="props.updateCurrentValue">
@@ -56,7 +56,7 @@
{% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_application_key %} {% block vrpayment_settings_content_card_channel_config_credentials_card_container_settings_application_key %}
<sw-inherit-wrapper <sw-inherit-wrapper
v-model:value="actualConfigData[CONFIG_APPLICATION_KEY]" v-model:value="actualConfigData[CONFIG_APPLICATION_KEY]"
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_APPLICATION_KEY]" :inheritedValue="getInheritedValue(CONFIG_APPLICATION_KEY)"
:customInheritationCheckFunction="checkTextFieldInheritance"> :customInheritationCheckFunction="checkTextFieldInheritance">
<template #content="props"> <template #content="props">
<sw-password-field <sw-password-field
@@ -66,7 +66,7 @@
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.credentials.applicationKey.label')" :label="$tc('vrpayment-settings.settingForm.credentials.applicationKey.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.applicationKey.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.applicationKey.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="!acl.can('vrpayment.editor')"
:value="props.currentValue" :value="props.currentValue"
:error="applicationKeyErrorState" :error="applicationKeyErrorState"
@update:value="props.updateCurrentValue"> @update:value="props.updateCurrentValue">
@@ -6,7 +6,7 @@ import constants from '../../page/vrpayment-settings/configuration-constants'
const {Component, Mixin} = Shopware; const {Component, Mixin} = Shopware;
Component.register('sw-vrpayment-credentials', { Component.register('sw-vrpayment-credentials', {
template: template, template,
name: 'VRPaymentCredentials', name: 'VRPaymentCredentials',
@@ -29,7 +29,9 @@ Component.register('sw-vrpayment-credentials', {
}, },
selectedSalesChannelId: { selectedSalesChannelId: {
required: true type: [String, null],
required: false,
default: null
}, },
spaceIdFilled: { spaceIdFilled: {
type: Boolean, type: Boolean,
@@ -68,38 +70,44 @@ Component.register('sw-vrpayment-credentials', {
}; };
}, },
computed: {
currentConfig() {
if (this.selectedSalesChannelId && this.allConfigs[this.selectedSalesChannelId]) {
return this.allConfigs[this.selectedSalesChannelId];
}
return this.allConfigs['null'] || {};
}
},
methods: { methods: {
checkTextFieldInheritance(value) { checkTextFieldInheritance(value) {
if (typeof value !== 'string') { return !value || value.length <= 0;
return true; },
}
return value.length <= 0; checkNumberFieldInheritance(value) {
}, return value == null || value === '';
},
checkNumberFieldInheritance(value) { checkBoolFieldInheritance(value) {
if (typeof value !== 'number') { return typeof value !== 'boolean';
return true; },
}
return value.length <= 0;
},
checkBoolFieldInheritance(value) {
return typeof value !== 'boolean';
},
// Emits the 'check-api-connection-event' with the current API connection parameters. // Emits the 'check-api-connection-event' with the current API connection parameters.
// Used to trigger API connection testing from this component. // Used to trigger API connection testing from this component.
emitCheckApiConnectionEvent() { emitCheckApiConnectionEvent() {
const apiConnectionParams = { const apiConnectionParams = {
spaceId: this.actualConfigData[constants.CONFIG_SPACE_ID], spaceId: this.currentConfig[constants.CONFIG_SPACE_ID],
userId: this.actualConfigData[constants.CONFIG_USER_ID], userId: this.currentConfig[constants.CONFIG_USER_ID],
applicationKey: this.actualConfigData[constants.CONFIG_APPLICATION_KEY] applicationKey: this.currentConfig[constants.CONFIG_APPLICATION_KEY]
}; };
this.$emit('check-api-connection-event', apiConnectionParams); this.$emit('check-api-connection-event', apiConnectionParams);
},
getInheritedValue(key) {
return this.allConfigs['null']?.[key] ?? null;
} }
} }
}); });
@@ -1,145 +1,145 @@
{% block vrpayment_settings %} {% block vrpayment_settings %}
<sw-page class="vrpayment-settings">
{% block vrpayment_settings_header %} <sw-page class="vrpayment-settings">
<template #smart-bar-header> {% block vrpayment_settings_header %}
<h2> <template #smart-bar-header>
{{ $tc('sw-settings.index.title') }} <h2>
<sw-icon name="small-arrow-medium-right" small></sw-icon> {{ $tc('sw-settings.index.title') }}
{{ $tc('vrpayment-settings.header') }} <mt-icon name="small-arrow-medium-right" size="16px"></mt-icon>
</h2> {{ $tc('vrpayment-settings.header') }}
</template> </h2>
{% endblock %} </template>
{% block vrpayment_settings_actions %}
<template #smart-bar-actions>
{% block vrpayment_settings_actions_save %}
<sw-button-process
v-model:value="isSaveSuccessful"
class="sw-settings-login-registration__save-action"
variant="primary"
:isLoading="isLoading"
:disabled="isLoading"
@click="onSave">
{{ $tc('vrpayment-settings.settingForm.save') }}
</sw-button-process>
{% endblock %}
</template>
{% endblock %}
{% block vrpayment_settings_content %}
<template #content>
{% block vrpayment_settings_content_card %}
<sw-card-view>
{% block vrpayment_settings_content_card_channel_config %}
<sw-sales-channel-config v-model:value="config"
ref="configComponent"
:domain="CONFIG_DOMAIN">
{% block vrpayment_settings_content_card_channel_config_sales_channel %}
<template #select="{ onInput, selectedSalesChannelId, salesChannel }">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card %}
<sw-card title="Sales Channel Switch">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_title %}
<sw-single-select
v-model:value="selectedSalesChannelId"
labelProperty="translated.name"
valueProperty="id"
:mapInheritance="props"
:isLoading="isLoading"
:options="salesChannel"
@update:value="onInput">
</sw-single-select>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer %}
<template #footer>
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container %}
<sw-container columns="2fr 1fr" gap="0px 30px">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_text %}
<p>{{ $tc('vrpayment-settings.salesChannelCard.button.description') }}</p>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_button %}
<sw-button-process
v-model:value="isSetDefaultPaymentSuccessful"
:isLoading="isSettingDefaultPaymentMethods"
@click="onSetPaymentMethodDefault">
{{ $tc('vrpayment-settings.salesChannelCard.button.label') }}
</sw-button-process>
{% endblock %}
</sw-container>
{% endblock %}
</template>
{% endblock %}
</sw-card>
{% endblock %}
</template>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_cards %}
<template #content="{ actualConfigData, allConfigs, selectedSalesChannelId }">
<div v-if="actualConfigData">
<sw-vrpayment-credentials
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:selectedSalesChannelId="selectedSalesChannelId"
:spaceIdErrorState="spaceIdErrorState"
:userIdErrorState="userIdErrorState"
:applicationKeyErrorState="applicationKeyErrorState"
:spaceIdFilled="spaceIdFilled"
:userIdFilled="userIdFilled"
:applicationKeyFilled="applicationKeyFilled"
:isLoading="isLoading"
:isTesting="isTesting"
@check-api-connection-event="onCheckApiConnection"
></sw-vrpayment-credentials>
<sw-vrpayment-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-options>
<sw-vrpayment-storefront-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-storefront-options>
<sw-vrpayment-advanced-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-advanced-options>
</div>
</template>
{% endblock %}
</sw-sales-channel-config>
{% endblock %}
{% block vrpayment_settings_content_card_loading %}
<sw-loader v-if="isLoading"></sw-loader>
{% endblock %}
</sw-card-view>
{% endblock %} {% endblock %}
</template> {% block vrpayment_settings_actions %}
{% endblock %} <template #smart-bar-actions>
</sw-page> {% block vrpayment_settings_actions_save %}
<mt-button
v-model:value="isSaveSuccessful"
class="sw-settings-login-registration__save-action"
variant="primary"
:isLoading="isLoading"
:disabled="isLoading"
@click="onSave">
{{ $tc('vrpayment-settings.settingForm.save') }}
</mt-button>
{% endblock %}
</template>
{% endblock %}
{% block vrpayment_settings_content %}
<template #content>
{% block vrpayment_settings_content_card %}
<mt-card-view>
{% block vrpayment_settings_content_card_channel_config %}
<sw-sales-channel-config v-model:value="config"
ref="configComponent"
:domain="CONFIG_DOMAIN">
{% block vrpayment_settings_content_card_channel_config_sales_channel %}
<template #select="{ onInput, selectedSalesChannelId, salesChannel }">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card %}
<mt-card title="Sales Channel Switch">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_title %}
<sw-single-select
:value="selectedSalesChannelId"
:options="salesChannel.map(sc => ({ id: sc.id, name: sc.translated.name }))"
labelProperty="name"
valueProperty="id"
:isLoading="isLoading"
@update:value="onInput"
/>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer %}
<template #footer>
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container %}
<sw-container columns="2fr 1fr" gap="0px 30px">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_text %}
<p>{{ $tc('vrpayment-settings.salesChannelCard.button.description') }}</p>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_button %}
<sw-button
variant="primary"
v-model:value="isSetDefaultPaymentSuccessful"
:isLoading="isSettingDefaultPaymentMethods"
@click="onSetPaymentMethodDefault">
{{ $tc('vrpayment-settings.salesChannelCard.button.label') }}
</sw-button>
{% endblock %}
</sw-container>
{% endblock %}
</template>
{% endblock %}
</mt-card>
{% endblock %}
</template>
{% endblock %}
{% block vrpayment_settings_content_card_channel_config_cards %}
<template #content="{ actualConfigData, allConfigs, selectedSalesChannelId }">
<div v-if="actualConfigData">
<sw-vrpayment-credentials
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:selectedSalesChannelId="selectedSalesChannelId"
:spaceIdErrorState="spaceIdErrorState"
:userIdErrorState="userIdErrorState"
:applicationKeyErrorState="applicationKeyErrorState"
:spaceIdFilled="spaceIdFilled"
:userIdFilled="userIdFilled"
:applicationKeyFilled="applicationKeyFilled"
:isLoading="isLoading"
:isTesting="isTesting"
@check-api-connection-event="onCheckApiConnection"
></sw-vrpayment-credentials>
<sw-vrpayment-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-options>
<sw-vrpayment-storefront-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-storefront-options>
<sw-vrpayment-advanced-options
:actualConfigData="actualConfigData"
:allConfigs="allConfigs"
:isLoading="isLoading"
:selectedSalesChannelId="selectedSalesChannelId"
>
</sw-vrpayment-advanced-options>
</div>
</template>
{% endblock %}
</sw-sales-channel-config>
{% endblock %}
{% block vrpayment_settings_content_card_loading %}
<mt-loader v-if="isLoading"></mt-loader>
{% endblock %}
</mt-card-view>
{% endblock %}
</template>
{% endblock %}
</sw-page>
{% endblock %} {% endblock %}
@@ -80,7 +80,7 @@ Component.register('vrpayment-settings', {
watch: { watch: {
config: { config: {
handler(configData) { handler(configData) {
const defaultConfig = this.$refs.configComponent.allConfigs.null; const defaultConfig = (this.$refs.configComponent.allConfigs || {}).null || {};
const salesChannelId = this.$refs.configComponent.selectedSalesChannelId; const salesChannelId = this.$refs.configComponent.selectedSalesChannelId;
if (salesChannelId === null) { if (salesChannelId === null) {
File diff suppressed because one or more lines are too long
@@ -10,6 +10,7 @@
<service id="VRPaymentPayment\Core\Api\Refund\Controller\RefundController" public="true"> <service id="VRPaymentPayment\Core\Api\Refund\Controller\RefundController" public="true">
<argument type="service" id="VRPaymentPayment\Core\Api\Refund\Service\RefundService"/> <argument type="service" id="VRPaymentPayment\Core\Api\Refund\Service\RefundService"/>
<argument type="service" id="VRPaymentPayment\Core\Settings\Service\SettingsService"/> <argument type="service" id="VRPaymentPayment\Core\Settings\Service\SettingsService"/>
<argument type="service" id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService"/>
<call method="setLogger"> <call method="setLogger">
<argument type="service" id="monolog.logger.vrpayment_payment"/> <argument type="service" id="monolog.logger.vrpayment_payment"/>
</call> </call>
@@ -15,6 +15,7 @@
<argument type="service" id="Shopware\Core\Checkout\Order\SalesChannel\OrderRoute"/> <argument type="service" id="Shopware\Core\Checkout\Order\SalesChannel\OrderRoute"/>
<argument type="service" id="Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler"/> <argument type="service" id="Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler"/>
<argument type="service" id="Shopware\Core\System\StateMachine\StateMachineRegistry"/> <argument type="service" id="Shopware\Core\System\StateMachine\StateMachineRegistry"/>
<argument type="service" id="Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface"/>
<call method="setLogger"> <call method="setLogger">
<argument type="service" id="monolog.logger.vrpayment_payment"/> <argument type="service" id="monolog.logger.vrpayment_payment"/>
</call> </call>
@@ -32,6 +33,7 @@
<argument id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService" type="service"/> <argument id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService" type="service"/>
<argument id="VRPaymentPayment\Core\Settings\Service\SettingsService" type="service"/> <argument id="VRPaymentPayment\Core\Settings\Service\SettingsService" type="service"/>
<argument id="VRPaymentPayment\Core\Util\PaymentMethodUtil" type="service"/> <argument id="VRPaymentPayment\Core\Util\PaymentMethodUtil" type="service"/>
<argument id="payment_method.repository" type="service"/>
<call method="setLogger"> <call method="setLogger">
<argument type="service" id="monolog.logger.vrpayment_payment"/> <argument type="service" id="monolog.logger.vrpayment_payment"/>
</call> </call>
BIN
View File
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
.sw-order-detail .sw-tabs{margin-top:40px}.sw-order-detail .sw-order-detail-base .sw-card-view__content{overflow-x:visible;overflow-y:visible}
.vrpayment-order-detail__data{display:grid}.vrpayment-order-detail__heading{padding-top:15px}
File diff suppressed because one or more lines are too long