* @date 2020-01-22 22:37:21 */ declare(strict_types=1); namespace App\Repositories\Service; use App\Exception\ApiException; use App\Jobs\AddPaymentResultJob; use App\Model\PaymentModel; use App\Model\PaymentTypeModel; use App\Model\VipOrderModel; use App\Repositories\CoinsRepository; use App\Repositories\OrderRepository; use App\Repositories\Service\Payment\PaymentInterface; use App\Repositories\Utils\M3u8CacheRepository; use App\Repositories\VipRepository; use Modules\Api\Services\AuthService; use Psr\SimpleCache\CacheInterface; class PaymentService { /** * 获取支付方式信息 * @return mixed */ public function getAllPayments($id = 0) { $key = 'paymentType'; $payments = make(CacheInterface::class)->get($key); if (empty($payments)) { $res = make(CommonService::class)->httpPost(env('PAY_CENTER_URL') . '/api/get/payment', ['data' => ['merchant_code' => env('PAY_CENTER_MERCHANT_CODE'), 'key' => env('PAY_CENTER_KEY')]]); if (empty($res)) { payLogger(__CLASS__, '获取支付列表失败'. $res); return []; } $res = json_decode($res, true); if (empty($res) || empty($res['data'])) { $this->_lastError = '请求异常!'; payLogger(__CLASS__, '支付列表解码异常或者没有返回通道'); return []; } $payments = $res['data']; make(CacheInterface::class)->set($key, $payments); } return $payments; } /** * @return bool */ public function delPaymentCache() { make(CacheInterface::class)->delete('payment'); return true; } /** * @return bool */ public function delPaymentTypeCache() { make(CacheInterface::class)->delete('paymentType'); return true; } /** * 根据金额获取可用的支付网关 * @param float $amount * @return array */ public function getPayGatewayByAmount($amount = 0.0, $deviceType = '', $paymentList = []) { $result = array(); if ($paymentList) { $payGetway = ['支付宝', '微信', '银行卡', '余额', '虚拟币']; foreach ($paymentList as $item) { // 排除(设备 状态) if (!empty($item['belong_device']) && ($deviceType != $item['belong_device'])) { continue; } $tempKey = $item['pay_type'] - 1; // 金额范围 if ($amount > 0) { if ($item['limit_type'] == 2) { $tempArr = explode('-', $item['limit']); if ($amount < $tempArr[0] || $amount > $tempArr[1]) { continue; } } else { $tempArr = explode(',', $item['limit']); if (!in_array($amount, $tempArr)) { continue; } } } $imgUrl = 'f2|/' . env('STATIC_DIR_NAME', 'doukui') . '/pay_type/' . $item['pay_type'] . '_144x144.ceb'; // 选项卡 if (empty($result[$tempKey])) { $result[$tempKey]['name'] = $payGetway[$tempKey]; $result[$tempKey]['img'] = M3u8CacheRepository::getImageUrl($imgUrl); $result[$tempKey]['pay_type'] = $item['pay_type']; } //解析数据 $result[$tempKey]['pay_list'][] = [ 'id' => $item['id'], 'name' => $item['name'], 'img' => M3u8CacheRepository::getImageUrl($imgUrl), 'pay_type' => $item['pay_type'], ]; } if ($result) { ksort($result); $result = array_values($result); } } return $result; } /** * 根据金额获取可用的支付网关(大鲨鱼版) * @param array $amount * @return array */ public function getGatewayByAmount($amount) { $url = 'https://umio.zjcthbkj.com/api/shark/getPayType'; $params = [ 'mercId' => 10070, 'money' => $amount, 'time' => (string)(int)(microtime(true) * 1000), ]; $params['sign'] = md5($params['mercId'] . implode(',', $params['money']) . '442811313797cef2cc857967fdb5f1a9'); $result = make(CommonService::class)->httpPost($url, $params); $result = json_decode($result, true); //记录mongo日志 make(QueueService::class)->addPaymentResultJob($result); $ways = []; if (isset($result['msg'])) { $ways = $result['msg']; } $key = []; foreach ($ways as $w) { $t = []; $w['money'] = floatval($w['money']); foreach ($w['types'] as $k => $v) { $type = substr(strval($v['payMent']), -1); $t[$k]['id'] = $v['type'] . ':' . $type; $t[$k]['name'] = $v['name']; $t[$k]['img'] = 'f2|/' . env('STATIC_DIR_NAME', 'doukui') . '/pay_type/' . $type . '_144x144.ceb'; } $key[round($w['money']) . ''] = $t; } return $key; } /** * 根据支付类型和金额匹配具体支付方式 * @param $payId * @param $amount * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model|\Hyperf\Database\Query\Builder|object|null */ public function getPaymentByAmount($payId, $amount) { $result = null; if ($amount <= 0) { return $result; } //获取合适的支付通道 $result = make(OrderRepository::class)->getPayChannel($payId); //根据金额和权重匹配对应的支付渠道 // $result = $this->weightsAmountChannel($paymentData, $amount); return $result; } /** * 根据金额和权重匹配通道 * * @param $PaymentData * @param $amount * @return mixed */ private function weightsAmountChannel($PaymentData, $amount) { $channel = []; $amount = (int)$amount; foreach ($PaymentData as $item) { //获取合适范围内的通道 switch ($item->limit_type) { case 1: //固定金额 $limitMap = explode(',', $item->limit); if (in_array($amount, $limitMap)) { $channel[] = $item; } break; case 2: //范围金额 $limitMap = explode('-', $item->limit); if ($amount >= $limitMap[0] && $amount < $limitMap[1]) { $channel[] = $item; } break; } } $res = []; if (!empty($channel)) { //通过权重匹配通道 $res = countWeight($channel); } return $res; } /** * 请求支付中心获取支付网关 * @param object $order * @return string */ public function getGateway($order, $payId) { $payData = array( 'orderSn' => $order->order_sn, 'orderId' => $order->id, 'money' => $order->real_amount, 'type' => $order->order_type, 'payId' => $payId ); $result = PaymentInterface::factory('Paycenter')->createPayLink($payData); if ($result) { return $result; } throw new ApiException('亲,换个支付方式试试呢?'); } /** * 支付异步通知 * @param int $orderId * @param string $orderType * @param string $gateway */ public function notify($orderId, $orderType) { logger(json_encode(request()->all()) . '发送回调信息!'); if (!$orderId || !$orderType) { throw new ApiException('参数错误'); } //我方订单号 $orderSn = ''; //交易单号(三方单号) $tradeNo = ''; //订单金额 $money = ''; $result = PaymentInterface::factory('Paycenter')->notify($orderSn, $tradeNo, $money); if ($result) { if ($orderType == 1) { //vip $result = make(VipRepository::class) ->doBuy($orderId, $tradeNo, $money, $orderType); } else { //金币 $result = make(CoinsRepository::class)->doBuy($orderId, $tradeNo, $money); } } if ($result) { return 'SUCCESS'; } return 'nook'; } }