Index: C:/projects/ecommerce4.7.0/paypal/paypal.module =================================================================== --- C:/projects/ecommerce4.7.0/paypal/paypal.module (revision 16) +++ C:/projects/ecommerce4.7.0/paypal/paypal.module (revision 21) @@ -5,6 +5,52 @@ * Drupal Hooks ********************************************************************/ +/** Access secret option key. */ +function paypal_get_secret_key() +{ + return 'paypal_secret'; +} + + +/** Access secret. */ +function paypal_get_secret() +{ + $default = 'replace_with_unique_string'; + + return variable_get(paypal_get_secret_key(), $default); +} + + +/** Verify secret arg in PayPal IPN */ +function paypal_verify_secret() +{ + $secret = $_GET['secret']; + + $same = (paypal_get_secret() == $secret); + + if (!$same) { + watchdog('paypal', t('IPN hit, secret invalid: secret=%secret', array('%secret' => $secret)), WATCHDOG_ERROR); + } + + return $same; +} + + +/** Verify paypal gross is same as transaction gross. */ +function paypal_verify_gross($txnid, $paypal_gross) +{ + $transaction_gross = db_result(db_query('SELECT gross FROM {ec_transaction} WHERE txnid = %d LIMIT 1', $txnid)); + + $same = ($transaction_gross == $paypal_gross); + + if (!$same) { + watchdog('paypal', t('IPN hit, gross mismatch: gross=%gross, paypal gross=%paypal_gross', array('%gross' => $transaction_gross, '%paypal_gross' => $paypal_gross)), WATCHDOG_ERROR); + } + + return $same; +} + + /** * Implementation of hook help(). */ @@ -15,7 +61,7 @@ return t('EC: Process payments using paypal.'); case 'admin/store/settings/paypal': - return t('
In order to use this module, you need to create an account with PayPal. Also, you can setup Instant Payment Notification (IPN) to track PayPal payments from your own website. The IPN URL of your site is:
%ipn_url
', array('%ipn_url' => url('paypal/ipn', NULL, NULL, TRUE))); + return t('In order to use this module, you need to create an account with PayPal. Also, you can setup Instant Payment Notification (IPN) to track PayPal payments from your own website. The IPN URL of your site is:
%ipn_url
', array('%ipn_url' => url(t('paypal/ipn'), 'secret='.paypal_get_secret(), NULL, TRUE))); } } @@ -32,8 +78,18 @@ return $items; } + function paypal_ec_settings() { + $form[paypal_get_secret_key()] = array( + '#type' => 'textfield', + '#title' => t('PayPal ipn unique vendor secret'), + '#default_value' => paypal_get_secret(), + '#size' => 70, + '#maxlength' => 180, + '#description' => t('Secret arg sent with PayPal ipn, to uniquely identify and validate vendor.') + ); + $form['paypal_receiver_email'] = array( '#type' => 'textfield', '#title' => t('PayPal Receiver Email'),'#default_value' => variable_get('paypal_receiver_email', variable_get('site_mail', ini_get('sendmail_from'))), '#size' => 70, '#maxlength' => 180, '#description' => t('Primary email address of the payment recipent. This is also your main paypal email address.') ); $form['paypal_url'] = array( '#type' => 'textfield', '#title' => t('PayPal processing URL'),'#default_value' => variable_get('paypal_url', 'https://www.paypal.com/xclick/'), '#size' => 70, '#maxlength' => 180, '#description' => t('URL of the secure payment page customers are sent to for payment processing.')); @@ -184,6 +240,7 @@ } + function paypal_ipn() { $has_txn_key = false; @@ -268,7 +325,10 @@ // HTTP ERROR $debug .= t("An HTTP error occurred\n"); } - elseif ($ppid && $has_txn_key) { // We can't do much without a txn_id + elseif (paypal_verify_secret() && + $ppid && + $has_txn_key && // We can't do much without a txn_id + paypal_verify_gross($txnid, $payment_amount)) { fputs ($fp, $header . $req); while (!feof($fp)) { $res = fgets ($fp, 1024);