Merge pull request #23278 from demeritcowboy/case-tags-static
[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 use Civi\Payment\Exception\PaymentProcessorException;
12
13 /**
14 *
15 * @package CRM
16 * @author Michael Morris and Gene Chi @ Phase2 Technology <mmorris@phase2technology.com>
17 */
18 require_once 'PayJunction/pjClasses.php';
19
20 /**
21 * Class CRM_Core_Payment_PayJunction.
22 */
23 class CRM_Core_Payment_PayJunction extends CRM_Core_Payment {
24 // (not used, implicit in the API, might need to convert?)
25 const CHARSET = 'UFT-8';
26
27 /**
28 * Constructor.
29 *
30 * @param string $mode
31 * The mode of operation: live or test.
32 *
33 * @param array $paymentProcessor
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|PropertyBag $params
45 *
46 * @param string $component
47 *
48 * @return array
49 * Result array (containing at least the key payment_status_id)
50 *
51 * @throws \Civi\Payment\Exception\PaymentProcessorException
52 */
53 public function doPayment(&$params, $component = 'contribute') {
54 $propertyBag = \Civi\Payment\PropertyBag::cast($params);
55 $this->_component = $component;
56 $result = $this->setStatusPaymentPending([]);
57
58 // If we have a $0 amount, skip call to processor and set payment_status to Completed.
59 // Conceivably a processor might override this - perhaps for setting up a token - but we don't
60 // have an example of that at the moment.
61 if ($propertyBag->getAmount() == 0) {
62 $result = $this->setStatusPaymentCompleted($result);
63 return $result;
64 }
65
66 $logon = $this->_paymentProcessor['user_name'];
67 $password = $this->_paymentProcessor['password'];
68 $url_site = $this->_paymentProcessor['url_site'];
69
70 // create pjpgCustInfo object
71 $pjpgCustInfo = new pjpgCustInfo();
72
73 $pjpgCustInfo->setEmail($params['email']);
74
75 $billing = [
76 'logon' => $logon,
77 'password' => $password,
78 'url_site' => $url_site,
79 'first_name' => $params['first_name'],
80 'last_name' => $params['last_name'],
81 'address' => $params['street_address'],
82 'city' => $params['city'],
83 'province' => $params['state_province'],
84 'postal_code' => $params['postal_code'],
85 'country' => $params['country'],
86 ];
87 $pjpgCustInfo->setBilling($billing);
88
89 // create pjpgTransaction object
90 $my_orderid = $params['invoiceID'];
91
92 $expiry_string = sprintf('%04d%02d', $params['year'], $params['month']);
93
94 $txnArray = [
95 'type' => 'purchase',
96 'order_id' => $my_orderid,
97 'amount' => sprintf('%01.2f', $params['amount']),
98 'pan' => $params['credit_card_number'],
99 'expdate' => $expiry_string,
100 'crypt_type' => '7',
101 'cavv' => $params['cvv2'],
102 'cust_id' => $params['contact_id'],
103 ];
104
105 // Allow further manipulation of params via custom hooks
106 CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $txnArray);
107
108 $pjpgTxn = new pjpgTransaction($txnArray);
109
110 // set customer info (level 3 data) for the transaction
111 $pjpgTxn->setCustInfo($pjpgCustInfo);
112
113 // empty installments convert to 999 because PayJunction do not allow open end donation
114 if ($params['installments'] === '') {
115 $params['installments'] = '999';
116 }
117
118 // create recurring object
119 if ($params['is_recur'] == TRUE && $params['installments'] > 1) {
120 // schedule start date as today
121 // format: YYYY-MM-DD
122 $params['dc_schedule_start'] = date("Y-m-d");
123
124 // Recur Variables
125 $dc_schedule_create = $params['is_recur'];
126 $recurUnit = $params['frequency_unit'];
127 $recurInterval = $params['frequency_interval'];
128 $dc_schedule_start = $params['dc_schedule_start'];
129
130 // next payment in moneris required format
131 $startDate = date("Y/m/d", $next);
132
133 $numRecurs = $params['installments'];
134
135 $recurArray = [
136 'dc_schedule_create' => $dc_schedule_create,
137 // (day | week | month)
138 'recur_unit' => $recurUnit,
139 // yyyy/mm/dd
140 'start_date' => $startDate,
141 'num_recurs' => $numRecurs,
142 'start_now' => 'false',
143 'period' => $recurInterval,
144 'dc_schedule_start' => $dc_schedule_start,
145 'amount' => sprintf('%01.2f', $params['amount']),
146 ];
147
148 $pjpgRecur = new pjpgRecur($recurArray);
149
150 $pjpgTxn->setRecur($pjpgRecur);
151 }
152
153 // create a pjpgRequest object passing the transaction object
154 $pjpgRequest = new pjpgRequest($pjpgTxn);
155
156 $pjpgHttpPost = new pjpgHttpsPost($pjpgRequest);
157
158 // get an pjpgResponse object
159 $pjpgResponse = $pjpgHttpPost->getPJpgResponse();
160
161 if (self::isError($pjpgResponse)) {
162 throw new PaymentProcessorException($pjpgResponse);
163 }
164
165 // Success
166 $params['trxn_result_code'] = $pjpgResponse['dc_response_code'];
167 $result['trxn_id'] = $pjpgResponse['dc_transaction_id'];
168 $result = $this->setStatusPaymentCompleted($result);
169 return $result;
170 }
171
172 // end function doDirectPayment
173
174 /**
175 * This function checks the PayJunction response code.
176 *
177 * @param array $response
178 *
179 * @return bool
180 */
181 public function isError(&$response) {
182 $responseCode = $response['dc_response_code'];
183
184 if ($responseCode === "00" || $responseCode === "85") {
185 return FALSE;
186 }
187 return TRUE;
188 }
189
190 /**
191 * This function checks to see if we have the right config values.
192 *
193 * @return string
194 * the error message if any
195 */
196 public function checkConfig() {
197 $error = [];
198 if (empty($this->_paymentProcessor['user_name'])) {
199 $error[] = ts('Username is not set for this payment processor');
200 }
201
202 if (empty($this->_paymentProcessor['password'])) {
203 $error[] = ts('Password is not set for this payment processor');
204 }
205
206 if (empty($this->_paymentProcessor['url_site'])) {
207 $error[] = ts('Site URL is not set for this payment processor');
208 }
209
210 if (!empty($error)) {
211 return implode('<p>', $error);
212 }
213 return NULL;
214 }
215
216 }
217 // end class CRM_Core_Payment_PayJunction