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
- Header aufbauen – From und To werden nach cXML-Konvention getauscht (der ursprüngliche
Towird zumFromder Antwort und umgekehrt) - BuyerCookie aus Session-
additionalFieldseinfügen - PunchOutOrderMessageHeader mit
operationAllowed,quoteStatus="final"und Gesamtpreis - Optional: Versand anhängen (wenn
attachShippingaktiv) - Optional: Steuer anhängen (wenn
attachTaxaktiv) - LineItems iterieren → je Position den passenden Resolver finden → Feldbaum rekursiv rendern
CxmlResponseGenerationEventfeuern → XML kann noch modifiziert werden- Ausgabe bereinigen (Zeilenumbrüche + Whitespace zwischen Tags entfernen)
Preis-Konfiguration
| System-Einstellung | Verwendeter Preis |
|---|---|
isTotalPriceNet() = true | Cart::getPrice()::getNetPrice() |
isTotalPriceNet() = false | Cart::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.dtdgesetzt
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:
| Event | Event-Name | Was kann geändert werden? |
|---|---|---|
CxmlResponseGenerationEvent | agiqon_connector.cxml.response.generation | Das 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);
}
}
Das Event erhält das fertig aufgebaute SimpleXMLElement. Über setCxml() kann das gesamte Dokument durch eine eigene Instanz ersetzt werden.