155 lines
5.5 KiB
PHP
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;
|
|
}
|
|
}
|