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