Merge pull request #17448 from mattwire/api4membershiptype
[civicrm-core.git] / CRM / Core / Payment / PayJunction.php
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 */
16 require_once 'PayJunction/pjClasses.php';
17
18 /**
19 * Class CRM_Core_Payment_PayJunction.
20 */
21 class CRM_Core_Payment_PayJunction extends CRM_Core_Payment {
22 // (not used, implicit in the API, might need to convert?)
23 const CHARSET = 'UFT-8';
24
25 /**
26 * Constructor.
27 *
28 * @param string $mode
29 * The mode of operation: live or test.
30 *
31 * @param $paymentProcessor
32 *
33 * @return \CRM_Core_Payment_PayJunction
34 */
35 public function __construct($mode, &$paymentProcessor) {
36 $this->_mode = $mode;
37 $this->_paymentProcessor = $paymentProcessor;
38 }
39
40 /**
41 * This function sends request and receives response from
42 * PayJunction payment process
43 *
44 * @param array $params
45 * Assoc array of input parameters for this transaction.
46 *
47 * @return array
48 * the result in an nice formatted array (or an error object)
49 */
50 public function doDirectPayment(&$params) {
51 $logon = $this->_paymentProcessor['user_name'];
52 $password = $this->_paymentProcessor['password'];
53 $url_site = $this->_paymentProcessor['url_site'];
54
55 // create pjpgCustInfo object
56 $pjpgCustInfo = new pjpgCustInfo();
57
58 $pjpgCustInfo->setEmail($params['email']);
59
60 $billing = [
61 "logon" => $logon,
62 "password" => $password,
63 "url_site" => $url_site,
64 "first_name" => $params['first_name'],
65 "last_name" => $params['last_name'],
66 "address" => $params['street_address'],
67 "city" => $params['city'],
68 "province" => $params['state_province'],
69 "postal_code" => $params['postal_code'],
70 "country" => $params['country'],
71 ];
72 $pjpgCustInfo->setBilling($billing);
73
74 // create pjpgTransaction object
75 $my_orderid = $params['invoiceID'];
76
77 $expiry_string = sprintf('%04d%02d', $params['year'], $params['month']);
78
79 $txnArray = [
80 'type' => 'purchase',
81 'order_id' => $my_orderid,
82 'amount' => sprintf('%01.2f', $params['amount']),
83 'pan' => $params['credit_card_number'],
84 'expdate' => $expiry_string,
85 'crypt_type' => '7',
86 'cavv' => $params['cvv2'],
87 'cust_id' => $params['contact_id'],
88 ];
89
90 // Allow further manipulation of params via custom hooks
91 CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $txnArray);
92
93 $pjpgTxn = new pjpgTransaction($txnArray);
94
95 // set customer info (level 3 data) for the transaction
96 $pjpgTxn->setCustInfo($pjpgCustInfo);
97
98 // empty installments convert to 999 because PayJunction do not allow open end donation
99 if ($params['installments'] == "") {
100 $params['installments'] = "999";
101 }
102
103 // create recurring object
104 if ($params['is_recur'] == TRUE && $params['installments'] > 1) {
105 // schedule start date as today
106 // format: YYYY-MM-DD
107 $params['dc_schedule_start'] = date("Y-m-d");
108
109 // Recur Variables
110 $dc_schedule_create = $params['is_recur'];
111 $recurUnit = $params['frequency_unit'];
112 $recurInterval = $params['frequency_interval'];
113 $dc_schedule_start = $params['dc_schedule_start'];
114
115 // next payment in moneris required format
116 $startDate = date("Y/m/d", $next);
117
118 $numRecurs = $params['installments'];
119
120 $recurArray = [
121 'dc_schedule_create' => $dc_schedule_create,
122 // (day | week | month)
123 'recur_unit' => $recurUnit,
124 // yyyy/mm/dd
125 'start_date' => $startDate,
126 'num_recurs' => $numRecurs,
127 'start_now' => 'false',
128 'period' => $recurInterval,
129 'dc_schedule_start' => $dc_schedule_start,
130 'amount' => sprintf('%01.2f', $params['amount']),
131 ];
132
133 $pjpgRecur = new pjpgRecur($recurArray);
134
135 $pjpgTxn->setRecur($pjpgRecur);
136 }
137
138 // create a pjpgRequest object passing the transaction object
139 $pjpgRequest = new pjpgRequest($pjpgTxn);
140
141 $pjpgHttpPost = new pjpgHttpsPost($pjpgRequest);
142
143 // get an pjpgResponse object
144 $pjpgResponse = $pjpgHttpPost->getPJpgResponse();
145
146 if (self::isError($pjpgResponse)) {
147 return self::error($pjpgResponse);
148 }
149
150 /* Check for application errors */
151
152 $result = self::checkResult($pjpgResponse);
153 if (is_a($result, 'CRM_Core_Error')) {
154 return $result;
155 }
156
157 // Success
158 $params['trxn_result_code'] = $pjpgResponse['dc_response_code'];
159 $params['trxn_id'] = $pjpgResponse['dc_transaction_id'];
160 $params['gross_amount'] = $params['amount'];
161
162 return $params;
163 }
164
165 // end function doDirectPayment
166
167 /**
168 * This function checks the PayJunction response code.
169 *
170 * @param array $response
171 *
172 * @return bool
173 */
174 public function isError(&$response) {
175 $responseCode = $response['dc_response_code'];
176
177 if ($responseCode == "00" || $responseCode == "85") {
178 return FALSE;
179 }
180 else {
181 return TRUE;
182 }
183 }
184
185 /**
186 * ignore for now, more elaborate error handling later.
187 * @param $response
188 *
189 * @return mixed
190 */
191 public function &checkResult(&$response) {
192 return $response;
193 }
194
195 /**
196 * Get the value of a field if set.
197 *
198 * @param string $field
199 * The field.
200 *
201 * @return mixed
202 * value of the field, or empty string if the field is
203 * not set
204 */
205 public function _getParam($field) {
206 if (isset($this->_params[$field])) {
207 return $this->_params[$field];
208 }
209 else {
210 return '';
211 }
212 }
213
214 /**
215 * @param null $error
216 *
217 * @return object
218 */
219 public function &error($error = NULL) {
220 $e = CRM_Core_Error::singleton();
221 if ($error) {
222 $e->push($error['dc_response_code'],
223 0, NULL,
224 $error['dc_response_message']
225 );
226 }
227 else {
228 $e->push(9001, 0, NULL, "Unknown System Error.");
229 }
230 return $e;
231 }
232
233 /**
234 * Set a field to the specified value. Value must be a scalar (int,
235 * float, string, or boolean)
236 *
237 * @param string $field
238 * @param mixed $value
239 *
240 * @return bool
241 * false if value is not a scalar, true if successful
242 */
243 public function _setParam($field, $value) {
244 if (!is_scalar($value)) {
245 return FALSE;
246 }
247 else {
248 $this->_params[$field] = $value;
249 }
250 }
251
252 /**
253 * This function checks to see if we have the right config values.
254 *
255 * @return string
256 * the error message if any
257 */
258 public function checkConfig() {
259 $error = [];
260 if (empty($this->_paymentProcessor['user_name'])) {
261 $error[] = ts('Username is not set for this payment processor');
262 }
263
264 if (empty($this->_paymentProcessor['password'])) {
265 $error[] = ts('Password is not set for this payment processor');
266 }
267
268 if (empty($this->_paymentProcessor['url_site'])) {
269 $error[] = ts('Site URL is not set for this payment processor');
270 }
271
272 if (!empty($error)) {
273 return implode('<p>', $error);
274 }
275 else {
276 return NULL;
277 }
278 }
279
280 }
281 // end class CRM_Core_Payment_PayJunction