|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace App\Service;
|
|
|
|
|
|
|
|
use App\Exception\BusinessException;
|
|
|
|
use App\Helper\Efps\Api;
|
|
|
|
use App\Helper\Efps\Result;
|
|
|
|
use App\Helper\Redis;
|
|
|
|
use App\Helper\RedisKey;
|
|
|
|
use App\Model\App;
|
|
|
|
use App\Model\Order;
|
|
|
|
use App\Model\RefundOrder;
|
|
|
|
use App\Request\ProtocolPayConfirmRequest;
|
|
|
|
use App\Request\ProtocolPayPreRequest;
|
|
|
|
|
|
|
|
class PaymentService extends AbstractService
|
|
|
|
{
|
|
|
|
public function createOrder(App $app, array $params) {
|
|
|
|
$order = new Order();
|
|
|
|
$order->app_id = $app->app_id;
|
|
|
|
$order->out_order_no = $params['outTradeNo'] ?: '';
|
|
|
|
$order->amount = $params['payAmount'] ?: 0;
|
|
|
|
$order->notify_url = $params['notifyUrl'] ?: '';
|
|
|
|
$order->order_info = json_encode($params['orderInfo'] ?: [], JSON_UNESCAPED_UNICODE);
|
|
|
|
return $order;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function handlePayResult(Result $result, Order $order) {
|
|
|
|
if ($result->get('payState') === '00') {
|
|
|
|
$order->status = Order::STATUS_PAYED;
|
|
|
|
$order->fee = $result->get('procedureFee', 0);
|
|
|
|
$order->pay_order_no = $result->get('transactionNo', '');
|
|
|
|
$order->channel_order_no = $result->get('channelOrder', '');
|
|
|
|
$order->payed_at = date('Y-m-d H:i:s');
|
|
|
|
$order->save();
|
|
|
|
} elseif ($result->get('payState') === '01') {
|
|
|
|
$order->status = Order::STATUS_FAILED;
|
|
|
|
$order->error_code = '01';
|
|
|
|
$order->error_msg = '支付失败';
|
|
|
|
$order->payed_at = date('Y-m-d H:i:s');
|
|
|
|
$order->save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function handleRefundResult(Result $result, RefundOrder $order) {
|
|
|
|
if ($result->get('refundState') === '00') {
|
|
|
|
$order->status = RefundOrder::STATUS_REFUND_SUCCESS;
|
|
|
|
$order->fee = $result->get('procedureFee', 0);
|
|
|
|
$order->refunded_at = date('Y-m-d H:i:s');
|
|
|
|
$order->save();
|
|
|
|
} elseif ($result->get('refundState') === '01') {
|
|
|
|
$order->status = RefundOrder::STATUS_REFUND_FAILED;
|
|
|
|
$order->error_code = '01';
|
|
|
|
$order->error_msg = '处理失败';
|
|
|
|
$order->refunded_at = date('Y-m-d H:i:s');
|
|
|
|
$order->save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function generateOrderNo() {
|
|
|
|
$now = time();
|
|
|
|
$key = RedisKey::getGenerateOrderNoKey($now);
|
|
|
|
$incrId = Redis::incr($key);
|
|
|
|
$incrId = '' . $incrId;
|
|
|
|
Redis::expire($key, 5*60);
|
|
|
|
$padLength = 6 - strlen($incrId);
|
|
|
|
$incrId = str_pad($incrId, $padLength, '0', STR_PAD_LEFT);
|
|
|
|
return date('YmdHis', $now) . $incrId;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function protocolPayPreRequest($params)
|
|
|
|
{
|
|
|
|
$req = new ProtocolPayPreRequest($params);
|
|
|
|
$app = $req->getApp();
|
|
|
|
$data = $req->getData();
|
|
|
|
$result = Api::protocolPayPre($data);
|
|
|
|
|
|
|
|
$order = $this->createOrder($app, $data);
|
|
|
|
|
|
|
|
if (!$result->isSuccess()) {
|
|
|
|
$order->status = Order::STATUS_APPLY_FAIL;
|
|
|
|
$order->save();
|
|
|
|
throw new BusinessException($result->getMessage());
|
|
|
|
}
|
|
|
|
$order->token = $result->get('token', '');
|
|
|
|
$order->protocol = $result->get('protocol', '');
|
|
|
|
$order->status = Order::STATUS_WAIT_PAY;
|
|
|
|
$order->save();
|
|
|
|
return $result->getData();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function protocolPayConfirm($params)
|
|
|
|
{
|
|
|
|
$req = new ProtocolPayConfirmRequest($params);
|
|
|
|
$app = $req->getApp();
|
|
|
|
$data = $req->getData();
|
|
|
|
$order = Order::where('app_id', $app->app_id)
|
|
|
|
->where('token', $data['token'])
|
|
|
|
->where('protocol', $data['protocol'])
|
|
|
|
->first();
|
|
|
|
if (!$order) {
|
|
|
|
throw new BusinessException('订单不存在');
|
|
|
|
}
|
|
|
|
$result = Api::protocolPayConfirm($req->getData());
|
|
|
|
if (!$result->isSuccess()) {
|
|
|
|
$order->status = Order::STATUS_FAILED;
|
|
|
|
$order->error_code = $result->getCode();
|
|
|
|
$order->error_msg = $result->getMessage();
|
|
|
|
$order->payed_at = date('Y-m-d H:i:s');
|
|
|
|
$order->save();
|
|
|
|
throw new BusinessException($result->getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
// 00 01 03
|
|
|
|
$this->handlePayResult($result, $order);
|
|
|
|
return $result->getData();
|
|
|
|
}
|
|
|
|
}
|