Paypal in Online-Shop integrieren mit PHP - Auf der eigenen Homepage Button erstellen, verkaufen und sale generieren

Paypal in Online-Shop integrieren mit PHP - Auf der eigenen Homepage Button erstellen, verkaufen und sale generieren

paypal credentials

Client ID und Secret (mit Fake-Credentials, die ähnlich wie die echten aussehen), Paypal Credentials

Bildmaße: 684 x 465 ,
Keywords: Api, credentials, Paypal

Paypal ist umfangreich und es ist schwer, sich zurechtzufinden. Das liegt daran, dass Paypal in der ganzen Welt vertreten ist. Manchmal benötigen verschiedene Länder verschiedene Technologien, außerdem entwickelt sich die zugrundeliegende Technik rasant, so dass immer Neuerungen hinzukommen, Abläufe veraltet erscheinen oder unsicher sind, so dass ein neuer Ablauf her muss. Auch die Regeln für den Geldverkehr ändern sich und der Online-Zahlungsverkehr muss sich anpassen, besonders an neue Sicherheitsrichtlinien. Das macht die Sache also sehr kompliziert. Ich möchte in diesem Artikel einige Möglichkeiten vorstellen. Konzentrieren möchte ich mich auf die PHP Rest-Api. Jeder Mensch hat andere Vorlieben, Fähigkeiten etc. Ich persönlich finde PHP sehr gut und praktisch, auch aus Sicherheitsgründen. Es ist eine Sprache, die in Entwicklung ist, das steigert die Sicherheit einer Sprache, wenn viele Menschen daran tätig sind.

Was ist die Paypal-Api

Was ist eine Api überhaupt? Das Wort API ist komplex, da es mehrere Bedeutungen hat. Im Prinzip ist es eine Schnittstelle (Application programming interface). In der Informatik ist ein Interface eine Definition der Methoden eines Programmes. Umgangsprachlich ist eine Api viel mehr als das. Wir wollen Methoden ja nicht nur definieren, sondern auch benutzen.

Paypal ist eine Bank und liefert einen Service. Früher ist man noch zur Bank gegangen oder man hat telefoniert. Heute kann man Käufe und Verkäufe online abwickeln.

Wikipedia definiert die Schnittstelle auch als Service: „Heutzutage stellen auch viele Online-Dienste Programmierschnittstellen zur Verfügung; diese heißen dann Webservice. Im weiteren Sinne wird die Schnittstelle jeder Bibliothek (engl. library) als Programmierschnittstelle bezeichnet."

Aber wie teile ich Paypal mit, dass jemand einen Kauf tätigen möchte, wie kann ich diesen Kauf direkt auf meinem Blog abwickeln und woher weiß Paypal, wer der Käufer ist und wer das Geld bekommen soll? Diese Mitteilungen erfolgen alle über das Internet. Anfragen gehen an die Api, und Anfragen werden von der Api beantwortet und bearbeitet. Curl ist ein Kommandozeilenprogramm, mit dem ich mit Webseiten ohne Umschweife über meine Console kommunizieren kann. Curl gibt es auch für PHP und kann dann serverseitig genutzt werden. Aber keine Angst, du musst dich nicht mit Curl herumschlagen. Dabei kommt nämlich solch hässlicher Code zustande:


curl -v -X GET https://api.sandbox.paypal.com/v1/payment-experience/web-profiles/XP-8YTH-NNP3-WSVN-3C76 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer Access-Token"

Was ist ein SDK und wofür brauche ich es?

Die Bezahlung per Paypal ein wundersamer Ablauf, den man selber erst mal verstehen muss, um dann den Code zu verstehen. Aber das geht Hand in Hand. Wenn ich den Code verstehen will, so muss man die Abläufe im Internet verstehen. Die Frage ist also: Wie funktioniert das Internet? In der Informatik hat man mehrere Ebenen, auf denen verschiedene Programme angesiedelt sind, die allesamt die Aufgabe haben, Abläufe möglichst einfach durchzuführen. Em Ende sitzt der Käufer, der von der ganzen Komplexität nichts, im Idealfall aber auch gar nichts, mitbekommt. Zuunterst ist der Maschinencode gelegen, der in Nullen und Einsen rechnet und abläuft. Darüber kommen weitere Schichten, irgendwann kommt die Paypal-Api. Man kann die Api auch direkt ansprechen, muss sich in diesem Fall allerdings auch selber um die Sicherheit kümmern. Das wird es bald höchstwahrscheinlich auch nicht mehr geben. Das Senden von Anfragen geschieht über die Curl-Bibliothek, eine Bibliothek, mit der man Gutes aber auch Böses anstellen kann. Verbrecher, also Hacker, arbeiten damit und nutzen diesen Code, um automatisiert an Server anfragen zu stellen, bis sie zusammenbrechen, oder bis sonst was passiert. Andererseits kann man dieses Instrument auch für gute Zwecke nutzen, um einfach Nachrichten oder Informationen im Allgemeinen abzurufen oder eben Transaktionen durchzuführen. Hier kommt das SDK ins Spiel. Damit wir uns mit dem dreckigen Curl-Code nicht abgeben müssen, werden diese Aufgaben in Klassen gekapselt und vereinfacht. SDK steht für Software Development Kit (Baukasten für die Entwicklung von Software). In diesen Baukästen (ja es gibt viele) gibt es einfache und intuitive Befehle, denen du nur die richtigen Argumente übergeben musst und sie tun dann die (Drecks-) Arbeit für dich. Das sind z.B. Funktionen wie execute, wobei das ganze, wenn ich es recht bedenke, so intuitiv gar nicht ist, denn in verschiedenen SDKs hat z.B. execute eine andere Bedeutung. Aber zumindest weiß man, was diese Funktion im Schilde führt, sie executed etwas, sie führt etwas aus, was genau, muss man dann genauer gucken. Durch die Datenkapselung und Verschachtelung in Namespaces und anderweitige Verschachtelungen ist natürlich nicht der ganze Code sichtbar. Der Code wird im Hintergrund geladen und es gehört auch eine Portion Vertrauen dazu, denn der Code ist groß, die Dateien dick und fett und man weiß nie, was darin verborgen ist. Nicht, dass ich Paypal misstrauen würde, sonst hätte ich den Code nicht auf meinen Server gepackt, aber man muss halt erwähnen, dass es eine Vertrauensfrage darstellt, ein SDK zu benutzen. Es versteht sich von selbst, dass man das SDK aus einer vertrauensvollen Quelle laden sollte. Paypal favorisiert den indirekten Weg über das Tool Composer, was auch wieder der Sicherheit dient, und man sollte das beherzigen. Es hat schon gute Gründe.

