Skip to content

Commit 0ee0ddb

Browse files
committed
finish paypal integration
1 parent e214e04 commit 0ee0ddb

File tree

5 files changed

+185
-3
lines changed

5 files changed

+185
-3
lines changed

backend/listener.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
// STEP 1: read POST data
3+
// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
4+
// Instead, read raw POST data from the input stream.
5+
$raw_post_data = file_get_contents('php://input');
6+
$raw_post_array = explode('&', $raw_post_data);
7+
$myPost = array();
8+
foreach ($raw_post_array as $keyval) {
9+
$keyval = explode ('=', $keyval);
10+
if (count($keyval) == 2)
11+
$myPost[$keyval[0]] = urldecode($keyval[1]);
12+
}
13+
// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
14+
$req = 'cmd=_notify-validate';
15+
if (function_exists('get_magic_quotes_gpc')) {
16+
$get_magic_quotes_exists = true;
17+
}
18+
foreach ($myPost as $key => $value) {
19+
if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
20+
$value = urlencode(stripslashes($value));
21+
} else {
22+
$value = urlencode($value);
23+
}
24+
$req .= "&$key=$value";
25+
}
26+
27+
// Step 2: POST IPN data back to PayPal to validate
28+
$ch = curl_init('https://ipnpb.paypal.com/cgi-bin/webscr');
29+
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
30+
curl_setopt($ch, CURLOPT_POST, 1);
31+
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
32+
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
33+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
34+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
35+
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
36+
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
37+
// In wamp-like environments that do not come bundled with root authority certificates,
38+
// please download 'cacert.pem' from "https://curl.haxx.se/docs/caextract.html" and set
39+
// the directory path of the certificate as shown below:
40+
// curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
41+
if ( !($res = curl_exec($ch)) ) {
42+
// error_log("Got " . curl_error($ch) . " when processing IPN data");
43+
curl_close($ch);
44+
exit;
45+
}
46+
curl_close($ch);
47+
48+
49+
50+
// inspect IPN validation result and act accordingly
51+
if (strcmp ($res, "VERIFIED") == 0) {
52+
// The IPN is verified, process it:
53+
// check whether the payment_status is Completed
54+
// check that txn_id has not been previously processed
55+
// check that receiver_email is your Primary PayPal email
56+
// check that payment_amount/payment_currency are correct
57+
// process the notification
58+
// assign posted variables to local variables
59+
$item_name = $_POST['item_name'];
60+
$item_number = $_POST['item_number'];
61+
$payment_status = $_POST['payment_status'];
62+
$payment_amount = $_POST['mc_gross'];
63+
$payment_currency = $_POST['mc_currency'];
64+
$txn_id = $_POST['txn_id'];
65+
$receiver_email = $_POST['receiver_email'];
66+
$payer_email = $_POST['payer_email'];
67+
68+
order::completeSuccessfulOrder($item_number, $txn_id);
69+
70+
71+
72+
73+
} else if (strcmp ($res, "INVALID") == 0) {
74+
// IPN invalid, log for manual investigation
75+
echo "The response from IPN was: <b>" .$res ."</b>";
76+
77+
78+
79+
80+
81+
}
82+
83+
84+
85+
86+
87+
?>

backend/orders.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,78 @@ function imgConvert($blob){
1414
return 'data:image/jpeg;base64,'.base64_encode($blob);
1515
}
1616

