load(); } use Automattic\WooCommerce\Client; use Mollie\Api\MollieApiClient; header('Content-Type: application/json'); $db = new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASS'], $_ENV['DB_NAME']); $action = $_GET['action'] ?? ''; // --- 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']; session_write_close(); echo json_encode(['success' => true, 'user' => $res['full_name']]); } else { http_response_code(401); echo json_encode(['error' => 'Login mislukt']); } exit; } if (!isset($_SESSION['user'])) { http_response_code(403); exit; } $woocommerce = new Client($_ENV['WC_URL'], $_ENV['WC_KEY'], $_ENV['WC_SECRET'], ['version' => 'wc/v3', 'verify_ssl' => false, 'timeout' => 400]); // --- CREATE ORDER --- if ($action === 'create_order') { $input = json_decode(file_get_contents('php://input'), true); try { $mediacode = $input['mediacode_internal'] ?? 'Geen'; $wc_gateway_id = $input['payment_method']; $mollie_method = str_replace(['mollie_wc_gateway_', 'rve_'], '', $wc_gateway_id); $input['payment_method'] = $wc_gateway_id; // Compacte meta_data om WAF blokkades te voorkomen $input['meta_data'] = [ ['key' => '_wc_order_attribution_source_type', 'value' => 'utm'], ['key' => '_wc_order_attribution_utm_source', 'value' => 'SalesPanel'], ['key' => '_wc_order_attribution_utm_campaign', 'value' => $mediacode], ['key' => 'Mediacode', 'value' => $mediacode] ]; // 1. Order aanmaken (Hier gaat de 500 error vaak mis door WAF) $order = $woocommerce->post('orders', $input); $mollie = new MollieApiClient(); $mollie->setApiKey($_ENV['MOLLIE_KEY']); $paymentData = [ "amount" => ["currency" => "EUR", "value" => 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}", "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] ]; // Verplichte adresvelden voor achteraf betalen if (in_array($mollie_method, ['in3', 'klarna', 'klarnapaylater', 'klarnasliceit', 'riverty'])) { $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, '.', '')] ]]; } $payment = $mollie->payments->create($paymentData); // Update meta in aparte call om de eerste POST klein te houden $woocommerce->put("orders/{$order->id}", ['meta_data' => [['key' => '_transaction_id', 'value' => $payment->id]]]); echo json_encode(['payment_url' => $payment->getCheckoutUrl()]); } catch (Exception $e) { http_response_code(422); echo json_encode(['error' => $e->getMessage()]); } exit; } // --- OVERIGE ACTIES (POSTCODE, PRODUCTS, LOGOUT) --- if ($action === 'get_payment_methods') { try { $gateways = $woocommerce->get('payment_gateways'); $output = []; foreach ($gateways as $gw) { 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([]); } exit; } if ($action === 'get_products') { try { $products = $woocommerce->get('products', ['status' => 'publish', 'per_page' => 100]); $enriched = []; foreach ($products as $product) { $p = (array)$product; $p['variation_details'] = ($product->type === 'variable') ? (array)$woocommerce->get("products/{$product->id}/variations", ['per_page' => 50]) : []; $enriched[] = $p; } echo json_encode($enriched); } 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); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $_ENV['POSTCODE_TECH_KEY']]); echo curl_exec($ch); exit; } if ($action === 'logout') { session_destroy(); echo json_encode(['success' => true]); exit; }