You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
5.4 KiB
152 lines
5.4 KiB
<?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\Constants\v3\OrderType;
|
|
use App\Constants\v3\Payment;
|
|
use App\Exception\ErrorCodeException;
|
|
use App\Model\v3\Order;
|
|
use App\Model\v3\OrderMain;
|
|
use App\Model\v3\User;
|
|
use App\Service\v3\CcbPay;
|
|
use App\Service\v3\Interfaces\PaymentServiceInterface;
|
|
use Hyperf\Di\Annotation\Inject;
|
|
|
|
/** @var Inject 注解使用 */
|
|
|
|
/**
|
|
* 建行支付
|
|
*/
|
|
class CcbPayService implements PaymentServiceInterface
|
|
{
|
|
/**
|
|
* @Inject
|
|
* @var Log
|
|
*/
|
|
protected Log $log;
|
|
|
|
public function do($globalOrderId, $money, $userId, $notifyUrl)
|
|
{
|
|
try {
|
|
// 待支付的,未超时(15min,900sec)的订单
|
|
$orderMain = OrderMain::where('created_at', '>=', (time() - 900))
|
|
->where(['state' => OrderState::UNPAID, 'global_order_id' => $globalOrderId, 'user_id' => $userId])
|
|
->first();
|
|
|
|
if (empty($orderMain)) {
|
|
throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE, '[支付订单号]' . $globalOrderId);
|
|
}
|
|
|
|
$payMoney = $orderMain->money; // 注:此处单位是元,不是分
|
|
if (env('APP_ENV') != 'prod' && $orderMain->type == OrderType::ONLINE) {
|
|
$payMoney = 0.01;
|
|
}
|
|
|
|
$user = User::select('openid')->find($userId);
|
|
|
|
// 设置分账规则
|
|
$order = Order::with('store:id,card_no')->where('order_main_id', $globalOrderId)->get();
|
|
$parList = [];
|
|
$seqNo = 1;
|
|
foreach ($order as $item) {
|
|
if (!empty($item->store->card_no)) {
|
|
$parList[] = [
|
|
'Seq_No' => $seqNo,
|
|
'Mkt_Mrch_Id' => $item->store->card_no,
|
|
// 'Amt' => 0, // TODO 分账金额
|
|
];
|
|
$seqNo++;
|
|
}
|
|
}
|
|
|
|
$res = CcbPay::getInstance()->gatherPlaceOrder([
|
|
'Ittparty_Jrnl_No' => $globalOrderId,
|
|
'Main_Ordr_No' => $globalOrderId,
|
|
'Ordr_Tamt' => $payMoney, // 订单总金额
|
|
'Txn_Tamt' => $payMoney, // 应付金额
|
|
'Sub_Openid' => $user['openid'],
|
|
'Orderlist' => [
|
|
'Ordr_Amt' => $payMoney, // 订单商品总金额,即应付金额,所有商品订单金额之和等于主订单金额;
|
|
'Cmdty_Ordr_No' => $globalOrderId, // 返显输入接口中的客户方子订单编号
|
|
'Txnamt' => $payMoney, // 消费者实付金额,所有商品订单金额之和等于主交易总金额金额
|
|
'Mkt_Mrch_Id' => env('CCB_MKT_MRCH_ID'), // 商家编号
|
|
'Clrg_Rule_Id' => env('CCB_CLRG_RULE_ID'), // 分账规则编号,1.“Py_Ordr_Tpcd(订单类型)”为“02-消费券购买订单”时该字段无效,可不送;2.走默认分账策略,可不送;3.多个子订单时不可送
|
|
'Parlist' => $parList,
|
|
],
|
|
]);
|
|
|
|
// 保存一下 $res['Py_Trn_No'] 参数,后续退款等都会用到
|
|
$orderMain->py_trn_no = $res['Py_Trn_No'];
|
|
$orderMain->save();
|
|
|
|
// 返回支付参数给前端
|
|
return [
|
|
'appId' => $res['Rtn_Par_Data']['appid'],
|
|
'timeStamp' => $res['Rtn_Par_Data']['timeStamp'],
|
|
'nonceStr' => $res['Rtn_Par_Data']['nonceStr'],
|
|
'package' => $res['Rtn_Par_Data']['package'],
|
|
'signType' => $res['Rtn_Par_Data']['signType'],
|
|
'paySign' => $res['Rtn_Par_Data']['paySign'],
|
|
'order_main_id' => $globalOrderId,
|
|
];
|
|
} catch (\Exception $e) {
|
|
$this->log->event(LogLabel::ORDER_PAYMENT_LOG, ['payment_do_exception_msg' => $e->getMessage()]);
|
|
throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[稍后重试]');
|
|
}
|
|
}
|
|
|
|
public function check()
|
|
{
|
|
// TODO: Implement check() method.
|
|
}
|
|
|
|
/**
|
|
* 退款的整单,用户申请的退款
|
|
* @param $globalOrderId
|
|
* @param $userId
|
|
* @return bool
|
|
*/
|
|
public function undo($globalOrderId, $userId)
|
|
{
|
|
try{
|
|
// 已支付的,未退款的,使用微信(或建行)支付的订单
|
|
$orderMain = OrderMain::query()
|
|
->whereIn('state', [OrderState::PAID, OrderState::DELIVERY, OrderState::COMPLETED, OrderState::EVALUATED, OrderState::REFUNDING])
|
|
->where(['global_order_id' => $globalOrderId, 'user_id' => $userId, 'pay_type' => Payment::WECHAT, 'refund_time' => 0])
|
|
->first();
|
|
|
|
if (empty($orderMain)) {
|
|
throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE, '[支付订单号]' . $globalOrderId);
|
|
}
|
|
|
|
$result = CcbPay::getInstance()->refundOrder([
|
|
'Ittparty_Jrnl_No' => $globalOrderId,
|
|
'Py_Trn_No' => $orderMain->py_trn_no,
|
|
]);
|
|
|
|
if (!isset($result['Refund_Rsp_St'])) { // 接口返回异常
|
|
throw new ErrorCodeException(ErrorCode::REFUND_PAYMENT_FAIL, '退款异常,操作失败');
|
|
} else if ($result['Refund_Rsp_St'] == '01') {
|
|
throw new ErrorCodeException(ErrorCode::REFUND_PAYMENT_FAIL, '退款失败');
|
|
} else if ($result['Refund_Rsp_St'] == '02') {
|
|
throw new ErrorCodeException(ErrorCode::REFUND_PAYMENT_FAIL, '退款延迟等待');
|
|
} else if ($result['Refund_Rsp_St'] == '03') {
|
|
throw new ErrorCodeException(ErrorCode::REFUND_PAYMENT_FAIL, '退款结果不确定,请稍后查看退款结果');
|
|
}
|
|
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
$this->log->event(LogLabel::ORDER_REFUND_LOG, ['payment_do_exception_msg' => $e->getMessage()]);
|
|
throw new ErrorCodeException(ErrorCode::REFUND_PAYMENT_FAIL);
|
|
}
|
|
}
|
|
|
|
public function payToWx($money, $tradeNo, $openId, $userName, $desc = '', $checkName = 'NO_CHECK')
|
|
{
|
|
throw new ErrorCodeException(500, 'payToWx未实现');
|
|
}
|
|
}
|