Exemplo n.º 1
0
        header("HTTP/1.1 500 Internal Server Error");
        echo "Order with ID '" . $orderId . "' has already been processed";
        exit;
    }
    $amount = (int) round(((double) $order["Price"] + (double) $order["Vat"]) * 100);
    // Amount in smallest possible unit (e.g. USD 10095 = USD 100.95)
    $currency = $order["Currency"];
    $continueUrl = SMEnvironment::GetExternalUrl();
    $continueUrl .= SMAttributes::GetAttribute("SMShopReceiptPage") !== null && SMAttributes::GetAttribute("SMShopReceiptPage") !== "" ? "/" . SMAttributes::GetAttribute("SMShopReceiptPage") : "";
    $callbackUrl = SMEnvironment::GetExternalUrl() . "/" . SMExtensionManager::GetCallbackUrl(SMExtensionManager::GetExecutingExtension(), "Callbacks/Payment") . "&PaymentOperation=Auth";
    $p = PSP::GetPaymentProvider($order["PaymentMethod"]);
    $p->RedirectToPaymentForm($orderId, $amount, $currency, $continueUrl, $callbackUrl);
} else {
    if ($operation === "Auth") {
        $data = PSP::GetCallbackData();
        // Securely obtain data passed to callback
        $transactionId = $data["TransactionId"];
        // String
        $orderId = $data["OrderId"];
        // String
        //$amount = $data["Amount"];				// Integer
        //$currency = $data["Currency"];			// String
        $order = getOrder($orderId);
        $order["TransactionId"] = $transactionId;
        $order["State"] = "Authorized";
        $ds = new SMDataSource("SMShopOrders");
        $ds->Lock();
        $ds->Update($order, "Id = '" . $ds->Escape($order["Id"]) . "'");
        $ds->Commit();
    }
}
Exemplo n.º 2
0
         $jsonItem = SMShopDataItemToJson($dsDef, $props, $item);
         // Data returned is UTF8 encoded
         $jsonItems .= ($jsonItems !== "" ? ", " : "") . $jsonItem;
     }
     echo "[" . $jsonItems . "]";
 } else {
     if ($command === "Update") {
         $item = new SMKeyValueCollection();
         foreach ($props as $prop => $val) {
             $item[$prop] = (string) $val;
         }
         if (isset($dsDef["Callbacks"]) === true && isset($dsDef["Callbacks"]["Functions"]["Update"]) === true) {
             require_once $dsDef["Callbacks"]["File"];
             $dsDef["Callbacks"]["Functions"]["Update"]($item);
         }
         $ds->Update($item, "Id = '" . $ds->Escape($props["Id"]) . "'");
         $ds->Commit();
         if (isset($dsDef["Callbacks"]) === true && isset($dsDef["Callbacks"]["Functions"]["UpdateCompleted"]) === true) {
             require_once $dsDef["Callbacks"]["File"];
             $dsDef["Callbacks"]["Functions"]["UpdateCompleted"]($item);
         }
         SMShopDataItemToJson($dsDef, $props, $item);
         // Return updated data to client (UTF8 encoded)
     } else {
         if ($command === "Delete") {
             if (isset($dsDef["Callbacks"]) === true && isset($dsDef["Callbacks"]["Functions"]["Delete"]) === true) {
                 require_once $dsDef["Callbacks"]["File"];
                 $dsDef["Callbacks"]["Functions"]["Delete"]($ds->Escape($props["Id"]));
             }
             $ds->Delete("Id = '" . $ds->Escape($props["Id"]) . "'");
             $ds->Commit();
Exemplo n.º 3
0
function SMShopProcessNewOrder(SMKeyValueCollection $order)
{
    // Variables
    $eDs = new SMDataSource("SMShopOrderEntries");
    $pDs = new SMDataSource("SMShopProducts");
    $products = null;
    $product = null;
    $discount = 0;
    $discountExpression = null;
    $expr = null;
    $price = 0;
    $priceTotal = 0;
    $vatTotal = 0;
    $currency = null;
    $weightTotal = 0;
    $weightUnit = null;
    $shippingExpense = 0;
    $shippingVat = 0;
    // Load order entries
    if ($eDs->GetDataSourceType() === SMDataSourceType::$Xml) {
        $eDs->Lock();
    }
    $entries = $eDs->Select("*", "OrderId = '" . $eDs->Escape($order["Id"]) . "'");
    // Ensure that order has order entries associated
    if (count($entries) === 0) {
        header("HTTP/1.1 500 Internal Server Error");
        echo "Inconsistent order - no associated order entries found (must be created first)";
        exit;
    }
    // Obtain new order ID (order was created with a temporary ID (GUID) generated client side)
    SMAttributes::Lock();
    // Prevent two sessions from obtaining the same Order ID
    SMAttributes::Reload(false);
    // No data will be lost when reloading attributes from a callback since no extensions are being executed
    $orderIdStr = SMAttributes::GetAttribute("SMShopNextOrderId");
    $orderId = $orderIdStr !== null ? (int) $orderIdStr : 1;
    SMAttributes::SetAttribute("SMShopNextOrderId", (string) ($orderId + 1));
    SMAttributes::Commit();
    // Also releases lock
    // Loop through order entries to extract currency, calculate
    // discounts/totals/VAT, and update entries with these information.
    foreach ($entries as $entry) {
        // Get product associated with entry
        $products = $pDs->Select("*", "Id = '" . $entry["ProductId"] . "'");
        if (count($products) === 0) {
            header("HTTP/1.1 500 Internal Server Error");
            echo "Product with ID '" . $entry["ProductId"] . "' has been removed";
            exit;
        }
        $product = $products[0];
        // Make sure all products are defined with the same currency and weight unit
        $currency = $currency !== null ? $currency : $product["Currency"];
        if ($currency !== $product["Currency"]) {
            header("HTTP/1.1 500 Internal Server Error");
            echo "Buying products with different currencies is not supported";
            exit;
        }
        $weightUnit = $weightUnit !== null ? $weightUnit : $product["WeightUnit"];
        if ($weightUnit !== $product["WeightUnit"]) {
            header("HTTP/1.1 500 Internal Server Error");
            echo "Buying products with different weight units is not supported";
            exit;
        }
        // Get discount expression
        $discount = 0;
        $discountExpression = $product["DiscountExpression"];
        if ($discountExpression !== "") {
            // Security validation
            //$discountExpression = preg_replace("/Math\\.[a-z]+/i", "", $discountExpression);
            $discountExpression = preg_replace("/ |[0-9]|\\*|\\+|\\-|\\/|=|&|\\||!|\\.|:|\\(|\\)|>|<|\\?|true|false/", "", $discountExpression);
            $discountExpression = preg_replace("/units|price|vat|currency|weight|weightunit/", "", $discountExpression);
            if ($discountExpression !== "") {
                header("HTTP/1.1 500 Internal Server Error");
                echo "Invalid and potentially insecure DiscountExpression detected";
                exit;
            }
            // Make variables available to discount expression
            $expr = "";
            $expr .= "\nunits = " . $entry["Units"] . ";";
            $expr .= "\nprice = " . $product["Price"] . ";";
            $expr .= "\nvat = " . $product["Vat"] . ";";
            $expr .= "\ncurrency = \"" . $product["Currency"] . "\";";
            $expr .= "\nweight = " . $product["Weight"] . ";";
            $expr .= "\nweightunit = \"" . $product["WeightUnit"] . "\";";
            $expr .= "\nreturn (" . $product["DiscountExpression"] . ");";
            // Turn JS variables into PHP compliant variables
            $expr = str_replace("units", "\$units", $expr);
            $expr = str_replace("price", "\$price", $expr);
            $expr = str_replace("vat", "\$vat", $expr);
            $expr = str_replace("currency", "\$currency", $expr);
            $expr = str_replace("weight", "\$weight", $expr);
            // $weight AND $weightunit (both starts with "weight")
            // Evaluate discount expression, and calculate price and VAT
            $discount = eval($expr);
            if (is_numeric($discount) === false) {
                header("HTTP/1.1 500 Internal Server Error");
                echo "DiscountExpression did not result in a valid numeric value";
                exit;
            }
        }
        // Totals
        $price = (int) $entry["Units"] * (double) $product["Price"] - $discount;
        $priceTotal += $price;
        $vatTotal += $price * ((double) $product["Vat"] / 100);
        $weightTotal += (int) $entry["Units"] * (double) $product["Weight"];
        // Update entry
        $entry["OrderId"] = (string) $orderId;
        $entry["UnitPrice"] = $product["Price"];
        $entry["Vat"] = $product["Vat"];
        $entry["Currency"] = $product["Currency"];
        $entry["Discount"] = (string) $discount;
        $entry["DiscountMessage"] = $discount !== 0 ? $product["DiscountMessage"] : "";
        $eDs->Update($entry, "Id = '" . $eDs->Escape($entry["Id"]) . "'");
    }
    $eDs->Commit();
    // Calculate shipping expense
    $shippingExpenseExpression = SMAttributes::GetAttribute("SMShopShippingExpenseExpression");
    $shippingExpenseVatPercentage = SMAttributes::GetAttribute("SMShopShippingExpenseVat");
    $shippingExpenseMessage = SMAttributes::GetAttribute("SMShopShippingExpenseMessage");
    if ($shippingExpenseExpression !== null && $shippingExpenseExpression !== "") {
        // Security validation
        $shippingExpenseExpression = preg_replace("/ |[0-9]|\\*|\\+|\\-|\\/|=|&|\\||!|\\.|:|\\(|\\)|>|<|\\?|true|false/", "", $shippingExpenseExpression);
        $shippingExpenseExpression = preg_replace("/price|vat|currency|weight|weightunit/", "", $shippingExpenseExpression);
        if ($shippingExpenseExpression !== "") {
            header("HTTP/1.1 500 Internal Server Error");
            echo "Invalid and potentially insecure ShippingExpenseExpression detected";
            exit;
        }
        // Make variables available to discount expression
        $expr = "";
        $expr .= "\nprice = " . $priceTotal . ";";
        $expr .= "\nvat = " . $vatTotal . ";";
        $expr .= "\ncurrency = \"" . $currency . "\";";
        $expr .= "\nweight = " . $weightTotal . ";";
        $expr .= "\nweightunit = \"" . $weightUnit . "\";";
        $expr .= "\nreturn (" . SMAttributes::GetAttribute("SMShopShippingExpenseExpression") . ");";
        // Turn JS variables into PHP compliant variables
        $expr = str_replace("price", "\$price", $expr);
        $expr = str_replace("vat", "\$vat", $expr);
        $expr = str_replace("currency", "\$currency", $expr);
        $expr = str_replace("weight", "\$weight", $expr);
        // $weight AND $weightunit (both starts with "weight")
        // Evaluate shipping expense expression
        $shippingExpense = eval($expr);
        if (is_numeric($shippingExpense) === false) {
            header("HTTP/1.1 500 Internal Server Error");
            echo "ShippingExpenseExpression did not result in a valid numeric value";
            exit;
        }
        $priceTotal += $shippingExpense;
        if ($shippingExpenseVatPercentage !== null && $shippingExpenseVatPercentage !== "") {
            $shippingVat = $shippingExpense * ((double) $shippingExpenseVatPercentage / 100);
            $vatTotal += $shippingVat;
        }
    }
    // Update order details
    $order["Id"] = (string) $orderId;
    $order["Price"] = (string) $priceTotal;
    $order["Vat"] = (string) $vatTotal;
    $order["Currency"] = $currency;
    $order["Weight"] = (string) $weightTotal;
    $order["WeightUnit"] = $weightUnit;
    $order["ShippingExpense"] = (string) $shippingExpense;
    $order["ShippingVat"] = (string) $shippingVat;
    $order["ShippingMessage"] = $shippingExpenseMessage !== null ? $shippingExpenseMessage : "";
    $order["TransactionId"] = "";
    $order["State"] = "Initial";
}