Changeset View
Changeset View
Standalone View
Standalone View
src/app/Http/Controllers/API/V4/PaymentsController.php
Show All 15 Lines | class PaymentsController extends Controller | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse The response | * @return \Illuminate\Http\JsonResponse The response | ||||
*/ | */ | ||||
public function mandate() | public function mandate() | ||||
{ | { | ||||
$user = Auth::guard()->user(); | $user = Auth::guard()->user(); | ||||
// TODO: Wallet selection | // TODO: Wallet selection | ||||
$wallet = $user->wallets->first(); | $wallet = $user->wallets()->first(); | ||||
$mandate = self::walletMandate($wallet); | $mandate = self::walletMandate($wallet); | ||||
return response()->json($mandate); | return response()->json($mandate); | ||||
} | } | ||||
/** | /** | ||||
* Create a new auto-payment mandate. | * Create a new auto-payment mandate. | ||||
* | * | ||||
* @param \Illuminate\Http\Request $request The API request. | * @param \Illuminate\Http\Request $request The API request. | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse The response | * @return \Illuminate\Http\JsonResponse The response | ||||
*/ | */ | ||||
public function mandateCreate(Request $request) | public function mandateCreate(Request $request) | ||||
{ | { | ||||
$current_user = Auth::guard()->user(); | $current_user = Auth::guard()->user(); | ||||
// TODO: Wallet selection | // TODO: Wallet selection | ||||
$wallet = $current_user->wallets->first(); | $wallet = $current_user->wallets()->first(); | ||||
$rules = [ | // Input validation | ||||
'amount' => 'required|numeric', | if ($errors = self::mandateValidate($request, $wallet)) { | ||||
'balance' => 'required|numeric|min:0', | |||||
]; | |||||
// Check required fields | |||||
$v = Validator::make($request->all(), $rules); | |||||
// TODO: allow comma as a decimal point? | |||||
if ($v->fails()) { | |||||
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422); | |||||
} | |||||
$amount = (int) ($request->amount * 100); | |||||
// Validate the minimum value | |||||
if ($amount < PaymentProvider::MIN_AMOUNT) { | |||||
$min = intval(PaymentProvider::MIN_AMOUNT / 100) . ' CHF'; | |||||
$errors = ['amount' => \trans('validation.minamount', ['amount' => $min])]; | |||||
return response()->json(['status' => 'error', 'errors' => $errors], 422); | return response()->json(['status' => 'error', 'errors' => $errors], 422); | ||||
} | } | ||||
$wallet->setSettings([ | $wallet->setSettings([ | ||||
'mandate_amount' => $request->amount, | 'mandate_amount' => $request->amount, | ||||
'mandate_balance' => $request->balance, | 'mandate_balance' => $request->balance, | ||||
]); | ]); | ||||
$request = [ | $mandate = [ | ||||
'currency' => 'CHF', | 'currency' => 'CHF', | ||||
'amount' => $amount, | |||||
'description' => \config('app.name') . ' Auto-Payment Setup', | 'description' => \config('app.name') . ' Auto-Payment Setup', | ||||
]; | ]; | ||||
// Normally the auto-payment setup operation is 0, if the balance is below the threshold | |||||
// we'll top-up the wallet with the configured auto-payment amount | |||||
if ($wallet->balance < intval($request->balance * 100)) { | |||||
vanmeeuwen: Let's make this "balance less than or equal to", since users expect their "this account balance… | |||||
$mandate['amount'] = intval($request->amount * 100); | |||||
} | |||||
$provider = PaymentProvider::factory($wallet); | $provider = PaymentProvider::factory($wallet); | ||||
$result = $provider->createMandate($wallet, $request); | $result = $provider->createMandate($wallet, $mandate); | ||||
$result['status'] = 'success'; | $result['status'] = 'success'; | ||||
return response()->json($result); | return response()->json($result); | ||||
} | } | ||||
/** | /** | ||||
* Revoke the auto-payment mandate. | * Revoke the auto-payment mandate. | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse The response | * @return \Illuminate\Http\JsonResponse The response | ||||
*/ | */ | ||||
public function mandateDelete() | public function mandateDelete() | ||||
{ | { | ||||
$user = Auth::guard()->user(); | $user = Auth::guard()->user(); | ||||
// TODO: Wallet selection | // TODO: Wallet selection | ||||
$wallet = $user->wallets->first(); | $wallet = $user->wallets()->first(); | ||||
$provider = PaymentProvider::factory($wallet); | $provider = PaymentProvider::factory($wallet); | ||||
$provider->deleteMandate($wallet); | $provider->deleteMandate($wallet); | ||||
$wallet->setSetting('mandate_disabled', null); | $wallet->setSetting('mandate_disabled', null); | ||||
return response()->json([ | return response()->json([ | ||||
Show All 9 Lines | class PaymentsController extends Controller | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse The response | * @return \Illuminate\Http\JsonResponse The response | ||||
*/ | */ | ||||
public function mandateUpdate(Request $request) | public function mandateUpdate(Request $request) | ||||
{ | { | ||||
$current_user = Auth::guard()->user(); | $current_user = Auth::guard()->user(); | ||||
// TODO: Wallet selection | // TODO: Wallet selection | ||||
$wallet = $current_user->wallets->first(); | $wallet = $current_user->wallets()->first(); | ||||
// Input validation | |||||
if ($errors = self::mandateValidate($request, $wallet)) { | |||||
return response()->json(['status' => 'error', 'errors' => $errors], 422); | |||||
} | |||||
$wallet->setSettings([ | |||||
'mandate_amount' => $request->amount, | |||||
'mandate_balance' => $request->balance, | |||||
// Re-enable the mandate to give it a chance to charge again | |||||
// after it has been disabled (e.g. because the mandate amount was too small) | |||||
'mandate_disabled' => null, | |||||
]); | |||||
// Trigger auto-payment if the balance is below the threshold | |||||
if ($wallet->balance < intval($request->balance * 100)) { | |||||
\App\Jobs\WalletCharge::dispatch($wallet); | |||||
} | |||||
$result = self::walletMandate($wallet); | |||||
$result['status'] = 'success'; | |||||
$result['message'] = \trans('app.mandate-update-success'); | |||||
return response()->json($result); | |||||
} | |||||
/** | |||||
* Validate an auto-payment mandate request. | |||||
* | |||||
* @param \Illuminate\Http\Request $request The API request. | |||||
* @param \App\Wallet $wallet The wallet | |||||
* | |||||
* @return array|null List of errors on error or Null on success | |||||
*/ | |||||
protected static function mandateValidate(Request $request, Wallet $wallet) | |||||
{ | |||||
$rules = [ | $rules = [ | ||||
'amount' => 'required|numeric', | 'amount' => 'required|numeric', | ||||
'balance' => 'required|numeric|min:0', | 'balance' => 'required|numeric|min:0', | ||||
]; | ]; | ||||
// Check required fields | // Check required fields | ||||
$v = Validator::make($request->all(), $rules); | $v = Validator::make($request->all(), $rules); | ||||
// TODO: allow comma as a decimal point? | // TODO: allow comma as a decimal point? | ||||
if ($v->fails()) { | if ($v->fails()) { | ||||
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422); | return $v->errors(); | ||||
} | } | ||||
$amount = (int) ($request->amount * 100); | $amount = (int) ($request->amount * 100); | ||||
// Validate the minimum value | // Validate the minimum value | ||||
if ($amount < PaymentProvider::MIN_AMOUNT) { | // It has to be at least minimum payment amount and must cover current debt | ||||
$min = intval(PaymentProvider::MIN_AMOUNT / 100) . ' CHF'; | if ( | ||||
$errors = ['amount' => \trans('validation.minamount', ['amount' => $min])]; | $wallet->balance < 0 | ||||
return response()->json(['status' => 'error', 'errors' => $errors], 422); | && $wallet->balance * -1 > PaymentProvider::MIN_AMOUNT | ||||
&& $wallet->balance + $amount < 0 | |||||
) { | |||||
return ['amount' => \trans('validation.minamountdebt')]; | |||||
} | } | ||||
// If the mandate is disabled the update will trigger | if ($amount < PaymentProvider::MIN_AMOUNT) { | ||||
// an auto-payment and the amount must cover the debt | $min = intval(PaymentProvider::MIN_AMOUNT / 100) . ' CHF'; | ||||
if ($wallet->getSetting('mandate_disabled')) { | return ['amount' => \trans('validation.minamount', ['amount' => $min])]; | ||||
if ($wallet->balance < 0 && $wallet->balance + $amount < 0) { | |||||
$errors = ['amount' => \trans('validation.minamountdebt')]; | |||||
return response()->json(['status' => 'error', 'errors' => $errors], 422); | |||||
} | |||||
$wallet->setSetting('mandate_disabled', null); | |||||
if ($wallet->balance < intval($request->balance * 100)) { | |||||
\App\Jobs\WalletCharge::dispatch($wallet); | |||||
} | |||||
} | } | ||||
$wallet->setSettings([ | return null; | ||||
'mandate_amount' => $request->amount, | |||||
'mandate_balance' => $request->balance, | |||||
]); | |||||
$result = self::walletMandate($wallet); | |||||
$result['status'] = 'success'; | |||||
$result['message'] = \trans('app.mandate-update-success'); | |||||
return response()->json($result); | |||||
} | } | ||||
/** | /** | ||||
* Create a new payment. | * Create a new payment. | ||||
* | * | ||||
* @param \Illuminate\Http\Request $request The API request. | * @param \Illuminate\Http\Request $request The API request. | ||||
* | * | ||||
* @return \Illuminate\Http\JsonResponse The response | * @return \Illuminate\Http\JsonResponse The response | ||||
*/ | */ | ||||
public function store(Request $request) | public function store(Request $request) | ||||
{ | { | ||||
$current_user = Auth::guard()->user(); | $current_user = Auth::guard()->user(); | ||||
// TODO: Wallet selection | // TODO: Wallet selection | ||||
$wallet = $current_user->wallets->first(); | $wallet = $current_user->wallets()->first(); | ||||
$rules = [ | $rules = [ | ||||
'amount' => 'required|numeric', | 'amount' => 'required|numeric', | ||||
]; | ]; | ||||
// Check required fields | // Check required fields | ||||
$v = Validator::make($request->all(), $rules); | $v = Validator::make($request->all(), $rules); | ||||
▲ Show 20 Lines • Show All 126 Lines • Show Last 20 Lines |
Let's make this "balance less than or equal to", since users expect their "this account balance lasts you until $date" to change along with the payment setup.