17+
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
18+
19+
function getUrl($protocol){
20+
$url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
21+
return $url;
22+
}
23+
24+
/*
25+
getUrl()
26+
http://localhost/nft/public_html/orders?checkout=id?action=boolean
27+
28+
<?php echo "".getUrl()."?checkout=#?cancel=true"; ?>
29+
<?php echo "".getUrl()."?checkout=#?ipn_listener=paypal"; ?>
30+
<?php echo "".getUrl()."?checkout=#?success=true"; ?>
31+
*/
32+
33+
34+
//testmode enables sandbox
35+
$testmode = true;
36+
$paypalurl = $testmode ? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' : 'https://ipnpb.paypal.com/cgi-bin/webscr';
37+
$cancelurl = "".getUrl($protocol)."?checkout=#?cancel=true";
38+
$ipnurl = $protocol . $_SERVER['HTTP_HOST'] . "/nft/".$GLOBALS["url_loc"][0]."/listener";
39+
$successurl = "".getUrl($protocol)."?checkout=#?success=true";
40+
41+
42+
if(isset($_POST["placeorder"]) || isset($_POST["paypal"])){
43+
44+
$data = array(
45+
'cmd' => '_cart',
46+
'upload' => '1',
47+
'lc' => 'EN',
48+
'business' => 'payments@imperfectandcompany.com',
49+
'cancel_return' => ''.$cancelurl.'',
50+
'notify_url' => ''.$ipnurl.'',
51+
'currency_code' => 'USD',
52+
'return' => ''.$successurl.'',
53+
);
54+
55+
$cartOrders = Order::getOrderDetails($_POST["itemid"]);
56+
57+
for ($i = 0; $i < count($cartOrders); $i++) {
58+
//order_id
59+
$data['item_number_' . ($i+1)] = $cartOrders[$i]['o_id'];
60+
//item name
61+
$data['item_name_' . ($i+1)] = $cartOrders[$i]['i_name'];
62+
//current price
63+
$data['amount_' . ($i+1)] = $cartOrders[$i]['current_price'];
64+
}
65+
66+
header('location:' . $paypalurl . '?' . http_build_query($data));
67+
// End script
68+
exit;
69+
}
70+
71+
if($_SERVER['REQUEST_METHOD'] == "GET"){
72+
if (isset($_GET['ipn_listener']) && $_GET['ipn_listener'] == 'paypal') {
73+
// Get all input variables and convert them all to URL string variables
74+
$raw_data = file_get_contents('php://input');
75+
$raw_array = explode('&', $raw_data);
76+
$myPost = [];
77+
78+
79+
80+
81+
echo $myData;
82+
echo var_dump($myData);
83+
}
84+
}
85+
86+
87+
88+
1789
//if id is specified after operation as string is given
1890
if($GLOBALS['url_loc'][2]){
1991
try{

classes/class.order.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ public static function getUsersOrdersAsBuyer()
114114
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));
115115
}
116116

117+
public static function completeSuccessfulOrder($item_number, $txn_id)
118+
{
119+
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));
120+
}
121+
122+
//gets order id, price, and name of an item that the user is intending to buy
123+
public static function getOrderDetails($itemid)
124+
{
125+
$userid = User::isLoggedIn();
126+
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));
127+
}
117128
}
118129

119130
?>

config.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
$PAGE_TITLE = "Sign In";
5252
$FRONTEND = "signin";
5353
break;
54+
case "listener":
55+
$BACKEND = "listener";
56+
$PAGE_TITLE = "Sign In";
57+
$FRONTEND = "listener";
58+
break;
5459
case "orders":
5560
$BACKEND = "orders";
5661
$PAGE_TITLE = "Orders";

frontend/orders.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,16 @@ class="absolute inset-0 bg-<?php echo $result["o_status"]==="pending" ? "yellow"
9292
</td>
9393
<td class="px-5 py-5 text-center border-b border-gray-200 bg-white text-sm">
9494
<?php if($result["o_status"]==="pending"): ?>
95-
<a href="./orders/remove_from_cart/<?php echo $result["o_item_id"] ?>" class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Remove</a>
96-
<?php endif;?>
97-
<a href="./orders/remove_from_cart/<?php echo $result["o_item_id"] ?>" class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Checkout</a>
95+
<div><a href="./orders/remove_from_cart/<?php echo $result["o_item_id"]; ?>"><div class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Remove</div></a>
96+
</div>
97+
<div>
98+
<form method="post">
99+
<input name="placeorder" type="hidden"></input>
100+
<input name="itemid" type="hidden" value="<?php echo $result["o_item_id"]; ?>"></input>
101+
<button onclick="this.disabled=true;this.value='Sending, please wait...';this.form.submit();" class="bg-indigo-600 px-4 py-2 rounded-md text-white font-semibold tracking-wide cursor-pointer">Checkout</button>
102+
</form>
103+
</div>
104+
98105
<?php endif;?>
99106
</td>
100107
</tr>

0 commit comments

Comments
 (0)