Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117751006
Payment.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
Payment.php
View Options
<?php
namespace
App
;
use
Dyrynda\Database\Support\NullableFields
;
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Database\Eloquent\Relations\BelongsTo
;
/**
* A payment operation on a wallet.
*
* @property int $amount Amount of money in cents of system currency (payment provider)
* @property int $credit_amount Amount of money in cents of system currency (wallet balance)
* @property string $description Payment description
* @property string $id Mollie's Payment ID
* @property string $status Payment status (Payment::STATUS_*)
* @property string $type Payment type (Payment::TYPE_*)
* @property ?string $vat_rate_id VAT rate identifier
* @property Wallet $wallet The wallet
* @property string $wallet_id The ID of the wallet
* @property string $currency Currency of this payment
* @property int $currency_amount Amount of money in cents of $currency
*/
class
Payment
extends
Model
{
use
NullableFields
;
public
const
STATUS_OPEN
=
'open'
;
public
const
STATUS_CANCELED
=
'canceled'
;
public
const
STATUS_PENDING
=
'pending'
;
public
const
STATUS_AUTHORIZED
=
'authorized'
;
public
const
STATUS_EXPIRED
=
'expired'
;
public
const
STATUS_FAILED
=
'failed'
;
public
const
STATUS_PAID
=
'paid'
;
public
const
TYPE_ONEOFF
=
'oneoff'
;
public
const
TYPE_RECURRING
=
'recurring'
;
public
const
TYPE_MANDATE
=
'mandate'
;
public
const
TYPE_REFUND
=
'refund'
;
public
const
TYPE_CHARGEBACK
=
'chargeback'
;
/** const int Minimum amount of money in a single payment (in cents) */
public
const
MIN_AMOUNT
=
100
;
/** @var bool Indicates that the model should be timestamped or not */
public
$incrementing
=
false
;
/** @var string The "type" of the auto-incrementing ID */
protected
$keyType
=
'string'
;
/** @var array<string, string> The attributes that should be cast */
protected
$casts
=
[
'amount'
=>
'integer'
,
'credit_amount'
=>
'integer'
,
'currency_amount'
=>
'integer'
,
];
/** @var list<string> The attributes that are mass assignable */
protected
$fillable
=
[
'id'
,
'wallet_id'
,
'amount'
,
'credit_amount'
,
'description'
,
'provider'
,
'status'
,
'vat_rate_id'
,
'type'
,
'currency'
,
'currency_amount'
,
];
/** @var array<int, string> The attributes that can be not set */
protected
$nullable
=
[
'vat_rate_id'
,
];
/**
* Create a payment record in DB from array.
*
* @param array $payment Payment information (required: id, type, wallet_id, currency, amount, currency_amount)
*
* @return Payment Payment object
*/
public
static
function
createFromArray
(
array
$payment
):
self
{
$db_payment
=
new
self
();
$db_payment
->
id
=
$payment
[
'id'
];
$db_payment
->
description
=
$payment
[
'description'
]
??
''
;
$db_payment
->
status
=
$payment
[
'status'
]
??
self
::
STATUS_OPEN
;
$db_payment
->
amount
=
$payment
[
'amount'
]
??
0
;
$db_payment
->
credit_amount
=
$payment
[
'credit_amount'
]
??
(
$payment
[
'amount'
]
??
0
);
$db_payment
->
vat_rate_id
=
$payment
[
'vat_rate_id'
]
??
null
;
$db_payment
->
type
=
$payment
[
'type'
];
$db_payment
->
wallet_id
=
$payment
[
'wallet_id'
];
$db_payment
->
provider
=
$payment
[
'provider'
]
??
''
;
$db_payment
->
currency
=
$payment
[
'currency'
];
$db_payment
->
currency_amount
=
$payment
[
'currency_amount'
];
$db_payment
->
save
();
return
$db_payment
;
}
/**
* Apply the successful payment's pecunia to the wallet
*
* @param string $method Payment method name
*/
public
function
credit
(
$method
):
void
{
if
(
empty
(
$this
->
wallet
))
{
throw
new
\Exception
(
"Cannot credit a payment not assigned to a wallet"
);
}
if
(
$this
->
credit_amount
<
0
)
{
throw
new
\Exception
(
"Cannot credit a payment with negative amount"
);
}
// TODO: Possibly we should sanity check that payment is paid?
// TODO: Localization?
$description
=
$this
->
type
==
self
::
TYPE_RECURRING
?
'Auto-payment'
:
'Payment'
;
$description
.=
" transaction {$this->id} using {$method}"
;
$this
->
wallet
->
credit
(
$this
,
$description
);
// Unlock the disabled auto-payment mandate
if
(
$this
->
wallet
->
balance
>=
0
)
{
$this
->
wallet
->
setSetting
(
'mandate_disabled'
,
null
);
}
if
(
$owner
=
$this
->
wallet
->
owner
)
{
// Remove RESTRICTED flag from the wallet owner and all users in the wallet
if
(
$owner
->
isRestricted
())
{
$owner
->
unrestrict
(
true
);
}
// Activate the inactive user
if
(!
$owner
->
isActive
())
{
$owner
->
status
|=
User
::
STATUS_ACTIVE
;
$owner
->
save
();
}
ReferralProgram
::
accounting
(
$owner
);
}
}
/**
* Creates a payment and transaction records for the refund/chargeback operation.
* Deducts an amount of pecunia from the wallet.
*
* @param array $refund A refund or chargeback data (id, type, amount, currency, description)
*
* @return ?Payment A payment object for the refund
*/
public
function
refund
(
array
$refund
):
?
self
{
if
(
empty
(
$refund
)
||
empty
(
$refund
[
'amount'
]))
{
return
null
;
}
// Convert amount to wallet currency (use the same exchange rate as for the original payment)
// Note: We assume a refund is always using the same currency
$exchange_rate
=
$this
->
amount
/
$this
->
currency_amount
;
$credit_amount
=
$amount
=
(
int
)
round
(
$refund
[
'amount'
]
*
$exchange_rate
);
// Set appropriate credit_amount if original credit_amount != original amount
if
(
$this
->
amount
!=
$this
->
credit_amount
)
{
$credit_amount
=
(
int
)
round
(
$amount
*
(
$this
->
credit_amount
/
$this
->
amount
));
}
// Apply the refund to the wallet balance
$method
=
$refund
[
'type'
]
==
self
::
TYPE_CHARGEBACK
?
'chargeback'
:
'refund'
;
$this
->
wallet
->{
$method
}(
$credit_amount
,
$refund
[
'description'
]
??
''
);
$refund
[
'amount'
]
=
$amount
*
-
1
;
$refund
[
'credit_amount'
]
=
$credit_amount
*
-
1
;
$refund
[
'currency_amount'
]
=
round
(
$amount
*
-
1
/
$exchange_rate
);
$refund
[
'currency'
]
=
$this
->
currency
;
$refund
[
'wallet_id'
]
=
$this
->
wallet_id
;
$refund
[
'provider'
]
=
$this
->
provider
;
$refund
[
'vat_rate_id'
]
=
$this
->
vat_rate_id
;
$refund
[
'status'
]
=
self
::
STATUS_PAID
;
// FIXME: Refunds/chargebacks are out of the reseller comissioning for now
return
self
::
createFromArray
(
$refund
);
}
/**
* Ensure the currency is appropriately cased.
*/
public
function
setCurrencyAttribute
(
$currency
)
{
$this
->
attributes
[
'currency'
]
=
strtoupper
(
$currency
);
}
/**
* The wallet to which this payment belongs.
*
* @return BelongsTo<Wallet, $this>
*/
public
function
wallet
()
{
return
$this
->
belongsTo
(
Wallet
::
class
,
'wallet_id'
,
'id'
);
}
/**
* The VAT rate assigned to this payment.
*
* @return BelongsTo<VatRate, $this>
*/
public
function
vatRate
()
{
return
$this
->
belongsTo
(
VatRate
::
class
,
'vat_rate_id'
,
'id'
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, Apr 4, 2:45 AM (4 d, 5 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9c/e9/f0f91b9eccfcf084bd8f25c4d6f6
Default Alt Text
Payment.php (7 KB)
Attached To
Mode
rK kolab
Attached
Detach File
Event Timeline