5 * Licensed to CiviCRM under the Academic Free License version 3.0.
7 * Written and contributed by Phase2 Technology, LLC (http://www.phase2technology.com)
14 * @author Michael Morris and Gene Chi @ Phase2 Technology <mmorris@phase2technology.com>
18 class CRM_Core_Payment_PayJunction
extends CRM_Core_Payment
{
19 # (not used, implicit in the API, might need to convert?)
20 const CHARSET
= 'UFT-8';
23 * We only need one instance of this object. So we use the singleton
24 * pattern and cache the instance in this variable
29 static private $_singleton = NULL;
34 * @param string $mode the mode of operation: live or test
36 * @param $paymentProcessor
38 * @return \CRM_Core_Payment_PayJunction
40 public function __construct($mode, &$paymentProcessor) {
41 //require PayJunction API library
42 require_once 'PayJunction/pjClasses.php';
45 $this->_paymentProcessor
= $paymentProcessor;
46 $this->_processorName
= ts('PayJunction');
50 * Singleton function used to manage this object
52 * @param string $mode the mode of operation: live or test
54 * @param object $paymentProcessor
55 * @param null $paymentForm
61 public static function &singleton($mode, &$paymentProcessor, &$paymentForm = NULL, $force = false) {
62 $processorName = $paymentProcessor['name'];
63 if (self
::$_singleton[$processorName] === NULL) {
64 self
::$_singleton[$processorName] = new CRM_Core_Payment_PayJunction($mode, $paymentProcessor);
66 return self
::$_singleton[$processorName];
70 * This function sends request and receives response from
71 * PayJunction payment process
74 * This function collects all the information from a web/api form and invokes
75 * the relevant payment processor specific functions to perform the transaction
77 * @param array $params assoc array of input parameters for this transaction
79 * @return array the result in an nice formatted array (or an error object)
82 public function doDirectPayment(&$params) {
83 $logon = $this->_paymentProcessor
['user_name'];
84 $password = $this->_paymentProcessor
['password'];
85 $url_site = $this->_paymentProcessor
['url_site'];
87 // create pjpgCustInfo object
88 $pjpgCustInfo = new pjpgCustInfo();
90 $pjpgCustInfo->setEmail($params['email']);
94 "password" => $password,
95 "url_site" => $url_site,
96 "first_name" => $params['first_name'],
97 "last_name" => $params['last_name'],
98 "address" => $params['street_address'],
99 "city" => $params['city'],
100 "province" => $params['state_province'],
101 "postal_code" => $params['postal_code'],
102 "country" => $params['country'],
104 $pjpgCustInfo->setBilling($billing);
106 // create pjpgTransaction object
107 $my_orderid = $params['invoiceID'];
109 $expiry_string = sprintf('%04d%02d', $params['year'], $params['month']);
112 'type' => 'purchase',
113 'order_id' => $my_orderid,
114 'amount' => sprintf('%01.2f', $params['amount']),
115 'pan' => $params['credit_card_number'],
116 'expdate' => $expiry_string,
118 'cust_id' => $params['contact_id'],
121 // Allow further manipulation of params via custom hooks
122 CRM_Utils_Hook
::alterPaymentProcessorParams($this, $params, $txnArray);
124 $pjpgTxn = new pjpgTransaction($txnArray);
126 // set customer info (level 3 data) for the transaction
127 $pjpgTxn->setCustInfo($pjpgCustInfo);
130 // empty installments convert to 999 because PayJunction do not allow open end donation
131 if ($params['installments'] == "") {
132 $params['installments'] = "999";
135 // create recurring object
136 if ($params['is_recur'] == TRUE && $params['installments'] > 1) {
137 // schedule start date as today
138 // format: YYYY-MM-DD
139 $params['dc_schedule_start'] = date("Y-m-d");
142 $dc_schedule_create = $params['is_recur'];
143 $recurUnit = $params['frequency_unit'];
144 $recurInterval = $params['frequency_interval'];
145 $dc_schedule_start = $params['dc_schedule_start'];
147 // next payment in moneris required format
148 $startDate = date("Y/m/d", $next);
150 $numRecurs = $params['installments'];
153 'dc_schedule_create' => $dc_schedule_create,
154 // (day | week | month)
155 'recur_unit' => $recurUnit,
157 'start_date' => $startDate,
158 'num_recurs' => $numRecurs,
159 'start_now' => 'false',
160 'period' => $recurInterval,
161 'dc_schedule_start' => $dc_schedule_start,
162 'amount' => sprintf('%01.2f', $params['amount']),
165 $pjpgRecur = new pjpgRecur($recurArray);
167 $pjpgTxn->setRecur($pjpgRecur);
170 // create a pjpgRequest object passing the transaction object
171 $pjpgRequest = new pjpgRequest($pjpgTxn);
173 $pjpgHttpPost = new pjpgHttpsPost($pjpgRequest);
175 // get an pjpgResponse object
176 $pjpgResponse = $pjpgHttpPost->getPJpgResponse();
178 if (self
::isError($pjpgResponse)) {
179 return self
::error($pjpgResponse);
182 /* Check for application errors */
184 $result = self
::checkResult($pjpgResponse);
185 if (is_a($result, 'CRM_Core_Error')) {
190 $params['trxn_result_code'] = $pjpgResponse['dc_response_code'];
191 $params['trxn_id'] = $pjpgResponse['dc_transaction_id'];
192 $params['gross_amount'] = $params['amount'];
196 // end function doDirectPayment
200 * This function checks the PayJunction response code
207 public function isError(&$response) {
208 $responseCode = $response['dc_response_code'];
210 if ($responseCode == "00" ||
$responseCode == "85") {
219 // ignore for now, more elaborate error handling later.
225 public function &checkResult(&$response) {
230 * Get the value of a field if set
232 * @param string $field the field
234 * @return mixed value of the field, or empty string if the field is
237 public function _getParam($field) {
238 if (isset($this->_params
[$field])) {
239 return $this->_params
[$field];
251 public function &error($error = NULL) {
252 $e = CRM_Core_Error
::singleton();
254 $e->push($error['dc_response_code'],
256 $error['dc_response_message']
260 $e->push(9001, 0, NULL, "Unknown System Error.");
266 * Set a field to the specified value. Value must be a scalar (int,
267 * float, string, or boolean)
269 * @param string $field
270 * @param mixed $value
272 * @return bool false if value is not a scalar, true if successful
274 public function _setParam($field, $value) {
275 if (!is_scalar($value)) {
279 $this->_params
[$field] = $value;
284 * This function checks to see if we have the right config values
286 * @return string the error message if any
288 public function checkConfig() {
290 if (empty($this->_paymentProcessor
['user_name'])) {
291 $error[] = ts('Username is not set for this payment processor');
294 if (empty($this->_paymentProcessor
['password'])) {
295 $error[] = ts('Password is not set for this payment processor');
298 if (empty($this->_paymentProcessor
['url_site'])) {
299 $error[] = ts('Site URL is not set for this payment processor');
302 if (!empty($error)) {
303 return implode('<p>', $error);
310 // end class CRM_Core_Payment_PayJunction