Ejegg has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/368948 )
Change subject: WIP Ingenico WX audit parsing ...................................................................... WIP Ingenico WX audit parsing Code copied over from I1eed97f975617706e9 Bug: T86090 Change-Id: Ie85c11fca0f4155359361119420fca6325f5bb9b --- A PaymentProviders/Ingenico/Audit/IngenicoAudit.php A PaymentProviders/Ingenico/Tests/Data/chargeback.xml.gz A PaymentProviders/Ingenico/Tests/Data/donation.xml.gz A PaymentProviders/Ingenico/Tests/Data/refund.xml.gz 4 files changed, 186 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/SmashPig refs/changes/48/368948/1 diff --git a/PaymentProviders/Ingenico/Audit/IngenicoAudit.php b/PaymentProviders/Ingenico/Audit/IngenicoAudit.php new file mode 100644 index 0000000..fd58434 --- /dev/null +++ b/PaymentProviders/Ingenico/Audit/IngenicoAudit.php @@ -0,0 +1,186 @@ +<?php namespace SmashPig\PaymentProviders\Ingenico\Audit; + +use DOMDocument; +use DOMElement; +use SmashPig\Core\Logging\Logger; + +class IngenicoAudit { + + protected $fileData = array(); + + protected $nodemap = array( + 'Recordcategory' => 'gc_category', + 'Recordtype' => 'gc_type', + 'Amount' => 'gross', + 'IPAddressCustomer' => 'user_ip', + 'BillingFirstname' => 'first_name', + 'BillingSurname' => 'last_name', + 'BillingStreet' => 'street_address', + 'BillingCity' => 'city', + 'ZipCode' => 'postal_code', + 'BillingCountryCode' => 'country', + 'BillingEmail' => 'email', + 'AdditionalReference' => 'contribution_tracking_id', // will need to trim everything after the dot, but it's there! Woooooo. + 'PaymentMethodId' => 'gc_method_id', // wut + 'PaymentProductId' => 'gc_product_id', // ...wut? + 'PaymentGroupId' => 'gc_group_id', // But seriously. WUT. + 'OrderID' => 'order_id', + 'PaymentCurrency' => 'currency', + 'AmountLocal' => 'gross', + 'TransactionDateTime' => 'datetime', // damn it. + ); + + protected $identifiers_we_can_cope_with = array( + // Credit card item that has been processed, but not settled. + // We take these seriously. + // TODO: Why aren't we waiting for +ON? + 'XON' => 'new', + // Settled "Invoice Payment". Could be invoice, bt, rtbt, check, + // prepaid card, ew, cash + '+IP' => 'new', + '-CB' => 'chargeback', // Credit card chargeback + '-CR' => 'refund', // Credit card refund + '+AP' => 'new', // Direct Debit collected + ); + + public function parseFile( $path ) { + $unzippedFullPath = $this->getUnzippedFile( $path ); + + // load the XML into a domdocument. + // Total Memory Hog Alert. Handle with care. + $domDoc = new DomDocument( '1.0' ); + Logger::info( "Loading XML from $unzippedFullPath" ); + $domDoc->load( $unzippedFullPath ); + Logger::info( "Processing" ); + + foreach ( $domDoc->getElementsByTagName( 'DataRecord' ) as $recordnode ) { + $this->parseRecord( $recordnode ); + } + + return $this->fileData; + } + + protected function parseRecord( DOMElement $recordNode ) { + // So, first things first. There is a TOTAL LOAD of data in this file + // that we genuinely don't care about at all. We're going to have to + // figure out how to distill this list in a reasonable way. + $temp = array(); + + foreach ( $this->nodemap as $theirs => $ours ) { + foreach ( $recordNode->getElementsByTagName( $theirs ) as $recorditem ) { + $temp[$ours] = $recorditem->nodeValue; // there 'ya go: Normal already. + } + } + + $record_type_identifier = $temp['gc_category'] . $temp['gc_type']; + + if ( !array_key_exists( $record_type_identifier, $this->identifiers_we_can_cope_with ) ) { + return; + } + $temp['type'] = $this->identifiers_we_can_cope_with[$record_type_identifier]; + + $temp = $this->addPaymentMethod( $temp ); + + $this->fileData[] = $temp; + } + + /** + * Gets our normalized payment_method and payment_submethod params from the + * codes that GC uses + * @param array $record The record from the wx file, in array format + * @return array The $record param with our normal keys appended + */ + function addPaymentMethod( $record ) { + // FIXME: move payment_submethods.yaml to ingenico config dir, use that + // everywhere + + $payment_products = array( + '1' => array( 'payment_method' => 'cc', 'payment_submethod' => 'visa' ), + '2' => array( 'payment_method' => 'cc', 'payment_submethod' => 'amex' ), + '3' => array( 'payment_method' => 'cc', 'payment_submethod' => 'mc' ), + '11' => array( 'payment_method' => 'bt', 'payment_submethod' => 'bt' ), + '117' => array( 'payment_method' => 'cc', 'payment_submethod' => 'maestro' ), + '118' => array( 'payment_method' => 'cc', 'payment_submethod' => 'solo' ), + '124' => array( 'payment_method' => 'cc', 'payment_submethod' => 'laser' ), + '125' => array( 'payment_method' => 'cc', 'payment_submethod' => 'jcb' ), + '128' => array( 'payment_method' => 'cc', 'payment_submethod' => 'discover' ), + '130' => array( 'payment_method' => 'cc', 'payment_submethod' => 'cb' ), + '500' => array( 'payment_method' => 'obt', 'payment_submethod' => 'bpay' ), + '701' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_nl' ), + '702' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_de' ), + '703' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_at' ), + '704' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_fr' ), + '705' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_gb' ), + '706' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_be' ), + '707' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_ch' ), + '708' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_it' ), + '709' => array( 'payment_method' => 'dd', 'payment_submethod' => 'dd_es' ), + '805' => array( 'payment_method' => 'rtbt', 'payment_submethod' => 'rtbt_nordea_sweden' ), + '809' => array( 'payment_method' => 'rtbt', 'payment_submethod' => 'rtbt_ideal' ), + '810' => array( 'payment_method' => 'rtbt', 'payment_submethod' => 'rtbt_enets' ), + '836' => array( 'payment_method' => 'rtbt', 'payment_submethod' => 'rtbt_sofortuberweisung' ), + '840' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_paypal' ), + '841' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_webmoney' ), + '843' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_moneybookers' ), + '845' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_cashu' ), + '849' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_yandex' ), + '856' => array( 'payment_method' => 'rtbt', 'payment_submethod' => 'rtbt_eps' ), + '861' => array( 'payment_method' => 'ew', 'payment_submethod' => 'ew_alipay' ), + '1503' => array( 'payment_method' => 'cash', 'payment_submethod' => 'cash_boleto' ), + ); + + if ( array_key_exists( $record['gc_product_id'], $payment_products ) ) { + $record = array_merge( $record, $payment_products[$record['gc_product_id']] ); + } else { + Logger::error( + __FUNCTION__ . ': No payment product found for code ' . $record['gc_product_id'], + 'MISSING_MANDATORY_DATA' + ); + } + + return $record; + } + + /** + * @param $path + * @return bool|string // FIXME: Exception? + */ + protected function getUnzippedFile( $path ) { + $zippedParts = explode( DIRECTORY_SEPARATOR, $path ); + $zippedFilename = array_pop( $zippedParts ); + // TODO keep unzipped files around? + $workingDirectory = sys_get_temp_dir(); + // whack the .gz on the end + $unzippedFilename = substr( $zippedFilename, 0, strlen( $zippedFilename ) - 3 ); + + $copiedZipPath = $workingDirectory . $zippedFilename; + if ( !file_exists( $copiedZipPath ) ) { + copy( $path, $copiedZipPath ); + if ( !file_exists( $copiedZipPath ) ) { + Logger::error( + "FILE PROBLEM: Trying to copy $path to $copiedZipPath " . + 'for decompression, and something went wrong' + ); + return false; + } + } + + $unzippedFullPath = $workingDirectory . $unzippedFilename; + if ( !file_exists( $unzippedFullPath ) ) { + // decompress + Logger::info( "Gunzipping $copiedZipPath" ); + // FIXME portability + $cmd = "gunzip -f $copiedZipPath"; + exec( escapeshellcmd( $cmd ) ); + // now check to make sure the file you expect actually exists + if ( !file_exists( $unzippedFullPath ) ) { + Logger::error( + 'FILE PROBLEM: Something went wrong with decompressing WX file: ' . + "$cmd : $unzippedFullPath doesn't exist." + ); + return false; + } + } + return $unzippedFullPath; + } +} diff --git a/PaymentProviders/Ingenico/Tests/Data/chargeback.xml.gz b/PaymentProviders/Ingenico/Tests/Data/chargeback.xml.gz new file mode 100644 index 0000000..b38a947 --- /dev/null +++ b/PaymentProviders/Ingenico/Tests/Data/chargeback.xml.gz Binary files differ diff --git a/PaymentProviders/Ingenico/Tests/Data/donation.xml.gz b/PaymentProviders/Ingenico/Tests/Data/donation.xml.gz new file mode 100644 index 0000000..55ee9de --- /dev/null +++ b/PaymentProviders/Ingenico/Tests/Data/donation.xml.gz Binary files differ diff --git a/PaymentProviders/Ingenico/Tests/Data/refund.xml.gz b/PaymentProviders/Ingenico/Tests/Data/refund.xml.gz new file mode 100644 index 0000000..8fc709c --- /dev/null +++ b/PaymentProviders/Ingenico/Tests/Data/refund.xml.gz Binary files differ -- To view, visit https://gerrit.wikimedia.org/r/368948 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie85c11fca0f4155359361119420fca6325f5bb9b Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/SmashPig Gerrit-Branch: master Gerrit-Owner: Ejegg <ej...@ejegg.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits