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

<?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未实现');
}
}