From e214e04a4f69a86cf984e6a1d5ccdfa0a17c9053 Mon Sep 17 00:00:00 2001 From: Daiyaan Ijaz <3193289+cheesea3@users.noreply.github.com> Date: Sat, 16 Apr 2022 20:01:32 -0400 Subject: [PATCH 1/2] Finished orders page and also fixed order flow / process --- backend/item.php | 4 +- backend/orders.php | 37 ++++++++++++++ classes/class.order.php | 69 +++++++++++++++----------- config.php | 5 ++ frontend/aside.php | 4 +- frontend/item.php | 2 +- frontend/orders.php | 107 ++++++++++++++++++++++++++++++++++++++++ loader.php | 6 +-- 8 files changed, 197 insertions(+), 37 deletions(-) create mode 100644 backend/orders.php create mode 100644 frontend/orders.php diff --git a/backend/item.php b/backend/item.php index 89011e4..10606c0 100644 --- a/backend/item.php +++ b/backend/item.php @@ -20,8 +20,8 @@ try{ switch($GLOBALS['url_loc'][3]){ - case $ADD_TO_CART: - $result = Order::addItemToCart($item_data['i_id'], $signed_in); + case "add_to_cart": + Order::addItemToCart($item_data['i_id'], $signed_in); break; case $REMOVE_FROM_CART: Order::removeItemFromCart($item_data['i_id'], $signed_in); diff --git a/backend/orders.php b/backend/orders.php new file mode 100644 index 0000000..cf77493 --- /dev/null +++ b/backend/orders.php @@ -0,0 +1,37 @@ +getMessage(); + } +} + + + + +?> \ No newline at end of file diff --git a/classes/class.order.php b/classes/class.order.php index 8e3711f..810ec0b 100644 --- a/classes/class.order.php +++ b/classes/class.order.php @@ -16,7 +16,7 @@ public static function isItemOpen($itemid) { //check to see if the item has an open order //also checks to see if a seller exists already - if (DatabaseConnector::query('SELECT o_id FROM orders WHERE o_item_id=:itemid AND o_status="open" AND o_seller_id IS NULL', array(':itemid'=>$itemid))) { + if (DatabaseConnector::query('SELECT o_id FROM orders WHERE o_item_id=:itemid AND o_status="open" AND o_buyer_id IS NULL', array(':itemid'=>$itemid))) { return true; } else { return false; @@ -39,7 +39,7 @@ public static function isItemPending($itemid) public static function isItemInUserCart($itemid, $userid) { //check to see if the item is already added to the users cart - if (DatabaseConnector::query('SELECT o_id FROM orders WHERE o_item_id=:itemid AND o_seller_id=:userid AND o_status="pending"', array(':itemid'=>$itemid, ':userid'=>$userid))) { + if (DatabaseConnector::query('SELECT o_id FROM orders WHERE o_item_id=:itemid AND o_buyer_id=:userid AND o_status="pending"', array(':itemid'=>$itemid, ':userid'=>$userid))) { return true; } else { return false; @@ -56,31 +56,29 @@ public static function isItemInUserCart($itemid, $userid) */ public static function addItemToCart($itemid, $userid) - { - //make sure item is open and available - if(self::isItemOpen($itemid)){ - //good! the item is open and without a seller id. - //lets make sure the user isn't adding an item that he already owns - if(self::isUsersListing($itemid, $userid) == false){ - - //since the user doesn't own the item we can proceed! - if(self::isItemInUserCart($itemid, $userid)== false){ - - //since item isn't in the user cart we can proceed - //looks like the item is ready to add into the cart... - //lets add a seller id to the order! - DatabaseConnector::query('UPDATE orders SET o_seller_id=:sellerid, o_status="pending" WHERE o_item_id=:itemid AND o_status="open" AND o_seller_id IS NULL', array(':sellerid'=>$userid, ':itemid'=>$itemid)); - } - else { - return false; - } - } else { - return false; - } - } else { - return false; - } - } + { + //make sure item is open and available + if(self::isItemOpen($itemid)){ + //good! the item is open and without a seller id. + //lets make sure the user isn't adding an item that he already owns + if(self::isUsersListing($itemid, $userid) == false){ + //since the user doesn't own the item we can proceed! + if(self::isItemInUserCart($itemid, $userid)== false){ + //since item isn't in the user cart we can proceed + //looks like the item is ready to add into the cart... + //lets add a seller id to the order! + DatabaseConnector::query('UPDATE orders SET o_buyer_id=:buyerid, o_status="pending" WHERE o_item_id=:itemid AND o_status="open" AND o_buyer_id IS NULL AND o_seller_id IS NOT NULL', array(':itemid'=>$itemid, ':buyerid'=>$userid)); + } + else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } public static function removeItemFromCart($itemid, $userid) { @@ -91,8 +89,8 @@ public static function removeItemFromCart($itemid, $userid) if(self::isItemInUserCart($itemid, $userid)== true){ //since item isn't in the user cart we can proceed //looks like the item is ready to add into the cart... - //lets remove the seller_id from theo rder! - DatabaseConnector::query('UPDATE orders SET o_seller_id=NULL, o_status=NULL WHERE o_item_id=:itemid AND o_status="pending" AND o_seller_id=:sellerid', array(':itemid'=>$itemid, ':sellerid'=>$userid)); + //lets remove the seller_id from the order! + DatabaseConnector::query('UPDATE orders SET o_buyer_id=NULL, o_status="open" WHERE o_item_id=:itemid AND o_status="pending" AND o_buyer_id=:buyerid', array(':itemid'=>$itemid, ':buyerid'=>$userid)); } } } @@ -102,7 +100,20 @@ public static function getUsersOrdersCount() { $userid = User::isLoggedIn(); return DatabaseConnector::query('SELECT COUNT(*) FROM orders WHERE o_seller_id=:userid OR o_buyer_id=:userid', array(':userid'=>$userid))[0]['COUNT(*)']; + } + + public static function getUsersOrdersAsSeller() + { + $userid = User::isLoggedIn(); + return DatabaseConnector::query('SELECT * FROM orders WHERE o_seller_id=:userid', array(':userid'=>$userid))[0]['COUNT(*)']; + } + + public static function getUsersOrdersAsBuyer() + { + $userid = User::isLoggedIn(); + return DatabaseConnector::query('SELECT o_id, o_item_id, o_seller_id, o_status, i_name, i_image FROM orders o JOIN item as i on o_item_id=i_id WHERE o_buyer_id=:userid', array(':userid'=>$userid)); } + } ?> \ No newline at end of file diff --git a/config.php b/config.php index 59e69a1..a6d0996 100644 --- a/config.php +++ b/config.php @@ -51,6 +51,11 @@ $PAGE_TITLE = "Sign In"; $FRONTEND = "signin"; break; + case "orders": + $BACKEND = "orders"; + $PAGE_TITLE = "Orders"; + $FRONTEND = "orders"; + break; default: $BACKEND = "index"; $PAGE_TITLE = "Index"; diff --git a/frontend/aside.php b/frontend/aside.php index 9f73faf..c02b8a7 100644 --- a/frontend/aside.php +++ b/frontend/aside.php @@ -136,8 +136,8 @@ class="h-6 w-6"
  • - /orders" class=""> diff --git a/frontend/item.php b/frontend/item.php index e76869a..5dbff87 100644 --- a/frontend/item.php +++ b/frontend/item.php @@ -67,7 +67,7 @@ } else { //make sure item isn't currently pending (in an offer).. if(!$is_item_pending){ - if($is_item_open){ + if(Order::isItemOpen($item_data['i_id'])){ //add item button drawAddToCartButton($item_data['i_id'], $BLUE_BUTTON, $ADD_TO_CART); } else { diff --git a/frontend/orders.php b/frontend/orders.php new file mode 100644 index 0000000..a5f9b05 --- /dev/null +++ b/frontend/orders.php @@ -0,0 +1,107 @@ + +
    + +
    +

    Your items

    + As a buyer +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    + Item + + Seller + + Price + + Status + + Action +
    + /item/"> +
    + +
    + " + alt="" /> +
    +
    +

    + +

    +
    +
    +
    +
    +

    +
    +

    + +

    +
    + -900 leading-tight"> + -200 opacity-50 rounded-full"> + + + + + " class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Remove + + " class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Checkout + +
    +
    +
    +
    + +
    \ No newline at end of file diff --git a/loader.php b/loader.php index 6d92257..d8f07c6 100644 --- a/loader.php +++ b/loader.php @@ -3,8 +3,8 @@ //This is how we get what page we should be on based on URL. $GLOBALS['url_loc'] = explode('/', htmlspecialchars(strtok($_SERVER['REQUEST_URI'], '?'), ENT_QUOTES)); -$GLOBALS['config']['url_offset'] = 1; -$GLOBALS['config']['url_root'] = ""; +$GLOBALS['config']['url_offset'] = 2; +$GLOBALS['config']['url_root'] = "/nft"; $GLOBALS['devmode'] = 1; @@ -15,7 +15,7 @@ $GLOBALS['db_conf']['db_pass'] = "oakland"; $GLOBALS['db_conf']['db_charset'] = "utf8"; -if($GLOBALS['config']['url_offset'] > 0){ +if($GLOBALS['config']['url_offset'] > 0) { $x = 0; while($x < ($GLOBALS['config']['url_offset'])){ unset($GLOBALS['url_loc'][$x]); $x++; } $GLOBALS['url_loc'] = array_values($GLOBALS['url_loc']); } From 0ee0ddb20ed8964af3965eef1303e8eb6a00d310 Mon Sep 17 00:00:00 2001 From: Daiyaan Ijaz <3193289+cheesea3@users.noreply.github.com> Date: Sun, 17 Apr 2022 10:10:24 -0400 Subject: [PATCH 2/2] finish paypal integration --- backend/listener.php | 87 +++++++++++++++++++++++++++++++++++++++++ backend/orders.php | 72 ++++++++++++++++++++++++++++++++++ classes/class.order.php | 11 ++++++ config.php | 5 +++ frontend/orders.php | 13 ++++-- 5 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 backend/listener.php diff --git a/backend/listener.php b/backend/listener.php new file mode 100644 index 0000000..6aac797 --- /dev/null +++ b/backend/listener.php @@ -0,0 +1,87 @@ + $value) { + if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { + $value = urlencode(stripslashes($value)); + } else { + $value = urlencode($value); + } + $req .= "&$key=$value"; +} + +// Step 2: POST IPN data back to PayPal to validate +$ch = curl_init('https://ipnpb.paypal.com/cgi-bin/webscr'); +curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); +curl_setopt($ch, CURLOPT_POST, 1); +curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); +curl_setopt($ch, CURLOPT_POSTFIELDS, $req); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); +curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); +curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); +curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); +// In wamp-like environments that do not come bundled with root authority certificates, +// please download 'cacert.pem' from "https://curl.haxx.se/docs/caextract.html" and set +// the directory path of the certificate as shown below: +// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); +if ( !($res = curl_exec($ch)) ) { + // error_log("Got " . curl_error($ch) . " when processing IPN data"); + curl_close($ch); + exit; +} +curl_close($ch); + + + +// inspect IPN validation result and act accordingly +if (strcmp ($res, "VERIFIED") == 0) { + // The IPN is verified, process it: + // check whether the payment_status is Completed + // check that txn_id has not been previously processed + // check that receiver_email is your Primary PayPal email + // check that payment_amount/payment_currency are correct + // process the notification + // assign posted variables to local variables + $item_name = $_POST['item_name']; + $item_number = $_POST['item_number']; + $payment_status = $_POST['payment_status']; + $payment_amount = $_POST['mc_gross']; + $payment_currency = $_POST['mc_currency']; + $txn_id = $_POST['txn_id']; + $receiver_email = $_POST['receiver_email']; + $payer_email = $_POST['payer_email']; + + order::completeSuccessfulOrder($item_number, $txn_id); + + + + +} else if (strcmp ($res, "INVALID") == 0) { + // IPN invalid, log for manual investigation + echo "The response from IPN was: " .$res .""; + + + + + +} + + + + + +?> \ No newline at end of file diff --git a/backend/orders.php b/backend/orders.php index cf77493..dc372b4 100644 --- a/backend/orders.php +++ b/backend/orders.php @@ -14,6 +14,78 @@ function imgConvert($blob){ return 'data:image/jpeg;base64,'.base64_encode($blob); } +$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; + +function getUrl($protocol){ +$url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; +return $url; +} + +/* +getUrl() +http://localhost/nft/public_html/orders?checkout=id?action=boolean + + + + +*/ + + +//testmode enables sandbox +$testmode = true; +$paypalurl = $testmode ? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' : 'https://ipnpb.paypal.com/cgi-bin/webscr'; +$cancelurl = "".getUrl($protocol)."?checkout=#?cancel=true"; +$ipnurl = $protocol . $_SERVER['HTTP_HOST'] . "/nft/".$GLOBALS["url_loc"][0]."/listener"; +$successurl = "".getUrl($protocol)."?checkout=#?success=true"; + + +if(isset($_POST["placeorder"]) || isset($_POST["paypal"])){ + + $data = array( + 'cmd' => '_cart', + 'upload' => '1', + 'lc' => 'EN', + 'business' => 'payments@imperfectandcompany.com', + 'cancel_return' => ''.$cancelurl.'', + 'notify_url' => ''.$ipnurl.'', + 'currency_code' => 'USD', + 'return' => ''.$successurl.'', + ); + + $cartOrders = Order::getOrderDetails($_POST["itemid"]); + + for ($i = 0; $i < count($cartOrders); $i++) { + //order_id + $data['item_number_' . ($i+1)] = $cartOrders[$i]['o_id']; + //item name + $data['item_name_' . ($i+1)] = $cartOrders[$i]['i_name']; + //current price + $data['amount_' . ($i+1)] = $cartOrders[$i]['current_price']; + } + + header('location:' . $paypalurl . '?' . http_build_query($data)); + // End script + exit; + } + +if($_SERVER['REQUEST_METHOD'] == "GET"){ + if (isset($_GET['ipn_listener']) && $_GET['ipn_listener'] == 'paypal') { + // Get all input variables and convert them all to URL string variables + $raw_data = file_get_contents('php://input'); + $raw_array = explode('&', $raw_data); + $myPost = []; + + + + +echo $myData; +echo var_dump($myData); + } +} + + + + //if id is specified after operation as string is given if($GLOBALS['url_loc'][2]){ try{ diff --git a/classes/class.order.php b/classes/class.order.php index 810ec0b..03576f1 100644 --- a/classes/class.order.php +++ b/classes/class.order.php @@ -114,6 +114,17 @@ public static function getUsersOrdersAsBuyer() return DatabaseConnector::query('SELECT o_id, o_item_id, o_seller_id, o_status, i_name, i_image FROM orders o JOIN item as i on o_item_id=i_id WHERE o_buyer_id=:userid', array(':userid'=>$userid)); } + public static function completeSuccessfulOrder($item_number, $txn_id) + { + DatabaseConnector::query('UPDATE orders SET o_transaction_id=:taxid, o_status="fulfilled" WHERE o_id=:orderid AND o_status="pending" AND o_buyer_id IS NOT NULL AND o_seller_id IS NOT NULL', array(':orderid'=>$item_number, ':taxid'=>$txn_id)); + } + + //gets order id, price, and name of an item that the user is intending to buy + public static function getOrderDetails($itemid) + { + $userid = User::isLoggedIn(); + return DatabaseConnector::query('SELECT o_id, current_price, i_name FROM orders o JOIN item as i on o_item_id=i_id WHERE o_buyer_id=:userid and o_item_id=:itemid', array(':itemid'=>$itemid, ':userid'=>$userid)); + } } ?> \ No newline at end of file diff --git a/config.php b/config.php index a6d0996..d5c386d 100644 --- a/config.php +++ b/config.php @@ -51,6 +51,11 @@ $PAGE_TITLE = "Sign In"; $FRONTEND = "signin"; break; + case "listener": + $BACKEND = "listener"; + $PAGE_TITLE = "Sign In"; + $FRONTEND = "listener"; + break; case "orders": $BACKEND = "orders"; $PAGE_TITLE = "Orders"; diff --git a/frontend/orders.php b/frontend/orders.php index a5f9b05..7786dd1 100644 --- a/frontend/orders.php +++ b/frontend/orders.php @@ -92,9 +92,16 @@ class="absolute inset-0 bg- -
    " class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Remove - - " class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Checkout +
    ">
    Remove
    +
    +
    +
    + + "> + +
    +
    +