class PayRefundServiceImpl implements PayRefundService {

    @Override
    public CommonResult<PayRefundSubmitBO> submitRefund(PayRefundSubmitDTO payRefundSubmitDTO) {
        // 校验 App 是否有效
        PayAppDO payAppDO = payAppService.validPayApp(payRefundSubmitDTO.getAppId());
        // 获得 PayTransactionDO ，并校验其是否存在
        PayTransactionDO payTransaction = payTransactionService.getTransaction(payRefundSubmitDTO.getAppId(), payRefundSubmitDTO.getOrderId());
        if (payTransaction == null) { // 是否存在
            return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
        }
        if (!PayTransactionStatusEnum.SUCCESS.getValue().equals(payTransaction.getStatus())) { // 校验状态，必须是待支付
            return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_STATUS_IS_NOT_SUCCESS.getCode());
        }
        if (payRefundSubmitDTO.getPrice() > payTransaction.getPrice() - payTransaction.getRefundTotal()) { // 金额校验
            return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_REFUND_PRICE_EXCEED.getCode());
        }
        // 获得 PayTransactionExtensionDO ，并校验其是否存在
        PayTransactionExtensionDO payTransactionExtension = payTransactionService.getPayTransactionExtension(payTransaction.getExtensionId());
        if (payTransactionExtension == null) { // 是否存在
            return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_NOT_FOUND.getCode());
        }
        if (!PayTransactionStatusEnum.SUCCESS.getValue().equals(payTransactionExtension.getStatus())) { // 校验状态，必须是待支付
            return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_SUCCESS.getCode());
        }
        // 插入 PayTransactionExtensionDO
        PayRefundDO payRefundDO = PayRefundConvert.INSTANCE.convert(payRefundSubmitDTO)
                .setTransactionId(payTransaction.getId())
                .setRefundCode(generateTransactionCode()) // TODO 芋艿，后续调整
                .setStatus(PayRefundStatus.WAITING.getValue())
                .setNotifyUrl(payAppDO.getRefundNotifyUrl())
                .setRefundChannel(payTransaction.getPayChannel());
        payRefundDO.setCreateTime(new Date());
        payRefundMapper.insert(payRefundDO);
        // 调用三方接口
        AbstractPaySDK paySDK = PaySDKFactory.getSDK(payTransaction.getPayChannel());
        CommonResult<String> invokeResult = paySDK.submitRefund(payRefundDO, payTransactionExtension, null); // TODO 暂时传入 extra = null
        if (invokeResult.isError()) {
            return CommonResult.error(invokeResult);
        }
        // 返回成功
        PayRefundSubmitBO payRefundSubmitBO = new PayRefundSubmitBO()
                .setId(payRefundDO.getId());
        return CommonResult.success(payRefundSubmitBO);
    }

}