774 lines
40 KiB
PHP
774 lines
40 KiB
PHP
<?php
|
|
// Prevent direct access to file
|
|
defined(security_key) or exit;
|
|
// Default values for the input form elements
|
|
$account = [
|
|
'first_name' => '',
|
|
'last_name' => '',
|
|
'address_street' => '',
|
|
'address_city' => '',
|
|
'address_state' => '',
|
|
'address_zip' => '',
|
|
'address_country' => '',
|
|
'role' => 'Member',
|
|
'address_phone' => ''
|
|
];
|
|
|
|
// Error array, output errors on the form
|
|
$errors = [];
|
|
// Redirect the user if the shopping cart is empty
|
|
if (empty($_SESSION['cart'])) {
|
|
header('Location: ' . url('index.php?page=cart'));
|
|
exit;
|
|
}
|
|
// Check if user is logged in
|
|
if (isset($_SESSION['account_loggedin'])) {
|
|
$stmt = $pdo->prepare('SELECT * FROM accounts WHERE id = ?');
|
|
$stmt->execute([ $_SESSION['account_id'] ]);
|
|
// Fetch the account from the database and return the result as an Array
|
|
$account = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
// Update discount code
|
|
if (isset($_POST['discount_code']) && !empty($_POST['discount_code'])) {
|
|
$_SESSION['discount'] = $_POST['discount_code'];
|
|
} else if (isset($_POST['discount_code']) && empty($_POST['discount_code']) && isset($_SESSION['discount'])) {
|
|
unset($_SESSION['discount']);
|
|
}
|
|
|
|
// Variables
|
|
$products_in_cart = isset($_SESSION['cart']) ? $_SESSION['cart'] : [];
|
|
$subtotal = 0.00;
|
|
$shippingtotal = 0.00;
|
|
$discounttotal = 0.00;
|
|
$taxtotal = 0.00;
|
|
$weighttotal = 0;
|
|
$selected_country = isset($_POST['address_country']) ? $_POST['address_country'] : $account['address_country'];
|
|
$selected_shipping_method = isset($_POST['shipping_method']) ? $_POST['shipping_method'] : null;
|
|
$selected_shipping_method_name = '';
|
|
$shipping_methods_available = [];
|
|
// If there are products in cart
|
|
|
|
if ($products_in_cart) {
|
|
// There are products in the cart so we need to select those products from the database
|
|
// Products in cart array to question mark string array, we need the SQL statement to include: IN (?,?,?,...etc)
|
|
$array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '?'));
|
|
$stmt = $pdo->prepare('SELECT p.*, (SELECT m.full_path FROM products_media pm JOIN media m ON m.id = pm.media_id WHERE pm.product_id = p.id ORDER BY pm.position ASC LIMIT 1) AS img, (SELECT GROUP_CONCAT(pc.category_id) FROM products_categories pc WHERE pc.product_id = p.id) AS categories FROM products p WHERE p.id IN (' . $array_to_question_marks . ')');
|
|
// We use the array_column to retrieve only the id's of the products
|
|
$stmt->execute(array_column($products_in_cart, 'id'));
|
|
// Fetch the products from the database and return the result as an Array
|
|
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
// Retrieve the discount code
|
|
if (isset($_SESSION['discount'])) {
|
|
$stmt = $pdo->prepare('SELECT * FROM discounts WHERE discount_code = ?');
|
|
$stmt->execute([ $_SESSION['discount'] ]);
|
|
$discount = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
// Get tax
|
|
$stmt = $pdo->prepare('SELECT * FROM taxes WHERE country = ?');
|
|
$stmt->execute([ isset($_POST['address_country']) ? $_POST['address_country'] : $account['address_country'] ]);
|
|
$tax = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
$tax_rate = $tax ? $tax['rate'] : 0.00;
|
|
// Get the current date
|
|
$current_date = strtotime((new DateTime())->format('Y-m-d H:i:s'));
|
|
// Retrieve shipping methods
|
|
$stmt = $pdo->query('SELECT * FROM shipping');
|
|
$shipping_methods = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
// Iterate the products in cart and add the meta data (product name, desc, etc)
|
|
|
|
foreach ($products_in_cart as &$cart_product) {
|
|
foreach ($products as $product) {
|
|
if ($cart_product['id'] == $product['id']) {
|
|
// If product no longer in stock, prepare for removal
|
|
if ((int)$product['quantity'] === 0) {
|
|
$cart_product['remove'] = 1;
|
|
|
|
} else {
|
|
$cart_product['meta'] = $product;
|
|
// Prevent the cart quantity exceeding the product quantity
|
|
$cart_product['quantity'] = ($cart_product['quantity'] > $product['quantity'] && $product['quantity'] !== -1) ? $product['quantity'] : $cart_product['quantity'];
|
|
$product_weight = $cart_product['options_weight'];
|
|
$weighttotal += $product_weight;
|
|
// Calculate the subtotal
|
|
$product_price = (float)$cart_product['options_price'];
|
|
$subtotal += $product_price * (int)$cart_product['quantity'];
|
|
|
|
// Calculate the final price, which includes tax
|
|
$cart_product['final_price'] = $product_price; //+ (($tax_rate / 100) * $product_price);
|
|
|
|
//-------------------------------
|
|
//TAX ON TOP OFF OF PRICE
|
|
//-------------------------------
|
|
//$taxtotal += (($tax_rate / 100) * $product_price) * (int)$cart_product['quantity'];
|
|
//-------------------------------
|
|
//TAX INCLUDED IN PRICE
|
|
//-------------------------------
|
|
$taxtotal += ($product_price - ($product_price/ (1 + ($tax_rate / 100))))* (int)$cart_product['quantity'];
|
|
|
|
//-------------------------------
|
|
//-------------------------------
|
|
// Check which products are eligible for a discount
|
|
if (isset($discount) && $discount && $current_date >= strtotime($discount['start_date']) && $current_date <= strtotime($discount['end_date'])) {
|
|
// Check whether product list is empty or if product id is whitelisted
|
|
if (empty($discount['product_ids']) || in_array($product['id'], explode(',', $discount['product_ids']))) {
|
|
// Check whether category list is empty or if category id is whitelisted
|
|
if (empty($discount['category_ids']) || array_intersect(explode(',', $product['categories']), explode(',', $discount['category_ids']))) {
|
|
$cart_product['discounted'] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove products that are out of stock
|
|
for ($i = 0; $i < count($products_in_cart); $i++) {
|
|
if (isset($products_in_cart[$i]['remove'])) {
|
|
unset($_SESSION['cart'][$i]);
|
|
unset($products_in_cart[$i]);
|
|
}
|
|
}
|
|
$_SESSION['cart'] = array_values($_SESSION['cart']);
|
|
$products_in_cart = array_values($products_in_cart);
|
|
// Redirect the user if the shopping cart is empty
|
|
if (empty($products_in_cart)) {
|
|
header('Location: ' . url('index.php?page=cart'));
|
|
exit;
|
|
}
|
|
// Calculate the shipping
|
|
foreach ($products_in_cart as &$cart_product) {
|
|
foreach ($shipping_methods as $shipping_method) {
|
|
// Product weight
|
|
$product_weight = $cart_product['options_weight'] ? $cart_product['options_weight'] : $weighttotal;
|
|
// Determine the price
|
|
$product_price = $shipping_method['type'] == 'Single Product' ? (float)$cart_product['options_price'] : $subtotal;
|
|
// Check if no country required or if shipping method only available in specified countries
|
|
if (empty($shipping_method['countries']) || in_array($selected_country, explode(',', $shipping_method['countries']))) {
|
|
// Compare the price and weight to meet shipping method requirements
|
|
if ($shipping_method['id'] == $selected_shipping_method && $product_price >= $shipping_method['price_from'] && $product_price <= $shipping_method['price_to'] && $product_weight >= $shipping_method['weight_from'] && $product_weight <= $shipping_method['weight_to']) {
|
|
if ($shipping_method['type'] == 'Single Product') {
|
|
// Calculate single product price
|
|
$cart_product['shipping_price'] += (float)$shipping_method['price'] * (int)$cart_product['quantity'];
|
|
$shippingtotal += $cart_product['shipping_price'];
|
|
} else {
|
|
// Calculate entire order price
|
|
$cart_product['shipping_price'] = (float)$shipping_method['price'] / count($products_in_cart);
|
|
$shippingtotal = (float)$shipping_method['price'];
|
|
}
|
|
$shipping_methods_available[] = $shipping_method['id'];
|
|
} else if ($product_price >= $shipping_method['price_from'] && $product_price <= $shipping_method['price_to'] && $product_weight >= $shipping_method['weight_from'] && $product_weight <= $shipping_method['weight_to']) {
|
|
// No method selected, so store all methods available
|
|
$shipping_methods_available[] = $shipping_method['id'];
|
|
}
|
|
}
|
|
// Update selected shipping method name
|
|
if ($shipping_method['id'] == $selected_shipping_method) {
|
|
$selected_shipping_method_name = $shipping_method['name'];
|
|
}
|
|
}
|
|
}
|
|
// Number of discounted products
|
|
$num_discounted_products = count(array_column($products_in_cart, 'discounted'));
|
|
// Iterate the products and update the price for the discounted products
|
|
foreach ($products_in_cart as &$cart_product) {
|
|
if (isset($cart_product['discounted']) && $cart_product['discounted']) {
|
|
$price = &$cart_product['final_price'];
|
|
if ($discount['discount_type'] == 'Percentage') {
|
|
$d = (float)$price * ((float)$discount['discount_value'] / 100);
|
|
//$price -= $d;
|
|
$discounttotal += $d * (int)$cart_product['quantity'];
|
|
}
|
|
if ($discount['discount_type'] == 'Fixed') {
|
|
$d = (float)$discount['discount_value'] / $num_discounted_products;
|
|
//$price -= $d / (int)$cart_product['quantity'];
|
|
$discounttotal += $d;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Override TAXTOTAAL IN CASE OF DISCOUNTS
|
|
//-------------------------------
|
|
//TAX ON TOP OFF OF PRICE
|
|
//-------------------------------
|
|
//$taxtotal = ($tax_rate / 100) * (($subtotal) - $discounttotal);
|
|
//-------------------------------
|
|
//TAX INCLUDED IN PRICE
|
|
//-------------------------------
|
|
|
|
$taxable_total = $subtotal - $discounttotal;
|
|
$taxtotal = $taxable_total - ($taxable_total / (1 + ($tax_rate / 100)));
|
|
//-------------------------------
|
|
//-------------------------------
|
|
}
|
|
// Make sure when the user submits the form all data was submitted and shopping cart is not empty
|
|
if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['address_street'], $_POST['address_city'], $_POST['address_state'], $_POST['address_zip'], $_POST['address_country'], $_POST['address_phone'], $_SESSION['cart']) && !isset($_POST['update'])) {
|
|
$account_id = null;
|
|
// If the user is already logged in
|
|
if (isset($_SESSION['account_loggedin'])) {
|
|
// Account logged-in, update the user's details
|
|
$stmt = $pdo->prepare('UPDATE accounts SET first_name = ?, last_name = ?, address_street = ?, address_city = ?, address_state = ?, address_zip = ?, address_country = ?, address_phone = ? WHERE id = ?');
|
|
$stmt->execute([ $_POST['first_name'], $_POST['last_name'], $_POST['address_street'], $_POST['address_city'], $_POST['address_state'], $_POST['address_zip'], $_POST['address_country'], $_POST['address_phone'], $_SESSION['account_id'] ]);
|
|
$account_id = $_SESSION['account_id'];
|
|
} else if (isset($_POST['email'], $_POST['password'], $_POST['cpassword']) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) && !empty($_POST['password']) && !empty($_POST['cpassword'])) {
|
|
// User is not logged in, check if the account already exists with the email they submitted
|
|
$stmt = $pdo->prepare('SELECT id FROM accounts WHERE email = ?');
|
|
$stmt->execute([ $_POST['email'] ]);
|
|
if ($stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
// Email exists, user should login instead...
|
|
$errors[] = $error_account_name;
|
|
}
|
|
if (strlen($_POST['password']) > 20 || strlen($_POST['password']) < 5) {
|
|
// Password must be between 5 and 20 characters long.
|
|
$errors[] = $error_account_password_rules;
|
|
}
|
|
if ($_POST['password'] != $_POST['cpassword']) {
|
|
// Password and confirm password fields do not match...
|
|
$errors[] = $error_account_password_match;
|
|
}
|
|
if (!$errors) {
|
|
// Hash the password
|
|
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
|
// Email doesnt exist, create new account
|
|
$stmt = $pdo->prepare('INSERT INTO accounts (email, password, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, address_phone) VALUES (?,?,?,?,?,?,?,?,?,?)');
|
|
$stmt->execute([ $_POST['email'], $password, $_POST['first_name'], $_POST['last_name'], $_POST['address_street'], $_POST['address_city'], $_POST['address_state'], $_POST['address_zip'], $_POST['address_country'], $_POST['address_phone'] ]);
|
|
$account_id = $pdo->lastInsertId();
|
|
$stmt = $pdo->prepare('SELECT * FROM accounts WHERE id = ?');
|
|
$stmt->execute([ $account_id ]);
|
|
// Fetch the account from the database and return the result as an Array
|
|
$account = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
} else if (account_required) {
|
|
$errors[] = $error_account;
|
|
}
|
|
if (!$errors && $products_in_cart) {
|
|
|
|
$payment_amount = (($subtotal)-$discounttotal)+$shippingtotal;
|
|
// No errors, process the order
|
|
if (pay_on_delivery_enabled && $_POST['method'] == 'payondelivery') {
|
|
// Process Normal Checkout
|
|
// Generate unique transaction ID
|
|
$transaction_id = strtoupper(uniqid('SC') . substr(md5(mt_rand()), 0, 5));
|
|
// Insert transaction into database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions (txn_id, payment_amount, payment_status, created, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, shipping_method, shipping_amount, discount_code, address_phone,tax_amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
|
$stmt->execute([
|
|
$transaction_id,
|
|
$payment_amount,
|
|
default_payment_status,
|
|
date('Y-m-d H:i:s'),
|
|
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
|
|
$_POST['first_name'],
|
|
$_POST['last_name'],
|
|
$_POST['address_street'],
|
|
$_POST['address_city'],
|
|
$_POST['address_state'],
|
|
$_POST['address_zip'],
|
|
$_POST['address_country'],
|
|
$account_id,
|
|
'PayOnDelivery',
|
|
$selected_shipping_method_name,
|
|
$shippingtotal,
|
|
isset($_SESSION['discount']) ? $_SESSION['discount'] : '',
|
|
$_POST['address_phone'],
|
|
$taxtotal
|
|
]);
|
|
// Get order ID
|
|
$order_id = $pdo->lastInsertId();
|
|
// Iterate products and deduct quantities
|
|
foreach ($products_in_cart as $product) {
|
|
// For every product in the shopping cart insert a new transaction into our database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options) VALUES (?,?,?,?,?)');
|
|
$stmt->execute([ $transaction_id, $product['id'], $product['final_price'], $product['quantity'], $product['options'] ]);
|
|
// Update product quantity in the products table
|
|
$stmt = $pdo->prepare('UPDATE products SET quantity = quantity - ? WHERE quantity > 0 AND id = ?');
|
|
$stmt->execute([ $product['quantity'], $product['id'] ]);
|
|
// Deduct option quantities
|
|
if ($product['options']) {
|
|
$options = explode(',', $product['options']);
|
|
foreach ($options as $opt) {
|
|
$option_name = explode('-', $opt)[0];
|
|
$option_value = explode('-', $opt)[1];
|
|
$stmt = $pdo->prepare('UPDATE products_options SET quantity = quantity - ? WHERE quantity > 0 AND title = ? AND (name = ? OR name = "")');
|
|
$stmt->execute([ $product['quantity'], $option_name, $option_value ]);
|
|
}
|
|
}
|
|
}
|
|
//Disable giftcard
|
|
if (isset($_SESSION['discount'])){
|
|
if (preg_match("/[#][0-9]/", $_SESSION['discount']) == 1){
|
|
useGiftCart($pdo, $_SESSION['discount']);
|
|
}
|
|
}
|
|
|
|
// Authenticate the user
|
|
if ($account_id != null) {
|
|
// Log the user in with the details provided
|
|
session_regenerate_id();
|
|
$_SESSION['account_loggedin'] = TRUE;
|
|
$_SESSION['account_id'] = $account_id;
|
|
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
|
|
}
|
|
// Send order details to the specified email address
|
|
send_order_details_email(
|
|
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
|
|
$products_in_cart,
|
|
$_POST['first_name'],
|
|
$_POST['last_name'],
|
|
$_POST['address_street'],
|
|
$_POST['address_city'],
|
|
$_POST['address_state'],
|
|
$_POST['address_zip'],
|
|
$_POST['address_country'],
|
|
$subtotal,
|
|
$discounttotal,
|
|
$shippingtotal,
|
|
$taxtotal,
|
|
$payment_amount,
|
|
$order_id
|
|
);
|
|
header('Location: ' . url('index.php?page=placeorder'));
|
|
exit;
|
|
|
|
}
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// Mollie ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
if (mollie_enabled && $_POST['method'] == 'mollie') {
|
|
// Process Normal Checkout
|
|
// Generate unique transaction ID
|
|
$transaction_id = strtoupper(uniqid('SC') . substr(md5(mt_rand()), 0, 5));
|
|
// Insert transaction into database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions (txn_id, payment_amount, payment_status, created, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, shipping_method, shipping_amount, discount_code, address_phone, tax_amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
|
$stmt->execute([
|
|
$transaction_id,
|
|
$payment_amount,
|
|
default_payment_status,
|
|
date('Y-m-d H:i:s'),
|
|
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
|
|
$_POST['first_name'],
|
|
$_POST['last_name'],
|
|
$_POST['address_street'],
|
|
$_POST['address_city'],
|
|
$_POST['address_state'],
|
|
$_POST['address_zip'],
|
|
$_POST['address_country'],
|
|
$account_id,
|
|
'Debit/Credit',
|
|
$selected_shipping_method_name,
|
|
$shippingtotal,
|
|
isset($_SESSION['discount']) ? $_SESSION['discount'] : '',
|
|
$_POST['address_phone'],
|
|
$taxtotal
|
|
]);
|
|
// Get order ID
|
|
$order_id = $pdo->lastInsertId();
|
|
// Iterate products and deduct quantities
|
|
foreach ($products_in_cart as $product) {
|
|
// For every product in the shopping cart insert a new transaction into our database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options) VALUES (?,?,?,?,?)');
|
|
$stmt->execute([ $transaction_id, $product['id'], $product['final_price'], $product['quantity'], $product['options'] ]);
|
|
// Update product quantity in the products table
|
|
$stmt = $pdo->prepare('UPDATE products SET quantity = quantity - ? WHERE quantity > 0 AND id = ?');
|
|
$stmt->execute([ $product['quantity'], $product['id'] ]);
|
|
// Deduct option quantities
|
|
if ($product['options']) {
|
|
$options = explode(',', $product['options']);
|
|
foreach ($options as $opt) {
|
|
$option_name = explode('-', $opt)[0];
|
|
$option_value = explode('-', $opt)[1];
|
|
$stmt = $pdo->prepare('UPDATE products_options SET quantity = quantity - ? WHERE quantity > 0 AND title = ? AND (name = ? OR name = "")');
|
|
$stmt->execute([ $product['quantity'], $option_name, $option_value ]);
|
|
}
|
|
}
|
|
}
|
|
// Authenticate the user
|
|
if ($account_id != null) {
|
|
// Log the user in with the details provided
|
|
session_regenerate_id();
|
|
$_SESSION['account_loggedin'] = TRUE;
|
|
$_SESSION['account_id'] = $account_id;
|
|
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
|
|
}
|
|
|
|
try {
|
|
/*
|
|
* Initialize the Mollie API library with your API key.
|
|
*
|
|
* See: https://www.mollie.com/dashboard/developers/api-keys
|
|
*/
|
|
require "initialize.php";
|
|
|
|
/*
|
|
* Generate a unique order id for this example. It is important to include this unique attribute
|
|
* in the redirectUrl (below) so a proper return page can be shown to the customer.
|
|
*/
|
|
$orderId = $transaction_id;
|
|
$value = number_format(($subtotal-$discounttotal)+$shippingtotal,2,'.','');
|
|
|
|
/*
|
|
* Determine the url parts to these example files.
|
|
*/
|
|
$protocol = isset($_SERVER['HTTPS']) && strcasecmp('off', $_SERVER['HTTPS']) !== 0 ? "https" : "http";
|
|
$hostname = $_SERVER['HTTP_HOST'];
|
|
$path = dirname($_SERVER['REQUEST_URI'] ?? $_SERVER['PHP_SELF']);
|
|
|
|
/*
|
|
* Payment parameters:
|
|
* amount Amount in EUROs. This example creates a € 10,- payment.
|
|
* description Description of the payment.
|
|
* redirectUrl Redirect location. The customer will be redirected there after the payment.
|
|
* webhookUrl Webhook location, used to report when the payment changes state.
|
|
* metadata Custom metadata that is stored with the payment.
|
|
*/
|
|
|
|
if (rewrite_url){
|
|
$redirectURL = $protocol.'://'.$hostname.$path.'placeorder/'.$orderId;
|
|
}else{
|
|
$redirectURL = $protocol.'://'.$hostname.$path.'index.php?page=placeorder&order_id='.$orderId;
|
|
}
|
|
|
|
$payment = $mollie->payments->create([
|
|
"amount" => [
|
|
"currency" => "EUR",
|
|
"value" => "{$value}", // You must send the correct number of decimals, thus we enforce the use of strings
|
|
],
|
|
"description" => "Order #{$orderId}",
|
|
"redirectUrl" => "$redirectURL",
|
|
"webhookUrl" => "{$protocol}://{$hostname}{$path}webhook.php",
|
|
"metadata" => [
|
|
"order_id" => $orderId,
|
|
],
|
|
]);
|
|
/*
|
|
* Send the customer off to complete the payment.
|
|
* This request should always be a GET, thus we enforce 303 http response code
|
|
*/
|
|
|
|
// Send order details to the specified email address
|
|
send_order_details_email(
|
|
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
|
|
$products_in_cart,
|
|
$_POST['first_name'],
|
|
$_POST['last_name'],
|
|
$_POST['address_street'],
|
|
$_POST['address_city'],
|
|
$_POST['address_state'],
|
|
$_POST['address_zip'],
|
|
$_POST['address_country'],
|
|
$subtotal,
|
|
$discounttotal,
|
|
$shippingtotal,
|
|
$taxtotal,
|
|
$payment_amount,
|
|
$order_id
|
|
);
|
|
|
|
// Send customer to checkout
|
|
header("Location: " . $payment->getCheckoutUrl(), true, 303);
|
|
|
|
} catch (\Mollie\Api\Exceptions\ApiException $e) {
|
|
echo "API call failed: " . htmlspecialchars($e->getMessage());
|
|
}
|
|
exit;
|
|
}
|
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// PayPal Payment + +++++++++++++++++++++++++++++++++++++++++
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
if (paypal_enabled && $_POST['method'] == 'paypal') {
|
|
// Process Normal Checkout first then do PayPal related
|
|
// Generate unique transaction ID
|
|
$transaction_id = strtoupper(uniqid('SC') . substr(md5(mt_rand()), 0, 5));
|
|
// Insert transaction into database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions (txn_id, payment_amount, payment_status, created, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, shipping_method, shipping_amount, discount_code, address_phone, tax_amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
|
$stmt->execute([
|
|
$transaction_id,
|
|
$payment_amount,
|
|
default_payment_status,
|
|
date('Y-m-d H:i:s'),
|
|
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
|
|
$_POST['first_name'],
|
|
$_POST['last_name'],
|
|
$_POST['address_street'],
|
|
$_POST['address_city'],
|
|
$_POST['address_state'],
|
|
$_POST['address_zip'],
|
|
$_POST['address_country'],
|
|
$account_id,
|
|
'paypal',
|
|
$selected_shipping_method_name,
|
|
$shippingtotal,
|
|
isset($_SESSION['discount']) ? $_SESSION['discount'] : '',
|
|
$_POST['address_phone'],
|
|
$taxtotal
|
|
]);
|
|
// Get order ID
|
|
$order_id = $pdo->lastInsertId();
|
|
// Iterate products and deduct quantities
|
|
foreach ($products_in_cart as $product) {
|
|
// For every product in the shopping cart insert a new transaction into our database
|
|
$stmt = $pdo->prepare('INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options) VALUES (?,?,?,?,?)');
|
|
$stmt->execute([ $transaction_id, $product['id'], $product['final_price'], $product['quantity'], $product['options'] ]);
|
|
// Update product quantity in the products table
|
|
$stmt = $pdo->prepare('UPDATE products SET quantity = quantity - ? WHERE quantity > 0 AND id = ?');
|
|
$stmt->execute([ $product['quantity'], $product['id'] ]);
|
|
// Deduct option quantities
|
|
if ($product['options']) {
|
|
$options = explode(',', $product['options']);
|
|
foreach ($options as $opt) {
|
|
$option_name = explode('-', $opt)[0];
|
|
$option_value = explode('-', $opt)[1];
|
|
$stmt = $pdo->prepare('UPDATE products_options SET quantity = quantity - ? WHERE quantity > 0 AND title = ? AND (name = ? OR name = "")');
|
|
$stmt->execute([ $product['quantity'], $option_name, $option_value ]);
|
|
}
|
|
}
|
|
}
|
|
if ($account_id != null) {
|
|
// Log the user in with the details provided
|
|
session_regenerate_id();
|
|
$_SESSION['account_loggedin'] = TRUE;
|
|
$_SESSION['account_id'] = $account_id;
|
|
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
|
|
}
|
|
//Process Payment
|
|
require_once __DIR__."/lib/paypal/paypal.php";
|
|
|
|
$base = PAYPAL_URL;
|
|
$id = PAYPAL_CLIENT_ID;
|
|
$secret = PAYPAL_CLIENT_SECRET;
|
|
|
|
//init input
|
|
$order = $transaction_id;
|
|
$price = $payment_amount;
|
|
$currency = "EUR";
|
|
|
|
//make payment
|
|
$paypal = new paypalCurl();
|
|
$paypal->init($id,$secret,$base);
|
|
$result = $paypal->makePaymentURL($order,$price,$currency);
|
|
|
|
if ($result->status === true) {
|
|
header("location:". $result->url);
|
|
die;
|
|
}
|
|
else { //raise error
|
|
echo $result->msg;
|
|
die;
|
|
}
|
|
}
|
|
|
|
}
|
|
// Preserve form details if the user encounters an error
|
|
$account = [
|
|
'first_name' => $_POST['first_name'],
|
|
'last_name' => $_POST['last_name'],
|
|
'address_street' => $_POST['address_street'],
|
|
'address_city' => $_POST['address_city'],
|
|
'address_state' => $_POST['address_state'],
|
|
'address_zip' => $_POST['address_zip'],
|
|
'address_country' => $_POST['address_country'],
|
|
'address_phone' => $_POST['address_phone']
|
|
];
|
|
}
|
|
|
|
$terms_link = url('index.php?page=termsandconditions');
|
|
|
|
?>
|
|
<?=template_header('Checkout')?>
|
|
|
|
|
|
<div class="checkout content-wrapper">
|
|
|
|
<h1><?=$h1_checkout?></h1>
|
|
|
|
<p class="error"><?=implode('<br>', $errors)?></p>
|
|
|
|
<?php if (!isset($_SESSION['account_loggedin'])): ?>
|
|
<p><?=$account_available?> <a href="<?=url('index.php?page=myaccount')?>"><?=$account_log_in?></a></p>
|
|
<?php endif; ?>
|
|
|
|
<form action="" method="post">
|
|
|
|
<div class="container">
|
|
|
|
<div class="shipping-details">
|
|
<div id="dropin-container"></div>
|
|
<h2><?=$payment_method?></h2>
|
|
|
|
<div class="payment-methods">
|
|
<?php if (mollie_enabled): ?>
|
|
<input id="mollie" type="radio" name="method" value="mollie" <?= ((mollie_default)? 'checked':'') ?>>
|
|
<label for="mollie">
|
|
<img src="./custom/assets/iDEAL.png" style="width: 50px;" alt="<?=$payment_method_1?>">
|
|
<img src="./custom/assets/bancontact.png" style="width: 50px;" alt="<?=$payment_method_1?>">
|
|
</label>
|
|
<?php endif; ?>
|
|
|
|
<?php if (paypal_enabled): ?>
|
|
<input id="paypal" type="radio" name="method" value="paypal" <?= ((paypal_default)? 'checked':'') ?>>
|
|
<label for="paypal"><img src="https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png" alt="PayPal Logo"></label>
|
|
<?php endif; ?>
|
|
|
|
<?php if (pay_on_delivery_enabled): ?>
|
|
<input id="payondelivery" type="radio" name="method" value="payondelivery" <?= ((pay_on_delivery_default)? 'checked':'') ?> >
|
|
<label for="payondelivery"><?=$payment_method_2?></label>
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
|
|
<?php if (!isset($_SESSION['account_loggedin'])): ?>
|
|
|
|
<h2><?=$account_create_email?></h2>
|
|
<label for="email"></label>
|
|
<input type="email" name="email" id="email" placeholder="<?=$account_create_email?>" class="form-field" required>
|
|
|
|
<h2><?=$account_create?><?php if (!account_required): ?> <?=$account_create_optional?><?php endif; ?></h2>
|
|
<label for="password"><?=$account_create_password?></label>
|
|
<input type="password" name="password" id="password" placeholder="<?=$account_create_password?>" class="form-field" autocomplete="new-password">
|
|
|
|
<label for="cpassword"><?=$account_create_password_confirm?></label>
|
|
<input type="password" name="cpassword" id="cpassword" placeholder="<?=$account_create_password_confirm?>" class="form-field" autocomplete="new-password">
|
|
<?php endif; ?>
|
|
|
|
<h2><?=$h2_Shipping_details?></h2>
|
|
|
|
<div class="row1">
|
|
<label for="first_name"><?=$shipping_first_name?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['first_name'], ENT_QUOTES)?>" name="first_name" id="first_name" placeholder="<?=$shipping_first_name?>" class="form-field" required>
|
|
</div>
|
|
|
|
<div class="row2">
|
|
<label for="last_name"><?=$shipping_last_name?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['last_name'], ENT_QUOTES)?>" name="last_name" id="last_name" placeholder="<?=$shipping_last_name?>" class="form-field" required>
|
|
</div>
|
|
|
|
<label for="address_street"><?=$shipping_address?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['address_street'], ENT_QUOTES)?>" name="address_street" id="address_street" placeholder="<?=$shipping_address?>" class="form-field" required>
|
|
|
|
<label for="address_city"><?=$shipping_city?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['address_city'], ENT_QUOTES)?>" name="address_city" id="address_city" placeholder="<?=$shipping_city?>" class="form-field" required>
|
|
|
|
<div class="row1">
|
|
<label for="address_state"><?=$shipping_state?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['address_state'], ENT_QUOTES)?>" name="address_state" id="address_state" placeholder="<?=$shipping_state?>" class="form-field">
|
|
</div>
|
|
|
|
<div class="row2">
|
|
<label for="address_zip"><?=$shipping_zip?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['address_zip'], ENT_QUOTES)?>" name="address_zip" id="address_zip" placeholder="<?=$shipping_zip?>" class="form-field" required>
|
|
</div>
|
|
|
|
|
|
<label for="address_phone"><?=$shipping_phone?></label>
|
|
<input type="text" value="<?=htmlspecialchars($account['address_phone'], ENT_QUOTES)?>" name="address_phone" id="address_phone" placeholder="<?=$shipping_phone?>" class="form-field" required>
|
|
|
|
<label for="address_country"><?=$shipping_country?></label>
|
|
<select name="address_country" class="ajax-update form-field" required>
|
|
<?php foreach(get_countries() as $country): ?>
|
|
<option value="<?=$country?>"<?=$country==$account['address_country']?' selected':''?>><?=$country?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="cart-details">
|
|
|
|
<h2><?=$h2_shoppingcart?></h2>
|
|
|
|
<table>
|
|
<?php foreach($products_in_cart as $product): ?>
|
|
<tr>
|
|
<td><img src="<?=$product['meta']['img']?>" width="35" height="35" alt="<?=$product['meta']['name']?>"></td>
|
|
<td><?=$product['quantity']?> x <?=$product['meta']['name']?></td>
|
|
<td class="price"><?=currency_code?><?=number_format($product['options_price'] * $product['quantity'],2)?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
|
|
<div class="discount-code">
|
|
<input type="text" class="ajax-update form-field" name="discount_code" placeholder="<?=$discount_label?>" value="<?=isset($_SESSION['discount']) ? $_SESSION['discount'] : ''?>">
|
|
<span class="result">
|
|
<?php if (isset($_SESSION['discount'], $discount) && !$discount): ?>
|
|
<?=$discount_error_1?>
|
|
<?php elseif (isset($_SESSION['discount'], $discount) && $current_date < strtotime($discount['start_date'])): ?>
|
|
<?=$discount_error_1?>
|
|
<?php elseif (isset($_SESSION['discount'], $discount) && $current_date > strtotime($discount['end_date'])): ?>
|
|
<?=$discount_error_2?>
|
|
<?php elseif (isset($_SESSION['discount'], $discount)): ?>
|
|
<?=$discount_message?>
|
|
<?php endif; ?>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="shipping-methods-container">
|
|
<?php if ($shipping_methods_available): ?>
|
|
<div class="shipping-methods">
|
|
<h3><?=$h3_shipping_method?></h3>
|
|
<?php foreach($shipping_methods as $k => $method): ?>
|
|
<?php if (!in_array($method['id'], $shipping_methods_available)) continue; ?>
|
|
<div class="shipping-method">
|
|
<input type="radio" class="ajax-update" id="sm<?=$k?>" name="shipping_method" value="<?=$method['id']?>" required<?=$selected_shipping_method==$method['id']?' checked':''?>>
|
|
<label for="sm<?=$k?>"><?=$method['name']?> (<?=currency_code?><?=number_format($method['price'], 2)?><?=$method['type']=='Single Product'?' per item':''?>)</label>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="summary">
|
|
<div class="subtotal">
|
|
<span><?=$total_subtotal?></span>
|
|
<span><?=currency_code?><?=number_format($subtotal,2)?></span>
|
|
</div>
|
|
|
|
<div class="shipping">
|
|
<span><?=$total_shipping?></span>
|
|
<span><?=currency_code?><?=number_format($shippingtotal,2)?></span>
|
|
</div>
|
|
|
|
<?php if ($discounttotal > 0): ?>
|
|
<div class="discount">
|
|
<span><?=$total_discount?></span>
|
|
<span>-<?=currency_code?><?=number_format(round($discounttotal, 1),2)?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($tax): ?>
|
|
<div class="vat">
|
|
<span>VAT <span class="alt">(<?=$tax['rate']?>%)</span></span>
|
|
<span><?=currency_code?><?=number_format($taxtotal,2)?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="total">
|
|
<span><?=$total_total?> <span class="alt"><?=$total_total_note?></span></span><span><?=currency_code?><?=number_format(($subtotal)-round($discounttotal,1)+$shippingtotal,2)?></span>
|
|
</div>
|
|
<div class="summary">
|
|
<div class="subtotal">
|
|
<span>
|
|
<input type="checkbox" id="consent" name="consent_comms" value="1"><?=$order_consent_1?></a>
|
|
</span>
|
|
</div>
|
|
<div class="subtotal">
|
|
<span>
|
|
<input type="checkbox" id="consent" name="consent" value="1" required><?=$order_consent_2?> <a href="<?=$terms_link?>" target="_blank"><?=$order_consent_3?></a>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="buttons">
|
|
<button type="submit" name="checkout" class="btn"><?=$btn_place_order?></button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
<?=template_footer()?>
|