1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-07-23 00:16:39 +08:00

整理代码

This commit is contained in:
xiaochong0302 2020-05-11 19:50:28 +08:00
parent 089db7e168
commit 1280283818
27 changed files with 546 additions and 325 deletions

View File

@ -55,6 +55,9 @@ class OrderTask extends Task
case OrderModel::ITEM_VIP:
$this->handleVipOrder($order);
break;
case OrderModel::ITEM_REWARD:
$this->handleRewardOrder($order);
break;
}
$task->status = TaskModel::STATUS_FINISHED;
@ -162,6 +165,14 @@ class OrderTask extends Task
}
}
/**
* @param OrderModel $order
*/
protected function handleRewardOrder(OrderModel $order)
{
}
/**
* @param OrderModel $order
*/

View File

@ -176,23 +176,14 @@ class TestController extends Controller
$order = $alipayTestService->createOrder();
$trade = $alipayTestService->createTrade($order);
$code = $alipayTestService->scan($trade);
$codeUrl = $alipayTestService->scan($trade);
if ($order && $trade && $code) {
if ($order && $trade && $codeUrl) {
$this->db->commit();
} else {
$this->db->rollback();
}
$codeUrl = null;
if (!empty($code)) {
$codeUrl = $this->url->get(
['for' => 'web.qrcode_img'],
['text' => urlencode($code)]
);
}
$this->view->pick('setting/pay_alipay_test');
$this->view->setVar('trade_sn', $trade->sn);
$this->view->setVar('code_url', $codeUrl);

View File

@ -17,9 +17,18 @@ class AlipayTest extends PayTest
{
$alipayService = new AlipayService();
$qrcode = $alipayService->scan($trade);
$code = $alipayService->scan($trade);
return $qrcode ?: false;
$codeUrl = null;
if ($code) {
$codeUrl = $this->url->get(
['for' => 'web.qrcode_img'],
['text' => urlencode($code)]
);
}
return $codeUrl ?: false;
}
public function status($tradeNo)

View File

@ -34,7 +34,11 @@ class OrderController extends Controller
$order = $service->handle();
return $this->jsonSuccess(['sn' => $order->sn]);
$service = new OrderInfoService();
$order = $service->handle($order->sn);
return $this->jsonSuccess(['order' => $order]);
}
/**

View File

@ -1,74 +0,0 @@
<?php
namespace App\Http\Web\Controllers;
use App\Services\Pay\Alipay as AlipayService;
use App\Services\Pay\Wxpay as WxpayService;
use App\Traits\Response as ResponseTrait;
class PayController extends \Phalcon\Mvc\Controller
{
use ResponseTrait;
/**
* @Post("/alipay/notify", name="web.alipay.notify")
*/
public function alipayNotifyAction()
{
$alipayService = new AlipayService();
$response = $alipayService->notify();
if (!$response) exit;
$response->send();
exit;
}
/**
* @Post("/wxpay/notify", name="web.wxpay.notify")
*/
public function wxpayNotifyAction()
{
$wxpayService = new WxpayService();
$response = $wxpayService->notify();
if (!$response) exit;
$response->send();
exit;
}
/**
* @Post("/alipay/status", name="web.alipay.status")
*/
public function alipayStatusAction()
{
$sn = $this->request->getPost('sn');
$alipayService = new AlipayService();
$status = $alipayService->status($sn);
return $this->jsonSuccess(['status' => $status]);
}
/**
* @Post("/wxpay/status", name="web.wxpay.status")
*/
public function wxpayStatusAction()
{
$sn = $this->request->getPost('sn');
$wxpayService = new WxpayService();
$status = $wxpayService->status($sn);
return $this->jsonSuccess(['status' => $status]);
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Refund\RefundCancel as RefundCancelService;
use App\Services\Frontend\Refund\RefundConfirm as RefundConfirmService;
use App\Services\Frontend\Refund\RefundCreate as RefundCreateService;
use App\Services\Frontend\Refund\RefundInfo as RefundInfoService;
/**
* @RoutePrefix("/refund")
*/
class RefundController extends Controller
{
/**
* @Get("/confirm", name="web.refund.confirm")
*/
public function confirmAction()
{
$service = new RefundConfirmService();
$info = $service->handle();
$this->view->setVar('info', $info);
}
/**
* @Post("/create", name="web.refund.create")
*/
public function createAction()
{
$service = new RefundCreateService();
$refund = $service->handle();
$service = new RefundInfoService();
$refund = $service->handle($refund->sn);
return $this->jsonSuccess(['refund' => $refund]);
}
/**
* @Get("/{sn:[0-9]+}/info", name="web.refund.info")
*/
public function infoAction($sn)
{
$service = new RefundInfoService();
$refund = $service->handle($sn);
return $this->jsonSuccess(['refund' => $refund]);
}
/**
* @Post("/{sn:[0-9]+}/cancel", name="web.refund.cancel")
*/
public function cancelAction($sn)
{
$service = new RefundCancelService();
$refund = $service->handle($sn);
return $this->jsonSuccess(['refund' => $refund]);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Http\Web\Controllers;
use App\Services\Frontend\Trade\TradeCreate as TradeCreateService;
use App\Http\Web\Services\Trade as TradeService;
use App\Services\Frontend\Trade\TradeInfo as TradeInfoService;
/**
@ -16,14 +16,11 @@ class TradeController extends Controller
*/
public function createAction()
{
$service = new TradeCreateService();
$service = new TradeService();
$result = $service->handle();
$content = $service->create();
return $this->jsonSuccess([
'trade_sn' => $result['trade_sn'],
'code_url' => $result['code_url'],
]);
return $this->jsonSuccess($content);
}
/**

View File

@ -0,0 +1,59 @@
<?php
namespace App\Http\Web\Services;
use App\Exceptions\BadRequest as BadRequestException;
use App\Models\Trade as TradeModel;
use App\Services\Frontend\Trade\TradeCreate as TradeCreateService;
use App\Services\Pay\Alipay as AlipayService;
class Trade extends Service
{
public function create()
{
$this->db->begin();
$service = new TradeCreateService();
$trade = $service->handle();
$qrCodeUrl = $this->getQrCodeUrl($trade);
if ($trade && $qrCodeUrl) {
$this->db->commit();
return [
'sn' => $trade->sn,
'channel' => $trade->channel,
'qrcode_url' => $qrCodeUrl,
];
} else {
$this->db->rollback();
throw new BadRequestException('trade.create_failed');
}
}
protected function getQrCodeUrl(TradeModel $trade)
{
$qrCodeUrl = null;
$alipayService = new AlipayService();
$text = $alipayService->scan($trade);
if ($text) {
$qrCodeUrl = $this->url->get(
['for' => 'web.qrcode_img'],
['text' => urlencode($text)]
);
}
return $qrCodeUrl;
}
}

View File

@ -34,21 +34,21 @@ class OrderConfirm extends Service
$course = $validator->checkCourse($itemId);
$result['item_info']['course'] = $this->handleCourse($course);
$result['item_info']['course'] = $this->handleCourseInfo($course);
$result['amount'] = $user->vip ? $course->vip_price : $course->market_price;
} elseif ($itemType == OrderModel::ITEM_PACKAGE) {
$package = $validator->checkPackage($itemId);
$result['item_info']['package'] = $this->handlePackage($package);
$result['item_info']['package'] = $this->handlePackageInfo($package);
$result['amount'] = $user->vip ? $package->vip_price : $package->market_price;
} elseif ($itemType == OrderModel::ITEM_VIP) {
$vip = $validator->checkVip($itemId);
$result['item_info']['vip'] = $this->handleVip($vip);
$result['item_info']['vip'] = $this->handleVipInfo($vip);
$result['amount'] = $vip->price;
} elseif ($itemType == OrderModel::ITEM_REWARD) {
@ -58,8 +58,8 @@ class OrderConfirm extends Service
$course = $validator->checkCourse($courseId);
$reward = $validator->checkReward($rewardId);
$result['item_info']['course'] = $this->handleCourse($course);
$result['item_info']['reward'] = $this->handleReward($reward);
$result['item_info']['course'] = $this->handleCourseInfo($course);
$result['item_info']['reward'] = $this->handleRewardInfo($reward);
$result['amount'] = $reward->price;
}
@ -68,12 +68,12 @@ class OrderConfirm extends Service
return $result;
}
protected function handleCourse(CourseModel $course)
protected function handleCourseInfo(CourseModel $course)
{
return $this->formatCourse($course);
return $this->formatCourseInfo($course);
}
protected function handlePackage(PackageModel $package)
protected function handlePackageInfo(PackageModel $package)
{
$result = [
'id' => $package->id,
@ -87,13 +87,13 @@ class OrderConfirm extends Service
$courses = $packageRepo->findCourses($package->id);
foreach ($courses as $course) {
$result['courses'][] = $this->formatCourse($course);
$result['courses'][] = $this->formatCourseInfo($course);
}
return $result;
}
protected function handleVip(VipModel $vip)
protected function handleVipInfo(VipModel $vip)
{
return [
'id' => $vip->id,
@ -103,7 +103,7 @@ class OrderConfirm extends Service
];
}
protected function handleReward(RewardModel $reward)
protected function handleRewardInfo(RewardModel $reward)
{
return [
'id' => $reward->id,
@ -112,16 +112,15 @@ class OrderConfirm extends Service
];
}
protected function formatCourse(CourseModel $course)
protected function formatCourseInfo(CourseModel $course)
{
$course->cover = kg_ci_img_url($course->cover);
return [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'model' => $course->model,
'level' => $course->level,
'rating' => $course->rating,
'study_expiry' => $course->study_expiry,
'refund_expiry' => $course->refund_expiry,
'market_price' => $course->market_price,

View File

@ -199,6 +199,8 @@ class OrderCreate extends Service
$studyExpiryTime = strtotime("+{$course->study_expiry} months");
$refundExpiryTime = strtotime("+{$course->refund_expiry} days");
$course->cover = CourseModel::getCoverPath($course->cover);
return [
'id' => $course->id,
'title' => $course->title,

View File

@ -23,12 +23,10 @@ class OrderInfo extends Service
$order->item_info = $this->handleItemInfo($order);
return [
'id' => $order->id,
'sn' => $order->sn,
'subject' => $order->subject,
'amount' => $order->amount,
'status' => $order->status,
'user_id' => $order->user_id,
'item_id' => $order->item_id,
'item_type' => $order->item_type,
'item_info' => $order->item_info,
@ -43,30 +41,37 @@ class OrderInfo extends Service
*/
$itemInfo = $order->item_info;
if ($order->item_type == OrderModel::ITEM_COURSE) {
$result = [];
return $this->handleCourseInfo($itemInfo);
} elseif ($order->item_type == OrderModel::ITEM_PACKAGE) {
return $this->handlePackageInfo($itemInfo);
} elseif ($order->item_type == OrderModel::ITEM_VIP) {
return $this->handleVipInfo($itemInfo);
switch ($order->item_type) {
case OrderModel::ITEM_COURSE:
$result = $this->handleCourseInfo($itemInfo);
break;
case OrderModel::ITEM_PACKAGE:
$result = $this->handlePackageInfo($itemInfo);
break;
case OrderModel::ITEM_VIP:
$result = $this->handleVipInfo($itemInfo);
break;
case OrderModel::ITEM_REWARD:
$result = $this->handleRewardInfo($itemInfo);
break;
case OrderModel::ITEM_TEST:
$result = $this->handleTestInfo($itemInfo);
break;
}
return $itemInfo;
return $result ?: new \stdClass();
}
protected function handleCourseInfo(array $itemInfo)
protected function handleCourseInfo($itemInfo)
{
$itemInfo['course']['cover'] = kg_ci_img_url($itemInfo['course']['cover']);
return $itemInfo;
}
protected function handlePackageInfo(array $itemInfo)
protected function handlePackageInfo($itemInfo)
{
$baseUrl = kg_ci_base_url();
@ -77,7 +82,17 @@ class OrderInfo extends Service
return $itemInfo;
}
protected function handleVipInfo(array $itemInfo)
protected function handleVipInfo($itemInfo)
{
return $itemInfo;
}
protected function handleRewardInfo($itemInfo)
{
return $itemInfo;
}
protected function handleTestInfo($itemInfo)
{
return $itemInfo;
}

View File

@ -1,35 +0,0 @@
<?php
namespace App\Services\Frontend\Pay;
use App\Models\Trade as TradeModel;
use App\Services\Frontend\Service;
use App\Services\Pay\Alipay as AlipayService;
class Alipay extends Service
{
public function scan(TradeModel $trade)
{
$qrCodeUrl = null;
$alipayService = new AlipayService();
$text = $alipayService->scan($trade);
if ($text) {
$qrCodeUrl = $this->url->get(
['for' => 'web.qrcode_img'],
['text' => urlencode($text)]
);
}
return $qrCodeUrl;
}
public function wap(TradeModel $trade)
{
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace App\Services\Frontend\Pay;
use App\Services\Frontend\Service;
class Wxpay extends Service
{
public function scan()
{
}
public function wap()
{
}
public function mini()
{
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Services\Frontend\Refund;
use App\Models\Refund as RefundModel;
use App\Services\Frontend\RefundTrait;
use App\Services\Frontend\Service;
use App\Validators\Refund as RefundValidator;
class RefundCancel extends Service
{
use RefundTrait;
public function handle($sn)
{
$refund = $this->checkRefundBySn($sn);
$user = $this->getLoginUser();
$validator = new RefundValidator();
$validator->checkOwner($user->id, $refund->user_id);
$refund->status = RefundModel::STATUS_CANCELED;
$refund->update();
return $refund;
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Services\Frontend\Refund;
use App\Models\Refund as RefundModel;
use App\Services\Frontend\OrderTrait;
use App\Services\Frontend\Service;
class RefundConfirm extends Service
{
use OrderTrait;
public function handle()
{
$sn = $this->request->getQuery('order_sn');
$order = $this->checkOrderBySn($sn);
}
protected function handleRefund(RefundModel $refund)
{
return [
'sn' => $refund->sn,
'subject' => $refund->subject,
'amount' => $refund->amount,
'status' => $refund->status,
'apply_note' => $refund->apply_note,
'review_note' => $refund->review_note,
'create_time' => $refund->create_time,
];
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Services\Frontend\Refund;
use App\Models\Refund as RefundModel;
use App\Services\Frontend\OrderTrait;
use App\Services\Frontend\Service;
use App\Services\Refund as RefundService;
use App\Validators\Order as OrderValidator;
use App\Validators\Refund as RefundValidator;
class RefundCreate extends Service
{
use OrderTrait;
public function handle()
{
$post = $this->request->getPost();
$order = $this->checkOrderBySn($post['order_sn']);
$user = $this->getLoginUser();
$validator = new OrderValidator();
$validator->checkIfAllowRefund($order);
$refundService = new RefundService();
$refundAmount = $refundService->getRefundAmount($order);
$validator = new RefundValidator();
$validator->checkAmount($order->amount, $refundAmount);
$applyNote = $validator->checkApplyNote($post['apply_note']);
$refund = new RefundModel();
$refund->subject = $order->subject;
$refund->amount = $order->amount;
$refund->apply_note = $applyNote;
$refund->order_id = $order->id;
$refund->trade_id = $order->id;
$refund->user_id = $user->id;
$refund->create();
return $refund;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Services\Frontend\Refund;
use App\Models\Refund as RefundModel;
use App\Services\Frontend\RefundTrait;
use App\Services\Frontend\Service;
class RefundInfo extends Service
{
use RefundTrait;
public function handle($sn)
{
$refund = $this->checkRefundBySn($sn);
return $this->handleRefund($refund);
}
protected function handleRefund(RefundModel $refund)
{
return [
'sn' => $refund->sn,
'subject' => $refund->subject,
'amount' => $refund->amount,
'apply_note' => $refund->apply_note,
'review_note' => $refund->review_note,
'status' => $refund->status,
'create_time' => $refund->create_time,
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Services\Frontend;
use App\Validators\Refund as RefundValidator;
trait RefundTrait
{
public function checkRefundById($id)
{
$validator = new RefundValidator();
return $validator->checkRefund($id);
}
public function checkRefundBySn($id)
{
$validator = new RefundValidator();
return $validator->checkRefundBySn($id);
}
}

View File

@ -5,8 +5,6 @@ namespace App\Services\Frontend\Trade;
use App\Models\Trade as TradeModel;
use App\Services\Frontend\OrderTrait;
use App\Services\Frontend\Service;
use App\Services\Pay\Alipay as AlipayService;
use App\Services\Pay\Wxpay as WxPayService;
use App\Validators\Trade as TradeValidator;
class TradeCreate extends Service
@ -26,62 +24,17 @@ class TradeCreate extends Service
$channel = $validator->checkChannel($post['channel']);
try {
$trade = new TradeModel();
$this->db->begin();
$trade->subject = $order->subject;
$trade->amount = $order->amount;
$trade->channel = $channel;
$trade->order_id = $order->id;
$trade->user_id = $user->id;
$trade = new TradeModel();
$trade->create();
$trade->subject = $order->subject;
$trade->amount = $order->amount;
$trade->channel = $channel;
$trade->order_id = $order->id;
$trade->user_id = $user->id;
$trade->create();
$qrCodeUrl = $this->getQrCodeUrl($trade);
$this->db->commit();
return [
'trade_sn' => $trade->sn,
'code_url' => $qrCodeUrl,
];
} catch (\Exception $e) {
$this->db->rollback();
throw new \RuntimeException('trade.create_failed');
}
}
protected function getQrCodeUrl(TradeModel $trade)
{
$qrCodeUrl = null;
if ($trade->channel == TradeModel::CHANNEL_ALIPAY) {
$alipayService = new AlipayService();
$text = $alipayService->scan($trade);
if ($text) {
$qrCodeUrl = $this->url->get(
['for' => 'web.qrcode_img'],
['text' => urlencode($text)]
);
}
} elseif ($trade->channel == TradeModel::CHANNEL_WXPAY) {
$wxpayService = new WxPayService();
$qrCodeUrl = $wxpayService->scan($trade);
}
return $qrCodeUrl;
return $trade;
}
}

View File

@ -21,7 +21,6 @@ class TradeInfo extends Service
protected function handleTrade(TradeModel $trade)
{
return [
'id' => $trade->id,
'sn' => $trade->sn,
'subject' => $trade->subject,
'amount' => $trade->amount,

View File

@ -31,6 +31,13 @@ abstract class Pay extends Service
*/
abstract public function scan(TradeModel $trade);
/**
* h5下单
*
* @param TradeModel $trade
*/
abstract public function wap(TradeModel $trade);
/**
* 异步通知
*/

View File

@ -6,6 +6,7 @@ use App\Models\Refund as RefundModel;
use App\Models\Trade as TradeModel;
use App\Repos\Trade as TradeRepo;
use App\Services\Pay as PayService;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
use Yansongda\Pay\Gateways\Alipay as AlipayGateway;
use Yansongda\Pay\Log;
use Yansongda\Pay\Pay;
@ -19,16 +20,19 @@ class Alipay extends PayService
*/
protected $settings;
/**
* @var AlipayGateway
*/
protected $gateway;
public function __construct()
{
$this->settings = $this->getSectionSettings('pay.alipay');
}
$this->gateway = $this->getGateway();
public function setReturnUrl($returnUrl)
{
$this->settings['return_url'] = $returnUrl;
}
public function setNotifyUrl($notifyUrl)
{
$this->settings['notify_url'] = $notifyUrl;
}
/**
@ -39,9 +43,11 @@ class Alipay extends PayService
*/
public function scan(TradeModel $trade)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->scan([
$response = $gateway->scan([
'out_trade_no' => $trade->sn,
'total_amount' => $trade->amount,
'subject' => $trade->subject,
@ -66,23 +72,23 @@ class Alipay extends PayService
* 移动端支付
*
* @param TradeModel $trade
* @return bool|string
* @return HttpResponse|bool
*/
public function wap(TradeModel $trade)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->wap([
return $gateway->wap([
'out_trade_no' => $trade->sn,
'total_amount' => $trade->amount,
'subject' => $trade->subject,
]);
$result = $response->qr_code ?? false;
} catch (\Exception $e) {
Log::error('Alipay Qrcode Exception', [
Log::error('Alipay Wap Exception', [
'code' => $e->getCode(),
'message' => $e->getMessage(),
]);
@ -95,12 +101,15 @@ class Alipay extends PayService
/**
* 异步通知
* @return HttpResponse|bool
*/
public function notify()
{
$gateway = $this->getGateway();
try {
$data = $this->gateway->verify();
$data = $gateway->verify();
Log::debug('Alipay Verify Data', $data->all());
@ -142,7 +151,7 @@ class Alipay extends PayService
$this->eventsManager->fire('pay:afterPay', $this, $trade);
return $this->gateway->success();
return $gateway->success();
}
/**
@ -154,11 +163,13 @@ class Alipay extends PayService
*/
public function find($outTradeNo, $type = 'wap')
{
$gateway = $this->getGateway();
try {
$order = ['out_trade_no' => $outTradeNo];
$result = $this->gateway->find($order, $type);
$result = $gateway->find($order, $type);
} catch (\Exception $e) {
@ -181,11 +192,11 @@ class Alipay extends PayService
*/
public function close($outTradeNo)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->close([
'out_trade_no' => $outTradeNo,
]);
$response = $gateway->close(['out_trade_no' => $outTradeNo]);
$result = $response->code == '10000';
@ -210,11 +221,11 @@ class Alipay extends PayService
*/
public function cancel($outTradeNo)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->cancel([
'out_trade_no' => $outTradeNo,
]);
$response = $gateway->cancel(['out_trade_no' => $outTradeNo]);
$result = $response->code == '10000';
@ -239,13 +250,15 @@ class Alipay extends PayService
*/
public function refund(RefundModel $refund)
{
$gateway = $this->getGateway();
try {
$tradeRepo = new TradeRepo();
$trade = $tradeRepo->findById($refund->trade_id);
$response = $this->gateway->refund([
$response = $gateway->refund([
'out_trade_no' => $trade->sn,
'out_request_no' => $refund->sn,
'refund_amount' => $refund->amount,
@ -281,6 +294,7 @@ class Alipay extends PayService
'app_id' => $this->settings['app_id'],
'ali_public_key' => $this->settings['public_key'],
'private_key' => $this->settings['private_key'],
'return_url' => $this->settings['return_url'],
'notify_url' => $this->settings['notify_url'],
'log' => [
'file' => log_path('alipay.log'),

View File

@ -6,6 +6,7 @@ use App\Models\Refund as RefundModel;
use App\Models\Trade as TradeModel;
use App\Repos\Trade as TradeRepo;
use App\Services\Pay as PayService;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
use Yansongda\Pay\Gateways\Wechat as WechatGateway;
use Yansongda\Pay\Log;
use Yansongda\Pay\Pay;
@ -19,16 +20,14 @@ class Wxpay extends PayService
*/
protected $settings;
/**
* @var WechatGateway
*/
protected $gateway;
public function __construct()
{
$this->settings = $this->getSectionSettings('pay.wxpay');
}
$this->gateway = $this->getGateway();
public function setNotifyUrl($notifyUrl)
{
$this->settings['notify_url'] = $notifyUrl;
}
/**
@ -39,9 +38,11 @@ class Wxpay extends PayService
*/
public function scan(TradeModel $trade)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->scan([
$response = $gateway->scan([
'out_trade_no' => $trade->sn,
'total_fee' => 100 * $trade->amount,
'body' => $trade->subject,
@ -62,14 +63,49 @@ class Wxpay extends PayService
return $result;
}
/**
* 移动端支付
*
* @param TradeModel $trade
* @return HttpResponse|bool
*/
public function wap(TradeModel $trade)
{
$gateway = $this->getGateway();
try {
return $gateway->wap([
'out_trade_no' => $trade->sn,
'total_fee' => 100 * $trade->amount,
'body' => $trade->subject,
]);
} catch (\Exception $e) {
Log::error('Wxpay Wap Exception', [
'code' => $e->getCode(),
'message' => $e->getMessage(),
]);
$result = false;
}
return $result;
}
/**
* 异步通知
*
* @return HttpResponse|bool
*/
public function notify()
{
$gateway = $this->getGateway();
try {
$data = $this->gateway->verify();
$data = $gateway->verify();
Log::debug('Wxpay Verify Data', $data->all());
@ -109,7 +145,7 @@ class Wxpay extends PayService
$this->eventsManager->fire('pay:afterPay', $this, $trade);
return $this->gateway->success();
return $gateway->success();
}
/**
@ -121,11 +157,13 @@ class Wxpay extends PayService
*/
public function find($outTradeNo, $type = 'wap')
{
$gateway = $this->getGateway();
try {
$order = ['out_trade_no' => $outTradeNo];
$result = $this->gateway->find($order, $type);
$result = $gateway->find($order, $type);
} catch (\Exception $e) {
@ -148,11 +186,11 @@ class Wxpay extends PayService
*/
public function close($outTradeNo)
{
$gateway = $this->getGateway();
try {
$response = $this->gateway->close([
'out_trade_no' => $outTradeNo,
]);
$response = $gateway->close(['out_trade_no' => $outTradeNo]);
$result = $response->result_code == 'SUCCESS';
@ -188,13 +226,15 @@ class Wxpay extends PayService
*/
public function refund(RefundModel $refund)
{
$gateway = $this->getGateway();
try {
$tradeRepo = new TradeRepo();
$trade = $tradeRepo->findById($refund->trade_id);
$response = $this->gateway->refund([
$response = $gateway->refund([
'out_trade_no' => $trade->sn,
'out_refund_no' => $refund->sn,
'total_fee' => 100 * $trade->amount,

View File

@ -8,11 +8,7 @@ use App\Repos\Course as CourseRepo;
class Refund extends Service
{
/**
* @param OrderModel $order
* @return float
*/
public function getRefundAmount($order)
public function getRefundAmount(OrderModel $order)
{
$amount = 0.00;
@ -29,28 +25,20 @@ class Refund extends Service
return $amount;
}
/**
* @param OrderModel $order
* @return float
*/
protected function getCourseRefundAmount($order)
protected function getCourseRefundAmount(OrderModel $order)
{
/**
* @var array $itemInfo
*/
$itemInfo = $order->item_info;
$course = $itemInfo['course'];
$courseId = $order->item_id;
$userId = $order->user_id;
$amount = $order->amount;
$expireTime = strtotime("+{$course['expiry']} days", $order->create_time);
$refundAmount = 0.00;
if ($expireTime > time()) {
if ($itemInfo['course']['refund_expiry_time'] > time()) {
$percent = $this->getCourseRefundPercent($courseId, $userId);
$refundAmount = $amount * $percent;
}
@ -58,25 +46,19 @@ class Refund extends Service
return $refundAmount;
}
/**
* @param OrderModel $order
* @return float
*/
protected function getPackageRefundAmount($order)
protected function getPackageRefundAmount(OrderModel $order)
{
/**
* @var array $itemInfo
*/
$itemInfo = $order->item_info;
$courses = $itemInfo['courses'];
$userId = $order->user_id;
$amount = $order->amount;
$totalMarketPrice = 0.00;
foreach ($courses as $course) {
foreach ($itemInfo['courses'] as $course) {
$totalMarketPrice += $course['market_price'];
}
@ -85,11 +67,8 @@ class Refund extends Service
/**
* 按照占比方式计算退款
*/
foreach ($courses as $course) {
$expireTime = strtotime("+{$course['expiry']} days", $order->create_time);
if ($expireTime > time()) {
foreach ($itemInfo['courses'] as $course) {
if ($course['refund_expiry_time'] > time()) {
$pricePercent = round($course['market_price'] / $totalMarketPrice, 4);
$refundPercent = $this->getCourseRefundPercent($userId, $course['id']);
$refundAmount = round($amount * $pricePercent * $refundPercent, 2);
@ -100,11 +79,6 @@ class Refund extends Service
return $totalRefundAmount;
}
/**
* @param int $courseId
* @param int $userId
* @return float
*/
protected function getCourseRefundPercent($courseId, $userId)
{
$courseRepo = new CourseRepo();

View File

@ -59,52 +59,52 @@ class Order extends Validator
{
$courseRepo = new CourseRepo();
$item = $courseRepo->findById($itemId);
$course = $courseRepo->findById($itemId);
if (!$item) {
if (!$course) {
throw new BadRequestException('order.item_not_found');
}
return $item;
return $course;
}
public function checkPackage($itemId)
{
$packageRepo = new PackageRepo();
$item = $packageRepo->findById($itemId);
$package = $packageRepo->findById($itemId);
if (!$item) {
if (!$package) {
throw new BadRequestException('order.item_not_found');
}
return $item;
return $package;
}
public function checkVip($itemId)
{
$vipRepo = new VipRepo();
$item = $vipRepo->findById($itemId);
$vip = $vipRepo->findById($itemId);
if (!$item) {
if (!$vip) {
throw new BadRequestException('order.item_not_found');
}
return $item;
return $vip;
}
public function checkReward($itemId)
{
$rewardRepo = new RewardRepo();
$item = $rewardRepo->findById($itemId);
$reward = $rewardRepo->findById($itemId);
if (!$item) {
if (!$reward) {
throw new BadRequestException('order.item_not_found');
}
return $item;
return $reward;
}
public function checkAmount($amount)
@ -118,13 +118,29 @@ class Order extends Validator
return $value;
}
public function checkIfAllowCancel($order)
public function checkIfAllowCancel(OrderModel $order)
{
if ($order->status != OrderModel::STATUS_PENDING) {
throw new BadRequestException('order.cancel_not_allowed');
}
}
public function checkIfAllowRefund(OrderModel $order)
{
if ($order->status != OrderModel::STATUS_FINISHED) {
throw new BadRequestException('order.refund_not_allowed');
}
$types = [
OrderModel::ITEM_COURSE,
OrderModel::ITEM_PACKAGE,
];
if (!in_array($order->item_type, $types)) {
throw new BadRequestException('order.refund_not_allowed');
}
}
public function checkIfBoughtCourse($userId, $courseId)
{
$orderRepo = new OrderRepo();

View File

@ -42,7 +42,10 @@ class Refund extends Validator
public function checkReviewStatus($status)
{
$list = [RefundModel::STATUS_APPROVED, RefundModel::STATUS_REFUSED];
$list = [
RefundModel::STATUS_APPROVED,
RefundModel::STATUS_REFUSED,
];
if (!in_array($status, $list)) {
throw new BadRequestException('refund.invalid_review_status');
@ -51,6 +54,13 @@ class Refund extends Validator
return $status;
}
public function checkAmount($orderAmount, $refundAmount)
{
if ($refundAmount > $orderAmount) {
throw new BadRequestException('refund.invalid_amount');
}
}
public function checkApplyNote($note)
{
$value = $this->filter->sanitize($note, ['trim', 'string']);
@ -85,7 +95,14 @@ class Refund extends Validator
return $value;
}
public function checkIfAllowReview($refund)
public function checkIfAllowCancel(RefundModel $refund)
{
if ($refund->status != RefundModel::STATUS_PENDING) {
throw new BadRequestException('refund.cancel_not_allowed');
}
}
public function checkIfAllowReview(RefundModel $refund)
{
if ($refund->status != RefundModel::STATUS_PENDING) {
throw new BadRequestException('refund.review_not_allowed');

View File

@ -278,6 +278,7 @@ $error['refund.apply_note_too_short'] = '退款原因太短少于2个字符
$error['refund.apply_note_too_long'] = '退款原因太长多于255个字符';
$error['refund.review_note_too_short'] = '审核备注太短少于2个字符';
$error['refund.review_note_too_long'] = '审核备注太长多于255个字符';
$error['refund.cancel_not_allowed'] = '当前不允许取消退款';
$error['refund.review_not_allowed'] = '当前不允许审核退款';
$error['refund.invalid_review_status'] = '无效的审核状态';