Odyssey
rdcDigiliti.i
1 <?php
2 # 12/12/18 For port to Odyssey -
3 # changed usage of 'Cn' to 'MBRACCT' or 'Uid' as needed
4 # updated sql to use Odyssey schema
5 # removed use of loanbalance info -- Digiliti does not support deposit to loans
6 # various 'check an email' functions consolidated to Odyssey function validateEmail()
7 #
8 function RDCconfig($dbh, &$parms) {
9  $parms['QA'] = (!HCU_array_key_value('QA', $parms) ? 0 : HCU_array_key_value('QA', $parms) );
10  if ($parms['QA']) {
11  $parms['dgMgmtURL'] = HCU_array_key_value('qaMgmtURL', $parms); # External Services / User Management
12  $parms['dgUser'] = HCU_array_key_value('qaUser', $parms); # HomeCU login
13  $parms['dgPass'] = htmlentities(HCU_array_key_value('qaPass', $parms), ENT_COMPAT | ENT_XML1); # HomeCU password
14  $parms['dgMobileURL'] = HCU_array_key_value('qaMobileURL', $parms); # Mobile Services / Deposits & History
15  } else {
16  $parms['dgMgmtURL'] = HCU_array_key_value('prodMgmtURL', $parms); # External Services / User Management
17  $parms['dgUser'] = HCU_array_key_value('prodUser', $parms); # HomeCU login
18  $parms['dgPass'] = htmlentities(HCU_array_key_value('prodPass', $parms), ENT_COMPAT | ENT_XML1); # HomeCU password
19  $parms['dgMobileURL'] = HCU_array_key_value('prodMobileURL', $parms); # Mobile Services / Deposits & History
20  }
21  # check the 4 we just set, and the default phone user password also.
22  if (empty($parms['dgMobileURL']) || empty($parms['dgMgmtURL']) ||
23  empty($parms['dgUser']) || empty($parms['dgPass']) || empty($parms['PhonePass']) ) {
24  throw new Exception("Missing Parameters", 100);
25  }
26 }
27 
28 function RDCauth($dbh, $HB_ENV, $MC, $parms) {
29 # requires: $parms['Cu']
30 # $parms['rdcvendor']
31 # Additional values rdcvendor retrieved and decoded from cutrusteddetail
32 #
33 # returns:
34  # assume we are going to succeed...
35  $return['status']['response'] = 'true';
36  $return['status']['code'] = '000';
37  $return['status']['message'] = 'Success';
38 
39  try {
40 // # just to test and get a vendor logging entry:
41 // $dgtest = digiGetAccountTypeNames($parms);
42 // $dgtest = digiGetABANumbers($parms);
43 //
44  # If authorizing at HomeCU, is member authorized?
45  if (HCU_array_key_value('HomeCUAuth', $parms)) {
46  $mbr_rdc = Get_RDCSetting($dbh, $HB_ENV, 'RDCDigiliti', $parms['MBRACCT']);
47  if ($mbr_rdc['status']['code'] != '000') {
48  throw new Exception($mbr_rdc['status']['message'], $mbr_rdc['status']['code']);
49  }
50  $dl = $mbr_rdc['rdcsetting'];
51  if (abs(intval($dl)) == 0) {
52 
53  $HB_Notices_ary = Get_NoticeInfo($dbh, $HB_ENV, $MC, 'M', "mblNoRDC", true);
54  if ($HB_Notices_ary['status']['code'] == '000') {
55  $noticeData = $HB_Notices_ary["notice"][0]["notice_text"];
56  } else {
57  $noticeData = "";
58  }
59  if (strlen($noticeData)) {
60  $message = $noticeData;
61  $code = 111;
62  } else {
63  $message = "Account not permitted for Remote Deposit. Please contact the Credit Union for more information";
64  $code = 110;
65  }
66  throw new Exception($message, $code);
67  }
68  }
69  # member is authorized - check for terms
70  $parms['rdcstatus'] = 'S';
71  $rdcterms = array();
72 
73  if (HCU_array_key_value('HomeCUterms', $parms)) {
74  $rdcterms = hcuGetRDCterms($dbh, $HB_ENV, $MC);
75 
76  if ($rdcterms['status']['response'] == 'false') {
77  $e = "HCU GetTerms call failed ({$rdcterms['status']['code']} {$rdcterms['status']['message']}";
78  throw new Exception($e, 301);
79  }
80  if ($rdcterms['data']['notice_popup'] == 1) {
81  $parms['rdcstatus'] = 'T';
82  }
83  }
84 
85  # Get HomeCU-eligible accounts
86  $parms['Fset2'] = $HB_ENV['Fset2']; # HB_ENV
87  $parms['Fset3'] = $HB_ENV['Fset3']; # HB_ENV
88  $parms['Uid'] = $HB_ENV['Uid'];
89  $hculist = RDCGetAccts($dbh, $parms);
90 
91  if ($hculist['status']['code'] !== '000') {
92  throw new Exception($hculist['status']['message'], $hculist['status']['code']);
93  }
94 
95  # got a valid RDC account list
96 
97  $parms['HCUAccounts'] = $hculist['data']; # from mammoth
98  $parms['deplimit'] = (isset($dl) ? $dl : 0);
99 
100  # got a valid RDC account list
101  # collect the Digiliti info
102 
103  $parms['live'] = HCU_array_key_value('live',$HB_ENV);
104  $dglist = digiStartSession($parms, $HB_ENV);
105  if ($dglist['status']['response'] == 'false') {
106  throw new Exception($dglist['status']['message'], $dglist['status']['code']);
107  }
108 
109  if (empty($dglist['data']['dgUserId'])) {
110  throw new Exception('Digiliti Invalid User ', 300);
111  }
112 # get user profile (deposit limits) here, and reformat messages as in PresentAccounts
113 # deposit limits, particularly the remaining available, may have changed since last call
114  $dgprofile = digiGetUserProfile($parms, $dglist['data']['dgUserId']);
115 
116 # dgprofile['data']['scanlimit']
117 # dgprofile['data']['UserRunningTotals']['AvailableItemsPerDay']
118 
119  if ($dgprofile['status']['response'] == 'false') {
120  throw new Exception($dgprofile['status']['message'], $dgprofile['status']['code']);
121  }
122  if ($dgprofile['data']['scanlimit'] <= 0) {
123  throw new Exception('Digiliti Profile Limits Exceeded', 999);
124  }
125  $dglist['data']['scanlimit'] = $dgprofile['data']['scanlimit'];
126 
127  $presaccts = RDCPresentAccounts($parms, $dglist, $rdcterms);
128  if ($presaccts['status']['response'] == 'false') {
129  # error send fail
130  throw new Exception($presaccts['status']['message'], $presaccts['status']['code']);
131  }
132  $depmessages=array();
133  if (HCU_array_key_value('ShowScanlimit', $parms)) {
134  $depmessages[] = array("MessageTextCd" => "HCU1","LocalizedText" => "Deposit Limit is " . sprintf("%.2f","{$dglist['data']['scanlimit']}"));
135  }
136 
137  # Now getting a new deposit record every time. Not tied
138  # to shared branching, so no cost implication for client?
139  # Check first for valid session key, if not found, start session
140  $newrec = 1;
141  # no session to recycle, or only old sessions
142  $parms['vendorinfo'] = array(
143  'Vendortime' => mktime(),
144  'userAgent' => $_SERVER['HTTP_USER_AGENT'],
145  'userIP' => $_SERVER['REMOTE_ADDR'],
146  'accounts' => $presaccts['data']['accounts'],
147  'depmessages' => $depmessages,
148  'scanlimit' => $dgprofile['data']['scanlimit'],
149  'dgUserId' => $presaccts['data']['dgUserId'],
150  'dgUserName' => $presaccts['data']['dgUserName']
151  );
152 
153  if (HCU_array_key_value('HomeCUterms', $parms)) {
154  $localTerms = (HCU_array_key_value('terms', $rdcterms['data']) ? $rdcterms['data']['terms'] : '');
155  } else {
156  $localTerms = '';
157  }
158 
159  if ($newrec) {
160  # start curdc record, return depositid as part of result
161  $depostat = curdc_start($dbh, $parms);
162  if ($depostat['status']['response'] == 'false') {
163  # error send fail
164  throw new Exception('HomeCU Start Deposit Failed', 200);
165  }
166  $parms['depositid'] = $depostat['data']['depositid'];
167  }
168  $return['data']['depositid'] = $parms['depositid'];
169  $return['data']['accounts'] = $parms['vendorinfo']['accounts'];
170  $return['data']['depmessages'] = $parms['vendorinfo']['depmessages'];
171  $return['data']['terms'] = $localTerms;
172 
173 
174  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
175  'vendorinfo' => json_encode($parms['vendorinfo'])));
176  if ($depostat['status']['response'] == 'false') {
177  # error send fail
178  throw new Exception($depostat['status']['message'], $depostat['status']['code']);
179  }
180  } catch (Exception $e) {
181  $return['status']['response'] = 'false';
182  $return['status']['code'] = $e->getCode();
183  $return['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
184  }
185  return $return;
186 }
187 
188 function RDCaccept($dbh, $HB_ENV, $MC, $parms) {
189 # requires: $parms['Cu']
190 # $parms['depositid']
191 # Additional values retrieved and decoded from cutrusteddetail
192 # or from curdcstatus record using depositid as key
193 # returns:
194  # assume we are going to succeed...
195  $return['status']['response'] = 'true';
196  $return['status']['code'] = '000';
197  $return['status']['message'] = 'Success';
198 
199  try {
200  if (!isset($parms['Cu']) || !isset($parms['depositid'])) {
201  throw new Exception('Missing Parameters', 100);
202  }
203  # look up depositid
204  # decode vendorinfo
205  $depo = curdc_read($dbh, $parms);
206  if ($depo['status']['response'] == 'false') {
207  throw new Exception('HomeCU DepositID not found', 205);
208  }
209 
210  # look up rdcTerms doc and then update to show acceptance
211  // get any notice text
212  $noticeInfo = Get_NoticeInfo($dbh, $HB_ENV, $MC, "P", "rdcTerms", false);
213  if ($noticeInfo["status"]["code"] == "000" && sizeof($noticeInfo['notice']) && intval($noticeInfo['notice'][0]['notice_id']) > 0) {
214  # action P post so set up the HCUPOST array
215  $HB_ENV['HCUPOST']['notice_id'] = $noticeInfo['notice'][0]['notice_id'];
216  $HB_ENV['HCUPOST']['notice_type'] = $noticeInfo['notice'][0]['notice_type'];
217  $HB_ENV['HCUPOST']['notice_device'] = 'P';
218  $HB_ENV["HCUPOST"]['notice_response'] = array("answer" => 1); // something non-zero but numeric
219  # not sure if the next two are needed -
220  $HB_ENV["HCUPOST"]['notice_cancel'] = "0";
221  $HB_ENV['HCUPOST']['notice_msg_show'] = 1;
222  $noticeUpd = Update_NoticeInfo($dbh, $HB_ENV, $MC);
223 
224  $return['status']['message'] = 'Accept Terms OK';
225  $vendorinfo = $depo['vendorinfo'];
226  $vendorinfo['terms'] = '';
227  $vendorinfo['Vendortime'] = mktime();
228  $parms['vendorinfo'] = $vendorinfo;
229  }
230 
231  # update curdcstatus record
232  $parms['rdcstatus'] = 'O';
233 
234  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
235  'rdcstatus' => $parms['rdcstatus'], 'vendorinfo' => json_encode($parms['vendorinfo'])));
236  if ($depostat['status']['response'] == 'false') {
237  # error send fail
238  throw new Exception($depostat['status']['message'], $depostat['status']['code']);
239  }
240  } catch (Exception $e) {
241  $return['status']['response'] = 'false';
242  $return['status']['code'] = $e->getCode();
243  $return['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
244  }
245  return $return;
246 }
247 
248 function RDChistorylist($dbh, $parms) {
249 # requires: $parms['Cu']
250 # $parms['depositid']
251 # Additional values retrieved and decoded from cutrusteddetail
252 # or from curdcstatus record using depositid as key
253 # returns:
254  # assume we are going to succeed...
255  $return['status']['response'] = 'true';
256  $return['status']['code'] = '000';
257  $return['status']['message'] = 'Success';
258 
259  try {
260  if (!isset($parms['Cu']) || !isset($parms['depositid'])) {
261  throw new Exception('Missing Parameters', 100);
262  }
263  # look up depositid
264  # decode vendorinfo
265  $depo = curdc_read($dbh, $parms);
266  if ($depo['status']['response'] == 'false') {
267  throw new Exception("HomeCU DepositID not found [{$parms['depositid']}]", 205);
268  }
269  # format the digiliti username value here
270  $parms['searchuser'] = (strlen($parms['MBRACCT']) < 4 ? substr('00000' . $parms['MBRACCT'], -4, 4) : $parms['MBRACCT']);
271 
272  $rdcresult = digiSearchTransactions($parms);
273  if ($rdcresult['status']['code'] != '000' && $rdcresult['status']['code'] != '404') {
274  throw new Exception('digi Get History List call failed. ' . $rdcresult['status']['message'], $rdcresult['status']['code']);
275  }
276 
277  if ($rdcresult['status']['code'] == '404') {
278  $return['status']['message'] = 'No Transactions Found';
279  } else {
280 // LogToFile( __LINE__ ,"digiSearch results", (array) $rdcresult['data']['Transactions']);
281  foreach ((array) $rdcresult['data']['Transactions'] as $histkey => $histitem) {
282  // set return values using ensenta names, just because
283  // they were first and OFXRequest expects those names
284 
285  // Bugs me to swap ReceiptReferenceNo & transactionid, but
286  // ReceiptReferenceNo needs to match the value saved as
287  // ['vendorinfo']['TransactionReceiptNumber'] in the curdcstatus rec
288  // because OFXRequest uses it for key matching
289  $rdcresult['data']['Transactions'][$histkey]['ReceiptReferenceNo'] = $histitem['TransactionId'];
290  $rdcresult['data']['Transactions'][$histkey]['TransactionId'] = "{$histitem['TransactionId']}_HCU_{$histitem['PartnerTransactionId']}";
291  $rdcresult['data']['Transactions'][$histkey]['transactiondttm'] = $histitem['SubmissionDate'];
292  # EnteredAmount? ApprovedAmount? RecognizedAmount? hmm....
293  $rdcresult['data']['Transactions'][$histkey]['submittedamount'] = sprintf('%.2f', $histitem['EnteredAmount']);
294  $rdcresult['data']['Transactions'][$histkey]['currentamount'] = sprintf('%.2f', $histitem['ApprovedAmount']);
295  $rdcresult['data']['Transactions'][$histkey]['status'] = $histitem['Status'];
296  $rdcresult['data']['Transactions'][$histkey]['statusdescr'] = "{$histitem['BizRuleEngineMessage']}";
297  $rdcresult['data']['Transactions'][$histkey]['statusdisplay'] = ($histitem['Status'] == 'NeedsReview' ? 'Needs Review' : $histitem['Status'] ) . ": {$histitem['BizRuleEngineMessage']}";
298  $rdcresult['data']['Transactions'][$histkey]['transactiontype'] = $histitem['AccountNickName'];
299  $rdcresult['data']['Transactions'][$histkey]['accountnumber'] = $histitem['UserAccountNumber'];
300  }
301 // LogToFile( __LINE__ ,"after parsing results", (array) $rdcresult['data']['Transactions']);
302  $return['status']['message'] = 'History List OK';
303  }
304  $vendorinfo = $depo['vendorinfo'];
305  $vendorinfo['Vendortime'] = mktime();
306  $parms['vendorinfo'] = $vendorinfo;
307 
308  # update curdcstatus record
309 
310  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
311  'vendorinfo' => json_encode($parms['vendorinfo'])));
312  if ($depostat['status']['response'] == 'false') {
313  # error send fail
314  throw new Exception($depostat['status']['message'], $depostat['status']['code']);
315  }
316  $return['data']['TransactionList'] = $rdcresult['data']['Transactions'];
317  $return['data']['rdcvendor'] = $depo['data']['rdcvendor'];
318  } catch (Exception $e) {
319  $return['status']['response'] = 'false';
320  $return['status']['code'] = $e->getCode();
321  $return['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
322  }
323  return $return;
324 }
325 
326 function RDChistorydetl($dbh, $parms) {
327 # 2/12/18 MH
328 # function does not appear to be called anywhere -
329 # but if we did call it, ItemId would need to be the
330 # ReceiptReferenceNo from the desired transaction
331 # requires: $parms['Cu']
332 # $parms['ItemId']
333 # Additional values retrieved and decoded from cutrusteddetail
334 # or from curdcstatus record using depositid as key
335 # returns:
336  # assume we are going to succeed...
337  $return['status']['response'] = 'true';
338  $return['status']['code'] = '000';
339  $return['status']['message'] = 'Success';
340 
341  try {
342  if (!isset($parms['Cu']) || !isset($parms['ItemId']) || !isset($parms['depositid'])) {
343  throw new Exception('Missing Parameters', 100);
344  }
345  # look up depositid
346  # decode vendorinfo
347  $depo = curdc_read($dbh, $parms);
348  if ($depo['status']['response'] == 'false') {
349  throw new Exception('HomeCU DepositID not found', 205);
350  }
351  $rdcresult = digiGetHistoryItem($parms, $parms['ItemId']);
352  if ($rdcresult['status']['response'] == 'false' || $rdcresult['data']['ResponseCode'] != '00') {
353  $e = ($rdcresult['status']['response'] == 'false' ? 'digi Get History Item call failed' :
354  "GetHistoryItem - " . $rdcresult['data']['ResponseCode'] . ' ' . $rdcresult['data']['ErrorResponseText'] . ' ' . $rdcresult['data']['LocalizedMessageText']);
355  throw new Exception($e, 305);
356  }
357  $return['status']['message'] = 'digi GetHistoryItem OK';
358  $vendorinfo = $depo['vendorinfo'];
359  $vendorinfo['Vendortime'] = mktime();
360  $parms['vendorinfo'] = $vendorinfo;
361 
362  # update curdcstatus record
363  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
364  'vendorinfo' => json_encode($parms['vendorinfo'])));
365  if ($depostat['status']['response'] == 'false') {
366  # error send fail
367  throw new Exception($depostat['status']['message'], $depostat['status']['code']);
368  }
369  $return['data'] = $rdcresult['data'];
370  } catch (Exception $e) {
371  $return['status']['response'] = 'false';
372  $return['status']['code'] = $e->getCode();
373  $return['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
374  }
375  return $return;
376 }
377 
378 function RDCdeposit($dbh, $parms) {
379 # requires: $parms['Cu']
380 # $parms['depositid']
381 # $parms['amount']
382 # $parms['acctid']
383 # $parms['rdcacctid']
384 # Additional values retrieved and decoded from cutrusteddetail
385 # or from curdcstatus record using depositid as key
386 # returns:
387  # assume we are going to succeed...
388  $return['status']['response'] = 'true';
389  $return['status']['message'] = 'Success';
390  $return['status']['code'] = '000';
391  try {
392  if (!isset($parms['Cu']) || !isset($parms['depositid']) ||
393  !isset($parms['amount']) || !isset($parms['acctid'])) {
394 // !isset($parms['rdcacctid'])) {
395  throw new Exception('Missing Parameters', 100);
396  }
397  /*
398  * need to use $parms['acctid'] to retrieve info about receiving account
399  * get from vendorinfo['accounts'] stored in deposit record, as that includes
400  * vendor-returned info
401  */
402 
403  # look up depositid
404  $depo = curdc_read($dbh, $parms);
405  if ($depo['status']['response'] == 'false') {
406  throw new Exception('HomeCU DepositID not found', 205);
407  }
408  $fail = '';
409  switch ($depo['data']['status']) {
410  case 'T':
411  $fail = 'Must accept terms of use before depositing funds';
412  break;
413  case 'R':
414  $fail = 'Deposit has been rejected';
415  break;
416  case 'C':
417  $fail = 'Deposit already completed';
418  break;
419  case 'B':
420  case 'F':
421  if (!isset($parms['POSTAWAY'])) {
422  $fail = 'Deposit requires override confirmation';
423  }
424  break;
425  }
426  if ("$fail" != '') {
427  throw new Exception($fail, 229);
428  }
429  if (is_null($depo['data']['frontpath']) || is_null($depo['data']['backpath']) || !getimagesize($depo['data']['frontpath']) || !getimagesize($depo['data']['backpath'])) {
430  throw new Exception('Check Images not found', 220);
431  }
432  $vendorinfo = $depo['data']['vendorinfo'];
433 
434  // Store amount, selected account in curdcstatus table
435  $depostat = curdc_update($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
436  'amount' => $parms['amount'], 'acctid' => $parms['acctid']));
437  if ($depostat['status']['response'] == 'false') {
438  throw new Exception('HomeCU Update Deposit Amount Failed', 225);
439  }
440 
441  $acctid = $parms['acctid'];
442  $hculist = RDCGetAccts($dbh, $parms, $acctid);
443 
444 // LogToFile(__LINE__, 'HCULIST', $hculist);
445 // LogToFile(__LINE__, 'VENDOR', $vendorinfo);
446  # call as LogToFile( __LINE__ ,"Title",$array_to_print);
447 
448  if ($hculist['status']['response'] !== 'true') {
449  throw new Exception('Invalid Deposit Account', 230);
450  }
451 // Ignore scan limit here - defer to client configuration at CheckReview
452 // $scanlimit = $vendorinfo['scanlimit'];
453 // if (!is_null($scanlimit) && $scanlimit < ($parms['amount'] * .01)) {
454 // throw new Exception("Deposit Amount Exceeds Deposit Limit (" .
455 // sprintf('%.2f', $scanlimit) . ")", 231);
456 // }
457  $parms['dgUserId'] = $vendorinfo['dgUserId'];
458  $parms['dgUserName'] = $vendorinfo['dgUserName'];
459  $parms['AccountNumber'] = $vendorinfo['accounts'][$acctid]['suffix'];
460  $parms['RDCName'] = $vendorinfo['accounts'][$acctid]['RDCName'];
461  # set default AccountType, then override if configured
462  $parms['AccountType'] = $vendorinfo['accounts'][$acctid]['rdctype'];
463  $parms['CheckFront'] = file_get_contents($depo['data']['frontpath']);
464  $parms['CheckBack'] = file_get_contents($depo['data']['backpath']);
465  $rdcresult = digiPostItem($parms);
466  if ($rdcresult['status']['code'] != '000' && $rdcresult['status']['code'] != '400') {
467  throw new Exception("PostItem failed {$rdcresult['status']['message']}", $rdcresult['status']['code']);
468  }
469 // {"BatchID":null,"ItemID":null,"WasSuccessful":false,"ErrorMessage":"Cannot read acct. data on bottom of check. Please retake. Ensure focus and all four corners visible."}
470  # check return values for error
471  if ($rdcresult['data']['Message'] !== 'Success') {
472  $parms['rdcstatus'] = 'R';
473  $vendorinfo['Vendortime'] = mktime();
474  $vendorinfo['DepositStatus'] = "Failed";
475  $vendorinfo['Message'] = $rdcresult['status']['message'];
476  $vendorinfo['Review'] = $rdcresult['data']['Transaction']['Status'];
477  $vendorinfo['DepositTime'] = date('YmdHis');
478  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'],
479  'rdcstatus' => $parms['rdcstatus'], 'vendorinfo' => json_encode($vendorinfo)));
480  if ($depostat['status']['response'] == 'false') {
481  throw new Exception('HomeCU Update Vendorinfo Failed', 240);
482  }
483  throw new Exception($rdcresult['status']['message'] . ' Deposit Cannot be processed as submitted', 241);
484  } else {
485  $parms['rdcstatus'] = 'C';
486  $vendorinfo['Vendortime'] = $rdcresult['data']['Transaction']['SubmissionDate'];
487  $vendorinfo['DepositStatus'] = $rdcresult['data']['Transaction']['Status'];
488  $vendorinfo['Message'] = $rdcresult['status']['message'];
489  $vendorinfo['Review'] = $rdcresult['data']['Transaction']['Status'];
490  $vendorinfo['TransactionReceiptNumber'] = $rdcresult['data']['Transaction']['TransactionId'];
491  $vendorinfo['TransactionDateTime'] = $rdcresult['data']['Transaction']['SubmissionDate'];
492 // $vendorinfo['raw']=$rdcresult['data']['raw'];
493  $depostat = curdc_setvinfo($dbh, array('Cu' => $parms['Cu'], 'depositid' => $parms['depositid'], 'frontaccept' => 'Y',
494  'backaccept' => 'Y', 'rdcstatus' => $parms['rdcstatus'], 'vendorinfo' => json_encode($vendorinfo)));
495  if ($depostat['status']['response'] == 'false') {
496  throw new Exception('HomeCU Update Vendorinfo Failed', 240);
497  }
498  $return['status']['response'] = 'true';
499  $return['status']['message'] = 'Digiliti Deposit Complete';
500  # this returns everything from Ensenta, but that will be a problem if we add other vendors
501  # pick a list of stuff to return and be consistent for everyone?
502  $return['data'] = $rdcresult['data'];
503  $return['data']['depositid'] = $parms['depositid'];
504  $return['data']['rdcstatus'] = $parms['rdcstatus'];
505  # use the Ensenta names for values the apps look for --
506  $return['data']['TransactionReceiptNumber'] = $rdcresult['data']['Transaction']['TransactionId'];
507  $return['data']['TransactionDateTime'] = $rdcresult['data']['Transaction']['SubmissionDate'];
508  $return['data']['MaskedAccountholderNumber'] = $vendorinfo['accounts'][$acctid]['suffix'];
509 
510  $hcumessage = "Your deposit request for account {$vendorinfo['accounts'][$acctid]['suffix']} has been received";
511  if ($rdcresult['data']['Transaction']['Status'] == 'NeedsReview') {
512  $hcumessage .= " pending review";
513  }
514  $hcumessage .= ". Your confirmation number is '{$rdcresult['data']['Transaction']['TransactionId']}_HCU_{$parms['depositid']}'. ";
515  $hcumessage .= "Please save this number and refer to it if you need to contact the credit union regarding this transaction. ";
516 
517  $return['data']['HCUReceiptMessage'] = $hcumessage;
518  }
519  } catch (Exception $e) {
520  $return['status']['response'] = 'false';
521  $return['status']['code'] = $e->getCode();
522  $return['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
523  }
524 
525  return $return;
526 }
527 
528 function RDCGetAccts($dbh, $parms, $Acctid = "") {
529  try {
530  $AcctList = array();
531  if (!HCU_array_key_value('Cu', $parms) || !HCU_array_key_value('Uid', $parms) || !HCU_array_key_value('MBRACCT', $parms) ) {
532  throw new Exception('Missing RDC Account Parameters', 910);
533  }
534 
535  $Cu = HCU_array_key_value('Cu', $parms);
536  $Uid = HCU_array_key_value('Uid', $parms);
537  $balwhere = HCU_array_key_value('balwhere', $parms);
538  $Fset2 = HCU_array_key_value('Fset2', $parms);
539  $Fset3 = HCU_array_key_value('Fset3', $parms);
540  $lnwhere = HCU_array_key_value('lnwhere', $parms);
541  $MBRACCT = HCU_array_key_value('MBRACCT', $parms);
542 
543 # digiliti can support loans - add 'LN' => 1 to the rtxn array
544  $rtxn = ( sizeof($parms['rtxn']) == 0 ?
545  array('AT' => 1) :
546  json_decode(HCU_array_key_value('rtxn', $parms), TRUE) );
547  $savingsql = (!HCU_array_key_value('savingsql', $parms) ?
548  "trim(accounttype)" :
549  HCU_array_key_value('savingsql', $parms) );
550  $draftsql = (!HCU_array_key_value('draftsql', $parms) ?
551  "trim(accounttype)" :
552  HCU_array_key_value('draftsql', $parms) );
553  $mbrsql = (!HCU_array_key_value('mbrsql', $parms) ?
554  "trim(accountnumber)" :
555  HCU_array_key_value('mbrsql', $parms) );
556 
557 # fetch transactions types
558 
559  $sql = "select ht.trancode, trim(t.trandesc), trim(ht.cudesc), t.specialproc
560  from cutrans t, cuhavetrans ht
561  where ht.cu='$Cu'
562  and ht.trancode = t.trancode\n";
563 
564  $sth = db_query($sql, $dbh);
565  #
566  # Return a line for each allowed transaction type.
567  #
568  $txncodes = array();
569  for ($row = 0; list($code, $desc, $cudesc, $spec) = db_fetch_array($sth, $row); $row++) {
570  $txncodes{$code} = array($desc, $spec, $cudesc);
571  }
572  db_free_result($sth);
573 
574  $sql = "";
575  $verb = "";
576 
577  $sv_rdcname = (!HCU_array_key_value('Sv_rdcname', $parms) ? 'Savings' : $parms['Sv_rdcname']);
578  $ck_rdcname = (!HCU_array_key_value('Ck_rdcname', $parms) ? 'Checking' : $parms['Ck_rdcname']);
579  $sv_rdctype = (!HCU_array_key_value('Sv_rdctype', $parms) ? '2' : $parms['Sv_rdctype']);
580  $ck_rdctype = (!HCU_array_key_value('Ck_rdctype', $parms) ? '1' : $parms['Ck_rdctype']);
581  # code was trying to:
582  # if the rdctype is all digits, leave it plain else wrap in single quotes for Postgres
583 // $sv_rdctype = (str_word_count($sv_rdctype, 0, '0123456789') > 1 ? $sv_rdctype : "'$sv_rdctype'");
584 // $ck_rdctype = (str_word_count($ck_rdctype, 0, '0123456789') > 1 ? $ck_rdctype : "'$ck_rdctype'");
585  # but didn't work as expected. Worked better to just quote the *_rdctype
586  # whether it was digits or string.
587 # and that appears to work for Checking / Savings... but what about the client that had 'MoneyMarket'?
588 # hmmm... Ignoring for now as can't find the client that needed it
589 
590 # find out how many valid accounts the member has:
591 $sql = "WITH accountlist as (
592  SELECT ab.accountnumber,
593  ua.display_name,
594  description,
595  ua.accounttype as accounttype,
596  ua.certnumber as certnumber,
597  ua.recordtype,
598  ua.view_balances,
599  ua.view_transactions,
600  ab.deposittype,
601  'DP' as cbtype, amount as currentbalance,
602  ua.display_order,
603  trim(ab.micraccount) as micraccount
604  FROM {$Cu}useraccounts as ua
605  INNER JOIN {$Cu}accountbalance as ab ON ab.accountnumber = ua.accountnumber
606  AND ab.accounttype = ua.accounttype
607  AND ua.certnumber = ua.certnumber
608  WHERE ua.user_id = $Uid
609  AND ua.accountnumber = '{$MBRACCT}'
610  AND ua.recordtype = 'D'
611  AND ab.may_deposit = true ) ";
612 
613  if (HCU_array_key_exists('AT',$txncodes) && HCU_array_key_exists('AT',$rtxn)) {
614 # $txncodes is configured list @HCU - $rtxn is allowed list for RDC
615 # Digiliti supports AT only, no LP
616 
617  $sql .= "SELECT recordtype as tbl,
618  $mbrsql as rdcmember, trim(description) as description,
619  trim(display_name) as display_name,
620  trim(accounttype) as accounttype, $savingsql as suffix,
621  certnumber as certnumber, '$sv_rdctype' as rdctype,
622  '$sv_rdcname' as rdcdesc,
623  display_order, trim(accountnumber) as accountnumber
624  FROM accountlist
625  WHERE recordtype = 'D' $balwhere
626  AND upper(deposittype) in ('S','N')
627  UNION
628  SELECT recordtype, $mbrsql as rdcmember,
629  trim(description), trim(display_name),
630  trim(accounttype), $draftsql,
631  certnumber, '$ck_rdctype',
632  '$ck_rdcname',
633  display_order,
634  trim(accountnumber)
635  FROM accountlist
636  WHERE recordtype = 'D' $balwhere
637  AND upper(deposittype) = 'Y' ";
638  }
639 
640  $sql .= " order by 6,2,3";
641  $acct_rs = db_query($sql, $dbh);
642 
643  if (db_num_rows($acct_rs) == 0) {
644 // RDC_response('920', array('No Eligible Accounts'), 'ERROR'); # RDCGetAccts no valid accounts
645 // $AcctList['sql'] = $sql;
646  throw new Exception("No Eligible RDC Accounts", 920);
647  } else {
648 
649  for ($row = 0; $drow = db_fetch_array($acct_rs, $row); $row++) {
650  $tbl = $drow['tbl'];
651  $accounttype = $drow['accounttype'];
652  $suffix = $drow['suffix'];
653  $cert = $drow['certnumber'];
654  $rdctype = $drow['rdctype'];
655  $rdcdesc = $drow['rdcdesc'];
656  $rdcmember = $drow['rdcmember'];
657  if (strpos($accounttype, "@")) {
658  list($jtype,$jacct) = explode("@",$accounttype);
659  $trust = 'joint';
660  } else {
661  $jtype=$accounttype;
662  $jacct=$MBRACCT;
663  $trust = 'primary';
664  }
665  $tokn = sha1("{$Uid}{$accounttype}{$Cu}{$rdctype}obl1vi0u5");
666 
667  $desc = getAccountDescription($dbh, $Cu, $drow['accountnumber'], $drow['description'], $drow['accounttype'], $drow['display_name'], $Fset3, $drow['certnumber'], false, false);
668  $desc = htmlspecialchars($desc, ENT_QUOTES,'UTF-8',FALSE);
669  $displaydesc = $desc;
670 
671  $Accts["$tbl|$jacct|$jtype|$cert"]['accounttype'] = $accounttype;
672  $Accts["$tbl|$jacct|$jtype|$cert"]['suffix'] = $suffix;
673  $Accts["$tbl|$jacct|$jtype|$cert"]['certnumber'] = $cert;
674  $Accts["$tbl|$jacct|$jtype|$cert"]['acctclass'] = $tbl;
675  $Accts["$tbl|$jacct|$jtype|$cert"]['description'] = $desc;
676  $Accts["$tbl|$jacct|$jtype|$cert"]['tokn'] = "$tokn";
677  $Accts["$tbl|$jacct|$jtype|$cert"]['Uid'] = "$Uid";
678  $Accts["$tbl|$jacct|$jtype|$cert"]['trust'] = "$trust";
679  $Accts["$tbl|$jacct|$jtype|$cert"]['displaydesc'] = "$displaydesc";
680  $Accts["$tbl|$jacct|$jtype|$cert"]['rdctype'] = $rdctype;
681  $Accts["$tbl|$jacct|$jtype|$cert"]['rdcdesc'] = $rdcdesc;
682  $Accts["$tbl|$jacct|$jtype|$cert"]['rdcmember'] = $rdcmember;
683  }
684  }
685  $AcctList['status']['response'] = 'true';
686  $AcctList['status']['code'] = '000';
687  $AcctList['status']['message'] = 'Success';
688 
689  if (!empty($Acctid)) {
690  # got an account identifier - return one only
691  if (!HCU_array_key_exists($Acctid, $Accts)) {
692  throw new Exception("Specified Account Not Found", 920);
693  }
694  $AcctList['data'][$Acctid]=$Accts[$Acctid];
695  } else {
696  $AcctList['data']=$Accts;
697 // $AcctList['sql'] = $sql;
698  }
699  } catch (Exception $e) {
700  $AcctList['status']['response'] = 'false';
701  $AcctList['status']['code'] = $e->getCode();
702  $AcctList['status']['message'] = "(" . $e->getLine() . ") " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8', FALSE);
703  }
704  return ($AcctList);
705 }
706 
707 /**
708  *
709  * @param array $parms
710  * @param array $dglist
711  * digiStartSession result, includes user profile & account list
712  * account list includes hcu account identifier
713  * @param type $rdcterms
714  * terms of use i(if any) served up from HomeCU
715  * @return array
716  * ['data']['accounts'] list of valid accounts
717  * each entry looks like this:
718  * ['D|666665|50|0'] => Array
719  (
720  ['suffix'] => 50
721  ['certnumber'] => 0
722  ['acctclass'] => D
723  ['description'] => REGULAR SHARES - 50
724  ['tokn'] => a9a525ac33035b7c3845809443c5eed626297e0f
725  ['member'] => 666665
726  ['tomember'] => 666665
727  ['trust'] => primary
728  ['displaydesc'] => REGULAR SHARES - 50
729  ['rdctype'] => 0
730  ['rdcdesc'] =>
731  * RDCAcctId is identifier returned from Digiliti
732  ['RDCAcctId'] => 1
733  )
734  * Note that for Digiliti we get a list of accounts from HomeCU and a list from
735  * Digiliti, then syncronize (digiSyncAcctList) to get a current list
736  *
737  * ['data']['terms'] terms of use (if any). HomeCU serves terms for Digiliti
738  * ['data'] array also contains any values returned from rdc vendor on
739  * start session call. For Digiliti, this is the dgUserId
740  * and the deposit limits from digiGetUserProfile
741  *
742  */
743 function RDCPresentAccounts($parms, $dglist, $rdcterms) {
744  # build array list to send to app
745  # include depositid
746  # include terms to be accepted if they are provided
747  # include labels acctttl, descttl
748  # $dglist['data']['Accounts'] is Digiliti list
749  # $parms['HCUAccounts'] is RDCGetAccts list
750 
751  $hc_keys = array();
752  foreach ($parms['HCUAccounts'] as $hcaKey => $hcaAccount) {
753  $key = $hcaAccount['suffix'];
754  $hc_keys[$key] = $hcaKey;
755  }
756 
757 
758  $pass_along['data']['dgUserId'] = $dglist['data']['dgUserId'];
759  $pass_along['data']['dgUserName'] = $dglist['data']['dgUserName'];
760  $pass_along['data']['accounts'] = array();
761  foreach($dglist['data']['Accounts'] as $key => $dgacct) {
762  $hcuTag = HCU_array_key_value($dgacct['AccountNumber'],$hc_keys);
763  # check for not empty($hcuTag) before using it in HCU_array_key_exists below
764  if (!empty($hcuTag) && $dgacct['Status'] == 'Active' &&
765  HCU_array_key_exists($hcuTag, $parms['HCUAccounts'])) {
766 // $parms['HCUAccounts'][$hcuTag]['RDCAcctId'] = $dgacct['Id'];
767 // $parms['HCUAccounts'][$hcuTag]['RDCName'] = $dgacct['AccountName'];
768  # plop these right into the pass_along, so only include active digi accounts
769  # that have a corresponding HCU account
770  $pass_along['data']['accounts'][$hcuTag] = $parms['HCUAccounts'][$hcuTag];
771  $pass_along['data']['accounts'][$hcuTag]['RDCAcctId'] = $dgacct['Id'];
772  $pass_along['data']['accounts'][$hcuTag]['RDCName'] = $dgacct['AccountName'];
773  }
774  }
775 // $pass_along['data']['accounts'] = $parms['HCUAccounts'];
776 
777  if (sizeof($rdcterms) > 0) {
778  $pass_along['data']['terms'] = $rdcterms['data']['terms'];
779  }
780  $pass_along['status']['response'] = 'true';
781  $pass_along['status']['code'] = '000';
782  $pass_along['status']['message'] = 'Success';
783  return $pass_along;
784 }
785 
786 function digiGetUserDetail($parms, $dgUserId) {
787 
788  try {
789  if (!isset($parms['dgMgmtURL']) ||
790  !isset($parms['dgUser']) ||
791  !isset($parms['dgPass']) ||
792  !isset($dgUserId)) {
793  throw new Exception("Missing Parameters", 100);
794  }
795 
796  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
797  $reqURL = "{$parms['dgMgmtURL']}/users/$dgUserId";
798  $parms["environment"]["logPoint"] = "dgGetUserDetail"; // this action in a readable form
799  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
800 
801  # look for errors, otherwise decode and save the token
802  if ($dgSaid['error'] != 0) {
803  # look for errors, otherwise decode and save the token
804  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
805  }
806  $return['status']['response'] = 'true';
807  $return['status']['code'] = '000';
808  $return['status']['message'] = 'Success';
809  $return['data'] = $dgSaid['data']['User'];
810  } catch (Exception $e) {
811  $return['status']['response'] = 'false';
812  $return['status']['message'] = $e->getMessage();
813  $return['status']['code'] = $e->getCode();
814  $return['data'] = array();
815  }
816 
817  return $return;
818 }
819 
820 function digiSearchUser($parms) {
821 // Search Users
822 //GET /users?UserName={Cn, min len 4}
823 //Gets member information about the user. Use UserId returned to read full member info
824 //but the UserName is always searched as 'starts with', so might be multiples
825 //loop through the list and find an exact match on Cn
826 //
827 # uses: $parms['dgUser'] digiliti UserID
828 # $parms['dgPass'] digiliti password
829 # $parms['MBRACCT'] selected homebanking user account number
830 # $parms['dgMgmtURL'] external services user mgmt URL
831 #
832  try {
833  if (!isset($parms['dgMgmtURL']) ||
834  !isset($parms['dgUser']) ||
835  !isset($parms['dgPass']) ||
836  !isset($parms['searchuser'])) {
837  throw new Exception("Missing Parameters", 100);
838  }
839  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
840  $reqURL = "{$parms['dgMgmtURL']}/users?UserName={$parms['searchuser']}";
841  $parms["environment"]["logPoint"] = "dgSearchUser"; // this action in a readable form
842  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
843 //{"Users":[{"UserId":9,"IsActiveUser":false,"FirstName":"Test","LastName":"User","PhoneNumber":"2085551212","PhoneIdentifier":null,"PhoneType":null,"AddressLine1":null,"AddressLine2":null,"City":null,"State":null,"Zip":null,"UserName":"666665","Email":"miki@homecu.com","MobileDataAutoremoveTime":30,"Password":null,"DateofBirth":null,"TaxIdentifier":null,"KnownCustomerScore":null,"OrgName":null,"HomePhoneNumber":null,"Accounts":[{"Id":0,"IsDefault":false,"AccountName":null,"AccountNumber":"T123","RoutingNumber":null,"BankName":null,"IsActive":null,"Status":null,"AccountTypeId":0,"AccountTypeName":null}]}],"StatusCode":0,"Message":"Success"}
844 # NOTE digiEmbcurl does a json_decode on the returned data - by the time we get here it is an array
845  if ($dgSaid['error'] != 0) {
846  # look for errors, otherwise decode and save the token
847  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
848  }
849  $found = 0;
850  if (!is_array($dgSaid['data']['Users'])) {
851  throw new Exception("Invalid Search User Response", 999);
852  } else {
853  foreach ($dgSaid['data']['Users'] as $ukey => $uarray) {
854  if ($uarray['UserName'] === $parms['searchuser']) {
855  $return['data'] = $uarray;
856  $found = 1;
857  break;
858  }
859  }
860  }
861  if ($found == 0) {
862  throw new Exception("Member not found", 404);
863  }
864 
865  $return['status']['response'] = 'true';
866  $return['status']['message'] = 'Success';
867  $return['status']['code'] = '000';
868  } catch (Exception $e) {
869  $return['status']['response'] = 'false';
870  $return['status']['message'] = $e->getMessage();
871  $return['status']['code'] = $e->getCode();
872  $return['data'] = array();
873  }
874  return $return;
875 }
876 
877 function digiAddNewUser($parms, $dgAccounts) {
878  # Add a user and account to dg system, or associates an additional account to an existing user
879  try {
880  if (!isset($parms['dgMgmtURL']) ||
881  !isset($parms['dgUser']) ||
882  !isset($parms['dgPass']) ||
883  !isset($parms['MIR']) ||
884  !is_array($dgAccounts) ||
885  !isset($parms['searchuser'])) {
886  throw new Exception("Missing Parameters", 100);
887  }
888  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"), "Content-Type: application/json");
889  $reqURL = "{$parms['dgMgmtURL']}/users";
890  # boolval($parms['defaultDGUserStat']) not available prior to php 5.5
891  # so have to fake it out
892  $setStat = (HCU_array_key_value('defaultDGUserStat',$parms) ? TRUE : FALSE );
893  $reqData = array(
894  "IsActiveUser" => $setStat,
895  "FirstName" => $parms['MIR']['firstname'],
896  "LastName" => $parms['MIR']['lastname'],
897  "PhoneNumber" => $parms['MIR']['phone'],
898  "UserName" => $parms['searchuser'],
899  "Email" => urldecode($parms['MIR']['email']),
900  "Password" => $parms['PhonePass']);
901  $reqData['Accounts'] = $dgAccounts;
902 
903  $reqData = json_encode($reqData);
904 
905  $parms["environment"]["logPoint"] = "dgAddNewUser"; // this action in a readable form
906  $dgSaid = digiEmbcurl($parms, $reqURL, 'POST', $reqHeaders, $reqData);
907  if ($dgSaid['error'] != 0) {
908  # look for errors, otherwise decode and save the token
909  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
910  }
911  $found = 0;
912  if (!is_array($dgSaid['data']['User'])) {
913  throw new Exception("Invalid Add User Response", 999);
914  } else {
915  $return['data'] = $dgSaid['data']['User'];
916  $found = 1;
917  }
918  if ($found == 0) {
919  throw new Exception("Member not added", 404);
920  }
921 
922  $return['status']['code'] = '000';
923  $return['status']['response'] = 'true';
924  $return['status']['message'] = 'Success';
925  } catch (Exception $e) {
926  $return['status']['response'] = 'false';
927  $return['status']['message'] = $e->getMessage();
928  $return['status']['code'] = $e->getCode();
929  $return['data'] = array();
930  }
931  return $return;
932 }
933 
934 /*
935  * $parms is from trusted detail rec and other
936  * settings collected from HomeCU
937  * $dgData is returned from previous call to
938  * Digiliti GetUserDetail method
939  *
940  */
941 
942 function digiUpdateUser($parms, $dgData) {
943 
944  # Updates user information in the dg system
945  try {
946  if (!isset($parms['dgMgmtURL']) ||
947  !isset($parms['dgUser']) ||
948  !isset($parms['dgPass']) ||
949  !isset($parms['MIR']) ||
950  !is_array($dgData['data']) || !isset($dgData['data']['UserId'])) {
951  throw new Exception("Missing Parameters", 100);
952  }
953  $needUpd = 0; # start out thinking we are current with Digiliti
954 
955  if ($dgData['data']['Email'] != urldecode($parms['MIR']['email'])) {
956  $needUpd = 1;
957  $dgData['data']['Email'] = urldecode($parms['MIR']['email']);
958  }
959  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"), "Content-Type: application/json");
960  $reqURL = "{$parms['dgMgmtURL']}/users";
961 # can't ignore the IsActiveUser - leaving it out sets inactive. Try to maintain current status?
962 
963  # this is updating user info based on MIR packet -- which for BATCH is dummy data
964  # this is update - not add - so use the values in dgData (from digiGetUserDetail) instead
965  $reqData = array(
966  "UserId" => $dgData['data']['UserId'],
967  "IsActiveUser" => TRUE,
968  "FirstName" => $dgData['data']['FirstName'],
969  "LastName" => $dgData['data']['LastName'],
970  "PhoneNumber" => $dgData['data']['PhoneNumber'],
971  "UserName" => $parms['searchuser'],
972  "Email" => $dgData['data']['Email'],
973  "Password" => $parms['PhonePass']);
974  $reqData['Accounts'] = $dgData['data']['Accounts'];
975  $reqData = json_encode($reqData);
976 
977  $parms["environment"]["logPoint"] = "dgUpdMobileUser"; // this action in a readable form
978  $dgSaid = digiEmbcurl($parms, $reqURL, 'PUT', $reqHeaders, $reqData);
979  if ($dgSaid['error'] != 0) {
980  # look for errors, otherwise decode and save the token
981  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
982  }
983  $return['status']['response'] = 'true';
984  $return['status']['message'] = 'Success';
985  $return['status']['code'] = '000';
986 // $GLOBALS['HB_ENV']["SYSENV"]["logger"]->info( "dgResponse " . print_r($dgSaid,true));
987  $return['data'] = $dgSaid['data']['User'];
988  } catch (Exception $e) {
989  $return['status']['response'] = 'false';
990  $return['status']['message'] = $e->getMessage();
991  $return['status']['code'] = $e->getCode();
992  $return['data'] = array();
993  }
994  return $return;
995 }
996 
997 function digiSearchTransactions($parms) {
998 // Search Transactions
999 //GET /transactions?username={Cn, min len 4}
1000 //Gets transaction history for the user. Use TransactionId returned to read full txn info
1001 //
1002 //but for search user, the UserName is always searched as 'starts with', so might be multiples
1003 // assume this one works the same way, loop through the list and return only those with
1004 // an exact match on Cn
1005 //
1006 # uses: $parms['dgUser'] digiliti UserID
1007 # $parms['dgPass'] digiliti password
1008 # $parms['MBRACCT'] selected homebanking user account number
1009 # $parms['dgMgmtURL'] external services user mgmt URL
1010 #
1011  try {
1012  if (!isset($parms['dgMgmtURL']) ||
1013  !isset($parms['dgUser']) ||
1014  !isset($parms['dgPass']) ||
1015  !isset($parms['searchuser'])) {
1016  throw new Exception("Missing Parameters", 100);
1017  }
1018  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
1019  $reqURL = "{$parms['dgMgmtURL']}/transactions?username={$parms['searchuser']}";
1020  $parms["environment"]["logPoint"] = "dgSearchTxns"; // this action in a readable form
1021  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
1022 # NOTE digiEmbcurl does a json_decode on the returned data - by the time we get here it is an array
1023  if ($dgSaid['error'] != 0) {
1024  # look for errors, otherwise decode and save the token
1025  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1026  }
1027  $found = 0;
1028  if (!is_array($dgSaid['data']['Transactions'])) {
1029  throw new Exception("Invalid Search Transactions Response", 999);
1030  } else {
1031  foreach ($dgSaid['data']['Transactions'] as $ukey => $uarray) {
1032  if ($uarray['UserName'] === $parms['searchuser']) {
1033  $return['data']['Transactions'][] = $uarray;
1034  $found++;
1035  }
1036  }
1037  }
1038  if ($found == 0) {
1039  throw new Exception("No Transactions found", 404);
1040  }
1041 
1042  $return['status']['response'] = 'true';
1043  $return['status']['message'] = 'Success';
1044  $return['status']['code'] = '000';
1045  } catch (Exception $e) {
1046  $return['status']['response'] = 'false';
1047  $return['status']['message'] = $e->getMessage();
1048  $return['status']['code'] = $e->getCode();
1049  $return['data'] = array();
1050  }
1051  return $return;
1052 }
1053 
1054 function digiGetHistoryItem($parms, $dgTxnId) {
1055 //GET /v1/CreditUnions/{creditUnionId}/Licenses/{licenseKey}/MobileUsers/{userId}/Items
1056 //Gets the deposit history for a user in a credit union
1057 
1058  try {
1059  if (!isset($parms['dgMgmtURL']) ||
1060  !isset($parms['dgUser']) ||
1061  !isset($parms['dgPass']) ||
1062  !isset($dgTxnId)) {
1063  throw new Exception("Missing Parameters", 100);
1064  }
1065 
1066  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
1067  $reqURL = "{$parms['dgMgmtURL']}/transactions/{$dgTxnId}";
1068 
1069  # look for errors, otherwise decode and save the token
1070 
1071  $parms["environment"]["logPoint"] = "dgGetHistoryDetail"; // this action in a readable form
1072  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
1073  if ($dgSaid['error'] != 0) {
1074  # look for errors, otherwise decode and save the token
1075  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1076  }
1077  $return['status']['response'] = 'true';
1078  $return['status']['message'] = 'Success';
1079  $return['data'] = $dgSaid['data'];
1080  } catch (Exception $e) {
1081  $return['status']['response'] = 'false';
1082  $return['status']['message'] = $e->getMessage();
1083  $return['status']['code'] = $e->getCode();
1084  $return['data'] = array();
1085  }
1086  return $return;
1087 }
1088 
1089 function digiPostItem($parms) {
1090 # Deposts a mobile item in a new batch and immediately submits that batch.
1091 # If the item was unable to be processed, the item and batch are rejected
1092 #
1093 # $parms['dgMgmtURL']
1094 # $parms['certfile']
1095 # $parms['SessionStateId']
1096 # $parms['amount']
1097  # $parms['RDCName'] is the selected Digiliti account name
1098  # $parms['RDCAcctId'] is the selected Digiliti account id
1099 
1100  try {
1101 /*
1102  * this line logs the parms array minus the check images
1103  * LogToFile(__LINE__, 'PARMS', array_diff_key($parms,array('CheckFront' => 'drop', 'CheckBack' => 'drop')));
1104  */
1105 
1106 // LogToFile(__LINE__, 'PARMS', array_diff_key($parms,array('CheckFront' => 'drop', 'CheckBack' => 'drop')));
1107  if (!isset($parms['dgMgmtURL']) ||
1108  !isset($parms['dgUser']) ||
1109  !isset($parms['dgPass']) ||
1110  !isset($parms['depositid']) ||
1111  !isset($parms['dgUserName']) ||
1112  !isset($parms['RDCName']) ||
1113  !isset($parms['CheckFront']) || !isset($parms['CheckBack']) ||
1114  !isset($parms['amount'])) {
1115  throw new Exception("Missing Parameters", 100);
1116  }
1117 
1118  $deposittime = date('c');
1119 
1120  $reqBound = 'CFSDepositService';
1121  $eol = "\r\n";
1122  $boundaryStringLine = "{$eol}--{$reqBound}{$eol}";
1123  $lastBoundaryStringLine = "{$eol}--{$reqBound}--{$eol}";
1124  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"), "Content-Type: multipart/form-data; boundary={$reqBound}");
1125  $reqURL = "{$parms['dgMgmtURL']}/transactions";
1126  $reqJSON = array("PhoneUserName" => "{$parms['dgUserName']}",
1127  "AccountNickName" => $parms['RDCName'],
1128  "PartnerTransactionId" => $parms['depositid'],
1129  "AmountInCents" => intval($parms['amount'])
1130  );
1131  $reqJSON = json_encode($reqJSON);
1132 
1133  $reqData = "{$boundaryStringLine}Content-Disposition: form-data; name=\"Json\"{$eol}Content type: application/json{$eol}{$eol}";
1134  $reqData .= "{$reqJSON}{$eol}";
1135  $reqData .= "{$boundaryStringLine}Content-Disposition: form-data; name=\"frontImage\"; filename=\"front.jpg\"{$eol}Content type: image/jpeg{$eol}{$eol}";
1136  $reqData .= "{$parms['CheckFront']}{$eol}";
1137  $reqData .= "{$boundaryStringLine}Content-Disposition: form-data; name=\"rearImage\"; filename=\"rear.jpg\"{$eol}Content type: image/jpeg{$eol}{$eol}";
1138  $reqData .= "{$parms['CheckBack']}{$eol}";
1139  $reqData .= "{$lastBoundaryStringLine}";
1140 
1141  $parms["environment"]["logPoint"] = "dgPostItem"; // this action in a readable form
1142 
1143 // LogToFile(__LINE__, 'HDRS', $reqHeaders);
1144 // LogToFile(__LINE__, 'DATA', $reqData);
1145  # call as LogToFile( __LINE__ ,"Title",$array_to_print);
1146 
1147  $dgSaid = digiEmbcurl($parms, $reqURL, 'POST', $reqHeaders, $reqData);
1148  if ($dgSaid['error'] != 0 && $dgSaid['error'] != 400) {
1149  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1150  } else {
1151  $return['status']['response'] = 'true';
1152  $return['status']['message'] = $dgSaid['message'];
1153  $return['data'] = $dgSaid['data'];
1154  }
1155  if ($dgSaid['error'] == 400) {
1156  # data rejected, but return message
1157  $return['status']['code'] = $dgSaid['error'];
1158  } else {
1159  $return['status']['code'] = '000';
1160  }
1161  } catch (Exception $e) {
1162  $return['status']['response'] = 'false';
1163  $return['status']['message'] = $e->getMessage();
1164  $return['status']['code'] = $e->getCode();
1165  $return['data'] = array();
1166  }
1167  return $return;
1168 }
1169 
1170 function digiEmbcurl($parms, $reqURL, $reqMethod, $reqHeaders, $reqData = '') {
1171  # reqURL is the service url, loginUrl for auth
1172  # reqMethod is yeah, the method
1173  # reqHeaders is an array of headers to be sent
1174  # will include Authorization: oauth token for all calls after the get token
1175 
1176  $curlopts = array(
1177  CURLOPT_RETURNTRANSFER => 1,
1178  CURLOPT_SSL_VERIFYPEER => 0,
1179  CURLOPT_SSL_VERIFYHOST => 0,
1180  CURLOPT_HEADER => FALSE,
1181  CURLOPT_URL => "$reqURL");
1182 
1183  $ch = curl_init();
1184 
1185 //curl_setopt($ch, CURLOPT_VERBOSE, true);
1186 //$verbose = fopen('/tmp/dgtrace', 'a+');
1187 //fwrite($verbose,"\n{$reqData}\n");
1188 //curl_setopt($ch, CURLOPT_STDERR, $verbose);
1189 
1190  curl_setopt_array($ch, $curlopts);
1191 // if (count($reqOpts)) {
1192 // curl_setopt_array($ch, $reqOpts);
1193 // }
1194  if ($reqMethod != 'GET') {
1195  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $reqMethod);
1196  }
1197  if (strlen($reqData) > 0) {
1198  curl_setopt($ch, CURLOPT_POSTFIELDS, $reqData);
1199  }
1200  curl_setopt($ch, CURLOPT_HTTPHEADER, $reqHeaders);
1201 
1202  $respERR = '';
1203  $return = '';
1204  $response = curl_exec($ch);
1205  $respHTTP = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1206  $respCURL = curl_errno($ch);
1207 
1208  if ($respCURL) {
1209  # Bad! Don't hide the error, return the curl error if it occurred.
1210  $respERR = "HCUERROR: Connection Failed cURL $respCURL";
1211  $return = array("error" => "hcuC{$respCURL}", "message" => "$respERR");
1212  } elseif ($respHTTP > 400 && $respHTTP < 600) {
1213  # HTTP Response 4xx client error or 5xx server error
1214  $respArr = json_decode($response, true);
1215  $respERR = "HCUERROR: Connection Failed HTTP $respHTTP " . $respArr['Message'];
1216  $return = array("error" => $respHTTP, "message" => "$respERR");
1217  } elseif (!isset($response) || trim($response) == '' ) {
1218  if ($respHTTP == 204 || $respHTTP == 200) {
1219  # HTTP 204 No Content w/o response = 'Everything OK but no data'
1220  # HTTP 200 OK w/o response = 'Everything OK but no data'
1221  $return = array("error" => 0, "message" => "No Data");
1222  } else {
1223  $return = array("error" => $respHTTP, "message" => "Empty Response");
1224  }
1225  } else {
1226  # response is sometimes JSON array w/Message & StatusCode,
1227  # sometimes simple list, which might be empty list.
1228  # For simple list, add success codes instead of throwing error
1229  $respArr = json_decode($response, TRUE);
1230  if (is_null($respArr)) {
1231  $return = array("error" => 990, "message" => "Invalid jSon Response (dgE)");
1232  } elseif (HCU_array_key_exists('Message', $respArr) &&
1233  HCU_array_key_value('Message', $respArr) !== 'Success') {
1234  if ($respHTTP == 400) {
1235  # HTTP 400 on post requests means data rejected
1236  # but don't throw error, need the message to bubble up
1237  # need to set non-zero error code, though, so next level up knows we had a problem
1238  $return = array("error" => 400, "message" => trim(HCU_array_key_value('StatusCode', $respArr)) . " " . trim(HCU_array_key_value('Message', $respArr)));
1239  } else {
1240  $return = array("error" => trim(HCU_array_key_value('StatusCode', $respArr))
1241  , "message" => HCU_array_key_value('Message', $respArr) . " (dgE)");
1242  }
1243  } else {
1244  $return = array();
1245  if (HCU_array_key_exists('StatusCode', $respArr)) {
1246  $return['error'] = trim($respArr['StatusCode']);
1247  } else {
1248  $return['error'] = 0;
1249  }
1250  if (HCU_array_key_exists('Message', $respArr)) {
1251  $return['message'] = trim($respArr['Message']);
1252  } else {
1253  $return['message'] = 'Success';
1254  }
1255  $return['data'] = $respArr;
1256  }
1257 
1258 //############
1259 // if (is_null($respArr)) {
1260 // $return = array("error" => 990, "message" => "Invalid jSon Response (dgE)");
1261 // } elseif (HCU_array_key_value('Message', $respArr) !== 'Success') {
1262 // $return = array("error" => trim(HCU_array_key_value('StatusCode', $respArr)), "message" => HCU_array_key_value('Message', $respArr) . " (dgE)");
1263 // } else {
1264 // $return = array("error" => trim(HCU_array_key_value('StatusCode', $respArr)), "message" => HCU_array_key_value('Message', $respArr) );
1265 // $return['data'] = $respArr;
1266 // }
1267 //################
1268  }
1269 
1270  if ($parms["logging"] == "enabled") {
1271  $logParms = $parms["environment"]; // get the environment info passed in
1272  $logParms["token"] = ''; // the id used across all communications in session
1273  $logParms["txnId"] = time(); // the id for this transaction
1274  $logParms["request"] = "curl "; // the request
1275  if ($reqMethod != 'GET') {
1276  $logParms["request"] .= "-X $reqMethod ";
1277  }
1278  if (is_array($reqHeaders)) {
1279  foreach ($reqHeaders as $hdr) {
1280  $logParms["request"] .= "-H '$hdr' ";
1281  }
1282  }
1283  if (strlen($reqData) > 0) {
1284  # no need to log the ginormous image data - weed it out
1285  $logData = $reqData;
1286  $marker = "Content type: image/jpeg";
1287  $fAnchor = strpos($logData, $marker);
1288  if ($fAnchor !== false) {
1289  $fAnchor += strlen($marker) + 2;
1290  $endfA = strpos($logData, '--CFSDepositService',$fAnchor) -1;
1291  $logData = substr_replace($logData, " Image Data ", $fAnchor, $endfA - $fAnchor);
1292  $rAnchor = strrpos($logData, $marker);
1293  if ($rAnchor !== false) {
1294  $rAnchor += strlen($marker) + 2;
1295  $endrA = strpos($logData, '--CFSDepositService',$rAnchor) -1;
1296  $logData = substr_replace($logData, " Image Data ", $rAnchor, $endrA - $rAnchor);
1297  }
1298  }
1299 
1300 // LogToFile(__LINE__, 'LOGDATA', " fAnchor $fAnchor end $endfA rAnchor $rAnchor end $endrA \n" . $logData );
1301 
1302  $logParms["request"] .= "-d '$logData' "; // the request
1303  }
1304  $logParms["request"] .= "'$reqURL' "; // the request
1305  $logParms["reply"] = $response; // the response
1306  if ($respERR > '') {
1307  $logParms["reply"] .= "\n$respERR";
1308  }
1309  $logParms["reply"] .= "\nrespHTTP: $respHTTP \nrespCURL: $respCURL";
1310  $logParms["reply"] .= "\nrespArr " . print_r($return, true);
1311 
1312 
1313  LogSSOActivity($logParms);
1314  }
1315 
1316  @curl_close($ch);
1317  return $return;
1318 }
1319 
1320 function LogToFile($line, $title, $show) {
1321  # call as LogToFile( __LINE__ ,"Title",$array_to_print);
1322  $log = date('Y-m-d H:i:s');
1323  $tfile = fopen("/tmp/dgLog", "a");
1324  fwrite($tfile, "+++ $log $line +++++++++++++++\n");
1325  fwrite($tfile, " $title " . print_r($show, true));
1326  fwrite($tfile, "\n++++++++++++++++++\n");
1327  fclose($tfile);
1328 }
1329 
1330 function digiGetMir($parms, $HB_ENV) {
1331  try {
1332  if (!HCU_array_key_value('MBRACCT', $parms)) {
1333  throw new Exception("Member Account not specified");
1334  }
1335  if (HCU_array_key_value('live', $parms)) {
1336  $MIR = GetMemberInfo($HB_ENV, array("member" => $parms['MBRACCT']));
1337  } else {
1338  # batch interface needs to fake MIR info */
1339  $MIR["data"] = array(
1340  'accountnumber' => $parms['MBRACCT'],
1341  'lastname' => (HCU_array_key_value('defLastName',$parms) ? $parms['defLastName'] : 'Member'),
1342  'firstname' => (HCU_array_key_value('defFirstName',$parms) ? $parms['defFirstName'] : 'Valued'),
1343  'email' => urldecode($parms['Ml']),
1344  'homephone' => '',
1345  'workphone' => (HCU_array_key_value('defWorkPhone',$parms) ? $parms['defWorkPhone'] : '2085551212'), # pick a better dummy number?
1346  'cellphone' => '',
1347  'fax' => '',
1348  'ssn' => '',
1349  'address1' => '',
1350  'address2' => '',
1351  'city' => '',
1352  'state' => '',
1353  'zip' => '',
1354  'cc' => '',
1355  'dob' => ''
1356  );
1357  }
1358 
1359  /* strip slashes and dashes and non-digits from phone numbers
1360  * and zip code and tax id; rearrange DOB into mmddyyyy
1361  */
1362 
1363  $MIR["data"]['phone'] = preg_replace('/\D/', '', HCU_array_key_value('homephone', $MIR["data"]));
1364  if (trim($MIR["data"]['phone']) == '' || strlen(trim($MIR["data"]['phone'])) !== 10 ) {
1365  $MIR["data"]['phone'] = preg_replace('/\D/', '', HCU_array_key_value('cellphone', $MIR["data"]));
1366  }
1367  if (trim($MIR["data"]['phone']) == '' || strlen(trim($MIR["data"]['phone'])) !== 10 ) {
1368  $MIR["data"]['phone'] = preg_replace('/\D/', '', HCU_array_key_value('workphone', $MIR["data"]));
1369  }
1370  if (trim($MIR["data"]['phone']) == '' || strlen(trim($MIR["data"]['phone'])) !== 10 ) {
1371  unset($MIR["data"]['phone']);
1372  }
1373  date_default_timezone_set('America/Denver');
1374  if ( HCU_array_key_value('dob', $MIR['data']) && ($st=strtotime($MIR['data']['dob'])) && $st > strtotime('-100 year') && $st < time()) {
1375  $MIR['data']['dob'] = date($datefmt, $st);
1376  } else {
1377  unset($MIR['data']['dob']);
1378  }
1379 
1380  $rmlist = array(' ', '-');
1381  $MIR['data']['ssn'] = str_replace($rmlist, '', HCU_array_key_value('ssn', $MIR['data']));
1382  if (trim($MIR['data']['ssn']) == '') {
1383  unset($MIR['data']['ssn']);
1384  }
1385 
1386  $MIR['data']['zip'] = str_replace($rmlist, '', HCU_array_key_value('zip', $MIR['data']));
1387  if (strlen($MIR['data']['zip']) < 5) {
1388  unset($MIR['data']['zip']);
1389  }
1390 
1391  $rmlist = array("#", "&", "/", "%", ",", ":", "=", "?", "'", ";");
1392 
1393  # override MIR email with HCU hb email if it is set, then make sure we have a valid value
1394  $EMAIL = (HCU_array_key_value('Ml', $parms) ? urldecode(HCU_array_key_value('Ml', $parms)) : HCU_array_key_value('email', $MIR["data"]));
1395  $EMAIL = str_replace($rmlist, "", $EMAIL);
1396  if (trim($EMAIL) != '' && validateEmail($EMAIL) ) {
1397  $MIR["data"]["email"] = $EMAIL;
1398  } else {
1399  unset($MIR["data"]["email"]);
1400  }
1401  $MIR["data"]["firstname"] = str_replace($rmlist, "", HCU_array_key_value('firstname', $MIR["data"]));
1402  $MIR["data"]["middlename"] = str_replace($rmlist, "", HCU_array_key_value('middlename', $MIR["data"]));
1403  if (trim($MIR["data"]["firstname"]) == '') {
1404  // allow empty FirstName (replace with a dot) in case it is a business
1405  $MIR['data']['firstname'] = '.';
1406  }
1407  $MIR["data"]["lastname"] = str_replace($rmlist, "", HCU_array_key_value('lastname', $MIR["data"]));
1408  if (trim($MIR["data"]["lastname"]) == '') {
1409  unset($MIR["data"]["lastname"]);
1410  }
1411  $MIR["data"]["address1"] = str_replace($rmlist, "", HCU_array_key_value('address1', $MIR["data"]));
1412  if (trim($MIR["data"]["address1"]) == '') {
1413  unset($MIR["data"]["address1"]);
1414  }
1415  $MIR["data"]["address2"] = str_replace($rmlist, "", HCU_array_key_value('address2', $MIR["data"]));
1416  $MIR["data"]["city"] = str_replace($rmlist, "", HCU_array_key_value('city', $MIR["data"]));
1417  if (trim($MIR["data"]["city"]) == '') {
1418  unset($MIR["data"]["city"]);
1419  }
1420  $MIR["data"]["state"] = str_replace($rmlist, "", HCU_array_key_value('state', $MIR["data"]));
1421  if (trim($MIR["data"]["state"]) == '') {
1422  unset($MIR["data"]["state"]);
1423  }
1424  $MIR["data"]["accountnumber"] = str_replace($rmlist, "", HCU_array_key_value('accountnumber', $MIR["data"]));
1425  if (trim($MIR["data"]["accountnumber"]) == '') {
1426  unset($MIR["data"]["accountnumber"]);
1427  }
1428 
1429  $reqMIR = array(
1430  'accountnumber' => 1,
1431  'firstname' => 1,
1432  'lastname' => 1,
1433  'email' => 1,
1434  'phone' => 1
1435  );
1436  $missing = array_diff_key($reqMIR, $MIR['data']);
1437  if (sizeof($missing)) {
1438  throw new Exception("Incomplete Member Info (" . join(", ", array_keys($missing)) . ")", 999);
1439  }
1440  $MIR['status']['response'] = 'true';
1441  $MIR['status']['message'] = 'Success';
1442  $MIR['status']['code'] = '000';
1443  } catch (Exception $e) {
1444  $MIR['status']['response'] = 'false';
1445  $MIR['status']['message'] = $e->getMessage();
1446  $MIR['status']['code'] = $e->getCode();
1447 // $MIR['data'] = array(); # pass back what we got for debugging
1448  }
1449  return $MIR;
1450 }
1451 
1452 function digiSyncAcctList($parms, $dgData) {
1453  # Syncronize the list of accounts from homecu ($parms['HCUAccounts'])
1454  # with the list returned from Digiliti ($dgData['data']['Accounts'])
1455  #
1456  # List of accounts presented to member is intersect of
1457  # parms['HCUAccounts'] and dgData['data']['Accounts'].
1458  #
1459  try {
1460  if (!is_array($dgData['data']) ||
1461  !isset($parms['HCUAccounts']) || !is_array($parms['HCUAccounts'])) {
1462  throw new Exception("Missing Parameters", 100);
1463  }
1464  $needUpd = 0; # start out thinking we are current with Digiliti
1465  $return['status']['response'] = 'true';
1466  $return['status']['message'] = 'Success';
1467  $return['status']['code'] = '000';
1468 
1469  # dg_keys is list of AccountNumber values from DIGI list
1470  # hc_keys is list of calculated suffix values from HCU list
1471  # (suffix is calculated unique key based on HCU trusted detail config,
1472  # and is used to populate AccountNumber on insert)
1473  $dg_keys = array();
1474  foreach ($dgData['data']['Accounts'] as $dgaKey => $dgaAccount) {
1475  $key = $dgaAccount['AccountNumber'];
1476 // $id = $dgaAccount['Id'];
1477  $dg_keys[$key] = $dgaKey;
1478  }
1479  $hc_keys = array();
1480  # ignore any rows with empty suffix.
1481  # If that results in empty list, throw error
1482  foreach ($parms['HCUAccounts'] as $hcaKey => $hcaAccount) {
1483  if (!empty(HCU_array_key_value('suffix', $hcaAccount))) {
1484  $key = $hcaAccount['suffix'];
1485  $hc_keys[$key] = $hcaKey;
1486  }
1487  }
1488  if (!count($hc_keys) ) {
1489  throw new Exception("No Valid HCU accounts", 100);
1490  }
1491 
1492  # inserts gets HCU items with key not in DIGI
1493  # deletes gets DIGI itmes with key not at HCU
1494  # updates gets intersect of items with key in both list
1495  $inserts = array_diff(array_keys($hc_keys), array_keys($dg_keys));
1496  $deletes = array_diff(array_keys($dg_keys), array_keys($hc_keys));
1497  $updates = array_intersect(array_keys($hc_keys), array_keys($dg_keys));
1498 
1499  # echo in the return array for logging,
1500  # turn this off before production
1501  $return['hc_keys'] = $hc_keys;
1502  $return['dg_keys'] = $dg_keys;
1503  $return['inserts'] = $inserts;
1504  $return['deletes'] = $deletes;
1505  $return['updates'] = $updates;
1506 
1507  foreach ($inserts as $key => $sfx) {
1508  $account = $parms['HCUAccounts']["{$hc_keys[$sfx]}"];
1509  # add new item to $dgData['data']['Accounts']
1510  $item = array(
1511  "Status" => $parms['defaultDGAcctStat'],
1512  "AccountName" => $account['description'],
1513  "AccountNumber" => $account['suffix']
1514  );
1515  # AccountNumber s/b HCU suffix as calculated based on trusted detail config
1516  # AccountTypeName / AccountTypeId s/b rdcdesc / Ck_rdctype - Sv_rdctype per HCU config
1517  # AccountName s/b Home Banking shortdesc
1518  # configure rdctype as 0 to pass as AccountTypeId, do not pass AccountTypeName
1519  # for some reason, can't add with AccountTypeName so use AccountTypeId instead
1520  $item["AccountTypeId"] = $account['rdctype']; # only include TypeName if TypeId <> 0
1521  $dgData['data']['Accounts'][] = $item;
1522  $needUpd++;
1523  }
1524  foreach ($deletes as $key => $sfx) {
1525  # do we care about the deletes? We are only going to offer the
1526  # member the accounts that are allowed, maybe we can ignore these?
1527  if (HCU_array_key_value($sfx, $dg_keys)) {
1528  $dgaKey = HCU_array_key_value($sfx, $dg_keys);
1529  # Digiliti does not allow delete, just deactivate it
1530  if ($dgData['data']['Accounts'][$dgaKey]['Status'] != 'Inactive') {
1531  $dgData['data']['Accounts'][$dgaKey]['Status'] = 'Inactive';
1532  # check if I should mess with these -
1533  # setting typeid to 0 generated error 'User check account type is not on the known types list'
1534 # $dgData['data']['Accounts'][$dgaKey]['AccountTypeId'] = 0;
1535 # unset($dgData['data']['Accounts'][$dgaKey]['AccountTypeName']);
1536  $needUpd++;
1537  } else {
1538  unset($dgData['data']['Accounts'][$dgaKey]);
1539  }
1540  }
1541  }
1542 
1543 
1544  # allow for default status and default profile
1545  foreach ($updates as $key => $sfx) {
1546  $dgaKey = $dg_keys[$sfx];
1547  $account = $parms['HCUAccounts']["{$hc_keys[$sfx]}"];
1548  # don't mess with the status - if we set it initially 'NeedsReview',
1549  # will have to use CheckReview portal to activate
1550  #$dgData['data']['Accounts'][$dgaKey]['Status'] = 'Active';
1551  # AccountName is the required unique value. Need something that won't change
1552  # not an active account? Skip over it
1553  if ($dgData['data']['Accounts'][$dgaKey]['Status'] != 'Active') {
1554  continue;
1555  }
1556 
1557  if ($dgData['data']['Accounts'][$dgaKey]['AccountName'] != $account['description'] ||
1558  $dgData['data']['Accounts'][$dgaKey]['AccountTypeId'] != $account['rdctype'] ) {
1559 
1560  $dgData['data']['Accounts'][$dgaKey]['AccountName'] = $account['description'];
1561  $dgData['data']['Accounts'][$dgaKey]['AccountTypeId'] = $account['rdctype'];
1562  # unset($dgData['data']['Accounts'][$dgaKey]['AccountTypeId']; # unset so not using zero with accounttypename?
1563  $needUpd++;
1564  }
1565  }
1566  $return['dgUpdated'] = $dgData['data']['Accounts'];
1567  $return['needUpdate'] = $needUpd;
1568  } catch (Exception $e) {
1569  $return['status']['response'] = 'false';
1570  $return['status']['message'] = $e->getMessage();
1571  $return['status']['code'] = $e->getCode();
1572  }
1573 
1574  if ($parms["logging"] == "enabled") {
1575  $logParms = $parms["environment"]; // get the environment info passed in
1576  $logParms["logPoint"] = "digiSyncAccounts";
1577  $logParms["token"] = ''; // the id used across all communications in session
1578  $logParms["txnId"] = time(); // the id for this transaction
1579  $logParms["request"] = "hcuAccounts "; // the request
1580  $logParms["request"] .= print_r($parms['HCUAccounts'], true); // the request
1581  $logParms["reply"] = "return " . print_r($return, true);
1582 
1583 
1584  LogSSOActivity($logParms);
1585  }
1586 
1587  return $return;
1588 }
1589 
1590 function digiGetAccountTypeNames($parms) {
1591 
1592  try {
1593  if (!isset($parms['dgMgmtURL']) ||
1594  !isset($parms['dgUser']) ||
1595  !isset($parms['dgPass'])) {
1596  throw new Exception("Missing Parameters", 100);
1597  }
1598 
1599  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
1600  $reqURL = "{$parms['dgMgmtURL']}/accountTypes/";
1601  $parms["environment"]["logPoint"] = "dgGetAccountTypes"; // this action in a readable form
1602  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
1603 
1604  # look for errors, otherwise decode and save the token
1605  if ($dgSaid['error'] != 0) {
1606  # look for errors, otherwise decode and save the token
1607  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1608  }
1609  $return['status']['response'] = 'true';
1610  $return['status']['code'] = '000';
1611  if ($dgSaid['message'] == 'No Data' ) {
1612  $return['status']['message'] = $dgSaid['message'];
1613  $return['data'] = array();
1614  } else {
1615  $return['status']['message'] = 'Success';
1616  $return['data'] = $dgSaid;
1617  }
1618  } catch (Exception $e) {
1619  $return['status']['response'] = 'false';
1620  $return['status']['message'] = $e->getMessage();
1621  $return['status']['code'] = $e->getCode();
1622  $return['data'] = array();
1623  }
1624 
1625  return $return;
1626 }
1627 
1628 function digiGetABANumbers($parms) {
1629 
1630  try {
1631  if (!isset($parms['dgMgmtURL']) ||
1632  !isset($parms['dgUser']) ||
1633  !isset($parms['dgPass'])) {
1634  throw new Exception("Missing Parameters", 100);
1635  }
1636 
1637  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
1638  $reqURL = "{$parms['dgMgmtURL']}/abas/";
1639  $parms["environment"]["logPoint"] = "dgGetABANumbers"; // this action in a readable form
1640  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
1641 
1642  # look for errors, otherwise decode and save the token
1643  if ($dgSaid['error'] != 0) {
1644  # look for errors, otherwise decode and save the token
1645  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1646  }
1647  $return['status']['response'] = 'true';
1648  $return['status']['code'] = '000';
1649  if ($dgSaid['message'] == 'No Data' ) {
1650  $return['status']['message'] = $dgSaid['message'];
1651  $return['data'] = array();
1652  } else {
1653  $return['status']['message'] = 'Success';
1654  $return['data'] = $dgSaid;
1655  }
1656  } catch (Exception $e) {
1657  $return['status']['response'] = 'false';
1658  $return['status']['message'] = $e->getMessage();
1659  $return['status']['code'] = $e->getCode();
1660  $return['data'] = array();
1661  }
1662 
1663  return $return;
1664 }
1665 
1666 function digiGetUserProfile($parms, $dgUserId) {
1667 
1668  try {
1669  if (!isset($parms['dgMgmtURL']) ||
1670  !isset($parms['dgUser']) ||
1671  !isset($parms['dgPass']) ||
1672  !isset($dgUserId)) {
1673  throw new Exception("Missing Parameters", 100);
1674  }
1675 
1676  $reqHeaders = array("Authorization: Basic " . base64_encode("{$parms['dgUser']}:{$parms['dgPass']}"));
1677  $reqURL = "{$parms['dgMgmtURL']}/users/{$dgUserId}/profile";
1678  $parms["environment"]["logPoint"] = "dgGetUserProfile"; // this action in a readable form
1679  $dgSaid = digiEmbcurl($parms, $reqURL, 'GET', $reqHeaders, '');
1680 
1681  # look for errors, otherwise decode and save the token
1682  if ($dgSaid['error'] != 0) {
1683  # look for errors, otherwise decode and save the token
1684  throw new Exception("{$dgSaid['message']}", $dgSaid['error']);
1685  }
1686 
1687  if ((HCU_array_key_exists('AvailableItemsPerDay', $dgSaid['data']['UserProfileInfo']['UserRunningTotals']) &&
1688  intval(HCU_array_key_value('AvailableItemsPerDay', $dgSaid['data']['UserProfileInfo']['UserRunningTotals'])) <= 0 ) ||
1689  (HCU_array_key_exists('AvailableDepositPerDay', $dgSaid['data']['UserProfileInfo']['UserRunningTotals']) &&
1690  intval(HCU_array_key_value('AvailableDepositPerDay', $dgSaid['data']['UserProfileInfo']['UserRunningTotals'])) <= 0 ) ||
1691  (HCU_array_key_exists('AvailableRolling30DayLimit', $dgSaid['data']['UserProfileInfo']['UserRunningTotals']) &&
1692  intval(HCU_array_key_value('AvailableRolling30DayLimit', $dgSaid['data']['UserProfileInfo']['UserRunningTotals'])) <= 0 )
1693  ) {
1694  throw new Exception('Digiliti Profile Limits Exceeded', 999);
1695  }
1696  /*
1697  * this is returning a single scanlimit amount, similar to what Bluepoint passes.
1698  * Consider allowing all the limits to flow through instead?
1699  * $dgSaid['data']['UserProfileInfo']['UserRunningTotals']['AvailableItemsPerDay']
1700  * $dgSaid['data']['UserProfileInfo']['UserRunningTotals']['AvailableDepositPerDay']
1701  * $dgSaid['data']['UserProfileInfo']['UserRunningTotals']['AvailableRolling30DayLimit']
1702  */
1703  $scanlimit = min(
1704  intval(HCU_array_key_value('MaxAmountPerDeposit', $dgSaid['data']['UserProfileInfo']['UserProfile'])), intval(HCU_array_key_value('AvailableDepositPerDay', $dgSaid['data']['UserProfileInfo']['UserRunningTotals'])), intval(HCU_array_key_value('AvailableRolling30DayLimit', $dgSaid['data']['UserProfileInfo']['UserRunningTotals']))
1705  );
1706 
1707  $return['status']['response'] = 'true';
1708  $return['status']['code'] = '000';
1709  $return['status']['message'] = 'Success';
1710  $return['data'] = $dgSaid['data']['UserProfileInfo'];
1711  $return['data']['scanlimit'] = $scanlimit;
1712  } catch (Exception $e) {
1713  $return['status']['response'] = 'false';
1714  $return['status']['message'] = $e->getMessage();
1715  $return['status']['code'] = $e->getCode();
1716  $return['data'] = array();
1717  }
1718 
1719  return $return;
1720 }
1721 /**
1722  * Given the configured trusted detail settings and the list of hcuAccounts
1723  * Get a mir packet
1724  * query for the member at Digiliti
1725  * add user and initial account list if needed
1726  * else query for user details and sync the account list with digiliti
1727  * query to get user details - add / update don't always return full acct list
1728  * parse the account list to collect active eligible accounts
1729  *
1730  * return the list of active, eligible accounts
1731  *
1732  * @param array $parms trusted detail settings, hcuAccount list
1733  * @return array
1734  * @throws Exception
1735  */
1736 function digiStartSession(&$parms, $HB_ENV) {
1737  try {
1738  # get the list of pre-defined Digiliti accounttypenames
1739  # don't need to do this - just use trusted detail definitions
1740  # for Sv_rdcname and Ck_rdcname
1741 // $dgAcctNames = digiGetAccountTypeNames($parms);
1742 // if ($dgAcctNames['status']['code'] !== '000') {
1743 // throw new Exception(__LINE__ . ' ' . $dgAcctNames['status']['message'], $dgAcctNames['status']['code']);
1744 // }
1745  $mirInfo = digiGetMir($parms, $HB_ENV); # be sure $parms['live'] is set so MIR works
1746  if ($mirInfo['status']['code'] !== '000') {
1747  throw new Exception(__LINE__ . ' ' . $mirInfo['status']['message'], $mirInfo['status']['code']);
1748  } else {
1749  $parms['MIR'] = $mirInfo['data'];
1750  }
1751  # format the digiliti username value here
1752  $parms['searchuser'] = (strlen($parms['MBRACCT']) < 4 ? substr('00000' . $parms['MBRACCT'], -4, 4) : $parms['MBRACCT']);
1753 
1754  $dgData = digiSearchUser($parms);
1755  if ($dgData['status']['code'] != '000' && $dgData['status']['code'] != '404') {
1756  throw new Exception($dgData['status']['message'], $dgData['status']['code']);
1757  }
1758 
1759  if ($dgData['status']['code'] == '404') {
1760  # user rec not found, add it now
1761  # but first format the list of accounts to add to Digiliti
1762  $dgAccts=array();
1763  foreach ($parms['HCUAccounts'] as $hcaKey => $hcaAccount) {
1764  # add new item to $dgData['data']['Accounts']
1765  $item = array(
1766  "Status" => $parms['defaultDGAcctStat'],
1767  "AccountName" => $hcaAccount['description'],
1768  "AccountNumber" => $hcaAccount['suffix']
1769  );
1770  # AccountNumber s/b HCU suffix as calculated based on trusted detail config
1771  # AccountTypeName / AccountTypeId s/b rdcdesc / Ck_rdctype - Sv_rdctype per HCU config
1772  # But can't add with AccountTypeName w/o AccountTypeId
1773  # so use AccountTypeId = rdctype
1774  # AccountName s/b Home Banking shortdesc
1775  # configure rdctype as 0 to pass as AccountTypeId, do not pass AccountTypeName
1776  $item["AccountTypeId"] = $hcaAccount['rdctype'];
1777  $dgAccts['data']['Accounts'][] = $item;
1778  }
1779 
1780  $dgData = digiAddNewUser($parms, $dgAccts['data']['Accounts']);
1781  if ($dgData['status']['code'] !== '000') {
1782  throw new Exception(__LINE__ . ' ' . $dgData['status']['message'], $dgData['status']['code']);
1783  }
1784  # get UserID to continue
1785  $dgUserId = $dgData['data']['UserId'];
1786  } else {
1787  if ( ! HCU_array_key_value('IsActiveUser',$dgData['data']) ) {
1788  throw new Exception('Use of this service requires activation/approval. Your request has been submitted to the CU.
1789  You will be notified when access has been approved and is ready to use.',909);
1790  }
1791  $dgUserId = $dgData['data']['UserId'];
1792  $dgData = digiGetUserDetail($parms, $dgUserId);
1793  if ($dgData['status']['code'] !== '000') {
1794  throw new Exception(__LINE__ . ' ' . $dgData['status']['message'], $dgData['status']['code']);
1795  }
1796 
1797  $sync = digiSyncAcctList($parms, $dgData);
1798  if ($sync['status']['code'] !== '000') {
1799  throw new Exception(__LINE__ . ' ' . $sync['status']['message'], $sync['status']['code']);
1800  }
1801  $dgData['data']['Accounts'] = $sync['dgUpdated'];
1802  if ($sync['needUpdate']) {
1803  # digiUpdateUser got errors, but they didn't bubble up to stop the process
1804  # Fixed! digiEmbCurl was sending error code 0 w/http 400 post error.
1805  $dgData = digiUpdateUser($parms, $dgData);
1806 
1807  if ($dgData['status']['code'] !== '000') {
1808  throw new Exception(__LINE__ . ' ' . $dgData['status']['message'], $dgData['status']['code']);
1809  }
1810  }
1811  }
1812  # Digiliti does not always return full account list after update.
1813  # SO make the call for UserDetail just to make sure we have everything
1814  # reflected the same as at Digiliti
1815  $dgData = digiGetUserDetail($parms, $dgUserId);
1816  if ($dgData['status']['code'] !== '000') {
1817  throw new Exception(__LINE__ . ' ' . $dgData['status']['message'], $dgData['status']['code']);
1818  }
1819  # now, with current list, only include the active accounts
1820  $count = array('Active' => 0, 'Inactive' => 0, 'NeedsReview' =>0);
1821  $return['data'] = $dgData['data'];
1822  $return['data']['dgUserId'] = $dgUserId;
1823  $return['data']['dgUserName'] = $dgData['data']['UserName'];
1824  $return['data']['Accounts'] = array();
1825  foreach ($dgData['data']['Accounts'] as $key => $dgAccount) {
1826  $count[$dgAccount['Status']]++;
1827  if ($dgAccount['Status'] == 'Active') {
1828  $return['data']['Accounts'][$key] = $dgAccount;
1829  }
1830  }
1831 
1832  if ( !HCU_array_key_value('Active',$count) ) {
1833  if ( HCU_array_key_value('NeedsReview',$count) ) {
1834  throw new Exception('Deposit Accounts require approval. Please contact the Credit Union for more information',910);
1835  } else {
1836  throw new Exception('No Deposit Accounts approved for Remote Deposit. Please contact the Credit Union for more information',920);
1837  }
1838  }
1839  $return['status']['response'] = 'true';
1840  $return['status']['code'] = '000';
1841  $return['status']['message'] = 'Success';
1842 
1843  } catch (Exception $e) {
1844  $return['status']['response'] = 'false';
1845  $return['status']['message'] = $e->getMessage();
1846  $return['status']['code'] = $e->getCode();
1847  $return['data'] = array();
1848  }
1849  if ($parms["logging"] == "enabled") {
1850  $logParms = $parms["environment"]; // get the environment info passed in
1851  $logParms["logPoint"] = "digiStartSession";
1852  $logParms["token"] = ''; // the id used across all communications in session
1853  $logParms["txnId"] = time(); // the id for this transaction
1854  $logParms["request"] = ""; // the request
1855 // $logParms["request"] = "parms "; // the request
1856 // $logParms["request"] .= print_r($parms, true); // the request
1857  if(isset($dgAccts)) {
1858  $logParms["request"] .= print_r($dgAccts, true); // the request
1859  } else {
1860  $logParms["request"] .= "dgAccts not set"; // the request
1861  }
1862  $logParms["reply"] = print_r($return, true);
1863 
1864  LogSSOActivity($logParms);
1865  }
1866  return $return;
1867 }
1868 
1869 ?>
Definition: User.php:7