Mwalker has submitted this change and it was merged.

Change subject: Amazon IPN listener
......................................................................


Amazon IPN listener

The only fully implemented message types are:
* SubscriptionSuccessful
* PS / SubscriptionPaymentSuccessful

Change-Id: Ie0bee461a0b904f38bce73678294e77392493190
---
A SmashPig/PaymentProviders/Amazon/Actions/IncomingMessage.php
A SmashPig/PaymentProviders/Amazon/AmazonAPI.php
A SmashPig/PaymentProviders/Amazon/AmazonListener.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/AmazonMessage.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentFailed.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentInitiated.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentRescheduled.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentReversed.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentSuccess.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PendingUserAction.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundFailed.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundSuccessful.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCancelled.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCompleted.php
A 
SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentCancelled.php
A 
SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentSuccess.php
A 
SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionSuccessful.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TokenCancellation.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionCommon.php
A SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionStatus.php
A SmashPig/PaymentProviders/Amazon/Messages/NormalizedMessage.php
A 
SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionPaymentSuccess.json
A SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionSuccessful.json
A SmashPig/PaymentProviders/Amazon/Tests/inject.py
M SmashPig/config_defaults.php
25 files changed, 595 insertions(+), 0 deletions(-)

Approvals:
  Mwalker: Verified; Looks good to me, approved



