PMProGateway_cybersource

The Paid Memberships Pro PMProGateway cybersource class.

Defined (1)

The class is defined in the following location(s).

/classes/gateways/class.pmprogateway_cybersource.php  
  1. class PMProGateway_cybersource extends PMProGateway 
  2. function __construct($gateway = NULL) 
  3. if(!class_exists("CyberSourceSoapClient")) 
  4. require_once(dirname(__FILE__) . "/../../includes/lib/CyberSource/cyber_source_soap_client.php"); 
  5.  
  6. $this->gateway = $gateway; 
  7. return $this->gateway; 
  8. }  
  9.  
  10. /** 
  11. * Run on WP init 
  12. *  
  13. * @since 1.8 
  14. */ 
  15. static function init() 
  16. {  
  17. //make sure CyberSource is a gateway option 
  18. add_filter('pmpro_gateways', array('PMProGateway_cybersource', 'pmpro_gateways')); 
  19.  
  20. //add fields to payment settings 
  21. add_filter('pmpro_payment_options', array('PMProGateway_cybersource', 'pmpro_payment_options')); 
  22. add_filter('pmpro_payment_option_fields', array('PMProGateway_cybersource', 'pmpro_payment_option_fields'), 10, 2);  
  23.  
  24. /** 
  25. * Make sure this gateway is in the gateways list 
  26. *  
  27. * @since 1.8 
  28. */ 
  29. static function pmpro_gateways($gateways) 
  30. if(empty($gateways['cybersource'])) 
  31. $gateways['cybersource'] = __('CyberSource', 'paid-memberships-pro' ); 
  32.  
  33. return $gateways; 
  34.  
  35. /** 
  36. * Get a list of payment options that the this gateway needs/supports. 
  37. *  
  38. * @since 1.8 
  39. */ 
  40. static function getGatewayOptions() 
  41. {  
  42. $options = array( 
  43. 'sslseal',  
  44. 'nuclear_HTTPS',  
  45. 'gateway_environment',  
  46. 'cybersource_merchantid',  
  47. 'cybersource_securitykey',  
  48. 'currency',  
  49. 'use_ssl',  
  50. 'tax_state',  
  51. 'tax_rate',  
  52. 'accepted_credit_cards' 
  53. ); 
  54.  
  55. return $options; 
  56.  
  57. /** 
  58. * Set payment options for payment settings page. 
  59. *  
  60. * @since 1.8 
  61. */ 
  62. static function pmpro_payment_options($options) 
  63. {  
  64. //get stripe options 
  65. $cybersource_options = PMProGateway_cybersource::getGatewayOptions(); 
  66.  
  67. //merge with others. 
  68. $options = array_merge($cybersource_options, $options); 
  69.  
  70. return $options; 
  71.  
  72. /** 
  73. * Display fields for this gateway's options. 
  74. *  
  75. * @since 1.8 
  76. */ 
  77. static function pmpro_payment_option_fields($values, $gateway) 
  78. ?> 
  79. <tr class="pmpro_settings_divider gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>> 
  80. <td colspan="2"> 
  81. <?php _e('CyberSource Settings', 'paid-memberships-pro' ); ?> 
  82. </td> 
  83. </tr> 
  84. <tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>> 
  85. <td colspan="2"> 
  86. <strong><?php _e('Note', 'paid-memberships-pro' );?>:</strong> <?php _e('This gateway option is in beta. Some functionality may not be available. Please contact Paid Memberships Pro with any issues you run into. <strong>Please be sure to upgrade Paid Memberships Pro to the latest versions when available.</strong>', 'paid-memberships-pro' );?> 
  87. </td>  
  88. </tr> 
  89. <tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>> 
  90. <th scope="row" valign="top"> 
  91. <label for="cybersource_merchantid"><?php _e('Merchant ID', 'paid-memberships-pro' );?>:</label> 
  92. </th> 
  93. <td> 
  94. <input type="text" id="cybersource_merchantid" name="cybersource_merchantid" size="60" value="<?php echo esc_attr($values['cybersource_merchantid'])?>" /> 
  95. </td> 
  96. </tr> 
  97. <tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>> 
  98. <th scope="row" valign="top"> 
  99. <label for="cybersource_securitykey"><?php _e('Transaction Security Key', 'paid-memberships-pro' );?>:</label> 
  100. </th> 
  101. <td> 
  102. <textarea id="cybersource_securitykey" name="cybersource_securitykey" rows="3" cols="80"><?php echo esc_textarea($values['cybersource_securitykey']);?></textarea>  
  103. </td> 
  104. </tr> 
  105. <?php 
  106.  
  107. /** 
  108. * Process checkout. 
  109. */ 
  110. function process(&$order) 
  111. //check for initial payment 
  112. if(floatval($order->InitialPayment) == 0) 
  113. //auth first, then process 
  114. if($this->authorize($order)) 
  115. {  
  116. $this->void($order);  
  117. if(!pmpro_isLevelTrial($order->membership_level)) 
  118. //subscription will start today with a 1 period trial 
  119. $order->ProfileStartDate = date_i18n("Y-m-d") . "T0:0:0"; 
  120. $order->TrialBillingPeriod = $order->BillingPeriod; 
  121. $order->TrialBillingFrequency = $order->BillingFrequency;  
  122. $order->TrialBillingCycles = 1; 
  123. $order->TrialAmount = 0; 
  124.  
  125. //add a billing cycle to make up for the trial, if applicable 
  126. if(!empty($order->TotalBillingCycles)) 
  127. $order->TotalBillingCycles++; 
  128. elseif($order->InitialPayment == 0 && $order->TrialAmount == 0) 
  129. //it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there 
  130. $order->ProfileStartDate = date_i18n("Y-m-d") . "T0:0:0";  
  131. $order->TrialBillingCycles++; 
  132.  
  133. //add a billing cycle to make up for the trial, if applicable 
  134. if($order->TotalBillingCycles) 
  135. $order->TotalBillingCycles++; 
  136. else 
  137. //add a period to the start date to account for the initial payment 
  138. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0"; 
  139.  
  140. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order); 
  141. return $this->subscribe($order); 
  142. else 
  143. if(empty($order->error)) 
  144. $order->error = __("Unknown error: Authorization failed.", 'paid-memberships-pro' ); 
  145. return false; 
  146. else 
  147. //charge first payment 
  148. if($this->charge($order)) 
  149. //set up recurring billing  
  150. if(pmpro_isLevelRecurring($order->membership_level)) 
  151. {  
  152. if(!pmpro_isLevelTrial($order->membership_level)) 
  153. //subscription will start today with a 1 period trial 
  154. $order->ProfileStartDate = date_i18n("Y-m-d") . "T0:0:0"; 
  155. $order->TrialBillingPeriod = $order->BillingPeriod; 
  156. $order->TrialBillingFrequency = $order->BillingFrequency;  
  157. $order->TrialBillingCycles = 1; 
  158. $order->TrialAmount = 0; 
  159.  
  160. //add a billing cycle to make up for the trial, if applicable 
  161. if(!empty($order->TotalBillingCycles)) 
  162. $order->TotalBillingCycles++; 
  163. elseif($order->InitialPayment == 0 && $order->TrialAmount == 0) 
  164. //it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there 
  165. $order->ProfileStartDate = date_i18n("Y-m-d") . "T0:0:0";  
  166. $order->TrialBillingCycles++; 
  167.  
  168. //add a billing cycle to make up for the trial, if applicable 
  169. if(!empty($order->TotalBillingCycles)) 
  170. $order->TotalBillingCycles++; 
  171. else 
  172. //add a period to the start date to account for the initial payment 
  173. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0"; 
  174.  
  175. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order); 
  176. if($this->subscribe($order)) 
  177. return true; 
  178. else 
  179. if($this->void($order)) 
  180. if(!$order->error) 
  181. $order->error = __("Unknown error: Payment failed.", 'paid-memberships-pro' ); 
  182. else 
  183. if(!$order->error) 
  184. $order->error = __("Unknown error: Payment failed.", 'paid-memberships-pro' ); 
  185.  
  186. $order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", 'paid-memberships-pro' ); 
  187.  
  188. return false;  
  189. else 
  190. //only a one time charge 
  191. $order->status = "success"; //saved on checkout page  
  192. return true; 
  193. else 
  194. if(empty($order->error)) 
  195. $order->error = __("Unknown error: Payment failed.", 'paid-memberships-pro' ); 
  196.  
  197. return false; 
  198. }  
  199. }  
  200.  
  201. function getCardType($name) 
  202. $card_types = array( 
  203. 'Visa' => '001',  
  204. 'MasterCard' => '002',  
  205. 'Master Card' => '002',  
  206. 'AMEX' => '003',  
  207. 'American Express' => '003',  
  208. 'Discover' => '004',  
  209. 'Diners Club' => '005',  
  210. 'Carte Blanche' => '006',  
  211. 'JCB' => '007'  
  212. ); 
  213.  
  214. if(isset($card_types[$name])) 
  215. return $card_types[$name]; 
  216. else 
  217. return false; 
  218.  
  219. function getWSDL($order) 
  220. //which gateway environment? 
  221. if(empty($order->gateway_environment)) 
  222. $gateway_environment = pmpro_getOption("gateway_environment"); 
  223. else 
  224. $gateway_environment = $order->gateway_environment; 
  225.  
  226. //which host? 
  227. if($gateway_environment == "live") 
  228. $host = "ics2ws.ic3.com";  
  229. else 
  230. $host = "ics2wstest.ic3.com";  
  231.  
  232. //path 
  233. $path = "/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.90.wsdl";  
  234.  
  235. //build url 
  236. $wsdl_url = "https://" . $host . $path; 
  237.  
  238. //filter 
  239. $wsdl_url = apply_filters("pmpro_cybersource_wsdl_url", $wsdl_url, $gateway_environment); 
  240.  
  241. return $wsdl_url; 
  242.  
  243. function authorize(&$order) 
  244. global $pmpro_currency; 
  245.  
  246. if(empty($order->code)) 
  247. $order->code = $order->getRandomCode(); 
  248.  
  249. $wsdl_url = $this->getWSDL($order); 
  250.  
  251. //what amount to authorize? just $1 to test 
  252. $amount = "1.00";  
  253.  
  254. //combine address  
  255. $address = $order->Address1; 
  256. if(!empty($order->Address2)) 
  257. $address .= "\n" . $order->Address2; 
  258.  
  259. //customer stuff 
  260. $customer_email = $order->Email; 
  261. $customer_phone = $order->billing->phone; 
  262.  
  263. if(!isset($order->membership_level->name)) 
  264. $order->membership_level->name = ""; 
  265.  
  266. //to store our request 
  267. $request = new stdClass(); 
  268.  
  269. //which service? 
  270. $ccAuthService = new stdClass(); 
  271. $ccAuthService->run = "true"; 
  272. $request->ccAuthService = $ccAuthService; 
  273.  
  274. //merchant id and order code 
  275. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  276. $request->merchantReferenceCode = $order->code; 
  277.  
  278. //bill to 
  279. $billTo = new stdClass(); 
  280. $billTo->firstName = $order->FirstName; 
  281. $billTo->lastName = $order->LastName; 
  282. $billTo->street1 = $address; 
  283. $billTo->city = $order->billing->city; 
  284. $billTo->state = $order->billing->state; 
  285. $billTo->postalCode = $order->billing->zip; 
  286. $billTo->country = $order->billing->country; 
  287. $billTo->email = $order->Email; 
  288. $billTo->ipAddress = $_SERVER['REMOTE_ADDR']; 
  289. $request->billTo = $billTo; 
  290.  
  291. //card 
  292. $card = new stdClass(); 
  293. $card->cardType = $this->getCardType($order->cardtype); 
  294. $card->accountNumber = $order->accountnumber; 
  295. $card->expirationMonth = $order->expirationmonth; 
  296. $card->expirationYear = $order->expirationyear; 
  297. $card->cvNumber = $order->CVV2; 
  298. $request->card = $card; 
  299.  
  300. //currency 
  301. $purchaseTotals = new stdClass(); 
  302. $purchaseTotals->currency = $pmpro_currency; 
  303. $request->purchaseTotals = $purchaseTotals; 
  304.  
  305. //item/price 
  306. $item0 = new stdClass(); 
  307. $item0->unitPrice = $amount; 
  308. $item0->quantity = "1"; 
  309. $item0->productName = $order->membership_level->name . " Membership"; 
  310. $item0->productSKU = $order->membership_level->id; 
  311. $item0->id = $order->membership_id;  
  312. $request->item = array($item0); 
  313.  
  314. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  315. $reply = $soapClient->runTransaction($request); 
  316.  
  317. if($reply->reasonCode == "100") 
  318. //success 
  319. $order->payment_transaction_id = $reply->requestID; 
  320. $order->updateStatus("authorized");  
  321. return true; 
  322. else 
  323. //error 
  324. $order->errorcode = $reply->reasonCode; 
  325. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  326. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  327. return false; 
  328. }  
  329.  
  330. function void(&$order) 
  331. //need a transaction id 
  332. if(empty($order->payment_transaction_id)) 
  333. return false; 
  334.  
  335. //get wsdl 
  336. $wsdl_url = $this->getWSDL($order); 
  337.  
  338. //to store our request 
  339. $request = new stdClass(); 
  340.  
  341. //which service? 
  342. $voidService = new stdClass(); 
  343. $voidService->run = "true"; 
  344. $voidService->voidRequestID = $order->payment_transaction_id; 
  345. $request->voidService = $voidService; 
  346.  
  347. //merchant id and order code 
  348. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  349. $request->merchantReferenceCode = $order->code;  
  350.  
  351. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  352. $reply = $soapClient->runTransaction($request); 
  353.  
  354. if($reply->reasonCode == "100") 
  355. //success 
  356. $order->payment_transaction_id = $reply->requestID; 
  357. $order->updateStatus("voided");  
  358. return true; 
  359. else 
  360. //error 
  361. $order->errorcode = $reply->reasonCode; 
  362. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  363. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  364. return false; 
  365. }  
  366. }  
  367.  
  368. function charge(&$order) 
  369. global $pmpro_currency; 
  370.  
  371. //get a code 
  372. if(empty($order->code)) 
  373. $order->code = $order->getRandomCode(); 
  374.  
  375. //get wsdl 
  376. $wsdl_url = $this->getWSDL($order); 
  377.  
  378. //what amount to charge?  
  379. $amount = $order->InitialPayment; 
  380.  
  381. //tax 
  382. $order->subtotal = $amount; 
  383. $tax = $order->getTax(true); 
  384. $amount = round((float)$order->subtotal + (float)$tax, 2); 
  385.  
  386. //combine address  
  387. $address = $order->Address1; 
  388. if(!empty($order->Address2)) 
  389. $address .= "\n" . $order->Address2; 
  390.  
  391. //customer stuff 
  392. $customer_email = $order->Email; 
  393. $customer_phone = $order->billing->phone; 
  394.  
  395. if(!isset($order->membership_level->name)) 
  396. $order->membership_level->name = ""; 
  397.  
  398. //to store our request 
  399. $request = new stdClass(); 
  400.  
  401. //authorize and capture  
  402. $ccAuthService = new stdClass(); 
  403. $ccAuthService->run = "true"; 
  404. $request->ccAuthService = $ccAuthService; 
  405.  
  406. $ccCaptureService = new stdClass(); 
  407. $ccCaptureService->run = "true"; 
  408. $request->ccCaptureService = $ccCaptureService; 
  409.  
  410. //merchant id and order code 
  411. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  412. $request->merchantReferenceCode = $order->code; 
  413.  
  414. //bill to 
  415. $billTo = new stdClass(); 
  416. $billTo->firstName = $order->FirstName; 
  417. $billTo->lastName = $order->LastName; 
  418. $billTo->street1 = $address; 
  419. $billTo->city = $order->billing->city; 
  420. $billTo->state = $order->billing->state; 
  421. $billTo->postalCode = $order->billing->zip; 
  422. $billTo->country = $order->billing->country; 
  423. $billTo->email = $order->Email; 
  424. $billTo->ipAddress = $_SERVER['REMOTE_ADDR']; 
  425. $request->billTo = $billTo; 
  426.  
  427. //card 
  428. $card = new stdClass(); 
  429. $card->cardType = $this->getCardType($order->cardtype); 
  430. $card->accountNumber = $order->accountnumber; 
  431. $card->expirationMonth = $order->expirationmonth; 
  432. $card->expirationYear = $order->expirationyear; 
  433. $card->cvNumber = $order->CVV2; 
  434. $request->card = $card; 
  435.  
  436. //currency 
  437. $purchaseTotals = new stdClass(); 
  438. $purchaseTotals->currency = $pmpro_currency; 
  439. $request->purchaseTotals = $purchaseTotals; 
  440.  
  441. //item/price 
  442. $item0 = new stdClass(); 
  443. $item0->unitPrice = $amount; 
  444. $item0->quantity = "1"; 
  445. $item0->productName = $order->membership_level->name . " Membership"; 
  446. $item0->productSKU = $order->membership_level->id; 
  447. $item0->id = $order->membership_id;  
  448. $request->item = array($item0); 
  449.  
  450. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  451. $reply = $soapClient->runTransaction($request); 
  452.  
  453. if($reply->reasonCode == "100") 
  454. //success 
  455. $order->payment_transaction_id = $reply->requestID; 
  456. $order->updateStatus("success");  
  457. return true; 
  458. else 
  459. //error 
  460. $order->errorcode = $reply->reasonCode; 
  461. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  462. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  463. return false; 
  464. }  
  465.  
  466. function subscribe(&$order) 
  467. global $pmpro_currency; 
  468.  
  469. //create a code for the order 
  470. if(empty($order->code)) 
  471. $order->code = $order->getRandomCode(); 
  472.  
  473. //filter order before subscription. use with care. 
  474. $order = apply_filters("pmpro_subscribe_order", $order, $this); 
  475.  
  476. //get wsdl 
  477. $wsdl_url = $this->getWSDL($order); 
  478.  
  479. //to store our request 
  480. $request = new stdClass(); 
  481.  
  482. //set service type 
  483. $paySubscriptionCreateService = new stdClass(); 
  484. $paySubscriptionCreateService->run = 'true'; 
  485. $paySubscriptionCreateService->disableAutoAuth = 'true'; //we do our own auth check 
  486. $request->paySubscriptionCreateService = $paySubscriptionCreateService; 
  487.  
  488. //merchant id and order code 
  489. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  490. $request->merchantReferenceCode = $order->code; 
  491.  
  492. /** 
  493. set up billing amount/etc 
  494. */ 
  495. //figure out the amounts 
  496. $amount = $order->PaymentAmount; 
  497. $amount_tax = $order->getTaxForPrice($amount);  
  498. $amount = round((float)$amount + (float)$amount_tax, 2); 
  499.  
  500. /** 
  501. There are two parts to the trial. Part 1 is simply the delay until the first payment 
  502. since we are doing the first payment as a separate transaction. 
  503. The second part is the actual "trial" set by the admin.  
  504. */ 
  505. //figure out the trial length (first payment handled by initial charge)  
  506. if($order->BillingPeriod == "Year") 
  507. $trial_period_days = $order->BillingFrequency * 365; //annual 
  508. elseif($order->BillingPeriod == "Day") 
  509. $trial_period_days = $order->BillingFrequency * 1; //daily 
  510. elseif($order->BillingPeriod == "Week") 
  511. $trial_period_days = $order->BillingFrequency * 7; //weekly 
  512. else 
  513. $trial_period_days = $order->BillingFrequency * 30; //assume monthly 
  514.  
  515. //convert to a profile start date 
  516. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0"; 
  517.  
  518. //filter the start date 
  519. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);  
  520.  
  521. //convert back to days 
  522. $trial_period_days = ceil(abs(strtotime(date_i18n("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400); 
  523.  
  524. //now add the actual trial set by the site 
  525. if(!empty($order->TrialBillingCycles))  
  526. $trialOccurrences = (int)$order->TrialBillingCycles; 
  527. if($order->BillingPeriod == "Year") 
  528. $trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual 
  529. elseif($order->BillingPeriod == "Day") 
  530. $trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily 
  531. elseif($order->BillingPeriod == "Week") 
  532. $trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly 
  533. else 
  534. $trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly  
  535.  
  536. //convert back into a date 
  537. $profile_start_date = date_i18n("Ymd", strtotime("+ " . $trial_period_days . " Days")); 
  538.  
  539. //figure out the frequency 
  540. if($order->BillingPeriod == "Year") 
  541. $frequency = "annually"; //ignoring BillingFrequency set on level.  
  542. elseif($order->BillingPeriod == "Month") 
  543. if($order->BillingFrequency == 6) 
  544. $frequency = "semi annually"; 
  545. elseif($order->BillingFrequency == 3) 
  546. $frequency = "quarterly"; 
  547. else 
  548. $frequency = "monthly"; 
  549. elseif($order->BillingPeriod == "Week") 
  550. if($order->BillingFrequency == 4) 
  551. $frequency = "quad-weekly"; 
  552. elseif($order->BillingFrequency == 2) 
  553. $frequency = "bi-weekly"; 
  554. else 
  555. $frequency = "weekly"; 
  556. elseif($order->BillingPeriod == "Day") 
  557. if($order->BillingFrequency == 365) 
  558. $frequency = "annually"; 
  559. elseif($order->BillingFrequency == 182) 
  560. $frequency = "semi annually"; 
  561. elseif($order->BillingFrequency == 183) 
  562. $frequency = "semi annually"; 
  563. elseif($order->BillingFrequency == 90) 
  564. $frequency = "quaterly"; 
  565. elseif($order->BillingFrequency == 30) 
  566. $frequency = "monthly"; 
  567. elseif($order->BillingFrequency == 15) 
  568. $frequency = "semi-monthly"; 
  569. elseif($order->BillingFrequency == 28) 
  570. $frequency = "quad-weekly"; 
  571. elseif($order->BillingFrequency == 14) 
  572. $frequency = "bi-weekly"; 
  573. elseif($order->BillingFrequency == 7) 
  574. $frequency = "weekly";  
  575. }  
  576.  
  577. //set subscription info for API 
  578. $subscription = new stdClass(); 
  579. $subscription->title = $order->membership_level->name; 
  580. $subscription->paymentMethod = "credit card"; 
  581. $request->subscription = $subscription; 
  582.  
  583. //recurring info  
  584. $recurringSubscriptionInfo = new stdClass(); 
  585. $recurringSubscriptionInfo->amount = number_format($amount, 2);  
  586. $recurringSubscriptionInfo->startDate = $profile_start_date; 
  587. $recurringSubscriptionInfo->frequency = $frequency; 
  588. if(!empty($order->TotalBillingCycles)) 
  589. $recurringSubscriptionInfo->numberOfPayments = $order->TotalBillingCycles;  
  590. $request->recurringSubscriptionInfo = $recurringSubscriptionInfo; 
  591.  
  592. //combine address  
  593. $address = $order->Address1; 
  594. if(!empty($order->Address2)) 
  595. $address .= "\n" . $order->Address2; 
  596.  
  597. //bill to 
  598. $billTo = new stdClass(); 
  599. $billTo->firstName = $order->FirstName; 
  600. $billTo->lastName = $order->LastName; 
  601. $billTo->street1 = $address; 
  602. $billTo->city = $order->billing->city; 
  603. $billTo->state = $order->billing->state; 
  604. $billTo->postalCode = $order->billing->zip; 
  605. $billTo->country = $order->billing->country; 
  606. $billTo->email = $order->Email; 
  607. $billTo->ipAddress = $_SERVER['REMOTE_ADDR']; 
  608. $request->billTo = $billTo; 
  609.  
  610. //card 
  611. $card = new stdClass(); 
  612. $card->cardType = $this->getCardType($order->cardtype); 
  613. $card->accountNumber = $order->accountnumber; 
  614. $card->expirationMonth = $order->expirationmonth; 
  615. $card->expirationYear = $order->expirationyear; 
  616. $card->cvNumber = $order->CVV2; 
  617. $request->card = $card; 
  618.  
  619. //currency 
  620. $purchaseTotals = new stdClass(); 
  621. $purchaseTotals->currency = $pmpro_currency; 
  622. $request->purchaseTotals = $purchaseTotals;  
  623.  
  624. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  625. $reply = $soapClient->runTransaction($request); 
  626.  
  627. if($reply->reasonCode == "100") 
  628. //success 
  629. $order->subscription_transaction_id = $reply->requestID; 
  630. $order->status = "success";  
  631. return true; 
  632. else 
  633. //error 
  634. $order->status = "error"; 
  635. $order->errorcode = $reply->reasonCode; 
  636. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  637. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  638. return false; 
  639. }  
  640. }  
  641.  
  642. function update(&$order) 
  643. {  
  644. //get wsdl 
  645. $wsdl_url = $this->getWSDL($order); 
  646.  
  647. //to store our request 
  648. $request = new stdClass(); 
  649.  
  650. //set service type 
  651. $paySubscriptionUpdateService = new stdClass(); 
  652. $paySubscriptionUpdateService ->run = "true";  
  653. $request->paySubscriptionUpdateService = $paySubscriptionUpdateService ; 
  654.  
  655. //merchant id and order code 
  656. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  657. $request->merchantReferenceCode = $order->code; 
  658.  
  659. //set subscription info for API 
  660. $recurringSubscriptionInfo = new stdClass(); 
  661. $recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id; 
  662. $request->recurringSubscriptionInfo = $recurringSubscriptionInfo; 
  663.  
  664. //combine address  
  665. $address = $order->Address1; 
  666. if(!empty($order->Address2)) 
  667. $address .= "\n" . $order->Address2; 
  668.  
  669. //bill to 
  670. $billTo = new stdClass(); 
  671. $billTo->firstName = $order->FirstName; 
  672. $billTo->lastName = $order->LastName; 
  673. $billTo->street1 = $address; 
  674. $billTo->city = $order->billing->city; 
  675. $billTo->state = $order->billing->state; 
  676. $billTo->postalCode = $order->billing->zip; 
  677. $billTo->country = $order->billing->country; 
  678. $billTo->email = $order->Email; 
  679. $billTo->ipAddress = $_SERVER['REMOTE_ADDR']; 
  680. $request->billTo = $billTo; 
  681.  
  682. //card 
  683. $card = new stdClass(); 
  684. $card->cardType = $this->getCardType($order->cardtype); 
  685. $card->accountNumber = $order->accountnumber; 
  686. $card->expirationMonth = $order->expirationmonth; 
  687. $card->expirationYear = $order->expirationyear; 
  688. $card->cvNumber = $order->CVV2; 
  689. $request->card = $card; 
  690.  
  691. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  692. $reply = $soapClient->runTransaction($request); 
  693.  
  694. if($reply->reasonCode == "100") 
  695. //success  
  696. return true; 
  697. else 
  698. //error 
  699. $order->errorcode = $reply->reasonCode; 
  700. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  701. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  702. return false; 
  703. }  
  704.  
  705. function cancel(&$order) 
  706. //require a subscription id 
  707. if(empty($order->subscription_transaction_id)) 
  708. return false; 
  709.  
  710. //get wsdl 
  711. $wsdl_url = $this->getWSDL($order); 
  712.  
  713. //to store our request 
  714. $request = new stdClass(); 
  715.  
  716. //which service? 
  717. $paySubscriptionDeleteService = new stdClass(); 
  718. $paySubscriptionDeleteService ->run = "true";  
  719. $request->paySubscriptionDeleteService = $paySubscriptionDeleteService ; 
  720.  
  721. //which order 
  722. $recurringSubscriptionInfo = new stdClass(); 
  723. $recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id; 
  724. $request->recurringSubscriptionInfo = $recurringSubscriptionInfo; 
  725.  
  726. //merchant id and order code 
  727. $request->merchantID = pmpro_getOption("cybersource_merchantid"); 
  728. $request->merchantReferenceCode = $order->code;  
  729.  
  730. $soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey"))); 
  731. $reply = $soapClient->runTransaction($request); 
  732.  
  733. if($reply->reasonCode == "100") 
  734. //success 
  735. $order->updateStatus("cancelled");  
  736. return true; 
  737. else 
  738. //error 
  739. $order->errorcode = $reply->reasonCode; 
  740. $order->error = $this->getErrorFromCode($reply->reasonCode); 
  741. $order->shorterror = $this->getErrorFromCode($reply->reasonCode); 
  742. return false; 
  743. }  
  744.  
  745. function getErrorFromCode($code) 
  746. $error_messages = array( 
  747. "100" => "Successful transaction.",  
  748. "101" => "The request is missing one or more required fields.",  
  749. "102" => "One or more fields in the request contains invalid data. Check that your billing address is valid.",  
  750. "104" => "Duplicate order detected.",  
  751. "110" => "Only partial amount was approved.",  
  752. "150" => "Error: General system failure.",  
  753. "151" => "Error: The request was received but there was a server timeout.",  
  754. "152" => "Error: The request was received, but a service did not finish running in time. ",  
  755. "200" => "Address Verification Service (AVS) failure.",  
  756. "201" => "Authorization failed.",  
  757. "202" => "Expired card or invalid expiration date.",  
  758. "203" => "The card was declined.",  
  759. "204" => "Insufficient funds in the account.",  
  760. "205" => "Stolen or lost card.",  
  761. "207" => "Issuing bank unavailable.",  
  762. "208" => "Inactive card or card not authorized for card-not-present transactions.",  
  763. "209" => "American Express Card Identification Digits (CID) did not match.",  
  764. "210" => "The card has reached the credit limit. ",  
  765. "211" => "Invalid card verification number.",  
  766. "221" => "The customer matched an entry on the processors negative file. ",  
  767. "230" => "Card verification (CV) check failed.",  
  768. "231" => "Invalid account number.",  
  769. "232" => "The card type is not accepted by the payment processor.",  
  770. "233" => "General decline by the processor.",  
  771. "234" => "There is a problem with your CyberSource merchant configuration.",  
  772. "235" => "The requested amount exceeds the originally authorized amount.",  
  773. "236" => "Processor failure.",  
  774. "237" => "The authorization has already been reversed.",  
  775. "238" => "The authorization has already been captured.",  
  776. "239" => "The requested transaction amount must match the previous transaction amount.",  
  777. "240" => "The card type sent is invalid or does not correlate with the credit card number.",  
  778. "241" => "The referenced request id is invalid for all follow-on transactions.",  
  779. "242" => "The request ID is invalid.",  
  780. "243" => "The transaction has already been settled or reversed.",  
  781. "246" => "The capture or credit is not voidable because the capture or credit information has already been submitted to your processor. Or, you requested a void for a type of transaction that cannot be voided.",  
  782. "247" => "You requested a credit for a capture that was previously voided.",  
  783. "250" => "Error: The request was received, but there was a timeout at the payment processor.",  
  784. "520" => "Smart Authorization failed."  
  785. ); 
  786.  
  787. if(isset($error_messages[$code])) 
  788. return $error_messages[$code]; 
  789. else 
  790. return "Unknown error.";