📄 paypal_functions.php
字号:
<?php
/**
* functions used by payment module class for Paypal IPN payment method
*
* @package paymentMethod
* @copyright Copyright 2003-2007 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @copyright Portions Copyright 2004 DevosC.com
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: paypal_functions.php 7195 2007-10-06 14:29:44Z drbyte $
*/
// Functions for paypal processing
function datetime_to_sql_format($paypalDateTime) {
//Copyright (c) 2004 DevosC.com
$months = array('Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08', 'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12');
$hour = substr($paypalDateTime, 0, 2);$minute = substr($paypalDateTime, 3, 2);$second = substr($paypalDateTime, 6, 2);
$month = $months[substr($paypalDateTime, 9, 3)];
$day = (strlen($day = preg_replace("/,/" , '' , substr($paypalDateTime, 13, 2))) < 2) ? '0'.$day: $day;
$year = substr($paypalDateTime, -8, 4);
if (strlen($day)<2) $day = '0'.$day;
return ($year . "-" . $month . "-" . $day . " " . $hour . ":" . $minute . ":" . $second);
}
function ipn_debug_email($message, $email_address = '', $always_send = false, $subjecttext = 'IPN DEBUG message') {
static $paypal_error_counter;
static $paypal_instance_id;
if ($email_address == '') $email_address = (defined('MODULE_PAYMENT_PAYPAL_DEBUG_EMAIL_ADDRESS') ? MODULE_PAYMENT_PAYPAL_DEBUG_EMAIL_ADDRESS : STORE_OWNER_EMAIL_ADDRESS);
if(!isset($paypal_error_counter)) $paypal_error_counter = 0;
if(!isset($paypal_instance_id)) $paypal_instance_id = time() . '_' . zen_create_random_value(4);
if ((defined('MODULE_PAYMENT_PAYPALWPP_DEBUGGING') && MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Log and Email') || (defined('MODULE_PAYMENT_PAYPAL_IPN_DEBUG') && MODULE_PAYMENT_PAYPAL_IPN_DEBUG == 'Log and Email') || $always_send) {
$paypal_error_counter ++;
zen_mail(STORE_OWNER, $email_address, $subjecttext . ' (' . $paypal_instance_id . ') #' . $paypal_error_counter, $message, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, array('EMAIL_MESSAGE_HTML'=>$message), 'debug');
}
if ((defined('MODULE_PAYMENT_PAYPAL_IPN_DEBUG') && (MODULE_PAYMENT_PAYPAL_IPN_DEBUG == 'Log and Email' || MODULE_PAYMENT_PAYPAL_IPN_DEBUG == 'Log File' || MODULE_PAYMENT_PAYPAL_IPN_DEBUG == 'Yes')) || (defined('MODULE_PAYMENT_PAYPALWPP_DEBUGGING') && (MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Log File' || MODULE_PAYMENT_PAYPALWPP_DEBUGGING == 'Log and Email'))) ipn_add_error_log($message, $paypal_instance_id);
}
function ipn_get_stored_session($session_stuff) {
global $db;
if (!is_array($session_stuff)) {
ipn_debug_email('IPN FATAL ERROR :: Could not find custom variable in POST, cannot re-create session as PayPal IPN transaction.');
return false;
}
$sql = "SELECT *
FROM " . TABLE_PAYPAL_SESSION . "
WHERE session_id = :sessionID";
$sql = $db->bindVars($sql, ':sessionID', $session_stuff[1], 'string');
$stored_session = $db->Execute($sql);
if ($stored_session->recordCount() < 1) {
ipn_debug_email('IPN FATAL ERROR :: Could not find stored session in DB, cannot re-create session as PayPal IPN transaction.');
return false;
}
$_SESSION = unserialize(base64_decode($stored_session->fields['saved_session']));
return true;
}
/**
* look up parent/original transaction record data and return matching order info if found, along with txn_type
*/
function ipn_lookup_transaction($postArray) {
global $db;
// find Zen Cart order number from the transactionID in the IPN
$useTable = TABLE_PAYPAL;
if (MODULE_PAYMENT_PAYPAL_TESTING == 'Test') $useTable = TABLE_PAYPAL_TESTING;
$ordersID = 0;
$paypalipnID = 0;
$transType = 'unknown';
$sql = "SELECT order_id, paypal_ipn_id, payment_status, txn_type, pending_reason
FROM " . $useTable . "
WHERE txn_id = :transactionID
ORDER BY order_id DESC ";
$sql1 = $db->bindVars($sql, ':transactionID', $postArray['parent_txn_id'], 'string');
$sql2 = $db->bindVars($sql, ':transactionID', $postArray['txn_id'], 'string');
if (isset($postArray['parent_txn_id']) && trim($postArray['parent_txn_id']) != '') {
$ipn_id = $db->Execute($sql1);
if($ipn_id->RecordCount() > 0) {
ipn_debug_email('IPN NOTICE :: This transaction HAS a parent record. Thus this is an update of some sort.');
$transType = 'parent';
$ordersID = $ipn_id->fields['order_id'];
$paypalipnID = $ipn_id->fields['paypal_ipn_id'];
}
} else {
$ipn_id = $db->Execute($sql2);
if ($ipn_id->RecordCount() <= 0) {
ipn_debug_email('IPN NOTICE :: Could not find matched txn_id record in DB. Therefore is new to us. ');
$transType = 'unique';
} else {
while(!$ipn_id->EOF) {
switch ($ipn_id->fields['pending_reason']) {
case 'address':
ipn_debug_email('IPN NOTICE :: Found pending-address record in database');
if ($postArray['payment_status'] == 'Completed') $transType = 'cleared-address';
if ($postArray['payment_status'] == 'Denied') $transType = 'denied-address';
if ($postArray['payment_status'] == 'Pending') $transType = 'pending-address';
break;
case 'multi_currency':
ipn_debug_email('IPN NOTICE :: Found pending-multicurrency record in database');
if ($postArray['payment_status'] == 'Completed') $transType = 'cleared-multicurrency';
if ($postArray['payment_status'] == 'Denied') $transType = 'denied-multicurrency';
if ($postArray['payment_status'] == 'Pending') $transType = 'pending-multicurrency';
break;
case 'echeck':
ipn_debug_email('IPN NOTICE :: Found pending-echeck record in database');
if ($postArray['payment_status'] == 'Completed') $transType = 'cleared-echeck';
if ($postArray['payment_status'] == 'Completed' && $postArray['txn_type'] == 'web_accept') $transType = 'cleared-echeck';
if ($postArray['payment_status'] == 'Denied') $transType = 'denied-echeck';
if ($postArray['payment_status'] == 'Failed') $transType = 'failed-echeck';
if ($postArray['payment_status'] == 'Pending') $transType = 'pending-echeck';
break;
case 'authorization':
ipn_debug_email('IPN NOTICE :: Found pending-authorization record in database');
$transType = 'cleared-authorization';
if ($postArray['payment_status'] == 'Voided') $transType = 'voided';
if ($postArray['payment_status'] == 'Pending') $transType = 'pending-authorization';
if ($postArray['payment_status'] == 'Captured') $transType = 'captured';
break;
case 'verify':
ipn_debug_email('IPN NOTICE :: Found pending-verify record in database');
$transType = 'cleared-verify';
break;
case 'intl':
ipn_debug_email('IPN NOTICE :: Found pending-intl record in database');
if ($postArray['payment_status'] == 'Completed') $transType = 'cleared-intl';
if ($postArray['payment_status'] == 'Denied') $transType = 'denied-intl';
if ($postArray['payment_status'] == 'Pending') $transType = 'pending-intl';
break;
case 'unilateral':
ipn_debug_email('IPN NOTICE :: Found record in database.' . "\n" . '*** NOTE: TRANSACTION IS IN *unilateral* STATUS pending creation of a PayPal account for this receiver_email address.' . "\n" . 'Please create the account, or make sure the account is *Verified*.');
$transType = 'pending-unilateral';
break;
}
if ($transType != 'unknown') {
$ordersID = $ipn_id->fields['order_id'];
$paypalipnID = $ipn_id->fields['paypal_ipn_id'];
}
$ipn_id->MoveNext();
}
}
}
return array('order_id' => $ordersID, 'paypal_ipn_id' => $paypalipnID, 'txn_type' => $transType);
}
/**
* IPN Validation
* - match email addresses
* - ensure that "VERIFIED" has been returned (otherwise somebody is trying to spoof)
*/
function ipn_validate_transaction($info, $postArray, $mode='IPN') {
if ($mode == 'IPN' && !eregi("VERIFIED",$info)) {
ipn_debug_email('IPN WARNING :: Transaction was not marked as VERIFIED. Keep this report for potential use in fraud investigations.' . "\n" . 'IPN Info = ' . "\n" . $info);
return false;
} elseif ($mode == 'PDT' && (!eregi("SUCCESS", $info) || eregi("FAIL", $info))) {
ipn_debug_email('IPN WARNING :: PDT Transaction was not marked as SUCCESS. Keep this report for potential use in fraud investigations.' . "\n" . 'IPN Info = ' . "\n" . $info);
return false;
}
$ppBusEmail = false;
$ppRecEmail = false;
if (defined('MODULE_PAYMENT_PAYPAL_BUSINESS_ID')) {
if (strtolower(trim($postArray['business'])) == strtolower(trim(MODULE_PAYMENT_PAYPAL_BUSINESS_ID))) $ppBusEmail = true;
if (strtolower(trim($postArray['receiver_email'])) == strtolower(trim(MODULE_PAYMENT_PAYPAL_BUSINESS_ID))) $ppRecEmail = true;
if (!$ppBusEmail && !$ppRecEmail) {
ipn_debug_email('IPN WARNING :: Transaction email address NOT matched.' . "\n" . 'From IPN = ' . $postArray['business'] . ' | ' . $postArray['receiver_email'] . "\n" . 'From CONFIG = ' . MODULE_PAYMENT_PAYPAL_BUSINESS_ID);
return false;
}
ipn_debug_email('IPN INFO :: Transaction email details.' . "\n" . 'From IPN = ' . $postArray['business'] . ' | ' . $postArray['receiver_email'] . "\n" . 'From CONFIG = ' . MODULE_PAYMENT_PAYPAL_BUSINESS_ID);
}
return true;
}
// determine acceptable currencies
function select_pp_currency() {
if (MODULE_PAYMENT_PAYPAL_CURRENCY == 'Selected Currency') {
$my_currency = $_SESSION['currency'];
} else {
$my_currency = substr(MODULE_PAYMENT_PAYPAL_CURRENCY, 5);
}
$pp_currencies = array('CAD', 'EUR', 'GBP', 'JPY', 'USD', 'AUD', 'CHF', 'CZK', 'DKK', 'HKD', 'HUF', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'THB');
if (!in_array($my_currency, $pp_currencies)) {
$my_currency = 'USD';
}
return $my_currency;
}
function valid_payment($amount, $currency, $mode = 'IPN') {
global $currencies;
$my_currency = select_pp_currency();
$exchanged_amount = ($mode == 'IPN' ? ($amount * $currencies->get_value($my_currency)) : $amount);
$transaction_amount = preg_replace('/[^0-9.]/', '', number_format($exchanged_amount, $currencies->get_decimal_places($my_currency), '.', ''));
if ( ($_POST['mc_currency'] != $my_currency) || ($_POST['mc_gross'] != $transaction_amount && $_POST['mc_gross'] != -0.01) && MODULE_PAYMENT_PAYPAL_TESTING != 'Test' ) {
ipn_debug_email('IPN WARNING :: Currency/Amount Mismatch. Details: ' . "\n" . 'PayPal email address = ' . $_POST['business'] . "\n" . ' | mc_currency = ' . $_POST['mc_currency'] . "\n" . ' | submitted_currency = ' . $my_currency . "\n" . ' | order_currency = ' . $currency . "\n" . ' | mc_gross = ' . $_POST['mc_gross'] . "\n" . ' | converted_amount = ' . $transaction_amount . "\n" . ' | order_amount = ' . $amount );
return false;
}
ipn_debug_email('IPN INFO :: Currency/Amount Details: ' . "\n" . 'PayPal email address = ' . $_POST['business'] . "\n" . ' | mc_currency = ' . $_POST['mc_currency'] . "\n" . ' | submitted_currency = ' . $my_currency . "\n" . ' | order_currency = ' . $currency . "\n" . ' | mc_gross = ' . $_POST['mc_gross'] . "\n" . ' | converted_amount = ' . $transaction_amount . "\n" . ' | order_amount = ' . $amount );
return true;
}
/**
* is this an existing transaction?
* (1) we find a matching record in the "paypal" table
* (2) we check for valid txn_types or payment_status such as Denied, Refunded, Partially-Refunded, Reversed, Voided, Expired
* @TODO -- this section is not complete yet
*/
function ipn_determine_txn_type($postArray, $txn_type = 'unknown') {
global $db;
if (substr($txn_type,0,8) == 'cleared-') return $txn_type;
if ($postArray['txn_type'] == 'send_money') return $postArray['txn_type'];
if ($postArray['txn_type'] == 'express_checkout' || $postArray['txn_type'] == 'cart') $txn_type = $postArray['txn_type'];
// if it's not unique or linked to a parent, then:
// 1. could be an e-check denied / cleared
// 2. could be an express-checkout "pending" transaction which has been Accepted in the merchant's PayPal console and needs activation in Zen Cart
if ($postArray['payment_status']=='Completed' && txn_type=='express_checkout' && $postArray['payment_type']=='echeck') {
$txn_type = 'express-checkout-cleared';
return $txn_type;
}
if ($postArray['payment_status']=='Completed' && $postArray['payment_type']=='echeck') {
$txn_type = 'echeck-cleared';
return $txn_type;
}
if (($postArray['payment_status']=='Denied' || $postArray['payment_status']=='Failed') && $postArray['payment_type']=='echeck') {
$txn_type = 'echeck-denied';
return $txn_type;
}
if ($postArray['payment_status']=='Denied') {
$txn_type = 'denied';
return $txn_type;
}
if (($postArray['payment_status']=='Pending') && $postArray['pending_reason']=='echeck') {
$txn_type = 'pending-echeck';
return $txn_type;
}
if (($postArray['payment_status']=='Pending') && $postArray['pending_reason']=='address') {
$txn_type = 'pending-address';
return $txn_type;
}
if (($postArray['payment_status']=='Pending') && $postArray['pending_reason']=='intl') {
$txn_type = 'pending-intl';
return $txn_type;
}
if (($postArray['payment_status']=='Pending') && $postArray['pending_reason']=='multi_currency') {
$txn_type = 'pending-multicurrency';
return $txn_type;
}
if (($postArray['payment_status']=='Pending') && $postArray['pending_reason']=='verify') {
$txn_type = 'pending-verify';
return $txn_type;
}
if (($postArray['payment_status']=='Voided') && $postArray['payment_type']=='instant') {
$txn_type = 'voided';
return $txn_type;
}
return $txn_type;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -