EasyWebshop API

The Application Programming Interface (API) bridges your webshop to external platforms such as payment providers, delivery services and office applications. We have put in tremendous effort to make the API easy to use, even for non tech nerds. This will in some cases allow our users to connect their webshop themselves instead of having to rely on an expensive developer.

Image of developers

Thanks to compatibility with general practices and industry standards, connections to our API can be made quickly and possibly with the help of AI generated code. Read this page carefully if you want to create a connection yourself.

Feature overview

  • Connect to payment service providers
  • Connect to delivery services
  • Connect to POS software, local and cloud
  • Import products from suppliers or wholesalers
  • Export products to comparison sites
  • Connect invoicing software
  • Connect CRM software
  • Connect logistics management software
  • Update stock (inventory) in real-time
  • Accept or deny customers based on certain criteria
  • Export orders in real-time for drop shipping
  • Export customers for newsletter applications
  • Export data for reports and analytics
  • Create connections that install HTML/JavaScript/CSS widgets with the click of a button
  • Create custom reports for inventory, orders, customers and sales

API, API Push, and Connections

APIAPI PushConnections
For importing and exporting categories, products, orders and customers.For synchronizing stock or accepting customers in real-time.For connecting payment providers, delivery services, comparison sites, point of sales, invoicing applications and installing widgets.
Authentication with Bearer token.Enter Push URL in API module.Authentication with Bearer token (connection) and installing the connection (user).
Customized to one user.Customized to one user.Can be installed by all users.


API

Activate the EasyWebshop API at Settings > Modules > Easywebshop API using the activation code MODA.
If EasyWebshop API is not shown in the menu, navigate to Settings > More options > User experience level and change the user experience level to Expert.

API Module

Only activate the API if you are going to use it. For security reasons, deactivate the API when not in use.

API endpointCopy
https://easywebshop.com/apiAlways use the https version! Authenticating over plain-text http may cause your API Token to be leaked.
Do not include the www sub domain.
?format=xml
Change the output format from JSON to XML.
?pretty=1
Pretty output for improved human readability. Remove this to save bandwidth in automated systems.

When using multiple parameters, separate with & (ampersand). For example: ?format=xml&pretty=1.
On the command line, escape ampersands like this: ?format=xml\&pretty=1.

Use our API with care and only query or update what you need. Do not use polling if the API Push feature can be used instead. Limits are imposed to prevent wasting server resources.

Authentication

Click the Add button to create an API Token and select the desired permissions for this token.

API Permissions

For added security, only select permissions that are strictly necessary. Revoke permissions when they are not needed.

After saving, copy your API Token for use in your application or to send it to a developer. You can only do this once: if you lose your API Token, you will have to delete it and create a new one.

API Token

Use your API Token with care.
Do not send your API Token over an insecure communications channel such as email or WhatsApp. We recommend SimpleX Chat if you need to send your API Token to a developer. Do not store your API Token on an insecure device. We do not store your API Token at all, only a hash of it.

  • Request
  • Response
  • curl
  • PHP
GET /api/status HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": "API online" } Retrieves the API status curl -D - https://easywebshop.com/api/status Saves the response in a JSON file curl https://easywebshop.com/api/status -o status.json -D, --dump-header -o, --output <file> curl man page: https://curl.se/docs/manpage.html <?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/status';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Optional: If you are sending data (e.g., for a POST request)
// Uncomment the following lines to send a JSON payload
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
*/

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;
}

// Close the cURL session
curl_close($ch);
?>

Copy

In this documentation, we provide examples for curl and PHP. Modern AI is increasingly good at converting code to other programming languages such as C, Java or Python.

Categories

Viewing categories

GET /api/category
Retrieves all categories
GET /api/category/[categoryName]
Retrieves all products within a specific category
Use the category name in the default language of the webshop
GET /api/category HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "categorylist": [ { "category": { "name:lang=en": "Cocktails", "name:lang=fr": "Cocktails", "name:lang=nl": "Cocktails", "visible": "1", "image": "https:\/\/ew.ms\/shops\/fashion\/category\/cocktails.jpg", "url": "https:\/\/all4you.be\/cocktails", "categorylist": [ { "category": { "name:lang=en": "Non-alcoholic", "name:lang=fr": "Sans alcool", "name:lang=nl": "Alcoholvrij", "visible": "1", "url": "https:\/\/all4you.be\/non-alcoholic" } } ] } } ] } Retrieves all categories curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/category Retrieves all products within a specific category curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/category/Cocktails Retrieves all categories in human readable JSON format curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/category?pretty=1 Retrieves all categories in human readable XML format curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/category?format=xml\&pretty=1<?php
header
("Content-Type: text/plain");

// API endpoint
// You can add a category name behind the slash for searching products within that category
const API_URL 'https://easywebshop.com/api/category/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Optional: If you are sending data (e.g., for a POST request)
// Uncomment the following lines to send a JSON payload
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
*/

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "categorylist": [ { "category": { "name:lang=en": "Cocktails", "name:lang=fr": "Cocktails", "name:lang=nl": "Cocktails", "visible": "1", "image": "https:\/\/ew.ms\/shops\/fashion\/category\/cocktails.jpg", "url": "https:\/\/all4you.be\/cocktails", "categorylist": [ { "category": { "name:lang=en": "Non-alcoholic", "name:lang=fr": "Sans alcool", "name:lang=nl": "Alcoholvrij", "visible": "1", "url": "https:\/\/all4you.be\/non-alcoholic" } } ] } } ] } <?xml version="1.0" encoding="UTF-8" ?> <categorylist> <category> <name lang="en">Cocktails</name> <name lang="fr">Cocktails</name> <name lang="nl">Cocktails</name> <visible>1</visible> <image>https://ew.ms/shops/fashion/category/cocktails.jpg</image> <url>https://all4you.be/cocktails</url> <categorylist> <category> <name lang="en">Non-alcoholic</name> <name lang="fr">Sans alcool</name> <name lang="nl">Alcoholvrij</name> <visible>1</visible> <url>https://all4you.be/non-alcoholic</url> </category> </categorylist> </category> </categorylist>

Copy

Categories can be viewed only. There is no API implementation for creating, editing and deleting categories because these features are rarely used and would create additional attack surface. Managing categories can be done by using the web interface.

Products

Viewing products

EasyWebshop follows the schema.org/Product format whenever possible.

GET /api/product
Retrieves the last 1000 products
GET /api/product?offset=1000
Retrieves the last 1000 products, but skips the first 1000 products
GET /api/product/86400
Retrieves products that were added or modified within the last 24h
GET /api/product/[productID]
Searches for a product by productID, case sensitive
GET /api/product HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "productlist": [ { "product": { "productID": "LA-B03", "category": "Ambiance", "price": 49.99, "stock": 0, "weight": 5, "status": "Available", "vat_code": 0, "old_price": "75", "colors": "Blue,Red,Violet", "promotion": 1 } }, { "product": { "productID": "LA-C05", "category": "Ambiance", "name:lang=en": "Example paint", "name:lang=nl": "Voorbeeld verf", "description:lang=en": "Lorem ipsum dolor sit amet.", "price": 79, "stock": 1, "status": "Available", "weight": 5, "vat_code": 0, "condition": "New", "gtin": "123456", "old_price": "179", "units": "test", "mpq": 1, "purchase_price": 50, "promo": 1, "label_id": 1, "colors": "Blue,Red,Violet", "params": "T,en,Name,,,\nS,en,Select size,[A|B|C],A,1", "review": 1 } }, { "product": { "productID": "LA-C05-A", "parent_productID": "LA-C05", "name:lang=en": "Variation A", "price": "79", "colors": "LightCoral" } }, { "product": { "productID": "LA-C05-B", "parent_productID": "LA-C05", "name:lang=en": "Variation B", "price": "89" } } ] } Retrieves the last 1000 products curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/product Retrieves the last 1000 products, but skips the first 1000 products curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/product?offset=1000 Retrieves products that were added or modified within the last 24h curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/product/86400 Searches for a product by productID, case sensitive curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/product/LA-C05<?php
header
("Content-Type: text/plain");

// API endpoint
// You can add a product search behind the slash
const API_URL 'https://easywebshop.com/api/product/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Optional: If you are sending data (e.g., for a POST request)
// Uncomment the following lines to send a JSON payload
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
*/

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($categories json_decode($responsetrue)) {
        echo 
"\n\n" print_r($categoriestrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "productlist": [ { "product": { "productID": "LA-B03", "category": "Ambiance", "price": 49.99, "stock": 0, "weight": 5, "status": "Available", "vat_code": 0, "old_price": "75", "colors": "Blue,Red,Violet", "promotion": 1 } }, { "product": { "productID": "LA-C05", "category": "Ambiance", "name:lang=en": "Example paint", "name:lang=nl": "Voorbeeld verf", "description:lang=en": "Lorem ipsum dolor sit amet.", "price": 79, "stock": 1, "status": "Available", "weight": 5, "vat_code": 0, "condition": "New", "gtin": "123456", "old_price": "179", "units": "test", "mpq": 1, "purchase_price": 50, "promo": 1, "label_id": 1, "colors": "Blue,Red,Violet", "params": "T,en,Name,,,\nS,en,Select size,[A|B|C],A,1", "review": 1 } }, { "product": { "productID": "LA-C05-A", "parent_productID": "LA-C05", "name:lang=en": "Variation A", "price": "79", "colors": "LightCoral" } }, { "product": { "productID": "LA-C05-B", "parent_productID": "LA-C05", "name:lang=en": "Variation B", "price": "89" } } ] } <?xml version="1.0" encoding="UTF-8" ?> <productlist> <product> <productID>LA-B03</productID> <category>Ambiance</category> <price>49.99</price> <stock>0</stock> <weight>5</weight> <status>Available</status> <vat_code>0</vat_code> <old_price>75</old_price> <colors>Blue,Red,Violet</colors> <promotion>1</promotion> </product> <product> <productID>LA-C05</productID> <category>Ambiance</category> <name lang="en">Example paint</name> <name lang="nl">Voorbeeld verf</name> <description lang="en">Lorem ipsum dolor sit amet.</description> <price>79</price> <stock>1</stock> <status>Available</status> <weight>5</weight> <vat_code>0</vat_code> <condition>New</condition> <gtin>123456</gtin> <old_price>179</old_price> <units>test</units> <mpq>1</mpq> <purchase_price>50</purchase_price> <promo>1</promo> <label_id>1</label_id> <colors>Blue,Red,Violet</colors> <params>T,en,Name,,, S,en,Select size,[A|B|C],A,1</params> <review>1</review> </product> <product> <productID>LA-C05-A</productID> <parent_productID>LA-C05</parent_productID> <name lang="en">Variation A</name> <price>79</price> <colors>LightCoral</colors> </product> <product> <productID>LA-C05-B</productID> <parent_productID>LA-C05</parent_productID> <name lang="en">Variation B</name> <price>89</price> </product> </productlist>

Copy

Importing products

POST /api/product
On success, 201 Created will be returned
POST /api/product HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json { "productlist": [ { "product": { "productID": "LA-B03", "category": "Ambiance", "price": 49.99, "stock": 0, "weight": 5, "status": "Available", "vat_code": 0, "old_price": "75", "colors": "Blue,Red,Violet", "promotion": 1 } }, { "product": { "productID": "LA-C05", "category": "Ambiance", "name:lang=en": "Example paint", "name:lang=nl": "Voorbeeld verf", "description:lang=en": "Lorem ipsum dolor sit amet.", "price": 79, "stock": 1, "status": "Available", "weight": 5, "vat_code": 0, "condition": "New", "gtin": "123456", "old_price": "179", "units": "test", "mpq": 1, "purchase_price": 50, "promo": 1, "label_id": 1, "colors": "Blue,Red,Violet", "params": "T,en,Name,,,\nS,en,Select size,[A|B|C],A,1", "review": 1 } }, { "product": { "productID": "LA-C05-A", "parent_productID": "LA-C05", "name:lang=en": "Variation A", "price": "79", "colors": "LightCoral" } }, { "product": { "productID": "LA-C05-B", "parent_productID": "LA-C05", "name:lang=en": "Variation B", "price": "89" } } ] } HTTP/2 201 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": [ "4 products inserted" ] } curl -X POST -H "Authorization: Bearer YOUR_API_TOKEN" -d @product-import.json https://easywebshop.com/api/product<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/product/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Uncomment the following lines to set data in PHP
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];

