Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | ||
3 | /** | |
4 | * Copyright (C) 2007 | |
5 | * Licensed to CiviCRM under the Academic Free License version 3.0. | |
6 | * | |
7 | * Written and contributed by Phase2 Technology, LLC (http://www.phase2technology.com) | |
8 | * | |
9 | */ | |
10 | ||
11 | /** | |
12 | * | |
13 | * @package CRM | |
14 | * @author Michael Morris and Gene Chi @ Phase2 Technology <mmorris@phase2technology.com> | |
15 | * $Id$ | |
16 | * | |
17 | */ | |
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'; | |
21 | ||
22 | /** | |
23 | * We only need one instance of this object. So we use the singleton | |
24 | * pattern and cache the instance in this variable | |
25 | * | |
26 | * @var object | |
27 | * @static | |
28 | */ | |
29 | static private $_singleton = NULL; | |
30 | ||
31 | /** | |
32 | * Constructor | |
33 | * | |
34 | * @param string $mode the mode of operation: live or test | |
35 | * | |
77b97be7 EM |
36 | * @param $paymentProcessor |
37 | * | |
38 | * @return \CRM_Core_Payment_PayJunction | |
6a488035 TO |
39 | */ |
40 | function __construct($mode, &$paymentProcessor) { | |
41 | //require PayJunction API library | |
42 | require_once 'PayJunction/pjClasses.php'; | |
43 | ||
44 | $this->_mode = $mode; | |
45 | $this->_paymentProcessor = $paymentProcessor; | |
46 | $this->_processorName = ts('PayJunction'); | |
47 | } | |
48 | ||
49 | /** | |
50 | * singleton function used to manage this object | |
51 | * | |
52 | * @param string $mode the mode of operation: live or test | |
53 | * | |
dd244018 EM |
54 | * @param object $paymentProcessor |
55 | * @param null $paymentForm | |
56 | * @param bool $force | |
57 | * | |
6a488035 TO |
58 | * @return object |
59 | * @static | |
6a488035 | 60 | */ |
ba650a58 | 61 | static function &singleton($mode, &$paymentProcessor, &$paymentForm = NULL, $force = false) { |
6a488035 TO |
62 | $processorName = $paymentProcessor['name']; |
63 | if (self::$_singleton[$processorName] === NULL) { | |
64 | self::$_singleton[$processorName] = new CRM_Core_Payment_PayJunction($mode, $paymentProcessor); | |
65 | } | |
66 | return self::$_singleton[$processorName]; | |
67 | } | |
68 | ||
69 | /* | |
70 | * This function sends request and receives response from | |
71 | * PayJunction payment process | |
72 | */ | |
b5c2afd0 EM |
73 | /** |
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 | |
76 | * | |
77 | * @param array $params assoc array of input parameters for this transaction | |
78 | * | |
79 | * @return array the result in an nice formatted array (or an error object) | |
80 | * @abstract | |
81 | */ | |
6a488035 TO |
82 | function doDirectPayment(&$params) { |
83 | $logon = $this->_paymentProcessor['user_name']; | |
84 | $password = $this->_paymentProcessor['password']; | |
85 | $url_site = $this->_paymentProcessor['url_site']; | |
86 | ||
87 | // create pjpgCustInfo object | |
88 | $pjpgCustInfo = new pjpgCustInfo(); | |
89 | ||
90 | $pjpgCustInfo->setEmail($params['email']); | |
91 | ||
92 | $billing = array( | |
93 | "logon" => $logon, | |
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'], | |
103 | ); | |
104 | $pjpgCustInfo->setBilling($billing); | |
105 | ||
106 | // create pjpgTransaction object | |
107 | $my_orderid = $params['invoiceID']; | |
108 | ||
109 | $expiry_string = sprintf('%04d%02d', $params['year'], $params['month']); | |
110 | ||
111 | $txnArray = array( | |
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, | |
117 | 'crypt_type' => '7', | |
118 | 'cust_id' => $params['contact_id'], | |
119 | ); | |
120 | ||
121 | // Allow further manipulation of params via custom hooks | |
122 | CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $txnArray); | |
123 | ||
124 | $pjpgTxn = new pjpgTransaction($txnArray); | |
125 | ||
126 | // set customer info (level 3 data) for the transaction | |
127 | $pjpgTxn->setCustInfo($pjpgCustInfo); | |
128 | ||
129 | ||
130 | // empty installments convert to 999 because PayJunction do not allow open end donation | |
131 | if ($params['installments'] == "") { | |
132 | $params['installments'] = "999"; | |
133 | } | |
134 | ||
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"); | |
140 | ||
141 | // Recur Variables | |
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']; | |
146 | ||
147 | // next payment in moneris required format | |
148 | $startDate = date("Y/m/d", $next); | |
149 | ||
150 | $numRecurs = $params['installments']; | |
151 | ||
152 | $recurArray = array( | |
153 | 'dc_schedule_create' => $dc_schedule_create, | |
154 | // (day | week | month) | |
155 | 'recur_unit' => $recurUnit, | |
156 | // yyyy/mm/dd | |
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']), | |
163 | ); | |
164 | ||
165 | $pjpgRecur = new pjpgRecur($recurArray); | |
166 | ||
167 | $pjpgTxn->setRecur($pjpgRecur); | |
168 | } | |
169 | ||
170 | // create a pjpgRequest object passing the transaction object | |
171 | $pjpgRequest = new pjpgRequest($pjpgTxn); | |
172 | ||
173 | $pjpgHttpPost = new pjpgHttpsPost($pjpgRequest); | |
174 | ||
175 | // get an pjpgResponse object | |
176 | $pjpgResponse = $pjpgHttpPost->getPJpgResponse(); | |
177 | ||
178 | if (self::isError($pjpgResponse)) { | |
179 | return self::error($pjpgResponse); | |
180 | } | |
181 | ||
182 | /* Check for application errors */ | |
183 | ||
184 | $result = self::checkResult($pjpgResponse); | |
185 | if (is_a($result, 'CRM_Core_Error')) { | |
186 | return $result; | |
187 | } | |
188 | ||
189 | // Success | |
190 | $params['trxn_result_code'] = $pjpgResponse['dc_response_code']; | |
191 | $params['trxn_id'] = $pjpgResponse['dc_transaction_id']; | |
192 | $params['gross_amount'] = $params['amount']; | |
193 | ||
194 | return $params; | |
195 | } | |
196 | // end function doDirectPayment | |
197 | ||
198 | ||
199 | /* | |
200 | * This function checks the PayJunction response code | |
201 | */ | |
6c786a9b EM |
202 | /** |
203 | * @param $response | |
204 | * | |
205 | * @return bool | |
206 | */ | |
6a488035 TO |
207 | function isError(&$response) { |
208 | $responseCode = $response['dc_response_code']; | |
209 | ||
210 | if ($responseCode == "00" || $responseCode == "85") { | |
211 | return FALSE; | |
212 | } | |
213 | else { | |
214 | return TRUE; | |
215 | } | |
216 | } | |
217 | ||
218 | ||
219 | // ignore for now, more elaborate error handling later. | |
6c786a9b EM |
220 | /** |
221 | * @param $response | |
222 | * | |
223 | * @return mixed | |
224 | */ | |
6a488035 TO |
225 | function &checkResult(&$response) { |
226 | return $response; | |
227 | } | |
228 | ||
229 | /** | |
230 | * Get the value of a field if set | |
231 | * | |
232 | * @param string $field the field | |
233 | * | |
234 | * @return mixed value of the field, or empty string if the field is | |
235 | * not set | |
236 | */ | |
237 | function _getParam($field) { | |
238 | if (isset($this->_params[$field])) { | |
239 | return $this->_params[$field]; | |
240 | } | |
241 | else { | |
242 | return ''; | |
243 | } | |
244 | } | |
245 | ||
6c786a9b EM |
246 | /** |
247 | * @param null $error | |
248 | * | |
249 | * @return object | |
250 | */ | |
6a488035 TO |
251 | function &error($error = NULL) { |
252 | $e = CRM_Core_Error::singleton(); | |
253 | if ($error) { | |
254 | $e->push($error['dc_response_code'], | |
255 | 0, NULL, | |
256 | $error['dc_response_message'] | |
257 | ); | |
258 | } | |
259 | else { | |
260 | $e->push(9001, 0, NULL, "Unknown System Error."); | |
261 | } | |
262 | return $e; | |
263 | } | |
264 | ||
265 | /** | |
266 | * Set a field to the specified value. Value must be a scalar (int, | |
267 | * float, string, or boolean) | |
268 | * | |
269 | * @param string $field | |
270 | * @param mixed $value | |
271 | * | |
272 | * @return bool false if value is not a scalar, true if successful | |
273 | */ | |
274 | function _setParam($field, $value) { | |
275 | if (!is_scalar($value)) { | |
276 | return FALSE; | |
277 | } | |
278 | else { | |
279 | $this->_params[$field] = $value; | |
280 | } | |
281 | } | |
282 | ||
283 | /** | |
284 | * This function checks to see if we have the right config values | |
285 | * | |
286 | * @return string the error message if any | |
287 | * @public | |
288 | */ | |
289 | function checkConfig() { | |
290 | $error = array(); | |
291 | if (empty($this->_paymentProcessor['user_name'])) { | |
292 | $error[] = ts('Username is not set for this payment processor'); | |
293 | } | |
294 | ||
295 | if (empty($this->_paymentProcessor['password'])) { | |
296 | $error[] = ts('Password is not set for this payment processor'); | |
297 | } | |
298 | ||
299 | if (empty($this->_paymentProcessor['url_site'])) { | |
300 | $error[] = ts('Site URL is not set for this payment processor'); | |
301 | } | |
302 | ||
303 | if (!empty($error)) { | |
304 | return implode('<p>', $error); | |
305 | } | |
306 | else { | |
307 | return NULL; | |
308 | } | |
309 | } | |
310 | } | |
311 | // end class CRM_Core_Payment_PayJunction | |
312 |