17 require_once SQ_CORE_PACKAGE_PATH.
'/page/page.inc';
19 define(
'LOG_FILE_PREFIX',
'paypal_transactions');
20 define(
'FAIL_LOG_FILE', LOG_FILE_PREFIX.
'_failure');
44 parent::__construct($assetid);
58 $allowed_links = parent::_getAllowedLinks();
60 $allowed_links[SQ_LINK_NOTICE][
'asset'] = Array(
'card' =>
'M',
'exclusive' => FALSE);
62 return $allowed_links;
75 $payment_info = Array();
76 $payment_info[
'request_server'] =
"There is a {$_SERVER['REQUEST_METHOD']} Request from {$_SERVER['REMOTE_ADDR']}";
79 if ($_SERVER[
'REQUEST_METHOD'] ==
'POST') {
80 $payment_info[
'txn_type'] = array_get_index($_POST,
'txn_type',
'');
81 $payment_info[
'txn_id'] = array_get_index($_POST,
'txn_id',
'');
82 $payment_info[
'test_ipn'] = array_get_index($_POST,
'test_ipn',
'0');
83 $payment_info[
'payment_status'] = array_get_index($_POST,
'payment_status',
'');
84 $payment_info[
'payment_date'] = array_get_index($_POST,
'payment_date',
'');
87 if (empty($payment_info[
'txn_type']) || empty($payment_info[
'txn_id']) || empty($payment_info[
'payment_status'])) {
88 $payment_info[
'error'] =
'THERE IS NO TRANSACTION TYPE, TRANSACTION ID OR PAYMENT STATUS.';
89 $this->_returnPageNotFound($payment_info);
92 if ($payment_info[
'payment_status'] ==
'Pending') {
93 $payment_info[
'incomplete_reason'] = array_get_index($_POST,
'pending_reason',
'');
95 $payment_info[
'incomplete_reason'] = array_get_index($_POST,
'reason_code',
'');
98 $payment_info[
'custom'] = array_get_index($_POST,
'custom',
'');
100 if (empty($payment_info[
'custom'])) {
101 $payment_info[
'error'] =
'CUSTOM VARIABLE IS NOT SENT BACK FROM PAYPAL.';
102 $this->_returnPageNotFound($payment_info);
105 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'paypal_payment_button');
107 list($custom_hash, $button_id, $custom) = explode(Paypal_Payment_Button::$CUSTOM_PARAM_SPLIT_STR, $payment_info[
'custom']);
109 $payment_info[
'button_id'] = $button_id;
110 if (empty($button_id)) {
111 $payment_info[
'error'] =
'BUTTON ID IS NOT SPECIFIED.';
112 $this->_returnPageNotFound($payment_info);
115 $button = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($button_id);
117 $paypal_config_id = $button->attr(
'paypal_config_id');
118 if (empty($paypal_config_id)) {
119 $payment_info[
'error'] =
"PAYPAL CONFIGURATION IS NOT SPECIFIED FOR THE BUTTON #$button_id.";
120 $this->_returnPageNotFound($payment_info);
123 $paypal_config = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($paypal_config_id);
126 $custom_var = $button_id.Paypal_Payment_Button::$CUSTOM_PARAM_SPLIT_STR.$custom;
128 if (!empty($custom)) {
129 $custom = urldecode($custom);
132 $notify_url_query = array_get_index($_SERVER,
'QUERY_STRING',
'');
134 $payment_info[
'real_custom_var'] = $custom;
135 $payment_info[
'notify_url_query'] = $notify_url_query;
137 if ($custom_hash != md5($paypal_config->attr(
'custom_param_secret_str').$custom_var.$paypal_config->attr(
'custom_param_secret_str').$notify_url_query)) {
139 $payment_info[
'error'] =
'THE CHECKSUM OF CUSTOM VARIABLES AND NOTIFY URL QUERY STRING IS INVALID.';
140 $this->_returnPageNotFound($payment_info);
143 $paypal_account_id = $button->attr(
'paypal_account_id');
144 if (empty($paypal_account_id)) {
145 $payment_info[
'error'] =
"PAYPAL BUSINESS ACCOUNT IS NOT SPECIFIED FOR THE BUTTON #$button_id.";
146 $this->_returnPageNotFound($payment_info);
149 $paypal_account = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($paypal_account_id);
151 $payment_info[
'business'] = array_get_index($_POST,
'business',
'');
153 if ($payment_info[
'business'] != $paypal_account->attr(
'account_id')) {
154 $payment_info[
'error'] =
"THE PAYMENT'S MERCHANT ID ({$payment_info['business']}) DOES NOT MATCH THE MERCHANT ID ({$paypal_account->attr('account_id')}) OF THE PAYPAL ACCOUNT #$paypal_account_id.";
155 $this->_returnPageNotFound($payment_info);
161 $payment_info[
'mc_currency'] = array_get_index($_POST,
'mc_currency',
'');
162 $payment_info[
'mc_gross'] = array_get_index($_POST,
'mc_gross', 0);
163 if ($payment_info[
'txn_type'] ==
'cart') {
164 $payment_info[
'num_cart_items'] = array_get_index($_POST,
'num_cart_items', 0);
165 for ($i = 1; $i <= $payment_info[
'num_cart_items']; $i++) {
166 $payment_info[
'item_name'.$i] = array_get_index($_POST,
'item_name'.$i,
'');
167 $payment_info[
'item_number'.$i] = array_get_index($_POST,
'item_number'.$i,
'');
168 $payment_info[
'quantity'.$i] = array_get_index($_POST,
'quantity'.$i, 1);
169 $payment_info[
'mc_gross_'.$i] = array_get_index($_POST,
'mc_gross_'.$i, 0);
170 $payment_info[
'price_'.$i] = $payment_info[
'mc_gross_'.$i]/$payment_info[
'quantity'.$i];
173 $payment_info[
'item_name'] = array_get_index($_POST,
'item_name',
'');
174 $payment_info[
'item_number'] = array_get_index($_POST,
'item_number',
'');
175 $payment_info[
'quantity'] = array_get_index($_POST,
'quantity', 1);
176 $payment_info[
'price'] = $payment_info[
'mc_gross']/$payment_info[
'quantity'];
181 $custom_splits = explode(
',', $custom);
182 foreach ($custom_splits as $name_value) {
183 list($name, $value) = explode(
'=', $name_value);
184 $params[trim($name)] = trim($value);
188 foreach ($params as $key => $value) {
189 $_POST[$key] = $value;
194 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_NOTICE,
'', FALSE,
'target_asset');
196 $assetid = $link[
'minorid'];
199 if (empty($assetid)) {
201 $assetid = array_get_index($_POST, $this->
attr(
'assetid_param_name'),
'');
204 if (empty($assetid)) {
205 $payment_info[
'target_assetid'] =
"No target asset ID specified.";
207 $payment_info[
'target_assetid'] = $assetid;
208 $target_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
211 if ($payment_info[
'payment_status'] ==
'Completed') {
212 if (empty($target_asset)) {
213 $payment_info[
'ipn_event'] =
"No IPN Completed event is broadcasted because there is no asset with ID #$assetid.";
215 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_paypal_ipn_completed', $target_asset);
216 $payment_info[
'ipn_event'] =
"An IPN Completed event was broadcasted to the asset #$assetid.";
219 $payment_info[
'ipn_event'] =
"No IPN Completed event is broadcasted because payment status is {$payment_info['payment_status']}.";
223 $paypal_account->addPaypalOrder($payment_info, $message);
224 $payment_info[
'paypal_order'] = $message;
227 $this->_logIncomingRequestInfo(LOG_FILE_PREFIX.
'_account_'.$paypal_account_id, $payment_info);
231 $this->_returnPageNotFound($payment_info);
246 private function _returnPageNotFound($payment_info) {
247 $protocol = current_protocol();
248 $url = strip_url(current_url(FALSE, TRUE));
249 if (!headers_sent()) {
250 header(
'HTTP/1.0 404 Not Found');
254 $payment_info[
'status_code'] =
"A 404 status code was sent back to the client.";
255 $this->_logIncomingRequestInfo(FAIL_LOG_FILE, $payment_info);
257 trigger_localised_error(
'SYS0218', E_USER_NOTICE, $protocol.
'://'.$url);
273 private function _logIncomingRequestInfo($file_name, $payment_info) {
275 foreach ($payment_info as $name => $message) {
276 if ($message ==
'') {
277 $message =
'[Empty]';
279 $data .=
"$name=$message\n";
281 log_write($data, $file_name, E_USER_NOTICE, FALSE);