diff --git a/SmashPig/PaymentProviders/Amazon/Actions/IncomingMessage.php 
b/SmashPig/PaymentProviders/Amazon/Actions/IncomingMessage.php
new file mode 100644
index 0000000..b92cc6e
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/Actions/IncomingMessage.php
@@ -0,0 +1,24 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\Actions;
+
+use SmashPig\Core\Actions\IListenerMessageAction;
+use SmashPig\Core\Configuration;
+use SmashPig\Core\Messages\ListenerMessage;
+
+class IncomingMessage implements IListenerMessageAction {
+       public function execute( ListenerMessage $msg ) {
+               //FIXME: I don't like this dispatch style
+               $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/SmashPig/PaymentProviders/Amazon/AmazonAPI.php 
b/SmashPig/PaymentProviders/Amazon/AmazonAPI.php
new file mode 100644
index 0000000..21ccfcc
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/AmazonAPI.php
@@ -0,0 +1,43 @@
+<? namespace SmashPig\PaymentProviders\Amazon;
+
+// TODO we are currently ignoring signatures ;)
+// ... this implementation is very not functional
+class AmazonAPI {
+       static public function verifySignature( $values ) {
+               return true;
+               // FUBAR
+
+               $incomingSignature = $values['signature'];
+               unset( $values['signature'] );
+               $incomingParams = http_build_query( $values, '', '&' );
+
+               $requestParams = array(
+                       'Action' => "VerifySignature",
+                       'HttpParameters' => $incomingParams,
+                       'SignatureMethod' => "HmacSHA256",
+                       'SignatureVersion' => "2",
+                       'Timestamp' => date( 'c' ),
+                       'Version' => "2010-08-28",
+               );
+
+               ksort( $requestParams );
+
+               $secret_key = $this->account_config[ "SecretKey" ];
+
+               $query_str = $this->encodeQuery( $params );
+               $path_encoded = str_replace( "%2F", "/", rawurlencode( $path ) 
);
+
+               $message = "GET\n{$host}\n{$path_encoded}\n{$query_str}";
+
+               $signature = self::signRequest( $parsed_uri[ 'host' ], 
$parsed_uri[ 'path' ], $query );
+               rawurlencode( base64_encode( hash_hmac( 'sha256', $message, 
$secret_key, TRUE ) ) );
+
+               //'url' => $this->getGlobal( "FpsURL" ),
+               $url .= "?{$query_str}&Signature={$signature}";
+
+               self::doRequest( $url );
+
+               //      'AWSAccessKeyId' => $this->account_config[ 'AccessKey' 
],
+               //      'UrlEndPoint' => $this->getGlobal( "ReturnURL" ),
+       }
+}
diff --git a/SmashPig/PaymentProviders/Amazon/AmazonListener.php 
b/SmashPig/PaymentProviders/Amazon/AmazonListener.php
new file mode 100644
index 0000000..ab2aa3b
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/AmazonListener.php
@@ -0,0 +1,89 @@
+<?php namespace SmashPig\PaymentProviders\Amazon;
+
+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\Amazon\ExpatriatedMessages as MsgDefs;
+
+/**
+ * Dispatches incoming messages accoring to type
+ */
+class AmazonListener extends RestListener {
+       protected $byTypes = array(
+               'TransactionStatus' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\TransactionStatus',
+               'TokenCancellation' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\TokenCancellation',
+       );
+
+       protected $byStatus = array(
+               'PS' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PaymentSuccess',
+               'PF' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PaymentFailed',
+               'PI' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PaymentInitiated',
+               'PR' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PaymentReversed',
+               'RS' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\RefundSuccessful',
+               'RF' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\RefundFailed',
+               'PaymentSuccess' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\SubscriptionPaymentSuccess',
+               'PendingUserAction' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PendingUserAction',
+               'PaymentRescheduled' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\PaymentRescheduled',
+               'PaymentCancelled' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\SubscriptionPaymentCancelled',
+               'SubscriptionCancelled' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\SubscriptionCancelled',
+               'SubscriptionCompleted' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\SubscriptionCompleted',
+               'SubscriptionSuccessful' => 
'SmashPig\PaymentProviders\Amazon\ExpatriatedMessages\SubscriptionSuccessful',
+       );
+
+       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->byType ) ) {
+                               $klass = $this->byType[$type];
+                               $message = new $klass();
+                               $message->constructFromValues($requestValues);
+
+                               $messages[] = $message;
+                       } else {
+                               Logger::info( "Message ignored: 
notificationType = {$type}" );
+                       }
+               } elseif ( array_key_exists( 'status', $requestValues ) ) {
+                       $status = $requestValues['status'];
+                       if ( array_key_exists( $status, $this->byStatus ) ) {
+                               $klass = $this->byStatus[$status];
+                               $message = new $klass();
+                               $message->constructFromValues($requestValues);
+                               $messages[] = $message;
+                       } else {
+                               Logger::info( "Message ignored: status = 
{$status}" );
+                       }
+               }
+
+               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 pure virtual function
+        */
+       protected function ackMessage( ListenerMessage $msg ) {
+               return true;
+       }
+
+       protected function ackEnvelope() {
+               //pass
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/AmazonMessage.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/AmazonMessage.php
new file mode 100644
index 0000000..26f12f2
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/AmazonMessage.php
@@ -0,0 +1,55 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+use SmashPig\Core\Messages\ListenerMessage;
+use SmashPig\PaymentProviders\Amazon\Messages\NormalizedMessage;
+
+abstract 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] : '');
+               }
+
+               // FIXME: temporary thing to help with dequeuing from "pending"
+               $this->correlationId = mt_rand( 100000000, 999999999 );
+       }
+
+       /**
+        * Do common normalizations.  Subclasses should perform normalizations
+        * specific to that message type.
+        *
+        * @return array associative queue message thing
+        */
+       public function normalizeForQueue() {
+               $queueMsg = new NormalizedMessage();
+
+               $queueMsg->gateway = 'amazon';
+
+               return $queueMsg;
+       }
+
+       public function getDestinationQueue() {
+               //stub
+               return null;
+       }
+
+       public function validate() {
+               //return AmazonAPI::validateSignature( 
+               return true;
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentFailed.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentFailed.php
new file mode 100644
index 0000000..39766b4
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentFailed.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PaymentFailed extends TransactionCommon {
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentInitiated.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentInitiated.php
new file mode 100644
index 0000000..ab71c24
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentInitiated.php
@@ -0,0 +1,5 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PaymentInitiated extends TransactionCommon {
+
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentRescheduled.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentRescheduled.php
new file mode 100644
index 0000000..6f31fd0
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentRescheduled.php
@@ -0,0 +1,5 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PaymentRescheduled extends TransactionCommon {
+
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentReversed.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentReversed.php
new file mode 100644
index 0000000..cccaca4
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentReversed.php
@@ -0,0 +1,5 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PaymentReversed extends TransactionCommon {
+
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentSuccess.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentSuccess.php
new file mode 100644
index 0000000..13bdfdd
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PaymentSuccess.php
@@ -0,0 +1,7 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PaymentSuccess extends TransactionCommon {
+       public function getDestinationQueue() {
+               return 'verified';
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PendingUserAction.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PendingUserAction.php
new file mode 100644
index 0000000..0230dd5
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/PendingUserAction.php
@@ -0,0 +1,5 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class PendingUserAction extends TransactionCommon {
+
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundFailed.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundFailed.php
new file mode 100644
index 0000000..5bba7f4
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundFailed.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class RefundFailed extends TransactionCommon {
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundSuccessful.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundSuccessful.php
new file mode 100644
index 0000000..95bbea6
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/RefundSuccessful.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class RefundSuccessful extends TransactionCommon {
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCancelled.php
 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCancelled.php
new file mode 100644
index 0000000..8b0e2e8
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCancelled.php
@@ -0,0 +1,12 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class SubscriptionCanceled extends AmazonMessage {
+       protected $fields = array(
+               'status',
+               'statusReason',
+               'subscriptionId',
+       );
+       protected $status;
+       protected $statusReason;
+       protected $subscriptionId;
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCompleted.php
 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCompleted.php
new file mode 100644
index 0000000..85fe73b
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionCompleted.php
@@ -0,0 +1,10 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class SubscriptionCompleted extends AmazonMessage {
+       protected $fields = array(
+               'status',
+               'subscriptionId',
+       );
+       protected $status;
+       protected $subscriptionId;
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentCancelled.php
 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentCancelled.php
new file mode 100644
index 0000000..0c2968d
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentCancelled.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class SubscriptionPaymentCancelled extends TransactionCommon {
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentSuccess.php
 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentSuccess.php
new file mode 100644
index 0000000..6ea9d95
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionPaymentSuccess.php
@@ -0,0 +1,7 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class SubscriptionPaymentSuccess extends TransactionCommon {
+       public function getDestinationQueue() {
+               return 'verified';
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionSuccessful.php
 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionSuccessful.php
new file mode 100644
index 0000000..f274687
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/SubscriptionSuccessful.php
@@ -0,0 +1,112 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+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',
+               'subscriptionPeriod',
+               '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 $subscriptionPeriod;
+       protected $transactionAmount;
+       protected $transactionSerialNumber;
+       protected $zip;
+
+       public function getDestinationQueue() {
+               return 'verified';
+       }
+
+       public function normalizeForQueue() {
+               $queueMsg = parent::normalizeForQueue();
+
+               if ( strtolower($this->recurringFrequency) === '1 month' ) {
+                       $frequency_unit = "month";
+                       $frequency_interval = 1;
+               } else {
+                       throw new SmashPigException( "Unhandled subscription 
interval, {$this->recurringFrequency}" );
+               }
+
+               if ( !$this->subscriptionPeriod or strtolower( 
$this->subscriptionPeriod ) === "forever" ) {
+                       $installments = 0;
+               } else {
+                       if ( preg_match( "/^(\d+) months?$/i", 
$this->subscriptionPeriod, $matches ) ) {
+                               $installments = $matches[1];
+                       } else {
+                               throw new SmashPigException( "Unhandled 
subscription period, {$this->subscriptionPeriod}" );
+                       }
+               }
+
+               if ( preg_match( "/^([A-Z]{3}) ([0-9.]+)$/", 
$this->transactionAmount, $matches ) ) {
+                       $currency = $matches[1];
+                       $amount = $matches[2];
+               } else {
+                       throw new SmashPigException( "Unhandled transaction 
amount , {$this->transactionAmount}" );
+               }
+
+               $queueMsg->gateway_txn_id = $this->subscriptionId;
+               $queueMsg->txn_type = 'subscr_signup';
+               $queueMsg->last_name = $this->buyerName;
+               $queueMsg->email = $this->buyerEmail;
+               $queueMsg->street_address = $this->addressLine1;
+               $queueMsg->supplemental_address_1 = $this->addressLine2;
+               $queueMsg->city = $this->city;
+               $queueMsg->state_province = $this->state;
+               $queueMsg->country = $this->country;
+               $queueMsg->postal_code = $this->zip;
+               $queueMsg->currency = $currency;
+               $queueMsg->amount = $amount;
+               $queueMsg->frequency_unit = $frequency_unit;
+               $queueMsg->frequency_interval = $frequency_interval;
+               $queueMsg->installments = $installments;
+               $queueMsg->date = $this->startValidityDate;
+               $queueMsg->subscr_id = $this->subscriptionId;
+               $queueMsg->recurring = 1;
+
+               $queueMsg->correlationId = 
"{$queueMsg->gateway}-{$queueMsg->gateway_txn_id}";
+
+               return $queueMsg;
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TokenCancellation.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TokenCancellation.php
new file mode 100644
index 0000000..f23f34d
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TokenCancellation.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class TokenCancellation extends TransactionCommon {
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionCommon.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionCommon.php
new file mode 100644
index 0000000..5a61f65
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionCommon.php
@@ -0,0 +1,105 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+/**
+ * Field shared by non-subscription notifications.
+ */
+abstract class TransactionCommon extends AmazonMessage {
+       //FIXME: it is not ideal to list the fields twice.
+       protected $fields = array(
+               'addressFullName',
+               'addressLine1',
+               'addressLine2',
+               'addressState',
+               'addressZip',
+               'addressCountry',
+               'addressPhone',
+               'buyerEmail',
+               'buyerName',
+               'certificateUrl',
+               'customerEmail',
+               'customerName',
+               'dateInstalled',
+               'isShippingAddressProvided',
+               'operation',
+               'notificationType',
+               'paymentMethod',
+               'paymentReason',
+               'recipientEmail',
+               'recipientName',
+               'referenceId',
+               'signature',
+               'signatureVersion',
+               'signatureMethod',
+               'subscriptionId',
+               'tokenId',
+               'tokenType',
+               'transactionAmount',
+               'transactionDate',
+               'transactionId',
+               'transactionStatus',
+       );
+       protected $addressFullName;
+       protected $addressLine1;
+       protected $addressLine2;
+       protected $addressState;
+       protected $addressZip;
+       protected $addressCountry;
+       protected $addressPhone;
+       protected $buyerEmail;
+       protected $buyerName;
+       protected $certificateUrl;
+       protected $customerEmail;
+       protected $customerName;
+       protected $dateInstalled;
+       protected $isShippingAddressProvided;
+       protected $operation;
+       protected $notificationType;
+       protected $paymentMethod;
+       protected $paymentReason;
+       protected $recipientEmail;
+       protected $recipientName;
+       protected $referenceId;
+       protected $signature;
+       protected $signatureVersion;
+       protected $signatureMethod;
+       protected $subscriptionId;
+       protected $tokenId;
+       protected $tokenType;
+       protected $transactionAmount;
+       protected $transactionDate;
+       protected $transactionId;
+       protected $transactionStatus;
+
+       public function normalizeForQueue() {
+               $queueMsg = parent::normalizeForQueue();
+
+               if ( preg_match( "/^([A-Z]{3}) ([0-9.]+)$/", 
$this->transactionAmount, $matches ) ) {
+                       $currency = $matches[1];
+                       $amount = $matches[2];
+               } else {
+                       throw new SmashPigException( "Unhandled transaction 
amount , {$this->transactionAmount}" );
+               }
+
+               $queueMsg->gateway_txn_id = $this->transactionId;
+               $queueMsg->last_name = $this->buyerName;
+               $queueMsg->email = $this->buyerEmail;
+               $queueMsg->street_address = $this->addressLine1;
+               $queueMsg->supplemental_address_1 = $this->addressLine2;
+               $queueMsg->state_province = $this->addressState;
+               $queueMsg->country = $this->addressCountry;
+               $queueMsg->postal_code = $this->addressZip;
+               $queueMsg->currency = $currency;
+               $queueMsg->gross = $amount;
+               $queueMsg->date = $this->transactionDate;
+
+               if ( $this->subscriptionId ) {
+                       $queueMsg->subscr_id = $this->subscriptionId;
+                       $queueMsg->txn_type = 'subscr_payment';
+                       $queueMsg->recurring = 1;
+               }
+
+               $queueMsg->correlationId = 
"{$queueMsg->gateway}-{$queueMsg->gateway_txn_id}";
+
+               return $queueMsg;
+       }
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionStatus.php 
b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionStatus.php
new file mode 100644
index 0000000..b3aa4bf
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/ExpatriatedMessages/TransactionStatus.php
@@ -0,0 +1,4 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\ExpatriatedMessages;
+
+class TransactionStatus extends TransactionCommon {
+}
diff --git a/SmashPig/PaymentProviders/Amazon/Messages/NormalizedMessage.php 
b/SmashPig/PaymentProviders/Amazon/Messages/NormalizedMessage.php
new file mode 100644
index 0000000..19cb272
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/Messages/NormalizedMessage.php
@@ -0,0 +1,10 @@
+<?php namespace SmashPig\PaymentProviders\Amazon\Messages;
+
+use SmashPig\Core\DataStores\KeyedOpaqueStorableObject;
+
+/**
+ * FIXME: this is lame
+ */
+class NormalizedMessage extends KeyedOpaqueStorableObject {
+
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionPaymentSuccess.json
 
b/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionPaymentSuccess.json
new file mode 100644
index 0000000..4aa5b67
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionPaymentSuccess.json
@@ -0,0 +1,21 @@
+{
+       "buyerEmail": "[email protected]",
+       "buyerName": "bart spanger",
+       "certificateUrl": 
"https://fps.sandbox.amazonaws.com/certs/090911/PKICert.pem?requestId=5vbnzevi12bhhhozf9sh37v2ateycga1062wmncwmejhv";,
+       "nextTransactionDate": "1370221421",
+       "operation": "pay",
+       "paymentMethod": "ABT",
+       "paymentReason": "Monthly donation to the Wikimedia Foundation",
+       "recipientEmail": "[email protected]",
+       "recipientName": "Test Business",
+       "referenceId": "450",
+       "signature": 
"Jx6llM31uBqLObt/ER7XccmOMIosq787DXDoJEIuMU/b6kD3xUW0ZYbZI0CG/CPKeey/51QRtHkZOMY/NIO047DQD4bIq7Uc+X2pdgVh3Fe3GYAnJqVS8WzRJqLmxObiBNlj6gG8PJF479LuCEWY+FLeG1t6Qm3sX715VYtIXMc=",
+       "signatureMethod": "RSA-SHA1",
+       "signatureVersion": "2",
+       "status": "PS",
+       "subscriptionId": "f138980f-90ca-43ba-9421-41a4996779ea",
+       "transactionAmount": "USD 1.00",
+       "transactionDate": "1367543022",
+       "transactionId": "17PJULZUA5ZLH6A184D2T6ST5NTBAQ18165",
+       "transactionSerialNumber": "1"
+}
diff --git 
a/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionSuccessful.json 
b/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionSuccessful.json
new file mode 100644
index 0000000..769ffaa
--- /dev/null
+++ 
b/SmashPig/PaymentProviders/Amazon/Tests/Data/IPN/SubscriptionSuccessful.json
@@ -0,0 +1,19 @@
+{
+       "buyerEmail": "[email protected]",
+       "buyerName": "bart spanger",
+       "certificateUrl": 
"https://fps.sandbox.amazonaws.com/certs/090911/PKICert.pem?requestId=5vbnzevi12bhhhozf9sh37v2ateycga1062wmncwmejhv";,
+       "noOfPromotionTransactions": "0",
+       "paymentMethod": "ABT",
+       "paymentReason": "Monthly donation to the Wikimedia Foundation",
+       "recipientEmail": "[email protected]",
+       "recipientName": "Test Business",
+       "recurringFrequency": "1 MONTH",
+       "referenceId": "450",
+       "signature": 
"ARkb+foHVmygo/R22Bbw3rQqcjkM56kl2zE5/+JZXr3yOPdsycKo+SQUOStGPnP9DmMbVVjw2nboC8W8ezfv9aaP7KUr/JcoxtSmTjZDSijz9RMgmLoIElMmehJo/bGba+P+DlT1K5erNIcndZNdB4N/0UOJQtZ6DrTyNDi+vUc=",
+       "signatureMethod": "RSA-SHA1",
+       "signatureVersion": "2",
+       "startValidityDate": "1367543021",
+       "status": "SubscriptionSuccessful",
+       "subscriptionId": "f138980f-90ca-43ba-9421-41a4996779ea",
+       "transactionAmount": "USD 1.00"
+}
diff --git a/SmashPig/PaymentProviders/Amazon/Tests/inject.py 
b/SmashPig/PaymentProviders/Amazon/Tests/inject.py
new file mode 100755
index 0000000..b6050e8
--- /dev/null
+++ b/SmashPig/PaymentProviders/Amazon/Tests/inject.py
@@ -0,0 +1,24 @@
+#!/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/amazon/listener 
Tests/Data/IPN/SubscriptionSuccessful.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)
+urllib2.urlopen(req)
diff --git a/SmashPig/config_defaults.php b/SmashPig/config_defaults.php
index 24b2973..757cf0b 100644
--- a/SmashPig/config_defaults.php
+++ b/SmashPig/config_defaults.php
@@ -117,6 +117,19 @@
                'actions' => array( ),
     ),
 
+       'amazon' => array(
+               'actions' => array(
+                       
'SmashPig\PaymentProviders\Amazon\Actions\IncomingMessage',
+               ),
+
+               'endpoints' => array(
+                       'listener' => array(
+                               'class' => 
'SmashPig\PaymentProviders\Amazon\AmazonListener',
+                               'inst-args' => array(),
+                       )
+               ),
+       ),
+
        'paypal' => array(
                'listener' => array(
                        // For testing purposes override this config.php to

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie0bee461a0b904f38bce73678294e77392493190
Gerrit-PatchSet: 16
Gerrit-Project: wikimedia/fundraising/PaymentsListeners
Gerrit-Branch: master
Gerrit-Owner: Adamw <[email protected]>
Gerrit-Reviewer: Adamw <[email protected]>
Gerrit-Reviewer: MZMcBride <[email protected]>
Gerrit-Reviewer: Mwalker <[email protected]>

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

Reply via email to