[MediaWiki-commits] [Gerrit] Cancel duplicate authorizations for a single order ID - change (wikimedia...SmashPig)

2016-03-28 Thread jenkins-bot (Code Review)
jenkins-bot has submitted this change and it was merged.

Change subject: Cancel duplicate authorizations for a single order ID
..


Cancel duplicate authorizations for a single order ID

Donors can somehow submit the Adyen iframe multiple times without
our generating new order IDs / merchant references.  If we get
duplicate authorizations, mark the donor details as captured after
capturing the first, then cancel all subsequent authorizations.

We send the pending queue message before the donor sees the credit
card form, so we assume that if no message exists, this is a duplicate
authorization and the original has already been sent to Civi.

Bug: T129935
Change-Id: I2b338164461130c3afd0d91efbbd7cfbeec1b680
---
M CrmLink/Messages/DonationInterfaceMessage.php
M PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
M PaymentProviders/Adyen/Tests/MockAdyenPaymentsAPI.php
M PaymentProviders/Adyen/Tests/phpunit/CaptureJobTest.php
M PaymentProviders/Amazon/Tests/phpunit/ApiTest.php
M Tests/BaseSmashPigUnitTestCase.php
6 files changed, 285 insertions(+), 54 deletions(-)

Approvals:
  Awight: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/CrmLink/Messages/DonationInterfaceMessage.php 
b/CrmLink/Messages/DonationInterfaceMessage.php
index 6db0360..3f9c391 100644
--- a/CrmLink/Messages/DonationInterfaceMessage.php
+++ b/CrmLink/Messages/DonationInterfaceMessage.php
@@ -6,6 +6,7 @@
  * Message sent to the 'cc-limbo' queue when a payment has been initiated and 
sent off to the gateway.
  */
 class DonationInterfaceMessage extends KeyedOpaqueStorableObject {
+   public $captured = '';
public $city = '';
public $city_2 = '';
public $comment = '';
diff --git a/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php 
b/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
index d6d5987..7323071 100644
--- a/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
+++ b/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
@@ -26,10 +26,10 @@
protected $avsResult;
protected $cvvResult;
// Actions to take after examining capture request and queue message
-   const ACTION_IGNORE = 'ignore'; // no donor info or auth already 
captured, do nothing
const ACTION_PROCESS = 'process'; // all clear to capture payment
const ACTION_REJECT = 'reject'; // very likely fraud - cancel the 
authorization
const ACTION_REVIEW = 'review'; // potential fraud - do not capture now
+   const ACTION_DUPLICATE = 'duplicate'; // probable duplicate - cancel 
the authorization
 
public static function factory( Authorisation $authMessage ) {
$obj = new ProcessCaptureRequestJob();
@@ -54,7 +54,11 @@
);
 
// Determine if a message exists in the pending queue; if it 
does not then
-   // this payment has already been sent to the verified queue.
+   // this payment has already been sent to the verified queue. If 
it does,
+   // we need to check $capture_requested in case we have 
requested a capture
+   // but have not yet received notification of capture success. 
Either case can
+   // occur when a donor submits their credit card details 
multiple times against
+   // a single order ID. We should cancel all the duplicate 
authorizations.
Logger::debug( 'Attempting to locate associated message in 
pending queue.' );
/**
 * @var \SmashPig\Core\DataStores\KeyedOpaqueDataStore
@@ -64,51 +68,58 @@
$success = true;
 
$action = $this->determineAction( $queueMessage );
-   if ( $action == self::ACTION_PROCESS ) {
-   // Tell the pending queue to keep the message around 
for the RecordCaptureJob
-   $pendingQueue->queueIgnoreObject();
-
-   // Attempt to capture the payment
-   $api = $this->getApi();
-   Logger::info(
-   "Attempting capture API call for currency 
'{$this->currency}', " .
-   "amount '{$this->amount}', reference 
'{$this->pspReference}'."
-   );
-   $captureResult = $api->capture( $this->currency, 
$this->amount, $this->pspReference );
-
-   if ( $captureResult ) {
-   // Success!
+   switch( $action ) {
+   case self::ACTION_PROCESS:
+   // Attempt to capture the payment
+   $api = $this->getApi();
Logger::info(
-   "Successfully captured payment! 
Returned reference: '{$captureResult}'. " .
-   'Leaving pending 

[MediaWiki-commits] [Gerrit] Cancel duplicate authorizations for a single order ID - change (wikimedia...SmashPig)

2016-03-14 Thread Ejegg (Code Review)
Ejegg has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/277427

Change subject: Cancel duplicate authorizations for a single order ID
..

Cancel duplicate authorizations for a single order ID

Donors can somehow submit the Adyen iframe multiple times without
our generating new order IDs / merchant references.  If we get
duplicate authorizations, mark the donor details as captured after
capturing the first, then cancel all subsequent authorizations.

We send the pending queue message before the donor sees the credit
card form, so we assume that if no message exists, this is a duplicate
authorization and the original has already been sent to Civi.

Bug: T129935
Change-Id: I2b338164461130c3afd0d91efbbd7cfbeec1b680
---
M CrmLink/Messages/DonationInterfaceMessage.php
M PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
2 files changed, 77 insertions(+), 46 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/SmashPig 
refs/changes/27/277427/1

diff --git a/CrmLink/Messages/DonationInterfaceMessage.php 
b/CrmLink/Messages/DonationInterfaceMessage.php
index 6db0360..3f9c391 100644
--- a/CrmLink/Messages/DonationInterfaceMessage.php
+++ b/CrmLink/Messages/DonationInterfaceMessage.php
@@ -6,6 +6,7 @@
  * Message sent to the 'cc-limbo' queue when a payment has been initiated and 
sent off to the gateway.
  */
 class DonationInterfaceMessage extends KeyedOpaqueStorableObject {
+   public $captured = '';
public $city = '';
public $city_2 = '';
public $comment = '';
diff --git a/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php 
b/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
index d0cc7e6..7600795 100644
--- a/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
+++ b/PaymentProviders/Adyen/Jobs/ProcessCaptureRequestJob.php
@@ -26,10 +26,10 @@
protected $avsResult;
protected $cvvResult;
// Actions to take after examining capture request and queue message
-   const ACTION_IGNORE = 'ignore'; // no donor info or auth already 
captured, do nothing
const ACTION_PROCESS = 'process'; // all clear to capture payment
const ACTION_REJECT = 'reject'; // very likely fraud - cancel the 
authorization
const ACTION_REVIEW = 'review'; // potential fraud - do not capture now
+   const ACTION_DUPLICATE = 'duplicate'; // probable duplicate - cancel 
the authorization
 
public static function factory( Authorisation $authMessage ) {
$obj = new ProcessCaptureRequestJob();
@@ -54,58 +54,69 @@
);
 
// Determine if a message exists in the pending queue; if it 
does not then
-   // this payment has already been sent to the verified queue.
+   // this payment has already been sent to the verified queue. If 
it does,
+   // we need to check $capture_requested in case we have 
requested a capture
+   // but have not yet received notification of capture success. 
Either case can
+   // occur when a donor submits their credit card details 
multiple times against
+   // a single order ID. We should cancel all the duplicate 
authorizations.
Logger::debug( 'Attempting to locate associated message in 
pending queue.' );
$pendingQueue = Configuration::getDefaultConfig()->object( 
'data-store/pending' );
$queueMessage = $pendingQueue->queueGetObject( null, 
$this->correlationId );
$success = true;
 
$action = $this->determineAction( $queueMessage );
-   if ( $action == self::ACTION_PROCESS ) {
-   // Tell the pending queue to keep the message around 
for the RecordCaptureJob
-   $pendingQueue->queueIgnoreObject();
-
-   // Attempt to capture the payment
-   $api = new AdyenPaymentsAPI( $this->account );
-   Logger::info(
-   "Attempting capture API call for currency 
'{$this->currency}', " .
-   "amount '{$this->amount}', reference 
'{$this->pspReference}'."
-   );
-   $captureResult = $api->capture( $this->currency, 
$this->amount, $this->pspReference );
-
-   if ( $captureResult ) {
-   // Success!
+   switch( $action ) {
+   case self::ACTION_PROCESS:
+   // Attempt to capture the payment
+   $api = new AdyenPaymentsAPI( $this->account );
Logger::info(
-   "Successfully captured payment! 
Returned reference: '{$captureResult}'. " .
-   'Leaving pending message in 
queue for