Skip to content

Commit d92e247

Browse files
committed
feat: Initial commit
1 parent 22cec43 commit d92e247

17 files changed

Lines changed: 741 additions & 2 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
app/private/.keys.env
2+
app/vendor/**
3+
composer.lock
4+
.DS_store

Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM php:8.1.18-apache
2+
3+
RUN apt-get update && apt-get install -y git
4+
5+
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
6+
7+
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
8+
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
9+
10+
# Install Composer
11+
RUN curl -sS https://getcomposer.org/installer | php -- --check && \
12+
export COMPOSER_MEMORY_LIMIT=-1 && \
13+
composer self-update --1 && \
14+
composer install --no-interaction --optimize-autoloader
15+
16+
RUN a2enmod rewrite && service apache2 restart

README.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,66 @@
1-
# sendcloud-checkout-php-example
2-
For the launch of the new Sendcloud Checkout API, I wrote a PHP service to show the checkout methods and their functions
1+
# Sendcloud Dynamic Checkout API - PHP Example Project
2+
3+
This repository hosts a simple PHP app that lists the delivery methods associated with your specified Sendcloud Dynamic Checkout Configuration
4+
5+
6+
## Documentation
7+
8+
[Sendcloud Dynamic Checkout API Documentation](https://api.sendcloud.dev/docs/sendcloud-public-api/dynamic-checkout)
9+
10+
11+
## Environment Variables
12+
13+
To run this project, you will need to add the following environment variables to your keys.env file
14+
15+
`API_KEY` : Your Sendcloud API Public Key
16+
17+
`SECRET_KEY` : Your Sendcloud API Private Key
18+
19+
`CHECKOUTID` : The ID of the Dynamic Checkout Configuration you are testing
20+
## Run in Docker
21+
22+
Clone the project
23+
24+
```bash
25+
git clone https://github.com/AlexLamond/sendcloud-checkout-php-example
26+
```
27+
28+
Go to the project directory and start the server
29+
30+
```bash
31+
docker compose -f "docker-compose.yaml" up -d --build
32+
```
33+
34+
[Launch the server](http://localhost:8080)
35+
## Run Locally
36+
37+
38+
Clone the project
39+
40+
```bash
41+
git clone https://github.com/AlexLamond/sendcloud-checkout-php-example
42+
```
43+
44+
Go to the web directory
45+
46+
```bash
47+
cd app/public
48+
```
49+
50+
Install the dependancies
51+
52+
```bash
53+
composer install
54+
```
55+
56+
Run the local PHP server
57+
58+
```bash
59+
php -S 127.0.0.1:8070
60+
```
61+
62+
[Launch the server](http://localhost:8080)
63+
## Contributing
64+
65+
Contributions are welcome, please add clear descriptions of changes made
66+
Pull requests should be committed with semantic naming

app/composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"require": {
3+
"vlucas/phpdotenv": "^5.5"
4+
}
5+
}

app/private/.keys.example.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
API_KEY=
2+
SECRET_KEY=
3+
CHECKOUTID=

app/private/Carrier.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/**
4+
* Summary of Carrier
5+
*/
6+
Class Carrier
7+
{
8+
public $name;
9+
public $logo_url;
10+
public $code;
11+
/**
12+
* Summary of __construct
13+
* @param array $carrier
14+
*/
15+
function __construct(array $carrier)
16+
{
17+
$this->name = $carrier['name'];
18+
$this->logo_url = $carrier['logo_url'];
19+
$this->code = $carrier['code'];
20+
}
21+
}

app/private/Functions.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
require_once(__DIR__."/../vendor/autoload.php");
4+
5+
Class Functions
6+
{
7+
static function setEnvVars()
8+
{
9+
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, ".keys.env");
10+
$dotenv->load();
11+
}
12+
}

app/private/GetCheckoutConfig.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/**
4+
* Summary of CheckoutConfig
5+
*/
6+
class CheckoutConfig {
7+
8+
static private $base_url = "https://panel.sendcloud.sc/api/v2/checkout/configurations/";
9+
private $url;
10+
private $key;
11+
private $secret;
12+
/**
13+
* Summary of __construct
14+
* @param string $configid
15+
* @param string|null $apikey
16+
* @param string|null $apisecret
17+
*/
18+
19+
function __construct(? string $checkoutid, ? string $apikey, ? string $apisecret)
20+
{
21+
Functions::setEnvVars();
22+
23+
$this->url = empty($checkoutid) ? self::$base_url.$_ENV['CHECKOUT_ID']."/delivery-options" : self::$base_url.$checkoutid."/delivery-options" ;
24+
$this->key = empty($apikey) ? $_ENV['API_KEY'] : $apikey;
25+
$this->secret = empty($apisecret) ? $_ENV['SECRET_KEY'] : $apisecret;
26+
}
27+
/**
28+
* Summary of getAllDeliveryOptions
29+
* @return string
30+
*/
31+
public function getAllDeliveryOptions(string $to_country, int $weight): array
32+
{
33+
$key = CheckoutConfig::generateApiKey();
34+
35+
$body = ["from_country" => "NL", "to_country" => $to_country, "value" => 0, "weight" => $weight];
36+
37+
$ch = curl_init();
38+
curl_setopt($ch, CURLOPT_URL, $this->url."?".http_build_query($body));
39+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
40+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
41+
curl_setopt($ch, CURLOPT_USERPWD,$key);
42+
$response = json_decode(curl_exec($ch), true);
43+
self::checkResponse($response);
44+
return $response;
45+
}
46+
/**
47+
* Summary of generateApiKey
48+
* @return string
49+
*/
50+
private function generateApiKey(): string
51+
{
52+
return $this->key.":".$this->secret;
53+
}
54+
private function checkResponse($response){
55+
if(!isset($response['delivery_options']))
56+
{
57+
throw new Exception("No delivery options have been specified. Please configure dynamic checkout first");
58+
}
59+
}
60+
}
61+
62+
?>

