Mwalker has submitted this change and it was merged. Change subject: GlobalCollect listener ......................................................................
GlobalCollect listener Change-Id: I6320086b974761e4f13c4e7725ccdc40054c7d8a --- A PaymentProviders/GlobalCollect/Actions/IncomingMessage.php A PaymentProviders/GlobalCollect/ExpatriatedMessages/GlobalCollectMessage.php A PaymentProviders/GlobalCollect/ExpatriatedMessages/PaymentMessage.php A PaymentProviders/GlobalCollect/GlobalCollectListener.php A PaymentProviders/GlobalCollect/Messages/NormalizedMessage.php A PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentNoCCDetails.json A PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentWithCCDetails.json A PaymentProviders/GlobalCollect/Tests/inject.py M config_defaults.php 9 files changed, 241 insertions(+), 0 deletions(-) Approvals: Mwalker: Verified; Looks good to me, approved diff --git a/PaymentProviders/GlobalCollect/Actions/IncomingMessage.php b/PaymentProviders/GlobalCollect/Actions/IncomingMessage.php new file mode 100644 index 0000000..2163e70 --- /dev/null +++ b/PaymentProviders/GlobalCollect/Actions/IncomingMessage.php @@ -0,0 +1,23 @@ +<?php namespace SmashPig\PaymentProviders\GlobalCollect\Actions; + +use SmashPig\Core\Actions\IListenerMessageAction; +use SmashPig\Core\Configuration; +use SmashPig\Core\Messages\ListenerMessage; + +class IncomingMessage implements IListenerMessageAction { + public function execute( ListenerMessage $msg ) { + $destinationQueue = $msg->getDestinationQueue(); + + if ( $destinationQueue ) { + $queue = Configuration::getDefaultConfig()->obj( "data-store/{$destinationQueue}" ); + $queueMsg = $msg->normalizeForQueue(); + + $queue->addObject( $queueMsg ); + } else { + $class = get_class( $msg ); + Logger::warning( "Ignoring message of type {$class}", $msg ); + } + + return true; + } +} diff --git a/PaymentProviders/GlobalCollect/ExpatriatedMessages/GlobalCollectMessage.php b/PaymentProviders/GlobalCollect/ExpatriatedMessages/GlobalCollectMessage.php new file mode 100644 index 0000000..22bcf9b --- /dev/null +++ b/PaymentProviders/GlobalCollect/ExpatriatedMessages/GlobalCollectMessage.php @@ -0,0 +1,53 @@ +<?php namespace SmashPig\PaymentProviders\GlobalCollect\ExpatriatedMessages; + +use SmashPig\Core\Messages\ListenerMessage; +use SmashPig\PaymentProviders\GlobalCollect\Messages\NormalizedMessage; + +abstract class GlobalCollectMessage extends ListenerMessage { + + protected function getFieldInfo() { + $fieldInfo = array(); + foreach ( $this->fields as $key => $info ) { + // Allow mixed list/hash + if ( is_numeric( $key ) ) { + $key = $info; + $info = array(); + } + $fieldInfo[$key] = $info; + } + return $fieldInfo; + } + + public function constructFromValues( array $values ) { + foreach ( $this->getFieldInfo() as $key => $info ) { + $upperKey = str_replace( '_', '', strtoupper( $key ) ); + $this->$key = (array_key_exists( $upperKey, $values ) ? $values[$upperKey] : ''); + } + } + + /** + * Do common normalizations. Subclasses should perform normalizations + * specific to that message type. + * + * @return array associative queue message thing + */ + public function normalizeForQueue() { + $queueMsg = new NormalizedMessage(); + + foreach ( $this->getFieldInfo() as $key => $info ) { + $destKey = (array_key_exists( 'map', $info ) ? $info['map'] : $key ); + $queueMsg->$destKey = $this->$key; + } + + $queueMsg->gateway = 'globalcollect'; + $queueMsg->correlationId = "{$queueMsg->gateway}-{$queueMsg->order_id}"; + + return $queueMsg; + } + + public function validate() { + return !empty( $this->order_id ); + } + + abstract function getDestinationQueue(); +} diff --git a/PaymentProviders/GlobalCollect/ExpatriatedMessages/PaymentMessage.php b/PaymentProviders/GlobalCollect/ExpatriatedMessages/PaymentMessage.php new file mode 100644 index 0000000..17befeb --- /dev/null +++ b/PaymentProviders/GlobalCollect/ExpatriatedMessages/PaymentMessage.php @@ -0,0 +1,38 @@ +<?php namespace SmashPig\PaymentProviders\GlobalCollect\ExpatriatedMessages; + +class PaymentMessage extends GlobalCollectMessage { + protected $additional_reference; + protected $amount; + protected $attempt_id; + protected $currency_code; + protected $effort_id; + protected $merchant_id; + protected $order_id; + protected $payment_method_id; + protected $payment_product_id; + protected $payment_reference; + protected $received_date; + protected $status_date; + protected $status_id; + + protected $fields = array( + 'additional_reference', + 'amount' => array('map' => 'gross'), + 'attempt_id', + 'currency_code' => array('map' => 'currency'), + 'effort_id', + 'merchant_id', + 'order_id', + 'payment_method_id', + 'payment_product_id' => array('map' => 'payment_product'), + 'payment_reference', + 'received_date' => array('map' => 'date'), + 'status_date', + 'status_id', + ); + + public function getDestinationQueue() { + // XXX + return 'verified'; + } +} diff --git a/PaymentProviders/GlobalCollect/GlobalCollectListener.php b/PaymentProviders/GlobalCollect/GlobalCollectListener.php new file mode 100644 index 0000000..830316a --- /dev/null +++ b/PaymentProviders/GlobalCollect/GlobalCollectListener.php @@ -0,0 +1,47 @@ +<?php namespace SmashPig\PaymentProviders\GlobalCollect; + +use SmashPig\Core\Http\Request; +use SmashPig\Core\Messages\ListenerMessage; +use SmashPig\Core\Listeners\ListenerSecurityException; +use SmashPig\Core\Listeners\RestListener; +use SmashPig\Core\Logging\Logger; + +use SmashPig\PaymentProviders\GlobalCollect\ExpatriatedMessages\PaymentMessage; + +/** + * Dispatches incoming messages accoring to type + */ +class GlobalCollectListener extends RestListener { + protected $success = false; + + protected function parseEnvelope( Request $request ) { + $message = new PaymentMessage(); + $message->constructFromValues( $request->getValues() ); + + $this->success = true; + + return array( $message ); + } + + /** + * Stub-- maybe this is an egregious pure virtual function + */ + protected function ackMessage( ListenerMessage $msg ) { + return true; + } + + protected function ackEnvelope() { + if ( $this->success ) { + $this->response->setContent( "OK\n" ); + } else { + $this->response->setContent( "NOK\n" ); + } + } + + /** + * Stub -- should be implemented using SSL client cert + */ + protected function doMessageSecurity( ListenerMessage $msg ) { + return true; + } +} diff --git a/PaymentProviders/GlobalCollect/Messages/NormalizedMessage.php b/PaymentProviders/GlobalCollect/Messages/NormalizedMessage.php new file mode 100644 index 0000000..4aa5669 --- /dev/null +++ b/PaymentProviders/GlobalCollect/Messages/NormalizedMessage.php @@ -0,0 +1,10 @@ +<?php namespace SmashPig\PaymentProviders\GlobalCollect\Messages; + +use SmashPig\Core\DataStores\KeyedOpaqueStorableObject; + +/** + * FIXME: this is lame + */ +class NormalizedMessage extends KeyedOpaqueStorableObject { + +} diff --git a/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentNoCCDetails.json b/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentNoCCDetails.json new file mode 100644 index 0000000..78efd23 --- /dev/null +++ b/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentNoCCDetails.json @@ -0,0 +1,19 @@ +{ + "MERCHANTID": "9991", + "ORDERID": "12345678", + "EFFORTID": "1", + "ATTEMPTID": "1", + "PAYMENTREFERENCE": "0", + "ADDITIONALREFERENCE": "1234567890", + "PAYMENTMETHODID": "1", + "PAYMENTPRODUCTID": "3", + "STATUSID": "625", + "STATUSDATE": "20120314144539", + "RECEIVEDDATE": "20120314144334", + "CURRENCYCODE": "EUR", + "AMOUNT": "1000", + "CVVRESULT": "0", + "FRAUDRESULT": "A", + "CCLASTFOURDIGITS": "1111", + "EXPIRYDATE": "0113" +} diff --git a/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentWithCCDetails.json b/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentWithCCDetails.json new file mode 100644 index 0000000..9159b5c --- /dev/null +++ b/PaymentProviders/GlobalCollect/Tests/Data/PSC/PaymentWithCCDetails.json @@ -0,0 +1,15 @@ +{ + "MERCHANTID": "9991", + "ORDERID": "98765432", + "EFFORTID": "1", + "ATTEMPTID": "2", + "PAYMENTREFERENCE": "999101111119", + "ADDITIONALREFERENCE": "911121242154", + "PAYMENTMETHODID": "7", + "PAYMENTPRODUCTID": "11", + "STATUSID": "800", + "STATUSDATE": "20120314143420", + "RECEIVEDDATE": "20120314143420", + "CURRENCYCODE": "EUR", + "AMOUNT": "150" +} diff --git a/PaymentProviders/GlobalCollect/Tests/inject.py b/PaymentProviders/GlobalCollect/Tests/inject.py new file mode 100755 index 0000000..0a330eb --- /dev/null +++ b/PaymentProviders/GlobalCollect/Tests/inject.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import sys +import urllib +import urllib2 +import json + +if len(sys.argv) < 4: + print """arguments: host path file [httpauthuser:password] +For example: + ./inject.py listeners.localweb /smashpig/globalcollect/listener Tests/Data/PSC/PaymentNoCCDetails.json +""" + exit(-1) + +headers = {} +if len(sys.argv) > 4: + import base64 + auth = base64.encodestring(sys.argv[4]).replace("\n", "") + headers['Authorization'] = "Basic " + auth + +data = urllib.urlencode(json.load(open(sys.argv[3], "r"))) + +req = urllib2.Request("http://%s%s" % (sys.argv[1], sys.argv[2]), data, headers) +out = urllib2.urlopen(req) +print "Output: ", out.read() diff --git a/config_defaults.php b/config_defaults.php index 2d21317..4b0e48b 100644 --- a/config_defaults.php +++ b/config_defaults.php @@ -146,6 +146,17 @@ ), 'globalcollect' => array( + 'actions' => array( + 'SmashPig\PaymentProviders\GlobalCollect\Actions\IncomingMessage', + ), + + 'endpoints' => array( + 'listener' => array( + 'class' => 'SmashPig\PaymentProviders\GlobalCollect\GlobalCollectListener', + 'inst-args' => array(), + ) + ), + 'data-store' => array( 'stomp' => array( 'queues' => array( -- To view, visit https://gerrit.wikimedia.org/r/94086 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6320086b974761e4f13c4e7725ccdc40054c7d8a Gerrit-PatchSet: 3 Gerrit-Project: wikimedia/fundraising/SmashPig Gerrit-Branch: master Gerrit-Owner: Adamw <awi...@wikimedia.org> Gerrit-Reviewer: Mwalker <mwal...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits