|
|
<?php
namespace App\Service\v3\Implementations;
use App\Commons\Log;use App\Constants\v3\ErrorCode;use App\Constants\v3\LogLabel;use App\Constants\v3\OrderState;use App\Exception\ErrorCodeException;use App\Model\v3\OrderMain;use App\Model\v3\User;use App\Service\v3\Interfaces\GoodsActivityServiceInterface;use App\Service\v3\Interfaces\PaymentServiceInterface;use EasyWeChat\Factory;use Hyperf\Guzzle\CoroutineHandler;use Hyperf\Di\Annotation\Inject;
class PaymentService implements PaymentServiceInterface{ /** * @Inject * @var Log */ protected $log;
/** * @Inject * @var GoodsActivityServiceInterface */ protected $goodsActivityService;
public function do($globalOrderId, $money, $userId, $notifyUrl) {
try {
$config = config('wxpay'); $app = Factory::payment($config); $app['guzzle_handler'] = CoroutineHandler::class;
// 待支付的,未超时(15min,900sec)的订单
$orderMain = OrderMain::query() ->where(['state' => OrderState::UNPAID, 'global_order_id' => $globalOrderId, 'user_id' => $userId]) ->where('created_at', '>=', (time()-900)) ->first();
if (empty($orderMain)) { throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE, '[支付订单号]'.$globalOrderId); }
$payMoney = bcmul((string)$orderMain->money, 100, 0); if (env('APP_ENV') != 'prod') { $payMoney = 1; }
$user = User::select('openid')->find($userId); $result = $app->order->unify([ 'body' => '懒族生活', 'out_trade_no' => $orderMain->global_order_id, 'total_fee' => $payMoney, 'notify_url' => $notifyUrl, 'trade_type' => 'JSAPI', 'openid' => $user['openid'], ]);
if ($result['return_code'] == 'FAIL') { throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$result['return_msg']); }
// 返回支付参数给前端
$parameters = [ 'appId' => $result['appid'], 'timeStamp' => '' . time() . '', 'nonceStr' => uniqid(), 'package' => 'prepay_id=' . $result['prepay_id'], 'signType' => 'MD5' ];
$parameters['paySign'] = $this->signture($parameters, $config['key']);
return $parameters;
} catch (\Exception $e) { $this->log->event(LogLabel::ORDER_PAYMENT_LOG, ['payment_exception_msg' => $e->getMessage()]); throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$e->getMessage()); } }
public function check() { // TODO: Implement check() method.
}
public function undo() { // TODO: Implement undo() method.
}
/** * 支付参数加签 * @param $parameters * @param $key * @return string */ private function signture($parameters, $key) { // 按字典序排序参数
ksort($parameters);
// http_query
$queryParams = $this->http_query($parameters);
// 加入KEY
$queryParams = $queryParams . "&key=" . $key;
// MD5加密
$queryParams = md5($queryParams);
// 字符转为大写
return strtoupper($queryParams); }
/** * 参数转为http query字串 * @param $parameters * @return string */ private function http_query($parameters) {
$http_query = []; foreach ($parameters as $key => $value) { $http_query[] = $key.'='.$value; }
return implode('&', $http_query); }}
|