remove a couple of unrequired lines from test
[civicrm-core.git] / CRM / Core / Payment / PayflowPro.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +----------------------------------------------------------------------------+
232624b1 4 | PayflowPro Core Payment Module for CiviCRM version 4.4 |
6a488035
TO
5 +----------------------------------------------------------------------------+
6 | Licensed to CiviCRM under the Academic Free License version 3.0 |
7 | |
8 | Written & Contributed by Eileen McNaughton - 2009 |
9 +---------------------------------------------------------------------------+
10 */
11class CRM_Core_Payment_PayflowPro extends CRM_Core_Payment {
12 // (not used, implicit in the API, might need to convert?)
13 CONST
14 CHARSET = 'UFT-8';
15
16 /**
17 * We only need one instance of this object. So we use the singleton
18 * pattern and cache the instance in this variable
19 *
20 * @var object
21 * @static
22 */
23 static private $_singleton = NULL;
24
25 /*
26 * Constructor
27 *
28 * @param string $mode the mode of operation: live or test
29 *
30 * @return void
31 */
32 function __construct($mode, &$paymentProcessor) {
33 // live or test
34 $this->_mode = $mode;
35 $this->_paymentProcessor = $paymentProcessor;
36 $this->_processorName = ts('Payflow Pro');
37 }
ceb10dc7 38
6a488035
TO
39 /**
40 * singleton function used to manage this object
41 *
42 * @param string $mode the mode of operation: live or test
43 *
44 * @return object
45 * @static
46 *
47 */
48 static function &singleton($mode, &$paymentProcessor) {
49 $processorName = $paymentProcessor['name'];
50 if (self::$_singleton[$processorName] === NULL) {
51 self::$_singleton[$processorName] = new CRM_Core_Payment_PayflowPro($mode, $paymentProcessor);
52 }
53 return self::$_singleton[$processorName];
54 }
55
56 /*
57 * This function sends request and receives response from
58 * the processor. It is the main function for processing on-server
59 * credit card transactions
60 */
61 function doDirectPayment(&$params) {
62 if (!defined('CURLOPT_SSLCERT')) {
63 CRM_Core_Error::fatal(ts('PayFlowPro requires curl with SSL support'));
64 }
65
66 /*
67 * define variables for connecting with the gateway
68 */
ceb10dc7 69
6a488035
TO
70 // Are you using the Payflow Fraud Protection Service?
71 // Default is YES, change to NO or blank if not.
72 //This has not been investigated as part of writing this payment processor
73 $fraud = 'NO';
74 //if you have not set up a separate user account the vendor name is used as the username
75 if (!$this->_paymentProcessor['subject']) {
76 $user = $this->_paymentProcessor['user_name'];
77 }
78 else {
79 $user = $this->_paymentProcessor['subject'];
80 }
81
82 // ideally this id would be passed through into this class as
83 // part of the paymentProcessor
84 //object with the other variables. It seems inefficient to re-query to get it.
85 //$params['processor_id'] = CRM_Core_DAO::getFieldValue(
86 // 'CRM_Contribute_DAO_ContributionP
87 //age',$params['contributionPageID'], 'payment_processor_id' );
88
89 /*
90 *Create the array of variables to be sent to the processor from the $params array
91 * passed into this function
92 *
93 */
94
95 $payflow_query_array = array(
96 'USER' => $user,
97 'VENDOR' => $this->_paymentProcessor['user_name'],
98 'PARTNER' => $this->_paymentProcessor['signature'],
99 'PWD' => $this->_paymentProcessor['password'],
100 // C - Direct Payment using credit card
101 'TENDER' => 'C',
102 // A - Authorization, S - Sale
103 'TRXTYPE' => 'S',
104 'ACCT' => urlencode($params['credit_card_number']),
105 'CVV2' => $params['cvv2'],
106 'EXPDATE' => urlencode(sprintf('%02d', (int) $params['month']) . substr($params['year'], 2, 2)),
107 'ACCTTYPE' => urlencode($params['credit_card_type']),
108 'AMT' => urlencode($params['amount']),
109 'CURRENCY' => urlencode($params['currency']),
110 'FIRSTNAME' => $params['billing_first_name'],
111 //credit card name
112 'LASTNAME' => $params['billing_last_name'],
113 //credit card name
114 'STREET' => $params['street_address'],
115 'CITY' => urlencode($params['city']),
116 'STATE' => urlencode($params['state_province']),
117 'ZIP' => urlencode($params['postal_code']),
118 'COUNTRY' => urlencode($params['country']),
119 'EMAIL' => $params['email'],
120 'CUSTIP' => urlencode($params['ip_address']),
121 'COMMENT1' => urlencode($params['contributionType_accounting_code']),
122 'COMMENT2' => $mode,
123 'INVNUM' => urlencode($params['invoiceID']),
124 'ORDERDESC' => urlencode($params['description']),
125 'VERBOSITY' => 'MEDIUM',
126 'BILLTOCOUNTRY' => urlencode($params['country']),
127 );
128
129 if ($params['installments'] == 1) {
130 $params['is_recur'] == FALSE;
131 }
132
133 if ($params['is_recur'] == TRUE) {
134
135 $payflow_query_array['TRXTYPE'] = 'R';
136 $payflow_query_array['OPTIONALTRX'] = 'S';
137 $payflow_query_array['OPTIONALTRXAMT'] = $params['amount'];
138 //Amount of the initial Transaction. Required
139 $payflow_query_array['ACTION'] = 'A';
140 //A for add recurring (M-modify,C-cancel,R-reactivate,I-inquiry,P-payment
141 $payflow_query_array['PROFILENAME'] = urlencode('RegularContribution');
142 //A for add recurring (M-modify,C-cancel,R-reactivate,I-inquiry,P-payment
143 if ($params['installments'] > 0) {
144 $payflow_query_array['TERM'] = $params['installments'] - 1;
145 //ie. in addition to the one happening with this transaction
146 }
147 // $payflow_query_array['COMPANYNAME']
148 // $payflow_query_array['DESC'] = not set yet Optional
149 // description of the goods or
150 //services being purchased.
151 //This parameter applies only for ACH_CCD accounts.
152 // The
153 // $payflow_query_array['MAXFAILPAYMENTS'] = 0;
154 // number of payment periods (as s
155 //pecified by PAYPERIOD) for which the transaction is allowed
156 //to fail before PayPal cancels a profile. the default
157 // value of 0 (zero) specifies no
158 //limit. Retry
159 //attempts occur until the term is complete.
160 // $payflow_query_array['RETRYNUMDAYS'] = (not set as can't assume business rule
161
162 switch ($params['frequency_unit']) {
163 case '1 week':
797b807e 164 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m"), date("d") + 7,
6a488035
TO
165 date("Y")
166 );
167 $params['end_date'] = mktime(0, 0, 0, date("m"), date("d") + (7 * $payflow_query_array['TERM']),
168 date("Y")
169 );
797b807e 170 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
171 $payflow_query_array['PAYPERIOD'] = "WEEK";
172 $params['frequency_unit'] = "week";
173 $params['frequency_interval'] = 1;
174 break;
175
176 case '2 weeks':
797b807e 177 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m"), date("d") + 14, date("Y"));
6a488035
TO
178 $params['end_date'] = mktime(0, 0, 0, date("m"), date("d") + (14 * $payflow_query_array['TERM'])
179 , date("Y ")
180 );
797b807e 181 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
182 $payflow_query_array['PAYPERIOD'] = "BIWK";
183 $params['frequency_unit'] = "week";
184 $params['frequency_interval'] = 2;
185 break;
186
187 case '4 weeks':
797b807e 188 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m"), date("d") + 28, date("Y")
6a488035
TO
189 );
190 $params['end_date'] = mktime(0, 0, 0, date("m"), date("d") + (28 * $payflow_query_array['TERM'])
191 , date("Y")
192 );
797b807e 193 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
194 $payflow_query_array['PAYPERIOD'] = "FRWK";
195 $params['frequency_unit'] = "week";
196 $params['frequency_interval'] = 4;
197 break;
198
199 case '1 month':
797b807e 200 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m") + 1,
6a488035
TO
201 date("d"), date("Y")
202 );
203 $params['end_date'] = mktime(0, 0, 0, date("m") +
204 (1 * $payflow_query_array['TERM']),
205 date("d"), date("Y")
206 );
797b807e 207 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
208 $payflow_query_array['PAYPERIOD'] = "MONT";
209 $params['frequency_unit'] = "month";
210 $params['frequency_interval'] = 1;
211 break;
212
213 case '3 months':
797b807e 214 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m") + 3, date("d")
6a488035
TO
215 , date("Y")
216 );
217 $params['end_date'] = mktime(0, 0, 0, date("m") +
218 (3 * $payflow_query_array['TERM']),
219 date("d"), date("Y")
220 );
797b807e 221 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
222 $payflow_query_array['PAYPERIOD'] = "QTER";
223 $params['frequency_unit'] = "month";
224 $params['frequency_interval'] = 3;
225 break;
226
227 case '6 months':
797b807e 228 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m") + 6, date("d"),
6a488035
TO
229 date("Y")
230 );
231 $params['end_date'] = mktime(0, 0, 0, date("m") +
232 (6 * $payflow_query_array['TERM']),
233 date("d"), date("Y")
234 );
797b807e 235 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date'
6a488035
TO
236 ]
237 );
238 $payflow_query_array['PAYPERIOD'] = "SMYR";
239 $params['frequency_unit'] = "month";
240 $params['frequency_interval'] = 6;
241 break;
242
243 case '1 year':
797b807e 244 $params['next_sched_contribution_date'] = mktime(0, 0, 0, date("m"), date("d"),
6a488035
TO
245 date("Y") + 1
246 );
247 $params['end_date'] = mktime(0, 0, 0, date("m"), date("d"),
248 date("Y") +
249 (1 * $payflow_query_array['TEM'])
250 );
797b807e 251 $payflow_query_array['START'] = date('mdY', $params['next_sched_contribution_date']);
6a488035
TO
252 $payflow_query_array['PAYPERIOD'] = "YEAR";
253 $params['frequency_unit'] = "year";
254 $params['frequency_interval'] = 1;
255 break;
256 }
257 }
258
259 CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $payflow_query_array);
260 $payflow_query = $this->convert_to_nvp($payflow_query_array);
261
262 /*
263 * Check to see if we have a duplicate before we send
264 */
265 if ($this->_checkDupe($params['invoiceID'])) {
266 return self::errorExit(9003, 'It appears that this transaction is a duplicate. Have you already submitted the form once? If so there may have been a connection problem. Check your email for a receipt. If you do not receive a receipt within 2 hours you can try your transaction again. If you continue to have problems please contact the site administrator.');
267 }
268
269 // ie. url at payment processor to submit to.
270 $submiturl = $this->_paymentProcessor['url_site'];
271
272 $responseData = self::submit_transaction($submiturl, $payflow_query);
273
274 /*
ceb10dc7 275 * Payment successfully sent to gateway - process the response now
6a488035
TO
276 */
277 $result = strstr($responseData, "RESULT");
278 $nvpArray = array();
279 while (strlen($result)) {
280 // name
281 $keypos = strpos($result, '=');
282 $keyval = substr($result, 0, $keypos);
283 // value
284 $valuepos = strpos($result, '&') ? strpos($result, '&') : strlen($result);
285 $valval = substr($result, $keypos + 1, $valuepos - $keypos - 1);
286 // decoding the respose
287 $nvpArray[$keyval] = $valval;
288 $result = substr($result, $valuepos + 1, strlen($result));
289 }
290 // get the result code to validate.
291 $result_code = $nvpArray['RESULT'];
292 /*debug
293 echo "<p>Params array</p><br>";
294 print_r($params);
295 echo "<p></p><br>";
296 echo "<p>Values to Payment Processor</p><br>";
297 print_r($payflow_query_array);
298 echo "<p></p><br>";
299 echo "<p>Results from Payment Processor</p><br>";
300 print_r($nvpArray);
301 echo "<p></p><br>";
302 */
303
304 switch ($result_code) {
305 case 0:
306
307 /*******************************************************
308 * Success !
309 * This is a successful transaction. PayFlow Pro does return further information
310 * about transactions to help you identify fraud including whether they pass
311 * the cvv check, the avs check. This is stored in
312 * CiviCRM as part of the transact
313 * but not further processing is done. Business rules would need to be defined
314
315 *******************************************************/
316 $params['trxn_id'] = $nvpArray['PNREF'] . $nvpArray['TRXPNREF'];
317 //'trxn_id' is varchar(255) field. returned value is length 12
318 $params['trxn_result_code'] = $nvpArray['AUTHCODE'] . "-Cvv2:" . $nvpArray['CVV2MATCH'] . "-avs:" . $nvpArray['AVSADDR'];
319
320 if ($params['is_recur'] == TRUE) {
321 $params['recur_trxn_id'] = $nvpArray['PROFILEID'];
322 //'trxn_id' is varchar(255) field. returned value is length 12
323 }
324 return $params;
325
326 case 1:
327 return self::errorExit(9008, "There is a payment processor configuration problem. This is usually due to invalid account information or ip restrictions on the account. You can verify ip restriction by logging // into Manager. See Service Settings >> Allowed IP Addresses. ");
328
329 case 12:
330 // Hard decline from bank.
331 return self::errorExit(9009, "Your transaction was declined ");
332
333 case 13:
334 // Voice authorization required.
335 return self::errorExit(9010, "Your Transaction is pending. Contact Customer Service to complete your order.");
336
337 case 23:
338 // Issue with credit card number or expiration date.
339 return self::errorExit(9011, "Invalid credit card information. Please re-enter.");
340
341 case 26:
342 return self::errorExit(9012, "You have not configured your payment processor with the correct credentials. Make sure you have provided both the <vendor> and the <user> variables ");
343
344 default:
345 return self::errorExit(9013, "Error - from payment processor: [" . $result_code . " " . $nvpArray['RESPMSG'] . "] ");
346 }
347
348 return self::errorExit(9014, "Check the code - all transactions should have been headed off before they got here. Something slipped through the net");
349 }
350
351 /**
352 * Checks to see if invoice_id already exists in db
353 *
354 * @param int $invoiceId The ID to check
355 *
356 * @return bool True if ID exists, else false
357 */
358 function _checkDupe($invoiceId) {
359 //copied from Eway but not working and not really sure it should!
360 $contribution = new CRM_Contribute_DAO_Contribution();
361 $contribution->invoice_id = $invoiceId;
362 return $contribution->find();
363 }
364
365 /*
366 * Produces error message and returns from class
367 */
368 function &errorExit($errorCode = NULL, $errorMessage = NULL) {
369 $e = CRM_Core_Error::singleton();
370 if ($errorCode) {
371 $e->push($errorCode, 0, NULL, $errorMessage);
372 }
373 else {
374 $e->push(9000, 0, NULL, 'Unknown System Error.');
375 }
376 return $e;
377 }
378
379
380 /*
381 * NOTE: 'doTransferCheckout' not implemented
382 */
383 function doTransferCheckout(&$params, $component) {
384 CRM_Core_Error::fatal(ts('This function is not implemented'));
385 }
386
387 /*
388 * This public function checks to see if we have the right processor config values set
389 *
390 * NOTE: Called by Events and Contribute to check config params are set prior to trying
391 * register any credit card details
392 *
393 * @param string $mode the mode we are operating in (live or test) - not used
394 *
395 * returns string $errorMsg if any errors found - null if OK
396 *
397 */
ceb10dc7 398
6a488035
TO
399 // function checkConfig( $mode ) // CiviCRM V1.9 Declaration
400
401 // CiviCRM V2.0 Declaration
402 function checkConfig() {
403 $errorMsg = array();
404 if (empty($this->_paymentProcessor['user_name'])) {
405 $errorMsg[] = ' ' . ts('ssl_merchant_id is not set for this payment processor');
406 }
407
408 if (empty($this->_paymentProcessor['url_site'])) {
409 $errorMsg[] = ' ' . ts('URL is not set for %1', array(1 => $this->_paymentProcessor['name']));
410 }
411
412 if (!empty($errorMsg)) {
413 return implode('<p>', $errorMsg);
414 }
415 else {
416 return NULL;
417 }
418 }
419 //end check config
420
421 /*
422 * convert to a name/value pair (nvp) string
423 */
424 function convert_to_nvp($payflow_query_array) {
425 foreach ($payflow_query_array as $key => $value) {
426 $payflow_query[] = $key . '[' . strlen($value) . ']=' . $value;
427 }
428 $payflow_query = implode('&', $payflow_query);
429
430 return $payflow_query;
431 }
432
433 /*
434 * Submit transaction using CuRL
435 * @submiturl string Url to direct HTTPS GET to
436 * @payflow_query value string to be posted
437 *
438 */
439 function submit_transaction($submiturl, $payflow_query) {
440 /*
441 * Submit transaction using CuRL
442 */
ceb10dc7 443
6a488035
TO
444 // get data ready for API
445 $user_agent = $_SERVER['HTTP_USER_AGENT'];
446 // Here's your custom headers; adjust appropriately for your setup:
447 $headers[] = "Content-Type: text/namevalue";
448 //or text/xml if using XMLPay.
449 $headers[] = "Content-Length : " . strlen($data);
450 // Length of data to be passed
451 // Here the server timeout value is set to 45, but notice
452 // below in the cURL section, the timeout
453 // for cURL is 90 seconds. You want to make sure the server
454 // timeout is less, then the connection.
455 $headers[] = "X-VPS-Timeout: 45";
456 //random unique number - the transaction is retried using this transaction ID
457 // in this function but if that doesn't work and it is re- submitted
458 // it is treated as a new attempt. PayflowPro doesn't allow
459 // you to change details (e.g. card no) when you re-submit
460 // you can only try the same details
461 $headers[] = "X-VPS-Request-ID: " . rand(1, 1000000000);
462 // optional header field
463 $headers[] = "X-VPS-VIT-Integration-Product: CiviCRM";
464 // other Optional Headers. If used adjust as necessary.
465 // Name of your OS
466 //$headers[] = "X-VPS-VIT-OS-Name: Linux";
467 // OS Version
468 //$headers[] = "X-VPS-VIT-OS-Version: RHEL 4";
469 // What you are using
470 //$headers[] = "X-VPS-VIT-Client-Type: PHP/cURL";
471 // For your info
472 //$headers[] = "X-VPS-VIT-Client-Version: 0.01";
473 // For your info
474 //$headers[] = "X-VPS-VIT-Client-Architecture: x86";
475 // Application version
476 //$headers[] = "X-VPS-VIT-Integration-Version: 0.01";
477 $ch = curl_init();
478 curl_setopt($ch, CURLOPT_URL, $submiturl);
479 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
480 curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
481 curl_setopt($ch, CURLOPT_HEADER, 1);
482 // tells curl to include headers in response
483 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
484 // return into a variable
485 curl_setopt($ch, CURLOPT_TIMEOUT, 90);
486 // times out after 90 secs
487 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
488 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'verifySSL'));
489 // this line makes it work under https
490 curl_setopt($ch, CURLOPT_POSTFIELDS, $payflow_query);
491 //adding POST data
17c04b52 492 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'verifySSL') ? 2 : 0);
6a488035
TO
493 //verifies ssl certificate
494 curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
495 //forces closure of connection when done
496 curl_setopt($ch, CURLOPT_POST, 1);
497 //data sent as POST
498
499 // Try to submit the transaction up to 3 times with 5 second delay. This can be used
500 // in case of network issues. The idea here is since you are posting via HTTPS there
501 // could be general network issues, so try a few times before you tell customer there
502 // is an issue.
503
504 $i = 1;
505 while ($i++ <= 3) {
506 $responseData = curl_exec($ch);
507 $responseHeaders = curl_getinfo($ch);
508 if ($responseHeaders['http_code'] != 200) {
509 // Let's wait 5 seconds to see if its a temporary network issue.
510 sleep(5);
511 }
512 elseif ($responseHeaders['http_code'] == 200) {
513 // we got a good response, drop out of loop.
514 break;
515 }
516 }
517
518 /*
519 * Transaction submitted -
520 * See if we had a curl error - if so tell 'em and bail out
521 *
522 * NOTE: curl_error does not return a logical value (see its documentation), but
523 * a string, which is empty when there was no error.
524 */
525 if ((curl_errno($ch) > 0) || (strlen(curl_error($ch)) > 0)) {
526 curl_close($ch);
527 $errorNum = curl_errno($ch);
528 $errorDesc = curl_error($ch);
529
530 //Paranoia - in the unlikley event that 'curl' errno fails
531 if ($errorNum == 0)
532 $errorNum = 9005;
533
534 // Paranoia - in the unlikley event that 'curl' error fails
535 if (strlen($errorDesc) == 0)
536 $errorDesc = "Connection to payment gateway failed";
537 if ($errorNum = 60) {
538 return self::errorExit($errorNum, "Curl error - " . $errorDesc .
539 " Try this link for more information http://curl.haxx.se/d
540 ocs/sslcerts.html"
541 );
542 }
543
544 return self::errorExit($errorNum, "Curl error - " . $errorDesc .
545 " processor response = " . $processorResponse
546 );
547 }
548
549 /*
550 * If null data returned - tell 'em and bail out
551 *
552 * NOTE: You will not necessarily get a string back, if the request failed for
553 * any reason, the return value will be the boolean false.
554 */
555 if (($responseData === FALSE) || (strlen($responseData) == 0)) {
556 curl_close($ch);
557 return self::errorExit(9006, "Error: Connection to payment gateway failed - no data
558 returned. Gateway url set to $submiturl");
559 }
560
561 /*
562 * If gateway returned no data - tell 'em and bail out
563 */
564 if (empty($responseData)) {
565 curl_close($ch);
566 return self::errorExit(9007, "Error: No data returned from payment gateway.");
567 }
568
569 /*
570 * Success so far - close the curl and check the data
571 */
572 curl_close($ch);
573 return $responseData;
574 }
575 //end submit_transaction
576
577 function getRecurringTransactionStatus($recurringProfileID, $processorID) {
578 if (!defined('CURLOPT_SSLCERT')) {
579 CRM_Core_Error::fatal(ts('PayFlowPro requires curl with SSL support'));
580 }
581
582 /*
583 * define variables for connecting with the gateway
584 */
ceb10dc7 585
6a488035
TO
586 //if you have not set up a separate user account the vendor name is used as the username
587 if (!$this->_paymentProcessor['subject']) {
588 $user = $this->_paymentProcessor['user_name'];
589 }
590 else {
591 $user = $this->_paymentProcessor['subject'];
592 }
593 //$recurringProfileID = "RT0000000001";
594 // c $trythis = $this->getRecurringTransactionStatus($recurringProfileID,17);
595
596
597 /*
598 *Create the array of variables to be sent to the processor from the $params array
599 * passed into this function
600 *
601 */
602
603 $payflow_query_array = array(
604 'USER' => $user,
605 'VENDOR' => $this->_paymentProcessor['user_name'],
606 'PARTNER' => $this->_paymentProcessor['signature'],
607 'PWD' => $this->_paymentProcessor['password'],
608 // C - Direct Payment using credit card
609 'TENDER' => 'C',
610 // A - Authorization, S - Sale
611 'TRXTYPE' => 'R',
612 'ACTION' => 'I',
613 //A for add recurring
614 //(M-modify,C-cancel,R-reactivate,
615 //I-inquiry,P-payment
616 'ORIGPROFILEID' => $recurringProfileID,
617 'PAYMENTHISTORY' => 'Y',
618 );
619
620 $payflow_query = $this->convert_to_nvp($payflow_query_array);
621 echo $payflow_query;
622 $submiturl = $this->_paymentProcessor['url_site'];
623 //ie. url at payment processor to submit to.
624 $responseData = self::submit_transaction($submiturl, $payflow_query);
625 /*
ceb10dc7 626 * Payment successfully sent to gateway - process the response now
6a488035 627 */
ceb10dc7 628
6a488035
TO
629 $result = strstr($responseData, "RESULT");
630 $nvpArray = array();
631 while (strlen($result)) {
632 // name
633 $keypos = strpos($result, '=');
634 $keyval = substr($result, 0, $keypos);
635 // value
636 $valuepos = strpos($result, '&') ? strpos($result, '&') : strlen($result);
637 $valval = substr($result, $keypos + 1, $valuepos - $keypos - 1);
638 // decoding the respose
639 $nvpArray[$keyval] = $valval;
640 $result = substr($result, $valuepos + 1, strlen($result));
641 }
642 // get the result code to validate.
643 $result_code = $nvpArray['RESULT'];
644 print_r($responseData);
645
646 //RESPMSG=Invalid Profile ID: Invalid recurring profile ID
647 //RT0000000001
648 }
649}
650