mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-08 11:14:31 -04:00
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:
parent
0c7ae3bca8
commit
84e888863f
@ -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'));
|
||||||
|
|
||||||
|
@ -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') {
|
||||||
@ -156,7 +170,7 @@ class CreditCard
|
|||||||
if ($response->status == 'Declined') {
|
if ($response->status == 'Declined') {
|
||||||
$this->checkout->unWindGatewayFees($this->checkout->payment_hash);
|
$this->checkout->unWindGatewayFees($this->checkout->payment_hash);
|
||||||
|
|
||||||
PaymentFailureMailer::dispatch($this->checkout->client, $response->response_summary, $this->checkout->client->company, $this->checkout->payment_hash->data->value);
|
PaymentFailureMailer::dispatch($this->checkout->client, $response->response_summary, $this->checkout->client->company, $this->checkout->payment_hash->data->value);
|
||||||
|
|
||||||
|
|
||||||
return $this->processUnsuccessfulPayment($response);
|
return $this->processUnsuccessfulPayment($response);
|
||||||
|
@ -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',
|
||||||
];
|
];
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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">
|
||||||
← {{ ctrans('texts.client_portal') }}
|
← {{ 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.paid') }}
|
||||||
- {{ ctrans('texts.unpaid') }}
|
</h3>
|
||||||
</h3>
|
<a href="{{ route('client.invoice.show', $invoice->hashed_id) }}?mode=portal"
|
||||||
</div>
|
class="mr-4 text-primary">
|
||||||
|
← {{ ctrans('texts.client_portal') }}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user