diff --git a/api.php b/api.php
index 60258aa..3efca87 100644
--- a/api.php
+++ b/api.php
@@ -1,7 +1,6 @@
connect_error) {
- die(json_encode(['error' => 'Database connectie mislukt']));
+if ($db->connect_error) { die(json_encode(['error' => 'Database connectie mislukt'])); }
+
+function writeLog($action, $details) {
+ global $db;
+ $user = $_SESSION['user'] ?? 'system';
+ $stmt = $db->prepare("INSERT INTO sales_logs (username, action, details, created_at) VALUES (?, ?, ?, NOW())");
+ $stmt->bind_param("sss", $user, $action, $details);
+ $stmt->execute();
}
+
$action = $_GET['action'] ?? '';
-// --- 1. LOGIN ACTIE ---
+// --- AUTH ---
if ($action === 'login') {
$input = json_decode(file_get_contents('php://input'), true);
$stmt = $db->prepare("SELECT password, full_name FROM sales_users WHERE username = ?");
$stmt->bind_param("s", $input['username']);
$stmt->execute();
$res = $stmt->get_result()->fetch_assoc();
-
if ($res && password_verify($input['password'], $res['password'])) {
$_SESSION['user'] = $input['username'];
$_SESSION['full_name'] = $res['full_name'];
+ writeLog('LOGIN', 'Gebruiker ingelogd');
session_write_close();
echo json_encode(['success' => true, 'user' => $res['full_name']]);
} else {
- http_response_code(401);
- echo json_encode(['error' => 'Inloggegevens onjuist']);
+ http_response_code(401); echo json_encode(['error' => 'Login mislukt']);
}
exit;
}
-// Auth check voor alle andere acties
if (!isset($_SESSION['user']) && $action !== 'login') {
- http_response_code(403);
- echo json_encode(['error' => 'Sessie verlopen']);
- exit;
+ http_response_code(403); exit;
}
-// --- CLIENTS ---
$woocommerce = new Client($_ENV['WC_URL'], $_ENV['WC_KEY'], $_ENV['WC_SECRET'], ['version' => 'wc/v3', 'verify_ssl' => false, 'timeout' => 400]);
-// --- 2. HELPERS ---
+// --- HELPERS ---
if ($action === 'get_payment_methods') {
try {
$gateways = $woocommerce->get('payment_gateways');
$output = [];
foreach ($gateways as $gw) {
- // Filter Apple Pay en Google Pay hier volledig weg
- if (str_contains($gw->id, 'applepay') || str_contains($gw->id, 'googlepay') || str_contains($gw->id, 'riverty') || str_contains($gw->id, 'klarna')) {
- continue;
- }
+ if (str_contains($gw->id, 'applepay') || str_contains($gw->id, 'googlepay')) continue;
if ($gw->enabled && (str_contains($gw->id, 'mollie') || str_contains($gw->id, 'riverty') || str_contains($gw->id, 'klarna'))) {
$output[] = ['id' => $gw->id, 'title' => $gw->method_title];
}
}
echo json_encode($output);
- } catch (Exception $e) {
- echo json_encode([]);
- }
+ } catch (Exception $e) { echo json_encode([]); }
exit;
}
@@ -88,108 +83,88 @@ if ($action === 'get_products') {
$enriched[] = $p;
}
echo json_encode($enriched);
- } catch (Exception $e) {
- echo json_encode([]);
- }
+ } catch (Exception $e) { echo json_encode([]); }
exit;
}
if ($action === 'postcode_check') {
$postcode = str_replace(' ', '', $_GET['postcode']);
$url = "https://postcode.tech/api/v1/postcode?postcode={$postcode}&number=" . $_GET['number'];
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $_ENV['POSTCODE_TECH_KEY']]);
- echo curl_exec($ch);
- exit;
+ echo curl_exec($ch); exit;
}
-// --- 3. CREATE ORDER (V7.0 - INCL. 100 EURO THRESHOLD) ---
+// --- CREATE ORDER (V8.1 - MET LOGGING) ---
if ($action === 'create_order') {
$input = json_decode(file_get_contents('php://input'), true);
try {
+ $email = $input['billing']['email'];
$mediacode = $input['mediacode_internal'] ?? 'Geen';
+ $shipping_incl_tax = (float)($input['shipping_total'] ?? 0);
$wc_gateway_id = $input['payment_method'];
$mollie_method = str_replace(['mollie_wc_gateway_', 'rve_'], '', $wc_gateway_id);
+ // 1. ACCOUNT SYNC
+ $existing_customers = $woocommerce->get('customers', ['email' => $email]);
+ $input['customer_id'] = !empty($existing_customers) ? $existing_customers[0]->id : 0;
+
+ // 2. SHIPPING TAX FIX
+ if ($shipping_incl_tax > 0) {
+ $shipping_ex_tax = $shipping_incl_tax / 1.21;
+ $input['shipping_lines'] = [['method_id' => 'flat_rate', 'method_title' => 'Verzendkosten', 'total' => number_format($shipping_ex_tax, 4, '.', '')]];
+ }
+
$input['payment_method'] = $wc_gateway_id;
$input['customer_note'] = "Agent: {$_SESSION['user']} | Mediacode: $mediacode";
- // Attribution data voor herkomst-blokje
+ // 3. ATTRIBUTION METADATA
$input['meta_data'][] = ['key' => '_wc_order_attribution_source_type', 'value' => 'utm'];
$input['meta_data'][] = ['key' => '_wc_order_attribution_utm_source', 'value' => 'SalesPanel'];
$input['meta_data'][] = ['key' => '_wc_order_attribution_utm_campaign', 'value' => $mediacode];
- $input['meta_data'][] = ['key' => '_wc_order_attribution_origin', 'value' => 'Sales Panel'];
$input['meta_data'][] = ['key' => 'Mediacode', 'value' => $mediacode];
- // A. Order aanmaken in WooCommerce
+ // ORDER AANMAKEN
$order = $woocommerce->post('orders', $input);
- // EXTRA CHECK: Termijn betalingen pas vanaf 100 euro
- if (in_array($mollie_method, ['in3', 'klarna', 'klarnapaylater', 'klarnasliceit']) && (float)$order->total < 100.00) {
+ // 4. TERMIJN CHECK
+ if (in_array($mollie_method, ['in3', 'klarna', 'klarnapaylater', 'klarnasliceit', 'riverty']) && (float)$order->total < 100.00) {
$woocommerce->delete("orders/{$order->id}", ['force' => true]);
- throw new Exception("Termijnbetaling (in3/Klarna) pas mogelijk vanaf €100,-");
+ throw new Exception("Termijnbetaling pas vanaf €100,-");
}
+ // 5. MOLLIE PAYMENT
$mollie = new MollieApiClient();
$mollie->setApiKey($_ENV['MOLLIE_KEY']);
- $is_sub = (stripos(json_encode($order->line_items), 'abonnement') !== false);
-
- // B. Voorbereiden Mollie Data
+
$paymentData = [
- "amount" => ["currency" => "EUR", "value" => ($mollie_method === 'ideal' && $is_sub) ? "0.01" : number_format((float)$order->total, 2, '.', '')],
- "description" => "Order #{$order->id}",
- "redirectUrl" => $_ENV['WC_URL'] . "/checkout/order-received/{$order->id}/?key={$order->order_key}&order_id={$order->id}&utm_source=SalesPanel&utm_campaign={$mediacode}",
+ "amount" => ["currency" => "EUR", "value" => number_format((float)$order->total, 2, '.', '')],
+ "description" => "Order #{$order->id} [$mediacode]",
+ "redirectUrl" => $_ENV['WC_URL'] . "/checkout/order-received/{$order->id}/?key={$order->order_key}&order_id={$order->id}&utm_source=SalesPanel&utm_campaign=" . urlencode($mediacode),
"webhookUrl" => $_ENV['WC_URL'] . "/wc-api/{$wc_gateway_id}/?key={$order->order_key}&order_id={$order->id}",
"method" => $mollie_method,
"metadata" => ["order_id" => (string)$order->id, "mediacode" => $mediacode]
];
- // C. "Light Lines" fix voor Server Error 500 / Klarna-validatie
if (in_array($mollie_method, ['in3', 'klarna', 'klarnapaylater', 'klarnasliceit', 'riverty'])) {
- if ($mollie_method === 'riverty') {
- $paymentData["captureMode"] = "manual";
- }
- $paymentData["billingAddress"] = [
- "givenName" => $input['billing']['first_name'],
- "familyName" => $input['billing']['last_name'],
- "email" => $input['billing']['email'],
- "streetAndNumber" => $input['billing']['address_1'],
- "city" => $input['billing']['city'],
- "postalCode" => $input['billing']['postcode'],
- "country" => "NL"
- ];
- $paymentData["lines"] = [[
- "name" => "Bestelling #" . $order->id,
- "quantity" => 1,
- "unitPrice" => ["currency" => "EUR", "value" => number_format((float)$order->total, 2, '.', '')],
- "totalAmount" => ["currency" => "EUR", "value" => number_format((float)$order->total, 2, '.', '')],
- "vatRate" => "21.00",
- "vatAmount" => ["currency" => "EUR", "value" => number_format((float)$order->total_tax, 2, '.', '')]
- ]];
+ if ($mollie_method === 'riverty') $paymentData["captureMode"] = "manual";
+ $paymentData["billingAddress"] = ["givenName" => $input['billing']['first_name'], "familyName" => $input['billing']['last_name'], "email" => $input['billing']['email'], "streetAndNumber" => $input['billing']['address_1'], "city" => $input['billing']['city'], "postalCode" => $input['billing']['postcode'], "country" => "NL"];
+ $paymentData["lines"] = [["name" => "Bestelling #" . $order->id, "quantity" => 1, "unitPrice" => ["currency" => "EUR", "value" => number_format((float)$order->total, 2, '.', '')], "totalAmount" => ["currency" => "EUR", "value" => number_format((float)$order->total, 2, '.', '')], "vatRate" => "21.00", "vatAmount" => ["currency" => "EUR", "value" => number_format((float)$order->total_tax, 2, '.', '')]]];
}
- // D. Mollie betaling aanmaken
$payment = $mollie->payments->create($paymentData);
- // E. Update Mollie ID in WooCommerce
- $woocommerce->put("orders/{$order->id}", ['meta_data' => [['key' => '_mollie_payment_id', 'value' => $payment->id], ['key' => '_transaction_id', 'value' => $payment->id], ['key' => '_mediacode', 'value' => $mediacode]]]);
-
- $woocommerce->post("orders/{$order->id}/notes", [
- 'note' => "Betaallink gegenereerd: " . $payment->getCheckoutUrl(),
- 'customer_note' => true // Dit stuurt een mail naar de klant met de link!
- ]);
+ // 7. FINISH ORDER
+ $woocommerce->put("orders/{$order->id}", ['meta_data' => [['key' => '_mollie_payment_id', 'value' => $payment->id], ['key' => '_transaction_id', 'value' => $payment->id]]]);
+ $woocommerce->post("orders/{$order->id}/notes", ['note' => "Voltooi de betaling of keur de incasso z.s.m. goed via de volgende link:
" . $payment->getCheckoutUrl(), 'customer_note' => true]);
+ writeLog('ORDER_CREATED', "Order #{$order->id} voor {$input['billing']['email']}");
echo json_encode(['payment_url' => $payment->getCheckoutUrl()]);
} catch (Exception $e) {
- http_response_code(422);
- echo json_encode(['error' => $e->getMessage()]);
+ writeLog('ERROR', $e->getMessage());
+ http_response_code(422); echo json_encode(['error' => $e->getMessage()]);
}
exit;
}
-if ($action === 'logout') {
- session_destroy();
- echo json_encode(['success' => true]);
- exit;
-}
+if ($action === 'logout') { session_destroy(); echo json_encode(['success' => true]); exit; }
\ No newline at end of file
diff --git a/index.html b/index.html
index 25d365a..f10ee0e 100644
--- a/index.html
+++ b/index.html
@@ -5,14 +5,14 @@
Upsell Suggesties
-