app/private/Method.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/**
4+
* Summary of CheckoutMethod
5+
*/
6+
Class CheckoutMethod
7+
{
8+
public $id;
9+
public $title;
10+
public $description;
11+
public $cut_off_time;
12+
public $checkoutMethodPrice;
13+
public array $checkoutDates;
14+
/**
15+
* Summary of __construct
16+
* @param array $method
17+
*/
18+
function __construct(array $method)
19+
{
20+
$this->id = $method['id'];
21+
$this->title = $method['title'];
22+
$this->description = $method['description'];
23+
$this->cut_off_time = $method['cut_off_time'];
24+
$this->checkoutMethodPrice = new CheckoutMethodPrice($method['shipping_rate']);
25+
$this->checkoutDates = isset($method['delivery_dates']) ? $method['delivery_dates'] : [["delivery_date"=> "Anytime", "parcel_handover_date" => "Anytime"]];
26+
}
27+
}
28+
29+
/**
30+
* Summary of CheckoutMethodPrice
31+
*/
32+
Class CheckoutMethodPrice extends CheckoutMethod
33+
{
34+
public $price;
35+
public $currency;
36+
/**
37+
* Summary of __construct
38+
* @param array $rate
39+
*/
40+
function __construct(array $rate)
41+
{
42+
43+
$this->price = isset($rate['price']) ? $rate['price'] : 0;
44+
$this->currency = $rate['currency'];
45+
}
46+
}

app/private/SendOrder.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/**
4+
* Summary of Order
5+
*/
6+
Class Order
7+
{
8+
private $name;
9+
private $house_number;
10+
private $address;
11+
private $city;
12+
private $postal_code;
13+
var $telephone;
14+
var $country;
15+
static $request_label = false;
16+
static $is_return = false;
17+
var $parcel_handover_date;
18+
static $quantity = 1;
19+
var $shipment_id;
20+
var $weight;
21+
static $order_number = random_bytes(32);
22+
static $url = "https://panel.sendcloud.sc/api/v2/parcel";
23+
24+
/**
25+
* Summary of __construct
26+
* @param mixed $name
27+
* @param mixed $house_number
28+
* @param mixed $address
29+
* @param mixed $city
30+
* @param mixed $postal_code
31+
* @param mixed $telephone
32+
* @param mixed $country
33+
* @param mixed $parcel_handover_date
34+
* @param mixed $weight
35+
*/
36+
function __construct($name, $house_number, $address, $city, $postal_code, $telephone, $country, $parcel_handover_date, $weight){
37+
$this->name = $name;
38+
$this->house_number = $house_number;
39+
$this->address = $address;
40+
$this->city = $city;
41+
$this->postal_code = $postal_code;
42+
$this->telephone = $telephone;
43+
$this->country = $country;
44+
$this->parcel_handover_date = $parcel_handover_date;
45+
$this->weight = $weight;
46+
}
47+
48+
function Create(): string
49+
{
50+
$ch = curl_init();
51+
curl_setopt($ch, CURLOPT_URL, $this->url);
52+
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->ParamsToHTTP());
53+
$result = curl_exec($ch);
54+
return $result;
55+
56+
}
57+
58+
function ParamsToHTTP(): string
59+
{
60+
$body = ["parcel"=>["name"=>$this->name,"house_number"=>$this->house_number,"address"=>$this->address,"city"=>$this->city,"postal_code"=>$this->postal_code,"telephone"=>$this->telephone,"country"=>$this->country,"request_label"=>$this->request_label,"is_return"=>$this->is_return,"parcel_handover_date"=>$this->parcel_handover_date,"quantity"=>$this->quantity,"shipment_id"=>$this->shipment_id,"weight"=>$this->weight,"order_number"=>$this->order_number]];
61+
return http_build_query($body);
62+
}
63+
}

0 commit comments

Comments
 (0)