Adamw has uploaded a new change for review. https://gerrit.wikimedia.org/r/60958
Change subject: WIP: Amazon IPN listener ...................................................................... WIP: Amazon IPN listener Change-Id: Ie0bee461a0b904f38bce73678294e77392493190 --- M SmashPig/Core/Http/Request.php M SmashPig/Core/Listeners/ListenerBase.php M SmashPig/Core/Listeners/RestListener.php A SmashPig/PaymentProviders/Amazon/AmazonListener.php A SmashPig/PaymentProviders/Amazon/Messages/AmazonMessage.php A SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCanceled.php A SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCompleted.php A SmashPig/PaymentProviders/Amazon/Messages/SubscriptionSuccessful.php 8 files changed, 179 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/PaymentsListeners refs/changes/58/60958/1 diff --git a/SmashPig/Core/Http/Request.php b/SmashPig/Core/Http/Request.php index bae378e..cc1a328 100644 --- a/SmashPig/Core/Http/Request.php +++ b/SmashPig/Core/Http/Request.php @@ -5,7 +5,21 @@ } + /** + * Get post data without interpretation + * + * @return string + */ public function getRawPostData() { return file_get_contents( 'php://input' ); } + + /** + * Get all post data as an associative array + * + * @return array + */ + public function getValues() { + return $_POST; + } } diff --git a/SmashPig/Core/Listeners/ListenerBase.php b/SmashPig/Core/Listeners/ListenerBase.php index ab681c7..491d082 100644 --- a/SmashPig/Core/Listeners/ListenerBase.php +++ b/SmashPig/Core/Listeners/ListenerBase.php @@ -133,7 +133,7 @@ return false; } } catch ( \Exception $ex ) { - + Logger::error( 'Failed message security check: ' . $ex->getMessage() ); } // We caught exceptions: therefore the message was not correctly processed. diff --git a/SmashPig/Core/Listeners/RestListener.php b/SmashPig/Core/Listeners/RestListener.php index 1520c52..2dc1dc6 100644 --- a/SmashPig/Core/Listeners/RestListener.php +++ b/SmashPig/Core/Listeners/RestListener.php @@ -44,17 +44,17 @@ } /** - * Parse the raw data from the web request and turn it into an array of message objects. This - * function should not return an exception unless the configuration data is malformed. If an - * individual message element in the envelope is malformed this function should log it and - * continue as normal. + * Parse the web request and turn it into an array of message objects. + * + * This function should not throw an exception strictly caused by message + * contents. If an individual message in the envelope is malformed, this + * function should log it and continue as normal. * - * @param string $data Raw web-request data + * @param Request $request Raw web-request * * @throws ListenerConfigException - * @throws ListenerDataException * - * @return mixed Array of @see Message + * @return array of @see Message */ abstract protected function parseEnvelope( Request $request ); diff --git a/SmashPig/PaymentProviders/Amazon/AmazonListener.php b/SmashPig/PaymentProviders/Amazon/AmazonListener.php new file mode 100644 index 0000000..af1de3e --- /dev/null +++ b/SmashPig/PaymentProviders/Amazon/AmazonListener.php @@ -0,0 +1,51 @@ +<?php namespace SmashPig\PaymentProviders\Amazon; + +use SmashPig\Core\Messages\ListenerMessage; +use SmashPig\Core\Listeners\ListenerSecurityException; +use SmashPig\Core\Logging\Logger; + +/** + * Dispatches incoming messages accoring to type + */ +class AmazonListener extends RestListener { + protected $types = array( + 'TransactionStatus' => 'SmashPig\PaymentProviders\Amazon\Messages\TransactionStatus', + 'TokenCancellation' => 'SmashPig\PaymentProviders\Amazon\Messages\TokenCancellation', + ); + + protected function parseEnvelope( Request $request ) { + $requestValues = $request->getValues(); + $messages = array(); + if ( array_key_exists( 'notificationType', $requestValues ) ) { + $type = $requestValues['notificationType']; + if ( array_key_exists( $type, $this->types ) ) { + $klass = $this->types[$type]; + $message = new $klass(); + $message->constructFromValues($requestValues); + $messages[] = $message; + } + } + return $messages; + } + + /** + * Validate message signature + * + * @param ListenerMessage $msg Message object to operate on + * + * @throws ListenerSecurityException on security violation + */ + protected function doMessageSecurity( ListenerMessage $msg ) { + if ( !AmazonAPI::verifySignature( $msg->getRawValues() ) ) { + throw new ListenerSecurityException(); + } + return true; + } + + /** + * Stub-- maybe this is an egregious abstract function + */ + protected function ackMessage( ListenerMessage $msg ) { + return true; + } +} diff --git a/SmashPig/PaymentProviders/Amazon/Messages/AmazonMessage.php b/SmashPig/PaymentProviders/Amazon/Messages/AmazonMessage.php new file mode 100644 index 0000000..6a0b9db --- /dev/null +++ b/SmashPig/PaymentProviders/Amazon/Messages/AmazonMessage.php @@ -0,0 +1,27 @@ +<?php namespace SmashPig\PaymentProviders\Amazon\Messages; + +use SmashPig\Core\Messages\ListenerMessage; + +class AmazonMessage extends ListenerMessage { + + protected $rawValues = array(); + + /** + * TODO: We only want to use this for signature validation, perhaps + * it can be made more specific to that, especially since Host and URL + * should be pulled from the Request anyway. + * + * @return array of incoming message params. + */ + public function getRawValues() { + return $this->rawValues; + } + + public function constructFromValues( array $values ) { + $this->rawValues = $values; + + foreach ( $this->fields as $key ) { + $this->$key = ( array_key_exists( $key, $values ) ? $values[$key] : ''; + } + } +} diff --git a/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCanceled.php b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCanceled.php new file mode 100644 index 0000000..ef79943 --- /dev/null +++ b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCanceled.php @@ -0,0 +1,12 @@ +<?php namespace SmashPig\PaymentProviders\Amazon\Messages; + +class SubscriptionCanceled extends AmazonMessage { + protected $fields = array( + 'status', + 'statusReason', + 'subscriptionId', + ); + protected $status; + protected $statusReason; + protected $subscriptionId; +} diff --git a/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCompleted.php b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCompleted.php new file mode 100644 index 0000000..98e25f3 --- /dev/null +++ b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionCompleted.php @@ -0,0 +1,10 @@ +<?php namespace SmashPig\PaymentProviders\Amazon\Messages; + +class SubscriptionCompleted extends AmazonMessage { + protected $fields = array( + 'status', + 'subscriptionId', + ); + protected $status; + protected $subscriptionId; +} diff --git a/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionSuccessful.php b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionSuccessful.php new file mode 100644 index 0000000..4b85889 --- /dev/null +++ b/SmashPig/PaymentProviders/Amazon/Messages/SubscriptionSuccessful.php @@ -0,0 +1,57 @@ +<?php namespace SmashPig\PaymentProviders\Amazon\Messages; + +class SubscriptionSuccessful extends AmazonMessage { + //FIXME: it is not ideal to list the fields twice. + protected $fields = array( + 'addressLine1', + 'addressLine2', + 'addressName', + 'buyerEmail', + 'buyerName', + 'city', + 'country', + 'noOfPromotionTransactions', + 'paymentMethod', + 'paymentReason', + 'phoneNumber', + 'promotionAmount', + 'recipientEmail', + 'recipientName', + 'recurringFrequency', + 'referenceId', + 'signature', + 'startValidityDate', + 'state', + 'status', + 'subscriptionId', + 'subsciptionPeriod', + 'transactionAmount', + 'transactionSerialNumber', + 'zip', + ); + protected $addressLine1; + protected $addressLine2; + protected $addressName; + protected $buyerEmail; + protected $buyerName; + protected $city; + protected $country; + protected $noOfPromotionTransactions; + protected $paymentMethod; + protected $paymentReason; + protected $phoneNumber; + protected $promotionAmount; + protected $recipientEmail; + protected $recipientName; + protected $recurringFrequency; + protected $referenceId; + protected $signature; + protected $startValidityDate; + protected $state; + protected $status; + protected $subscriptionId; + protected $subsciptionPeriod; + protected $transactionAmount; + protected $transactionSerialNumber; + protected $zip; +} -- To view, visit https://gerrit.wikimedia.org/r/60958 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie0bee461a0b904f38bce73678294e77392493190 Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/PaymentsListeners Gerrit-Branch: master Gerrit-Owner: Adamw <awi...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits