Ejegg has submitted this change and it was merged.

Change subject: WorldPay Lynk (WP US) reconciliation
......................................................................


WorldPay Lynk (WP US) reconciliation

Change-Id: I20d7fa469f4982da19626d432b7db1a4c394c54a
---
A PaymentProviders/WorldPay/Audit/LynkReconciliationFile.php
M PaymentProviders/WorldPay/Audit/WorldPayAudit.php
2 files changed, 196 insertions(+), 0 deletions(-)

Approvals:
  Ejegg: Looks good to me, approved



diff --git a/PaymentProviders/WorldPay/Audit/LynkReconciliationFile.php 
b/PaymentProviders/WorldPay/Audit/LynkReconciliationFile.php
new file mode 100644
index 0000000..28b6c45
--- /dev/null
+++ b/PaymentProviders/WorldPay/Audit/LynkReconciliationFile.php
@@ -0,0 +1,195 @@
+<?php
+namespace SmashPig\PaymentProviders\WorldPay\Audit;
+
+use \Exception;
+
+/**
+ * See Transaction Detail Version 2 US Report.doc
+ */
+class LynkReconciliationFile {
+
+       const filenamePattern = '/^TranDetVer2_.*/';
+
+       protected $recordTypes;
+       protected $fileData = array( );
+
+       function __construct() {
+               $this->columnHeaders = array(
+                       'Record Type',
+                       // TODO: turns out this number is not actually unique, 
we are getting final zeroes
+                       'Reference Number',
+                       // TODO: This is documented but doesn't exist?
+                       // 'Lowest Defined User field',
+                       'Merchant Number',
+                       'Terminal ID',
+                       'Process Date',
+                       'Batch Number',
+                       'Sequence Number',
+                       'Card Network Type',
+                       'Transaction Type',
+                       // This is rounded to the nearest *day*.
+                       'Transaction Date Time',
+                       'Authorization Only',
+                       // Seems to be our best approximation of donation time.
+                       // TODO: I'm randomly and irresponsibly guessing this 
is in UTC.
+                       'Authorization Date Time',
+                       // Empty.
+                       'Card Payment Date',
+                       'Approval Code',
+                       'Settled Amount',
+                       'Dispensed Amount',
+                       'Cash Back Amount',
+                       'Surcharge Amount',
+                       'Original Authorized Amt',
+                       'Total Authorized Amount',
+                       'Complete Code',
+                       'Card Number',
+                       'Expiration Date',
+                       'Card Merchant Number',
+                       'Switch Network',
+                       'Authorized Network',
+                       'Authorized Code',
+                       'Authorized Type',
+                       'Authorized Response Code',
+                       'Response ACI',
+                       'Authorized Source Code',
+                       'VISA Trans Ref Num',
+                       'MC Banknet Data  ',
+                       'Validation Code',
+                       'AVS Response Code',
+                       'Capture Type',
+                       'POS Entry Mode',
+                       'POS Term Capability',
+                       'Card ID Method',
+                       'Industry Type',
+                       'Restaurant Server ID',
+                       'Restaurant Tip Amt',
+                       'Lodge Folio Number  ',
+                       'Lodge Arrival Date',
+                       'Lodge Departure Date',
+                       'Lodge No Show',
+                       'Lodge Stay Duration',
+                       'Lodge Local Phone  ',
+                       'Lodge Customer Service Phone',
+                       'Lodge Charge Description',
+                       'Lodge Room Rate',
+                       'Lodge Prestige Prop Indicator',
+                       'Merchant Order Number',
+               );
+       }
+
+       static function isMine( $path ) {
+               $filename = basename( $path );
+               return preg_match( self::filenamePattern, $filename );
+       }
+
+       function parse( $path ) {
+               $this->path = $path;
+               $this->file = fopen( $path, 'r' );
+
+               $ignoreLines = 2;
+               for ( $i = 0; $i < $ignoreLines; $i++ ) {
+                       fgets( $this->file );
+               }
+
+               while ( $line = fgetcsv( $this->file, 0, ',', '"', '\\' ) ) {
+                       try {
+                               $this->parseLine( $line );
+                       } catch ( NormalizationException $ex ) {
+                               Logger::error( $ex->getMessage() );
+                       }
+               }
+               fclose( $this->file );
+
+               return $this->fileData;
+       }
+
+       /**
+        * Parse one line.
+        */
+       protected function parseLine( $line ) {
+               if ( $line[0] === '3' ) {
+                       // Something like end-of-file.  Undocumented, but 
expected.
+                       return;
+               }
+
+               // Truncate row, cos we get differing numbers of zero columns 
after the
+               // known fields.
+               while ( count( $line ) > count( $this->columnHeaders ) ) {
+                       array_pop( $line );
+               }
+               $row = array_combine( $this->columnHeaders, $line );
+
+               $msg = $this->normalize( $row );
+               $this->fileData[] = $msg;
+       }
+
+       /**
+        * Normalize the pieces of the message that exist, according to the
+        * definition of a standard WMF queue message.
+        *
+        * Defaults should always be left up to the relevant queue consumer.
+        *
+        * See https://wikitech.wikimedia.org/wiki/Fundraising/Queue_messages
+        */
+       protected function normalize( $record ) {
+               $msg = array( );
+
+               switch ( $record['Transaction Type'] ) {
+               case 'Credit Sale':
+               case 'Credit Ticket':
+                       $queue = 'donations';
+                       break;
+               case 'Credit Return':
+               case 'Credit Refund':
+                       $queue = 'refund';
+                       break;
+               default:
+                       throw new NormalizationException( "Unknown transaction 
type: " . $record['Transaction Type'] );
+               }
+
+               $msg['date'] = strtotime( $record['Authorization Date Time'] . 
' UTC' );
+
+               $msg['gateway'] = 'worldpay';
+
+               // FIXME: Do we want to do anything about the missing '.0'?
+               $msg['gateway_txn_id'] = $record['Merchant Order Number'];
+
+               $msg['currency'] = 'USD';
+               $msg['gross'] = $record['Settled Amount'];
+
+               if ( $queue === 'refund' ) {
+                       $msg['gross_currency'] = $msg['currency'];
+                       $msg['gateway_parent_id'] = $msg['gateway_txn_id'];
+                       # Note that we do not have a new txn id for the refund
+                       $msg['gateway_refund_id'] = $msg['gateway_txn_id'];
+                       # FIXME: chargeback vs refund info is not available in 
this file.
+                       $msg['type'] = 'refund';
+                       return $msg;
+               }
+
+               $msg['payment_method'] = 'cc'; //this one is okay, because WP 
only does cc at this point. Maybe forever?
+               $msg['payment_submethod'] = $this->lookupCardType( 
$record['Card Network Type'] );
+
+               return $msg;
+       }
+
+       protected function lookupCardType( $rawType ) {
+               $mapping = array(
+                       'Visa' => 'visa',
+                       'MasterCard' => 'mc',
+                       'American Express NS' => 'amex',
+                       'Discover' => 'discover',
+               );
+
+               if ( array_key_exists( $rawType, $mapping ) ) {
+                       return $mapping[$rawType];
+               }
+
+               Logger::warning( "Unknown card type [{$rawType}]" );
+               return $rawType;
+       }
+}
+
+class NormalizationException extends Exception {
+}
diff --git a/PaymentProviders/WorldPay/Audit/WorldPayAudit.php 
b/PaymentProviders/WorldPay/Audit/WorldPayAudit.php
index d0efaca..d3f51fa 100644
--- a/PaymentProviders/WorldPay/Audit/WorldPayAudit.php
+++ b/PaymentProviders/WorldPay/Audit/WorldPayAudit.php
@@ -12,6 +12,7 @@
                // FIXME: this should be specified in configuration
                $fileTypes = array(
                        
'SmashPig\PaymentProviders\WorldPay\Audit\TransactionReconciliationFile',
+                       
'SmashPig\PaymentProviders\WorldPay\Audit\LynkReconciliationFile',
                );
 
                foreach ( $fileTypes as $type ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/177730
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I20d7fa469f4982da19626d432b7db1a4c394c54a
Gerrit-PatchSet: 6
Gerrit-Project: wikimedia/fundraising/SmashPig
Gerrit-Branch: master
Gerrit-Owner: Awight <[email protected]>
Gerrit-Reviewer: Awight <[email protected]>
Gerrit-Reviewer: Ejegg <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to