Authorize.net: Throw a PaymentFailed exception if token not found

Checkout.com: Throw a PaymentFailed exception if token not found
- Show "Client portal" button even when invoice is paid
- Authorize.net: Pass token hashed_id instead of token to frontend
- Checkout.com: Pass token hashed_id instead of token to frontend
- Show "Paid" label for paid invoices
- Translation for not found token
This commit is contained in:
Benjamin Beganović 2021-01-27 12:45:38 +01:00
parent 0c7ae3bca8
commit 84e888863f
7 changed files with 47 additions and 21 deletions

View File

@ -12,6 +12,7 @@
namespace App\PaymentDrivers\Authorize; namespace App\PaymentDrivers\Authorize;
use App\Exceptions\PaymentFailed;
use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Mail\PaymentFailureMailer;
use App\Jobs\Util\SystemLogger; use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
@ -81,7 +82,14 @@ class AuthorizeCreditCard
private function processTokenPayment($request) private function processTokenPayment($request)
{ {
$client_gateway_token =ClientGatewayToken::where('token', $request->token)->firstOrFail(); $client_gateway_token = ClientGatewayToken::query()
->where('id', $this->decodePrimaryKey($request->token))
->where('company_id', auth('contact')->user()->client->company->id)
->first();
if (!$client_gateway_token) {
throw new PaymentFailed(ctrans('texts.payment_token_not_found'), 401);
}
$data = (new ChargePaymentProfile($this->authorize))->chargeCustomerProfile($client_gateway_token->gateway_customer_reference, $client_gateway_token->token, $request->input('amount_with_fee')); $data = (new ChargePaymentProfile($this->authorize))->chargeCustomerProfile($client_gateway_token->gateway_customer_reference, $client_gateway_token->token, $request->input('amount_with_fee'));

View File

@ -12,9 +12,12 @@
namespace App\PaymentDrivers\CheckoutCom; namespace App\PaymentDrivers\CheckoutCom;
use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Mail\PaymentFailureMailer;
use App\Models\ClientGatewayToken;
use App\PaymentDrivers\CheckoutComPaymentDriver; use App\PaymentDrivers\CheckoutComPaymentDriver;
use App\Utils\Traits\MakesHash;
use Checkout\Library\Exceptions\CheckoutHttpException; use Checkout\Library\Exceptions\CheckoutHttpException;
use Checkout\Models\Payments\IdSource; use Checkout\Models\Payments\IdSource;
use Checkout\Models\Payments\Payment; use Checkout\Models\Payments\Payment;
@ -25,6 +28,7 @@ use Illuminate\View\View;
class CreditCard class CreditCard
{ {
use Utilities; use Utilities;
use MakesHash;
/** /**
* @var CheckoutComPaymentDriver * @var CheckoutComPaymentDriver
@ -78,6 +82,15 @@ class CreditCard
{ {
$this->checkout->init(); $this->checkout->init();
$cgt = ClientGatewayToken::query()
->where('id', $this->decodePrimaryKey($request->input('token')))
->where('company_id', auth('contact')->user()->client->company->id)
->first();
if (!$cgt) {
throw new PaymentFailed(ctrans('texts.payment_token_not_found'), 401);
}
$state = [ $state = [
'server_response' => json_decode($request->gateway_response), 'server_response' => json_decode($request->gateway_response),
'value' => $request->value, 'value' => $request->value,
@ -90,11 +103,12 @@ class CreditCard
$state = array_merge($state, $request->all()); $state = array_merge($state, $request->all());
$state['store_card'] = boolval($state['store_card']); $state['store_card'] = boolval($state['store_card']);
$state['token'] = $cgt;
$this->checkout->payment_hash->data = array_merge((array) $this->checkout->payment_hash->data, $state); $this->checkout->payment_hash->data = array_merge((array)$this->checkout->payment_hash->data, $state);
$this->checkout->payment_hash->save(); $this->checkout->payment_hash->save();
if ($request->has('token') && !is_null($request->token) && !empty($request->token)) { if ($request->has('token')) {
return $this->attemptPaymentUsingToken($request); return $this->attemptPaymentUsingToken($request);
} }
@ -103,7 +117,7 @@ class CreditCard
private function attemptPaymentUsingToken(PaymentResponseRequest $request) private function attemptPaymentUsingToken(PaymentResponseRequest $request)
{ {
$method = new IdSource($this->checkout->payment_hash->data->token); $method = new IdSource($this->checkout->payment_hash->data->token->token);
return $this->completePayment($method, $request); return $this->completePayment($method, $request);
} }
@ -125,7 +139,7 @@ class CreditCard
$payment->amount = $this->checkout->payment_hash->data->value; $payment->amount = $this->checkout->payment_hash->data->value;
$payment->reference = $this->checkout->payment_hash->data->reference; $payment->reference = $this->checkout->payment_hash->data->reference;
$this->checkout->payment_hash->data = array_merge((array) $this->checkout->payment_hash->data, ['checkout_payment_ref' => $payment]); $this->checkout->payment_hash->data = array_merge((array)$this->checkout->payment_hash->data, ['checkout_payment_ref' => $payment]);
$this->checkout->payment_hash->save(); $this->checkout->payment_hash->save();
if ($this->checkout->client->currency()->code === 'EUR') { if ($this->checkout->client->currency()->code === 'EUR') {

View File

@ -3383,5 +3383,5 @@ return [
'create_webhook_failure' => 'Failed to create Webhook', 'create_webhook_failure' => 'Failed to create Webhook',
'number' => 'Number', 'number' => 'Number',
'payment_message_extended' => 'Thank you for your payment of :amount for :invoice', 'payment_message_extended' => 'Thank you for your payment of :amount for :invoice',
'payment_token_not_found' => 'Payment token not found, please try again. If an issue still persist, try with another payment method',
]; ];

View File

@ -38,7 +38,7 @@
<label class="mr-4"> <label class="mr-4">
<input <input
type="radio" type="radio"
data-token="{{ $token->token }}" data-token="{{ $token->hashed_id }}"
name="payment-type" name="payment-type"
class="form-radio cursor-pointer toggle-payment-with-token"/> class="form-radio cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span> <span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span>

View File

@ -141,7 +141,7 @@
<label class="mr-4"> <label class="mr-4">
<input <input
type="radio" type="radio"
data-token="{{ $token->token }}" data-token="{{ $token->hashed_id }}"
name="payment-type" name="payment-type"
class="form-radio cursor-pointer toggle-payment-with-token"/> class="form-radio cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span> <span class="ml-1 cursor-pointer">**** {{ optional($token->meta)->last4 }}</span>

View File

@ -48,7 +48,8 @@
<div class="sm:flex sm:items-start sm:justify-between"> <div class="sm:flex sm:items-start sm:justify-between">
<div> <div>
<h3 class="text-lg leading-6 font-medium text-gray-900"> <h3 class="text-lg leading-6 font-medium text-gray-900">
{{ ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice->number])}} - {{ ctrans('texts.unpaid') }} {{ ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice->number])}}
- {{ ctrans('texts.paid') }}
</h3> </h3>
</div> </div>
</div> </div>

View File

@ -21,7 +21,8 @@
</div> </div>
</div> </div>
<div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center"> <div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center">
<a href="{{ route('client.invoice.show', $invoice->hashed_id) }}?mode=portal" class="mr-4 text-primary"> <a href="{{ route('client.invoice.show', $invoice->hashed_id) }}?mode=portal"
class="mr-4 text-primary">
&#8592; {{ ctrans('texts.client_portal') }} &#8592; {{ ctrans('texts.client_portal') }}
</a> </a>
@ -36,15 +37,17 @@
</div> </div>
</form> </form>
@else @else
<div class="bg-white shadow sm:rounded-lg mb-4" translate> <div class="bg-white shadow sm:rounded-lg mb-4">
<div class="px-4 py-5 sm:p-6"> <div class="px-4 py-5 sm:p-6">
<div class="sm:flex sm:items-start sm:justify-between"> <div class="sm:flex sm:items-start sm:justify-between">
<div>
<h3 class="text-lg leading-6 font-medium text-gray-900"> <h3 class="text-lg leading-6 font-medium text-gray-900">
{{ ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice->number])}} {{ ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice->number])}}
- {{ ctrans('texts.unpaid') }} - {{ ctrans('texts.paid') }}
</h3> </h3>
</div> <a href="{{ route('client.invoice.show', $invoice->hashed_id) }}?mode=portal"
class="mr-4 text-primary">
&#8592; {{ ctrans('texts.client_portal') }}
</a>
</div> </div>
</div> </div>
</div> </div>