diff --git a/pagseguro_ipn.php b/pagseguro_ipn.php
new file mode 100644
index 0000000..25eb8c5
--- /dev/null
+++ b/pagseguro_ipn.php
@@ -0,0 +1,112 @@
+<?php
+	// Require the functions to fetch config values
+	require 'config.php';
+
+	$pagseguro = $config['pagseguro'];
+	$notificationCode = $_POST['notificationCode'];
+	$notificationType = $_POST['notificationType'];
+
+	// Require the functions to connect to database
+	require 'engine/database/connect.php';
+
+	// Fetch and sanitize POST and GET values
+	function getValue($value) {
+		return (!empty($value)) ? sanitize($value) : false;
+	}
+	function sanitize($data) {
+		return htmlentities(strip_tags(mysql_znote_escape_string($data)));
+	}
+
+	// Util function to insert log
+	function report($code, $details = '') {
+		$connectedIp = $_SERVER['REMOTE_ADDR'];
+		$details = getValue($details);
+		$details .= '\nConnection from IP: '. $connectedIp;
+		mysql_insert('INSERT INTO `znote_pagseguro_notifications` VALUES (null, \'' . getValue($code) . '\', \'' . $details . '\', CURRENT_TIMESTAMP)');
+	}
+
+	function VerifyPagseguroIPN($code) {
+		global $pagseguro;
+		$url = $pagseguro['urls']['ws'];
+
+		$cURL = curl_init();
+		curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, false);
+		curl_setopt($cURL, CURLOPT_SSL_VERIFYHOST, false);
+		curl_setopt($cURL, CURLOPT_URL, 'https://' . $url . '/v3/transactions/notifications/' . $code . '?email=' . $pagseguro['email'] . '&token=' . $pagseguro['token']);
+		curl_setopt($cURL, CURLOPT_HEADER, false);
+		curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($cURL, CURLOPT_FORBID_REUSE, true);
+		curl_setopt($cURL, CURLOPT_FRESH_CONNECT, true);
+		curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT, 30);
+		curl_setopt($cURL, CURLOPT_TIMEOUT, 60);
+		curl_setopt($cURL, CURLINFO_HEADER_OUT, true);
+		curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
+			'Connection: close',
+			'Expect: ',
+		));
+		$Response = curl_exec($cURL);
+		$Status = (int)curl_getinfo($cURL, CURLINFO_HTTP_CODE);
+		curl_close($cURL);
+
+		$output = print_r($Response, true);
+		if(empty($Response) OR !$Status){
+			return null;
+		}
+		if(intval($Status / 100) != 2){
+			return false;
+		}
+		return trim($Response);
+	}
+
+	// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
+	header('HTTP/1.1 200 OK');
+
+	if(empty($notificationCode) || empty($notificationType)){
+		report($notificationCode, 'notificationCode or notificationType is empty. Type: ' . $notificationType . ', Code: ' . $notificationCode);
+		exit();
+	}
+
+	if ($notificationType !== 'transaction') {
+		report($notificationCode, 'Unknown ' . $notificationType . ' notificationType');
+		exit();
+	}
+
+	$rawPayment = VerifyPagseguroIPN($notificationCode);
+	$payment = simplexml_load_string($rawPayment);
+
+	report($notificationCode, $rawPayment);
+
+	// Updating Payment Status
+	mysql_update('UPDATE `znote_pagseguro` SET `payment_status` = ' . ($payment->status) . ' WHERE `transaction` = \'' . $payment->code . '\' ');
+
+	// Check that the payment_status is Completed
+	if ($payment->status == 3) {
+
+		// Check that transaction has not been previously processed
+		$transaction = mysql_select_single('SELECT `transaction`, `completed` FROM `znote_pagseguro` WHERE `transaction`= \'' . $payment->code .'\'');
+		$status = true;
+		$custom = (int) $payment->reference;
+
+		if ($transaction['completed'] == '1') {
+			$status = false;
+		}
+
+		if ($payment->grossAmount == 0.0) $status = false; // Wrong ammount of money
+		$item = $payment->items->item[0];
+		if ($item->amount != ($pagseguro['price'] / 100)) $status = false;
+
+		if ($status) {
+			// transaction log
+			mysql_update('UPDATE `znote_pagseguro` SET `completed` = 1 WHERE `transaction` = \'' . $payment->code . '\'');
+
+			// Process payment
+			$data = mysql_select_single("SELECT `points` AS `old_points` FROM `znote_accounts` WHERE `account_id`='$custom';");
+
+			// Give points to user
+			$new_points = $data['old_points'] + $item->quantity;
+			mysql_update("UPDATE `znote_accounts` SET `points`='$new_points' WHERE `account_id`='$custom'");
+		}
+	} else if ($payment->status == 7) {
+		mysql_update('UPDATE `znote_pagseguro` SET `completed` = 1 WHERE `transaction` = \'' . $payment->code . '\' ');
+	}
+?>
\ No newline at end of file
diff --git a/pagseguro_retorno.php b/pagseguro_retorno.php
new file mode 100644
index 0000000..8b486bb
--- /dev/null
+++ b/pagseguro_retorno.php
@@ -0,0 +1,107 @@
+<?php
+	/*
+		Instalação
+			- Configurando Pagseguro (Acessar https://pagseguro.uol.com.br/preferencias/integracoes.jhtml)
+				- Notificação de Transação:
+					- http://you-site/pagseguro_ipn.php
+				- Página de redirecionamento:
+					- A. Página fixa de redirecionamento
+						- http://you-site/znote/pagseguro_retorno.php
+					- B. Redirecionamento com o código da transação
+						- transaction
+				- Gerar o Token e copiar para a próxima etapa
+
+			- Configurando ZnoteACC
+				- config.php
+					- $config['pagseguro']['email']
+						- Seu email da conta do pagseguro que irá receber o pagamento
+					- $config['pagseguro']['token']
+						- Preencher com o Token que pedi pra copiar na primeira etapa
+					- $config['pagseguro']['product_name']
+						- Nome do Produto
+
+			- Instalando Tabelas
+				CREATE TABLE IF NOT EXISTS `znote_pagseguro` (
+				  `id` int(11) NOT NULL AUTO_INCREMENT,
+				  `transaction` varchar(36) NOT NULL,
+				  `account` int(11) NOT NULL,
+				  `price` decimal(11,2) NOT NULL,
+				  `points` int(11) NOT NULL,
+				  `payment_status` tinyint(1) NOT NULL,
+				  `completed` tinyint(4) NOT NULL,
+				  PRIMARY KEY (`id`),
+				  FOREIGN KEY (account) REFERENCES accounts(id)
+				) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+				CREATE TABLE IF NOT EXISTS `znote_pagseguro_notifications` (
+				  `id` int(11) NOT NULL AUTO_INCREMENT,
+				  `notification_code` varchar(40) NOT NULL,
+				  `details` text NOT NULL,
+				  `receive_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+				  PRIMARY KEY (`id`),
+				) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+	*/
+
+	// Require the functions to fetch config values
+	require 'config.php';
+
+	// Require the functions to connect to database
+	require 'engine/database/connect.php';
+
+	$pagseguro = $config['pagseguro'];
+
+	// Fetch and sanitize POST and GET values
+	function getValue($value) {
+		return (!empty($value)) ? sanitize($value) : false;
+	}
+	function sanitize($data) {
+		return htmlentities(strip_tags(mysql_znote_escape_string($data)));
+	}
+
+	// Util function to insert log
+	function report($code, $details = '') {
+		$connectedIp = $_SERVER['REMOTE_ADDR'];
+		$details = getValue($details);
+		$details .= '\nConnection from IP: '. $connectedIp;
+		mysql_insert('INSERT INTO `znote_pagseguro_notifications` VALUES (null, \'' . getValue($code) . '\', \'' . $details . '\', CURRENT_TIMESTAMP)');
+	}
+
+	function VerifyPagseguroIPN($code) {
+		global $pagseguro;
+		$url = $pagseguro['urls']['ws'];
+
+		$cURL = curl_init();
+		curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, false);
+		curl_setopt($cURL, CURLOPT_SSL_VERIFYHOST, false);
+		curl_setopt($cURL, CURLOPT_URL, 'https://' . $url . '/v3/transactions/' . $code . '?email=' . $pagseguro['email'] . '&token=' . $pagseguro['token']);
+		curl_setopt($cURL, CURLOPT_HEADER, false);
+		curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($cURL, CURLOPT_FORBID_REUSE, true);
+		curl_setopt($cURL, CURLOPT_FRESH_CONNECT, true);
+		curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT, 30);
+		curl_setopt($cURL, CURLOPT_TIMEOUT, 60);
+		curl_setopt($cURL, CURLINFO_HEADER_OUT, true);
+		curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
+			'Connection: close',
+			'Expect: ',
+		));
+		$Response = curl_exec($cURL);
+		$Status = (int)curl_getinfo($cURL, CURLINFO_HTTP_CODE);
+		curl_close($cURL);
+
+		return trim($Response);
+	}
+
+	$transactionCode = getValue($_GET['transaction']);
+	$rawTransaction = VerifyPagseguroIPN($transactionCode);
+	$transaction = simplexml_load_string($rawTransaction);
+
+	$completed = ($transaction->status != 7) ? 0 : 1;
+
+	$custom = (int) $transaction->reference;
+	$item = $transaction->items->item[0];
+	$points = $item->quantity;
+	$price = $item->quantity * ($pagseguro['price'] / 100);
+	mysql_insert('INSERT INTO `znote_pagseguro` VALUES (null, \'' . $transaction->code . '\', ' . $custom . ', \'' . $price . '\', \'' . $points . '\', ' . $transaction->status . ', ' . $completed . ')');
+
+	header('Location: shop.php?callback=processing');
diff --git a/shop.php b/shop.php
index e002428..402f803 100644
--- a/shop.php
+++ b/shop.php
@@ -2,6 +2,10 @@
 protect_page();
 include 'layout/overall/header.php'; 
 
+if (isset($_GET['callback']) && $_GET['callback'] === 'processing') {
+	echo '<script>alert("Seu pagamento está sendo processado pelo PagSeguro...");</script>';
+}
+
 // Import from config:
 $shop = $config['shop'];
 $shop_list = $config['shop_offers'];