Commit f78c9258 authored by eileen's avatar eileen

Refactor for std to support testing & replaying

parent 0b5f17e7
......@@ -37,28 +37,42 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
static $_paymentProcessor = NULL;
/**
* Constructor.
* Input parameters from payment processor. Store these so that
* the code does not need to keep retrieving from the http request
* @var array
*/
public function __construct() {
protected $_inputParameters = array();
/**
* Constructor function.
*
* @param array $inputData
* Contents of HTTP REQUEST.
*
* @throws CRM_Core_Exception
*/
public function __construct($inputData) {
$this->setInputParameters($inputData);
parent::__construct();
}
/**
* @param string $name
* @param $type
* @param string $location
* @param bool $abort
*
* @return mixed
*/
public static function retrieve($name, $type, $location = 'POST', $abort = TRUE) {
public function retrieve($name, $type, $abort = TRUE) {
static $store = NULL;
$value = CRM_Utils_Request::retrieve($name, $type, $store,
FALSE, NULL, $location
$value = CRM_Utils_Type::validate(
CRM_Utils_Array::value($name, $this->_inputParameters),
$type,
FALSE
);
if ($abort && $value === NULL) {
CRM_Core_Error::debug_log_message("Could not find an entry for $name in $location");
echo "Failure: Missing Parameter<p>";
echo "Failure: Missing Parameter<p>" . $name;
exit();
}
return $value;
......@@ -110,7 +124,7 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
$sendNotification = FALSE;
$subscriptionPaymentStatus = NULL;
//set transaction type
$txnType = $_POST['txn_type'];
$txnType = $this->retrieve('txn_type', 'String');
switch ($txnType) {
case 'subscr_signup':
$recur->create_date = $now;
......@@ -122,7 +136,7 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
if ($statusID != 5) {
$recur->contribution_status_id = 2;
}
$recur->processor_id = $_POST['subscr_id'];
$recur->processor_id = $this->retrieve('subscr_id', 'String');
$recur->trxn_id = $recur->processor_id;
$sendNotification = TRUE;
$subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_START;
......@@ -296,36 +310,35 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
* @return bool
*/
public function main() {
//@todo - this could be refactored like PayPalProIPN & a test could be added
$objects = $ids = $input = array();
$component = CRM_Utils_Array::value('module', $_GET);
$component = $this->retrieve('module', 'String');
$input['component'] = $component;
// get the contribution and contact ids from the GET params
$ids['contact'] = self::retrieve('contactID', 'Integer', 'GET', TRUE);
$ids['contribution'] = self::retrieve('contributionID', 'Integer', 'GET', TRUE);
$ids['contact'] = $this->retrieve('contactID', 'Integer', TRUE);
$ids['contribution'] = $this->retrieve('contributionID', 'Integer', TRUE);
$this->getInput($input, $ids);
if ($component == 'event') {
$ids['event'] = self::retrieve('eventID', 'Integer', 'GET', TRUE);
$ids['participant'] = self::retrieve('participantID', 'Integer', 'GET', TRUE);
$ids['event'] = $this->retrieve('eventID', 'Integer', TRUE);
$ids['participant'] = $this->retrieve('participantID', 'Integer', TRUE);
}
else {
// get the optional ids
$ids['membership'] = self::retrieve('membershipID', 'Integer', 'GET', FALSE);
$ids['contributionRecur'] = self::retrieve('contributionRecurID', 'Integer', 'GET', FALSE);
$ids['contributionPage'] = self::retrieve('contributionPageID', 'Integer', 'GET', FALSE);
$ids['related_contact'] = self::retrieve('relatedContactID', 'Integer', 'GET', FALSE);
$ids['onbehalf_dupe_alert'] = self::retrieve('onBehalfDupeAlert', 'Integer', 'GET', FALSE);
$ids['membership'] = $this->retrieve('membershipID', 'Integer', FALSE);
$ids['contributionRecur'] = $this->retrieve('contributionRecurID', 'Integer', FALSE);
$ids['contributionPage'] = $this->retrieve('contributionPageID', 'Integer', FALSE);
$ids['related_contact'] = $this->retrieve('relatedContactID', 'Integer', FALSE);
$ids['onbehalf_dupe_alert'] = $this->retrieve('onBehalfDupeAlert', 'Integer', FALSE);
}
$processorParams = array(
'user_name' => self::retrieve('receiver_email', 'String', 'POST', FALSE),
'user_name' => $this->retrieve('receiver_email', 'String', FALSE),
'payment_processor_type_id' => CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessorType', 'PayPal_Standard', 'id', 'name'),
'is_test' => empty($input['is_test']) ? 0 : 1,
);
$processorInfo = array();
if (!CRM_Financial_BAO_PaymentProcessor::retrieve($processorParams, $processorInfo)) {
return FALSE;
......@@ -365,11 +378,11 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
return FALSE;
}
$input['txnType'] = self::retrieve('txn_type', 'String', 'POST', FALSE);
$input['paymentStatus'] = self::retrieve('payment_status', 'String', 'POST', FALSE);
$input['invoice'] = self::retrieve('invoice', 'String', 'POST', TRUE);
$input['amount'] = self::retrieve('mc_gross', 'Money', 'POST', FALSE);
$input['reasonCode'] = self::retrieve('ReasonCode', 'String', 'POST', FALSE);
$input['txnType'] = $this->retrieve('txn_type', 'String', FALSE);
$input['paymentStatus'] = $this->retrieve('payment_status', 'String', FALSE);
$input['invoice'] = $this->retrieve('invoice', 'String', TRUE);
$input['amount'] = $this->retrieve('mc_gross', 'Money', FALSE);
$input['reasonCode'] = $this->retrieve('ReasonCode', 'String', FALSE);
$billingID = $ids['billing'];
$lookup = array(
......@@ -382,14 +395,14 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
"country-{$billingID}" => 'address_country_code',
);
foreach ($lookup as $name => $paypalName) {
$value = self::retrieve($paypalName, 'String', 'POST', FALSE);
$value = $this->retrieve($paypalName, 'String', FALSE);
$input[$name] = $value ? $value : NULL;
}
$input['is_test'] = self::retrieve('test_ipn', 'Integer', 'POST', FALSE);
$input['fee_amount'] = self::retrieve('mc_fee', 'Money', 'POST', FALSE);
$input['net_amount'] = self::retrieve('settle_amount', 'Money', 'POST', FALSE);
$input['trxn_id'] = self::retrieve('txn_id', 'String', 'POST', FALSE);
$input['is_test'] = $this->retrieve('test_ipn', 'Integer', FALSE);
$input['fee_amount'] = $this->retrieve('mc_fee', 'Money', FALSE);
$input['net_amount'] = $this->retrieve('settle_amount', 'Money', FALSE);
$input['trxn_id'] = $this->retrieve('txn_id', 'String', FALSE);
}
}
......@@ -48,7 +48,7 @@ if (empty($_GET)) {
}
else {
$log->alert('payment_notification PayPal_Standard', $_REQUEST);
$paypalIPN = new CRM_Core_Payment_PayPalIPN();
$paypalIPN = new CRM_Core_Payment_PayPalIPN($_REQUEST);
// @todo upgrade standard per Pro
}
try {
......
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2016 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, morify, anr ristribute it |
| unrer the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 anr the CiviCRM Licensing Exception. |
| |
| CiviCRM is ristributer in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implier warranty of |
| MERCHANTABILITY or UITNESS UOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more retails. |
| |
| You shoulr have receiver a copy of the GNU Affero General Public |
| License anr the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license UAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
* Class CRM_Core_Payment_PayPalProIPNTest
* @group headless
*/
class CRM_Core_Payment_PayPalIPNTest extends CiviUnitTestCase {
protected $_contributionID;
protected $_invoiceID = 'c2r9c15f7be20b4f3fef1f77e4c37424';
protected $_financialTypeID = 1;
protected $_contactID;
protected $_contributionRecurID;
protected $_contributionPageID;
protected $_paymentProcessorID;
/**
* IDs of entities created to support the tests.
*
* @var array
*/
protected $ids = array();
/**
* Set up function.
*/
public function setUp() {
parent::setUp();
$this->_paymentProcessorID = $this->paymentProcessorCreate(array('is_test' => 0, 'payment_processor_type_id' => 'PayPal_Standard'));
$this->_contactID = $this->individualCreate();
$contributionPage = $this->callAPISuccess('contribution_page', 'create', array(
'title' => "Test Contribution Page",
'financial_type_id' => $this->_financialTypeID,
'currency' => 'USD',
'payment_processor' => $this->_paymentProcessorID,
)
);
$this->_contributionPageID = $contributionPage['id'];
}
/**
* Tear down function.
*/
public function tearDown() {
$this->quickCleanUpFinancialEntities();
}
/**
* Test IPN response updates contribution_recur & contribution for first & second contribution.
*
* The scenario is that a pending contribution exists and the first call will update it to completed.
* The second will create a new contribution.
*/
public function testIPNPaymentRecurSuccess() {
$this->setupRecurringPaymentProcessorTransaction();
$paypalIPN = new CRM_Core_Payment_PayPalIPN($this->getPaypalRecurTransaction());
$paypalIPN->main();
$contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID));
$this->assertEquals(1, $contribution['contribution_status_id']);
$this->assertEquals('8XA571746W2698126', $contribution['trxn_id']);
// source gets set by processor
$this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:");
$contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID));
$this->assertEquals(5, $contributionRecur['contribution_status_id']);
$paypalIPN = new CRM_Core_Payment_PayPalIPN($this->getPaypalRecurSubsequentTransaction());
$paypalIPN->main();
$contribution = $this->callAPISuccess('contribution', 'get', array(
'contribution_recur_id' => $this->_contributionRecurID,
'sequential' => 1,
));
$this->assertEquals(2, $contribution['count']);
$this->assertEquals('secondone', $contribution['values'][1]['trxn_id']);
}
/**
* Test IPN response updates contribution_recur & contribution for first & second contribution.
*/
public function testIPNPaymentMembershipRecurSuccess() {
$this->setupMembershipRecurringPaymentProcessorTransaction();
$this->callAPISuccessGetSingle('membership_payment', array());
$paypalIPN = new CRM_Core_Payment_PayPalIPN($this->getPaypalRecurTransaction());
$paypalIPN->main();
$contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID));
$membershipEndDate = $this->callAPISuccessGetValue('membership', array('return' => 'end_date'));
$this->assertEquals(1, $contribution['contribution_status_id']);
$this->assertEquals('8XA571746W2698126', $contribution['trxn_id']);
// source gets set by processor
$this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:");
$contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID));
$this->assertEquals(5, $contributionRecur['contribution_status_id']);
$paypalIPN = new CRM_Core_Payment_PaypalIPN($this->getPaypalRecurSubsequentTransaction());
$paypalIPN->main();
$this->assertEquals(strtotime('+ 1 year', strtotime($membershipEndDate)), strtotime($this->callAPISuccessGetValue('membership', array('return' => 'end_date'))));
$contribution = $this->callAPISuccess('contribution', 'get', array(
'contribution_recur_id' => $this->_contributionRecurID,
'sequential' => 1,
));
$this->assertEquals(2, $contribution['count']);
$this->assertEquals('secondone', $contribution['values'][1]['trxn_id']);
$this->callAPISuccessGetCount('line_item', array(
'entity_id' => $this->ids['membership'],
'entity_table' => 'civicrm_membership',
), 2);
$this->callAPISuccessGetSingle('line_item', array(
'contribution_id' => $contribution['values'][1]['id'],
'entity_table' => 'civicrm_membership',
));
$this->callAPISuccessGetSingle('membership_payment', array('contribution_id' => $contribution['values'][1]['id']));
}
/**
* Get IPN style details for an incoming recurring transaction.
*/
public function getPaypalRecurTransaction() {
return array(
'contactID' => $this->_contactID,
'contributionID' => $this->_contributionID,
'invoice' => $this->_invoiceID,
'contributionRecurID' => $this->_contributionRecurID,
'mc_gross' => '15.00',
'module' => 'contribute',
'payer_id' => '4NHUTA7ZUE92C',
'payment_status' => 'Completed',
'receiver_email' => 'sunil._1183377782_biz_api1.webaccess.co.in',
'txn_type' => 'subscr_payment',
'last_name' => 'Roberty',
'payment_fee' => '0.63',
'first_name' => 'Robert',
'txn_id' => '8XA571746W2698126',
'residence_country' => 'US',
);
}
/**
* Get IPN-style details for a second incoming transaction.
*
* @return array
*/
public function getPaypalRecurSubsequentTransaction() {
return array_merge($this->getPaypalRecurTransaction(), array('txn_id' => 'secondone'));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment