Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
Core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
925
Issues
925
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Development
Core
Commits
f78c9258
Commit
f78c9258
authored
Jul 06, 2016
by
eileen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor for std to support testing & replaying
parent
0b5f17e7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
213 additions
and
33 deletions
+213
-33
CRM/Core/Payment/PayPalIPN.php
CRM/Core/Payment/PayPalIPN.php
+45
-32
extern/ipn.php
extern/ipn.php
+1
-1
tests/phpunit/CRM/Core/Payment/PayPalPNTest.php
tests/phpunit/CRM/Core/Payment/PayPalPNTest.php
+167
-0
No files found.
CRM/Core/Payment/PayPalIPN.php
View file @
f78c9258
...
...
@@ -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
);
}
}
extern/ipn.php
View file @
f78c9258
...
...
@@ -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
{
...
...
tests/phpunit/CRM/Core/Payment/PayPalPNTest.php
0 → 100644
View file @
f78c9258
<?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'
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment