OpenCart 🇺🇦

Схема

public mixed ipn ( )

Аргументы

Аргумент Возможный тип Описание
У метода нет аргументов

Описание

Метод пока еще не документирован.

Исходный код

$this->load->model('payment/pp_express');
$this->load->model('account/recurring');

$request = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
	$request .= '&' . $key . '=' . urlencode(stripslashes($value));
}

if ($this->config->get('pp_express_test') == 1) {
	$curl = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
} else {
	$curl = curl_init('https://www.paypal.com/cgi-bin/webscr');
}

curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

$response = trim(curl_exec($curl));

if (!$response) {
	$this->model_payment_pp_express->log(array('error' => curl_error($curl),'error_no' => curl_errno($curl)), 'Curl failed');
}

$this->model_payment_pp_express->log(array('request' => $request,'response' => $response), 'IPN data');

if ( (string)$response == "VERIFIED" )  {
	if($this->config->get('pp_express_debug') == 1) {
		$this->log->write((isset($this->request->post['transaction_entity']) ? $this->request->post['transaction_entity'] : ''));
	}

	if(isset($this->request->post['txn_id'])) {
		$transaction = $this->model_payment_pp_express->getTransactionRow($this->request->post['txn_id']);
	} else {
		$transaction = false;
	}

	if(isset($this->request->post['parent_txn_id'])) {
		$parent_transaction = $this->model_payment_pp_express->getTransactionRow($this->request->post['parent_txn_id']);
	} else {
		$parent_transaction = false;
	}

	if($transaction) {
		//transaction exists, check for cleared payment or updates etc
		if($this->config->get('pp_express_debug') == 1) {
			$this->log->write('Transaction exists');
		}

		//if the transaction is pending but the new status is completed
		if($transaction['payment_status'] != $this->request->post['payment_status']) {
			$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = '" . $this->request->post['payment_status'] . "' WHERE `transaction_id` = '" . $this->db->escape($transaction['transaction_id']) . "' LIMIT 1");


		}elseif($transaction['payment_status'] == 'Pending' && ($transaction['pending_reason'] != $this->request->post['pending_reason'])) {
			//payment is still pending but the pending reason has changed, update it.
			$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `pending_reason` = '" . $this->request->post['pending_reason'] . "' WHERE `transaction_id` = '" . $this->db->escape($transaction['transaction_id']) . "' LIMIT 1");
		}
	} else {
		if($this->config->get('pp_express_debug') == 1) {
			$this->log->write('Transaction does not exist');
		}

		if($parent_transaction) {
			//parent transaction exists
			if($this->config->get('pp_express_debug') == 1) {
				$this->log->write('Parent transaction exists');
			}

			//insert new related transaction
			$transaction = array(
				'paypal_order_id' => $parent_transaction['paypal_order_id'],
				'transaction_id' => $this->request->post['txn_id'],
				'parent_transaction_id' => $this->request->post['parent_txn_id'],
				'note' => '',
				'msgsubid' => '',
				'receipt_id' => (isset($this->request->post['receipt_id']) ? $this->request->post['receipt_id'] : ''),
				'payment_type' => (isset($this->request->post['payment_type']) ? $this->request->post['payment_type'] : ''),
				'payment_status' => (isset($this->request->post['payment_status']) ? $this->request->post['payment_status'] : ''),
				'pending_reason' => (isset($this->request->post['pending_reason']) ? $this->request->post['pending_reason'] : ''),
				'amount' => $this->request->post['mc_gross'],
				'debug_data' => json_encode($this->request->post),
				'transaction_entity' => (isset($this->request->post['transaction_entity']) ? $this->request->post['transaction_entity'] : ''),
			);

			$this->model_payment_pp_express->addTransaction($transaction);

			/**
			 * If there has been a refund, log this against the parent transaction.
			 */
			if(isset($this->request->post['payment_status']) && $this->request->post['payment_status'] == 'Refunded') {
				if(($this->request->post['mc_gross'] * -1) == $parent_transaction['amount']) {
					$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = 'Refunded' WHERE `transaction_id` = '" . $this->db->escape($parent_transaction['transaction_id']) . "' LIMIT 1");
				} else {
					$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = 'Partially-Refunded' WHERE `transaction_id` = '" . $this->db->escape($parent_transaction['transaction_id']) . "' LIMIT 1");
				}
			}

			/**
			 * If the capture payment is now complete
			 */
			if(isset($this->request->post['auth_status']) && $this->request->post['auth_status'] == 'Completed' && $parent_transaction['payment_status'] == 'Pending') {
				$captured = number_format($this->model_payment_pp_express->totalCaptured($parent_transaction['paypal_order_id']), 2);
				$refunded = number_format($this->model_payment_pp_express->totalRefundedOrder($parent_transaction['paypal_order_id']), 2);
				$remaining = number_format($parent_transaction['amount'] - $captured + $refunded, 2);

				if($this->config->get('pp_express_debug') == 1) {
					$this->log->write('Captured: '.$captured);
					$this->log->write('Refunded: '.$refunded);
					$this->log->write('Remaining: '.$remaining);
				}

				if($remaining > 0.00) {
					$transaction = array(
						'paypal_order_id' => $parent_transaction['paypal_order_id'],
						'transaction_id' => '',
						'parent_transaction_id' => $this->request->post['parent_txn_id'],
						'note' => '',
						'msgsubid' => '',
						'receipt_id' => '',
						'payment_type' => '',
						'payment_status' => 'Void',
						'pending_reason' => '',
						'amount' => '',
						'debug_data' => 'Voided after capture',
						'transaction_entity' => 'auth'
					);

					$this->model_payment_pp_express->addTransaction($transaction);
				}

				$this->model_payment_pp_express->updateOrder('Complete', $parent_transaction['order_id']);
			}

		} else {
			//parent transaction doesn't exists, need to investigate?
			if($this->config->get('pp_express_debug') == 1) {
				$this->log->write('Parent transaction not found');
			}
		}
	}

	/*
	 * Subscription payments
	 *
	 * profile ID should always exist if its a recurring payment transaction.
	 *
	 * also the reference will match a recurring payment ID
	 */
	if (isset($this->request->post['txn_type'])) {
		//payment
		if ($this->request->post['txn_type'] == 'recurring_payment') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `amount` = '" . (float)$this->request->post['amount'] . "', `type` = '1'");

				//as there was a payment the profile is active, ensure it is set to active (may be been suspended before)
				if ($profile['status'] != 1) {
					$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "'");
				}
			}
		}

		//suspend
		if ($this->request->post['txn_type'] == 'recurring_payment_suspended') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '6'");
				$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 3 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "' LIMIT 1");
			}
		}

		//suspend due to max failed
		if ($this->request->post['txn_type'] == 'recurring_payment_suspended_due_to_max_failed_payment') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '7'");
				$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 3 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "' LIMIT 1");
			}
		}

		//payment failed
		if ($this->request->post['txn_type'] == 'recurring_payment_failed') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '4'");
			}
		}

		//outstanding payment failed
		if ($this->request->post['txn_type'] == 'recurring_payment_outstanding_payment_failed') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '8'");
			}
		}

		//outstanding payment
		if ($this->request->post['txn_type'] == 'recurring_payment_outstanding_payment') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `amount` = '" . (float)$this->request->post['amount'] . "', `type` = '2'");

				//as there was a payment the profile is active, ensure it is set to active (may be been suspended before)
				if ($profile['status'] != 1) {
					$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "'");
				}
			}
		}

		//created
		if ($this->request->post['txn_type'] == 'recurring_payment_profile_created') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '0'");

				if ($profile['status'] != 1) {
					$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "'");
				}
			}
		}

		//cancelled
		if ($this->request->post['txn_type'] == 'recurring_payment_profile_cancel') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false && $profile['status'] != 3) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '5'");
				$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 4 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "' LIMIT 1");
			}
		}

		//skipped
		if ($this->request->post['txn_type'] == 'recurring_payment_skipped') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '3'");
			}
		}

		//expired
		if ($this->request->post['txn_type'] == 'recurring_payment_expired') {
			$profile = $this->model_account_recurring->getProfileByRef($this->request->post['recurring_payment_id']);

			if ($profile != false) {
				$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "', `created` = NOW(), `type` = '9'");
				$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 5 WHERE `order_recurring_id` = '" . (int)$profile['order_recurring_id'] . "' LIMIT 1");
			}
		}
	}
}elseif( (string)$response == "INVALID" ) {
	$this->model_payment_pp_express->log(array('IPN was invalid'), 'IPN fail');
} else {
	if($this->config->get('pp_express_debug') == 1) {
		$this->log->write('string unknown ');
	}
}

header("HTTP/1.1 200 Ok");