PayPal Tracking Nummern übertragen

Hi Community,

heute möchte ich mal als stillschweigender Leser auch was zurückgeben.

Ich musste mir etwas überlegen, damit PayPal nicht soviel Geld einbehält und der eigene Status verbessert wird. Ich denke andere haben das Problem auch, bzw. wollen es nicht erst zu einem Problem werden lassen. Manuell jeder Bestellung bei PayPal die Sendungsverfolgung einzutragen war keine Dauerlösung und ein Plugin wollte ich dafür nicht kaufen/installieren.
Also habe ich mich mit der REST API beschäftigt und eine PHP gebastelt, die vom Server per Cronjob um 00:10 Uhr aufgerufen wird und für jede gepackte Bestellung die Sendungsverfolgung an PayPal schickt.

Erklärungen:

  • ich nutze Pickware, die Sendungsnummern sind in der Shopware Datenbank. Ansich kann man die Abfragen aber auch für jede andere Datenbank anpassen.
  • ich habe 3 Versandarten: Deutsche Post, DHL und UPS, daher 3 getrennte SQL Abfragen wegen den unterschiedlichen zu reportenden carrier (Versender)
  • Bei vielen Paketen am Tag erreicht man möglicherweise ein Rate Limit. Man kann aber auch statt einmal in 24h einfach jede letzte Stunde an PayPal reporten und die PHP 24x am Tag aufrufen.
  • Anpassen muss man die Client ID und den Secret Key, sowie den Datenbank Zugang bzw. evtl. auch die Abfrage und den carrier, wenn man andere benutzt. Den genutzten Carrier sieht man auch bei den Transaktionen, wenn man eine händisch gepflegt hat.
  • Ich lasse mir das Ergebnis des Cronjob immer vom Server schicken, dann sehe ich ob alle Aufrufe geklappt haben oder ich ein Rate Limit erreicht habe.

P.S.: Der Code ist mit Vorsicht zu genießen, ich bin weder PHP Entwickler noch SQL-Experte. Die PHP hat aber schon seit Dezember mehrere tausende Tracking IDs erfolgreich verarbeitet und PayPal hat sich noch nicht beschwert :wink:

Die Dokumentation liegt hier: https://developer.paypal.com/docs/tracking/integrate/

Und so sieht die PHP aus:

<?php
// ------------------------------------------------------------- Fetch Access / Bearer Token from PayPal */
$curl = curl_init();

/* Sandbox PayPal
$url = "https://api.sandbox.paypal.com/v1/oauth2/token";
$clientId = "von-paypal-erhalten";
$secret = "von-paypal-erhalten"; */

/* Live PayPal */
$url = "https://api.paypal.com/v1/oauth2/token";
$clientId = "von-paypal-erhalten";
$secret = "von-paypal-erhalten";

curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
//We need to send grant_type=client_credentials in POST Request Body
CURLOPT_POSTFIELDS => "grant_type=client_credentials",
//Setting Basic Authentication using Client ID and Secret
CURLOPT_USERPWD => $clientId.":".$secret,
// This specific header needs to be set for the API call to work
CURLOPT_HTTPHEADER => array("Content-Type: application/x-www-form-urlencoded"),)
); 

//make API request
$result = curl_exec($curl);

//close connection
curl_close($curl);

//convert json response into PHP associative array
$response = json_decode($result, true);
$access_token = $response['access_token'];

//echo $access_token."<br />";

// ------------------------------------------------------------- SQL Request
	$host="localhost";
	$user="admin";
	$password="passwort";
	$database="datenbank";

// Create connection
	$conn = new mysqli($host, $user, $password, $database);
// Check connection
	if ($conn->connect_error) {
	  die("Connection failed: " . $conn->connect_error);
	}

