Index: branches/fundraising/extensions/DonationInterface/donationinterface.php |
— | — | @@ -59,6 +59,7 @@ |
60 | 60 | $wgAutoloadClasses['DonationData'] = $donationinterface_dir . 'gateway_common/DonationData.php'; |
61 | 61 | $wgAutoloadClasses['GatewayAdapter'] = $donationinterface_dir . 'gateway_common/gateway.adapter.php'; |
62 | 62 | $wgAutoloadClasses['GatewayForm'] = $donationinterface_dir . 'gateway_common/GatewayForm.php'; |
| 63 | +$wgAutoloadClasses['DonationApi'] = $donationinterface_dir . 'gateway_common/donation.api.php'; |
63 | 64 | |
64 | 65 | //THE GATEWAYS WILL RESET THIS when they are instantiated. You can override it, but it won't stick around that way. |
65 | 66 | $wgDonationInterfaceTest = false; |
— | — | @@ -98,6 +99,8 @@ |
99 | 100 | # Unit tests |
100 | 101 | $wgHooks['UnitTestsList'][] = 'efDonationInterfaceUnitTests'; |
101 | 102 | |
| 103 | +// enable the API |
| 104 | +$wgAPIModules['donate'] = 'DonationApi'; |
102 | 105 | |
103 | 106 | // Resource modules |
104 | 107 | $wgResourceTemplate = array( |
Index: branches/fundraising/extensions/DonationInterface/payflowpro_gateway/api_payflowpro_gateway.php |
— | — | @@ -1,6 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | 4 | * PayflowPro Gateway API extension |
| 5 | + * Call with api.php?action=pfp |
5 | 6 | */ |
6 | 7 | |
7 | 8 | class ApiPayflowProGateway extends ApiBase { |
Index: branches/fundraising/extensions/DonationInterface/gateway_common/donation.api.php |
— | — | @@ -0,0 +1,57 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Generic Donation API |
| 5 | + * This API should be able to accept donation submissions for any gateway or payment type |
| 6 | + * Call with api.php?action=donate |
| 7 | + */ |
| 8 | +class DonationApi extends ApiBase { |
| 9 | + public function execute() { |
| 10 | + global $wgRequest, $wgParser; |
| 11 | + |
| 12 | + $params = $this->extractRequestParams(); |
| 13 | + |
| 14 | + $ddObj = new DonationData( 'DonationApi', false, $params ); |
| 15 | + |
| 16 | + $normalizedData = $ddObj->getData(); |
| 17 | + |
| 18 | + // Some test output |
| 19 | + $this->getResult()->addValue( 'data', 'gateway', $normalizedData['gateway'] ); |
| 20 | + $this->getResult()->addValue( 'data', 'amount', $normalizedData['amount'] ); |
| 21 | + } |
| 22 | + |
| 23 | + public function getAllowedParams() { |
| 24 | + return array( |
| 25 | + 'gateway' => array( |
| 26 | + ApiBase::PARAM_TYPE => 'string', |
| 27 | + ApiBase::PARAM_REQUIRED => true, |
| 28 | + ), |
| 29 | + 'amount' => array( |
| 30 | + ApiBase::PARAM_TYPE => 'string', |
| 31 | + ), |
| 32 | + ); |
| 33 | + } |
| 34 | + |
| 35 | + public function getParamDescription() { |
| 36 | + return array( |
| 37 | + 'gateway' => 'Which payment gateway to use - payflowpro, globalcollect, etc.', |
| 38 | + 'amount' => 'The amount donated', |
| 39 | + ); |
| 40 | + } |
| 41 | + |
| 42 | + public function getDescription() { |
| 43 | + return array( |
| 44 | + 'This API allow you to submit a donation to the Wikimedia Foundation using a', |
| 45 | + 'variety of payment processors.', |
| 46 | + ); |
| 47 | + } |
| 48 | + |
| 49 | + public function getExamples() { |
| 50 | + return array( |
| 51 | + 'api.php?action=donate&gateway=payflowpro&amount=2.00', |
| 52 | + ); |
| 53 | + } |
| 54 | + |
| 55 | + public function getVersion() { |
| 56 | + return __CLASS__ . ': $Id: DonationApi.php 1.0 kaldari $'; |
| 57 | + } |
| 58 | +} |
Index: branches/fundraising/extensions/DonationInterface/gateway_common/DonationData.php |
— | — | @@ -10,20 +10,20 @@ |
11 | 11 | protected $normalized = array( ); |
12 | 12 | public $boss; |
13 | 13 | |
14 | | - function __construct( $owning_class, $test = false, $testdata = false ) { |
| 14 | + function __construct( $owning_class, $test = false, $data = false ) { |
15 | 15 | //TODO: Actually think about this bit. |
16 | 16 | // ...and keep in mind we can re-populate if it's a test or whatever. (But that may not be a good idea either) |
17 | 17 | //maybe we should just explicitly pass in where we get the data from. (Test, post, API...) |
18 | 18 | $this->boss = $owning_class; |
19 | | - $this->populateData( $test, $testdata ); |
| 19 | + $this->populateData( $test, $data ); |
20 | 20 | } |
21 | 21 | |
22 | | - function populateData( $test = false, $testdata = false ) { |
| 22 | + function populateData( $test = false, $data = false ) { |
23 | 23 | $this->normalized = array( ); |
24 | | - //TODO: Uh, the API should probably be able to get in this far, too... and have its own populate function. |
25 | | - //Maybe check for the boss class... |
26 | 24 | if ( $test ) { |
27 | | - $this->populateData_Test( $testdata ); |
| 25 | + $this->populateData_Test( $data ); |
| 26 | + } else if ( $this->boss == 'DonationApi' ) { |
| 27 | + $this->populateData_Api( $data ); |
28 | 28 | } else { |
29 | 29 | $this->populateData_Form(); |
30 | 30 | } |
— | — | @@ -152,7 +152,7 @@ |
153 | 153 | 'currency' => $wgRequest->getText( 'currency_code' ), |
154 | 154 | 'payment_method' => $wgRequest->getText( 'payment_method' ), |
155 | 155 | 'order_id' => $wgRequest->getText( 'order_id', null ), //as far as I know, this won't actually ever pull anything back. |
156 | | - 'i_order_id' => $wgRequest->getText( 'i_order_id', null ), |
| 156 | + 'i_order_id' => $wgRequest->getText( 'i_order_id', null ), //internal id for each contribution attempt |
157 | 157 | 'numAttempt' => $wgRequest->getVal( 'numAttempt', 0 ), |
158 | 158 | 'referrer' => ( $wgRequest->getVal( 'referrer' ) ) ? $wgRequest->getVal( 'referrer' ) : $wgRequest->getHeader( 'referer' ), |
159 | 159 | 'utm_source' => self::getUtmSource(), //TODO: yes. That. |
— | — | @@ -177,6 +177,66 @@ |
178 | 178 | $this->setVal( 'posted', false ); |
179 | 179 | } |
180 | 180 | } |
| 181 | + |
| 182 | + function populateData_Api( $data ) { |
| 183 | + global $wgRequest; |
| 184 | + $this->normalized = array( |
| 185 | + // Do we need 'posted' here? |
| 186 | + 'amount' => $data['amount'], |
| 187 | + 'amountGiven' => $data['amountGiven'], |
| 188 | + 'amountOther' => $data['amountOther'], |
| 189 | + 'email' => $data['email'], |
| 190 | + 'fname' => $data['fname'], |
| 191 | + 'mname' => $data['mname'], |
| 192 | + 'lname' => $data['lname'], |
| 193 | + 'street' =>$data['street'], |
| 194 | + 'city' => $data['city'], |
| 195 | + 'state' => $data['state'], |
| 196 | + 'zip' => $data['zip'], |
| 197 | + 'country' => $data['country'], |
| 198 | + 'fname2' => $data['fname'], |
| 199 | + 'lname2' => $data['lname'], |
| 200 | + 'street2' => $data['street'], |
| 201 | + 'city2' => $data['city'], |
| 202 | + 'state2' => $data['state'], |
| 203 | + 'zip2' => $data['zip'], |
| 204 | + /** |
| 205 | + * For legacy reasons, we might get a 0-length string passed into the form for country2. If this happens, we need to set country2 |
| 206 | + * to be 'country' for downstream processing (until we fully support passing in two separate addresses). I thought about completely |
| 207 | + * disabling country2 support in the forms, etc but realized there's a chance it'll be resurrected shortly. Hence this silly hack. |
| 208 | + */ |
| 209 | + 'country2' => ( strlen( $data['country2'] ) ) ? $data['country2'] : $data['country'], |
| 210 | + 'size' => $data['size'], |
| 211 | + 'premium_language' => ( $data['premium_language'] ) ? $data['premium_language'] : 'en', |
| 212 | + 'card_num' => str_replace( ' ', '', $data['card_num'] ), |
| 213 | + 'card_type' => $data['card_type'], |
| 214 | + 'expiration' => $data['mos'] . substr( $data['year'], 2, 2 ), |
| 215 | + 'cvv' => $data['cvv'], |
| 216 | + 'currency' => $data['currency_code'], |
| 217 | + 'payment_method' => $data['payment_method'], |
| 218 | + 'order_id' => $data['order_id'], //as far as I know, this won't actually ever pull anything back. |
| 219 | + 'i_order_id' => $data['i_order_id'], //internal id for each contribution attempt |
| 220 | + 'numAttempt' => $data['numAttempt'], |
| 221 | + 'referrer' => $data['referrer'] ? $data['referrer'] : $wgRequest->getHeader( 'referer' ), |
| 222 | + 'utm_source' => self::getUtmSource( $data['$utm_source'], $data['$utm_source_id'] ), |
| 223 | + 'utm_medium' => $data['utm_medium'], |
| 224 | + 'utm_campaign' => $data['utm_campaign'], |
| 225 | + // try to honor the user-set language (uselang), otherwise the language set in the URL (language) |
| 226 | + 'language' => ( $data['uselang'] ) ? $data['uselang'] : $data['language'], |
| 227 | + 'comment-option' => $data['comment-option'], |
| 228 | + 'comment' => $data['comment'], |
| 229 | + 'email-opt' => $data['email-opt'], |
| 230 | + 'test_string' => $data['process'], // for showing payflow string during testing |
| 231 | + '_cache_' => $data['_cache_'], |
| 232 | + 'token' => $data['token'], |
| 233 | + 'contribution_tracking_id' => $data['contribution_tracking_id'], |
| 234 | + 'data_hash' => $data['data_hash'], |
| 235 | + 'action' => $data['action'], |
| 236 | + 'gateway' => $data['gateway'], //likely to be reset shortly by setGateway(); |
| 237 | + 'owa_session' => $data['owa_session'], |
| 238 | + 'owa_ref' => $data['owa_ref'], |
| 239 | + ); |
| 240 | + } |
181 | 241 | |
182 | 242 | function isSomething( $key ) { |
183 | 243 | if ( array_key_exists( $key, $this->normalized ) && !empty( $this->normalized[$key] ) ) { |
— | — | @@ -288,10 +348,14 @@ |
289 | 349 | |
290 | 350 | function setGateway() { |
291 | 351 | //TODO: Hum. If we have some other gateway in the form data, should we go crazy here? (Probably) |
292 | | - if ( class_exists( $this->boss ) ) { |
293 | | - $c = $this->boss; |
294 | | - $gateway = $c::getIdentifier(); |
295 | | - $this->setVal( 'gateway', $gateway ); |
| 352 | + if ( $this->boss == 'DonationApi' ) { |
| 353 | + $this->setVal( 'gateway', $this->normalized['gateway'] ); |
| 354 | + } else { |
| 355 | + if ( class_exists( $this->boss ) ) { |
| 356 | + $c = $this->boss; |
| 357 | + $gateway = $c::getIdentifier(); |
| 358 | + $this->setVal( 'gateway', $gateway ); |
| 359 | + } |
296 | 360 | } |
297 | 361 | } |
298 | 362 | |