mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-02 19:54:33 -04:00
Stripe payments
This commit is contained in:
parent
8027e72217
commit
46602a21c5
@ -122,7 +122,6 @@ class InvoiceController extends Controller
|
|||||||
|
|
||||||
$total = $invoices->sum('balance');
|
$total = $invoices->sum('balance');
|
||||||
|
|
||||||
|
|
||||||
$invoices->filter(function ($invoice){
|
$invoices->filter(function ($invoice){
|
||||||
return $invoice->isPayable();
|
return $invoice->isPayable();
|
||||||
})->map(function ($invoice){
|
})->map(function ($invoice){
|
||||||
@ -131,8 +130,6 @@ class InvoiceController extends Controller
|
|||||||
return $invoice;
|
return $invoice;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$formatted_total = Number::formatMoney($total, auth()->user()->client);
|
$formatted_total = Number::formatMoney($total, auth()->user()->client);
|
||||||
|
|
||||||
$payment_methods = auth()->user()->client->getPaymentMethods($total);
|
$payment_methods = auth()->user()->client->getPaymentMethods($total);
|
||||||
@ -142,6 +139,7 @@ class InvoiceController extends Controller
|
|||||||
'invoices' => $invoices,
|
'invoices' => $invoices,
|
||||||
'formatted_total' => $formatted_total,
|
'formatted_total' => $formatted_total,
|
||||||
'payment_methods' => $payment_methods,
|
'payment_methods' => $payment_methods,
|
||||||
|
'hashed_ids' => $ids,
|
||||||
'total' => $total,
|
'total' => $total,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -11,26 +11,30 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use Cache;
|
|
||||||
use App\Filters\PaymentFilters;
|
use App\Filters\PaymentFilters;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use App\Utils\Number;
|
||||||
|
use App\Utils\Traits\MakesDates;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Cache;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Yajra\DataTables\Facades\DataTables;
|
use Yajra\DataTables\Facades\DataTables;
|
||||||
use Yajra\DataTables\Html\Builder;
|
use Yajra\DataTables\Html\Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class InvoiceController
|
* Class PaymentController
|
||||||
* @package App\Http\Controllers\ClientPortal\InvoiceController
|
* @package App\Http\Controllers\ClientPortal\PaymentController
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PaymentController extends Controller
|
class PaymentController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
use MakesDates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the list of Invoices
|
* Show the list of Invoices
|
||||||
@ -84,41 +88,47 @@ class PaymentController extends Controller
|
|||||||
* The request will also contain the amount
|
* The request will also contain the amount
|
||||||
* and invoice ids for reference.
|
* and invoice ids for reference.
|
||||||
*
|
*
|
||||||
* @param int $company_gateway_id The CompanyGateway ID
|
|
||||||
* @param int $gateway_type_id The gateway_type_id ID
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function process($company_gateway_id)
|
public function process()
|
||||||
{
|
{
|
||||||
|
|
||||||
$invoices = Invoice::whereIn('id', $this->transformKeys(request()->input('invoice_ids')))
|
$invoices = Invoice::whereIn('id', $this->transformKeys(explode(",",request()->input('hashed_ids'))))
|
||||||
->whereClientId(auth()->user()->client->id)
|
->whereClientId(auth()->user()->client->id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$amount = request()->input('amount');
|
$amount = $invoices->sum('balance');
|
||||||
|
|
||||||
//build a cache record to maintain state
|
$invoices->filter(function ($invoice){
|
||||||
$cache_hash = str_random(config('ninja.key_length'));
|
return $invoice->isPayable();
|
||||||
|
})->map(function ($invoice){
|
||||||
|
$invoice->balance = Number::formatMoney($invoice->balance, $invoice->client);
|
||||||
|
$invoice->due_date = $this->formatDate($invoice->due_date, $invoice->client->date_format());
|
||||||
|
return $invoice;
|
||||||
|
});
|
||||||
|
|
||||||
Cache::put($cache_hash, 'value', now()->addMinutes(10));
|
$payment_methods = auth()->user()->client->getPaymentMethods($amount);
|
||||||
|
|
||||||
//boot the payment gateway
|
//boot the payment gateway
|
||||||
$gateway = CompanyGateway::find($company_gateway_id);
|
$gateway = CompanyGateway::find(request()->input('company_gateway_id'));
|
||||||
|
|
||||||
|
$payment_method_id = request()->input('payment_method_id');
|
||||||
|
|
||||||
//if there is a gateway fee, now is the time to calculate it
|
//if there is a gateway fee, now is the time to calculate it
|
||||||
//and add it to the invoice
|
//and add it to the invoice
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'cache_hash' => $cache_hash,
|
|
||||||
'invoices' => $invoices,
|
'invoices' => $invoices,
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
'fee' => $gateway->calcGatewayFee($amount),
|
'fee' => $gateway->calcGatewayFee($amount),
|
||||||
'amount_with_fee' => ($amount + $gateway->calcGatewayFee($amount)),
|
'amount_with_fee' => $amount + $gateway->calcGatewayFee($amount),
|
||||||
'gateway' => $gateway,
|
'token' => auth()->user()->client->gateway_token($gateway->id, $payment_method_id),
|
||||||
'token' => auth()->user()->client->gateway_token($gateway->id),
|
'payment_method_id' => $payment_method_id,
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('gateways.pay_now', $data);
|
|
||||||
|
return $gateway->driver(auth()->user()->client)->processPayment($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,15 +110,15 @@ class Client extends BaseModel
|
|||||||
* Allows the storage of multiple tokens
|
* Allows the storage of multiple tokens
|
||||||
* per client per gateway per payment_method
|
* per client per gateway per payment_method
|
||||||
*
|
*
|
||||||
* @param int $gateway_id The gateway ID
|
* @param int $company_gateway_id The company gateway ID
|
||||||
* @param int $payment_method_id The payment method ID
|
* @param int $payment_method_id The payment method ID
|
||||||
* @return ClientGatewayToken The client token record
|
* @return ClientGatewayToken The client token record
|
||||||
*/
|
*/
|
||||||
public function gateway_token($gateway_id, $payment_method_id)
|
public function gateway_token($company_gateway_id, $payment_method_id)
|
||||||
{
|
{
|
||||||
return $this->gateway_tokens
|
return $this->gateway_tokens()
|
||||||
->whereCompanyGatewayId($gateway_id)
|
->whereCompanyGatewayId($company_gateway_id)
|
||||||
->wherePaymentMethod_id($payment_method_id)
|
->whereGatewayTypeId($payment_method_id)
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +264,14 @@ class Client extends BaseModel
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCurrencyCode()
|
||||||
|
{
|
||||||
|
if ($this->currency) {
|
||||||
|
return $this->currency->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'USD';
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Generates an array of payment urls per client
|
* Generates an array of payment urls per client
|
||||||
* for a given amount.
|
* for a given amount.
|
||||||
@ -326,9 +334,8 @@ class Client extends BaseModel
|
|||||||
|
|
||||||
$payment_urls[] = [
|
$payment_urls[] = [
|
||||||
'label' => ctrans('texts.' . $gateway->getTypeAlias($gateway_type_id)) . $fee_label,
|
'label' => ctrans('texts.' . $gateway->getTypeAlias($gateway_type_id)) . $fee_label,
|
||||||
'url' => URL::signedRoute('client.payments.process', [
|
|
||||||
'company_gateway_id' => $gateway_id,
|
'company_gateway_id' => $gateway_id,
|
||||||
'gateway_type_id' => $gateway_type_id])
|
'gateway_type_id' => $gateway_type_id
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
{
|
{
|
||||||
$types = [
|
$types = [
|
||||||
GatewayType::CREDIT_CARD,
|
GatewayType::CREDIT_CARD,
|
||||||
GatewayType::TOKEN,
|
//GatewayType::TOKEN,
|
||||||
];
|
];
|
||||||
|
|
||||||
if($this->company_gateway->getSofortEnabled() && $this->invitation && $this->client() && isset($this->client()->country) && in_array($this->client()->country, ['AUT', 'BEL', 'DEU', 'ITA', 'NLD', 'ESP']))
|
if($this->company_gateway->getSofortEnabled() && $this->invitation && $this->client() && isset($this->client()->country) && in_array($this->client()->country, ['AUT', 'BEL', 'DEU', 'ITA', 'NLD', 'ESP']))
|
||||||
@ -130,6 +130,7 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
|
|
||||||
public function authorizeCreditCardView($data)
|
public function authorizeCreditCardView($data)
|
||||||
{
|
{
|
||||||
|
|
||||||
$intent['intent'] = $this->getSetupIntent();
|
$intent['intent'] = $this->getSetupIntent();
|
||||||
|
|
||||||
return view('portal.default.gateways.stripe.add_credit_card', array_merge($data, $intent));
|
return view('portal.default.gateways.stripe.add_credit_card', array_merge($data, $intent));
|
||||||
@ -185,13 +186,52 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
return redirect()->route('client.payment_methods.index');
|
return redirect()->route('client.payment_methods.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the payment with this gateway
|
||||||
|
*
|
||||||
|
* @var invoices
|
||||||
|
* @var amount
|
||||||
|
* @var fee
|
||||||
|
* @var amount_with_fee
|
||||||
|
* @var token
|
||||||
|
* @var payment_method_id
|
||||||
|
* @param array $data variables required to build payment page
|
||||||
|
* @return view Gateway and payment method specific view
|
||||||
|
*/
|
||||||
|
public function processPayment(array $data)
|
||||||
|
{
|
||||||
|
$payment_intent_data = [
|
||||||
|
'amount' => $data['amount_with_fee']*100,
|
||||||
|
'currency' => $this->client->getCurrencyCode(),
|
||||||
|
'customer' => $this->findOrCreateCustomer(),
|
||||||
|
'description' => $data['invoices']->pluck('id'),
|
||||||
|
];
|
||||||
|
|
||||||
|
if($data['token'])
|
||||||
|
$payment_intent_data['payment_method'] = $data['token']->token;
|
||||||
|
else{
|
||||||
|
// $payment_intent_data['setup_future_usage'] = 'off_session';
|
||||||
|
// $payment_intent_data['save_payment_method'] = true;
|
||||||
|
// $payment_intent_data['confirm'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$data['intent'] = $this->createPaymentIntent($payment_intent_data);
|
||||||
|
$data['gateway'] = $this;
|
||||||
|
|
||||||
|
return view($this->viewForType($data['payment_method_id']), $data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new String Payment Intent
|
* Creates a new String Payment Intent
|
||||||
*
|
*
|
||||||
* @param array $data The data array to be passed to Stripe
|
* @param array $data The data array to be passed to Stripe
|
||||||
* @return PaymentIntent The Stripe payment intent object
|
* @return PaymentIntent The Stripe payment intent object
|
||||||
*/
|
*/
|
||||||
public function createIntent($data) :?\Stripe\PaymentIntent
|
public function createPaymentIntent($data) :?\Stripe\PaymentIntent
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->init();
|
$this->init();
|
||||||
@ -258,6 +298,9 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!$customer)
|
||||||
|
throw Exception('Unable to create gateway customer');
|
||||||
|
|
||||||
return $customer;
|
return $customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include($gateway->driver(auth()->user()->client)->viewForType($gateway_type_id))
|
@yield('pay_now')
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
{{ ctrans('texts.save') }}
|
{{ ctrans('texts.save') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
@extends('portal.default.gateways.pay_now')
|
||||||
|
|
||||||
|
@section('pay_now')
|
||||||
|
|
||||||
|
@if($token)
|
||||||
|
<div class="py-md-5 ninja stripe">
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" id="cardholder-name" type="text" placeholder="{{ ctrans('texts.name') }}">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="card-element"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button id="card-button" data-secret="{{ $intent->client_secret }}">
|
||||||
|
Submit Payment
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@else
|
||||||
|
<div class="py-md-5 ninja stripe">
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control" id="cardholder-name" type="text" placeholder="{{ ctrans('texts.name') }}">
|
||||||
|
</div>
|
||||||
|
<!-- placeholder for Elements -->
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="card-element" class="form-control"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check form-check-inline mr-1">
|
||||||
|
<input class="form-check-input" id="proxy_is_default" type="checkbox">
|
||||||
|
<label class="form-check-label" for="proxy_is_default">{{ ctrans('texts.save_as_default') }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="card-errors" role="alert"></div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<button id="card-button" class="btn btn-primary pull-right" data-secret="{{ $intent->client_secret }}">
|
||||||
|
{{ ctrans('texts.pay_now') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var stripe = Stripe('{{ $gateway->getPublishableKey() }}');
|
||||||
|
|
||||||
|
var elements = stripe.elements();
|
||||||
|
var cardElement = elements.create('card');
|
||||||
|
cardElement.mount('#card-element');
|
||||||
|
|
||||||
|
|
||||||
|
var cardholderName = document.getElementById('cardholder-name');
|
||||||
|
var cardButton = document.getElementById('card-button');
|
||||||
|
var clientSecret = cardButton.dataset.secret;
|
||||||
|
|
||||||
|
cardButton.addEventListener('click', function(ev) {
|
||||||
|
stripe.handleCardPayment(
|
||||||
|
clientSecret, cardElement, {
|
||||||
|
payment_method_data: {
|
||||||
|
billing_details: {name: cardholderName.value}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).then(function(result) {
|
||||||
|
if (result.error) {
|
||||||
|
// Display error.message in your UI.
|
||||||
|
// console.log(result.error);
|
||||||
|
// console.log(result.error.message);
|
||||||
|
|
||||||
|
$("#card-errors").empty();
|
||||||
|
$("#card-errors").append("<b>" + result.error.message + "</b>");
|
||||||
|
$("#card-button").removeAttr("disabled");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The setup has succeeded. Display a success message.
|
||||||
|
console.log(result);
|
||||||
|
postResult(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#card-button").attr("disabled", true);
|
||||||
|
|
||||||
|
$('#cardholder-name').on('input',function(e){
|
||||||
|
if($("#cardholder-name").val().length >=1)
|
||||||
|
$("#card-button").removeAttr("disabled");
|
||||||
|
else
|
||||||
|
$("#card-button").attr("disabled", true);
|
||||||
|
});
|
||||||
|
|
||||||
|
function postResult(result)
|
||||||
|
{
|
||||||
|
|
||||||
|
$("#gateway_response").val(JSON.stringify(result.setupIntent));
|
||||||
|
$("#is_default").val($('#proxy_is_default').is(":checked"));
|
||||||
|
$("#card-button").attr("disabled", true);
|
||||||
|
$('#server_response').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@push('css')
|
||||||
|
<style type="text/css">
|
||||||
|
.StripeElement {
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
padding: 10px 12px;
|
||||||
|
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
box-shadow: 0 1px 3px 0 #e6ebf1;
|
||||||
|
-webkit-transition: box-shadow 150ms ease;
|
||||||
|
transition: box-shadow 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.StripeElement--focus {
|
||||||
|
box-shadow: 0 1px 3px 0 #cfd7df;
|
||||||
|
}
|
||||||
|
|
||||||
|
.StripeElement--invalid {
|
||||||
|
border-color: #fa755a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.StripeElement--webkit-autofill {
|
||||||
|
background-color: #fefde5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
@endpush
|
@ -5,6 +5,19 @@
|
|||||||
@section('body')
|
@section('body')
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
{!! Former::framework('TwitterBootstrap4'); !!}
|
||||||
|
|
||||||
|
{!! Former::horizontal_open()
|
||||||
|
->id('payment_form')
|
||||||
|
->route('client.payments.process')
|
||||||
|
->method('POST'); !!}
|
||||||
|
|
||||||
|
{!! Former::hidden('hashed_ids')->id('hashed_ids')->value($hashed_ids) !!}
|
||||||
|
{!! Former::hidden('company_gateway_id')->id('company_gateway_id') !!}
|
||||||
|
{!! Former::hidden('payment_method_id')->id('payment_method_id') !!}
|
||||||
|
|
||||||
|
{!! Former::close() !!}
|
||||||
|
|
||||||
<div class="row" style="padding-top: 30px;">
|
<div class="row" style="padding-top: 30px;">
|
||||||
<div class="col d-flex justify-content-center">
|
<div class="col d-flex justify-content-center">
|
||||||
<div class="card w-50 p-10">
|
<div class="card w-50 p-10">
|
||||||
@ -43,21 +56,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="btn-group pull-right" role="group">
|
<div class="btn-group pull-right" role="group">
|
||||||
<button class="btn btn-primary dropdown-toggle" id="pay_now" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ ctrans('texts.pay_now') }}</button>
|
<button class="btn btn-primary dropdown-toggle" id="pay_now" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ ctrans('texts.pay_now') }}</button>
|
||||||
<div class="dropdown-menu" aria-labelledby="pay_now">
|
<div class="dropdown-menu" aria-labelledby="pay_now">
|
||||||
<a class="dropdown-item" href="#">Dropdown link</a>
|
@foreach($payment_methods as $payment_method)
|
||||||
<a class="dropdown-item" href="#">Dropdown link</a>
|
<a class="dropdown-item" onClick="paymentMethod({{ $payment_method['company_gateway_id'] }}, {{ $payment_method['gateway_type_id'] }})">{{$payment_method['label']}}</a>
|
||||||
</div>
|
@endforeach
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn-group pull-right">
|
|
||||||
<button type="button" class="btn btn-primary" id="pay_now">{{ ctrans('texts.pay_now') }}</button>
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" id="pay_now_drop" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<span class="sr-only">Toggle Dropdown</span>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<a class="dropdown-item" id="download_invoices">{{ctrans('texts.download_pdf')}}</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -172,6 +176,15 @@ $("#modal_pay_now_button").on('click', function(e){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function paymentMethod(company_gateway_id, payment_method_id)
|
||||||
|
{
|
||||||
|
$('#company_gateway_id').val(company_gateway_id);
|
||||||
|
$('#payment_method_id').val(payment_method_id);
|
||||||
|
$('#payment_form').submit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getSignature()
|
function getSignature()
|
||||||
{
|
{
|
||||||
//check in signature is required
|
//check in signature is required
|
||||||
|
@ -24,7 +24,7 @@ Route::group(['middleware' => ['auth:contact'], 'prefix' => 'client', 'as' => 'c
|
|||||||
Route::get('recurring_invoices', 'ClientPortal\RecurringInvoiceController@index')->name('recurring_invoices.index');
|
Route::get('recurring_invoices', 'ClientPortal\RecurringInvoiceController@index')->name('recurring_invoices.index');
|
||||||
|
|
||||||
Route::get('payments', 'ClientPortal\PaymentController@index')->name('payments.index');
|
Route::get('payments', 'ClientPortal\PaymentController@index')->name('payments.index');
|
||||||
Route::get('payments/{company_gateway_id}/{payment_method_id}', 'PaymentController@process')->name('payments.process')->middleware('signed');
|
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
|
||||||
|
|
||||||
Route::get('profile/{client_contact}/edit', 'ClientPortal\ProfileController@edit')->name('profile.edit');
|
Route::get('profile/{client_contact}/edit', 'ClientPortal\ProfileController@edit')->name('profile.edit');
|
||||||
Route::put('profile/{client_contact}/edit', 'ClientPortal\ProfileController@update')->name('profile.update');
|
Route::put('profile/{client_contact}/edit', 'ClientPortal\ProfileController@update')->name('profile.update');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user