Sign.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. <?php
  2. namespace Pay\Yspay;
  3. use Dever;
  4. header("Content-Type:text/html;charset=utf-8");
  5. Class Sign
  6. {
  7. static $key = "o5ho739mgrphdm28g5rwx1nw";
  8. static $accesser_id = '2d9081bd7db8ad75017dbbe68981314f';
  9. private $url = 'https://yinshangpai.chinaums.com/self-contract-nmrs/interface/autoReg/';
  10. static $sign_type = 'SHA-256';
  11. private $test = 2;
  12. //private $product_id = array('0','1','in1','in2','in3','in4');
  13. private $product_id = array('0');
  14. private $document_type = array
  15. (
  16. 'idcard_front' => ['document_type' => '0001','document_name' => '身份证正面'],
  17. 'idcard_back' => ['document_type' => '0011','document_name' => '身份证反面'],
  18. 'license' => ['document_type' => '0002','document_name' => '营业执照'],
  19. 'tax' => ['document_type' => '0003','document_name' => '税务登记证'],
  20. 'door' => ['document_type' => '0005','document_name' => '门头照'],
  21. 'hand_idcard' => ['document_type' => '0007','document_name' => '手持身份证自拍照'],
  22. 'open' => ['document_type' => '0006','document_name' => '开户许可证'],
  23. 'bank_fount' => ['document_type' => '0025','document_name' => '银行卡正面照'],
  24. 'bank_back' => ['document_type' => '0026','document_name' => '银行卡反面照'],
  25. 'house_pic' => ['document_type' => '0015','document_name' => '室内照片'],
  26. 'screen_pic' => ['document_type' => '0034','document_name' => '商户网站/APP截图'],
  27. );
  28. public function update($id, $name, $data)
  29. {
  30. $cash = Dever::param('cash', $data);
  31. $sign = Dever::db('pay/yspay_sign')->find($id);
  32. if ($cash && $cash > 0) {
  33. $this->account_check($sign, $cash);
  34. }
  35. }
  36. # 计划任务
  37. public function cron_api()
  38. {
  39. $where['step'] = '4,5';
  40. $data = Dever::db('pay/yspay_sign')->getData($where);
  41. if ($data) {
  42. foreach ($data as $k => $v) {
  43. $this->check($v);
  44. }
  45. }
  46. return 'ok';
  47. }
  48. # 获取合同链接
  49. public function getAgreement_api($sign_id)
  50. {
  51. $sign = Dever::db('pay/yspay_sign')->find($sign_id);
  52. return $this->agreement($sign, false);
  53. }
  54. # 获取当前状态
  55. public function getStatus_api($sign_id)
  56. {
  57. $sign = Dever::db('pay/yspay_sign')->find($sign_id);
  58. return $this->check($sign);
  59. }
  60. # 获取最新一条日志
  61. public function getLog($sign_id, $status)
  62. {
  63. if ($status == 1) {
  64. return '签约已完成';
  65. }
  66. $sign = Dever::db('pay/yspay_sign')->find($sign_id);
  67. $log = Dever::db('pay/yspay_sign_log')->find(array('merchant_id' => $sign['merchant_id']));
  68. if ($log) {
  69. $date = date('Y-m-d H:i', $log['cdate']);
  70. $step = Dever::db('pay/yspay_sign_log')->config['step'][$log['step']];
  71. return $date . '<br />' . $step . '<br />' . $log['desc'];
  72. } else {
  73. return '待提交资料';
  74. }
  75. }
  76. # 获取日志列表
  77. public function getLogList($sign_id)
  78. {
  79. $sign = Dever::db('pay/yspay_sign')->find($sign_id);
  80. if (!$sign) {
  81. return Dever::timeline('填写资料');
  82. }
  83. $result = array();
  84. $log = Dever::db('pay/yspay_sign_log')->select(array('merchant_id' => $sign['merchant_id']));
  85. if ($log) {
  86. foreach ($log as $k => $v) {
  87. if ($v['step'] == 4) {
  88. //$v['response'] = Dever::json_decode($v['response']);
  89. $url = $this->agreement($sign, false);
  90. $v['desc'] .= ' <a href="'.$url.'" target="_blank">点此打开</a> <a style="cursor:pointer" data-clipboard-text="'.$url.'" class="clipboard">复制链接</a>';
  91. }
  92. $date = date('Y-m-d H:i', $v['cdate']);
  93. $name = '';
  94. if ($v['admin_id'] > 0) {
  95. $admin = Dever::db('manage/admin')->find($v['admin_id']);
  96. if ($admin) {
  97. $name = '[' . $admin['username'] . ']&nbsp;&nbsp;';
  98. }
  99. }
  100. $result[] = $date . '&nbsp;&nbsp;' . $name . ''. $v['desc'];
  101. }
  102. }
  103. if ($sign['step'] == -1) {
  104. $url = Dever::url('pay/yspay/sign.handle?sign_id=' . $sign['id'] . '&json=1');
  105. $result[] = '<a href="javascript:;" onclick="load(\''.$url.'\')">点此上传资料</a>';
  106. }
  107. $result = Dever::timeline('签约记录', $result);
  108. return $result;
  109. }
  110. # 统一处理接口
  111. public function handle_api($sign_id)
  112. {
  113. $sign = Dever::db('pay/yspay_sign')->find($sign_id);
  114. if (!$sign) {
  115. Dever::alert('档案资料未上传');
  116. }
  117. $sign['bank_acct_no'] = str_replace(' ', '', $sign['bank_acct_no']);
  118. switch($sign['step']) {
  119. case -1:
  120. # 提交资料
  121. return $this->up($sign);
  122. break;
  123. case 1:
  124. case 6:
  125. if ($sign['bank_acct_type'] == 1) {
  126. # 对公打款
  127. return $this->account($sign);
  128. } else {
  129. # 签约
  130. return $this->agreement($sign);
  131. }
  132. break;
  133. case 2:
  134. # 打款验证
  135. return $this->account_check($sign);
  136. break;
  137. case 4:
  138. case 5:
  139. # 验证签约
  140. return $this->check($sign);
  141. break;
  142. case 6:
  143. # 签约成功,变更签约?
  144. return '签约已成功,后续可以变更签约';
  145. return $this->up($sign);
  146. break;
  147. }
  148. return 'ok';
  149. }
  150. # 上传图片
  151. public function upload_api()
  152. {
  153. $document_type = $this->document_type;
  154. $key = Dever::input('key');
  155. $upload = Dever::json_decode(Dever::input('upload'));
  156. if ($upload && isset($document_type[$key]) && isset($upload['url'])) {
  157. $url = md5($upload['url']);
  158. $sign_pic = Dever::db('pay/yspay_sign_pic')->find(array('key' => $key, 'url' => $url));
  159. if (!$sign_pic) {
  160. $pic = $this->pic($upload['url']);
  161. if ($pic && isset($pic['data']['file_path']) && $pic['data']['file_path']) {
  162. $insert = array();
  163. $insert['url'] = $url;
  164. $insert['document_type'] = $document_type[$key]['document_type'];
  165. $insert['document_name'] = $document_type[$key]['document_name'];
  166. $insert['key'] = $key;
  167. $insert['path'] = Dever::json_encode($pic['data']);
  168. Dever::db('pay/yspay_sign_pic')->insert($insert);
  169. }
  170. }
  171. }
  172. return 'ok';
  173. }
  174. #3.2 详细采集档案资料上传接口
  175. private function up($sign)
  176. {
  177. $service = 'complex_upload';
  178. $data['remark'] = '线上支付商户';
  179. $data['accesser_user_id'] = $sign['id'];
  180. if ($sign['reg_mer_type'] == 1) {
  181. $sign['reg_mer_type'] = '00';
  182. } elseif ($sign['reg_mer_type'] == 2) {
  183. $sign['reg_mer_type'] = '01';
  184. } elseif ($sign['reg_mer_type'] == 3) {
  185. $sign['reg_mer_type'] = '02';
  186. }
  187. $data['reg_mer_type'] = $sign['reg_mer_type'];#注册类型
  188. $data['legal_name'] = $sign['name'];#法人姓名
  189. $data['legal_idcard_no'] = $sign['idcard'];#法人身份证号
  190. $data['legal_mobile'] = $sign['mobile'];#法人手机号
  191. $data['legal_card_deadline'] = $sign['card_deadline'] == '长期' ? '9999-12-31' : date('Y-m-d',$sign['card_deadline']);#证件截止代表日期
  192. $data['shop_name'] = $sign['name'];#店铺名称
  193. if ($sign['bank_acct_type'] == -1) {
  194. $data['bank_acct_type'] = 0;
  195. $data['bank_acct_name'] = $sign['name'];#开户账号名称
  196. } else {
  197. $data['bank_acct_type'] = 1;
  198. $data['bank_acct_name'] = $sign['company_name'];#开户账号名称
  199. }
  200. $data['bank_acct_no'] = $sign['bank_acct_no'];#开户行账号
  201. $data['mccCode'] = $sign['mccCode'];
  202. $area = explode(',', $sign['area']);
  203. $data['shop_province_id'] = $area[0]/10000;
  204. $data['shop_city_id'] = $area[1]/100;
  205. $data['shop_country_id'] = $area[2];
  206. $sign_area = explode(',',$sign['area']);
  207. $data['shop_lic'] = $sign['license_number'];#营业执照号
  208. $bank = $this->bank_list($sign_area[0]/10000, $sign['bank_acct_noname']);
  209. if($bank && isset($bank['branchBankList']) && $bank['branchBankList']){
  210. $bank['branchBankList'] = $bank['branchBankList'][0];
  211. $in['where_id'] = $sign['id'];
  212. $in['bank_no'] = $bank['branchBankList']['code'];
  213. $in['shop_addr_ext'] = $bank['branchBankList']['bankBranchName'];
  214. Dever::db('pay/yspay_sign')->update($in);
  215. $data['bank_no'] = $bank['branchBankList']['code'];
  216. $data['shop_addr_ext'] = $bank['branchBankList']['bankBranchName'];
  217. } else {
  218. return $this->log(1, $sign, '开户行行号不存在');
  219. }
  220. if ($sign['reg_mer_type'] == '00' && $sign['bank_acct_type'] != '1') {
  221. return $this->log(1, $sign, '账户类型不正确1');
  222. }
  223. if ($sign['legalmanHomeAddr']) {
  224. $data['legalmanHomeAddr'] = $sign['legalmanHomeAddr'];
  225. }
  226. $document_type = $this->document_type;
  227. foreach ($document_type as $k => $v) {
  228. if (isset($sign[$k]) && $sign[$k]) {
  229. $sign[$k] = Dever::pic($sign[$k]);
  230. $url = md5($sign[$k]);
  231. $sign_pic = Dever::db('pay/yspay_sign_pic')->find(array('key' => $k, 'url' => $url));
  232. if (!$sign_pic) {
  233. $pic = $this->pic($sign[$k]);
  234. if ($pic && isset($pic['data']['file_path']) && $pic['data']['file_path']) {
  235. $insert = array();
  236. $insert['url'] = $url;
  237. $insert['document_type'] = $v['document_type'];
  238. $insert['document_name'] = $v['document_name'];
  239. $insert['key'] = $k;
  240. $insert['path'] = Dever::json_encode($pic['data']);
  241. Dever::db('pay/yspay_sign_pic')->insert($insert);
  242. $data['pic_list'][] = array('document_name' => $v['document_name'], 'document_type' => $v['document_type'] , 'file_path'=> $pic['data']['file_path'], 'file_size'=>$pic['data']['file_size']);
  243. }
  244. } else {
  245. $pic = Dever::json_decode($sign_pic['path']);
  246. $data['pic_list'][] = array('document_name' => $sign_pic['document_name'], 'document_type' => $sign_pic['document_type'] , 'file_path'=> $pic['file_path'], 'file_size'=>$pic['file_size']);
  247. }
  248. }
  249. }
  250. $ids = $this->product_id;
  251. $data['product'] = array();
  252. foreach ($ids as $k => $v) {
  253. $data['product'][$k] = ['product_id' => $v];
  254. }
  255. $result = $this->get($service, $data);
  256. if ($result && $result['code'] == 1 && isset($result['data']['ums_reg_id']) && $result['data']['ums_reg_id']) {
  257. $update = array();
  258. $update['where_id'] = $sign['id'];
  259. $sign['ums_reg_id'] = $update['ums_reg_id'] = $result['data']['ums_reg_id'];
  260. Dever::db('pay/yspay_sign')->update($update);
  261. $this->log(1, $sign, '资料上传成功', $data, $result['data'], $result['request_seq']);
  262. if ($data['bank_acct_type'] == 1) {
  263. return $this->account($sign);
  264. } else {
  265. return $this->agreement($sign);
  266. }
  267. } else {
  268. $this->log(1, $sign, $result['msg'], $data, $result['data'], $result['request_seq']);
  269. }
  270. return Dever::input('json') == 1 ? 'reload' : $result;
  271. }
  272. # 3.7 发起对公账户验证交易接口
  273. public function account($sign)
  274. {
  275. $step = 2;
  276. $service = 'request_account_verify';
  277. $data['ums_reg_id'] = $sign['ums_reg_id'];
  278. $data['company_account'] = $sign['bank_acct_no'];
  279. $result = $this->get($service, $data);
  280. if ($result && $result['code'] == 1 && isset($result['data']['request_seq']) && $result['data']['request_seq']) {
  281. $update = array();
  282. $update['where_id'] = $sign['id'];
  283. $update['step'] = $step;
  284. $update['clear'] = true;
  285. Dever::db('pay/yspay_sign')->update($update);
  286. $this->log($update['step'], $sign, '公户打款成功', $data, $result['data'], $result['request_seq']);
  287. } else {
  288. $this->log($step, $sign, $result['msg'], $data, $result['data'], $result['request_seq']);
  289. }
  290. return Dever::input('json') == 1 ? 'reload' : $result;
  291. }
  292. # 3.6 对公账户认证接口
  293. public function account_check($sign, $num)
  294. {
  295. $step = 3;
  296. $trans_amt = $num;
  297. $service = 'company_account_verify';
  298. $data['ums_reg_id'] = $sign['ums_reg_id'];
  299. $data['company_account'] = $sign['bank_acct_no'];
  300. $data['trans_amt'] = $trans_amt;
  301. $result = $this->get($service, $data, $sign['ums_reg_id']);
  302. if ($result && $result['code'] == 1 && isset($result['data']['request_seq']) && $result['data']['request_seq']) {
  303. $update = array();
  304. $update['where_id'] = $sign['id'];
  305. $update['step'] = $step;
  306. $update['clear'] = true;
  307. Dever::db('pay/yspay_sign')->update($update);
  308. $this->log($update['step'], $sign, '公户对账成功', $data, $result['data'], $result['request_seq']);
  309. return $this->agreement($sign);
  310. } else {
  311. $this->log($step, $sign, $result['msg'], $data, $result['data'], $result['request_seq']);
  312. }
  313. return $result;
  314. }
  315. # 3.3 前台签约接口
  316. public function agreement($sign, $log = true)
  317. {
  318. $step = 4;
  319. $service = 'agreement_sign';
  320. $data['ums_reg_id'] = $sign['ums_reg_id'];
  321. $data['pcOrH5'] = 'H5';
  322. $result = $this->get($service, $data);
  323. if ($result && $result['code'] == 1 && isset($result['data']['url']) && $result['data']['url']) {
  324. $update = array();
  325. $update['where_id'] = $sign['id'];
  326. $update['step'] = $step;
  327. $update['url'] = $result['data']['url'];
  328. $update['clear'] = true;
  329. Dever::db('pay/yspay_sign')->update($update);
  330. if ($log) {
  331. $this->log($update['step'], $sign, '请复制链接进行合同签署', $data, $result['data'], $result['request_seq']);
  332. } else {
  333. return $update['url'];
  334. }
  335. } else {
  336. $this->log($step, $sign, $result['msg'], $data, $result['data'], $result['request_seq']);
  337. }
  338. return Dever::input('json') == 1 ? 'reload' : $result;
  339. }
  340. # 3.4 入网状态查询接口
  341. public function check($sign)
  342. {
  343. $step = 5;
  344. $service = 'apply_qry';
  345. $data['ums_reg_id'] = $sign['ums_reg_id'];
  346. $result = $this->get($service, $data, $sign['ums_reg_id']);
  347. if ($result && $result['code'] == 1 && isset($result['data']['apply_status'])) {
  348. if ($result['data']['apply_status'] == '03') {
  349. $step = 6;
  350. }
  351. $update = array();
  352. $update['where_id'] = $sign['id'];
  353. $update['step'] = $step;
  354. $update['clear'] = true;
  355. if ($result['data']['apply_status'] == '03' && isset($result['data']['mer_no']) && $result['data']['mer_no']) {
  356. $update['mid'] = $result['data']['mer_no'];
  357. }
  358. Dever::db('pay/yspay_sign')->update($update);
  359. $this->log($update['step'], $sign, $result['data']['apply_status_msg'], $data, $result['data'], $result['request_seq']);
  360. } else {
  361. $this->log($step, $sign, $result['data']['apply_status_msg'], $data, $result['data'], $result['request_seq']);
  362. }
  363. return $result;
  364. }
  365. private function encrypt($data='', $key='', $use3des = true)
  366. {
  367. $key = self::$key;
  368. $res = bin2hex(openssl_encrypt($data, 'DES-EDE3', $key, OPENSSL_RAW_DATA));
  369. return $res;
  370. }
  371. private function decrypt($data='', $key='', $use3des = true)
  372. {
  373. $key = self::$key;
  374. return openssl_decrypt(pack('H*',$data), 'DES-EDE3', $key, OPENSSL_RAW_DATA);
  375. }
  376. private function get($service, $data)
  377. {
  378. $accesser_id = self::$accesser_id;
  379. $sign_type = self::$sign_type;
  380. $param = $data;
  381. $param['service'] = $service;
  382. $param['sign_type'] = $sign_type;
  383. $param['accesser_id'] = $accesser_id;
  384. $param['request_date'] = date('YmdHis');
  385. $param['request_seq'] = Dever::order();
  386. $sign_data = json_encode($param, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
  387. $send['json_data'] = $this->encrypt($sign_data);
  388. $send['sign_data'] = hash('sha256', $sign_data);
  389. $send['accesser_id'] = $accesser_id;
  390. $url = $this->url;
  391. $result = array();
  392. $result['request_seq'] = $param['request_seq'];
  393. $result['code'] = 2;
  394. $result['msg'] = '请求失败';
  395. $result['data'] = array();
  396. if ($service == 'agreement_sign') {
  397. $result['code'] = 1;
  398. $result['msg'] = '请求成功';
  399. $result['data']['url'] = $url . '?' . http_build_query($send);
  400. return $result;
  401. }
  402. if ($this->test != 1) {
  403. $response = Dever::curl($url, $send, 'post');
  404. } else {
  405. # 数据模拟
  406. $response = $this->data($service, $param);
  407. }
  408. $result['data'] = $response;
  409. if ($response) {
  410. $response = Dever::json_decode($response);
  411. if (isset($response['res_code']) && ($response['res_code'] == '0000' || $response['res_code'] == '1446')) {
  412. $result['code'] = 1;
  413. $result['msg'] = '请求成功';
  414. $result['data'] = $response;
  415. } elseif (isset($response['res_msg']) && $response['res_msg']) {
  416. $result['code'] = 2;
  417. $result['msg'] = $response['res_msg'];
  418. $result['data'] = $response;
  419. } elseif (isset($response['apply_status_msg']) && $response['apply_status_msg']) {
  420. $result['code'] = 2;
  421. $result['msg'] = $response['apply_status_msg'];
  422. $result['data'] = $response;
  423. }
  424. }
  425. return $result;
  426. }
  427. private function data($service, $data)
  428. {
  429. $result = array();
  430. $result['res_code'] = '0000';
  431. $result['res_msg'] = 'ok';
  432. $result['request_seq'] = $data['request_seq'];
  433. if ($service == 'pic_upload') {
  434. $result['file_path'] = $data['request_seq'];
  435. $result['file_type'] = 'jpg';
  436. $result['file_size'] = strlen($result['file_path']);
  437. } elseif ($service == 'complex_upload') {
  438. $result['ums_reg_id'] = $data['request_seq'];
  439. } elseif ($service == 'agreement_sign') {
  440. $result['url'] = 'https://www.baidu.com/';
  441. } elseif ($service == 'apply_qry') {
  442. $result['apply_status'] = '03';
  443. $result['apply_status_msg'] = '入网成功(最终成功状态)';
  444. } elseif ($service == 'branch_bank_list') {
  445. $result['branchBankList'][] = array('code' => '308100005607', 'bankBranchName' => '招商银行股份有限公司北京天通苑支行');
  446. }
  447. return Dever::json_encode($result);
  448. }
  449. private function pic($pic)
  450. {
  451. $service = 'pic_upload';
  452. if ($pic) {
  453. $pic_base64 = $this->test != 1 ? file_get_contents($pic) : 'content';
  454. if ($pic_base64) {
  455. $temp = explode('?', $pic);
  456. if ($temp) {
  457. $one = pathinfo($temp[0]);
  458. } else {
  459. $one = pathinfo($pic);
  460. }
  461. $data['pic_base64'] = "data:image/".$one['extension'].";base64,".base64_encode($pic_base64);
  462. $result = $this->get($service, $data);
  463. return $result;
  464. }
  465. }
  466. return false;
  467. }
  468. # 查询支行
  469. private function bank_list($areaCode, $key)
  470. {
  471. $service = 'branch_bank_list';
  472. $data['areaCode'] = $areaCode;
  473. $data['key'] = $key;
  474. $result = $this->get($service,$data);
  475. return $result['data'];
  476. }
  477. # 记录日志
  478. private function log($step, $sign, $msg, $request = array(), $response = array(), $request_seq = '')
  479. {
  480. if (!$sign) {
  481. return $msg;
  482. }
  483. $data['step'] = $step;
  484. $data['merchant_id'] = $sign['merchant_id'];
  485. $data['desc'] = $msg;
  486. $info = false;
  487. if ($step == 4 || $step == 5) {
  488. $info = Dever::db('pay/yspay_sign_log')->find($data);
  489. }
  490. $admin = Dever::load('manage/auth.info');
  491. if ($admin) {
  492. $data['admin_id'] = $admin['id'];
  493. }
  494. if ($request_seq) {
  495. $data['request_seq'] = $request_seq;
  496. }
  497. if ($request) {
  498. $data['request'] = Dever::json_encode($request);
  499. }
  500. if ($response) {
  501. if (is_array($response)) {
  502. $response = Dever::json_encode($response);
  503. }
  504. $data['response'] = $response;
  505. }
  506. if ($info) {
  507. $data['where_id'] = $info['id'];
  508. Dever::db('pay/yspay_sign_log')->update($data);
  509. } else {
  510. Dever::db('pay/yspay_sign_log')->insert($data);
  511. }
  512. return $msg;
  513. }
  514. }