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