Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.alias.php |
— | — | @@ -0,0 +1,8 @@ |
| 2 | +<?php |
| 3 | +$aliases = array(); |
| 4 | + |
| 5 | +/** English */ |
| 6 | +$aliases['en'] = array( |
| 7 | + 'PayflowProGateway' => array( 'PayflowProGateway' ), |
| 8 | +); |
| 9 | + |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php |
— | — | @@ -0,0 +1,536 @@ |
| 2 | +<?php |
| 3 | +class PayflowProGateway extends SpecialPage { |
| 4 | + function __construct() { |
| 5 | + parent::__construct( 'PayflowProGateway', $restriction = '', $listed = false ); |
| 6 | + |
| 7 | + wfLoadExtensionMessages('PayflowProGateway'); |
| 8 | + } |
| 9 | + |
| 10 | + function execute( $par ) { |
| 11 | + global $wgRequest, $wgOut, $wgUser; |
| 12 | + |
| 13 | + global $wgParser; |
| 14 | + $wgParser->disableCache(); |
| 15 | + |
| 16 | + |
| 17 | + $this->setHeaders(); |
| 18 | + |
| 19 | + //create token if one doesn't already exist |
| 20 | + $token = $wgUser->editToken('mrxc877668DwQQ'); |
| 21 | + |
| 22 | + // Declare form post variables |
| 23 | + $data = array( |
| 24 | + 'amount' => '', |
| 25 | + 'email' => '', |
| 26 | + 'fname' => '', |
| 27 | + 'mname' => '', |
| 28 | + 'lname' => '', |
| 29 | + 'street' => '', |
| 30 | + 'city' => '', |
| 31 | + 'state' => '', |
| 32 | + 'zip' => '', |
| 33 | + 'country' => '', |
| 34 | + 'card_num' => '', |
| 35 | + 'expiration' => '', |
| 36 | + 'cvv' => '', |
| 37 | + 'currency' => '', |
| 38 | + 'payment_method' => '', |
| 39 | + ); |
| 40 | + |
| 41 | + $error[] = ''; |
| 42 | + |
| 43 | + //find out if amount was a radio button or textbox, set amount |
| 44 | + if (isset($_REQUEST['amount'])) { |
| 45 | + $amount = number_format($wgRequest->getText('amount'), 2); |
| 46 | + } else if (isset($_REQUEST['amount2'])) { |
| 47 | + $amount = number_format($wgRequest->getText('amount2'), 2, '.', ''); |
| 48 | + } else { |
| 49 | + $wgOut->addHTML("This page is only accessible from the donation page"); |
| 50 | + return; |
| 51 | + } |
| 52 | + |
| 53 | + // Populate from data |
| 54 | + $data = array( |
| 55 | + 'amount' => $amount, |
| 56 | + 'email' => $wgRequest->getText('email'), |
| 57 | + 'fname' => $wgRequest->getText('fname'), |
| 58 | + 'mname' => $wgRequest->getText('mname'), |
| 59 | + 'lname' => $wgRequest->getText('lname'), |
| 60 | + 'street' => $wgRequest->getText('street'), |
| 61 | + 'city' => $wgRequest->getText('city'), |
| 62 | + 'state' => $wgRequest->getText('state'), |
| 63 | + 'zip' => $wgRequest->getText('zip'), |
| 64 | + 'country' => $wgRequest->getText('country'), |
| 65 | + 'card' => $wgRequest->getText('card'), |
| 66 | + 'card_num' => str_replace(' ','',$wgRequest->getText('card_num')), |
| 67 | + 'expiration' => $wgRequest->getText('mos').substr($wgRequest->getText('year'), 2, 2), |
| 68 | + 'cvv' => $wgRequest->getText('cvv'), |
| 69 | + 'currency' => $wgRequest->getText('currency_code'), |
| 70 | + 'payment_method' => $wgRequest->getText('payment_method'), |
| 71 | + 'token' => $wgRequest->getVal('token'), |
| 72 | + 'test_string' => $wgRequest->getText('process') //for showing payflow string during testing |
| 73 | + ); |
| 74 | + |
| 75 | + |
| 76 | + // Get array of default account values necessary for Payflow |
| 77 | + require_once('includes/payflowUser.inc'); |
| 78 | + |
| 79 | + $payflow_data = payflowUser(); |
| 80 | + |
| 81 | + // Check form for errors and display |
| 82 | + // match token |
| 83 | + $success = $wgUser->matchEditToken($token, 'mrxc877668DwQQ'); |
| 84 | + |
| 85 | + if ($success) { |
| 86 | + if ($data['payment_method'] == "processed") { |
| 87 | + // Check form for errors and redisplay with messages |
| 88 | + if ($form_errors = $this->validateForm($data, $error)) { |
| 89 | + $this->displayForm($data, $error); |
| 90 | + } else { |
| 91 | + // The submitted data is valid, so process it |
| 92 | + $this->processTransaction($data, $payflow_data); |
| 93 | + } |
| 94 | + } |
| 95 | + else { |
| 96 | + //Display form for the first time |
| 97 | + $this->displayForm($data, $error); |
| 98 | + } |
| 99 | + } // end $success |
| 100 | + |
| 101 | +} |
| 102 | + |
| 103 | + /* |
| 104 | + * Displays form to user |
| 105 | + * |
| 106 | + * @params |
| 107 | + * $data array of posted user input |
| 108 | + * $error array of error messages returned by validate_form function |
| 109 | + * |
| 110 | + * Form can be output as a table or as a fieldset. Fieldset is commented out by default. Both include class names. |
| 111 | + * |
| 112 | + * The message at the top of the form can be edited in the payflow_gateway.i18.php file |
| 113 | + */ |
| 114 | + private function displayForm($data, &$error) { |
| 115 | + require_once('includes/stateAbbreviations.inc'); |
| 116 | + require_once('includes/countryCodes.inc'); |
| 117 | + |
| 118 | + global $wgOut; |
| 119 | + |
| 120 | + $form = wfMsg('form-message'); |
| 121 | + |
| 122 | + //show error messages if they exist |
| 123 | + if (!empty($error)) { |
| 124 | + //add styling |
| 125 | + $form .= '<div class="creditcard_error">'; |
| 126 | + foreach($error as $key) { |
| 127 | + $form .= '<p class="creditcard_error_msg">'.$key.'</p>'; |
| 128 | + } |
| 129 | + $form .= '</div>'; |
| 130 | + } |
| 131 | + |
| 132 | + //create drop down of countries |
| 133 | + //$countries = $this->countryCodes(); |
| 134 | + $countries = countryCodes(); |
| 135 | + |
| 136 | + foreach($countries as $key => $value) { |
| 137 | + $countryMenu .= '<option value='. $key . '>'. $value .'</option>'; |
| 138 | + } |
| 139 | + |
| 140 | + //Form implemented as a table with classnames |
| 141 | + //***Comment this section out and uncomment the subsequent implementation as a fieldset if preferred*** |
| 142 | + $form .='<div class="mw-creditcard_form"><form name="payment" method="post" action=""> |
| 143 | + <table class="mw-creditcard_table" border="0" cellspacing="1" cellpadding="3"> |
| 144 | + <tr><td class="mw-mw-creditcard-label">Donation Amount: </td><td class="mw-mw-creditcard-input">'.$data['amount'].'</td></tr> |
| 145 | + <input type="hidden" name="amount" value="'.$data['amount'].'"> |
| 146 | + <tr><td class="mw-creditcard-label">Donor Information:</td></tr> |
| 147 | + <tr><td class="mw-creditcard-name">E-mail Address:</td> |
| 148 | + <td class="mw-creditcard-input"><input type="text" name="email" value="'.$data['email'].'" maxlength="150" size="30" /></td></tr> |
| 149 | + <tr><td class="mw-creditcard-name">First Name:</td> |
| 150 | + <td class="mw-creditcard-input"><input type="text" name="fname" value="'.$data['fname'].'" maxlength="35" size="20" /></td></tr> |
| 151 | + <tr><td class="mw-creditcard-name">Middle Name:</td> |
| 152 | + <td class="mw-creditcard-input"><input type="text" name="mname" value="'.$data['mname'].'" maxlength="35" size="20" /></td></tr> |
| 153 | + <tr><td class="mw-creditcard-name">Last Name:</td> |
| 154 | + <td class="mw-creditcard-input"><input type="text" name="lname" value="'.$data['lname'].'" maxlength="35" size="20" /></td></tr> |
| 155 | + <tr><td class="mw-creditcard-name">Street:</td> |
| 156 | + <td class="mw-creditcard-input"><input type="text" name="street" value="'.$data['street'].'" maxlength="100" size="30" /></td></tr> |
| 157 | + <tr><td class="mw-creditcard-name">City:</td> |
| 158 | + <td class="mw-creditcard-input"><input type="text" name="city" value="'.$data['city'].'" maxlength="35" size="20" /></td></tr> |
| 159 | + <tr><td class="mw-creditcard-name">State:</td> |
| 160 | + <td class="mw-creditcard-input"><select name="state" value="'.$data['state'].'" />'. statesMenu() .'</td></tr> |
| 161 | + <tr><td class="mw-creditcard-name">Postal Code:</td> |
| 162 | + <td class="mw-creditcard-input"><input type="text" name="zip" value="'.$data['zip'].'" maxlength="18" size="15" /></td></tr> |
| 163 | + <tr><td class="mw-creditcard-name">Country/Region:</td> |
| 164 | + <td class="mw-creditcard-input"><select name="country" value="'.$data['country'].'" />'.$countryMenu.'</select></td></tr> |
| 165 | + <tr><td class="mw-creditcard-label">Credit Card Information:</td></tr> |
| 166 | + <tr><td class="mw-creditcard-name">Credit Card:</td> |
| 167 | + <td class="mw-creditcard-input"><select name="card"> |
| 168 | + <option value="visa">Visa</option><option selected="selected" value="mastercard">MasterCard</option> |
| 169 | + <option value="american">American Express</option></select></td></tr> |
| 170 | + <tr><td class="mw-creditcard-name">Card Number: </td> |
| 171 | + <td class="mw-creditcard-input"><input type="text" name="card_num" maxlength="100" /></td></tr> |
| 172 | + <tr><td class="mw-creditcard-name">Expiration Date:</td><td class="mw-creditcard-input"> |
| 173 | + <select name="mos"> |
| 174 | + <option value="01">01</option> |
| 175 | + <option value="02">02</option> |
| 176 | + <option value="03">03</option> |
| 177 | + <option value="04">04</option> |
| 178 | + <option value="05">05</option> |
| 179 | + <option value="06">06</option> |
| 180 | + <option value="07">07</option> |
| 181 | + <option value="08">08</option> |
| 182 | + <option value="09">09</option> |
| 183 | + <option value="10">10</option> |
| 184 | + <option value="11">11</option> |
| 185 | + <option value="12" selected="selected">12</option> |
| 186 | + </select> |
| 187 | + <select name="year"> |
| 188 | + <option value="'.(date('Y')).'">'.(date('Y')).'</option> |
| 189 | + <option value="'.(date('Y')+1).'">'.(date('Y')+1).'</option> |
| 190 | + <option value="'.(date('Y')+2).'" selected="selected">'.(date('Y')+2).'</option> |
| 191 | + <option value="'.(date('Y')+3).'">'.(date('Y')+3).'</option> |
| 192 | + <option value="'.(date('Y')+4).'">'.(date('Y')+4).'</option> |
| 193 | + <option value="'.(date('Y')+5).'">'.(date('Y')+5).'</option> |
| 194 | + <option value="'.(date('Y')+6).'">'.(date('Y')+6).'</option> |
| 195 | + <option value="'.(date('Y')+7).'">'.(date('Y')+7).'</option> |
| 196 | + <option value="'.(date('Y')+8).'">'.(date('Y')+8).'</option> |
| 197 | + <option value="'.(date('Y')+9).'">'.(date('Y')+9).'</option> |
| 198 | + <option value="'.(date('Y')+10).'">'.(date('Y')+10).'</option> |
| 199 | + </select></td></tr> |
| 200 | + <tr><td class="mw-creditcard-name">Card Security Code:</td><td class="mw-creditcard-input"><input type="text" name="cvv" size="5" maxlength="35" /></td></tr> |
| 201 | + <tr><td> |
| 202 | + <input type="hidden" name="process" value="CreditCard" /> |
| 203 | + <input type="hidden" name="payment_method" value="processed" /> |
| 204 | + <input type="hidden" name="token" value="'.$data['token'].'"> |
| 205 | + <input type="hidden" name="currency_code" value="'.$data['currency'].'" /> |
| 206 | + <input type="hidden" name="orderid" value="'.$data['order_id'].'" /></td> |
| 207 | + <td><input type="submit" value=" Donate " /></td></tr> |
| 208 | + </table> |
| 209 | + </form></div> |
| 210 | + </div>'; |
| 211 | + |
| 212 | + //Implemented as a form with fieldsets |
| 213 | + //***Uncomment this section and comment out the previous table implementation if preferred*** |
| 214 | + /* |
| 215 | + $form .= '<div class="mw-creditcard-form"> |
| 216 | + <form name="payment" method="post" action=""> |
| 217 | + <legend class="mw-creditcard-amount">Donation Amount: '.$data['amount'].'</legend> |
| 218 | + <input type="hidden" name="amount" value="'.$data['amount'].'"> |
| 219 | + <fieldset class="mw-creditcard-donor"> |
| 220 | + <legend>Donor Information:</legend> |
| 221 | + <p><label>E-mail Address:</label><input type="text" name="email" value="'.$data['email'].'" maxlength="150" size="30" /></p> |
| 222 | + <p><label>First Name:</label><input type="text" name="fname" value="'.$data['fname'].'" maxlength="35" size="20" /></p> |
| 223 | + <p><label>Middle Name:</label><input type="text" name="mname" value="'.$data['mname'].'" maxlength="35" size="20" /></p> |
| 224 | + <p><label>Last Name:</label><input type="text" name="lname" value="'.$data['lname'].'" maxlength="35" size="20" /></p> |
| 225 | + <p><label>Street:</label><input type="text" name="street" value="'.$data['street'].'" maxlength="100" size="30" /></p> |
| 226 | + <p><label>City:</label><input type="text" name="city" value="'.$data['city'].'" maxlength="35" size="20" /></p> |
| 227 | + <p><label>State:</label><select name="state" value="'.$data['state'].'" />'. statesMenu() .'</select></p> |
| 228 | + <p><label>Postal Code:</label><input type="text" name="zip" value="'.$data['zip'].'" maxlength="18" size="15" /></p> |
| 229 | + <p><label>Country/Region:</label><select name="country" value="'.$data['country'].'" />'.$countryMenu.'</select></p> |
| 230 | + </fieldset> |
| 231 | + <fieldset class="mw-creditcard-label"> |
| 232 | + <legend>Credit Card Information:</legend> |
| 233 | + <p><label>Credit Card:</label> |
| 234 | + <select name="card"> |
| 235 | + <option value="visa">Visa</option><option selected="selected" value="mastercard">MasterCard</option> |
| 236 | + <option value="american">American Express</option> |
| 237 | + </select></p> |
| 238 | + <p><label>Card Number: </label><input type="text" name="card_num" maxlength="100" /></p> |
| 239 | + <p><label>Expiration Date:</label> |
| 240 | + <select name="mos"> |
| 241 | + <option value="01">01</option><option value="02">02</option><option value="03">03</option><option value="04">04</option> |
| 242 | + <option value="05">05</option><option value="06">06</option><option value="07">07</option><option value="08">08</option> |
| 243 | + <option value="09">09</option><option value="10">10</option><option value="11">11</option><option value="12" selected="selected">12</option> |
| 244 | + </select> |
| 245 | + <select name="year"> |
| 246 | + <option value="'.(date('Y')).'">'.(date('Y')).'</option> |
| 247 | + <option value="'.(date('Y')+1).'">'.(date('Y')+1).'</option> |
| 248 | + <option value="'.(date('Y')+2).'" selected="selected">'.(date('Y')+2).'</option> |
| 249 | + <option value="'.(date('Y')+3).'">'.(date('Y')+3).'</option> |
| 250 | + <option value="'.(date('Y')+4).'">'.(date('Y')+4).'</option> |
| 251 | + <option value="'.(date('Y')+5).'">'.(date('Y')+5).'</option> |
| 252 | + <option value="'.(date('Y')+6).'">'.(date('Y')+6).'</option> |
| 253 | + <option value="'.(date('Y')+7).'">'.(date('Y')+7).'</option> |
| 254 | + <option value="'.(date('Y')+8).'">'.(date('Y')+8).'</option> |
| 255 | + <option value="'.(date('Y')+9).'">'.(date('Y')+9).'</option> |
| 256 | + <option value="'.(date('Y')+10).'">'.(date('Y')+10).'</option> |
| 257 | + </select></p> |
| 258 | + <p><label>Card Security Code:</label><input type="text" name="cvv" size="5" maxlength="35" /></p> |
| 259 | + <input type="hidden" name="process" value="CreditCard" /> |
| 260 | + <input type="hidden" name="payment_method" value="processed" /> |
| 261 | + <input type="hidden" name="token" value="'.$data['token'].'"> |
| 262 | + <input type="hidden" name="currency_code" value="'.$data['currency'].'" /> |
| 263 | + <input type="hidden" name="orderid" value="'.$data['order_id'].'" /> |
| 264 | + <input type="submit" value=" Donate " /> |
| 265 | + </fieldset> |
| 266 | + </form> |
| 267 | + </div> |
| 268 | + </div>'; |
| 269 | + */ |
| 270 | + |
| 271 | + $wgOut->addHTML( $form ); |
| 272 | + $wgOut->addHTML('<p class="mw-creditcard-submessage">This donation is being made in ' .$data['currency'] . '</p>'); |
| 273 | + |
| 274 | + } |
| 275 | + |
| 276 | + |
| 277 | + /* |
| 278 | + * Checks posted form data for errors and returns array of messages |
| 279 | + */ |
| 280 | + private function validateForm($data, &$error) { |
| 281 | + global $wgOut; |
| 282 | + |
| 283 | + //begin with no errors |
| 284 | + $error_result = '0'; |
| 285 | + |
| 286 | + //create the human-speak message for required fields |
| 287 | + //does not include fields that are not required |
| 288 | + $msg = array( |
| 289 | + 'amount' => "donation amount", |
| 290 | + 'email' => "email address", |
| 291 | + 'fname' => "first name", |
| 292 | + 'lname' => "last name", |
| 293 | + 'street' => "street address", |
| 294 | + 'city' => "city", |
| 295 | + 'state' => "state", |
| 296 | + 'zip' => "zip code", |
| 297 | + 'card_num' => "credit card number", |
| 298 | + 'expiration' => "card's expiration date", |
| 299 | + 'cvv' => "the CVV from the back of your card", |
| 300 | + ); |
| 301 | + |
| 302 | + //find all empty fields and create message |
| 303 | + foreach($data as $key => $value) { |
| 304 | + if ($value == '') { |
| 305 | + //ignore fields that are not required |
| 306 | + if ($msg[$key]) { |
| 307 | + $error[$key] = "**Please enter your " . $msg[$key] . "**<br />"; |
| 308 | + $error_result = '1'; |
| 309 | + } |
| 310 | + } |
| 311 | + } |
| 312 | + |
| 313 | + //is email address valid? |
| 314 | + $isEmail = eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $data['email']); |
| 315 | + |
| 316 | + //create error message (supercedes empty field message) |
| 317 | + if (!$isEmail) { |
| 318 | + $error['email'] = "**Please enter a valid email address**"; |
| 319 | + $error_result = '1'; |
| 320 | + } |
| 321 | + |
| 322 | + //validate that credit card number entered is correct for the brand |
| 323 | + switch($data['card']) |
| 324 | + { |
| 325 | + case 'american' : |
| 326 | + //pattern for Amex |
| 327 | + $pattern = "/^([34|37]{2})([0-9]{13})$/"; |
| 328 | + |
| 329 | + //if the pattern doesn't match |
| 330 | + if (!preg_match($pattern,$data['card_num'])) { |
| 331 | + $error_result = '1'; |
| 332 | + $error['card'] = "**Please enter a correct card number for American Express.**"; |
| 333 | + } |
| 334 | + break; |
| 335 | + |
| 336 | + case 'mastercard' : |
| 337 | + //pattern for Mastercard |
| 338 | + $pattern = "/^([51|52|53|54|55]{2})([0-9]{14})$/"; |
| 339 | + |
| 340 | + //if pattern doesn't match |
| 341 | + if (!preg_match($pattern,$data['card_num'])) { |
| 342 | + $error_result = '1'; |
| 343 | + $error['card'] = "**Please enter a correct card number for Mastercard.**"; |
| 344 | + } |
| 345 | + break; |
| 346 | + |
| 347 | + case 'visa' : |
| 348 | + //pattern for Visa |
| 349 | + $pattern = "/^([4]{1})([0-9]{12,15})$/"; |
| 350 | + |
| 351 | + //if pattern doesn't match |
| 352 | + if (!preg_match($pattern,$data['card_num'])) { |
| 353 | + $error_result = '1'; |
| 354 | + $error['card'] = "**Please enter a correct card number for Visa.**"; |
| 355 | + } |
| 356 | + break; |
| 357 | + }//end switch*/ |
| 358 | + |
| 359 | + return $error_result; |
| 360 | + } |
| 361 | + |
| 362 | + |
| 363 | + /* |
| 364 | + * Sends a name-value pair string to Payflow gateway |
| 365 | + * |
| 366 | + * parameters: |
| 367 | + * $data array of user input |
| 368 | + * $payflow_data array of necessary Payflow variables to include in string (ie Vendor, password) |
| 369 | + * |
| 370 | + */ |
| 371 | + private function processTransaction($data, $payflow_data) { |
| 372 | + global $wgOut; |
| 373 | + |
| 374 | + /* Create name-value pair query string */ |
| 375 | + $payflow_query = "TRXTYPE=$payflow_data[trxtype]&TENDER=$payflow_data[tender]&USER=$payflow_data[user]&VENDOR=$payflow_data[vendor]&PARTNER=$payflow_data[partner]&PWD=$payflow_data[password]&ACCT=$data[card_num]&EXPDATE=$data[expiration]&AMT=$data[amount]&FIRSTNAME=$data[fname]&LASTNAME=$data[lname]&STREET=$data[street]&ZIP=$data[zip]&INVNUM=$payflow_data[order_id]&CVV2=$data[cvv]&CURRENCY=$data[currency]&VERBOSITY=$payflow_data[verbosity]&CUSTIP=$payflow_data[user_ip]"; |
| 376 | + |
| 377 | + // assign header data necessary for the curl_setopt() function |
| 378 | + $user_agent = $_SERVER['HTTP_USER_AGENT']; |
| 379 | + $headers[] = "Content-Type: text/xml"; |
| 380 | + $headers[] = "Content-Length : " . strlen ($payflow_query); |
| 381 | + $headers[] = "X-VPS-Timeout: 45"; |
| 382 | + $headers[] = "X-VPS-Request-ID:" . $payflow_data['order_id']; |
| 383 | + |
| 384 | + $ch = curl_init(); |
| 385 | + curl_setopt($ch, CURLOPT_URL, $payflow_data['testingurl']); |
| 386 | + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); |
| 387 | + curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); |
| 388 | + curl_setopt($ch, CURLOPT_HEADER, 1); |
| 389 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| 390 | + curl_setopt($ch, CURLOPT_TIMEOUT, 90); |
| 391 | + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); |
| 392 | + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); |
| 393 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $payflow_query); |
| 394 | + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); |
| 395 | + curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE); |
| 396 | + curl_setopt($ch, CURLOPT_POST, 1); |
| 397 | + |
| 398 | + // As suggested in the PayPal developer forum sample code, try more than once to get a response |
| 399 | + // in case there is a general network issue |
| 400 | + $i=1; |
| 401 | + while ($i++ <= 3) { |
| 402 | + $result = curl_exec($ch); |
| 403 | + $headers = curl_getinfo($ch); |
| 404 | + if ($headers['http_code'] != 200) { |
| 405 | + sleep(5); |
| 406 | + } else if ($headers['http_code'] == 200) { |
| 407 | + break; |
| 408 | + } |
| 409 | + } |
| 410 | + |
| 411 | + if ($headers['http_code'] != 200) { |
| 412 | + $wgOut->addHTML('<h3>No response from credit card processor. Please try again later!</h3><p>'); |
| 413 | + curl_close($ch); |
| 414 | + exit; |
| 415 | + } |
| 416 | + |
| 417 | + curl_close($ch); |
| 418 | + |
| 419 | + // get result string |
| 420 | + $result = strstr($result, "RESULT"); |
| 421 | + |
| 422 | + // parse string and display results to the user |
| 423 | + $this->getResults($data, $result); |
| 424 | + |
| 425 | + } |
| 426 | + |
| 427 | + |
| 428 | + /* |
| 429 | + * "Reads" the name-value pair result string returned by Payflow and creates corresponding error messages |
| 430 | + * |
| 431 | + * @params: |
| 432 | + * $data array of user input |
| 433 | + * $result string of name-value pair results returned by Payflow |
| 434 | + * |
| 435 | + * Credit:code modified from payflowpro_example_EC.php posted (and supervised) on the PayPal developers message board |
| 436 | + */ |
| 437 | + private function getResults($data, $result) { |
| 438 | + global $wgOut; |
| 439 | + |
| 440 | + //prepare NVP response for sorting and outputting |
| 441 | + $responseArray = array(); |
| 442 | + |
| 443 | + while(strlen($result)){ |
| 444 | + // name |
| 445 | + $namepos= strpos($result,'='); |
| 446 | + $nameval = substr($result,0,$namepos); |
| 447 | + // value |
| 448 | + $valuepos = strpos($result,'&') ? strpos($result,'&'): strlen($result); |
| 449 | + $valueval = substr($result,$namepos+1,$valuepos-$namepos-1); |
| 450 | + // decoding the respose |
| 451 | + $responseArray[$nameval] = $valueval; |
| 452 | + $result = substr($result,$valuepos+1,strlen($result)); |
| 453 | + } |
| 454 | + |
| 455 | + // errors fall into three categories, "try again please", "sorry it didn't work out", and "approved" |
| 456 | + // try again errors have not yet been developed |
| 457 | + // they will most likely return false and the form is displayed again with the error message (counted) |
| 458 | + // declines and approvals are displayed with data |
| 459 | + $resultCode = $responseArray['RESULT']; |
| 460 | + $responseMsg = "There was an problem processing the transaction. Please try again or contact us."; |
| 461 | + $errorReturn = "0"; |
| 462 | + |
| 463 | + |
| 464 | + //declines and approval |
| 465 | + if ($resultCode == '0') { |
| 466 | + $responseMsg = "Your transaction has been approved. Thank you for your donation!"; |
| 467 | + $errorReturn = "1"; |
| 468 | + } else if ($resultCode == "12" ) { |
| 469 | + $responseMsg = "Your transaction has been declined. Please contact your credit card company for further information."; |
| 470 | + $errorReturn = "1"; |
| 471 | + } else if ($resultCode == '13') { |
| 472 | + $responseMsg = "Voice authorization is required. Please contact us to continue the donation process."; |
| 473 | + $errorReturn = "1"; |
| 474 | + } |
| 475 | + |
| 476 | + //try again please |
| 477 | + |
| 478 | + //Development of this functionality is pending testing on live test site and further clarification from Paypal |
| 479 | + /* |
| 480 | + if ($responseCode == '23' || $responseCode == '24') { |
| 481 | + $responseMsg = "Your credit card number or expiration date is incorrect. Please try again."; |
| 482 | + $errorReturn = "1"; |
| 483 | + } else if () |
| 484 | + */ |
| 485 | + |
| 486 | + $this->displayResults($data, $responseMsg); |
| 487 | + |
| 488 | + }// end display results |
| 489 | + |
| 490 | + |
| 491 | + /* |
| 492 | + * Display response message to user with submitted user-supplied data |
| 493 | + * |
| 494 | + * @params |
| 495 | + * $data array of posted data from form |
| 496 | + * $responseMsg message supplied by getResults function |
| 497 | + * |
| 498 | + */ |
| 499 | + function displayResults($data, $responseMsg) { |
| 500 | + global $wgOut; |
| 501 | + |
| 502 | + require_once('includes/countryCodes.inc'); |
| 503 | + |
| 504 | + // display response message |
| 505 | + $wgOut->addHTML('<h3 class="response_message">' . $responseMsg . "</h3>"); |
| 506 | + |
| 507 | + //translate country code into text |
| 508 | + $countries = countryCodes(); |
| 509 | + |
| 510 | + // display user submitted info |
| 511 | + $submittedUserInfo = '<div class="submitted_response"><table> |
| 512 | + <tr> |
| 513 | + <td><h5>Transaction Details:</h5></td> |
| 514 | + </tr> |
| 515 | + <tr> |
| 516 | + <td>Amount: </td><td>'. $data['amount'] . '</td> |
| 517 | + </tr> |
| 518 | + <td>Email: </td><td>'. $data['email'] . '</td> |
| 519 | + </tr> |
| 520 | + <td>Name: </td><td>'. $data['fname'] . '</td> |
| 521 | + <td>'. $data['mname'] . '</td> |
| 522 | + <td>'. $data['lname'] . '</td> |
| 523 | + </tr> |
| 524 | + <td>Address: </td><td>'. $data['street'] . '</td> |
| 525 | + <td>'. $data['city'] . '</td> |
| 526 | + <td>'. $data['state'] . '</td> |
| 527 | + <td>'. $data['zip'] . '</td> |
| 528 | + <td>'. $countries[$data['country']] . '</td> |
| 529 | + </tr> |
| 530 | + </table>'; |
| 531 | + |
| 532 | + $wgOut->addHTML($submittedUserInfo); |
| 533 | + |
| 534 | + } |
| 535 | + |
| 536 | + |
| 537 | +} // end class |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/includes/stateAbbreviations.inc |
— | — | @@ -0,0 +1,64 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * Supplies drop down menu options of US states |
| 6 | + */ |
| 7 | +function statesMenu() { |
| 8 | + $states = '<option value="">Select a State</option> |
| 9 | + <option value="XX">Outside the U.S.</option> |
| 10 | + <option value="AK">Alaska</option> |
| 11 | + <option value="AL">Alabama</option> |
| 12 | + <option value="AR">Arkansas</option> |
| 13 | + <option value="AZ">Arizona</option> |
| 14 | + <option value="CA">California</option> |
| 15 | + <option value="CO">Colorado</option> |
| 16 | + <option value="CT">Connecticut</option> |
| 17 | + <option value="DC">Washington D.C.</option> |
| 18 | + <option value="DE">Delaware</option> |
| 19 | + <option value="FL">Florida</option> |
| 20 | + <option value="GA">Georgia</option> |
| 21 | + <option value="HI">Hawaii</option> |
| 22 | + <option value="IA">Iowa</option> |
| 23 | + <option value="ID">Idaho</option> |
| 24 | + <option value="IL">Illinois</option> |
| 25 | + <option value="IN">Indiana</option> |
| 26 | + <option value="KS">Kansas</option> |
| 27 | + <option value="KY">Kentucky</option> |
| 28 | + <option value="LA">Louisiana</option> |
| 29 | + <option value="MA">Massachusetts</option> |
| 30 | + <option value="MD">Maryland</option> |
| 31 | + <option value="ME">Maine</option> |
| 32 | + <option value="MI">Michigan</option> |
| 33 | + <option value="MN">Minnesota</option> |
| 34 | + <option value="MO">Missourri</option> |
| 35 | + <option value="MS">Mississippi</option> |
| 36 | + <option value="MT">Montana</option> |
| 37 | + <option value="NC">North Carolina</option> |
| 38 | + <option value="ND">North Dakota</option> |
| 39 | + <option value="NE">Nebraska</option> |
| 40 | + <option value="NH">New Hampshire</option> |
| 41 | + <option value="NJ">New Jersey</option> |
| 42 | + <option value="NM">New Mexico</option> |
| 43 | + <option value="NV">Nevada</option> |
| 44 | + <option value="NY">New York</option> |
| 45 | + <option value="OH">Ohio</option> |
| 46 | + <option value="OK">Oklahoma</option> |
| 47 | + <option value="OR">Oregon</option> |
| 48 | + <option value="PA">Pennsylvania</option> |
| 49 | + <option value="PR">Puerto Rico</option> |
| 50 | + <option value="RI">Rhode Island</option> |
| 51 | + <option value="SC">South Carolina</option> |
| 52 | + <option value="SD">South Dakota</option> |
| 53 | + <option value="TN">Tennessee</option> |
| 54 | + <option value="TX">Texas</option> |
| 55 | + <option value="UT">Utah</option> |
| 56 | + <option value="VA">Virginia</option> |
| 57 | + <option value="VT">Vermont</option> |
| 58 | + <option value="WA">Washington</option> |
| 59 | + <option value="WI">Wisconsin</option> |
| 60 | + <option value="WV">West Virginia</option> |
| 61 | + <option value="WY">Wyoming</option>'; |
| 62 | + |
| 63 | + return $states; |
| 64 | + } |
| 65 | + |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/includes/payflowUser.inc |
— | — | @@ -0,0 +1,31 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | +* Payflow Pro account information |
| 6 | +* Payflow individual account information must be defined in the LocalSettings.php file |
| 7 | +*/ |
| 8 | +function payflowUser() { |
| 9 | + // User account information from LocalSettings.php |
| 10 | + global $wgPayflowProPartnerID, |
| 11 | + $wgPayflowProVendorID, |
| 12 | + $wgPayflowProUserID, |
| 13 | + $wgPayflowProPassword, |
| 14 | + $wgPayflowProURL, |
| 15 | + $wgPayflowProTestingURL; |
| 16 | + |
| 17 | + $payflow_data = array( |
| 18 | + 'partner' => $wgPayflowProPartnerID, //PayPal or original authorized reseller |
| 19 | + 'vendor' => $wgPayflowProVendorID, // paypal merchant login ID |
| 20 | + 'user' => $wgPayflowProUserID, //if one or more users are set up, authorized user ID, else same as VENDOR |
| 21 | + 'password' => $wgPayflowProPassword, //merchant login password |
| 22 | + 'paypalurl' => $wgPayflowProURL, |
| 23 | + 'testingurl' => $wgPayflowProTestingURL, // Payflow testing URL |
| 24 | + 'trxtype' => "S", //transaction type - all donations are a sale |
| 25 | + 'tender' => "C", //credit card - all transactions in this case are credit cards |
| 26 | + 'verbosity' => "MEDIUM", //level of detail in Payflow response |
| 27 | + 'user_ip' => $_SERVER['REMOTE_ADDR'], //current user's ip address |
| 28 | + 'order_id' => date('ymdH').rand(1000,9999), // Generate random order number |
| 29 | + ); |
| 30 | + |
| 31 | + return $payflow_data; |
| 32 | +} |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/includes/countryCodes.inc |
— | — | @@ -0,0 +1,256 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * List of ISO numeric country codes to display as select menu to user |
| 6 | + * needed to translate country to name-value pair 3-digit variable |
| 7 | + */ |
| 8 | +function countryCodes() { |
| 9 | + |
| 10 | + $countryCode = array( |
| 11 | + '840' => 'United States', |
| 12 | + '124' => 'Canada', |
| 13 | + '826' => 'United Kingdom', |
| 14 | + '004' => 'Afghanistan', |
| 15 | + '008' => 'Albania', |
| 16 | + '012' => 'Algeria', |
| 17 | + '016' => 'American Samoa', |
| 18 | + '020' => 'Andorra', |
| 19 | + '024' => 'Angola', |
| 20 | + '660' => 'Anguilla', |
| 21 | + '010' => 'Antarctica', |
| 22 | + '028' => 'Antigua and Barbuda', |
| 23 | + '032' => 'Argentina', |
| 24 | + '051' => 'Armenia', |
| 25 | + '533' => 'Aruba', |
| 26 | + '036' => 'Australia', |
| 27 | + '040' => 'Austria', |
| 28 | + '031' => 'Azerbaijan', |
| 29 | + '044' => 'Bahamas', |
| 30 | + '048' => 'Bahrain', |
| 31 | + '050' => 'Bangladesh', |
| 32 | + '052' => 'Barbados', |
| 33 | + '112' => 'Belarus', |
| 34 | + '056' => 'Belgium', |
| 35 | + '084' => 'Belize', |
| 36 | + '204' => 'Benin', |
| 37 | + '060' => 'Bermuda', |
| 38 | + '064' => 'Bhutan', |
| 39 | + '068' => 'Bolivia, Plurinational State of', |
| 40 | + '070' => 'Bosnia and Herzegovina', |
| 41 | + '072' => 'Botswana', |
| 42 | + '074' => 'Bouvet Island', |
| 43 | + '076' => 'Brazil', |
| 44 | + '086' => 'British Indian Ocean Territory', |
| 45 | + '096' => 'Brunei Darussalam', |
| 46 | + '100' => 'Bulgaria', |
| 47 | + '854' => 'Burkina Faso', |
| 48 | + '108' => 'Burundi', |
| 49 | + '116' => 'Cambodia', |
| 50 | + '120' => 'Cameroon', |
| 51 | + '124' => 'Canada', |
| 52 | + '132' => 'Cape Verde', |
| 53 | + '136' => 'Cayman Islands', |
| 54 | + '140' => 'Central African Republic', |
| 55 | + '148' => 'Chad', |
| 56 | + '152' => 'Chile', |
| 57 | + '156' => 'China', |
| 58 | + '162' => 'Christmas Island', |
| 59 | + '166' => 'Cocos (Keeling) Islands', |
| 60 | + '017' => 'Colombia', |
| 61 | + '174' => 'Comoros', |
| 62 | + '178' => 'Congo', |
| 63 | + '180' => 'Congo, the Democratic Republic of the', |
| 64 | + '184' => 'Cook Islands', |
| 65 | + '188' => 'Costa Rica', |
| 66 | + '384' => "Côte d'Ivoire", |
| 67 | + '191' => 'Croatia (Hrvatska)', |
| 68 | + '192' => 'Cuba', |
| 69 | + '196' => 'Cyprus', |
| 70 | + '203' => 'Czech Republic', |
| 71 | + '208' => 'Denmark', |
| 72 | + '262' => 'Djibouti', |
| 73 | + '212' => 'Dominica', |
| 74 | + '214' => 'Dominican Republic', |
| 75 | + '626' => 'East Timor', |
| 76 | + '218' => 'Ecuador', |
| 77 | + '818' => 'Egypt', |
| 78 | + '222' => 'El Salvador', |
| 79 | + '226' => 'Equatorial Guinea', |
| 80 | + '232' => 'Eritrea', |
| 81 | + '233' => 'Estonia', |
| 82 | + '231' => 'Ethiopia', |
| 83 | + '238' => 'Falkland Islands (Malvinas)', |
| 84 | + '234' => 'Faroe Islands', |
| 85 | + '242' => 'Fiji', |
| 86 | + '246' => 'Finland', |
| 87 | + '250' => 'France', |
| 88 | + '254' => 'French Guiana', |
| 89 | + '258' => 'French Polynesia', |
| 90 | + '260' => 'French Southern Territories', |
| 91 | + '266' => 'Gabon', |
| 92 | + '270' => 'Gambia', |
| 93 | + '268' => 'Georgia', |
| 94 | + '276' => 'Germany', |
| 95 | + '288' => 'Ghana', |
| 96 | + '292' => 'Gibraltar', |
| 97 | + '300' => 'Greece', |
| 98 | + '304' => 'Greenland', |
| 99 | + '308' => 'Grenada', |
| 100 | + '312' => 'Guadeloupe', |
| 101 | + '316' => 'Guam', |
| 102 | + '320' => 'Guatemala', |
| 103 | + '324' => 'Guinea', |
| 104 | + '624' => 'Guinea-Bissau', |
| 105 | + '328' => 'Guyana', |
| 106 | + '332' => 'Haiti', |
| 107 | + '334' => 'Heard Island and McDonald Islands', |
| 108 | + '340' => 'Honduras', |
| 109 | + '344' => 'Hong Kong', |
| 110 | + '348' => 'Hungary', |
| 111 | + '352' => 'Iceland', |
| 112 | + '356' => 'India', |
| 113 | + '360' => 'Indonesia', |
| 114 | + '364' => 'Iran, Islamic Republic of', |
| 115 | + '368' => 'Iraq', |
| 116 | + '372' => 'Ireland', |
| 117 | + '376' => 'Israel', |
| 118 | + '380' => 'Italy', |
| 119 | + '388' => 'Jamaica', |
| 120 | + '392' => 'Japan', |
| 121 | + '400' => 'Jordan', |
| 122 | + '398' => 'Kazakhstan', |
| 123 | + '404' => 'Kenya', |
| 124 | + '296' => 'Kiribati', |
| 125 | + '408' => "Korea, Democratic People's Republic of", |
| 126 | + '410' => 'Korea, Republic of', |
| 127 | + '414' => 'Kuwait', |
| 128 | + '417' => 'Kyrgyzstan', |
| 129 | + '418' => 'Lao People\'s Democratic Republic', |
| 130 | + '428' => 'Latvia', |
| 131 | + '422' => 'Lebanon', |
| 132 | + '426' => 'Lesotho', |
| 133 | + '430' => 'Liberia', |
| 134 | + '434' => 'Libyan Arab Jamahiriya', |
| 135 | + '438' => 'Liechtenstein', |
| 136 | + '440' => 'Lithuania', |
| 137 | + '442' => 'Luxembourg', |
| 138 | + '446' => 'Macao', |
| 139 | + '807' => 'Macedonia, the former Yugoslav Republic of', |
| 140 | + '450' => 'Madagascar', |
| 141 | + '454' => 'Malawi', |
| 142 | + '458' => 'Malaysia', |
| 143 | + '462' => 'Maldives', |
| 144 | + '466' => 'Mali', |
| 145 | + '470' => 'Malta', |
| 146 | + '584' => 'Marshall Islands', |
| 147 | + '474' => 'Martinique', |
| 148 | + '478' => 'Mauritania', |
| 149 | + '480' => 'Mauritius', |
| 150 | + '175' => 'Mayotte', |
| 151 | + '484' => 'Mexico', |
| 152 | + '583' => 'Micronesia, Federated States of', |
| 153 | + '498' => 'Moldova, Republic of', |
| 154 | + '492' => 'Monaco', |
| 155 | + '496' => 'Mongolia', |
| 156 | + '499' => 'Montenegro', |
| 157 | + '500' => 'Montserrat', |
| 158 | + '504' => 'Morocco', |
| 159 | + '508' => 'Mozambique', |
| 160 | + '104' => 'Myanmar', |
| 161 | + '516' => 'Namibia', |
| 162 | + '520' => 'Nauru', |
| 163 | + '524' => 'Nepal', |
| 164 | + '528' => 'Netherlands', |
| 165 | + '530' => 'Netherlands Antilles', |
| 166 | + '540' => 'New Caledonia', |
| 167 | + '554' => 'New Zealand', |
| 168 | + '558' => 'Nicaragua', |
| 169 | + '562' => 'Niger', |
| 170 | + '566' => 'Nigeria', |
| 171 | + '570' => 'Niue', |
| 172 | + '574' => 'Norfolk Island', |
| 173 | + '580' => 'Northern Mariana Islands', |
| 174 | + '578' => 'Norway', |
| 175 | + '512' => 'Oman', |
| 176 | + '586' => 'Pakistan', |
| 177 | + '585' => 'Palau', |
| 178 | + '591' => 'Panama', |
| 179 | + '598' => 'Papua New Guinea', |
| 180 | + '600' => 'Paraguay', |
| 181 | + '604' => 'Peru', |
| 182 | + '608' => 'Philippines', |
| 183 | + '612' => 'Pitcairn', |
| 184 | + '616' => 'Poland', |
| 185 | + '620' => 'Portugal', |
| 186 | + '630' => 'Puerto Rico', |
| 187 | + '634' => 'Qatar', |
| 188 | + '638' => 'Réunion', |
| 189 | + '642' => 'Romania', |
| 190 | + '643' => 'Russian Federation', |
| 191 | + '646' => 'Rwanda', |
| 192 | + '659' => 'Saint Kitts and Nevis', |
| 193 | + '662' => 'Saint Lucia', |
| 194 | + '670' => 'Saint Vincent and the Grenadines', |
| 195 | + '882' => 'Samoa', |
| 196 | + '674' => 'San Marino', |
| 197 | + '678' => 'Sao Tome and Principe', |
| 198 | + '682' => 'Saudi Arabia', |
| 199 | + '686' => 'Senegal', |
| 200 | + '690' => 'Seychelles', |
| 201 | + '694' => 'Sierra Leone', |
| 202 | + '702' => 'Singapore', |
| 203 | + '703' => 'Slovakia', |
| 204 | + '705' => 'Slovenia', |
| 205 | + '090' => 'Solomon Islands', |
| 206 | + '706' => 'Somalia', |
| 207 | + '710' => 'South Africa', |
| 208 | + '239' => 'South Georgia and the South Sandwich Islands', |
| 209 | + '724' => 'Spain', |
| 210 | + '144' => 'Sri Lanka', |
| 211 | + '654' => 'Saint Helena', |
| 212 | + '666' => 'Saint Pierre and Miquelon', |
| 213 | + '736' => 'Sudan', |
| 214 | + '740' => 'Suriname', |
| 215 | + '744' => 'Svalbard and Jan Mayen', |
| 216 | + '748' => 'Swaziland', |
| 217 | + '752' => 'Sweden', |
| 218 | + '756' => 'Switzerland', |
| 219 | + '760' => 'Syrian Arab Republic', |
| 220 | + '762' => 'Tajikistan', |
| 221 | + '834' => 'Tanzania, United Republic of', |
| 222 | + '158' => 'Taiwan, Province of China', |
| 223 | + '764' => 'Thailand', |
| 224 | + '768' => 'Togo', |
| 225 | + '772' => 'Tokelau', |
| 226 | + '776' => 'Tonga', |
| 227 | + '780' => 'Trinidad and Tobago', |
| 228 | + '788' => 'Tunisia', |
| 229 | + '792' => 'Turkey', |
| 230 | + '795' => 'Turkmenistan', |
| 231 | + '796' => 'Turks and Caicos Islands', |
| 232 | + '798' => 'Tuvalu', |
| 233 | + '800' => 'Uganda', |
| 234 | + '804' => 'Ukraine', |
| 235 | + '784' => 'United Arab Emirates', |
| 236 | + '826' => 'United Kingdom', |
| 237 | + '840' => 'United States', |
| 238 | + '581' => 'United States Minor Outlying Islands', |
| 239 | + '858' => 'Uruguay', |
| 240 | + '860' => 'Uzbekistan', |
| 241 | + '548' => 'Vanuatu', |
| 242 | + '336' => 'Vatican City State', |
| 243 | + '862' => 'Venezuela, Bolivarian Republic of', |
| 244 | + '704' => 'Viet Nam', |
| 245 | + '092' => 'Virgin Islands, British', |
| 246 | + '850' => 'Virgin Islands, U.S.', |
| 247 | + '876' => 'Wallis and Futuna', |
| 248 | + '732' => 'Western Sahara', |
| 249 | + '882' => 'Western Samoa', |
| 250 | + '887' => 'Yemen', |
| 251 | + '891' => 'Yugoslavia', |
| 252 | + '894' => 'Zambia', |
| 253 | + '716' => 'Zimbabwe' |
| 254 | + ); |
| 255 | + |
| 256 | + return $countryCode; |
| 257 | + } |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.i18n.php |
— | — | @@ -0,0 +1,9 @@ |
| 2 | +<?php |
| 3 | +$messages = array(); |
| 4 | + |
| 5 | +$messages['en'] = array( |
| 6 | + 'payflowprogateway' => 'Support Wikimedia', |
| 7 | + 'greeting' => '<h3>Support Wikimedia</h3>', |
| 8 | + 'form-message' => '<div id="mw-creditcard"><div class="mw-creditcard-intro"><p>Contribute with your credit card. (Other ways to give, including Paypal, check, or mail can be <a href="http://wikimediafoundation.org/wiki/Donate/WaysToGive/en"> found here</a>.)</p> |
| 9 | + <p>To change amount or currency, return to <a href="https://www.mediawiki.org/index.php?title=Donate"> the donation page</a></p></div>' |
| 10 | +); |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.php |
— | — | @@ -0,0 +1,86 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly. |
| 5 | +if (!defined('MEDIAWIKI')) { |
| 6 | + echo <<<EOT |
| 7 | +To install my extension, put the following line in LocalSettings.php: |
| 8 | +require_once( "\$IP/extensions/payflowpro_gateway/payflowpro_gateway.php" ); |
| 9 | +EOT; |
| 10 | + exit( 1 ); |
| 11 | +} |
| 12 | + |
| 13 | +$wgExtensionCredits['specialpage'][] = array( |
| 14 | + 'name' => 'PayflowPro Gateway', |
| 15 | + 'author' => 'Four Kitchens', |
| 16 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:PayflowProGateway', |
| 17 | + 'description' => 'Integrates Paypal Payflow Pro credit card processing', |
| 18 | + 'descriptionmsg' => 'payflowpro_gateway-desc', |
| 19 | + 'version' => '1.0.0', |
| 20 | +); |
| 21 | + |
| 22 | +$dir = dirname(__FILE__) . '/'; |
| 23 | + |
| 24 | + |
| 25 | +$wgAutoloadClasses['PayflowProGateway'] = $dir . 'payflowpro_gateway.body.php'; # Tell MediaWiki to load the extension body. |
| 26 | +$wgExtensionMessagesFiles['PayflowProGateway'] = $dir . 'payflowpro_gateway.i18n.php'; |
| 27 | +$wgExtensionAliasesFiles['PayflowProGateway'] = $dir . 'payflowpro_gateway.alias.php'; |
| 28 | +$wgSpecialPages['PayflowProGateway'] = 'PayflowProGateway'; # Let MediaWiki know about your new special page. |
| 29 | + |
| 30 | + |
| 31 | +/** |
| 32 | +* Hooks required to interface with the donation extension (include <donate> on page) |
| 33 | +* |
| 34 | +* gwValue supplies the value of the form option, the name that appears on the form |
| 35 | +* and the currencies supported by the gateway in the $values array |
| 36 | +*/ |
| 37 | +$wgHooks['gwValue'][] = 'pfpGatewayValue'; |
| 38 | +$wgHooks['gwPage'][] = 'pfpGatewayPage'; |
| 39 | + |
| 40 | +/* |
| 41 | +* Hook to register form value and display name of this gateway |
| 42 | +* also supplies currencies supported by this gateway |
| 43 | +*/ |
| 44 | +function pfpGatewayValue(&$values) { |
| 45 | + |
| 46 | + $values['payflow'] = array( |
| 47 | + 'gateway' => "payflow", |
| 48 | + 'display_name' => "Credit Card", |
| 49 | + 'form_value' => "payflow", |
| 50 | + 'currencies' => array( |
| 51 | + 'GBP' => "GBP: British Pound", |
| 52 | + 'EUR' => "EUR: Euro", |
| 53 | + 'USD' => "USD: U.S. Dollar", |
| 54 | + 'AUD' => "AUD: Australian Dollar", |
| 55 | + 'CAD' => "CAD: Canadian Dollar", |
| 56 | + 'CHF' => "CHF: Swiss Franc", |
| 57 | + 'CZK' => "CZK: Czech Koruna", |
| 58 | + 'DKK' => "DKK: Danish Krone", |
| 59 | + 'HKD' => "HKD: Hong Kong Dollar", |
| 60 | + 'HUF' => "HUF: Hungarian Forint", |
| 61 | + 'JPY' => "JPY: Japanese Yen", |
| 62 | + 'NZD' => "NZD: New Zealand Dollar", |
| 63 | + 'NOK' => "NOK: Norwegian Krone", |
| 64 | + 'PLN' => "PLN: Polish Zloty", |
| 65 | + 'SGD' => "SGD: Singapore Dollar", |
| 66 | + 'SEK' => "SEK: Swedish Krona", |
| 67 | + 'ILS' => "ILS: Isreali Shekel", |
| 68 | + ), |
| 69 | + ); |
| 70 | + |
| 71 | + return true; |
| 72 | +} |
| 73 | + |
| 74 | +/* |
| 75 | +* Hook to supply the page address of the payment gateway |
| 76 | +* |
| 77 | +* The user will redirected here with supplied data with input data appended (GET). |
| 78 | +* For example, if $url[$key] = index.php?title=Special:PayflowPro |
| 79 | +* the result might look like this: http://www.yourdomain.com/index.php?title=Special:PayflowPro&amount=75.00¤cy_code=USD&payment_method=payflow |
| 80 | +*/ |
| 81 | +function pfpGatewayPage(&$url) { |
| 82 | + global $wgScript; |
| 83 | + |
| 84 | + $url['payflow'] = $wgScript. "?title=Special:PayflowProGateway"; |
| 85 | + |
| 86 | + return true; |
| 87 | +} |
\ No newline at end of file |
Index: trunk/extensions/DonationInterface/paypal_gateway/paypal_gateway.il8n.php |
— | — | @@ -0,0 +1,6 @@ |
| 2 | +<?php |
| 3 | +$messages = array(); |
| 4 | + |
| 5 | +$messages['en'] = array( |
| 6 | + 'paypalgateway' => 'Paypal Gateway', |
| 7 | +); |
\ No newline at end of file |
Index: trunk/extensions/DonationInterface/paypal_gateway/paypal_gateway.php |
— | — | @@ -0,0 +1,82 @@ |
| 2 | +<?php |
| 3 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly. |
| 4 | +if (!defined('MEDIAWIKI')) { |
| 5 | + echo <<<EOT |
| 6 | +To install my extension, put the following line in LocalSettings.php: |
| 7 | +require_once( "\$IP/extensions/paypal_gateway/paypal_gateway.php" ); |
| 8 | +EOT; |
| 9 | + exit( 1 ); |
| 10 | +} |
| 11 | + |
| 12 | +$wgExtensionCredits['specialpage'][] = array( |
| 13 | + 'name' => 'Paypal Gateway', |
| 14 | + 'author' => 'Four Kitchens', |
| 15 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:PaypalGateway', |
| 16 | + 'description' => 'Registers paypal as a donation payment', |
| 17 | + 'descriptionmsg' => 'paypal_gateway-desc', |
| 18 | + 'version' => '1.0.0', |
| 19 | +); |
| 20 | + |
| 21 | + |
| 22 | +$dir = dirname(__FILE__) . '/'; |
| 23 | + |
| 24 | +$wgExtensionMessagesFiles['PaypalGateway'] = $dir . 'paypal_gateway.il8n.php'; |
| 25 | + |
| 26 | +/** |
| 27 | +* Hooks required to interface with the donation extension (include <donate> on page) |
| 28 | +* |
| 29 | +* gwValue supplies the value of the form option, the name that appears on the form |
| 30 | +* and the currencies supported by the gateway in the $values array |
| 31 | +*/ |
| 32 | +$wgHooks['gwValue'][] = 'paypalGatewayValue'; |
| 33 | +$wgHooks['gwPage'][] = 'paypalGatewayPage'; |
| 34 | + |
| 35 | +/* |
| 36 | +* Hook to register form value and display name of this gateway |
| 37 | +* also supplies currencies supported by this gateway |
| 38 | +*/ |
| 39 | +function paypalGatewayValue(&$values) { |
| 40 | + |
| 41 | + $values['paypal'] = array( |
| 42 | + 'gateway' => "paypal", |
| 43 | + 'display_name' => "Paypal", |
| 44 | + 'form_value' => "paypal", |
| 45 | + 'currencies' => array( |
| 46 | + 'GBP' => "GBP: British Pound", |
| 47 | + 'EUR' => "EUR: Euro", |
| 48 | + 'USD' => "USD: U.S. Dollar", |
| 49 | + 'AUD' => "AUD: Australian Dollar", |
| 50 | + 'CAD' => "CAD: Canadian Dollar", |
| 51 | + 'CHF' => "CHF: Swiss Franc", |
| 52 | + 'CZK' => "CZK: Czech Koruna", |
| 53 | + 'DKK' => "DKK: Danish Krone", |
| 54 | + 'HKD' => "HKD: Hong Kong Dollar", |
| 55 | + 'HUF' => "HUF: Hungarian Forint", |
| 56 | + 'JPY' => "JPY: Japanese Yen", |
| 57 | + 'NZD' => "NZD: New Zealand Dollar", |
| 58 | + 'NOK' => "NOK: Norwegian Krone", |
| 59 | + 'PLN' => "PLN: Polish Zloty", |
| 60 | + 'SGD' => "SGD: Singapore Dollar", |
| 61 | + 'SEK' => "SEK: Swedish Krona", |
| 62 | + 'ILS' => "ILS: Israeli Shekel", |
| 63 | + ), |
| 64 | + ); |
| 65 | + |
| 66 | + return true; |
| 67 | +} |
| 68 | + |
| 69 | +/* |
| 70 | +* Hook to supply the page address of the payment gateway |
| 71 | +* |
| 72 | +* The user will redirected here with amount and currency code appended (GET). |
| 73 | +* NOTE: $wgPaypalEmail is the business email associated with the Paypal account |
| 74 | +* It is set in the LocalSettings.php file |
| 75 | +*/ |
| 76 | +function paypalGatewayPage(&$url) { |
| 77 | + // Business email address set in LocalSettings.php |
| 78 | + global $wgPaypalEmail; |
| 79 | + |
| 80 | + $url['paypal'] = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=". urlencode($wgPaypalEmail) ."&lc=US&no_note=1&no_shipping=1&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; |
| 81 | + |
| 82 | + return true; |
| 83 | +} |
\ No newline at end of file |
Index: trunk/extensions/DonationInterface/donate_interface/donate_interface.setup.php |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +# Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly. |
| 5 | +if (!defined('MEDIAWIKI')) { |
| 6 | + echo <<<EOT |
| 7 | +To install my extension, put the following line in LocalSettings.php: |
| 8 | +require_once( "\$IP/extensions/donate_interface/donate_interface.php" ); |
| 9 | +EOT; |
| 10 | + exit( 1 ); |
| 11 | +} |
| 12 | + |
| 13 | + |
| 14 | +$dir = dirname(__FILE__) . '/'; |
| 15 | + |
| 16 | +$wgAutoloadClasses['donate_interface'] = $dir . 'donate_interface.php'; # Tell MediaWiki to load the extension body. |
| 17 | +$wgExtensionMessagesFiles['donate_interface'] = $dir . 'donate_interface.i18n.php'; |
\ No newline at end of file |
Index: trunk/extensions/DonationInterface/donate_interface/validate_donation.js |
— | — | @@ -0,0 +1,53 @@ |
| 2 | +//<![CDATA[ |
| 3 | +function validateForm( form ) { |
| 4 | + |
| 5 | + var minimums = { |
| 6 | + 'USD' : 1, |
| 7 | + 'GBP' : 1, // $1.26 |
| 8 | + 'EUR' : 1, // $1.26 |
| 9 | + 'AUD' : 2, // $1.35 |
| 10 | + 'CAD' : 1, // $0.84 |
| 11 | + 'CHF' : 1, // $0.85 |
| 12 | + 'CZK' : 20, // $1.03 |
| 13 | + 'DKK' : 5, // $0.85 |
| 14 | + 'HKD' : 10, // $1.29 |
| 15 | + 'HUF' : 200, // $0.97 |
| 16 | + 'JPY' : 100, // $1 |
| 17 | + 'NZD' : 2, // $1.18 |
| 18 | + 'NOK' : 10, // $1.44 |
| 19 | + 'PLN' : 5, // $1.78 |
| 20 | + 'SGD' : 2, // $1.35 |
| 21 | + 'SEK' : 10, // $1.28 |
| 22 | + }; |
| 23 | + |
| 24 | + var error = true; |
| 25 | + |
| 26 | + // Get amount selection |
| 27 | + var amount = null; |
| 28 | + for ( var i = 0; i < form.amount.length; i++ ) { |
| 29 | + if ( form.amount[i].checked ) { |
| 30 | + amount = form.amount[i].value; |
| 31 | + } |
| 32 | + } |
| 33 | + if ( form.amount2.value != "" ) { |
| 34 | + amount = form.amount2.value; |
| 35 | + } |
| 36 | + // Check amount is a real number |
| 37 | + error = ( amount == null || isNaN( amount ) || amount.value <= 0 ); |
| 38 | + if ( error ) { |
| 39 | + alert( 'You must enter a valid amount.' ); |
| 40 | + } |
| 41 | + |
| 42 | + // Check amount is at least the minimum |
| 43 | + var currency = form.currency_code[form.currency_code.selectedIndex].value; |
| 44 | + if ( typeof( minimums[currency] ) == 'undefined' ) { |
| 45 | + minimums[currency] = 1; |
| 46 | + } |
| 47 | + if ( amount < minimums[currency] ) { |
| 48 | + alert( 'You must contribute at least $1'.replace('$1', minimums[currency] + ' ' + currency ) ); |
| 49 | + error = true; |
| 50 | + } |
| 51 | + |
| 52 | + return !error; |
| 53 | +} |
| 54 | +//]]> |
Index: trunk/extensions/DonationInterface/donate_interface/donate_interface.php |
— | — | @@ -0,0 +1,146 @@ |
| 2 | +<?php |
| 3 | +//Avoid unstubbing $wgParser on setHook() too early on modern (1.12+) MW versions, as per r35980 |
| 4 | +if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) { |
| 5 | + $wgHooks['ParserFirstCallInit'][] = 'efDonateSetup'; |
| 6 | +} else { // Otherwise do things the old fashioned way |
| 7 | + $wgExtensionFunctions[] = 'efDonateSetup'; |
| 8 | +} |
| 9 | + |
| 10 | +/* |
| 11 | +* Create <donate /> tag to include landing page donation form |
| 12 | +*/ |
| 13 | +function efDonateSetup(&$parser) { |
| 14 | + global $wgParser, $wgOut, $wgRequest; |
| 15 | + |
| 16 | + $parser->disableCache(); |
| 17 | + |
| 18 | + $wgParser->setHook( 'donate', 'efDonateRender' ); |
| 19 | + |
| 20 | + |
| 21 | + // if form has been submitted, assign data and redirect user to chosen payment gateway |
| 22 | + if ($_POST['process'] == "_yes_") { |
| 23 | + //find out which amount option was chosen for amount, redefined buttons or text box |
| 24 | + if (isset($_POST['amount'])) { |
| 25 | + $amount = number_format($wgRequest->getText('amount'), 2); |
| 26 | + } else { $amount = number_format($wgRequest->getText('amount2'), 2, '.', ''); } |
| 27 | + |
| 28 | + // create array of user input |
| 29 | + $userInput = array ( |
| 30 | + 'currency' => $wgRequest->getText('currency_code'), |
| 31 | + 'amount' => $amount, |
| 32 | + 'payment_method' => $wgRequest->getText('payment_method') |
| 33 | + ); |
| 34 | + |
| 35 | + // ask payment processor extensions for their URL/page title |
| 36 | + wfRunHooks('gwPage', array(&$url)); |
| 37 | + |
| 38 | + // send user to correct page for payment |
| 39 | + redirectToProcessorPage($userInput, $url); |
| 40 | + |
| 41 | + }// end if form has been submitted |
| 42 | + |
| 43 | + return true; |
| 44 | +} |
| 45 | + |
| 46 | + |
| 47 | +/* |
| 48 | +* Function called by the <donate> parser tag |
| 49 | +* |
| 50 | +* Outputs the donation landing page form which collects |
| 51 | +* the donation amount, currency and payment processor type. |
| 52 | +* |
| 53 | +*/ |
| 54 | +function efDonateRender( $input, $args, &$parser) { |
| 55 | + global $wgOut; |
| 56 | + |
| 57 | + $parser->disableCache(); |
| 58 | + |
| 59 | + //add javascript validation to <head> |
| 60 | + $parser->mOutput->addHeadItem('<script type="text/javascript" language="javascript" src="/extensions/donate_interface/validate_donation.js"></script>'); |
| 61 | + |
| 62 | + //display form to gather data from user |
| 63 | + $output = createOutput(); |
| 64 | + |
| 65 | + return $output; |
| 66 | +} |
| 67 | + |
| 68 | +/* |
| 69 | +* Supplies the form to efDonateRender() |
| 70 | +* |
| 71 | +* Payment gateway options are created with the hook 'gwValue". Each potential payment |
| 72 | +* option supplies it's value and name for the form, as well as currencies it supports. |
| 73 | +*/ |
| 74 | +function createOutput() { |
| 75 | + |
| 76 | + //get payment method gateway value and name from each gateway and create menu of options |
| 77 | + $values = ''; |
| 78 | + wfRunHooks('gwValue', array(&$values)); |
| 79 | + |
| 80 | + foreach($values as $current) { |
| 81 | + $optionMenu .= '<option value='. $current['form_value'] . '>'. $current['display_name'] .'</option>'; |
| 82 | + } |
| 83 | + |
| 84 | + //get available currencies |
| 85 | + //NOTE: currently all available currencies are accepted by all developed gateways |
| 86 | + //the next version will include gateway/currency checking |
| 87 | + //and inform user of gateways that aren't an option for that currency |
| 88 | + foreach($values as $key) { |
| 89 | + $currencies = $key['currencies']; |
| 90 | + } |
| 91 | + |
| 92 | + foreach($currencies as $key => $value) { |
| 93 | + $currencyMenu .= '<option value='. $key .'>'. $value .'</option>'; |
| 94 | + } |
| 95 | + |
| 96 | + // form markup |
| 97 | + $output ='<form method="post" action="" name="donate" onsubmit="return validateForm(this)"> |
| 98 | + <div>Please choose a payment method, amount, and currency. (Other ways to give, including check or mail, can be <a href="https://www.mediawiki.org/wiki/Donate/WaysToGive/en" title="Donate/WaysToGive/en">found here</a>.)</div> |
| 99 | + <div>Donation Amount: </div> |
| 100 | + <div id="amount_box"> |
| 101 | + <input type="hidden" name="title" value="Special:PayflowPro" /> |
| 102 | + <input type="radio" name="amount" id="input_amount_3" value="100" /> |
| 103 | + <label for="input_amount_3">$100</label> |
| 104 | + <input type="radio" name="amount" id="input_amount_2" value="75" /> |
| 105 | + <label for="input_amount_2">$75</label> |
| 106 | + <input type="radio" name="amount" id="input_amount_1" value="30" /> |
| 107 | + <label for="input_amount_1">$30</label> |
| 108 | + <label for="input_amount_other">Other: </label> <input type="text" name="amount2" size="5" /> |
| 109 | + <!-- currency menu --> |
| 110 | + <p>Select Currency</p> |
| 111 | + <select name="currency_code" id="input_currency_code" size="1"> |
| 112 | + <option value="USD" selected="selected">USD: U.S. Dollar</option> |
| 113 | + <option value="XXX">-------</option> |
| 114 | + '. $currencyMenu .' |
| 115 | + </select></div> |
| 116 | + <div>Payment method: |
| 117 | + <select name="payment_method" id="select_payment_method"> |
| 118 | + '.$optionMenu.' |
| 119 | + </select></div> |
| 120 | + <input type="hidden" name="process" value="_yes_" /> |
| 121 | + <br /> |
| 122 | + <input class="red-input-button" type="submit" value="DONATE"/> |
| 123 | + </form>'; |
| 124 | + |
| 125 | + return $output; |
| 126 | +} |
| 127 | + |
| 128 | + |
| 129 | +/* |
| 130 | +* Redirects user to their chosen payment processor |
| 131 | +* |
| 132 | +* Includes the user's input passed as GET |
| 133 | +* $url for the gateway was supplied with the gwPage hook and the key |
| 134 | +* matches the form value (also supplied by the gateway) |
| 135 | +*/ |
| 136 | +function redirectToProcessorPage($userInput, $url) { |
| 137 | + global $wgOut; |
| 138 | + |
| 139 | + $chosenGateway = $userInput['payment_method']; |
| 140 | + |
| 141 | + $wgOut->redirect($url[$chosenGateway].'&amount='.$userInput['amount'].'¤cy_code='.$userInput['currency']); |
| 142 | + |
| 143 | +} |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | + |
Index: trunk/extensions/DonationInterface/donate_interface/donate_interface.il8n.php |
— | — | @@ -0,0 +1,6 @@ |
| 2 | +<?php |
| 3 | +$messages = array(); |
| 4 | + |
| 5 | +$messages['en'] = array( |
| 6 | + 'donate_interface' => 'Support Wikimedia', |
| 7 | +); |
\ No newline at end of file |