Installation der SDKs

Es gibt, soweit zu erkennen ist, für PHP zwei SDKs. Das Checkout-PHP-SDK und das PayPal-PHP-SDK. Auf Github steht über das Checkout-SDK folgendes: „Dies ist ein Teil des nächsten großen PayPal SDK.“ Es scheint also noch nicht vollständig operabel zu sein. Wichtig ist auch, dass die bisher besprochenen Smart Payment Buttons, über das Checkout-SDK betrieben werden und dass dieses nur auf PHP 5.6 oder höher läuft, laut Angaben auf Github. Das HTTPS-Protokoll, also eine Seite mit Sicherheitszertifikat und Verschlüsselung, wird ebenfalls benötigt. Paypal hat mit Braintree Großes vor und Mark Zuckerberg hat mit Paypal Großes vor. Braintree wurde 2013 von Paypal übernommen und scheint eine immer größere Rolle zu spielen, denn direkte Zahlungen per Kreditkarte sollen direkt über Braintree laufen. Das PayPal-PHP-SDK soll eigentlich nicht mehr genutzt werden und man wird auf die Checkout-SDK verwiesen. Dass das Paypal-PHP-SDK veraltet ist, sieht man auch daran, dass PHP 5.3 ausreicht.

Am einfachsten ist es, wenn du auf auf dem eigenen Computer einen Server installierst, z.B. XAMP, hier das gewünschte System konfigurierst und dann einfach per FTP die Ordner, wie sie Composer erstellt hat, hochlädst. Nicht jeder hat leider die Möglichkeit, per SSH auf dem Server zu arbeiten. Aber was ist Composer? Das SDK, besonders das Checkout SDK, hat viele Abhängigkeiten. D.h. es benötigt zum Betrieb weitere Dateien. Viele weitere Dateien. Da man selber nicht genau weiß, welche Dateien man braucht, damit das SDK ordnungsgemäß funktioniert, kommt Composer ins Spiel. Es ist ein Programm, das über die Kommandozeile bedienbar ist, und genau weiß, welche Dateien und Bibliotheken du brauchst und automatisch alles herunterlädt und bereitstellt. XAMPP ist sehr einfach zu installieren. Du brauchst Xamp, weil Composer auf PHP läuft. Auf Windows brauchst du also ein Programm namens php.exe und das kriegst du durch Xampp. Du musst den Server eigentlich auch gar nicht nutzen. Du brauchst nur die php.exe innerhalb des Gesamtpakets, das XAMPP liefert.

xamp

XAMPP gibt es für Windows, Linux sowie OS X, ein kostenloser Server.

Bildmaße: 502 x 423 ,
Keywords: Xamp, Server, Apache, Apachefriends

Du kriegst den Server auf der Seite der Apachefriends. Dann kannst du Composer installieren, das geht ebenfalls sehr einfach. Du kriegst Composer auf https://getcomposer.org/. Wenn du installierst, musst du vor der Installation noch den Standort der php.exe angeben, die Datei wird von Composer benötigt.


How to install Composer, Path to PHP.exe

Du findest die Datei php.exe im Ordner xampp/php, das ist der Pfad zur Datei php.exe.

Bildmaße: 300 x 97 ,
Keywords: Pfad, install, Composer, php.exe

Sobald du Composer installiert hast, kannst du es in der Console deines Computers von jedem Ordner aus aufrufen und musst nicht den Ordner wechseln. Das ist auch ganz einfach. So kannst du auch die Checkout-SDK herunterladen.


Installation der PHP-SDK von PayPal via Composer

Du musst nur den richtigen Befehl eingeben und das Programm kümmert sich um die Abhängigkeiten. Installation des paypal-checkout-sdk via Composer.

Bildmaße: 1366 x 444 ,
Keywords: Installation, paypal, checkout, sdk

