ich arbeite gerade an einer Shopware-Instanz mit Headless-Funktion, d.h. alle Aktionen gehen über die REST API.
Bei der Integration des PayPal-Plugins im Backend mit den Smart Payment-Buttons von PayPal im Frontend komme ich leider nicht mehr weiter. Es ist mir zwar gelungen, die Bestellung im Backend anzulegen, die Zahlung über PayPal durchzuführen (mithilfe eines vorhergehenden Aufrufs von /store-api/v3/paypal/spb/create-order um eine ID zu erzeugen) und den Webhook des Plugins zu nutzen, sodass die Bestellung als “bezahlt” markiert wird.
Was jedoch nicht funktioniert, ist, dass die beiden Custom Fields **swag\_paypal\_token** und **swag\_paypal\_transaction\_id** in der **order-transaction** gesetzt werden. Das führt leider dazu, dass in der Admin-Oberfläche keine Details zur PayPal-Zahlung abgerufen werden können.
Wer hat einen Tipp, welche Route des PayPal-Plugins ich nutzen kann, um die Custom Fields nach der Zahlung zu setzen?
um die Bezahlung komplett abzuschließen, solltest du noch die HandlePaymentMethodRoute aufrufen. Diese Route sorgt wiederum dafür dass PayPalPaymentHandler::pay aufgerufen wird. Hierbei ist wichtig, dass du den Parameter „isPayPalSpbCheckout“ mitsendest, Dieser wird hier gebraucht, um eine Smart Payment Button Zahlung zu erkennen. Anschließend wird der schon von dir genannte EcsSpbHandler aufgerufen. Dieser benötigt noch „paypalOrderId“ als Parameter, wo du die ID der aktuellen PayPal-Order mitsenden musst. Danach sollte das auch korrekt in der DB abgespeichert sein.
Meine Aussagen beziehen sich jetzt auf die aktuellste Version des PayPal Plugins (2.0.2).
besten Dank für deine ausführliche Antwort! Das hat mich der Lösung ein großes Stück näher gebracht
Nachdem ich **/handle-payment** mit den erforderlichen Parametern aufrufe, werden die beiden Custom Fields gesetzt und ich erhalte eine redirectUrl zurück. Diese Redirect URL ist jedoch nicht immer gleich. Sie führt manchmal zu https://** sandbox.paypal.com/checkoutnowund manchmal zu http:// **localhost/payment/finalize-transaction
Ich konnte bisher nicht herausfinden, wann welche URL zurückgegeben wird.
Jenachdem, welche URL zurückgegeben wird, passiert folgendes:
wenn ich der URL zu paypal.com folge, werde ich erneut aufgefordert auf “Jetzt bezahlen” zu klicken (obowhl das vorher schon passiert ist). Anschließend wird man über http://localhost/payment/finalize-transaction (302 FOUND) zur finishUrl weitergeleitet, die beim Aufruf von /handle-payment mitgegeben wurde.
wenn ich (direkt) der URL zu /finalize-transaction (inkl. Parameter) folge, wird ein 404 NOT FOUND geschmissen:
Der zusätzliche Schritt über paypal.com/checkoutnow erscheint mir nicht richtig, da der Kunde zuvor schon auf “Jetzt bezahlen” geklickt hat und man das Payment theoretisch auch im Frontend (ohne paypal.com/checkoutnow aufzurufen) über actions.order.capture() einziehen könnte.
Wenn ich mich nicht täusche, erfolgt im Demoshop auch kein zweiter Redirect zu paypal.com nach dem Aufruf von /handle-payment. Hast du eine Idee, was bei meinem Prozess noch fehlt/falsch ist?
//UPDATE #1: okay, das Rätsel um die verschiedenen Redirect URLs scheint gelöst: der Request zu /handle-payment sollte ein POST sein, wobei einige der Parameter (z.B. der isPayPalSpbCheckout ) im Body und andere (z.B. die orderId ) im Query String erwartet werden. Um diese “Falle” zu vermeiden führe ich nun einen POST mit allen Parametern als Query String und gleichzeitig im Body durch. Dann wird stets die Redirect URL zu /finalize-transaction zurückgeliefert.
Fraglich ist noch, weshalb diese zu dem o.g. 404 Not Found führt
//UPDATE #2 : ich bin fälschlicherweise davon ausgegangen, dass der “Payment Capture”-Prozess serverseitig bei /finalize-transaction ausgeführt wird. Das scheint aber nicht der Fall zu sein. Wenn ich das Capture im Frontend über **actions.order.capture() **durchführe, ist der Request zu /finalize-transaction vermutlich nicht mehr notwendig. Die Bestellung befindet sich (durch den Webhook) im Status paid und die Details zur Transaktion werden (durch den Request zu /handle-payment ) im PayPal-Tab angezeigt. Also alles wie es sein sollte
genau, im Prinzip machen wir das genauso, nur über die Storefront. Nachdem die „handle-payment“ Route aufgerufen ist, kannst du einfach zur Finish Seite weiterleiten
Viele Grüße aus Schöppingen
Michael Telgmann
PS: übrigens schön zu sehen, dass das PayPal Plugin auch in einem Headless Shop funktioniert
ich stehe aktuell vor dem gleichen Problem wie Mike. Also das PayPal Plugin bei einem Headless Shop zum funktionieren zu bringen Ich fand diesen thread schon sehr hilfreich, danke an dieser Stelle schonmal. Bei mir ist es aktuell so, dass ich eine Bestellung durchgeführt bekomme, aber dann im Backend der Zahlungsstatus als “in Bearbeitung” steht. Die Reihenfolge in der ich meine Aufrufe durchführe ist die folgende —> /paypal/spb/create-order —> bezahlen —> /checkout/order ----> handle-payment. Ich befürchte das an der Reihenfolge etwas nicht stimmt. Das zweite Problem das ich habe ist, dass ich nicht weiß, was für einen Wert ich dem Parameter isPayPalSpbCheckout geben soll. Wär super wenn ihr (oder irgendjemand anderes) mir da irgendwie weiterhelfen könntet
den Parameter „isPayPalSpbCheckout“ einfach den Wert „true“ übergeben. Dadurch wird im PayPal Payment Handler der Workflow für die Smart Payment Buttons ausgelöst.
danke für deine schnelle Antwort. Ich versteh leider immernoch nicht so ganz wie ich eine Bestellung auf bezahlt setzen kann, muss eine Bestellung vor der Bezahlung erstellt werden? Bzw. muss ich die handle-payment route vor der Bezahlung aufrufen, oder wie versteht shopware dass die Bezahlung vernünftig durchgeführt wurde? Wenn ich das richtig verstanden habe muss ich irgendwas mit der Webhook machen?
Ich hänge leider auch bei dem Paypal/Headless-Prozess. Vielleicht hat jemand einen Tipp/Anschub!
Ich habe SW6 als Headless-Variante umgesetzt. Im Falle einer Paypal-Zahlungsmethode starte ich den Paypal-Prozess indem ich über die Paypal-eigene API die Zahlung erstelle, im Erfolgsfall erstelle ich die Bestellung über die SW6-Api (checkout/order) und führe dann die Zahlung via Paypal-API aus. Als Rückgabe erhalte ich die Zahlungs-ID sowie das Token zur Paypal-Zahlung. Wie bekomme ich nun diese Informationen in die entsprechende Bestellung?
Ich befürchte, dass die Implementierung der Zahlung über das Paypal-Plugin erfolgen muss (nicht über eine eigene Implementierung über die Paypal-API). Hat jemand Informationen oder Ressourcen, wie das Paypal-Plugin über die Rest-API von SW6 genutzt werden soll/muss? Gibt es eine Dolumentation dazu?
du hast es zwischenzeitlich vielleicht schon selbst gelöst, ich lass mein Kommentar trotzdem mal hier:
ich nehme an du hast im Frontend die Smart Payment Buttons (SPB) von PayPal, richtig? Bei den Buttons sieht man häufig die client-seitige Zahlungsabwicklung:
paypal.Buttons({
// Set up the transaction (client-side)
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '88.44'
}
}]
});
},
// etc...
}).render('#paypal-button-container');
Wir wollen die PayPal-Zahlung aber über Shopware abwickeln lassen, d.h. du musst in der createOrder()-Methode die entsprechende Route des PayPal-Plugins (/store-api/paypal/spb/create-order) aufrufen:
Soweit ich weiß, wird anhand des sw-context-token der Warenkorb des Kunden abgerufen und eine Order im Backend erstellt, die mit dieser PayPal-Zahlung dann direkt verknüpft ist (siehe SPBCreateOrderRoute.php).