Files
xk-api-old-laravel/app/Models/Pay/RefundBill.php
2025-01-11 14:16:20 +08:00

155 lines
5.5 KiB
PHP

<?php
namespace App\Models\Pay;
use App\Models\BaseModel;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
/**
* App\Models\Pay\RefundBill
*
* @property int $id
* @property int $bill_id 支付订单号id
* @property string|null $refund_billable_type 多态模型名称
* @property int|null $refund_billable_id 支付订单号id
* @property string $refund_amount 退款发起金额
* @property string $refund_no 退款商户订单号
* @property string|null $refund_service_no 退款支付商订单号
* @property string|null $refund_at 退款到账时间
* @property int $refund_status 退款状态
* @property string|null $remark 备注
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\Models\Pay\Bill|null $bill 支付单
* @property-read string $created_at_format 创建时间的格式化
* @property-read string $refund_status_string 退款状态名称
* @property-read string $status_string 状态名称
* @property-read string $updated_at_format 更新时间的格式化
* @property-read \Illuminate\Database\Eloquent\Model|\Eloquent $refundBillable
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Pay\RefundBill newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Pay\RefundBill newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Pay\RefundBill query()
* @mixin \Eloquent
*/
class RefundBill extends BaseModel
{
protected $attributes = [
'refund_status' => self::REFUND_STATUS_REFUNDING,
];
// 退款状态
const REFUND_STATUS_LABEL = [
self::REFUND_STATUS_REFUNDING => 'info',
self::REFUND_STATUS_SUCCESS => 'success',
self::REFUND_STATUS_FAIL => 'error',
self::REFUND_STATUS_CANCEL => 'default',
];
const REFUND_STATUS = [
self::REFUND_STATUS_REFUNDING => '退款中',
self::REFUND_STATUS_SUCCESS => '退款成功',
self::REFUND_STATUS_FAIL => '退款失败',
self::REFUND_STATUS_CANCEL => '退款取消',
];
const REFUND_STATUS_REFUNDING = 1;
const REFUND_STATUS_SUCCESS = 2;
const REFUND_STATUS_FAIL = 3;
const REFUND_STATUS_CANCEL = 4;
protected static function boot()
{
parent::boot();
static::creating(function (self $refundBill) {
if (!$refundBill->refund_no) {
$refundBill->refund_no = self::getNewNumber('refund_no');
}
});
}
/**
* @comment 支付单
* @return BelongsTo
*/
public function bill(): BelongsTo
{
return $this->belongsTo(Bill::class, 'bill_id');
}
public function refundBillable(): MorphTo
{
return $this->morphTo();
}
/**
* refund_status_string
*
* @comment 退款状态名称
* @return string
*/
public function getRefundStatusStringAttribute(): string
{
return self::REFUND_STATUS[$this->refund_status] ?? '';
}
/**
* 退款回调通知处理 - 异步.
*
* @param array $data
* @return bool|string
*/
public static function handleNotify(array $data): bool|string
{
/* @var RefundBill $refund */
$refund = self::with('bill')->where('refund_no', $data['refund_no'])->first();
if (!$refund) {
log_i("找不到退款订单信息:退款单 {$data['refund_no']} 支付单 {$data['pay_no']}", 'refund-bill-error', $refund->bill->pay_way_alias);
return '找不到退款订单信息';
}
if ($refund->refund_status != self::REFUND_STATUS_REFUNDING) {
log_i("订单状态非退款中:{$data['refund_no']},订单状态:{$refund->refund_status_string}", 'refund-bill-error', $refund->bill->pay_way_alias);
return '订单状态非退款中';
}
if ($refund->refund_amount != $data['refund_amount']) {
log_i("订单退款金额不一致:{$data['refund_no']},订单金额:{$refund->refund_amount},回调金额:{$data['refund_amount']}", 'refund-bill-error', $refund->bill->pay_way_alias);
return '订单退款金额不一致';
}
$refund->fill([
'refund_service_no' => $data['refund_service_no'],
'refund_at' => $data['refund_at'],
'refund_status' => self::REFUND_STATUS_SUCCESS,
]);
$refund->save();
$refund->bill->load(['refunds' => function (Relation $relation) {
$relation->where('refund_status', self::REFUND_STATUS_SUCCESS);
}]);
$refund->bill->fill([
'pay_status' => $refund->bill->refunds->sum('refund_amount') == $refund->bill->pay_amount
? Bill::PAY_STATUS_REFUND_FULL
: Bill::PAY_STATUS_REFUND_PART
]);
$refund->bill->save();
try {
if ($refund->refund_billable_type && $refund->refund_billable_id) {
$refund->loadMissing(['refundBillable']);
if ($refund->refundBillable) {
$refund->refundBillable->handleRefunded($refund);
}
} else {
$refund->bill->loadMissing(['billable']);
if ($refund->bill->billable) {
$refund->bill->billable->handleRefunded($refund);
}
}
} catch (Exception $exception) {
}
return true;
}
}