star-cloud/app/Models/Transaction/Order.php
sky121113 3d35218d6b [FEAT] 新增手機支付與 LINE Pay 官方直連支付類型
1. Order.php getPaymentTypeLabels() 新增支付碼 10(手機支付/NFC 行動支付,走信用卡軌道)與 70(LINE Pay 官方直連,非 TapPay 底下的 30)。
2. config/api-docs.php B600 order.payment_type 說明字串補上 10 與 70 兩碼定義。
3. api-technical-specs SKILL.md Appendix A 支付類型對照表同步補上 10、70,並將 30 備註明確為「TapPay 底下的 LINE Pay」以區分兩條 LINE Pay 路線。
4. 三語系 (zh_TW/en/ja) 新增 "Mobile Pay"、"LINE Pay (Official)" 詞條,並重新 ksort 對齊字母排序。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:55:08 +08:00

222 lines
6.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models\Transaction;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Traits\TenantScoped;
use App\Models\Machine\Machine;
use App\Models\Member\Member;
class Order extends Model
{
use HasFactory, SoftDeletes, TenantScoped;
// 支付狀態
public const PAYMENT_STATUS_FAILED = 0;
public const PAYMENT_STATUS_SUCCESS = 1;
// 出貨狀態
public const DELIVERY_STATUS_FAILED = 0;
public const DELIVERY_STATUS_SUCCESS = 1;
public const DELIVERY_STATUS_PARTIAL = 2;
protected $fillable = [
'company_id',
'flow_id',
'order_no',
'machine_id',
'member_id',
'payment_type',
'total_amount',
'discount_amount',
'pay_amount',
'change_amount',
'points_used',
'original_amount',
'payment_status',
'payment_request',
'payment_response',
'payment_at',
'member_barcode',
'code_id',
'welcome_gift_id',
'invoice_info',
'machine_time',
'status',
'metadata',
'delivery_status',
];
protected $casts = [
'total_amount' => 'decimal:2',
'discount_amount' => 'decimal:2',
'pay_amount' => 'decimal:2',
'change_amount' => 'decimal:2',
'original_amount' => 'decimal:2',
'payment_at' => 'datetime',
'machine_time' => 'datetime',
'metadata' => 'array',
'payment_type' => 'integer',
'delivery_status' => 'integer',
];
/**
* 取得所有支付類型的對照標籤
*/
public static function getPaymentTypeLabels(): array
{
return [
1 => __('Credit Card'),
2 => __('E-Ticket (EasyCard/iPass)'),
3 => __('QR Code Payment'),
4 => __('Bill Acceptor'),
5 => __('Pass Code'), // 使用者要求由「通關密碼」改為「通行碼」
6 => __('Pickup Code'),
7 => __('Welcome Gift'),
8 => __('Questionnaire'),
9 => __('Coin Acceptor'),
10 => __('Mobile Pay'), // NFC 手機感應(行動支付,信用卡軌道,依使用者按鈕分類)
21 => __('Offline + 1'),
22 => __('Offline + 2'),
23 => __('Offline + 3'),
24 => __('Offline + 4'),
25 => __('Offline + 9'),
30 => __('LINE Pay'),
31 => __('JKO Pay'),
32 => __('Easy Wallet'),
33 => __('Pi Pay'),
34 => __('PlusPay'),
40 => __('Member Verify Pickup'),
41 => __('Staff Card'),
42 => __('Pickup Voucher'),
50 => __('Offline + LINE Pay'),
51 => __('Offline + JKO Pay'),
52 => __('Offline + Easy Wallet'),
53 => __('Offline + Pi Pay'),
54 => __('Offline + PlusPay'),
60 => __('Points/Voucher'),
61 => __('Member + 1'),
62 => __('Member + 2'),
63 => __('Member + 3'),
64 => __('Member + 4'),
65 => __('Member + 5'),
66 => __('Member + 6'),
67 => __('Member + 7'),
68 => __('Member + 8'),
69 => __('Member + 9'),
70 => __('LINE Pay (Official)'), // LINE Pay 官方直連(非 TapPay 底下的 30
90 => __('Member + LINE Pay'),
91 => __('Member + JKO Pay'),
92 => __('Member + Easy Wallet'),
93 => __('Member + Pi Pay'),
94 => __('Member + PlusPay'),
];
}
/**
* 取得目前的支付類型標籤 (Accessor)
*/
public function getPaymentTypeLabelAttribute(): string
{
return self::getPaymentTypeLabels()[$this->payment_type] ?? __('Unknown');
}
public function getMaskedPickupRecipientAttribute(): ?string
{
if (empty($this->member_barcode)) {
return null;
}
return self::maskPickupRecipientName($this->member_barcode);
}
public static function maskPickupRecipientName(string $value): string
{
$value = trim($value);
if ($value === '') {
return $value;
}
if (preg_match('/^([^\s(]+)(.*)$/us', $value, $matches) !== 1) {
return self::maskName($value);
}
return self::maskName($matches[1]) . ($matches[2] ?? '');
}
private static function maskName(string $name): string
{
$length = mb_strlen($name);
if ($length <= 1) {
return $name;
}
if ($length === 2) {
return mb_substr($name, 0, 1) . 'O';
}
return mb_substr($name, 0, 1)
. str_repeat('O', $length - 2)
. mb_substr($name, -1);
}
public function machine()
{
return $this->belongsTo(Machine::class);
}
public function member()
{
return $this->belongsTo(Member::class);
}
public function items()
{
return $this->hasMany(OrderItem::class);
}
public function invoice()
{
return $this->hasOne(Invoice::class);
}
public function dispenseRecords()
{
return $this->hasMany(DispenseRecord::class);
}
public function staffCardLog()
{
return $this->hasOne(\App\Models\StaffCardLog::class);
}
public function welcomeGift()
{
return $this->belongsTo(WelcomeGift::class);
}
/**
* 取得所有出貨狀態的對照標籤
*/
public static function getDeliveryStatusLabels(): array
{
return [
self::DELIVERY_STATUS_FAILED => __('Dispense Failed'),
self::DELIVERY_STATUS_SUCCESS => __('Dispense Success'),
self::DELIVERY_STATUS_PARTIAL => __('Partial Dispense Success'),
];
}
/**
* 取得目前出貨狀態標籤 (Accessor)
*/
public function getDeliveryStatusLabelAttribute(): string
{
return self::getDeliveryStatusLabels()[$this->delivery_status] ?? __('Unknown');
}
}