Die Lock-Datei beinhaltet genaue Angaben zum heruntergeladenen Paket, so dass das Download exakt reproduzierbar ist. Das ist nützlich, wenn man für verschiedene Teams in einer Firma exakt die gleichen Versionen der Abhängigkeiten benötigt:


{
    "_readme": [
        "This file locks the dependencies of your project to a known state",
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "5a18ca45ec68842e3b98fddf2286c729",
    "packages": [
        {
            "name": "braintree/braintreehttp",
            "version": "0.3.0",
            "source": {
                "type": "git",
                "url": "https://github.com/braintree/braintreehttp_php.git",
                "reference": "204e36494d9e4b31033328df96af54b17f68b698"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/braintree/braintreehttp_php/zipball/204e36494d9e4b31033328df96af54b17f68b698",
                "reference": "204e36494d9e4b31033328df96af54b17f68b698",
                "shasum": ""
            },
            "require": {
                "ext-curl": "*"
            },
            "require-dev": {
                "phpunit/phpunit": "^5.7",
                "wiremock-php/wiremock-php": "1.43.2"
            },
            "type": "library",
            "autoload": {
                "psr-4": {
                    "BraintreeHttp\\": "lib/BraintreeHttp"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Braintree",
                    "email": "code@getbraintree.com"
                }
            ],
            "time": "2018-04-17T20:53:31+00:00"
        },
        {
            "name": "paypal/paypal-checkout-sdk",
            "version": "1.0.0",
            "source": {
                "type": "git",
                "url": "https://github.com/paypal/Checkout-PHP-SDK.git",
                "reference": "b321066fdce122cd63368b559d54674bdf2f12a8"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/paypal/Checkout-PHP-SDK/zipball/b321066fdce122cd63368b559d54674bdf2f12a8",
                "reference": "b321066fdce122cd63368b559d54674bdf2f12a8",
                "shasum": ""
            },
            "require": {
                "braintree/braintreehttp": "0.3.0"
            },
            "require-dev": {
                "phpunit/phpunit": "^5.7"
            },
            "type": "library",
            "autoload": {
                "psr-4": {
                    "PayPalCheckoutSdk\\": "lib/PayPalCheckoutSdk",
                    "Sample\\": "samples/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PayPal",
                    "homepage": "https://github.com/paypal/Checkout-PHP-SDK/contributors"
                }
            ],
            "description": "PayPal's PHP SDK for Checkout REST APIs",
            "homepage": "http://github.com/paypal/Checkout-PHP-SDK/",
            "keywords": [
                "checkout",
                "orders",
                "payments",
                "paypal",
                "rest",
                "sdk"
            ],
            "time": "2019-02-04T06:59:08+00:00"
        }
    ],
    "packages-dev": [],
    "aliases": [],
    "minimum-stability": "stable",
    "stability-flags": [],
    "prefer-stable": false,
    "prefer-lowest": false,
    "platform": [],
    "platform-dev": []
}


Neben einer Datei composer.json und der genannten composer.lock findest du auch den Ordner vendor, das Objekt der Begierde. Im Ordner drin sieht es so aus. Und im Ordner paypal ist dann der Ordner paypal-checkout-sdk. Du siehst also, dass es mit dem checkout-sdk nicht getan ist und dass weitere Abhängigkeiten bestehen, wie z.B. zum Ordner braintree, der braintreehttp enthält:


Inhalt des Ordners vendor von PayPal

So sieht es aus im Vendor-Ordner von Paypal.

Bildmaße: 210 x 161 ,
Keywords: vendor, Ordner, paypal-checkout-sdk, Ordnerstruktur

Sobald du nun den Ordner hast, kannst du ihn einfach per ftp auf deinen Server laden.


Einige nützliche Links:


  1. Die Api.

  2. Smart Payment Buttons.

  3. paypal-checkout-sdk installation.

  4. paypal-checkout-sdk auf github.

  5. Basic integration.

  6. Basic integration Beispiel.

  7. Verfügbare Programmiersprachen für das PayPal-PHP-SDK.

  8. Rest apis, get Startet.

  9. PayPal-PHP-SDK Example code.

  10. Zahlung durchführen.

  11. Autorisieren und Zahlung zu einem späteren Zeitpunkt durchführen.

Den Quickstart für das PayPal-PHP-SDK findest du

Die verschiedenen Methoden zur Durchführung eines Verkaufs - ein Sale generieren

  1. Es gibt sehr viele Methoden, die man zur Durchführung eines Sales nutzen kann. Die einfachste ist die Nutzung eines Buttons, den man sich auf der Paypal-Seite erstellt. Dafür brauchst du einen merchant account, also einen Business-Account (Geschäftskonto). Du logst dich ein und erstellst den Button. Hier gibst du auch die Redirect-Adresse (redirectUrls) an. Das sind die Adressen, zu der der Kunde nach dem Kauf wieder auf deine Seite zurückkehrt. Eine für die erfolgreiche Abwicklung des Kaufs und eine für den Fall, dass der Käufer den Kaufprozess abbricht. Der Kauf wird also komplett auf Paypal abgewickelt. Das ist wichtig für die Differenzierung der Methoden.

    Du kannst die Buttons auch manuell programmieren, und direkt in deine Seite einbauen (Smart Payment Buttons).

  2. Die Express-Checkout Methode besteht darin, dass der Käufer auf deine Seite zurückkehrt, um hier den Kauf abzuschließen. Express heißt die Methode, weil der Kunde einfach und schnell kaufen kann, denn er oder sie muss keine Daten eingeben. Du leitest den Kunden an Paypal, der Kunde bestätigt den Kauf, der Kunde wird zurückgeleitet, alle relevanten Kundendaten kann man nun im Hintergrund abrufen. Das ist für den Kunden praktisch, denn er muss nichts eingeben, keine Versandadressen, keine E-Mail, denn du kannst über die Api alle Informationen, die du zur Kaufabwicklung brauchst, abrufen.

Was ist eine ReST-Api genau und wie funktioniert der Ablauf

REST steht für „Representational State Transfer“, API für „Application Programming Interface“. Bei einem Transfer von Daten wird das Protokoll HTTP benutzt, überwiegend verschlüsselt, dabei kommen die Methoden Get und Post zum Einsatz. Bei der Get-Methode sind übergebene Daten sichtbar, weil sie in der URL übergeben werden, also quasi direkt mit der Internetadresse. Ein Beispiel ist eine Get-Anfrage an die Google-Api:


https://www.google.de/search?client=opera&q=was+ist+eine+api&sourceid=opera&ie=UTF-8&oe=UTF-8

Im Beispiel werden mehrere Informationen an Google übergeben:

  1. q (steht wohl für Query) ist „was+ist+eine+api“, wobei die Plus-Zeichen für Leerzeichen stehen. Der User hat also eingegeben „was ist eine api“.
  2. sourceid ist „Opera“.
  3. ie ist UTF-8
  4. oe ist UTF-8

Die einzelnen Informationen werden durch „&“ getrennt.

Bei der Post-Methode sind die Daten nicht sichtbar und werden im Hintergrund übergeben. Der Austausch oder Transfer von Daten lässt sich vergleichen mit einer Konversation, bei der einer etwas sagt, und der andere antwortet. Die Konversation wird nicht fortgeführt. Wenn man eine neue Anfrage stellt, kann der Server nicht auf die vorherigen Informationen zugreifen, um die neue Anfrage schneller zu verarbeiten. Zum Beispiel, weiß die Api nicht, dass ich vor 5 Minuten schon mal eine Anfrage gestellt habe und sie erspart mir nicht, mich ein weiteres Mal zu identifizieren bzw. zu autorisieren. Das würde in etwa damit vergleichbar sein:

Man stelle sich vor, dass so ein Gespräch in der Bank stattfinden würde. Die Leute würden denken, dass wir bekloppt sind. Ich stelle mich bei demselben Mitarbeiter für drei Anfragen dreimal vor.

Wie funktioniert ein Smart Payment Button?

Diese Buttons sind sehr praktisch und gut, weil sie sich an alle Geräte und Bildschirmgrössen anpassen. Das nennt man responsive Design und man braucht nichts zu machen, die Buttons sind schon responsive und passen sich automatisch dem Container an.

paypal buttons smart payment

Adaptive Paypal Buttons im responsiven Design, Paypal Smart Payment Buttons

Bildmaße: 765 x 248 ,
Keywords: Paypal, Api, Buttons, Java Script, Smart, Payment

Zugriff auf den eigenen Server, also den Ort, wo die eigene Homepage gehostet ist, sollte man eigentlich immer haben. Falls du noch Hilfe brauchst in dieser Materie, so schau dir ruhig mal meine Informationen zur Webseitenerstellung an. Hier der Code für die Homepage, die nur Buttons enthält. Du kannst ihn schon in der Produktion nutzen, du musst nur die Daten anpassen und vor allem deine Sandbox ID zum Testen einfügen. Wie und wo, das siehst du gleich.

<!DOCTYPE html>

<head>
    <!-- Add meta tags for mobile and IE -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="dcterms.created" content="So, 09 Jun 2019 04:30:54 GMT">
    <meta name="description" content="Paypal Demo von Karsten Fink andaptiert. ">
    <meta name="keywords" content="Smart, Payment, Buttons, Paypal, Api, Integration, via, Javascript">
    <title>Smart payment Buttons</title>	
</head>

<body>



    <!-- Wir erstellen ein leeres container element für den button,  
         hier wird derButton durch den Scipt eingefügt. -->

    <div id="paypal-button-container"></div>

    
    
    
    
    <!-- Das PayPal JavaScript SDK wird geladen. 
         Es kümmert sich um (fast) alles.
         Anstelle von  „sb“ nimmst du deine Sandbox-ID. 
         Du willst ja nicht, dass der Testshop von Alfredo Barco alles
         Geld kassiert.
         Falls der Code zu weit nach rechts rückt, klick auf den Code 
         und benutze die Pfeiltasten.-->
    <script src="https://www.paypal.com/sdk/js?currency=EUR&client-id=sb"></script>

    
    
    
        <!-- Der bestückte Button wird gerendert,  
         das Rendern findet statt im zuvor festgelegten 
		 Container. --> 
    
    <script>

        paypal.Buttons({

            // Wir bauen zuerst mit Json das Transaktionsobjekt 
createOrder: function(data, actions) {
 return actions.order.create({
  "intent": "CAPTURE",
  "application_context": {
    "return_url": "https://example.com",
    "cancel_url": "https://example.com",
    "brand_name": "Primitivecode.com",
    "locale": "de-DE",
    "landing_page": "BILLING",
    "shipping_preference": "SET_PROVIDED_ADDRESS",
    "user_action": "CONTINUE"
  },
  "purchase_units": [
    {
      "reference_id": "PUHF",
      "description": "Sporting Goods",

      "custom_id": "CUST-HighFashions",
      "soft_descriptor": "HighFashions",
      "amount": {
        "currency_code": "EUR",
        "value": "70.00",
        "breakdown": {
          "item_total": {
            "currency_code": "EUR",
            "value": "20.00"
          },
          "shipping": {
            "currency_code": "EUR",
            "value": "30.00"
          },
          "handling": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "tax_total": {
            "currency_code": "EUR",
            "value": "20.00"
          },
          "shipping_discount": {
            "currency_code": "EUR",
            "value": "10"
          }
        }
      },
      "items": [
        {
          "name": "T-Shirt",
          "description": "Green XL",
          "sku": "sku01",
          "unit_amount": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "tax": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "quantity": "1",
          "category": "PHYSICAL_GOODS"
        },
        {
          "name": "Shoes",
          "description": "Running, Size 10.5",
          "sku": "sku02",
          "unit_amount": {
            "currency_code": "EUR",
            "value": "5.00"
          },
          "tax": {
            "currency_code": "EUR",
            "value": "5.00"
          },
          "quantity": "2",
          "category": "PHYSICAL_GOODS"
        }
      ],
      "shipping": {
        "method": "United States Postal Service",
        "address": {
          "name": {
            "give_name":"John",
            "surname":"Doe"
          },
          "address_line_1": "123 Townsend St",
          "address_line_2": "Floor 6",
          "admin_area_2": "San Francisco",
          "admin_area_1": "CA",
          "postal_code": "94107",
          "country_code": "US"
        }
      }
    }
  ]
});
            },

            // Der Kauf wird abgeschlossen durch die Funktion capture.
            onApprove: function(data, actions) {
                return actions.order.capture().then(function(details) {
                    // Hier Rückmeldung generieren
					console.log (details);
                    alert('Transaction completed by ' + details.payer.name.given_name + '!');
                });
            }


        }).render('#paypal-button-container');
    </script>
</body>
    
</html>
testing shop

Der obige code erstellt bei Klick auf den Button diesen Testshop von primitivecode.

Bildmaße: 480 x 573 ,
Keywords: Shop, Paypal, Sandbox, Test

Du musst natürlich deine eigene Client-Id einfügen, damit der Shop funktioniert und nicht „sb“ Sonst steht zwar primitivecode.com drauf, aber da ist kein primitivecode.com drin, sondern Alfredo Barko's Teststore. Welcher Name bei Paypal genannt wird, steht im „application_context“-Objekt, das ein Unterobjekt des Transaktionsobjektes ist. Hier stehen Daten wie die Return-URL, wobei das vermutlich nicht funktioniert, weil der zugrundeliegende Code wieder auf die Shopseite zurückspringt. Das ist doch schon sehr praktisch, dass sich einfach ein kleines Paypal-Fenster über dem eigenen Shop auftut. Die Abwicklung nach dem Kauf bei Paypal packst du in die Funktion „then“, wo ich details z.B. in die Konsole geschrieben habe, weil ich mir das Objekt mal anschauen wollte. Wie du im Code für das Alert-Fenster siehst, kannst du auf die verschiedenen Eigenschaften mittels des Punkt-Operators zugreifen. Du kannst hier sehr schön nachvollziehen, dass der ganze Bankenapparat mittels Objekten in Json-Schreibweise aufgebaut ist. Diese Objekte, die sich sehr viele Ebenen tief verschachteln können, werden Milliardenfach jede Minute durch das Netz gejagt. Bei der Angabe von anderen Währungen oder wenn man an Barco zahlt, liegt die Zahlung erst mal auf Eis, d.h. die Zahlung ist offen. Wenn ich “sb“ durch meine Verkäufer-Id ersetze, funktioniert es. Eine andere Sache ist ebenfalls sehr wichtig und sollte erwähnt werden. Wenn du die Beträge zusammensetzt, so muss die Rechnung stimmen. Wenn z.B. ein Paar Schuhe 90 EUR kostet und du hast als Menge zwei bestimmt, so kann das Total nicht 30 EUR sein. Die Api meldet dir in der Konsole des Browsers diese Fehler.

Objekt details in der Konsole

Ein Blick in die Konsole zeigt das ganze Ausmaß des Objektes. Hier siehst du auch, wer wirklich hinter den Buttons steht, nämlich Alfredo. Seine E-Mail lautet: barco.03-facilitator@gmail.com und nicht detlef@primitivecode.com. So sieht es also aus, das Details-Objekt.

Bildmaße: 796 x 417 ,
Keywords: Paypal, Transaktion, Details, Konsole, Objekt

Transaktionen von detlef im Sandbox Account

Die Käufe haben funktioniert. Hier siehst du die Transaktionen von detlef@primitivecode.com im Sandbox Account.

Bildmaße: 807 x 557 ,
Keywords: Paypal, Sanbox, Account, Testkäufe, offen, abgeschlossen

Hier folgt nun der erweiterte Code. Nach Abschluss des Kaufs über die Funktion Capture, wird in diesem Beispiel mithilfe von fetch die Transaktionsnummer an den Server geleitet und von dort eine Antwort in Empfang genommen. Das Antworten erfolgt über die Funktion echo. Die Fetch-Aktion spielt sich im Hintergrund ab, und der User muss nur auf die Antwort des Servers warten. Diese Transaktionsnummer wird im PHP-Code in die Variable $Bestellnummer geschrieben und dann an die Paypal-Api weitergeleitet , um die Transaktionsdetails zu erhalten. In unserem Beispiel werden einfach die Details zurückgeleitet und im Json-Format in ein HTML-Element mit der ID Tasse geschrieben und dem User angezeigt. Vorher werden die Daten noch durch prettyprint formatiert. Der Inhalt wird in der Variablen Kaffee gespeichert, der Kaffee kommt also in die Tasse. Der Code kann so wie gedruckt benutzt werden, angepasst werden müssen natürlich die Client-ID und die URL, falls man den Code in der Produktion nutzen möchte. Da benutzt man nämlich nicht die Sandbox-Url.



Sale.html


<!DOCTYPE html>

<head>
    <!-- Add meta tags for mobile and IE -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="dcterms.created" content="So, 09 Jun 2019 04:30:54 GMT">
    <meta name="description" content="Paypal Demo von Karsten Fink andaptiert. ">
    <meta name="keywords" content="Smart, Payment, Buttons, Paypal, Api, Integration, via, Javascript">
    <title>Smart payment Buttons</title>	
</head>

<body>


   
    <!-- Wir erstellen ein leeres container element für den button,  
         hier wird derButton durch den Scipt eingefügt. -->

    <div id="paypal-button-container"></div>

    <br />
	<br />
	<br />
	<br />
	<br />
	
    <pre id="Tasse"></pre>
    
    
    <!-- Das PayPal JavaScript SDK wird geladen. 
         Es kümmert sich um (fast) alles.
         Anstelle von  „sb“ nimmst du deine Sandbox-ID. 
         Du willst ja nicht, dass der Testshop von Alfredo Barco alles
         Geld kassiert.
         Falls der Code zu weit nach rechts rückt, klick auf den Code 
         und benutze die Pfeiltasten.-->
    <script src="https://www.paypal.com/sdk/js?currency=EUR&client-id=hier_musst_du_deine_client-id_eintragen"></script>

    
    
    
        <!-- Der bestückte Button wird gerendert,  
         das Rendern findet statt im zuvor festgelegten 
		 Container. --> 
    
    <script>

        paypal.Buttons({

            // Wir bauen zuerst mit Json das Transaktionsobjekt 
createOrder: function(data, actions) {
 return actions.order.create({
  "intent": "CAPTURE",
  "application_context": {
    "return_url": "https://example.com",
    "cancel_url": "https://example.com",
    "brand_name": "Primitivecode.com",
    "locale": "de-DE",
    "landing_page": "BILLING",
    "shipping_preference": "SET_PROVIDED_ADDRESS",
    "user_action": "CONTINUE"
  },
  "purchase_units": [
    {
      "reference_id": "PUHF",
      "description": "Sporting Goods",

      "custom_id": "CUST-HighFashions",
      "soft_descriptor": "HighFashions",
      "amount": {
        "currency_code": "EUR",
        "value": "70.00",
        "breakdown": {
          "item_total": {
            "currency_code": "EUR",
            "value": "20.00"
          },
          "shipping": {
            "currency_code": "EUR",
            "value": "30.00"
          },
          "handling": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "tax_total": {
            "currency_code": "EUR",
            "value": "20.00"
          },
          "shipping_discount": {
            "currency_code": "EUR",
            "value": "10"
          }
        }
      },
      "items": [
        {
          "name": "T-Shirt",
          "description": "Green XL",
          "sku": "sku01",
          "unit_amount": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "tax": {
            "currency_code": "EUR",
            "value": "10.00"
          },
          "quantity": "1",
          "category": "PHYSICAL_GOODS"
        },
        {
          "name": "Shoes",
          "description": "Running, Size 10.5",
          "sku": "sku02",
          "unit_amount": {
            "currency_code": "EUR",
            "value": "5.00"
          },
          "tax": {
            "currency_code": "EUR",
            "value": "5.00"
          },
          "quantity": "2",
          "category": "PHYSICAL_GOODS"
        }
      ],
      "shipping": {
        "method": "United States Postal Service",
        "address": {
          "name": {
            "give_name":"John",
            "surname":"Doe"
          },
          "address_line_1": "123 Townsend St",
          "address_line_2": "Floor 6",
          "admin_area_2": "San Francisco",
          "admin_area_1": "CA",
          "postal_code": "94107",
          "country_code": "US"
        }
      }
    }
  ]
});
            },

            // Der Kauf wird abgeschlossen durch die Funktion capture.
            onApprove: function(data, actions) {
                return actions.order.capture().then(function(details) {
                    // Hier Rückmeldung generieren
					console.log (details);
                    alert('orderID ' + data.orderID );
					return fetch('https://www.primitivecode.com/project/vendor/paypal/paypal-checkout-sdk/samples/GetOrder.php', {
						   method: 'post',
          				   headers: {
						   'content-type': 'application/json'
         				    },
						body: data.orderID
					
                }).then(function (Antwort) {
				 console.log("Antwort: ");
				 console.dir(Antwort);
				 Rueckgabe = Antwort.json();// parses JSON response into native Javascript object
				 console.dir ("Rueckgabe von Homepage ist ein Promise-Objekt: ");
       			 console.dir(Rueckgabe);
				 return Rueckgabe; 
    			 })
		  		   .then(function(Kaffee) {
				     console.log("Das Promise-Objekt gibt ein weiteres Promise-Objekt zurueck, den eigentlichen Wert: ");
    			     console.log(Kaffee);
					 var container=document.getElementById("Tasse");
					 container.innerHTML = JSON.stringify(Kaffee, undefined ,2);
				   });
			  });
            }


        }).render('#paypal-button-container');
    </script>
</body>
    
</html>


GetOrder.php


<?php

namespace Sample;




    /**
     * error reporting wird erst einmal angeschaltet, d.h. 
     * die Fehler werden angezeigt, was gut 
     * für die Fehlerbehebung (Debugging) ist. Nicht vergessen 
     * in der Produktion wieder auszuschalten!
     */
     
error_reporting(E_ALL);
ini_set("display_errors", "on");
ini_set("display_startip_errors", "on");





    /**
     * Aus den Post-Daten wird die übergebene Bestellnummer ausgelesen. 
     */
     
$Bestellnummer = file_get_contents('php://input');



    /**
     * Die Datei autoload.php ist die wichtigste Datei. 
     * Sie muss geladen werden, damit 
     * das ganze System überhaupt läuft. Sie lädt alle 
     * anderen Dateien. 
     * Auch die Herstellung einer Verbindung zu den 
     * weiteren Namespaces wie z.B. 
     * use Sample\CaptureIntentExamples\CreateOrder; 
     * ist essentiell.
     * Auch die Pfade müssen stimmen, wenn man 
     * vendor/autoload.php laden möchte.
     * Vom aktuellen Verzeichnis __DIR__, wo die  
     * aufrufende Datei gespeichert ist, 
     * gehe ich fünf Ebenen nach oben und dann eine
     * von vendor nach unten oder nur drei nach oben.
     * Die Datei GetOrder.php ist in in Samples, also
     * vendor dann paypal dann paypal-checkout-sdk dann samples
     * Die Datei autoload.php ist in vendor
     * zusammen mit dem Ordner Paypal.
     */

require __DIR__ . '/../../../../vendor/autoload.php';

use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;
use Sample\CaptureIntentExamples\CreateOrder;



class GetOrder
{

    /**
     * Mithilfe dieser Funktion wird die 
     * Transaktion von der Api angefordert, 
     * es wird die Transaktionsnummer übergeben, 
     * die in $orderId gespeichert ist.
     * Der eigentliche Befehl ist OrdersGetRequest in 
     * $response = $client->execute(new OrdersGetRequest($orderId));
     * Die Antwort wird in der Variablen 
     * $response gespeichert.
     * Der Befehl ist verschachtelt in der Authentifizierung.
     * Vorher muss nämlich erst eine Authentifizierung
     * des Servers stattfinden, d.h. der Server, 
     * der die Anfrage stellt, 
     * muss sich ausweisen. Das geschieht in der 
     * statischen Funktion client(); 
     * Diese Funktion hat nichts mit dem Client,
     * also dem Browser, zu tun, wo der Kauf 
     * stattfindet. Die Funktion erstellt ein 
     * Authentifizierungsobjekt.
     * Dass die Funktion statisch ist, sieht man am ::.
     * Die Rückgabe an den Client erfolgt über 
     * echo 
     * json_encode($response->result, JSON_PRETTY_PRINT), "\n";
     * Die relevante Information wird als Json enkodiert, 
     * damit sie wieder zurückgeschickt werden kann.
     * Und sie wird durch JSON_PRETTY_PRINT 
     * verschönert, die Funktion gibt es auch in PHP.
     */
    public static function getOrder($orderId)
    {
        
        $client = PayPalClient::client();
        $response = $client->execute(new OrdersGetRequest($orderId));


        echo json_encode($response->result, JSON_PRETTY_PRINT), "\n";
    }
}



/**
 * $createdOrder = CreateOrder::createOrder()->result; habe ich
 * deaktiviert, denn wir kriegen ja eine Echte Bestellnummer.
 * 
 * Hier wird einfach die Funktion aufgerufen und die Bestellnummer übergeben.
 * 
 */
 
if (!count(debug_backtrace()))
{
    //$createdOrder = CreateOrder::createOrder()->result;
    GetOrder::getOrder($Bestellnummer);
}
?>


Im Prinzip sind das nur einige Zeilen Code. Durch die Kommentare erscheint es viel und auch dadurch, dass die Paypal SDK Objektorientiert programmiert ist. Aufgrund der Tatsache, dass es sich um ein sehr großes Projekt handelt, in das auch der Code von Braintree eingebunden ist, werden auch Namespaces benutzt. Die Hürde bei der Einbindung von Smart Payment Express Checkout Buttons und vor allem, wenn man das selber machen will, ohne überteuerte Shopsysteme, ohne dass diese Systeme ihr SEO durch ihren aufgeblasenen Code aufmöbeln, ohne dass man Speicherplatz opfern muss und ohne Kopfschmerzen und Abhängigkeit von der Gnade dieser Anbieter, ist, dass man einige Programmierkenntnisse haben muss. An dem Punkt fragt man sich, wie der eigene Server sich bei Paypal authentifiziert, denn es werden sensible Daten nicht nur von einem selbst, sondern auch vom Käufer preisgegeben: z.B. Lieferadresse, Name und E-Mail. Man stößt dann auf die Klasse PayPalClient, die sich im Namensraum Sample\PayPalClient befindet. Öffnet man diese Datei mit der Klasse PayPalClient, so stellt man fest, dass genau diese Datei für die Identifizierung des Servers bei Paypal dient, also für die persönliche Authentifizierung, dazu, dass ich kein Verbrecher bin, sondern jemand der legale Transaktionen durchführen will. Man benötigt also noch eine Änderung in einer Datei, um die Zahlung durchzuführen:


PayPalClient.php


<?php

namespace Sample;

use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;


class PayPalClient
{
    /**
     * Zuerst wird ein Environment-Objekt erstellt. 
     * Dieses beinhaltet Client ID und Secret.
     * Dieses Environment-Objekt wird an die Klasse 
     * PayPalHttpClient übergeben.
     * Dabei kommt eine Instanz von HTTP client 
     * heraus, die das Environment enthält und  
     * auch die Zugangsdaten. Damit kann 
     * dann die API aufgerufen werden, 
     * vorausgesetzt, der Berechtigungsnachweis 
     * genügt den Zugangsüberprüfungen.
     */
    public static function client()
    {
        return new PayPalHttpClient(self::environment());
    }
    
    /**
     * Aufbau des Environments, mit dem 
     * zurückgegebenen Objekt hat man dann die 
     * Zugangsberechtigung zur Api.
     * Es ist für Testzwecke geeignet, 
     * weshalb wir SandboxEnvironment nutzen.
     * In der Produktion ist es das LiveEnvironment.
     * Die Funktion getenv() habe ich in den 
     * Tiefen des SDKs nicht gefunden.
     * Und nicht vergessen, deine Credentials 
     * in der Funktion 
     * public static function environment()
     * einzugügen.
     */
    public static function environment()
    {
        $clientId = getenv("Bitte hier zwischen Gänsefüßchen deine CientID einfügen.") ?: "Bitte hier zwischen Gänsefüßchen deine CientID einfügen.";
        $clientSecret = getenv("Bitte hier zwischen Gänsefüßchen das Secret einfügen.") ?: "Bitte hier zwischen Gänsefüßchen das Secret einfügen.";
        return new SandboxEnvironment($clientId, $clientSecret);
    }
}

Ablauf der Transaktion

Ablauf der Transaktion

Wie eine Transaktion vor sich geht, der Ablauf.

Bildmaße: 2063 x 1941 ,
Keywords: Paypal, Transaktion, Smart, Payment, Buttons, Ablauf, requests, response

Ablauf der Transaktion

So sieht es dann aus, zuerst findet der Kauf statt, es öffnet sich über der Webseite mit dem Kaufbutton ein Fenster von Paypal, das sieht elegant aus und geht schnell, Sale mit Smart Payment Buttons.

Bildmaße: 1366 x 734 ,
Keywords: Paypal, Transaktion, Smart, Payment, Buttons, Ablauf, Sale

Ablauf der Transaktion

Nach Klick auf "Jetzt bezahlen" wird der Kauf sofort abgewickelt , dann kehrt der Käufer auf die Seite zurück, es öffnet sich das Alert-Fenster, der Code wird angehalten, nach Bestätigung arbeitet der Code weiter, Sale mit Smart Payment Buttons.

Bildmaße: 1315 x 328 ,
Keywords: Paypal, Transaktion, Smart, Payment, Buttons, Ablauf, Sale

Ablauf der Transaktion

Nun wird per fetch der Server aufgerufen, dieser ruft die Paypal-Api auf, fordert die Transaktionsdaten an, bekommt sie und sendet sie zurück, wie in der Konsole und auf der Seite zu sehen ist. Die Transaktionsdaten werden unter dem Button dynamisch eingefügt, Sale mit Smart Payment Buttons.

Bildmaße: 1325 x 627 ,
Keywords: Paypal, Transaktion, Smart, Payment, Buttons, Ablauf, Sale



Description: Wir erklären heute, wie man auf seiner Webseite den Verkauf über Paypal integriert. Wir schauen uns die zugrunde liegende Technik an, so dass du auch selbst einen Warenkorb programmieren kannst.

Keywords: Verkaufen, Paypal, Button, Verkauf, sale, abwickeln, Abwicklung, Verkäufer, Käufer, Transaktion, transaction, Zahlung, Payment, api, rest, erstellen, integrieren, Spenden-Link, onlineshop, online, shop, create, token, PaymentExecution, execute
Geschrieben:
Sprache: de (Deutsch)

Primitivecode ist Grammatik pur. Aber Programmieren kommt auch nicht zu kurz, denn die Seite mache ich allein. Informationen zum Datenschutz findest du hier.