16 function apn_config(&$parms) {
18 $parms[
'devMode'] = (! HCU_array_key_value(
'devMode', $parms) ? 0 : HCU_array_key_value(
'devMode', $parms));
19 if ($parms[
'devMode']) {
21 $parms[
'apnDomain'] = HCU_array_key_value(
'devDomain', $parms);
23 $parms[
'apnPubkey'] = HCU_array_key_value(
'devPubkey', $parms);
25 $parms[
'apnPrivkey'] = HCU_array_key_value(
'devPrivkey', $parms);
27 $parms[
'apnURL'] = HCU_array_key_value(
'devURL', $parms);
31 $parms[
'apnDomain'] = HCU_array_key_value(
'prdDomain', $parms);
33 $parms[
'apnPubkey'] = HCU_array_key_value(
'prdPubkey', $parms);
35 $parms[
'apnPrivkey'] = HCU_array_key_value(
'prdPrivkey', $parms);
37 $parms[
'apnURL'] = HCU_array_key_value(
'prdURL', $parms);
41 empty($parms[
'apnDomain']) ||
42 empty($parms[
'apnPubkey']) ||
43 empty($parms[
'apnPrivkey']) ||
44 empty($parms[
'apnURL'])
46 throw new Exception(
"Missing Parameters", 100);
57 function apn_buildSSOPayload($apnDomain, $mbrAccount, $mir, $accounts) {
60 $return[
'status'][
'response'] =
true;
61 $return[
'status'][
'message'] =
'Success';
63 'Application' =>
'BILLPAY',
64 'UserName' => $mbrAccount,
65 'FinancialInstitutionId' => $apnDomain
68 if ($mir[
'class'] ==
'B') {
69 $req_arr[
'PrimaryCompanyName'] = $mir[
'lastname'];
72 $req_arr[
'FirstName'] = $mir[
'firstname'];
73 $req_arr[
'LastName'] = $mir[
'lastname'];
76 $req_arr[
'Email'] = $mir[
'email'];
77 $req_arr[
'Accounts'] = [];
78 $req_arr[
'Address1'] = $mir[
'address1'];
79 $req_arr[
'City'] = $mir[
'city'];
80 $req_arr[
'State'] = $mir[
'state'];
81 $req_arr[
'Zip'] = $mir[
'zip'];
83 if (HCU_array_key_exists(
'phonenumbers',$mir)) {
84 $req_arr[
'PhoneNumbers'] = $mir[
'phonenumbers'];
87 $mirtype = (HCU_array_key_value(
'class', $mir) ==
'B') ?
'Business' :
'Personal';
89 if (!is_array($accounts) || !count($accounts)) {
90 throw new Exception(
'No Eligible Payment Accounts Found');
94 foreach ($accounts as $acctID => $account) {
101 'AccountNumber' => $account[
'AccountNumber'],
102 'AccountName' => $account[
'AccountName'],
104 'AvailableAccountBalance' => $account[
'AvailableAccountBalance'] * 1,
105 'RoutingNumber' => $account[
'RoutingNumber'],
106 'AccountOwnerType' => $mirtype,
107 'AccountType' => $account[
'AccountType']
110 $account[
'AccountOwnerType'] = $mirtype;
112 $req_arr[
'Accounts'][
'$values'][] = $a;
115 $return[
'data'] = json_encode($req_arr);
117 }
catch (Exception $e) {
118 $return[
'status'][
'response'] =
false;
119 $return[
'status'][
'message'] = $e->getMessage() .
" (" . $e->getLine() .
")";
120 $return[
'data'] = [];
134 function apn_selectAccounts($dbh, $Cu, $Cn, $parms) {
137 $return[
'status'][
'response'] =
true;
138 $return[
'status'][
'message'] =
"Success";
140 $return[
'data'] = [];
142 if (!HCU_array_key_value(
'rtn', $parms)) {
143 throw new Exception(
'Missing Routing Number');
147 $rtn = HCU_array_key_value(
'rtn', $parms);
148 $acctsql = (HCU_array_key_value(
'acctsql', $parms) ? $parms[
'acctsql'] :
"trim(micraccount)");
149 $balwhere = (HCU_array_key_value(
'balwhere', $parms) ? $parms[
'balwhere'] :
"and deposittype = 'Y' and trim(micraccount) <> ''");
150 $sendjoint = (HCU_array_key_value(
'sendjoint', $parms) ? $parms[
'sendjoint'] : 0);
152 $sql =
"select {$acctsql} as account, trim(description) as name, available, 153 case when deposittype = 'Y' then 'checking' else 'savings' end as atype 154 from {$Cu}accountbalance where accountnumber='$Cn' 155 and deposittype in ('Y','S','N') $balwhere";
158 $sql .=
" and accounttype not like '%@%' ";
160 $sql .=
" order by accounttype;";
162 $sth = db_query($sql, $dbh);
164 if (! ($sth) || (db_num_rows($sth) == 0)) {
165 throw new Exception(
'No Eligible Payment Accounts Found');
168 for ($row = 0; $drow = db_fetch_array($sth, $row); $row++) {
170 $return[
'data'][] = [
171 'AccountNumber' => HCU_array_key_value(
'account', $drow),
172 'AccountName' => HCU_array_key_value(
'name', $drow),
173 'AvailableAccountBalance' => HCU_array_key_value(
'available', $drow),
174 'RoutingNumber' => $rtn,
175 'AccountType' => HCU_array_key_value(
'atype', $drow)
179 }
catch (Exception $e) {
180 $return[
'status'][
'response'] =
false;
181 $return[
'status'][
'message'] = $e->getMessage() .
" (" . $e->getLine() .
")";
182 $return[
'data'] = [];
196 function apn_buildAuthHdr($apnURL, $apnDomain, $apnPubkey, $apnPrivkey, $mbrAccount) {
199 $return[
'status'][
'response'] =
true;
200 $return[
'status'][
'message'] =
'Success';
202 if (empty($apnURL) || empty($apnDomain) || empty($apnPubkey) || empty($apnPrivkey) || empty($mbrAccount)) {
203 throw new Exception(
'Missing Parameters');
206 $authdate = apn_timestamp();
207 $sigstring =
"{$apnURL}\r\n{$authdate}\r\n";
208 $signature = hash_hmac(
'SHA1', $sigstring, $apnPrivkey, TRUE);
209 $signature = base64_encode($signature);
210 $authstring =
"Authorization: TIMESTAMP username={$mbrAccount};domain={$apnDomain};" 211 .
"timestamp={$authdate};signature={$signature};publicKey={$apnPubkey}";
212 $return[
'data'] = $authstring;
214 }
catch (Exception $e) {
215 $return[
'status'][
'response'] =
false;
216 $return[
'status'][
'message'] = $e->getMessage() .
" (" . $e->getLine() .
")";
217 $return[
'data'] = [];
228 function apn_timestamp() {
230 $t = microtime(
true);
231 $t = substr($t, strpos($t,
'.'), 4);
233 $d = str_replace(
'+00:00',
"{$t}Z", $d);
246 function apn_embcurl($parms, $reqURL, $reqMethod, $reqHeaders, $reqData =
'') {
249 CURLOPT_RETURNTRANSFER => 1,
250 CURLOPT_SSL_VERIFYPEER => 0,
251 CURLOPT_SSL_VERIFYHOST => 0,
252 CURLOPT_HEADER => FALSE,
253 CURLOPT_URL => $reqURL
257 curl_setopt_array($ch, $curlopts);
259 if ($reqMethod !=
'GET') {
260 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $reqMethod);
262 if (strlen($reqData) > 0) {
263 curl_setopt($ch, CURLOPT_POSTFIELDS, $reqData);
266 curl_setopt($ch, CURLOPT_HTTPHEADER, $reqHeaders);
267 $response = curl_exec($ch);
269 if ($parms[
"logging"] ==
"enabled") {
271 'env' => ($parms[
'environment']) ??
'No Environment in params',
272 'ch' => print_r($ch,
true),
273 'headers' => $reqHeaders,
274 'method' => $reqMethod,
277 'response' => $response,
278 'curlinfo' => print_r(curl_getinfo($ch),
true)
280 LogSSOActivity(AlliedLogParams($log));
283 $respHTTP = curl_getinfo($ch, CURLINFO_HTTP_CODE);
285 if ($respHTTP >= 400 && $respHTTP < 600) {
289 "status" =>
"hcuH" . $respHTTP,
290 "message" =>
"Connection Failed HTTP Error" 293 } elseif (curl_errno($ch)) {
296 "status" =>
"hcuC" . curl_errno($ch),
297 "message" =>
"Curl Error" 300 } elseif (!isset($response) || $response ==
'') {
303 "status" =>
"hcuE" . curl_errno($ch),
304 "message" =>
"Empty Response" 308 $respArr = json_decode($response, TRUE);
321 function AlliedLogParams($log_params) {
324 $logParms = $log_params[
'env'];
326 $logParms[
"token"] =
'';
332 $logParms[
"txnId"] = time();
334 $logParms[
"request"] =
"curl ";
336 if ($log_params[
'method'] !=
'GET') {
337 $logParms[
"request"] .=
"-X {$log_params['method']} ";
340 if (is_array($log_params[
'headers'])) {
341 foreach ($log_params[
'headers'] as $hdr) {
342 $logParms[
'request'] .=
"-H '$hdr' ";
347 if (strlen($log_params[
'data']) > 0) {
348 $logParms[
'request'] .=
"-d '{$log_params['data']}' ";
351 $logParms[
'request'] .=
"'{$log_params['url']}' ";
352 $logParms[
"reply"] = $log_params[
'curlinfo'];
353 $logParms[
"reply"] .=
"\n{$log_params['response']}";
374 function apn_populateMIR($MIR, $Ml, $reqMIR, $datefmt =
'Y-m-d', $phones =
'flat', $noEmpty =
false) {
382 if ($phones ==
'flat') {
384 $MIR[
'data'][
'phone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'homephone']);
385 if (trim($MIR[
'data'][
'phone']) ==
'') {
386 $MIR[
'data'][
'phone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'cellphone']);
388 if (trim($MIR[
'data'][
'phone']) ==
'') {
389 $MIR[
'data'][
'phone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'workphone']);
392 } elseif ($phones ==
'split') {
394 $MIR[
'data'][
'homephone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'homephone']);
395 switch (strlen($MIR[
'data'][
'homephone'])) {
397 $MIR[
'data'][
'homephone'] = [
398 'area' => substr($MIR[
'data'][
'homephone'], 0, 3),
399 'pre' => substr($MIR[
'data'][
'homephone'], 3, 3),
400 'num' => substr($MIR[
'data'][
'homephone'], 6, 4)
404 $MIR[
'data'][
'homephone'] = [
405 'pre' => substr($MIR[
'data'][
'homephone'], 3, 3),
406 'num' => substr($MIR[
'data'][
'homephone'], 6, 4)
410 unset($MIR[
'data'][
'homephone']);
414 $MIR[
'data'][
'cellphone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'cellphone']);
416 switch (strlen($MIR[
'data'][
'cellphone'])) {
418 $MIR[
'data'][
'cellphone'] = [
419 'area' => substr($MIR[
'data'][
'cellphone'], 0, 3),
420 'pre' => substr($MIR[
'data'][
'cellphone'], 3, 3),
421 'num' => substr($MIR[
'data'][
'cellphone'], 6, 4)
425 $MIR[
'data'][
'cellphone'] = [
426 'pre' => substr($MIR[
'data'][
'cellphone'], 3, 3),
427 'num' => substr($MIR[
'data'][
'cellphone'], 6, 4)
431 unset($MIR[
'data'][
'cellphone']);
435 $MIR[
'data'][
'workphone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'workphone']);
437 switch (strlen($MIR[
'data'][
'workphone'])) {
439 $MIR[
'data'][
'workphone'] = [
440 'area' => substr($MIR[
'data'][
'workphone'], 0, 3),
441 'pre' => substr($MIR[
'data'][
'workphone'], 3, 3),
442 'num' => substr($MIR[
'data'][
'workphone'], 6, 4)
446 $MIR[
'data'][
'workphone'] = [
447 'pre' => substr($MIR[
'data'][
'workphone'], 3, 3),
448 'num' => substr($MIR[
'data'][
'workphone'], 6, 4)
452 unset($MIR[
'data'][
'workphone']);
456 } elseif ($phones ==
'named') {
458 $MIR[
'data'][
'phonenumbers'] = [];
459 $MIR[
'data'][
'homephone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'homephone']);
461 switch (strlen($MIR[
'data'][
'homephone'])) {
464 $MIR[
'data'][
'phonenumbers'][] = [
465 'number' => $MIR[
'data'][
'homephone'],
467 'isTextCapable' => FALSE
471 unset($MIR[
'data'][
'homephone']);
475 $MIR[
'data'][
'cellphone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'cellphone']);
477 switch (strlen($MIR[
'data'][
'cellphone'])) {
481 $MIR[
'data'][
'phonenumbers'][] = [
482 'number' => $MIR[
'data'][
'cellphone'],
484 'isTextCapable' => TRUE
488 unset($MIR[
'data'][
'cellphone']);
492 $MIR[
'data'][
'workphone'] = preg_replace(
'/\D/',
'', $MIR[
'data'][
'workphone']);
494 switch (strlen($MIR[
'data'][
'workphone'])) {
497 $MIR[
'data'][
'phonenumbers'][] = [
498 'number' => $MIR[
'data'][
'workphone'],
500 'isTextCapable' => FALSE
504 unset($MIR[
'data'][
'workphone']);
508 if (!count($MIR[
'data'][
'phonenumbers'])) {
509 unset($MIR[
'data'][
'phonenumbers']);
514 $MIR[
'data'][
'dob'] = format_date($MIR[
'data'][
'dob'], $datefmt);
516 $rmlist = [
' ',
'-'];
517 $MIR[
'data'][
'ssn'] = str_replace($rmlist,
'', $MIR[
'data'][
'ssn']);
518 $MIR[
'data'][
'zip'] = str_replace($rmlist,
'', $MIR[
'data'][
'zip']);
520 if (strlen($MIR[
'data'][
'zip']) < 5) {
521 unset($MIR[
'data'][
'zip']);
524 $rmlist = [
"#",
"&",
"/",
"%",
",",
":",
"=",
"?",
"'"];
526 $EMAIL = (empty($MIR[
'data'][
'email']) ? $Ml : $MIR[
'data'][
'email']);
527 $MIR[
'data'][
'email'] = str_replace($rmlist,
"", $EMAIL);
528 $MIR[
'data'][
'firstname'] = str_replace($rmlist,
"", $MIR[
'data'][
'firstname']);
529 $MIR[
'data'][
'middlename'] = str_replace($rmlist,
"", $MIR[
'data'][
'middlename']);
530 $MIR[
'data'][
'lastname'] = str_replace($rmlist,
"", $MIR[
'data'][
'lastname']);
531 $MIR[
'data'][
'address1'] = str_replace($rmlist,
"", $MIR[
'data'][
'address1']);
532 $MIR[
'data'][
'address2'] = str_replace($rmlist,
"", $MIR[
'data'][
'address2']);
533 $MIR[
'data'][
'city'] = str_replace($rmlist,
"", $MIR[
'data'][
'city']);
534 $MIR[
'data'][
'state'] = str_replace($rmlist,
"", $MIR[
'data'][
'state']);
535 $MIR[
'data'][
'accountnumber'] = str_replace($rmlist,
"", $MIR[
'data'][
'accountnumber']);
536 # default country code to US. Assume CU will specify for other countries 537 if (trim($MIR[
'data'][
'cc']) ==
'') {
538 $MIR[
'data'][
'cc'] =
'US';
542 if (! HCU_array_key_value(
'firstname', $MIR[
'data']) && HCU_array_key_value(
'lastname', $MIR[
'data'])) {
543 $MIR[
'data'][
'class'] =
'B';
545 unset($reqMIR[
'firstname']);
564 foreach ($keys as $field) {
565 if (trim($MIR[
'data'][$field]) ==
false) {
566 unset($MIR[
'data'][$field]);
571 $missing = array_diff_key($reqMIR, $MIR[
'data']);
572 if (
sizeof($missing)) {
573 throw new Exception(
"Incomplete Member Info (" . join(
", ", array_keys($missing)) .
")");
576 $return[
'status'][
'response'] =
true;
577 $return[
'status'][
'message'] =
'Success';
578 $return[
'data'] = $MIR[
'data'];
580 }
catch (Exception $e) {
581 $return[
'status'][
'response'] =
false;
582 $return[
'status'][
'message'] = $e->getMessage();
584 $return[
'data'] = [];