Changeset View
Changeset View
Standalone View
Standalone View
src/app/Providers/PaymentProvider.php
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | public static function factory($provider_or_wallet = null, $currency = null) | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Create a new auto-payment mandate for a wallet. | * Create a new auto-payment mandate for a wallet. | ||||
* | * | ||||
* @param \App\Wallet $wallet The wallet | * @param \App\Wallet $wallet The wallet | ||||
* @param array $payment Payment data: | * @param array $payment Payment data: | ||||
* - amount: Value in cents | * - amount: Value in cents (wallet currency) | ||||
* - credit_amount: Balance'able base amount in cents (wallet currency) | |||||
* - vat_rate_id: VAT rate id | |||||
* - currency: The operation currency | * - currency: The operation currency | ||||
* - description: Operation desc. | * - description: Operation desc. | ||||
* - methodId: Payment method | * - methodId: Payment method | ||||
* | * | ||||
* @return array Provider payment data: | * @return array Provider payment data: | ||||
* - id: Operation identifier | * - id: Operation identifier | ||||
* - redirectUrl: the location to redirect to | * - redirectUrl: the location to redirect to | ||||
*/ | */ | ||||
Show All 38 Lines | abstract class PaymentProvider | ||||
*/ | */ | ||||
abstract public function name(): string; | abstract public function name(): string; | ||||
/** | /** | ||||
* Create a new payment. | * Create a new payment. | ||||
* | * | ||||
* @param \App\Wallet $wallet The wallet | * @param \App\Wallet $wallet The wallet | ||||
* @param array $payment Payment data: | * @param array $payment Payment data: | ||||
* - amount: Value in cents | * - amount: Value in cents (wallet currency) | ||||
* - credit_amount: Balance'able base amount in cents (wallet currency) | |||||
* - vat_rate_id: Vat rate id | |||||
* - currency: The operation currency | * - currency: The operation currency | ||||
* - type: first/oneoff/recurring | * - type: first/oneoff/recurring | ||||
* - description: Operation description | * - description: Operation description | ||||
* - methodId: Payment method | * - methodId: Payment method | ||||
* | * | ||||
* @return array Provider payment/session data: | * @return array Provider payment/session data: | ||||
* - id: Operation identifier | * - id: Operation identifier | ||||
* - redirectUrl | * - redirectUrl | ||||
Show All 12 Lines | abstract class PaymentProvider | ||||
* | * | ||||
* @param array $payment Payment information | * @param array $payment Payment information | ||||
* @param string $wallet_id Wallet ID | * @param string $wallet_id Wallet ID | ||||
* | * | ||||
* @return \App\Payment Payment object | * @return \App\Payment Payment object | ||||
*/ | */ | ||||
protected function storePayment(array $payment, $wallet_id): Payment | protected function storePayment(array $payment, $wallet_id): Payment | ||||
{ | { | ||||
$db_payment = new Payment(); | $payment['wallet_id'] = $wallet_id; | ||||
$db_payment->id = $payment['id']; | $payment['provider'] = $this->name(); | ||||
$db_payment->description = $payment['description'] ?? ''; | |||||
$db_payment->status = $payment['status'] ?? self::STATUS_OPEN; | |||||
$db_payment->amount = $payment['amount'] ?? 0; | |||||
$db_payment->type = $payment['type']; | |||||
$db_payment->wallet_id = $wallet_id; | |||||
$db_payment->provider = $this->name(); | |||||
$db_payment->currency = $payment['currency']; | |||||
$db_payment->currency_amount = $payment['currency_amount']; | |||||
$db_payment->save(); | |||||
return $db_payment; | return Payment::createFromArray($payment); | ||||
} | } | ||||
/** | /** | ||||
* Convert a value from $sourceCurrency to $targetCurrency | * Convert a value from $sourceCurrency to $targetCurrency | ||||
* | * | ||||
* @param int $amount Amount in cents of $sourceCurrency | * @param int $amount Amount in cents of $sourceCurrency | ||||
* @param string $sourceCurrency Currency from which to convert | * @param string $sourceCurrency Currency from which to convert | ||||
* @param string $targetCurrency Currency to convert to | * @param string $targetCurrency Currency to convert to | ||||
* | * | ||||
* @return int Exchanged amount in cents of $targetCurrency | * @return int Exchanged amount in cents of $targetCurrency | ||||
*/ | */ | ||||
protected function exchange(int $amount, string $sourceCurrency, string $targetCurrency): int | protected function exchange(int $amount, string $sourceCurrency, string $targetCurrency): int | ||||
{ | { | ||||
return intval(round($amount * \App\Utils::exchangeRate($sourceCurrency, $targetCurrency))); | return intval(round($amount * \App\Utils::exchangeRate($sourceCurrency, $targetCurrency))); | ||||
} | } | ||||
/** | /** | ||||
* Deduct an amount of pecunia from the wallet. | |||||
* Creates a payment and transaction records for the refund/chargeback operation. | |||||
* | |||||
* @param \App\Wallet $wallet A wallet object | |||||
* @param array $refund A refund or chargeback data (id, type, amount, description) | |||||
* | |||||
* @return void | |||||
*/ | |||||
protected function storeRefund(Wallet $wallet, array $refund): void | |||||
{ | |||||
if (empty($refund) || empty($refund['amount'])) { | |||||
return; | |||||
} | |||||
// Preserve originally refunded amount | |||||
$refund['currency_amount'] = $refund['amount'] * -1; | |||||
// Convert amount to wallet currency | |||||
// TODO We should possibly be using the same exchange rate as for the original payment? | |||||
$amount = $this->exchange($refund['amount'], $refund['currency'], $wallet->currency); | |||||
$wallet->balance -= $amount; | |||||
$wallet->save(); | |||||
if ($refund['type'] == self::TYPE_CHARGEBACK) { | |||||
$transaction_type = Transaction::WALLET_CHARGEBACK; | |||||
} else { | |||||
$transaction_type = Transaction::WALLET_REFUND; | |||||
} | |||||
Transaction::create([ | |||||
'object_id' => $wallet->id, | |||||
'object_type' => Wallet::class, | |||||
'type' => $transaction_type, | |||||
'amount' => $amount * -1, | |||||
'description' => $refund['description'] ?? '', | |||||
]); | |||||
$refund['status'] = self::STATUS_PAID; | |||||
$refund['amount'] = -1 * $amount; | |||||
// FIXME: Refunds/chargebacks are out of the reseller comissioning for now | |||||
$this->storePayment($refund, $wallet->id); | |||||
} | |||||
/** | |||||
* List supported payment methods from this provider | * List supported payment methods from this provider | ||||
mollekopf: Rather call the actual method instead of assembling a string that is then invoked as a method… | |||||
* | * | ||||
* @param string $type The payment type for which we require a method (oneoff/recurring). | * @param string $type The payment type for which we require a method (oneoff/recurring). | ||||
* @param string $currency Currency code | * @param string $currency Currency code | ||||
* | * | ||||
* @return array Array of array with available payment methods: | * @return array Array of array with available payment methods: | ||||
* - id: id of the method | * - id: id of the method | ||||
* - name: User readable name of the payment method | * - name: User readable name of the payment method | ||||
* - minimumAmount: Minimum amount to be charged in cents | * - minimumAmount: Minimum amount to be charged in cents | ||||
▲ Show 20 Lines • Show All 126 Lines • Show Last 20 Lines |
Rather call the actual method instead of assembling a string that is then invoked as a method, IMO.