CregisPayService.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services;
  12. use App\Models\BalanceLogModel;
  13. use Cregis\Dispatch\CregisDispatch;
  14. /**
  15. * Cregis U盾钱包服务管理-服务类
  16. * @author laravel开发员
  17. * @since 2020/11/11
  18. * @package App\Services
  19. */
  20. class CregisPayService extends BaseService
  21. {
  22. // 静态对象
  23. protected static $instance = null;
  24. protected $dispatch = null;
  25. protected static $config = [];
  26. public function __construct()
  27. {
  28. $config = ConfigService::make()->getConfigByGroup(7);
  29. $notifyUrl = isset($config['cregis_callback_url']['value']) ? $config['cregis_callback_url']['value'] : '';
  30. $notifyUrl = $notifyUrl ? $notifyUrl : '/api/v1/wallet-api/cregisCallback';
  31. self::$config = [
  32. 'project_no' => isset($config['cregis_project_no']['value']) ? $config['cregis_project_no']['value'] : '', //商户号
  33. 'api_key' => isset($config['cregis_api_key']['value']) ? $config['cregis_api_key']['value'] : '', //apikey
  34. 'endpoint' => isset($config['cregis_endpoint']['value']) ? $config['cregis_endpoint']['value'] : '', //节点
  35. 'callUrl' => url($notifyUrl, '', true), //回调地址
  36. 'debug' => false //调试模式
  37. ];
  38. $this->dispatch = new CregisDispatch(self::$config);
  39. }
  40. /**
  41. * @return static|null
  42. */
  43. public static function make()
  44. {
  45. if (!self::$instance) {
  46. self::$instance = new static();
  47. }
  48. return self::$instance;
  49. }
  50. /**
  51. * 获取支持的币种
  52. * @param bool $showBalance 是否返回余额
  53. * @return mixed
  54. */
  55. public function supportCoins($showBalance = true)
  56. {
  57. try{
  58. return $this->dispatch->coinslist($showBalance);
  59. } catch (\Exception $exception) {
  60. $this->error = $exception->getMessage();
  61. return false;
  62. }
  63. }
  64. /**
  65. * HTTP 接口签名
  66. * @param array $params 参数数组
  67. * @return false|string
  68. */
  69. public function makeSign(array $params)
  70. {
  71. if(empty($params)){
  72. return false;
  73. }
  74. ksort($params);
  75. $signStr = '';
  76. foreach ($params as $key => $val){
  77. $signStr .= "{$key}{$val}";
  78. }
  79. $sign = md5(self::$config['api_key'].$signStr);
  80. return $sign;
  81. }
  82. /**
  83. * 创建钱包地址
  84. * @param string $mainCoinType
  85. * @return mixed
  86. */
  87. public function createAddress($mainCoinType = '195')
  88. {
  89. $result = $this->dispatch->createAddress(self::$config['project_no'], $mainCoinType);
  90. $code = isset($result['code']) ? intval($result['code']) : 0;
  91. $address = isset($result['data']['address']) ? trim($result['data']['address']) : '';
  92. if ($code == 200 && $address) {
  93. return $address;
  94. } else {
  95. RedisService::set("caches:cregisPay:createAddress:error_" . date('YmdHis'), ['mainCoinType' => $mainCoinType, 'result' => $result], 7200);
  96. return '';
  97. }
  98. }
  99. /**
  100. * 验证钱包地址合法性
  101. * @param $address 地址
  102. * @param string $mainCoinType 主币
  103. * @return mixed
  104. */
  105. public function checkAddress($address, $mainCoinType = '195')
  106. {
  107. try {
  108. return $this->dispatch->addressLegal(self::$config['project_no'], $mainCoinType, $address);
  109. } catch (\Exception $exception) {
  110. $this->error = $exception->getMessage();
  111. return false;
  112. }
  113. }
  114. /**
  115. * 查询地址是否存在
  116. * @return mixed
  117. */
  118. public function existAddress($address, $mainCoinType = '195')
  119. {
  120. return $this->dispatch->addressInner(self::$config['project_no'], $mainCoinType, $address);
  121. }
  122. /**
  123. * 提币
  124. * @param $address 地址
  125. * @param $amount 金额
  126. * @param $orderNo 单号
  127. * @param string $mainCoinType 主链编号 波场-195,solana-1000
  128. * @param string $coinType 子链或代币合约地址
  129. * @param string $remark 备注
  130. * @return false
  131. */
  132. public function withdraw($address, $amount, $orderNo, $mainCoinType = '1000', $coinType = '', $remark = '')
  133. {
  134. try {
  135. $callback = self::$config['callUrl'];
  136. $tokenAddress = ConfigService::make()->getConfigByCode('solana_usdt_token', 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB');
  137. $coinType = $coinType ? $coinType : $tokenAddress;
  138. RedisService::set("caches:cregisPay:{$orderNo}:withdraw", ['callback'=> $callback,'order_no'=>$orderNo,'amount'=>$amount,'remark'=>$remark,'mainType'=>$mainCoinType,'coinType'=>$address],7200);
  139. return $this->dispatch->payout(self::$config['project_no'], $mainCoinType . '@' . $coinType, $address, $amount, $callback, $orderNo, time(), $remark);
  140. } catch (\Exception $exception) {
  141. $this->error = $exception->getMessage();
  142. return false;
  143. }
  144. }
  145. /**
  146. * 查询订单
  147. * @param $orderNo 交易单号
  148. * @return mixed
  149. */
  150. public function queryOrder($tradeOutNo)
  151. {
  152. try {
  153. return $this->dispatch->payoutQuery(self::$config['project_no'], $tradeOutNo);
  154. } catch (\Exception $exception) {
  155. $this->error = $exception->getMessage();
  156. return false;
  157. }
  158. }
  159. /**
  160. * 充值回调
  161. * @return mixed
  162. */
  163. public function callback()
  164. {
  165. $result = $this->dispatch->changeBackUrl();
  166. RedisService::set("caches:cregisPay:recharge:callback", ['params' => request()->all(), 'result' => $result], 3600);
  167. return $result;
  168. }
  169. /**
  170. * 提现回调
  171. * @return mixed
  172. */
  173. public function withdrawCallBack()
  174. {
  175. $data = file_get_contents('php://input');
  176. $params = $data?json_decode($data, true) : [];
  177. if(empty($params)){
  178. RedisService::set("caches:cregisPay:data_".date('YmdHis'),['params'=> $params,'data'=> $data], 3600);
  179. return 'Callback data error';
  180. }
  181. $getSign = $params['sign'];
  182. $orderNo = isset($params['third_party_id'])? trim($params['third_party_id']) : '';
  183. $sgin = $this->dispatch->generateSign(self::$config['api_key'], $params);
  184. RedisService::set("caches:cregisPay:{$orderNo}:callback", ['params' => request()->all(), 'result' => $params], 7200);
  185. if($getSign!=$sgin){
  186. RedisService::set("caches:cregisPay:{$orderNo}:signCheck",['params'=> request()->all(),'result'=> $params], 3600);
  187. return '';
  188. }
  189. $payStatus = $params['status'] == 0 || $params['status'] == 6? 20 : 30;
  190. $remark = '交易回调成功';
  191. if ($params['status'] == 2) {
  192. $remark = '签名驳回';
  193. } else if ($params['status'] == 4) {
  194. $remark = '审批驳回';
  195. } else if ($params['status'] == 7) {
  196. $remark = '交易失败';
  197. }
  198. $tradeCid = isset($params['cid'])? trim($params['cid']) : '';
  199. $txid = isset($params['txid'])? trim($params['txid']) : '';
  200. $updateData = ['pay_status'=> $payStatus,'hash'=>$txid,'remark'=> $remark];
  201. if($payStatus == 20){
  202. $updateData['pay_at'] = date('Y-m-d H:i:s');
  203. }
  204. if(!BalanceLogModel::where(['order_no'=> $orderNo,'trade_cid'=> $tradeCid,'mark'=>1])->update($updateData)){
  205. RedisService::set("caches:cregisPay:{$orderNo}:failed", ['params' => request()->all(),'data'=>$updateData, 'result' => $params], 7200);
  206. $this->error = 2034;
  207. return '';
  208. }
  209. RedisService::set("caches:cregisPay:{$orderNo}:success", ['params' => request()->all(),'data'=>$updateData, 'result' => $params], 7200);
  210. return 'success';
  211. }
  212. /**
  213. * 回调处理
  214. * @param $params
  215. */
  216. public function catchNotify($params)
  217. {
  218. RedisService::set('caches:cregisPay:notify', $params);
  219. }
  220. }