$data = json_encode($data);
*/

// Get data from file
$data file_get_contents('product-import.json');

curl_setopt($chCURLOPT_POSTtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "productlist": [ { "product": { "productID": "LA-B03", "category": "Ambiance", "price": 49.99, "stock": 0, "weight": 5, "status": "Available", "vat_code": 0, "old_price": "75", "colors": "Blue,Red,Violet", "promotion": 1 } }, { "product": { "productID": "LA-C05", "category": "Ambiance", "name:lang=en": "Example paint", "name:lang=nl": "Voorbeeld verf", "description:lang=en": "Lorem ipsum dolor sit amet.", "price": 79, "stock": 1, "status": "Available", "weight": 5, "vat_code": 0, "condition": "New", "gtin": "123456", "old_price": "179", "units": "test", "mpq": 1, "purchase_price": 50, "promo": 1, "label_id": 1, "colors": "Blue,Red,Violet", "params": "T,en,Name,,,\nS,en,Select size,[A|B|C],A,1", "review": 1 } }, { "product": { "productID": "LA-C05-A", "parent_productID": "LA-C05", "name:lang=en": "Variation A", "price": "79", "colors": "LightCoral" } }, { "product": { "productID": "LA-C05-B", "parent_productID": "LA-C05", "name:lang=en": "Variation B", "price": "89" } } ] } <?xml version="1.0" encoding="UTF-8" ?> <productlist> <product> <productID>LA-B03</productID> <category>Ambiance</category> <price>49.99</price> <stock>0</stock> <weight>5</weight> <status>Available</status> <vat_code>0</vat_code> <old_price>75</old_price> <colors>Blue,Red,Violet</colors> <promotion>1</promotion> </product> <product> <productID>LA-C05</productID> <category>Ambiance</category> <name lang="en">Example paint</name> <name lang="nl">Voorbeeld verf</name> <description lang="en">Lorem ipsum dolor sit amet.</description> <price>79</price> <stock>1</stock> <status>Available</status> <weight>5</weight> <vat_code>0</vat_code> <condition>New</condition> <gtin>123456</gtin> <old_price>179</old_price> <units>test</units> <mpq>1</mpq> <purchase_price>50</purchase_price> <promo>1</promo> <label_id>1</label_id> <colors>Blue,Red,Violet</colors> <params>T,en,Name,,, S,en,Select size,[A|B|C],A,1</params> <review>1</review> </product> <product> <productID>LA-C05-A</productID> <parent_productID>LA-C05</parent_productID> <name lang="en">Variation A</name> <price>79</price> <colors>LightCoral</colors> </product> <product> <productID>LA-C05-B</productID> <parent_productID>LA-C05</parent_productID> <name lang="en">Variation B</name> <price>89</price> </product> </productlist>

Copy

You can find a detailed explanation of all product fields on the documentation page of Basic product management and Advanced product management.

ParameterTypeDescription
productIDstringArticle. A unique and user defined identifier for the product.
Avoid special characters and duplicate or ambiguous identifiers. When editing a product the productID is used as an identifier. The productID can only be changed with product management.
parent_productIDstringIf you want this product to be a product variation, enter here the productID of the parent product. Variations act like products on their own. They are connected to a parent product instead of a category and are therefore not visible in product lists. Sub variations are not recommended and can only be set with product management.
categorystringThe name of the category in the default language of the webshop. Not applicable for product variations.
name:langstringName. You can set names and descriptions for all languages, even if they are not activated in the webshop.
Available languages (ISO 639-1): cs, da, de, el, en, es, fi, fr, it, ja, ko, nl, no, pl, pt, ro, ru, sv, tr, zh
description:langstringDescription
Available languages (ISO 639-1): cs, da, de, el, en, es, fi, fr, it, ja, ko, nl, no, pl, pt, ro, ru, sv, tr, zh
pricestringPrice. Can be decimal, integer, empty or a string.
stockintegerInventory. Leave at 0 for infinite stock or disabled stock.
statusstringStatus
Available, Available but not online, Pre-order, Sold Out, Invisible, Customers only, Price visible for customers, Choose property, Hide status, custom0, custom1, ..., custom9
image:nostringInclude an image URL to upload product photos. The first image is the main photo, the next four are sub photos. When a product photo already exists, it will be replaced. After uploading, the images will be scaled proportionally according to the webshop settings, thumbnails will be created automatically and the image will be synchronized to multiple file servers. Make sure that each image has a valid URL, a maximum file size of 25MB, a valid extension (.jpg, .jpeg, .png or .gif) and a valid MIME type (image/jpeg, image/jpg, image/png, image/gif).
Uploading images takes time and server resources. Avoid replacing the same images when updating products. If you encounter time-outs, upload a limited number of products in batches of 25 images each.1 - 5
thumbnail:nostringThumbnails are generated automatically. This is a read only parameter.
weightdecimalWeight. SI unit kilogram.
vat_codeintegerTax rate. VAT Rate set at invoice settings.
0, 1, 2
conditionstringCondition
New, Used, Refurbished
gtinstringEAN code
old_pricestringOld price
unitsstringUnits
mpqintegerMinimum purchase
purchase_pricedecimalPurchase price
promobooleanPromote this product on the homepage of my shop. Not applicable for product variations.
label_idintegerLabel. Leave at 0 for no label. Not applicable for product variations.
0 - 100
colorsstringColors. Choose from the 256 web safe color names in English, separated by commas.
paramsstringProduct personalization. Parameters have a special format and can best be set using the product management interface. Once you have an example, you can copy it for importing.
reviewbooleanReviews. Enable or disable product reviews.
last_updatedatetimeLast activity. Read only.

These sections can only be set using the management interface: quantity discounts, customer groups, gift vouchers, reservations, digital products, filters, related products.

Up to 100 products can be imported at once. If you want to import more products, you can repeat the command once every 5 minutes.

Editing products

You can also edit products using the quick edit feature, the import feature and the bulk operations feature.

PUT /api/product
On success, 200 OK will be returned
PUT /api/product HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json { "productlist": [ { "product": { "code": "LA-C05", "price": 16, "status": "Available", "stock": 7, "image:no=1": "https://easywebshop.com/img/slideshow/9001.jpg", "image:no=2": "https://easywebshop.com/img/easywebshop.png" } }, { "product": { "code": "SI-V55", "price": "28", "status": "Sold Out", "stock": "0", "weight": "2", "old_price": "43" } } ] } HTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": [ "Product SI-V55 not found, skipping", "1 products updated" ] } curl -X PUT -H "Authorization: Bearer YOUR_API_TOKEN" -d @product-edit.json https://easywebshop.com/api/product<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/product/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Uncomment the following lines to set data in PHP
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];

$data = json_encode($data);
*/

// Get data from file
$data file_get_contents('product-edit.json');

curl_setopt($chCURLOPT_CUSTOMREQUEST'PUT');
curl_setopt($chCURLOPT_POSTFIELDS$data);

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "productlist": [ { "product": { "code": "LA-C05", "price": 16, "status": "Available", "stock": 7, "image:no=1": "https://easywebshop.com/img/slideshow/9001.jpg", "image:no=2": "https://easywebshop.com/img/easywebshop.png" } }, { "product": { "code": "SI-V55", "price": "28", "status": "Sold Out", "stock": "0", "weight": "2", "old_price": "43" } } ] } <?xml version="1.0" encoding="UTF-8" ?> <productlist> <product> <code>LA-C05</code> <price>16</price> <status>Available</status> <stock>7</stock> <image no="1">https://easywebshop.com/img/slideshow/9001.jpg</image> <image no="2">https://easywebshop.com/img/easywebshop.png</image> </product> <product> <code>SI-V55</code> <price>28</price> <status>Sold Out</status> <stock>0</stock> <weight>2</weight> <old_price>43</old_price> </product> </productlist>

Copy

If you want to update product stock, only update the fields status and stock. Remember to set the appropriate product status for situations like Sold out or Infinite stock.

Up to 100 products can be updated at once. If you want to update more products, you can repeat the command once every 5 minutes.

Deleting products

DELETE /api/product/[productID]
On success, 204 No Content will be returned
  • Request
  • Response
  • curl
  • PHP
DELETE /api/product/LA-C05 HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 204 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 curl -k -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/product/LA-C05<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/product/LA-B03';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);


curl_setopt($chCURLOPT_CUSTOMREQUEST'DELETE');

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
$httpcode curl_getinfo($chCURLINFO_HTTP_CODE);
    if (
$httpcode == 204) {
        echo 
"Delete successful";
    } else {
        echo 
$response;
    }

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }


}

// Close the cURL session
curl_close($ch);
?>

Copy

Customers

Viewing customers

EasyWebshop follows the schema.org/Person format.

