75 lines
2.9 KiB
PHP
75 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace Modules\Core\Payment\Drivers;
|
|
|
|
use Illuminate\Support\Str;
|
|
use Lunar\DataTypes\Price;
|
|
use Modules\Core\Payment\Contracts\Configurable;
|
|
use Modules\Core\Payment\Contracts\SupportsPay;
|
|
use Modules\Core\Payment\Contracts\SupportsRefunds;
|
|
use Modules\Core\Payment\DTOs\PaymentResult;
|
|
use Modules\Core\Payment\Enums\PaymentResultStatus;
|
|
use Modules\Core\Payment\Events\PaymentCaptured;
|
|
use Modules\Core\Payment\Events\PaymentRefunded;
|
|
|
|
/**
|
|
* Manual/attested, same trust model as OfflinePaymentDriver — there is no
|
|
* bank API to call, so both pay() and refund() decide success immediately
|
|
* on a staff member's say-so (they've already sent/received the wire
|
|
* outside the system). Distinct from OfflinePaymentDriver in intent: this
|
|
* exists so a payment taken through a DIFFERENT method (e.g.
|
|
* cash-on-delivery) can still be REFUNDED via bank transfer — an admin
|
|
* chooses this driver explicitly in the refund action, independent of
|
|
* which driver the original payment went through (see
|
|
* Payment\Support\TransactionDriverAdapter::refundVia() and
|
|
* Order\Filament\Extensions\OrderActionsExtension). pay() exists so
|
|
* the same driver also covers receiving a payment by bank transfer, but
|
|
* the admin UI for that (bank reference, notes, proof-of-transfer upload)
|
|
* is deliberately not built yet — see the follow-up work tracked from this
|
|
* session; pay() itself is complete and usable via the registry today.
|
|
*
|
|
* $reference is generated here for the same reason as OfflinePaymentDriver's
|
|
* pay(): there is no gateway to hand one back. 'notes' in $context (not
|
|
* $data — refund() has no $data parameter) is folded into
|
|
* PaymentResult::$meta, which Order\Services\TransactionRecorder::record()
|
|
* already writes straight into Transaction.meta with no extra plumbing.
|
|
*/
|
|
class BankTransferPaymentDriver implements Configurable, SupportsPay, SupportsRefunds
|
|
{
|
|
/**
|
|
* Always true — no external dependency to be missing.
|
|
*/
|
|
public function isConfigured(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function pay(string $type, Price $amount, array $data = [], array $context = []): PaymentResult
|
|
{
|
|
$result = new PaymentResult(
|
|
status: PaymentResultStatus::Succeeded,
|
|
reference: 'bank-transfer-'.Str::uuid(),
|
|
amount: $amount,
|
|
meta: array_filter(['notes' => $data['notes'] ?? null]),
|
|
);
|
|
|
|
PaymentCaptured::dispatch($type, $result, $context);
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function refund(string $reference, Price $amount, array $context = []): PaymentResult
|
|
{
|
|
$result = new PaymentResult(
|
|
status: PaymentResultStatus::Succeeded,
|
|
reference: 'bank-transfer-'.Str::uuid(),
|
|
amount: $amount,
|
|
meta: array_filter(['notes' => $context['notes'] ?? null]),
|
|
);
|
|
|
|
PaymentRefunded::dispatch('bank-transfer', $result, $context);
|
|
|
|
return $result;
|
|
}
|
|
}
|