'未支付', self::STATUS_SUCCESS => '支付成功', self::STATUS_FAIL => '支付失败', self::STATUS_REFUND => '转入退款', self::STATUS_CLOSED => '支付关闭', self::STATUS_REVOKED => '支付撤销', self::STATUS_ERROR => '支付错误', self::STATUS_FINISHED => '支付完结', ]; const STATUS_LABEL_MAP = [ self::STATUS_NOPAY => 'default', self::STATUS_SUCCESS => 'success', self::STATUS_FAIL => 'warning', self::STATUS_REFUND => 'info', self::STATUS_CLOSED => 'primary', self::STATUS_REVOKED => 'primary', self::STATUS_ERROR => 'danger', self::STATUS_FINISHED => 'success', ]; /** * 支付方式 */ const DRIVER_ALIPAY = 'alipay'; const DRIVER_WECHAT = 'wechat'; const DRIVER_SCORE = 'score'; const DRIVER_MAP = [ self::DRIVER_ALIPAY => '支付宝', self::DRIVER_WECHAT => '微信支付', self::DRIVER_SCORE => '水滴支付', ]; const DRIVER_LABEL_MAP = [ self::DRIVER_ALIPAY => 'info', self::DRIVER_WECHAT => 'success', ]; protected static function boot() { parent::boot(); self::creating(function ($model) { $time = explode(' ', microtime()); $counter = $model->whereDate('created_at', Carbon::today())->count() + 1; $len = Setting::orderByDesc('in_use')->value('trade_id_counter_length'); $len = $len < 6 ? 6 : $len; $len = $len > 16 ? 16 : $len; $model->trade_id = date('YmdHis'). sprintf('%06d', $time[0] * 1e6). sprintf('%0'.$len.'d', $counter); $model->state = self::STATUS_NOPAY; }); } /** * Notes: 支付渠道 * * @Author: 玄尘 * @Date : 2021/5/18 11:14 * @return string */ public function getDriverTextAttribute(): string { return self::DRIVER_MAP[$this->driver]; } /** * Notes: 支付状态 * * @Author: 玄尘 * @Date : 2021/5/18 11:17 * @return string */ public function getStateTextAttribute(): string { return self::STATUS_MAP[$this->state]; } /** * Notes : 要支付的模型 * * @Date : 2021/4/21 1:59 下午 * @Author : < Jason.C > * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ public function order(): MorphTo { return $this->morphTo(); } /** * Notes : 结果通知 * * @Date : 2021/4/23 11:49 上午 * @Author : < Jason.C > * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function notifies(): HasMany { return $this->hasMany(PaymentNotify::class); } /** * Notes : 退款单 * * @Date : 2021/6/1 11:13 上午 * @Author : < Jason.C > * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function refunds(): HasMany { return $this->hasMany(Refund::class); } /** * Notes : 退款状态 * * @Date : 2021/6/1 11:40 上午 * @Author : < Jason.C > * @return string */ public function getRefundStatusTextAttribute(): string { if ($this->refunds->count()) { return ($this->refunds->sum('total') == $this->total) ? '全额退款' : '部分退款'; } else { return ''; } } /** * Notes : 直接通过 order 来设置关联的支付订单 * * @Date : 2021/4/21 12:43 下午 * @Author : < Jason.C > * @param \App\Models\Model $order */ public function setOrderAttribute(Model $order) { $this->attributes['order_type'] = get_class($order); $this->attributes['order_id'] = $order->getKey(); } /** * Notes : 通过模型来设置所属用户 * * @Date : 2021/4/21 1:48 下午 * @Author : < Jason.C > * @param \Modules\User\Models\User $user */ public function setUserAttribute(User $user) { $this->attributes['user_id'] = $user->getKey(); } /** * Notes : 支付成功,调用的方法 * * @Date : 2021/4/20 5:42 下午 * @Author : < Jason.C > */ public function paid(): void { $this->state = self::STATUS_SUCCESS; $this->paid_at = now(); $this->save(); event(new Paid($this)); } /** * Notes : 根据支付订单,获取支付渠道需要的接口数据 * * @Date : 2021/4/21 4:24 下午 * @Author : < Jason.C > * @param string $title 订单标题 * @param array $extends 扩展数据, 微信公众号 ['openid' => OPENID] * @return mixed * @throws \Exception */ public function getPaymentParams(string $title, array $extends = []) { $order['out_trade_no'] = $this->trade_id; $driver = $this->driver; $gateway = $this->gateway; if ($driver === self::DRIVER_WECHAT) { $order['out_trade_no'] = $this->trade_id; if (config('payment.version', 2) == 2) { $order['body'] = $title; $order['total_fee'] = $this->total * 100; } else { $order['description'] = $title; $order['amount']['total'] = $this->total * 100; } } elseif ($driver === self::DRIVER_ALIPAY) { $order['total_amount'] = $this->total; $order['out_trade_no'] = $this->trade_id; $order['subject'] = $title; } else { throw new Exception('unsupported driver'); } if (! empty($extends)) { $order = array_merge($order, $extends); } return Pay::$driver()->$gateway($order); } }