Eigene Zahlungssysteme

xmstore ermöglicht die Umsetzung eigener Zahlungssysteme. Somit kann die Bezahlung über Anbieter realisiert werden, welche nicht direkt von xmstore unterstützt werden.

Umsetzung Beispielsystem

Um den Prozess der Erstellung eines Zahlungssystems beispielhaft zu erläutern, wird hier das fiktive Zahlungssystem bits implementiert.

Dateien anlegen

Zunächst wird der Ordner FTP: /htdocs/data/payment/bits erstellt. Dieser wird die Dateien des neuen Zahlungssystems beinhalten.

Im nächsten Schritt wird die Datei FTP: /htdocs/data/payment/skeleton.php nach FTP: /htdocs/data/payment/bits/bits.pm.php kopiert. Die Hauptdatei eines Zahlungssystems muss den gleichen Dateinamen haben wie der Ordner, in dem sie aufbewahrt wird. Außerdem muss die Dateiendung .pm.php genutzt werden.

Im letzten Schritt werden die jeweiligen Locale-Dateien, z.B. FTP: /htdocs/data/payment/bits/bits.locale_de.json, angelegt. Auch hier gilt es der Dateinamenskonvention besondere Beachtung zu schenken.

Modul umsetzen

Zunächst wird in der Datei FTP: /htdocs/data/payment/bits/bits.pm.php Name und Version angepasst, sodass die Datei wie folgt aussieht.
Zusätzlich wird die Einstellungsmöglichkeit server_url hinzugefügt. Die Metaklasse übernimmt Laden und Speichern von Einstellungen automatisch.

 <?php
 require_once(WEBROOT . '/data/payment/paymentprovider.if.php');
 
 class PaymentSkeleton extends PaymentProviderBase
 {
     public $providerName = 'bits';
     public $providerVersion = '0.1';
     
     public $aSettings = array('server_url');
     public $sqlConnection;
     
     public function __construct($sqlConnection)
     {
         parent::__construct($sqlConnection);
     }
 }

Die folgenden Methoden können in einem Zahlmodul aus der Metaklasse vererbt und überschrieben werden:

Methode Beschreibung
userIssueOrder(AS_Order $oOrder) Wird aufgerufen, wenn der Kunde den Kaufen-Button im letzten Bestellungsschritt gedrückt hat.
userPaymentSend(AS_Frontend $oFrontend, $form_id) Gibt das Formular und den Kaufen-Button zurück. Der Button sollte nicht sichtbar sein, da das Formular über JavaScript abgesendet wird (wozu jedoch ein Submit-Button benötigt wird).

Beispielimplementation:

 return '<form method="get" action="' . URLROOT . '/order/complete" id="' . $form_id . '">
     <input type="submit" value="" style="display: none;" />
 </form>';
userPaymentReturn() ?
incomingData() Wird aufgerufen, wenn von einem externen Zahlungsdienstleister Daten via HTTP gesendet wurden. Es kann normal mit PHP's Superglobalen gearbeitet werden.

Die URL lautet http://domain.com/ajax.php?m=order&a=pmping&force_frontend=1

backendPrintPaymentData($data) Wird vom Backend aufgerufen, wenn ein Benutzer das Tab Zahlungsdetails aufruft.

Die Umsetzung des Beispielmodus geschieht also wie folgt:

In der Methode userPaymentSend wird der Kunde auf den Server von bits weitergeleitet, um dort eine Zahlung abzuschließen.
Zusätzlich wird die Variable orderid zur späteren Identifikation des Kaufes übergeben. Hier gilt zu beachten, dass eine Bestellung zu diesem Zeitpunkt noch über keine eindeutige Bestellungsnummer oder Rechnungsnummer verfügt. Deshalb muss das Behilfsfeld payment_id, das eine eindeutige Nummer zur Identifizierung des Zahlvorganges beinhaltet, genutzt werden.

     public function userPaymentSend(AS_Frontend $oFrontend, $form_id)
     {
         return '<form method="post" action="http://' . $this->config['server_url'] . '/payment" id="' . $form_id . '">
             <input type="hidden" name="orderid" value="' . $oFrontend->oOrder->payment_id . '" />
             <input type="submit" value="" style="display: none;" />
         </form>';
     }

In der Methode incomingData werden nun Daten, welche von bits zurückkommen, verarbeitet. Hier entscheidet sich, ob die Zahlung erfolgreich war oder nicht.

Dazu wird zunächst ein Order-Objekt mit der zuvor mitgegebenen payment_id instanziert, um auf die lokalen Bestelldaten zugreifen zu können und ggf. Änderungen vornehmen zu können.

Dann wird anhand des fiktiven Wertes payment_succeeded vom bits-Server geprüft, ob die Zahlung erfolgreich war und die entsprechenden Änderungen an der Bestellung werden vorgenommen.
     public function incomingData()
     {
         if (isset($_POST['data']))
         {
             $oOrder = new AS_Order($this->sqlConnection);
             $oOrder->payment_id = $_POST['data']['orderid'];
             $oOrder = $oOrder->selectBaseDataByPaymentId();
 
             if ($_POST['payment_succeeded'] == 1)
             {
                 $oOrder->PaymentData($_POST); // Speichern der Daten, die der Bits-Server lieferte
                 $oOrder->payment_status = 1;  // Zahlstatus auf 1 (bezahlt) setzen
 
                 // locale laden
                 $l10n = json_decode(file_get_contents(WEBROOT . '/data/language/frontend/order.locale_en.json'), true);
                 
                 // Bestellbestätigungs-Mail senden
                 $oOrder->sendPaymentMail($l10n['email']['order'], $l10n['email']['order_subject'], $oLanguage->language_code);
 
                 // Bestellung abschließen
                 $oOrder->Complete();
             }
         }
     }