Zum Hauptinhalt springen

cXML Response Generator

Der CxmlConnectorResponseGenerator stellt drei Methoden bereit: eine für den Login-Handshake, eine für Fehler-Responses und eine für den eigentlichen Warenkorb-Transfer.


generatePunchoutSetupResponse()

public function generatePunchoutSetupResponse(
string $cxmlString,
string $startUrl,
SalesChannelContext $context
): string

Erzeugt die cXML-Antwort auf den PunchOutSetupRequest des Procurement-Systems. Sie enthält eine StartPage-URL, zu der das Procurement-System den Browser des Käufers weiterleitet.

Response-Struktur:

<cXML payloadID="..." timestamp="..." xml:lang="de-DE">
<Response>
<Status code="200" text="OK"/>
<PunchOutSetupResponse>
<StartPage>
<URL>https://shop.example.com/AgiqonCxmlEntry/auth/...</URL>
</StartPage>
</PunchOutSetupResponse>
</Response>
</cXML>

generateInvalidPunchoutSetupResponse()

public function generateInvalidPunchoutSetupResponse(
SimpleXMLElement $requestXml,
int $statusCode,
string $text,
string $message
): string

Erzeugt eine Fehler-Response (z.B. 400 Bad Request, 401 Unauthorized) wenn der Login fehlschlägt.


generateCxmlPunchOutOrderMessage()

public function generateCxmlPunchOutOrderMessage(
ConnectorSession $session,
CxmlSystemEntity $cxmlSystem,
Cart $cart,
SalesChannelContext $context
): string

Die Hauptmethode für den Warenkorb-Transfer. Sie erzeugt den vollständigen cXML-PunchOutOrderMessage-Body.

Ablauf

  1. Header aufbauen – From und To werden nach cXML-Konvention getauscht (der ursprüngliche To wird zum From der Antwort und umgekehrt)
  2. BuyerCookie aus Session-additionalFields einfügen
  3. PunchOutOrderMessageHeader mit operationAllowed, quoteStatus="final" und Gesamtpreis
  4. Optional: Versand anhängen (wenn attachShipping aktiv)
  5. Optional: Steuer anhängen (wenn attachTax aktiv)
  6. LineItems iterieren → je Position den passenden Resolver finden → Feldbaum rekursiv rendern
  7. CxmlResponseGenerationEvent feuern → XML kann noch modifiziert werden
  8. Ausgabe bereinigen (Zeilenumbrüche + Whitespace zwischen Tags entfernen)

Preis-Konfiguration

System-EinstellungVerwendeter Preis
isTotalPriceNet() = trueCart::getPrice()::getNetPrice()
isTotalPriceNet() = falseCart::getPrice()::getTotalPrice()

Die Nachkommastellen werden durch priceDigits des Systems konfiguriert.

Hierarchischer Feldbaum

cXML-Felder können verschachtelt werden (Parent/Child-Beziehung). Der Generator baut intern einen Feldbaum auf und rendert ihn rekursiv als XML-Elemente. Die Reihenfolge innerhalb jeder Ebene wird durch das position-Attribut der Felder bestimmt.

XML-Attribute

Felder können neben einem Textwert auch ein XML-Attribut tragen:

  • Standard-Attribut – wird direkt am Element gesetzt
  • Namespace-Attribut – wird mit dem cXML-Namespace http://xml.cxml.org/schemas/cXML/1.2.040/cXML.dtd gesetzt

Der Attributwert wird entweder aus einem DataField aufgelöst oder als statischer String konfiguriert.


CxmlResponseGenerationEvent

Kurz vor der Serialisierung des XML-Dokuments feuert der Generator:

EventEvent-NameWas kann geändert werden?
CxmlResponseGenerationEventagiqon_connector.cxml.response.generationDas vollständige SimpleXMLElement-Objekt

Beispiel:

use AgiqonConnector\Connector\System\Cxml\Event\CxmlResponseGenerationEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use SimpleXMLElement;

#[AsEventListener(event: CxmlResponseGenerationEvent::EVENT_NAME)]
final class MyCxmlResponseListener
{
public function __invoke(CxmlResponseGenerationEvent $event): void
{
$xml = $event->getCxml();

// Eigene XML-Elemente hinzufügen oder bestehende ändern
// $event->setCxml($modifiedXml);
}
}
info

Das Event erhält das fertig aufgebaute SimpleXMLElement. Über setCxml() kann das gesamte Dokument durch eine eigene Instanz ersetzt werden.