// DEUTSCHE POST Trackingcodes
	$dp_query = "
		SELECT s_order.transactionID, s_viison_german_post_shipments.trackingCode 
		FROM s_order
		INNER JOIN s_viison_german_post_shipments ON s_order.id=s_viison_german_post_shipments.orderId 
		WHERE s_viison_german_post_shipments.created > (SELECT now() - INTERVAL 1 DAY) AND s_order.paymentID = 7 AND s_viison_german_post_shipments.returnShipment = 0";
	$dp_result = $conn->query($dp_query);
		
	if ($dp_result->num_rows > 0) {
		while($row = $dp_result->fetch_assoc()) {
			$transaction_id = $row["transactionID"];
			$tracking_number = $row["trackingCode"];
			$carrier = 'DHL_DEUTSCHE_POST';
			echo $row["transactionID"]." ".$row["trackingCode"]." ".$carrier."<br />";
			$result = curl_addtracking($transaction_id,$tracking_number,$carrier,$access_token);
		}
	}

// UPS Trackingcodes
	$ups_query = "
		SELECT s_order.transactionID, s_order_viison_ups.trackingCode 
		FROM s_order
		INNER JOIN s_order_viison_ups ON s_order.id=s_order_viison_ups.orderId 
		WHERE s_order_viison_ups.created > (SELECT now() - INTERVAL 1 DAY) AND s_order.paymentID = 7 AND s_order_viison_ups.returnShipment = 0";
	$ups_result = $conn->query($ups_query);
		
	if ($ups_result->num_rows > 0) {
		while($row = $ups_result->fetch_assoc()) {
			$transaction_id = $row["transactionID"];
			$tracking_number = $row["trackingCode"];
			$carrier = 'UPS';
			echo $row["transactionID"]." ".$row["trackingCode"]." ".$carrier."<br />";
			$result = curl_addtracking($transaction_id,$tracking_number,$carrier,$access_token);
		}
	}

// DHL Trackingcodes
	$dhl_query = "
		SELECT s_order.transactionID, s_order_viison_dhl.trackingCode 
		FROM s_order
		INNER JOIN s_order_viison_dhl ON s_order.id=s_order_viison_dhl.orderId 
		WHERE s_order_viison_dhl.created > (SELECT now() - INTERVAL 1 DAY) AND s_order.paymentID = 7 AND s_order_viison_dhl.returnShipment = 0";
	$dhl_result = $conn->query($dhl_query);
		
	if ($dhl_result->num_rows > 0) {
		while($row = $dhl_result->fetch_assoc()) {
			$transaction_id = $row["transactionID"];
			$tracking_number = $row["trackingCode"];
			$carrier = 'DE_DHL_PACKET';
			echo $row["transactionID"]." ".$row["trackingCode"]." ".$carrier."<br />";
			$result = curl_addtracking($transaction_id,$tracking_number,$carrier,$access_token);
		}
	}
// Close connection
	$conn->close();

// ------------------------------------------------------------- Add tracking information to one or more transactions */
function curl_addtracking($transaction_id,$tracking_number,$carrier,$access_token) {
	$curl = curl_init();

	//API Endpoint
	/* Live PayPal */
	$url = 'https://api.paypal.com/v1/shipping/trackers-batch'; 
	/* Sandbox PayPal
	$url = 'https://api.sandbox.paypal.com/v1/shipping/trackers-batch'; */

	//tracking info
	$tracker = array( 'transaction_id' => $transaction_id,
					  'tracking_number' => $tracking_number,
					  'status' => 'SHIPPED',
					  'carrier' => $carrier); 

	// The trackers array, the API can handle multiple transactions at a time.
	$trackers = array('trackers' => array($tracker));

	curl_setopt_array($curl, array(
		CURLOPT_URL => $url,
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_ENCODING => "",
		CURLOPT_MAXREDIRS => 10,
		CURLOPT_TIMEOUT => 0,
		CURLOPT_FOLLOWLOCATION => true,
		CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		CURLOPT_CUSTOMREQUEST => "POST",
		CURLOPT_POSTFIELDS => json_encode($trackers),
		CURLOPT_HTTPHEADER => array(
		"Authorization: Bearer {$access_token}",
		"Content-Type: application/json"
	  ),
	));

	$response = curl_exec($curl);

	curl_close($curl);

	echo $response;
}
?>

Falls hier auch pfiffige Entwickler dabei sind, oder jemand weiß, wie man mehrere Trackingnummern senden kann, ohne das Rate Limit zu erreichen, freue ich mich auf Feedback. Der PayPal Support konnte/wollte nicht helfen.

Hoffe, ich konnte dem einen oder anderen damit helfen :wink:

2 Likes