GET /api/customer
Retrieves the last 1000 customers
GET /api/customer?offset=1000
Retrieves the last 1000 customers, but skips the first 1000 customers
GET /api/customer/86400
Retrieves customers that were added or modified within the last 24h
GET /api/customer/[email]
Retrieves a specific customer by email address
GET /api/customer HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "customerlist": [ { "customer": { "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "en", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "memberOf": "OpenGroup", "denied": 0 } }, { "customer": { "givenName": "Cindy", "familyName": "Test", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "cindytest@ew.ms", "denied": 0 } } ] } Retrieves the last 1000 customers curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/customer Retrieves the last 1000 customers, but skips the first 1000 customers curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/customer?offset=1000 Retrieves customers that were added or modified within the last 24h curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/customer/86400 Retrieves a specific customer by email address curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/customer/email@address.com<?php
header
("Content-Type: text/plain");

// API endpoint
// You can add an email address behind the slash for searching a specific customer
const API_URL 'https://easywebshop.com/api/customer/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Optional: If you are sending data (e.g., for a POST request)
// Uncomment the following lines to send a JSON payload
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
*/

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($categories json_decode($responsetrue)) {
        echo 
"\n\n" print_r($categoriestrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "customerlist": [ { "customer": { "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "en", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "memberOf": "OpenGroup", "denied": 0 } }, { "customer": { "givenName": "Cindy", "familyName": "Test", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "cindytest@ew.ms", "denied": 0 } } ] } <?xml version="1.0" encoding="UTF-8" ?> <customerlist> <customer> <givenName>Test</givenName> <familyName>Buddy</familyName> <brand></brand> <vatID></vatID> <knowsLanguage>en</knowsLanguage> <address> <addressCountry>BE</addressCountry> <addressLocality>Gent</addressLocality> <addressRegion></addressRegion> <postalCode>9000</postalCode> <streetAddress>Veldstraat</streetAddress> <houseNo>1</houseNo> </address> <telephone>123456789</telephone> <email>testbuddy@ew.ms</email> <memberOf>OpenGroup</memberOf> <denied>0</denied> </customer> <customer> <givenName>Cindy</givenName> <familyName>Test</familyName> <brand></brand> <vatID></vatID> <knowsLanguage>nl</knowsLanguage> <address> <addressCountry>BE</addressCountry> <addressLocality>Gent</addressLocality> <addressRegion></addressRegion> <postalCode>9000</postalCode> <streetAddress>Veldstraat</streetAddress> <houseNo>1</houseNo> </address> <telephone>123456789</telephone> <email>cindytest@ew.ms</email> <denied>0</denied> </customer> </customerlist>

Copy

Importing customers

Each customer receives an email for verifying the email address.

POST /api/customer
On success, 201 Created will be returned
POST /api/customer HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json { "customerlist": [ { "customer": { "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "en", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "memberOf": "OpenGroup", "denied": 0 } }, { "customer": { "givenName": "Cindy", "familyName": "Test", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "cindytest@ew.ms", "denied": 0 } } ] } HTTP/2 201 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": [ "Customer testbuddy@ew.ms: inserted successfully", "Customer testbuddy@ew.ms: verification email sent successfully", "Customer cindytest@ew.ms: inserted successfully", "Customer cindytest@ew.ms: verification email sent successfully", "2 customers inserted" ] } curl -X POST -H "Authorization: Bearer YOUR_API_TOKEN" -d @customer-import.json https://easywebshop.com/api/customer<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/customer/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Uncomment the following lines to set data in PHP
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];

$data = json_encode($data);
*/

// Get data from file
$data file_get_contents('customer-import.json');

curl_setopt($chCURLOPT_POSTtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "customerlist": [ { "customer": { "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "en", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "memberOf": "OpenGroup", "denied": 0 } }, { "customer": { "givenName": "Cindy", "familyName": "Test", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "cindytest@ew.ms", "denied": 0 } } ] } <?xml version="1.0" encoding="UTF-8" ?> <customerlist> <customer> <givenName>Test</givenName> <familyName>Buddy</familyName> <brand></brand> <vatID></vatID> <knowsLanguage>en</knowsLanguage> <address> <addressCountry>BE</addressCountry> <addressLocality>Gent</addressLocality> <addressRegion></addressRegion> <postalCode>9000</postalCode> <streetAddress>Veldstraat</streetAddress> <houseNo>1</houseNo> </address> <telephone>123456789</telephone> <email>testbuddy@ew.ms</email> <memberOf>OpenGroup</memberOf> <denied>0</denied> </customer> <customer> <givenName>Cindy</givenName> <familyName>Test</familyName> <brand></brand> <vatID></vatID> <knowsLanguage>nl</knowsLanguage> <address> <addressCountry>BE</addressCountry> <addressLocality>Gent</addressLocality> <addressRegion></addressRegion> <postalCode>9000</postalCode> <streetAddress>Veldstraat</streetAddress> <houseNo>1</houseNo> </address> <telephone>123456789</telephone> <email>cindytest@ew.ms</email> <denied>0</denied> </customer> </customerlist>

Copy

Detailed information can be found on the customer management wiki page.

ParameterTypeDescription
emailstringEmail address. The email address is the unique identifier for the customer.
givenNamestringFirst name
familyNamestringLast name
brandstringCompany
vatIDstringVAT Number
knowsLanguagestringLanguage (ISO 639-1): cs, da, de, el, en, es, fi, fr, it, ja, ko, nl, no, pl, pt, ro, ru, sv, tr, zh
addressCountrystringCountry (ISO_3166-1)
addressLocalitystringCity / Town
addressRegionstringCounty / Province / State. Not required for most countries and often omitted to make the checkout form shorter.
postalCodestringZip code. Not all countries have zip codes.
streetAddressstringStreet
houseNostringHouse number. Some places have no house numbers.
telephonestringPhone
memberOfstringCustomer group
statusstringStatus
Unconfirmed, Confirmed, Denied
deniedbooleanDenied
0 - 1
newsletterbooleanReceive newsletter. Only customers themselves can activate this.
registration_datedatetimeRegistration date. Read only.

Up to 100 customers can be imported at once. If you want to import more customers, you can repeat the command once every 5 minutes.

Editing customers

Note that only customers can update their data as a security measure. You can update the customer group and the customer status (allowed or denied).

PUT /api/customer
On success, 200 OK will be returned
PUT /api/customer HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json { "customerlist": [ { "customer": { "email": "cindytest@ew.ms", "memberOf": "OpenGroup", "denied": 0 } } ] } HTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": [ "Customer cindytest@ew.ms: updated successfully", "1 customers updated" ] } curl -X PUT -H "Authorization: Bearer YOUR_API_TOKEN" -d @customer-edit.json https://easywebshop.com/api/customer<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/customer/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Uncomment the following lines to set data in PHP
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];

$data = json_encode($data);
*/

// Get data from file
$data file_get_contents('customer-edit.json');

curl_setopt($chCURLOPT_CUSTOMREQUEST'PUT');
curl_setopt($chCURLOPT_POSTFIELDS$data);

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "customerlist": [ { "customer": { "email": "cindytest@ew.ms", "memberOf": "OpenGroup", "denied": 0 } } ] } <?xml version="1.0" encoding="UTF-8" ?> <customerlist> <customer> <email>cindytest@ew.ms</email> <memberOf>OpenGroup</memberOf> <denied>0</denied> </customer> </customerlist>

Copy

Up to 100 customers can be updated at once. If you want to update more customers, you can repeat the command once every 5 minutes.

Deleting customers

DELETE /api/customer/[email]
On success, 204 No Content will be returned
  • Request
  • Response
  • curl
  • PHP
DELETE /api/customer/email@address.com HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 204 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 curl -k -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/customer/email@address.com<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/customer/email@address.com';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);


curl_setopt($chCURLOPT_CUSTOMREQUEST'DELETE');

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
$httpcode curl_getinfo($chCURLINFO_HTTP_CODE);
    if (
$httpcode == 204) {
        echo 
"Delete successful";
    } else {
        echo 
$response;
    }

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }


}

// Close the cURL session
curl_close($ch);
?>

Copy

Orders

Viewing orders

EasyWebshop follows the schema.org/Order format whenever possible.

GET /api/order
Retrieves the last 1000 orders
GET /api/order?offset=1000
Retrieves the last 1000 orders, but skips the first 1000 orders
GET /api/order/86400
Retrieves orders that were placed or modified within the last 24h
GET /api/order/[orderNumber]
Retrieves a specific order by order number
GET /api/order HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "orderlist": [ { "order": { "@context": "https:\/\/schema.org", "@type": "Order", "orderNumber": "20250-71911-55107-56027", "orderDate": "2025-04-16 15:39:52", "OrderStatus": "OrderPaymentDue", "description": "", "language": "en", "currency": "EUR", "totalprice": "79", "productlist": [ { "product": { "@type": "Product", "productId": "LA-C05", "description": "Example paint", "price": "79", "amount": "1", "vat_code": "0" } } ], "customer": { "@context": "https:\/\/schema.org", "@type": "Person", "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "status": "Confirmed", "newsletter": 0, "registration_date": "2009-03-27 15:42:02" }, "paymentMethod": "bank", "paymentUrl": "https:\/\/all4you.be\/payment\/20250-71911-55107-56027", "last_update": "2025-04-19 13:18:17" } } ] } Retrieves the last 1000 orders curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/order Retrieves the last 1000 orders, but skips the first 1000 orders curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/order?offset=1000 Retrieves orders that were placed or modified within the last 24h curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/order/86400 Retrieves a specific order by order number curl -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/order/20250-00544-27497-22264<?php
header
("Content-Type: text/plain");

// API endpoint
// You can add an order code behind the slash for searching a specific order
const API_URL 'https://easywebshop.com/api/order/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Optional: If you are sending data (e.g., for a POST request)
// Uncomment the following lines to send a JSON payload
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
*/

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($categories json_decode($responsetrue)) {
        echo 
"\n\n" print_r($categoriestrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "orderlist": [ { "order": { "@context": "https:\/\/schema.org", "@type": "Order", "orderNumber": "20250-71911-55107-56027", "orderDate": "2025-04-16 15:39:52", "OrderStatus": "OrderPaymentDue", "description": "", "language": "en", "currency": "EUR", "totalprice": "79", "productlist": [ { "product": { "@type": "Product", "productId": "LA-C05", "description": "Example paint", "price": "79", "amount": "1", "vat_code": "0" } } ], "customer": { "@context": "https:\/\/schema.org", "@type": "Person", "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "status": "Confirmed", "newsletter": 0, "registration_date": "2009-03-27 15:42:02" }, "paymentMethod": "bank", "paymentUrl": "https:\/\/all4you.be\/payment\/20250-71911-55107-56027", "last_update": "2025-04-19 13:18:17" } } ] } <?xml version="1.0" encoding="UTF-8" ?> <orderlist> <order> <@context>https://schema.org</@context> <@type>Order</@type> <orderNumber>20250-71911-55107-56027</orderNumber> <orderDate>2025-04-16 15:39:52</orderDate> <OrderStatus>OrderPaymentDue</OrderStatus> <description></description> <language>en</language> <currency>EUR</currency> <totalprice>79</totalprice> <productlist> <product> <@type>Product</@type> <productId>LA-C05</productId> <description>Example paint</description> <price>79</price> <amount>1</amount> <vat_code>0</vat_code> </product> </productlist> <customer> <@context>https://schema.org</@context> <@type>Person</@type> <givenName>Test</givenName> <familyName>Buddy</familyName> <brand></brand> <vatID></vatID> <knowsLanguage>nl</knowsLanguage> <address> <addressCountry>BE</addressCountry> <addressLocality>Gent</addressLocality> <addressRegion></addressRegion> <postalCode></postalCode> <streetAddress>Veldstraat</streetAddress> <houseNo>1</houseNo> </address> <telephone>123456789</telephone> <email>testbuddy@ew.ms</email> <status>Confirmed</status> <newsletter>0</newsletter> <registration_date>2009-03-27 15:42:02</registration_date> </customer> <paymentMethod>bank</paymentMethod> <paymentUrl>https://all4you.be/payment/20250-71911-55107-56027</paymentUrl> <last_update>2025-04-19 13:18:17</last_update> </order> </orderlist>

Copy

Importing orders

Due to the complex nature of the checkout flow, orders can only be inserted by placing the order in the webshop or by using the POS app.

Editing orders

PUT /api/order
On success, 200 OK will be returned
PUT /api/customer HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json { "orderlist": [ { "order": { "code": "20250-71911-55107-56027", "status": "OrderDelivered", "reference": "Internal note", "mail_customer": 1 } } ] } HTTP/2 200 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 { "status": "success", "message": [ "Order 20250-71911-55107-56027: updated successfully", "Order 20250-71911-55107-56027: email successfully sent to testbuddy@ew.ms" ] } curl -X PUT -H "Authorization: Bearer YOUR_API_TOKEN" -d @order-edit.json https://easywebshop.com/api/order<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/order/';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);

// Uncomment the following lines to set data in PHP
/*
$data = [
    'key1' => 'value1',
    'key2' => 'value2'
];

$data = json_encode($data);
*/

// Get data from file
$data file_get_contents('order-edit.json');

curl_setopt($chCURLOPT_CUSTOMREQUEST'PUT');
curl_setopt($chCURLOPT_POSTFIELDS$data);

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
echo $response;

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }
}

// Close the cURL session
curl_close($ch);
?>
{ "orderlist": [ { "order": { "code": "20250-71911-55107-56027", "status": "OrderDelivered", "reference": "Internal note", "mail_customer": 1 } } ] } <?xml version="1.0" encoding="UTF-8" ?> <orderlist> <order> <code>20250-71911-55107-56027</code> <status>OrderDelivered</status> <reference>Internal note</reference> <mail_customer>1</mail_customer> </order> </orderlist>

Copy

Detailed information can be found on the order management wiki page.

ParameterTypeDescription
orderNumberstringOrder number. The order number or order code is the unique identifier for the order.
statusstringStatus
ParameterDescription
OrderReceivedOrder received
OrderPaymentDueWaiting for payment
OrderPaymentReceivedPayment received
OrderProcessingProcessing order
OrderInTransitOrder shipped
OrderDeliveredComplete
OrderCancelledCancelled
referencestringThis is a reference for internal purposes that can be set for each order. The reference will not be shown to the customer.
mail_customerbooleanSend an email notification to the customer.

Up to 100 orders can be updated at once. If you want to update more orders, you can repeat the command once every 5 minutes.

Deleting orders

DELETE /api/order/[orderNumber]
On success, 204 No Content will be returned
  • Request
  • Response
  • curl
  • PHP
DELETE /api/order/20250-00544-27497-22264 HTTP/2 Host: easywebshop.com Authorization: Bearer YOUR_API_TOKEN Content-Type: application/jsonHTTP/2 204 Server: nginx Date: Wed, 12 Mar 2025 12:00:00 GMT Content-Type: text/plain;charset=UTF-8 curl -k -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" -D - https://easywebshop.com/api/order/20250-00544-27497-22264<?php
header
("Content-Type: text/plain");

// API endpoint
const API_URL 'https://easywebshop.com/api/order/20250-71911-55107-56027';

// Your Bearer token
const API_TOKEN 'YOUR_API_TOKEN';

// True: show request and response headers
const DEBUG true;

// Initialize cURL session
$ch curl_init(API_URL);

// Set cURL options
// Return the response as a string
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_HTTPHEADER, [
    
'Authorization: Bearer ' API_TOKEN,
    
'Content-Type: application/json'
]);


curl_setopt($chCURLOPT_CUSTOMREQUEST'DELETE');

// Activate request and response details (for showing later)
if (DEBUG) {
    
curl_setopt($chCURLOPT_HEADERtrue);
    
curl_setopt($chCURLINFO_HEADER_OUTtrue);
    
curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
    
curl_setopt($chCURLOPT_SSL_VERIFYHOSTfalse);
}

// Execute the cURL request
$response curl_exec($ch);

// Show the request details
if (DEBUG) {
    echo 
curl_getinfo($chCURLINFO_HEADER_OUT);
}

// Check for errors
if (curl_errno($ch)) {
    echo 
'cURL error: ' curl_error($ch);

// Print the response
} else {

    
// Print request and response header
    
if (DEBUG) {
        
$header_size curl_getinfo($chCURLINFO_HEADER_SIZE);
        
$header substr($response0$header_size);
        
$response substr($response$header_size);
        echo 
$header;
    }

    
// Print response
    
$httpcode curl_getinfo($chCURLINFO_HTTP_CODE);
    if (
$httpcode == 204) {
        echo 
"Delete successful";
    } else {
        echo 
$response;
    }

    
// Print response in PHP array
    
if ($response_array json_decode($responsetrue)) {
        echo 
"\n\n" print_r($response_arraytrue);
    }


}

// Close the cURL session
curl_close($ch);
?>

Copy

Note that when deleting orders or changing the status to Cancelled, the stock will be re-added (if the products still exist) and products will change status from Sold out to Available if applicable. When uncancelling an order, the stock will be subtracted from the products again.

Limits

EasyWebshop is optimized for redundancy and extremely fast website load times. Behind the scenes, there is a server cluster geographically spread over multiple data centers in various countries. This has a cost: when adding and updating data and files, they need to be synchronized over the server cluster and caches have to be cleared on all servers. Images need to be compressed and resized to various formats for zoom photos and thumbnails, SEO-filenames need to be checked and created and all the data needs to be synchronized over distributed file servers and backed-up servers.

The purpose of the limits is so that one user can not overload our systems, which would cause harm to other users.

API Requests300 requests per 24h
Viewing items1000 items per request
Importing items100 items per request
Updating items100 items per request
Uploading images100 images per request (25 Megabyte per image)

High API limits

In normal situations, the default limits should be sufficient. Only for webshops with a huge amount of products the limits could be a barrier.

At Settings > More options > EasyWebshop API the feature High API limits can be activated. This allows for extra API requests to be purchased.

API Push

API Push sends a HTTPS request with JSON or XML data. This data can be "caught" by a server and processed.

If you simply want to receive an email of your orders at an additional destination, use administrator accounts. You can also receive instant notifications for incoming orders.

At Settings > Modules > EasyWebshop API > API Push, enter the URL of your application and save. After saving, a Test button will appear which allows you to send an example request. To deactivate, simply leave the URLs empty and save.

API Push

Customer PushOrder Push
A HTTPS request is sent when a customer creates an account containing all the information about the customer, similar to the Customer API.A HTTPS request is sent when a customer places an order in the webshop or when an order is placed using the POS. This request contains all the data of the order, the purchased products and information about the customer, similar to the Order API.


  • Customer Push
  • Order Push
  • index.php
{ "customerlist": [ { "customer": { "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "en", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "memberOf": "OpenGroup", "denied": 0 } }, { "customer": { "givenName": "Cindy", "familyName": "Test", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "9000", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "cindytest@ew.ms", "denied": 0 } } ] } { "orderlist": [ { "order": { "@context": "https:\/\/schema.org", "@type": "Order", "orderNumber": "20250-71911-55107-56027", "orderDate": "2025-04-16 15:39:52", "OrderStatus": "OrderPaymentDue", "description": "", "language": "en", "currency": "EUR", "totalprice": "79", "productlist": [ { "product": { "@type": "Product", "productId": "LA-C05", "description": "Example paint", "price": "79", "amount": "1", "vat_code": "0" } } ], "customer": { "@context": "https:\/\/schema.org", "@type": "Person", "givenName": "Test", "familyName": "Buddy", "brand": "", "vatID": "", "knowsLanguage": "nl", "address": { "addressCountry": "BE", "addressLocality": "Gent", "addressRegion": "", "postalCode": "", "streetAddress": "Veldstraat", "houseNo": "1" }, "telephone": "123456789", "email": "testbuddy@ew.ms", "status": "Confirmed", "newsletter": 0, "registration_date": "2009-03-27 15:42:02" }, "paymentMethod": "bank", "paymentUrl": "https:\/\/all4you.be\/payment\/20250-71911-55107-56027", "last_update": "2025-04-19 13:18:17" } } ] } <?php
/*--------------------------------------------
 * EasyWebshop API Push test script
--------------------------------------------*/

// Address to send data to
$email 'test@ew.ms';

// Collect data
$feedback "\n\nGET variables:\n\n";

foreach (
$_GET as $name => $value) {
    
$feedback .= $name ': ' $value "\n";
}

$feedback .= "\n\nPOST variables:\n\n";
foreach (
$_POST as $name => $value) {
    
$feedback .= $name ': ' $value "\n";
}

$feedback .= "\n\nInput data:\n\n" file_get_contents("php://input");

// Send mail
mail($email'EasyWebshop API Push '$feedback "\n\n" .

    
// Username
    
(isset($_SERVER['PHP_AUTH_USER']) ? 'User: ' $_SERVER['PHP_AUTH_USER'] . "\n" '') .

    
// IP Address
    
(isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n" '') .
    
$_SERVER['REMOTE_ADDR']);


// Return success
header('HTTP/1.1 200 OK');
die(
'200 OK');

?>

Copy

Connections

Connections are small web applications that live on their own server and have their own URL. They can be installed by all webshops, thus their code can be re-used by all EasyWebshop users.

At Settings > Modules > EasyWebshop API > Connections Tokens, click the Add button to create a new API Connection Token. You will have to enter the URL of the connection.

Make sure you are creating an API Connection Token and not a regular API Token.

API Connections

The types of connections are:
Delivery service, HTML widget, Invoice, Product feed, Payment Service Provider.

Connections typically have a number of files:

FileDescription
settings.xmlThis is the configuration file of the connection.
name
The name of the connection. Only use upper and lowercase letters, numbers and underscores. This name is used as an identifier.
logo
The filename of a logo within the connection directory.
type
The connection type, choose from:
ds (delivery service), html (HTML widget), invoice, productfeed, psp (Payment Service Provider)
url
The URL where the index.php file is hosted.
parameter
Five optional parameters can be entered by the merchant when installing or editing the connection. For example: the API token of a PSP can be entered here by the merchant.
easywebshop.phpThis is the file that connects to the EasyWebshop API.
Set your API Connection Token (not a regular API Token) in this file.
index.phpThis is the main file and first file to get accessed when the connection is used. In case of a delivery service, the GET fields with the customers' address are sent to this file. In the case of a PSP, the POST fields of the order are sent to this file.
report.phpThis file is used in case of PSP and Invoice and is typically requested in the background by the PSP to send updates about the payment status. This file then updates the order status in the webshop to Payment received.

To make it easy to create new connections, we kept the examples below as simple and straightforward as possible.

Delivery service

Use the example below for creating connections to delivery or transport services.

The connection needs to be installed by the merchant and shipping methods need to be connected by selecting them.

  1. The customer is on the checkout page and selects a shipping method. Because your connection is connected to a shipping method, this triggers a popup with an iframe that points to your index.php file.
  2. The customers address data is sent as GET variables in the query string.
  3. In your connection, the customer can choose a shipping method or select a pick-up point from a map.
  4. Your connection sends the shipping method name, price, description and a logo to our confirmation URL (/dsconfirm).
  5. The data is added to the order and the customer gets a confirmation.
  • settings.xml
  • easywebshop.php
  • index.php
  • style.css
<?xml version="1.0" encoding="UTF-8" ?> <settings> <name>ExampleDeliveryService</name> <logo>logo.png</logo> <type>ds</type> <url>https://www.webshopdata.com/app/easywebshop-ds/index.php</url> <parameter name="Account ID"></parameter> <parameter name="Passphrase"></parameter> </settings> <?php
/*
   EasyWebshop API Connector
   Documentation: https://easywebshop.com/doc/api
*/
function easyApp($data '') {

    
// Set your API Connection Token (not API Token!) here
    
$conn_token 'YOUR_API_TOKEN';

    
// No need to change anything below. You can watch, but you can't touch!
    
if (!isset($_REQUEST['shop_id']) || !$_REQUEST['shop_id'] ||
        !
filter_var($_REQUEST['shop_id'], FILTER_VALIDATE_INT,
        array(
'options' => array('min_range' => 1'max_range' => 1000000000)))) {
        die(
'Error: $_REQUEST[\'shop_id\'] not set');
    }

    
$settings = new SimpleXMLElement(file_get_contents(dirname(__FILE__) . '/settings.xml'));
    
$method      = isset($data['function']) && substr($data['function'], 03) == 'set' 'PUT' 'GET';
    
$format   = isset($data['format']) && in_array(strtolower($data['format']), array('json''xml')) ?
            
strtolower($data['format']) : 'array';
    
$data     is_array($data) ? ($method == 'GET' http_build_query($data) : json_encode($data)) : '';
    
$apiurl      'https://easywebshop.jan/api/conn/' $_REQUEST['shop_id'] . '/' $settings->name .
            (
$method == 'GET' && $data '?' $data ''); // HTTPS only
    
$opts     = array(
        
'http' => array(
            
'header' =>    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    
'Authorization: Bearer ' .
                    
hash('sha512'$_REQUEST['shop_id'] . $settings->name hash('sha256'$conn_token) . $data) . "\r\n",
            
'method' =>    $method,
            
'ignore_errors' => true),
        
'ssl'  => array('verify_peer' => false'verify_peer_name' => false)
        );
    if (
$method == 'PUT') { $opts['http']['content'] = $data; }
    
$response file_get_contents($apiurlfalsestream_context_create($opts));
    
$appdata  $format == 'array' json_decode($responsetrue) : $response;

    
// Output log - only in debug mode
    
if (defined('DEBUG') && DEBUG) {
        echo 
"-- easywebshop.php " $settings->name "\n> Accessing API: " .
            
$apiurl "\n> API response: " $response "--\n";
    }

    return 
$appdata// this can be a PHP array, JSON or XML, depending on the $data['format'] value

// easyApp()
?>
<?php
/*--------------------------------------------
   EasyWebshop Delivery service example 

    Install link:
    https://easywebshop.com/software/connections?install=https://www.webshopdata.com/app/easywebshop-ds

    Block 1: Variables
    Block 2: Languages
    Block 3: Delivery service API code
    Block 4: Process form data
    Block 5: Start page

--------------------------------------------*/

/*--------------------------------
    Block 1: Variables
-------------------------------*/
// Debug mode for testing, set to false in production
define('DEBUG'true); 

// Use test data
define('TEST'true);

// Use for testing without GET vars from checkout form
if (TEST) {
    
$_REQUEST = array('shop_id' => 71911'lang' => 'en');
    
$_GET = array('shop_id'        => $_REQUEST['shop_id'],
        
'webshop_url'        => 'https://all4you.be',
        
'shipping_method'    => 'Standard delivery',
        
#'shipping_method'    => 'Pickup at collection point',
        
'firstname'        => 'Bruno',
        
'lastname'        => 'Test',
        
'street'        => 'Mottakerveien',
        
'no'            => '14',
        
'zipcode'        => '0150',
        
'city'            => 'Oslo',
        
'province'        => '',
        
'country'        => 'NO',
        
'lang'            => $_REQUEST['lang'],
        
'weight'        => 0.5// total weight of the shopping basket in kg
        
'freeshipping'        => ''// shipping discount
        
'email'            => 'bruno@mailinator.com',
        
'phone'            => '12345678',
        
'total'            => 100); // total price of the order, can be used to give discounts
// TEST

// Get the connection settings
$settings = new SimpleXMLElement(file_get_contents(dirname(__FILE__) . '/settings.xml'));

// Get the data from the webshop
require 'easywebshop.php';
$appdata easyApp();

/* This gives us the following array
Array
(
    [webshop] => Array
        (
            [email]    => example@voorbeeldshop.be
            [url]    => https://voorbeeldshop.be
            [name]    => Voorbeeld webshop
            [country]    => BE
            [lang]    => nl
            [currency]    => EUR
        )

    [response_time] => 0.00084
)*/

// Show all the data we have for testing
if (DEBUG) {
    echo 
"<pre>--------------------------------\n\tGET variables:\n--------------------------------\n\n";
    
print_r($_GET);
    echo 
"\n\n</pre>";

    echo 
"<pre>--------------------------------\n\tConnection variables:\n--------------------------------\n\n";
    
print_r($appdata);
    echo 
"\n\n</pre>";
}

/*--------------------------------
    Block 3: Delivery service API code
    Delivery variables
        - These can be hard coded, or requested from another source
        - Prices can also depend on customer location, use $_GET['zipcode'] for this
-------------------------------*/

$delivery_prices = array(2.51.50);

/*--------------------------------
    Block 2: Languages
-------------------------------*/

// Dutch
if ($_REQUEST['lang'] == 'nl') {
    
$l_deliverymethod 'Kies uw verzendmethode';
    
$l_deliverymethods = array('Levering met drone''Levering met fiets''Afhalen in pakketautomaat');
    
$l_confirm 'Bevestigen';

// Other languages
} else {
    
$l_deliverymethod 'Choose your delivery method';
    
$l_deliverymethods = array('Delivery by drone''Delivery by bicycle''Pick up in a parcel machine');
    
$l_confirm 'Confirm';
}



/*--------------------------------
    Block 4: Process form data
-------------------------------*/

if (isset($_POST['deliverymethod'])) {

    
// Send delivery method
    
$ds_method $l_deliverymethods[0];
    if (
is_numeric($_POST['deliverymethod']) && isset($l_deliverymethods[$_POST['deliverymethod']])) {
        
$ds_method $l_deliverymethods[$_POST['deliverymethod']];
    }

    
// Separate prices per delivery method
    
$ds_price $delivery_prices[0];
    if (
is_numeric($_POST['deliverymethod']) && isset($delivery_prices[$_POST['deliverymethod']])) {
        
$ds_price $delivery_prices[$_POST['deliverymethod']];
    }

    
// Show a logo on the confirm page, always use HTTPS for displaying images on a HTTPS page
    
$ds_logo 'https://www.webshopdata.com/app/easywebshop-ds/logo.png';

    
// Order number
    
$ds_info 'Reference ' rand(010000); // this can be a reference to an external database

    // Confirm delivery method
    
header('Location: ' $appdata['webshop']['url'] . '/dsconfirm' .
        
'?ds=' urlencode($settings->name) .
        
'&ds_price=' $ds_price .
        
'&ds_method=' urlencode($ds_method) .
        
'&ds_info=' urlencode($ds_info) .
        
'&ds_logo=' urlencode($ds_logo) .
        
'&ds_seconds=5'); // how long to show the confirmation message

    
die;
}
/*--------------------------------
    Block 5: Start page
        - Let's keep it very simple
-------------------------------*/

// Header
echo '<!DOCTYPE html><html lang="en"><head><title>' $settings->name '</title><meta charset="utf-8">' .
    
'<link rel="stylesheet" href="style.css"></head>' // you can also include javascript here
    
'<body><main><img src="logo.png" alt="' $settings->name '" id="logo"><h1>' $settings->name '</h1>' .

    
// Form
    
'<form method="POST">' .
    
'<input type="hidden" name="shop_id" value="' $_REQUEST['shop_id'] . '">' .
    
'<input type="hidden" name="lang" value="' $_REQUEST['lang'] . '">' .
    
'<table>' .
    
'<tr><td>' $l_deliverymethod '</td><td>';

// Loop delivery methods
foreach ($l_deliverymethods as $k => $v) {
    echo 
'<input type="radio" name="deliverymethod" value="' $k '" id="' $k '">' .
        
'<label for="' $k '">' $v ' <strong>€ ' $delivery_prices[$k] . '</strong></label><br>';
}
echo 
'</td></tr>' .

    
// Submit form
    
'<tr><td></td><td><input type="submit" name="submit" value="' $l_confirm '"></td></tr>' .
    
'</table></form>' .

    
// End page
    
'</main></body></html>';

?>
body    { margin: 0; font-family: Helvetica, Arial, sans-serif; color: #333; background-color: #E4E4E4; }
main    { margin: 0 auto; margin-top: 30px; margin-bottom: 30px; padding: 20px; width: 760px; background-color: #FFF; border-radius: 8px; border: 1px solid #CCC; box-shadow: 5px 5px 5px #888; }
#logo    { margin-bottom: 10px; }
h1    { font-size: 22px; margin: 0; padding: 0; color: #06C; margin-bottom: 80px; }
hr    { clear: both; border-style: solid; border-width: 1px 0 0 0; border-color: #E4E4E4; margin: 20px 0; }

/*--------------------------------
     Navigation
-------------------------------*/
nav    { margin: 40px 0; clear: both; }
nav a    {
    display: block; width: 70%; margin: 30px auto; padding: 20px; vertical-align: top;
    border: 1px solid #E4E4E4; box-shadow: 2px 2px 2px #888;
    /*border-style: solid; border-width: 0 0 1px 0; border-color: #CCC;*/
    text-decoration: none; color: #06C; font-size: 20px; font-weight: bold;
    transition: background 0.4s;
}

nav a:hover { background: #EEE; }
nav img    { display: inline-block; float: left; width: 100px; height: 100px; vertical-align: top; }
nav span{ display: inline-block; line-height: 100px; text-indent: 30px; }
.langselect { font-size: 0.8em; font-weight: bold; }
/*--------------------------------
     Buttons
-------------------------------*/
a.glowbutton, input[type="submit"], input[type="button"]    {
    white-space: nowrap; display: inline-block; min-width: 210px; margin: 0 0 10px 0; padding: 0;
    text-decoration: none; text-align: center;
    color: #FFF; background-color: #06C; border: 0; border-radius: 3px;
    line-height: 33px; height: 33px; font-weight: bold; font-size: 0.9em;
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    transition: background 0.4s;
}

a.glowbutton:hover, input[type="submit"]:hover    {
    background-color: #06F; text-decoration: none;
}

/*--------------------------------
     Fancy
-------------------------------*/

a    { color: #06C; text-decoration: none; }
a:hover    { text-decoration: underline; }
h2    { font-size: 1.6em; }
h3    { font-size: 1.4em; }
h4    { font-size: 1.1em; color: #666; }
.blue    { color: #06C; }
.orange { color: #F60; }
.code    { font-family: monospace; color: #090; }
.code a    { font-weight: bold; color: #090; }
.warn    { background-color: #FC0; padding: 15px 5px; text-align: center; border-radius: 5px; font-size: 0.9em; box-shadow: 2px 2px 2px #888; }

/*--------------------------------
     Forms
-------------------------------*/
textarea                    { width: 99%; height: 200px; font-size: 1.2em; color: #666; }
input, select, textarea                { border: 1px solid #CCC; border-radius: 3px; padding: 3px; }
input:focus, textarea:focus            { background-color: #EEE; }
input[type="checkbox"], input[type="radio"]    { border: 0;}
input[type="submit"], input[type="button"]    { cursor: pointer; float: right; margin: 10px 0 0 0;  }
form table                    { width: 100%; }
form table td:first-child            { width: 50%; }
label                        { display: inline-block; max-width: 90%; padding: 0 0 0 10px; cursor: pointer; }
/*--------------------------------
     Responsive
-------------------------------*/
@media all and (max-width: 790px) {
    main        { width: 100%; margin: 0; padding: 20px 0; border: none; border-radius: 0; }
    nav a        { margin: 0 auto; margin-top: 20px; margin-bottom: 20px; }
    textarea    { width: 97%; }
}

HTML widget

Widgets can be used to easily insert HTML, CSS and JavaScript code. The user can choose on which pages of the website he or she wants to install this code. It's basically the same as copy and paste, but more user friendly.

  • settings.xml
<?xml version="1.0" encoding="UTF-8" ?> <settings> <name>ExampleWidget</name> <type>html</type> <parameter name="Enter variable data 1">Example data 1</parameter> <parameter name="Enter variable data 2">Example data 2</parameter> <url>https://www.webshopdata.com/app/easywebshop-html/settings.xml</url> <html><![CDATA[<p> Hello! I'm a <strong>HTML example</strong>.<br> You can use HTML, CSS and JavaScript code here.<br> The user can insert it on any page of the website. </p> <p> Your first parameter was <strong>[PARAMETER1]</strong>.<br> Your second parameter was <strong>[PARAMETER2]</strong>. </p> <p> To install me, redirect your user to:<br> https://easywebshop.com/software/connections?install=https://www.webshopdata.com/app/easywebshop-html </p> <p> Replace the second part of the URL by the directory on your sever.<br> Only this settings.xml file is required in the directory. </p>]]></html> </settings>

Invoice

Invoice works in the same way as Payment Service Provider, but focused on payment on invoice where customer data is needed. When the type is set to psp, only the necessary data that a PSP needs to process a payment is available. When the type is invoice, the customer data also becomes available.

Product feed

Used for retrieving product data, for example for use on comparison sites.

  • settings.xml
  • easywebshop.php
  • index.php
  • style.css
<?xml version="1.0" encoding="UTF-8" ?> <settings> <name>DemoFeed</name> <type>productfeed</type> <url>https://www.webshopdata.com/app/easywebshop-productfeed/index.php</url> </settings> <?php
/*
   EasyWebshop API Connector
   Documentation: https://easywebshop.com/doc/api
*/
function easyApp($data '') {

    
// Set your API Connection Token (not API Token!) here
    
$conn_token 'YOUR_API_TOKEN';

    
// No need to change anything below. You can watch, but you can't touch!
    
if (!isset($_REQUEST['shop_id']) || !$_REQUEST['shop_id'] ||
        !
filter_var($_REQUEST['shop_id'], FILTER_VALIDATE_INT,
        array(
'options' => array('min_range' => 1'max_range' => 1000000000)))) {
        die(
'Error: $_REQUEST[\'shop_id\'] not set');
    }

    
$settings = new SimpleXMLElement(file_get_contents(dirname(__FILE__) . '/settings.xml'));
    
$method      = isset($data['function']) && substr($data['function'], 03) == 'set' 'PUT' 'GET';
    
$format   = isset($data['format']) && in_array(strtolower($data['format']), array('json''xml')) ?
            
strtolower($data['format']) : 'array';
    
$data     is_array($data) ? ($method == 'GET' http_build_query($data) : json_encode($data)) : '';
    
$apiurl      'https://easywebshop.jan/api/conn/' $_REQUEST['shop_id'] . '/' $settings->name .
            (
$method == 'GET' && $data '?' $data ''); // HTTPS only
    
$opts     = array(
        
'http' => array(
            
'header' =>    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    
'Authorization: Bearer ' .
                    
hash('sha512'$_REQUEST['shop_id'] . $settings->name hash('sha256'$conn_token) . $data) . "\r\n",
            
'method' =>    $method,
            
'ignore_errors' => true),
        
'ssl'  => array('verify_peer' => false'verify_peer_name' => false)
        );
    if (
$method == 'PUT') { $opts['http']['content'] = $data; }
    
$response file_get_contents($apiurlfalsestream_context_create($opts));
    
$appdata  $format == 'array' json_decode($responsetrue) : $response;

    
// Output log - only in debug mode
    
if (defined('DEBUG') && DEBUG) {
        echo 
"-- easywebshop.php " $settings->name "\n> Accessing API: " .
            
$apiurl "\n> API response: " $response "--\n";
    }

    return 
$appdata// this can be a PHP array, JSON or XML, depending on the $data['format'] value

// easyApp()
?>
<?php
/*--------------------------------------------
   EasyWebshop Productfeed example 

    Install link:
    https://easywebshop.com/software/connections?install=https://www.webshopdata.com/app/easywebshop-productfeed

    Block 1: Variables
    Block 2: Generate feed
    Block 3: Languages
    Block 4: Productfeed form
    Block X: Functions

--------------------------------------------*/

/*--------------------------------
    Block 1: Variables
-------------------------------*/

define('DEBUG'true);            // Debug mode for testing, set to false in production
$languages = array('cs''da''de''el''en''es''fi''fr''it''ja''ko''nl''no''pl''pt''ro''ru''sv''tr''zh');

define('SHOP_ID', isset($_REQUEST['shop_id']) && checkId($_REQUEST['shop_id']) ? $_REQUEST['shop_id'] : 0);
define('LANG', isset($_REQUEST['lang']) && in_array($_REQUEST['lang'], $languages) ? $_REQUEST['lang'] : 'en');

$settings = new SimpleXMLElement(file_get_contents(dirname(__FILE__) . '/settings.xml'));

/*--------------------------------
    Block 2: Generate feed
-------------------------------*/
if (SHOP_ID && isset($_GET['token']) &&
    
preg_match('/^[0-9a-f]{40}$/i'$_GET['token']) && $_GET['token'] == sha1(SHOP_ID LANG 'roor8weiChait0gai')) {

    
/*--------------------------------
        Connect to the EasyWebshop App API
            easyApp(
                [data]        Data to send to the API, optional
            )
        - Returns an array of requested data, view with: print_r($appdata);
    -------------------------------*/

    
header('Content-Type: text/xml; charset=utf-8');

    
// Show feed in XML format
    
echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?" ">\n<items>\n";

    if (
DEBUG) {
        echo 
'<debug><![CDATA[';
    }

    include 
'easywebshop.php';
    
$appdata easyApp(array('lang' => LANG'seconds' => 0'start' => 0'length' => 1000)); //, 'format' => 'xml'));

    
if (DEBUG) {
        echo 
"]]></debug>\n";
    }

    if (isset(
$appdata['products'])) {
        
displayProducts($appdata);

        
// Max 5000 products
        
for ($i 1$i 5$i++) {
            if (
count($appdata['products']) >= 1000) {
                
$appdata easyApp(array('lang' => LANG'seconds' => 0'start' => ($i 1000), 'length' => 1000)); //, 'format' => 'xml'));
                
displayProducts($appdata);
            }
        }
            
        
//"<updated>" . gmdate("Ymd\THis\Z") . "</updated>\n";
    
}

    echo 
'</items>';
    die;

}

/*--------------------------------
    Block 3: Languages
-------------------------------*/

// Danish
if (LANG == 'da') {

    
$l_language        'Sprog';
    
$l_languages        = array('cs' => 'Tjekkisk''da' => 'Dansk''de' => 'Tysk''el' => 'Greek''en' => 'Engelsk''es' => 'Spansk''fi' => 'Finsk''fr' => 'Fransk''it' => 'Italiensk''ja' => 'Japansk''ko' => 'Koreansk''nl' => 'Nederlandsk''no' => 'Norsk''pl' => 'Polsk''pt' => 'Portugisisk''ro' => 'Rumænsk''ru' => 'Russisk''sv' => 'Svensk''tr' => 'Tyrkisk''zh' => 'Kinesisk');
    
$l_generate_feed     'Generer produktfeed';
    
$l_feed_url         'Din <strong>' $settings->name '</strong> feedwebadresse er:';

// German
} elseif (LANG == 'de') {

    
$l_language        'Sprache';
    
$l_languages        = array('cs' => 'Tschechisch''da' => 'Dänisch''de' => 'Deutsch''el' => 'Griechisch''en' => 'Englisch''es' => 'Spanisch''fi' => 'Finnisch''fr' => 'Französisch''it' => 'Italienisch''ja' => 'Japanisch''ko' => 'Koreanisch''nl' => 'Niederländisch''no' => 'Norwegisch''pl' => 'Polnisch''pt' => 'Portugiesisch''ro' => 'Rumänisch''ru' => 'Russisch''sv' => 'Schwedisch''tr' => 'Türkisch''zh' => 'Chinesisch');
    
$l_generate_feed     'Produktfeed generieren';
    
$l_feed_url         'Ihre Feed-URL für <strong>' $settings->name '</strong> lautet:';


// Spanish
} elseif (LANG == 'es') {

    
$l_language        'Idioma';
    
$l_languages        = array('cs' => 'Checo''da' => 'Danés''de' => 'Alemán''el' => 'Griego''en' => 'Inglés''es' => 'Español''fi' => 'Finlandés''fr' => 'Francés''it' => 'Italiano''ja' => 'Japonés''ko' => 'Coreano''nl' => 'Neerlandés''no' => 'Noruego''pl' => 'Polaco''pt' => 'Portugués''ro' => 'Rumano''ru' => 'Ruso''sv' => 'Sueco''tr' => 'Turco''zh' => 'Chino');
    
$l_generate_feed     'Generar feed de producto';
    
$l_feed_url         'Su <strong>' $settings->name '</strong> URL de feed es:';

// French
} elseif (LANG == 'fr') {

    
$l_language        'Langue';
    
$l_languages        = array('cs' => 'Tchèque''da' => 'Danois''de' => 'Allemand''el' => 'Grecque''en' => 'Anglais''es' => 'Espagnol''fi' => 'Finnois''fr' => 'Français''it' => 'Italien''ja' => 'Japonais''ko' => 'Coréen''nl' => 'Néerlandais''no' => 'Norvège''pl' => 'Polonais''pt' => 'Portugais''ro' => 'Roumain''ru' => 'Russe''sv' => 'Suédois''tr' => 'Turc''zh' => 'Chinois');
    
$l_generate_feed     'Générer le flux de produits';
    
$l_feed_url         'Votre URL de flux <strong>' $settings->name '</strong> est la suivante:';

// Dutch
} elseif (LANG == 'nl') {

    
$l_language         'Taal';
    
$l_languages         = array('cs' => 'Tsjechisch''da' => 'Deens''de' => 'Duits''el' => 'Grieks''en' => 'Engels''es' => 'Spaans''fi' => 'Fins''fr' => 'Frans''it' => 'Italiaans''ja' => 'Japans''ko' => 'Koreaans''nl' => 'Nederlands''no' => 'Noors''pl' => 'Pools''pt' => 'Portugees''ro' => 'Roemeens''ru' => 'Russisch''sv' => 'Zweeds''tr' => 'Turks''zh' => 'Chinees');
    
$l_generate_feed     'Productfeed genereren';
    
$l_feed_url 'Uw <strong>' $settings->name '</strong> feed URL is:';

// Norwegian
} elseif (LANG == 'no') {

    
$l_language        'Språk';
    
$l_languages        = array('cs' => 'Tsjekkisk''da' => 'Danske''de' => 'Tysk''el' => 'Gresk''en' => 'Engelsk''es' => 'Spansk''fi' => 'Finske''fr' => 'Fransk''it' => 'Italiensk''ja' => 'Japansk''ko' => 'Koreansk''nl' => 'Nederlandsk''no' => 'Norsk''pl' => 'Polsk''pt' => 'Portugisisk''ro' => 'Rumensk''ru' => 'Russiske''sv' => 'Svenske''tr' => 'Turkish''zh' => 'Kinesisk');
    
$l_generate_feed     'Generer produktmating';
    
$l_feed_url         'Din <strong>' $settings->name '</strong> feed-nettadresse er:';

// Swedish
} elseif (LANG == 'sv') {

    
$l_language        'Språk';
    
$l_languages        = array('cs' => 'Tjeckisk''da' => 'Danska''de' => 'Tyska''el' => 'Grekiska''en' => 'Engelska''es' => 'Spanska''fi' => 'Finska''fr' => 'Franska''it' => 'Italienska''ja' => 'Japansk''ko' => 'koreansk''nl' => 'Nederländska''no' => 'Norska''pl' => 'Polska''pt' => 'Portugisiska''ro' => 'Rumänska''ru' => 'Ryska''sv' => 'Svenska''tr' => 'Turkiska''zh' => 'Kinesisk');
    
$l_generate_feed     'Generera produktmatning';
    
$l_feed_url         'Din <strong>' $settings->name '</strong> matningsadress är:';

// English by default
} else {

    
$l_language 'Language';
    
$l_languages = array('cs' => 'Czech''da' => 'Danish''de' => 'German''el' => 'Greek''en' => 'English''es' => 'Spanish''fi' => 'Finnish''fr' => 'French''it' => 'Italian''ja' => 'Japanese''ko' => 'Korean''nl' => 'Dutch''no' => 'Norwegian''pl' => 'Polish''pt' => 'Portuguese''ro' => 'Romanian''ru' => 'Russian''sv' => 'Swedish''tr' => 'Turkish''zh' => 'Chinese');
    
$l_generate_feed     'Generate product feed';
    
$l_feed_url         'Your <strong>' $settings->name '</strong> feed URL is:';
}

/*--------------------------------
    Block 4: Productfeed form
-------------------------------*/

echo '<!DOCTYPE html><html lang="en"><head><title>' $settings->name '</title><meta charset="utf-8">' .
    
'<link rel="stylesheet" href="style.css"></head>' .
    
'<body><main><h1>' $settings->name '</h1>';

// Show feed URL
if (isset($_POST['shop_id']) && SHOP_ID) {

    
// Create a token for this feed so the URL cannot be guessed
    
$feedurl 'https://' $_SERVER['HTTP_HOST'] . $_SERVER['DOCUMENT_URI'] .
        
'?shop_id=' SHOP_ID '&lang=' LANG '&token=' sha1(SHOP_ID LANG 'roor8weiChait0gai');
    echo 
'<p>' $l_feed_url '<br><a href="' $feedurl '" target="_blank">' $feedurl '</a></p>';

// Show generate feed form
} else {
    echo 
'<form method="POST"><table>';

    
// Shop ID
    
if (SHOP_ID) {
        echo 
'<input type="hidden" name="shop_id" value="' SHOP_ID '">';
    } else {
        echo 
'<tr><td>Shop ID</td><td><input type="text" name="shop_id" size="6"></td></tr>';
    }

    
// Language
    
echo '<tr><td>' $l_language '</td><td><select name="lang">';
    
asort($l_languages);
    foreach (
$l_languages as $l => $l_name) {
        echo 
'<option value="' $l '"' . ($l == $lang ' selected' '') . '>' $l_name '</option>';
    }
    echo 
'</select></td></tr>';

    
// Submit form
    
echo '<tr><td></td><td><input type="submit" name="submit" value="' $l_generate_feed '"></td></tr>' .
        
'</table></form>';
}

echo 
'</main></body></html>';

/*--------------------------------
    Block X: Functions
-------------------------------*/

function displayProducts($appdata) {

    
/* Google product feed:
        https://support.google.com/merchants/answer/7052112?hl=en
    */

    
foreach ($appdata['products'] as $p) {

        if (!isset(
$p['category'])) {
            
$p['category'] = '';
        }

        
//echo "<item>\n";
                
        // Image
        //echo '<additional_image_link>' . $p['image'] . "</additional_image_link>\n

        // ID (mandatory)
        
echo "<item>\n<id><![CDATA[" $p['productID'] . "]]></id>\n<availability>" .

        
// Availability (Mandatory)
            
$p['status'] . "</availability>\n<brand><![CDATA[" .

        
// Brand (Mandatory)
            
$p['category'] . "]]></brand>\n" .

        
// Color
            
($p['colors'] ? '<color>' $p['colors'] . "</color>\n" '') .

        
// Condition (Recommended)
            
'<condition>' $p['itemCondition'] . "</condition>\n<title><![CDATA[" .

        
// Title (Mandatory)
            
$p['name'] . "]]></title>\n<description><![CDATA[" .

        
// Description (Mandatory)
            
preg_replace('/[^(\x20-\x7F)]*/'''$p['description']) . "]]></description>\n";

        
// EAN (Recommended)
        
if ($p['ean']) {
            echo 
'<ean>' $p['ean'] . "</ean>\n";
        }

        
// Product code
        //echo '<unique_id><![CDATA[' . $p['productID'] . "]]></unique_id>\n<size>" .

        // Size (Mandatory)
        
echo '<size>' $p['weight'] . "</size>\n<image_link>" .

        
// Image link (Mandatory)
            
$p['image'] . "</image_link>\n";

        
// Additional image links
        
for ($i 2$i <= 5$i++) {
            if (isset(
$p['image' $i])) {
                echo 
'<additional_image_link>' $p['image' $i] . "</additional_image_link>\n";
            }
        }

        
// Purchase price
        
if ($p['purchase_price']) {
            echo 
'<cost_of_goods_sold>' $p['purchase_price'] . "</cost_of_goods_sold>\n";
        }

        
// Price (Mandatory)
        
echo '<price>' . ($p['old_price'] ? $p['old_price'] : $p['price']) . "</price>\n<sale_price>" .

        
// Sale price (Mandatory)
            
$p['price'] . "</sale_price>\n<link>" .

        
// Link (Mandatory)
            
$p['url'] . "</link>\n<product_type><![CDATA[" .

        
// Breadcrumb (Mandatory)
            
$p['category'] . "]]></product_type>\n<stock>" .

        
// Stock (Recommended)
            
$p['stock'] . "</stock>\n";



        
/* Shipping costs

                    [shipping] => Array
                        (
                            [Worldwide] => Array
                                (
                                    [Pickup in the store] => 0
                                    [Pickup at collection point] => 0
                                )

                            [BE] => Array
                                (
                                    [Standard delivery] => 10
                                )

                            [NL] => Array
                                (
                                    [Collect on delivery] => 5
                                )

                        )

        */
        
if (isset($p['shipping']) && $p['shipping']) {

            
$price_set false;
            foreach (
$p['shipping'] as $country => $methods) {

                
// Try to set a shipping price
                
foreach ($methods as $method => $price) {

                    if (
$price_set) {
                        break;
                    }

                    if (
$method != 'Pickup in the store') {
                        echo 
'<shipping_price>' $price "</shipping_price>\n"// ' ' . $appdata['webshop']['currency']
                        
$price_set true;
                        break;
                    }
                }
            }
        }


        echo 
"</item>\n";

    }
// displayProducts()

// Check for a valid shop id
function checkId($id) {
    return 
filter_var($idFILTER_VALIDATE_INT, array('options' => array('min_range' => 1'max_range' => 1000000000)));
// checkId()
?>
body    { margin: 0; font-family: Helvetica, Arial, sans-serif; color: #333; background-color: #e4e4e4; }
main    { margin: 0 auto; margin-top: 30px; margin-bottom: 30px; padding: 20px; width: 760px; background-color: #fff; border-radius: 8px; border: 1px solid #ccc; box-shadow: 5px 5px 5px #888; }
#logo    { float: left; margin-bottom: 10px; }
h1    { font-size: 22px; margin: 0; padding: 0; color: #06c; margin-bottom: 80px; }
hr    { clear: both; border-style: solid; border-width: 1px 0 0 0; border-color: #e4e4e4; margin: 20px 0; }

/*--------------------------------
     Buttons
-------------------------------*/
a.glowbutton, input[type="submit"], input[type="button"]    {
    white-space: nowrap; display: inline-block; min-width: 210px; margin: 0 0 10px 0; padding: 0;
    text-decoration: none; text-align: center;
    color: #fff; background-color: #06c; border: 0; border-radius: 3px;
    line-height: 33px; height: 33px; font-weight: bold; font-size: 0.9em;
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    transition: background 0.4s;
}

a.glowbutton:hover, input[type="submit"]:hover    {
    background-color: #06f; text-decoration: none;
}

/*--------------------------------
     Fancy
-------------------------------*/

a    { color: #06c; text-decoration: none; }
a:hover    { text-decoration: underline; }
h2    { font-size: 1.6em; }
h3    { font-size: 1.4em; }
h4    { font-size: 1.1em; color: #666; }
.blue    { color: #06c; }
.orange { color: #f60; }
.code    { font-family: monospace; color: #090; }
.code a    { font-weight: bold; color: #090; }
.warn    { background-color: #fc0; padding: 15px 5px; text-align: center; border-radius: 5px; font-size: 0.9em; box-shadow: 2px 2px 2px #888; }

/*--------------------------------
     Forms
-------------------------------*/
textarea                    { width: 99%; height: 200px; font-size: 1.2em; color: #666; }
input, select, textarea                { border: 1px solid #ccc; border-radius: 3px; margin: 0px 0 8px 0; padding: 8px; }
input:focus, textarea:focus            { background-color: #eee; }
input[type="checkbox"], input[type="radio"]    { border: 0;}
input[type="submit"], input[type="button"]    { cursor: pointer; float: right; margin: 10px 0 0 0;  }
form table                    { width: 100%; }
form table td:first-child            { width: 50%; }
/*--------------------------------
     Responsive
-------------------------------*/
@media all and (max-width: 790px) {
    main        { max-width: calc(100vw - 20px); margin: 0; padding: 20px 10px; border: none; border-radius: 0; }
    textarea    { width: 97%; }
}

Payment Service Provider

This is the way to connect a Payment Service Provider (PSP) to EasyWebshop.

The connection needs to be installed by the merchant and payment methods need to be connected by selecting them.

After the customer has placed an order in the webshop, the page with the Pay now button appears. This button submits a HTML form.

  1. Your connection receives the POST data from this form, which includes the order code. With the API Connection Token you can safely retrieve the order data which is necessary for processing the payment.
  2. Connect to the API of the PSP and send the order data.
  3. If the payment is executed successfully, the payment service provider requests the report.php file which updates the status of the order in the webshop to Payment received.
  4. The customer is redirected to the payment ok or to the payment failed URL, depending on the success or failure of the payment.
  5. If multiple payment methods are set, the customer can choose another payment method after a failed payment.
  • settings.xml
  • easywebshop.php
  • index.php
  • report.php
  • style.css
<?xml version="1.0" encoding="UTF-8" ?> <settings> <name>DemoPSP</name> <logo>demo-psp.png</logo> <type>psp</type> <url>https://www.webshopdata.com/app/easywebshop-psp/index.php</url> <parameter name="PSP API key">123456789</parameter> </settings> <?php
/*
   EasyWebshop API Connector
   Documentation: https://easywebshop.com/doc/api
*/
function easyApp($data '') {

    
// Set your API Connection Token (not API Token!) here
    
$conn_token 'YOUR_API_TOKEN';

    
// No need to change anything below. You can watch, but you can't touch!
    
if (!isset($_REQUEST['shop_id']) || !$_REQUEST['shop_id'] ||
        !
filter_var($_REQUEST['shop_id'], FILTER_VALIDATE_INT,
        array(
'options' => array('min_range' => 1'max_range' => 1000000000)))) {
        die(
'Error: $_REQUEST[\'shop_id\'] not set');
    }

    
$settings = new SimpleXMLElement(file_get_contents(dirname(__FILE__) . '/settings.xml'));
    
$method      = isset($data['function']) && substr($data['function'], 03) == 'set' 'PUT' 'GET';
    
$format   = isset($data['format']) && in_array(strtolower($data['format']), array('json''xml')) ?
            
strtolower($data['format']) : 'array';
    
$data     is_array($data) ? ($method == 'GET' http_build_query($data) : json_encode($data)) : '';
    
$apiurl      'https://easywebshop.jan/api/conn/' $_REQUEST['shop_id'] . '/' $settings->name .
            (
$method == 'GET' && $data '?' $data ''); // HTTPS only
    
$opts     = array(
        
'http' => array(
            
'header' =>    "Content-Type: application/x-www-form-urlencoded\r\n" .
                    
'Authorization: Bearer ' .
                    
hash('sha512'$_REQUEST['shop_id'] . $settings->name hash('sha256'$conn_token) . $data) . "\r\n",
            
'method' =>    $method,
            
'ignore_errors' => true),
        
'ssl'  => array('verify_peer' => false'verify_peer_name' => false)
        );
    if (
$method == 'PUT') { $opts['http']['content'] = $data; }
    
$response file_get_contents($apiurlfalsestream_context_create($opts));
    
$appdata  $format == 'array' json_decode($responsetrue) : $response;

    
// Output log - only in debug mode
    
if (defined('DEBUG') && DEBUG) {
        echo 
"<pre>-- easywebshop.php " $settings->name "\n> Accessing API: " .
            
$apiurl "\n> API response: " $response "--\n</pre>";
    }

    return 
$appdata// this can be a PHP array, JSON or XML, depending on the $data['format'] value

// easyApp()
?>
<?php
/*--------------------------------------------
 * This page redirects a customer to the PSP

    Install link:
    https://easywebshop.com/software/connections?install=https://www.webshopdata.com/app/easywebshop-psp

    Block 1: Variables
    Block 2: Languages
    Block 3: PSP API code
    Block 4: Start page
    Block X: Functions

--------------------------------------------*/

/*--------------------------------
    Block 1: Variables
-------------------------------*/

// Debug mode for testing, set to false in production
define('DEBUG',    true);

// Use test data
define('TEST'true);

// Use for testing without POST vars from payment form
if (TEST) {
    
$_REQUEST    = array('shop_id' => 71911'ordercode' => '20250-71911-19417-18497''lang' => 'en');
}

define('SHOP_ID', isset($_REQUEST['shop_id']) && checkId($_REQUEST['shop_id']) ? $_REQUEST['shop_id'] : 0);
define('ORDERCODE', isset($_REQUEST['ordercode']) && checkOrderCode($_REQUEST['ordercode']) ? $_REQUEST['ordercode'] : '');

$error        '';

if (!
ORDERCODE) {
    
$error    'Invalid Order code';
}

// Easywebshop API connector
require        'easywebshop.php';
$appdata    easyApp(array('ordercode' => ORDERCODE));
$settings    = (array)simplexml_load_file('settings.xml');
$log        "REQUEST variables:\n\n" print_r($_REQUESTtrue) .
        
"\n\nAppdata: \n\n" print_r($appdatatrue) . "\n\nSettings: \n\n" print_r($settingstrue);

// URL requested by PSP on payment status update
$reporturl    'https://' $_SERVER['HTTP_HOST'] .
            
substr($_SERVER['DOCUMENT_URI'], 0strrpos($_SERVER['DOCUMENT_URI'], '/')) .
            
'/report.php?shop_id=' SHOP_ID;

/*--------------------------------
    Block 2: Languages
-------------------------------*/

// Dutch
if ($_REQUEST['lang'] == 'nl') {

    
$l_paymentok        'Betaling geslaagd';
    
$l_paymentfail        'Betaling mislukt';

// German
} elseif ($_REQUEST['lang'] == 'de') {

    
$l_paymentok        'Zahlung erfolgreich';
    
$l_paymentfail        'Zahlung fehlgeschlagen';

// Spanish
} elseif ($_REQUEST['lang'] == 'es') {

    
$l_paymentok        'Pago efectuado';
    
$l_paymentfail        'Pago fallido';

// French
} elseif ($_REQUEST['lang'] == 'fr') {

    
$l_paymentok        'Paiement réussi';
    
$l_paymentfail        'Échec du paiement';

// Default to English
} else {

    
$l_paymentok        'Payment successful';
    
$l_paymentfail        'Payment failed';
}

/*--------------------------------
    Block 3: PSP API code
-------------------------------*/

/*--------------------------------
    Block 4: Start page
-------------------------------*/
echo '<!DOCTYPE html><html lang="en"><head><title>' $settings['name'] .
    
'</title><meta charset="utf-8"><link rel="stylesheet" href="style.css"></head>' .
    
'<body><main><p><img src="' $settings['logo'] . '" style="margin: 5px"></p>';

// Error message
if ($error) {
    echo 
'<p class="warn">' $error '</p>';
}

// Action buttons
if (isset($appdata['order']['code'])) {
    echo 
'<p class="leftbuttons"><a href="' $reporturl '&ordercode=' $appdata['order']['code'] .
        
'" class="glowbutton" style="background: #5fc331">' $l_paymentok '</a><a href="' .
        
$appdata['webshop']['paymentfailed'] . '" class="glowbutton" style="background: #c00">' .
        
$l_paymentfail '</a></p>';


    
// Back to webshop
    
echo '<hr><p><a href="' $appdata['webshop']['url'] . '/payment/' $appdata['order']['code'] .
        
'" class="glowbutton">' $appdata['webshop']['name'] . '</a></p>';
}

// Debug output -- you can find all $_POST, $appdata and $settings variables here
if (DEBUG) {
    echo 
'<h2>Debug log</h2><pre>' $log '</pre>';
}

echo 
'</main></body></html>';

/*--------------------------------
    Block X: Functions
-------------------------------*/

// Check for a valid shop id
function checkId($id) {
    return 
filter_var($idFILTER_VALIDATE_INT, array('options' => array('min_range' => 1'max_range' => 1000000000)));
// checkId()

function checkOrderCode($code) {
    return 
strlen($code) == 23 && preg_match('/\d\d\d\d\d-\d\d\d\d\d-\d\d\d\d\d-\d\d\d\d\d/'$code);
// checkOrderCode()
?>
<?php
/*--------------------------------------------
 * This page is usually requested "under water" by the PSP and updates the payment status

    Block 1: Variables for EasyWebshop API
    Block 2: PSP API code
    Block 3: Set order paid
    Block X: Functions
--------------------------------------------*/

header("Content-Type: text/plain; charset=utf-8");

/*--------------------------------
    Block 1: Variables
-------------------------------*/
define('DEBUG',        true);        // Debug mode for testing, set to false in production
define('DEBUG_EMAIL',    'test@ew.ms');    // Send an email with debug log
$error        '';

// Easywebshop API connector
require 'easywebshop.php';
$appdata    easyApp(); // PSP must send shop_id in GET or POST
$settings    = (array)simplexml_load_file('settings.xml');
$log        $settings['name'] . " report.php\n\n" .
            
'X forwarded: ' . (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ?
            
$_SERVER['HTTP_X_FORWARDED_FOR'] : '') .
            
', IP: ' $_SERVER['REMOTE_ADDR'] .
            
"\n\nGET variables:\n\n" print_r($_GETtrue) .
            
"\n\nPOST variables:\n\n" print_r($_POSTtrue) .
            
"\n\nAppdata: \n\n" print_r($appdatatrue) .
            
"\n\nSettings: \n\n" print_r($settingstrue);

// report.php needed variables
$order_code    ''// PSP must send order_code in GET or POST
$order_paid    false// Set to TRUE if payment is successful

/*--------------------------------
    Block 2: PSP API code
-------------------------------*/

// Check if ordercode is correct
if (isset($_REQUEST['ordercode']) && strlen($_REQUEST['ordercode']) == 23 &&
    
preg_match('/\d\d\d\d\d-\d\d\d\d\d-\d\d\d\d\d-\d\d\d\d\d/'$_REQUEST['ordercode'])) {
    
$order_code $_REQUEST['ordercode']; // this variable is safe now

} else {
    
$error 'Invalid order code';
}

// Check if correct GET or POST variables are received
if (!$error) {

    
/* Here you can check if the payment status update request is valid:
        - Calculate a hash
        - Make a request to the PSP API
    */

    // Calculate hash
    
if (true) {
        
$order_paid true;
    }

    
/* Check payment status with PSP
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, '');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'api_key: ' . $appdata['parameter1'],
        'Accept: application/json',
        'Content-Type: application/json'
        )
    );
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    if (DEBUG) {
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLOPT_STDERR, $verbose = fopen('php://temp', 'rw+'));
        curl_setopt($ch, CURLOPT_FILETIME, true);
    }

    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        $error_msg = curl_error($ch);
    }
    curl_close($ch);

    if (DEBUG) {
        $log .= (isset($error_msg) ? "\n\nHTTP Log:\n" . print_r($error_msg, true) . "\n\n" : '') .
                "Verbose information:\n" . !rewind($verbose) . stream_get_contents($verbose) . "\n\n" .
                print_r($response, true);
    }

    $response = json_decode($response, true);
    if ($response && isset($response['success']) && $response['success'] &&
        isset($response['data']['financial_status']) && $response['data']['financial_status'] == 'completed') {

        $order_paid = true;
        $order_code = $response['data']['var2'];

    }
    */

// Error found
} elseif (DEBUG) {
    
mailLog($log "\n\nErrors:\n\n" $error);

// no errors


/*--------------------------------
    Block 3: Set order paid
-------------------------------*/
if ($order_paid) {

    
// The connector needs $_REQUEST['shop_id'] and $_REQUEST['ordercode'] for changing the order status
    
$pmdata        easyApp(array('function' => 'setOrderPaid''ordercode' => $order_code));
    
$log        .= "\n\nOrder update result:\n\n" print_r($pmdatatrue);
}

if (
DEBUG) {
    echo 
$log;
    
mailLog($log);
}

// Optional: redirect if customer comes on this page directly
header('Location: ' $appdata['webshop']['paymentok']);

// Acknowledge we have successfully received a valid notification by returning OK
echo 'OK';

/*--------------------------------
    Block X: Functions
-------------------------------*/

// Send mail
function mailLog($log) {

    
$subject preg_split('#\r?\n#'ltrim($log), 2)[0]; // get first line

    
mail(DEBUG_EMAIL$subject$log "\n\n" .

        
// Username
        
(isset($_SERVER['PHP_AUTH_USER']) ? 'User: ' $_SERVER['PHP_AUTH_USER'] . "\n" '') .

        
// IP Address
        
(isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n" '') .
        
$_SERVER['REMOTE_ADDR']);
// mailLog()

die;
?>
body    { margin: 0; font-family: Helvetica, Arial, sans-serif; color: #333; background-color: #E4E4E4; }
main {
    margin: 0 auto; margin-top: 30px; margin-bottom: 30px; padding: 20px; width: 760px;
    background-color: #FFF; border-radius: 8px; border: 1px solid #CCC; box-shadow: 5px 5px 5px #888;
}
h1    { font-size: 22px; margin: 0; padding: 0; color: #06C; margin-bottom: 80px; }
hr    { clear: both; border-style: solid; border-width: 1px 0 0 0; border-color: #E4E4E4; margin: 20px 0; }

/*--------------------------------
     Navigation
-------------------------------*/
nav    { margin: 40px 0; clear: both; }
nav a    {
    display: block; width: 70%; margin: 30px auto; padding: 20px; vertical-align: top;
    border: 1px solid #E4E4E4; box-shadow: 2px 2px 2px #888;
    /*border-style: solid; border-width: 0 0 1px 0; border-color: #CCC;*/
    text-decoration: none; color: #06C; font-size: 20px; font-weight: bold;
    transition: background 0.4s;
}

nav a:hover { background: #EEE; }
nav img    { display: inline-block; float: left; width: 100px; height: 100px; vertical-align: top; }
nav span{ display: inline-block; line-height: 100px; text-indent: 30px; }
.langselect { font-size: 0.8em; font-weight: bold; }

/*--------------------------------
     Buttons
-------------------------------*/
a.glowbutton, input[type="submit"], input[type="button"]    {
    white-space: nowrap; display: inline-block; min-width: 210px; margin: 0 0 10px 0; padding: 0;
    text-decoration: none; text-align: center;
    color: #FFF; background-color: #00abee; border: 0; border-radius: 6px;
    line-height: 33px; height: 33px; font-weight: bold; font-size: 0.9em;
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    transition: background 0.4s;
}

a.glowbutton:hover, input[type="submit"]:hover    {
    background-color: #0085c4; text-decoration: none;
}

.leftbuttons a        { margin-right: 10px !important; }

/*--------------------------------
     Fancy
-------------------------------*/

a    { color: #06C; text-decoration: none; }
a:hover    { text-decoration: underline; }
h2    { font-size: 1.6em; }
h3    { font-size: 1.4em; }
h4    { font-size: 1.1em; color: #666; }
.blue    { color: #06C; }
.orange { color: #F60; }
.code    { font-family: monospace; color: #090; }
.code a    { font-weight: bold; color: #090; }
.warn    {
    background-color: #FC0; padding: 15px 5px; text-align: center;
    border-radius: 5px; font-size: 0.9em; box-shadow: 2px 2px 2px #888;
}

/*--------------------------------
     Forms
-------------------------------*/
textarea                    { width: 99%; height: 200px; font-size: 1.2em; color: #666; }
input, select, textarea                { border: 1px solid #CCC; border-radius: 3px; padding: 3px; }
input:focus, textarea:focus            { background-color: #EEE; }
input[type="checkbox"], input[type="radio"]    { border: 0;}
input[type="submit"], input[type="button"]    { cursor: pointer; float: right; margin: 10px 0 0 0;  }
form table                    { width: 100%; }
form table td:first-child            { width: 50%; }

/*--------------------------------
     Responsive
-------------------------------*/
@media all and (max-width: 790px) {
    main        { width: 100%; margin: 0; padding: 20px 0; border: none; border-radius: 0; }
    nav a        { margin: 0 auto; margin-top: 20px; margin-bottom: 20px; }
    textarea    { width: 97%; }
}

Copy

Installing connections

Change the URL in the example to the URL of your connection. Our back-end automatically reads your settings.xml file and asks the user to enter the necessary data.

<a href="https://easywebshop.com/software/connections/?install=https://www.webshopdata.com/app/easywebshop-psp">Install</a>

You can add the EasyWebshop logo to your website when the connection is ready.

Logo

Troubleshooting

We polished the EasyWebshop API to make it as easy as we possibly could. We also offer a high-quality help desk service with optional assistance by a developer for more technical questions. The purpose of the API is that you can connect to other platforms and applications. They may not have an easy to use API nor the level of support that we offer. Remember when contacting us, we can only provide help for EasyWebshop and not for external applications.

If you need help with programming languages, it's best to read their documentation pages. Most are very well documented. Possibly you can use AI to generate the code for your connection, but please do not expect that our support will fix bugs in your code.

During the Summer of web design we develop custom connections for our users. These connections are made by experienced developers. If you need a complex connection or feature, this is the way to go.

I'm getting the error: "Invalid data integrity hash"
  • Check that the API Connection Token (not a regular API Token) is set in the easywebshop.php file
  • Check that the URL is correctly set
  • Check that the connection is installed by a webshop

Useful links

The technologies our API uses were chosen for the following reasons:

  • Easy to implement
  • Secure data transfer over HTTPS (no more insecure FTP connections)
  • Real-time communication
  • No additional servers or extra databases required
  • Scalable to larger volumes of data
  • Can be used with any platform, framework and programming language
  • No problems with firewalls
  • Makes use of REST, JSON, JSON-LD, XML and HTTPS standards and general practices
  • Bearer authentication with custom permissions
  • UTF-8 Encoding

If you want to use curl in PHP, you need to install the php-curl extension. On Debian based systems (including Ubuntu), use the following command:

sudo apt-get install php-curl

Scroll to top

This website does not use tracking cookies nor sells personal data.Terms and conditionsPrivacy Statement 2009 ‑ 2025 EasyWebshop