PMProGateway_payflowpro

The Paid Memberships Pro PMProGateway payflowpro class.

Defined (1)

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

/classes/gateways/class.pmprogateway_payflowpro.php  
  1. class PMProGateway_payflowpro extends PMProGateway 
  2. function __construct($gateway = NULL) 
  3. $this->gateway = $gateway; 
  4. return $this->gateway; 
  5.  
  6. /** 
  7. * Run on WP init 
  8. * @since 1.8 
  9. */ 
  10. static function init() 
  11. //make sure Payflow Pro/PayPal Pro is a gateway option 
  12. add_filter('pmpro_gateways', array('PMProGateway_payflowpro', 'pmpro_gateways')); 
  13.  
  14. //add fields to payment settings 
  15. add_filter('pmpro_payment_options', array('PMProGateway_payflowpro', 'pmpro_payment_options')); 
  16. add_filter('pmpro_payment_option_fields', array('PMProGateway_payflowpro', 'pmpro_payment_option_fields'), 10, 2); 
  17.  
  18. /** 
  19. * Make sure this gateway is in the gateways list 
  20. * @since 1.8 
  21. */ 
  22. static function pmpro_gateways($gateways) 
  23. if(empty($gateways['payflowpro'])) 
  24. $gateways['payflowpro'] = __('Payflow Pro/PayPal Pro', 'paid-memberships-pro' ); 
  25.  
  26. return $gateways; 
  27.  
  28. /** 
  29. * Get a list of payment options that the this gateway needs/supports. 
  30. * @since 1.8 
  31. */ 
  32. static function getGatewayOptions() 
  33. $options = array( 
  34. 'sslseal',  
  35. 'nuclear_HTTPS',  
  36. 'gateway_environment',  
  37. 'payflow_partner',  
  38. 'payflow_vendor',  
  39. 'payflow_user',  
  40. 'payflow_pwd',  
  41. 'currency',  
  42. 'use_ssl',  
  43. 'tax_state',  
  44. 'tax_rate',  
  45. 'accepted_credit_cards' 
  46. ); 
  47.  
  48. return $options; 
  49.  
  50. /** 
  51. * Set payment options for payment settings page. 
  52. * @since 1.8 
  53. */ 
  54. static function pmpro_payment_options($options) 
  55. //get stripe options 
  56. $payflowpro_options = PMProGateway_payflowpro::getGatewayOptions(); 
  57.  
  58. //merge with others. 
  59. $options = array_merge($payflowpro_options, $options); 
  60.  
  61. return $options; 
  62.  
  63. /** 
  64. * Display fields for this gateway's options. 
  65. * @since 1.8 
  66. */ 
  67. static function pmpro_payment_option_fields($values, $gateway) 
  68. ?> 
  69. <tr class="pmpro_settings_divider gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  70. <td colspan="2"> 
  71. <?php _e('Payflow Pro Settings', 'paid-memberships-pro' ); ?> 
  72. </td> 
  73. </tr> 
  74. <tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  75. <th scope="row" valign="top"> 
  76. <label for="payflow_partner"><?php _e('Partner', 'paid-memberships-pro' );?>:</label> 
  77. </th> 
  78. <td> 
  79. <input type="text" id="payflow_partner" name="payflow_partner" size="60" value="<?php echo esc_attr($values['payflow_partner'])?>" /> 
  80. </td> 
  81. </tr> 
  82. <tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  83. <th scope="row" valign="top"> 
  84. <label for="payflow_vendor"><?php _e('Vendor', 'paid-memberships-pro' );?>:</label> 
  85. </th> 
  86. <td> 
  87. <input type="text" id="payflow_vendor" name="payflow_vendor" size="60" value="<?php echo esc_attr($values['payflow_vendor'])?>" /> 
  88. </td> 
  89. </tr> 
  90. <tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  91. <th scope="row" valign="top"> 
  92. <label for="payflow_user"><?php _e('User', 'paid-memberships-pro' );?>:</label> 
  93. </th> 
  94. <td> 
  95. <input type="text" id="payflow_user" name="payflow_user" size="60" value="<?php echo esc_attr($values['payflow_user'])?>" /> 
  96. </td> 
  97. </tr> 
  98. <tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  99. <th scope="row" valign="top"> 
  100. <label for="payflow_pwd"><?php _e('Password', 'paid-memberships-pro' );?>:</label> 
  101. </th> 
  102. <td> 
  103. <input type="password" id="payflow_pwd" name="payflow_pwd" size="60" value="<?php echo esc_attr($values['payflow_pwd'])?>" /> 
  104. </td> 
  105. </tr> 
  106. <tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>> 
  107. <th scope="row" valign="top"> 
  108. <label><?php _e('IPN Handler', 'paid-memberships-pro' );?>:</label> 
  109. </th> 
  110. <td> 
  111. <p><?php 
  112. $addon_url = "http://www.paidmembershipspro.com/add-ons/plugins-on-github/payflow-recurring-orders-addon/"; 
  113. printf(__('Payflow does not use IPN. To sync recurring subscriptions, please see <a target="_blank" href="%s">this addon</a>.', 'paid-memberships-pro' ), $addon_url);?> 
  114. </p> 
  115. </td> 
  116. </tr> 
  117. <?php 
  118.  
  119. /** 
  120. * Process checkout. 
  121. */ 
  122. function process(&$order) 
  123. if(floatval($order->InitialPayment) == 0) 
  124. //auth first, then process 
  125. $authorization_id = $this->authorize($order); 
  126. if($authorization_id) 
  127. $this->void($order, $authorization_id); 
  128. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0"; 
  129. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order); 
  130. return $this->subscribe($order); 
  131. else 
  132. if(empty($order->error)) 
  133. $order->error = __("Unknown error: Authorization failed.", 'paid-memberships-pro' ); 
  134. return false; 
  135. else 
  136. //charge first payment 
  137. if($this->charge($order)) 
  138. //set up recurring billing 
  139. if(pmpro_isLevelRecurring($order->membership_level)) 
  140. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0"; 
  141. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order); 
  142. if($this->subscribe($order)) 
  143. return true; 
  144. else 
  145. if($this->void($order, $order->payment_transaction_id)) 
  146. if(empty($order->error)) 
  147. $order->error = __("Unknown error: Payment failed.", 'paid-memberships-pro' ); 
  148. else 
  149. if(empty($order->error)) 
  150. $order->error = __("Unknown error: Payment failed.", 'paid-memberships-pro' ); 
  151.  
  152. $order->error .= " " . __("A partial payment was made that we could not refund. Please contact the site owner immediately to correct this.", 'paid-memberships-pro' ); 
  153.  
  154. return false; 
  155. else 
  156. //only a one time charge 
  157. $order->status = "success"; //saved on checkout page 
  158. $order->saveOrder(); 
  159. return true; 
  160.  
  161. function authorize(&$order) 
  162. if(empty($order->code)) 
  163. $order->code = $order->getRandomCode(); 
  164.  
  165. //paypal profile stuff 
  166. $nvpStr = ""; 
  167.  
  168. $nvpStr .="&AMT=1.00"; 
  169. /** PayFlow Pro doesn't use IPN so this is a little confusing */ 
  170. // $nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler"); 
  171. //$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount; 
  172.  
  173. $nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code; 
  174.  
  175. //credit card fields 
  176. if($order->cardtype == "American Express") 
  177. $cardtype = "Amex"; 
  178. else 
  179. $cardtype = $order->cardtype; 
  180.  
  181. if(!empty($order->accountnumber)) 
  182. $nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2; 
  183.  
  184. //billing address, etc 
  185. if(!empty($order->Address1)) 
  186. $nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1; 
  187.  
  188. if($order->Address2) 
  189. $nvpStr .= " " . $order->Address2; 
  190.  
  191. $nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone; 
  192.  
  193. /** 
  194. * Filter NVP string 
  195. * @since 1.8.5.6 
  196. */ 
  197. $nvpStr = apply_filters('pmpro_payflow_authorize_nvpstr', $nvpStr, $this); 
  198.  
  199. //for debugging, let's attach this to the class object 
  200. $this->nvpStr = $nvpStr; 
  201.  
  202. $this->httpParsedResponseAr = $this->PPHttpPost('A', $nvpStr); 
  203.  
  204. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) { 
  205. $order->authorization_id = $this->httpParsedResponseAr['PNREF']; 
  206. $order->updateStatus("authorized"); 
  207. return $order->authorization_id; 
  208. } else { 
  209. $order->status = "error"; 
  210. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  211. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  212. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  213. return false; 
  214.  
  215. function void(&$order, $authorization_id = null) 
  216. if(empty($authorization_id)) 
  217. return false; 
  218.  
  219. //paypal profile stuff 
  220. $nvpStr="&ORIGID=" . $authorization_id; 
  221.  
  222. /** 
  223. * Filter NVP string 
  224. * @since 1.8.5.6 
  225. */ 
  226. $nvpStr = apply_filters('pmpro_payflow_void_nvpstr', $nvpStr, $this); 
  227.  
  228. $this->httpParsedResponseAr = $this->PPHttpPost('V', $nvpStr); 
  229.  
  230. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) { 
  231. return true; 
  232. } else { 
  233. $order->status = "error"; 
  234. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  235. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  236. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  237. return false; 
  238.  
  239. function charge(&$order) 
  240. global $pmpro_currency; 
  241.  
  242. if(empty($order->code)) 
  243. $order->code = $order->getRandomCode(); 
  244.  
  245. //taxes on the amount 
  246. $amount = $order->InitialPayment; 
  247. $amount_tax = $order->getTaxForPrice($amount); 
  248. $order->subtotal = $amount; 
  249. $amount = round((float)$amount + (float)$amount_tax, 2); 
  250.  
  251. //paypal profile stuff 
  252. $nvpStr = ""; 
  253. $nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency; 
  254. /** PayFlow Pro doesn't use IPN so this is a little confusing */ 
  255. // $nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler"); 
  256. //$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount; 
  257.  
  258. $nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code; 
  259.  
  260. if(!empty($order->accountnumber)) 
  261. $nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2; 
  262.  
  263. //billing address, etc 
  264. if($order->Address1) 
  265. $nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1; 
  266.  
  267. if($order->Address2) 
  268. $nvpStr .= " " . $order->Address2; 
  269.  
  270. $nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone; 
  271.  
  272. /** 
  273. * Filter NVP string 
  274. * @since 1.8.5.6 
  275. */ 
  276. $nvpStr = apply_filters('pmpro_payflow_charge_nvpstr', $nvpStr, $this); 
  277.  
  278. $this->nvpStr = $nvpStr; 
  279. $this->httpParsedResponseAr = $this->PPHttpPost('S', $nvpStr); 
  280.  
  281. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) { 
  282. $order->payment_transaction_id = $this->httpParsedResponseAr['PNREF']; 
  283. $order->updateStatus("success"); 
  284. return true; 
  285. } else { 
  286. $order->status = "error"; 
  287. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  288. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  289. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  290. return false; 
  291.  
  292. function subscribe(&$order) 
  293. global $pmpro_currency; 
  294.  
  295. if(empty($order->code)) 
  296. $order->code = $order->getRandomCode(); 
  297.  
  298. //filter order before subscription. use with care. 
  299. $order = apply_filters("pmpro_subscribe_order", $order, $this); 
  300.  
  301. //taxes on the amount 
  302. $amount = $order->PaymentAmount; 
  303. $amount_tax = $order->getTaxForPrice($amount); 
  304. $amount = round((float)$amount + (float)$amount_tax, 2); 
  305.  
  306. if($order->BillingPeriod == "Day") 
  307. $payperiod = "DAYS"; 
  308. elseif($order->BillingPeriod == "Week") 
  309. $payperiod = "WEEK"; 
  310. elseif($order->BillingPeriod == "Month") 
  311. $payperiod = "MONT"; 
  312. elseif($order->BillingPeriod == "Year") 
  313. $payperiod = "YEAR"; 
  314.  
  315. //paypal profile stuff 
  316. $nvpStr = "&ACTION=A"; 
  317. $nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency; 
  318. /** PayFlow Pro doesn't use IPN so this is a little confusing */ 
  319. // $nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler"); 
  320. //$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount; 
  321.  
  322. $nvpStr .= "&PROFILENAME=" . urlencode( apply_filters( 'pmpro_paypal_level_description', substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127), $order->membership_level->name, $order, get_bloginfo("name")) ); 
  323.  
  324. $nvpStr .= "&PAYPERIOD=" . $payperiod; 
  325. $nvpStr .= "&FREQUENCY=" . $order->BillingFrequency; 
  326.  
  327. $nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code; 
  328.  
  329. //if billing cycles are defined 
  330. if(!empty($order->TotalBillingCycles)) 
  331. $nvpStr .= "&TERM=" . $order->TotalBillingCycles; 
  332. else 
  333. $nvpStr .= "&TERM=0"; 
  334.  
  335. if(!empty($order->accountnumber)) 
  336. $nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2; 
  337.  
  338. /** 
  339. Let's figure out the start date. There are two parts. 
  340. 1. We need to add the billing period to the start date to account for the initial payment. 
  341. 2. We can allow for free trials by further delaying the start date of the subscription. 
  342. */ 
  343. if($order->BillingPeriod == "Year") 
  344. $trial_period_days = $order->BillingFrequency * 365; //annual 
  345. elseif($order->BillingPeriod == "Day") 
  346. $trial_period_days = $order->BillingFrequency * 1; //daily 
  347. elseif($order->BillingPeriod == "Week") 
  348. $trial_period_days = $order->BillingFrequency * 7; //weekly 
  349. else 
  350. $trial_period_days = $order->BillingFrequency * 30; //assume monthly 
  351.  
  352. //convert to a profile start date 
  353. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0"; 
  354.  
  355. //filter the start date 
  356. $order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order); 
  357.  
  358. //convert back to days 
  359. $trial_period_days = ceil(abs(strtotime(date_i18n("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400); 
  360.  
  361. //now add the actual trial set by the site 
  362. if(!empty($order->TrialBillingCycles)) 
  363. $trialOccurrences = (int)$order->TrialBillingCycles; 
  364. if($order->BillingPeriod == "Year") 
  365. $trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual 
  366. elseif($order->BillingPeriod == "Day") 
  367. $trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily 
  368. elseif($order->BillingPeriod == "Week") 
  369. $trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly 
  370. else 
  371. $trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly 
  372.  
  373. //convert back into a date 
  374. $order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0"; 
  375.  
  376. //start date 
  377. $nvpStr .= "&START=" . date_i18n("mdY", strtotime($order->ProfileStartDate)); 
  378.  
  379. if(!empty($order->accountnumber)) 
  380. $nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2; 
  381.  
  382. //billing address, etc 
  383. if($order->Address1) 
  384. $nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1; 
  385.  
  386. if($order->Address2) 
  387. $nvpStr .= " " . $order->Address2; 
  388.  
  389. $nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone; 
  390.  
  391. /** 
  392. * Filter NVP string 
  393. * @since 1.8.5.6 
  394. */ 
  395. $nvpStr = apply_filters('pmpro_payflow_subscribe_nvpstr', $nvpStr, $this); 
  396.  
  397. $this->nvpStr = $nvpStr; 
  398. $this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr); 
  399.  
  400. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) { 
  401. $order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID']; 
  402. $order->status = "success"; 
  403. return true; 
  404. } else { 
  405. $order->status = "error"; 
  406. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  407. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  408. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  409. return false; 
  410.  
  411. function update(&$order) 
  412. $order->getMembershipLevel(); 
  413.  
  414. //paypal profile stuff 
  415. $nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=M"; 
  416. /** PayFlow Pro doesn't use IPN so this is a little confusing */ 
  417. // $nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler"); 
  418.  
  419. $nvpStr .= "&PROFILENAME=" . urlencode( apply_filters( 'pmpro_paypal_level_description', substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127), $order->membership_level->name, $order, get_bloginfo("name")) ); 
  420.  
  421. $nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code; 
  422.  
  423. if(!empty($order->accountnumber)) 
  424. $nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2; 
  425.  
  426. //billing address, etc 
  427. if($order->Address1) 
  428. $nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1; 
  429.  
  430. if($order->Address2) 
  431. $nvpStr .= " " . $order->Address2; 
  432.  
  433. $nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone; 
  434.  
  435. /** 
  436. * Filter NVP string 
  437. * @since 1.8.5.6 
  438. */ 
  439. $nvpStr = apply_filters('pmpro_payflow_update_nvpstr', $nvpStr, $this); 
  440.  
  441. $this->nvpStr = $nvpStr; 
  442. $this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr); 
  443.  
  444. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) { 
  445. $order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID']; 
  446. $order->updateStatus("success"); 
  447. return true; 
  448. } else { 
  449. $order->status = "error"; 
  450. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  451. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  452. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  453. return false; 
  454.  
  455. function cancel(&$order) 
  456. //require a subscription id 
  457. if(empty($order->subscription_transaction_id)) 
  458. return false; 
  459.  
  460. //paypal profile stuff 
  461. $nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=C"; 
  462.  
  463. /** 
  464. * Filter NVP string 
  465. * @since 1.8.5.6 
  466. */ 
  467. $nvpStr = apply_filters('pmpro_payflow_cancel_nvpstr', $nvpStr, $this); 
  468.  
  469. $this->nvpStr = $nvpStr; 
  470. $this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr); 
  471.  
  472. if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) 
  473. $order->updateStatus("cancelled"); 
  474. return true; 
  475. else 
  476. $order->status = "error"; 
  477. $order->errorcode = $this->httpParsedResponseAr['RESULT']; 
  478. $order->error = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  479. $order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']); 
  480. return false; 
  481.  
  482. /** 
  483. * PAYPAL Function 
  484. * Send HTTP POST Request 
  485. * @param string $methodName_ The API method name 
  486. * @param string $nvpStr_ The POST Message fields in &name=value pair format 
  487. * @return array Parsed HTTP Response body 
  488. */ 
  489. function PPHttpPost($methodName_, $nvpStr_) { 
  490. global $gateway_environment; 
  491. $environment = $gateway_environment; 
  492.  
  493. $PARTNER = pmpro_getOption("payflow_partner"); 
  494. $VENDOR = pmpro_getOption("payflow_vendor"); 
  495. $USER = pmpro_getOption("payflow_user"); 
  496. $PWD = pmpro_getOption("payflow_pwd"); 
  497. $API_Endpoint = "https://payflowpro.paypal.com"; 
  498. if("sandbox" === $environment || "beta-sandbox" === $environment) { 
  499. $API_Endpoint = "https://pilot-payflowpro.paypal.com"; 
  500.  
  501. $version = urlencode('4'); 
  502.  
  503. // NVPRequest for submitting to server 
  504. $nvpreq = "TRXTYPE=" . $methodName_ . "&TENDER=C&PARTNER=" . $PARTNER . "&VENDOR=" . $VENDOR . "&USER=" . $USER . "&PWD=" . $PWD . "&VERBOSITY=medium" . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_; 
  505.  
  506. //post to PayPal 
  507. $response = wp_remote_post( $API_Endpoint, array( 
  508. 'timeout' => 60,  
  509. 'sslverify' => FALSE,  
  510. 'httpversion' => '1.1',  
  511. 'body' => $nvpreq 
  512. ); 
  513.  
  514. $httpParsedResponseAr = array(); 
  515.  
  516. if ( is_wp_error( $response ) ) { 
  517. $error_message = $response->get_error_message(); 
  518. wp_die( "{$methodName_} failed: $error_message" ); 
  519. } else { 
  520. //extract the response details 
  521. parse_str(wp_remote_retrieve_body($response), $httpParsedResponseAr); 
  522.  
  523. //check for valid response 
  524. if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('RESULT', $httpParsedResponseAr)) { 
  525. exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint."); 
  526.  
  527. return $httpParsedResponseAr;