Fixes for intercepting gateway feels that are between 0.01 and 0

This commit is contained in:
David Bomba 2025-03-25 14:04:16 +11:00
parent 0b02ec4e3c
commit b5f3aa790e
10 changed files with 350 additions and 217 deletions

View File

@ -255,6 +255,7 @@ class CompanyGatewayController extends BaseController
$company_gateway->setConfig($config); $company_gateway->setConfig($config);
$company_gateway->save(); $company_gateway->save();
dispatch(function () use ($company_gateway) { dispatch(function () use ($company_gateway) {
MultiDB::setDb($company_gateway->company->db); MultiDB::setDb($company_gateway->company->db);
$company_gateway->driver()->updateFees(); $company_gateway->driver()->updateFees();
@ -263,6 +264,7 @@ class CompanyGatewayController extends BaseController
break; break;
case $this->cbapowerboard_key: case $this->cbapowerboard_key:
dispatch(function () use ($company_gateway) { dispatch(function () use ($company_gateway) {
MultiDB::setDb($company_gateway->company->db); MultiDB::setDb($company_gateway->company->db);
$company_gateway->driver()->init()->settings()->updateSettings(); $company_gateway->driver()->init()->settings()->updateSettings();

View File

@ -12,17 +12,19 @@
namespace App\PaymentDrivers\Forte; namespace App\PaymentDrivers\Forte;
use App\Http\Requests\Request;
use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
use App\Models\SystemLog;
use App\Models\GatewayType;
use App\Models\PaymentHash; use App\Models\PaymentHash;
use App\Models\PaymentType; use App\Models\PaymentType;
use App\Models\SystemLog; use App\Http\Requests\Request;
use App\PaymentDrivers\Common\LivewireMethodInterface; use App\Jobs\Util\SystemLogger;
use App\PaymentDrivers\FortePaymentDriver;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use App\Models\ClientGatewayToken;
use App\Exceptions\PaymentFailed;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use App\PaymentDrivers\FortePaymentDriver;
use App\PaymentDrivers\Common\LivewireMethodInterface;
class ACH implements LivewireMethodInterface class ACH implements LivewireMethodInterface
{ {
@ -59,22 +61,22 @@ class ACH implements LivewireMethodInterface
return render('gateways.forte.ach.authorize', $data); return render('gateways.forte.ach.authorize', $data);
} }
public function authorizeResponse(Request $request) private function storePaymentMethod(array $payload)
{ {
$cst = $this->forte->findOrCreateCustomer(); $cst = $this->forte->findOrCreateCustomer();
$name = $request->account_holder_name;
$data = [ $data = [
"notes" => $request->account_holder_name, "notes" => $payload['account_holder_name'],
"echeck" => [ "echeck" => [
"one_time_token" => $request->one_time_token, "one_time_token" => $payload['one_time_token'],
"account_holder" => $request->account_holder_name, "account_holder" => $payload['account_holder_name'],
"account_type" => "checking" "account_type" => "checking"
], ],
]; ];
$response = $this->forte->stubRequest() $response = $this->forte
->stubRequest()
->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/customers/{$cst}/paymethods", $data); ->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/customers/{$cst}/paymethods", $data);
if ($response->successful()) { if ($response->successful()) {
@ -85,7 +87,7 @@ class ACH implements LivewireMethodInterface
$payment_meta->exp_month = (string) ''; $payment_meta->exp_month = (string) '';
$payment_meta->exp_year = (string) ''; $payment_meta->exp_year = (string) '';
$payment_meta->brand = (string) 'ACH'; $payment_meta->brand = (string) 'ACH';
$payment_meta->last4 = (string) $request->last_4; $payment_meta->last4 = (string) $payload['last_4'];
$payment_meta->type = GatewayType::BANK_TRANSFER; $payment_meta->type = GatewayType::BANK_TRANSFER;
$data = [ $data = [
@ -94,13 +96,14 @@ class ACH implements LivewireMethodInterface
'payment_method_id' => GatewayType::BANK_TRANSFER, 'payment_method_id' => GatewayType::BANK_TRANSFER,
]; ];
$this->forte->storeGatewayToken($data, ['gateway_customer_reference' => $cst]); $cgt = $this->forte->storeGatewayToken($data, ['gateway_customer_reference' => $cst]);
return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.'); return $cgt;
} }
$error = $response->object(); $error = $response->object();
$message = [ $message = [
'server_message' => $error->response->response_desc, 'server_message' => $error->response->response_desc,
'server_response' => $response->json(), 'server_response' => $response->json(),
@ -120,6 +123,21 @@ class ACH implements LivewireMethodInterface
} }
public function authorizeResponse(Request $request)
{
$data = [
'account_holder_name' => $request->account_holder_name,
'one_time_token' => $request->one_time_token,
'last_4' => $request->last_4,
];
$cgt = $this->storePaymentMethod($data);
return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.');
}
public function paymentView(array $data) public function paymentView(array $data)
{ {
$data = $this->paymentData($data); $data = $this->paymentData($data);
@ -129,75 +147,63 @@ class ACH implements LivewireMethodInterface
public function paymentResponse($request) public function paymentResponse($request)
{ {
nlog($request->all());
$payment_hash = PaymentHash::where('hash', $request->input('payment_hash'))->firstOrFail(); $payment_hash = PaymentHash::where('hash', $request->input('payment_hash'))->firstOrFail();
try { //Handle Token Billing
$curl = curl_init(); if($request->token && strlen($request->token) > 4){
curl_setopt_array($curl, [
CURLOPT_URL => $this->forte_base_uri.'organizations/'.$this->forte_organization_id.'/locations/'.$this->forte_location_id.'/transactions',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{
"action":"sale",
"authorization_amount": '.$payment_hash->data->total->amount_with_fee.',
"echeck":{
"sec_code":"PPD",
},
"billing_address":{
"first_name": "'.$this->forte->client->name.'",
"last_name": "'.$this->forte->client->name.'"
},
"echeck":{
"one_time_token":"'.$request->payment_token.'"
}
}',
CURLOPT_HTTPHEADER => [
'X-Forte-Auth-Organization-Id: '.$this->forte_organization_id,
'Content-Type: application/json',
'Authorization: Basic '.base64_encode($this->forte_api_access_id.':'.$this->forte_secure_key),
],
]);
$response = curl_exec($curl); $cgt = \App\Models\ClientGatewayToken::where('token', $request->token)->firstOrFail();
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $payment = $this->tokenBilling($cgt, $payment_hash);
curl_close($curl); return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]);
$response = json_decode($response);
} catch (\Throwable $th) {
throw $th;
} }
$message = [ //Handle Storing Payment Method + Token Billing
'server_message' => $response->response->response_desc, if(isset($this->forte->company_gateway->token_billing) && $this->forte->company_gateway->token_billing != 'off'){
'server_response' => $response,
'data' => $payment_hash->data, $data = [
'account_holder_name' => $request->account_holder_name,
'one_time_token' => $request->payment_token,
'last_4' => $request->last_4,
]; ];
if ($httpcode > 299) { $cgt = $this->storePaymentMethod($data);
SystemLogger::dispatch(
$message,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_FORTE,
$this->forte->client,
$this->forte->client->company,
);
$error = Validator::make([], []); $payment = $this->tokenBilling($cgt, $payment_hash);
$error->getMessageBag()->add('gateway_error', $response->response->response_desc); return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]);
return redirect()->route('client.invoice.show', ['invoice' => $payment_hash->fee_invoice->hashed_id])->withErrors($error);
// return response()->redirect('client/invoices')->withErrors($error);
} }
$data = [
'action' => 'sale',
'authorization_amount' => $payment_hash->data->total->amount_with_fee,
'echeck' => [
'sec_code' => 'PPD',
'one_time_token' => $request->payment_token
],
'billing_address' => [
'first_name' => $this->forte->client->name,
'last_name' => $this->forte->client->name
]
];
$response = $this->forte
->stubRequest()
->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/transactions", $data);
if ($response->successful()) {
$forte_response = $response->object();
$message = [
'server_message' => $forte_response->response->response_desc,
'server_response' => $forte_response,
'data' => $payment_hash->data,
];
SystemLogger::dispatch( SystemLogger::dispatch(
$message, $message,
SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::CATEGORY_GATEWAY_RESPONSE,
@ -211,15 +217,120 @@ class ACH implements LivewireMethodInterface
'payment_method' => $request->payment_method_id, 'payment_method' => $request->payment_method_id,
'payment_type' => PaymentType::ACH, 'payment_type' => PaymentType::ACH,
'amount' => $payment_hash->data->amount_with_fee, 'amount' => $payment_hash->data->amount_with_fee,
'transaction_reference' => $response->transaction_id, 'transaction_reference' => $forte_response->transaction_id,
'gateway_type_id' => GatewayType::BANK_TRANSFER, 'gateway_type_id' => GatewayType::BANK_TRANSFER,
]; ];
$payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED); $payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED);
// return redirect('client/invoices')->withSuccess('Invoice paid.');
return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]);
}
//Handle Failures.
$forte_response = $response->object();
$message = [
'server_message' => $forte_response->response->response_desc,
'server_response' => $forte_response,
'data' => $payment_hash->data,
];
SystemLogger::dispatch(
$message,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_FORTE,
$this->forte->client,
$this->forte->client->company,
);
$error = Validator::make([], []);
$error->getMessageBag()->add('gateway_error', $forte_response->response->response_desc);
return redirect()->route('client.invoice.show', ['invoice' => $payment_hash->fee_invoice->hashed_id])->withErrors($error);
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
$amount_with_fee = $payment_hash->data->amount_with_fee;
$fee_total = $payment_hash->fee_total;
$data = [
"action" => "sale",
"authorization_amount" => $amount_with_fee,
"paymethod_token" => $cgt->token,
"billing_address" => [
"first_name" => $this->forte->client->present()->first_name(),
"last_name" => $this->forte->client->present()->last_name()
],
"echeck" => [
"sec_code" => "WEB",
]
];
if ($fee_total > 0) {
$data["service_fee_amount"] = $fee_total;
}
$response = $this->forte
->stubRequest()
->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/transactions", $data);
$forte_response = $response->object();
if ($response->successful()) {
$data = [
'payment_method' => $cgt->gateway_type_id,
'payment_type' => \App\Models\PaymentType::ACH,
'amount' => $payment_hash->data->amount_with_fee,
'transaction_reference' => $forte_response->transaction_id,
'gateway_type_id' => $cgt->gateway_type_id,
];
$payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED);
$message = [
'server_message' => $forte_response->response->response_desc,
'server_response' => $response->json(),
'data' => $data,
];
SystemLogger::dispatch(
$message,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_FORTE,
$this->forte->client,
$this->forte->client->company,
);
return $payment;
}
$forte_response = $response->object();
$message = [
'server_message' => $forte_response->response->response_desc,
'server_response' => $forte_response,
'data' => $payment_hash->data,
];
SystemLogger::dispatch(
$message,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_FORTE,
$this->forte->client,
$this->forte->client->company,
);
throw new PaymentFailed($forte_response->response->response_desc ?? 'Unable to process payment', 500);
} }
/** /**

View File

@ -29,7 +29,7 @@ class AddGatewayFee extends AbstractService
{ {
$gateway_fee = round($this->company_gateway->calcGatewayFee($this->amount, $this->gateway_type_id, $this->invoice->uses_inclusive_taxes), $this->invoice->client->currency()->precision); $gateway_fee = round($this->company_gateway->calcGatewayFee($this->amount, $this->gateway_type_id, $this->invoice->uses_inclusive_taxes), $this->invoice->client->currency()->precision);
if (! $gateway_fee || $gateway_fee == 0) { if (! $gateway_fee || $gateway_fee == 0 || ($gateway_fee > 0 && $gateway_fee < 0.01)) {
return $this->invoice; return $this->invoice;
} }

File diff suppressed because one or more lines are too long

View File

@ -1,9 +0,0 @@
var s=Object.defineProperty;var d=(n,e,t)=>e in n?s(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var o=(n,e,t)=>(d(n,typeof e!="symbol"?e+"":e,t),t);import{i,w as u}from"./wait-8f4ae121.js";/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/class c{constructor(e){o(this,"handleAuthorization",()=>{var e=document.getElementById("account-number").value,t=document.getElementById("routing-number").value,r={api_login_id:this.apiLoginId,account_number:e,routing_number:t,account_type:"checking"};return document.getElementById("pay-now")&&(document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden")),forte.createToken(r).success(this.successResponseHandler).error(this.failedResponseHandler),!1});o(this,"successResponseHandler",e=>(document.getElementById("payment_token").value=e.onetime_token,document.getElementById("server_response").submit(),!1));o(this,"failedResponseHandler",e=>{var t='<div class="alert alert-failure mb-4"><ul><li>'+e.response_description+"</li></ul></div>";return document.getElementById("forte_errors").innerHTML=t,document.getElementById("pay-now").disabled=!1,document.querySelector("#pay-now > svg").classList.add("hidden"),document.querySelector("#pay-now > span").classList.remove("hidden"),!1});o(this,"handle",()=>{let e=document.getElementById("pay-now");return e&&e.addEventListener("click",t=>{this.handleAuthorization()}),this});this.apiLoginId=e}}function a(){const n=document.querySelector('meta[name="forte-api-login-id"]').content;new c(n).handle()}i()?a():u("#force-ach-payment").then(()=>a());

View File

@ -12,7 +12,7 @@
"file": "assets/wait-8f4ae121.js" "file": "assets/wait-8f4ae121.js"
}, },
"resources/js/app.js": { "resources/js/app.js": {
"file": "assets/app-059c169b.js", "file": "assets/app-9bdef65d.js",
"imports": [ "imports": [
"_index-08e160a7.js", "_index-08e160a7.js",
"__commonjsHelpers-725317a4.js" "__commonjsHelpers-725317a4.js"
@ -126,7 +126,7 @@
"src": "resources/js/clients/payments/eway-credit-card.js" "src": "resources/js/clients/payments/eway-credit-card.js"
}, },
"resources/js/clients/payments/forte-ach-payment.js": { "resources/js/clients/payments/forte-ach-payment.js": {
"file": "assets/forte-ach-payment-546428ee.js", "file": "assets/forte-ach-payment-4cd2417c.js",
"imports": [ "imports": [
"_wait-8f4ae121.js" "_wait-8f4ae121.js"
], ],

View File

@ -43,7 +43,8 @@ class ForteAuthorizeACH {
successResponseHandler = (response) => { successResponseHandler = (response) => {
document.getElementById('payment_token').value = response.onetime_token; document.getElementById('payment_token').value = response.onetime_token;
document.getElementById('last_4').value = response.last_4;
document.getElementById('account_holder_name').value = document.getElementById('account-holder-name').value;
document.getElementById('server_response').submit(); document.getElementById('server_response').submit();
return false; return false;
@ -62,11 +63,65 @@ class ForteAuthorizeACH {
return false; return false;
}; };
completePaymentUsingToken() {
let payNowButton = document.getElementById('pay-now');
this.payNowButton = payNowButton;
this.payNowButton.disabled = true;
this.payNowButton.querySelector('svg').classList.remove('hidden');
this.payNowButton.querySelector('span').classList.add('hidden');
document.getElementById('server_response').submit();
return false;
}
handle = () => { handle = () => {
Array.from(
document.getElementsByClassName('toggle-payment-with-token')
).forEach((element) =>
element.addEventListener('click', (element) => {
document
.getElementById('forte-payment-container')
.classList.add('hidden');
document.querySelector('input[name=token]').value =
element.target.dataset.token;
})
);
document
.getElementById('toggle-payment-with-new-bank-account')
.addEventListener('click', (element) => {
document
.getElementById('forte-payment-container')
.classList.remove('hidden');
document.querySelector('input[name=token]').value = '';
});
let payNowButton = document.getElementById('pay-now'); let payNowButton = document.getElementById('pay-now');
if (payNowButton) { if (payNowButton) {
payNowButton.addEventListener('click', (e) => { payNowButton.addEventListener('click', (e) => {
let tokenInput =
document.querySelector('input[name=token]');
console.log(tokenInput.value);
if (tokenInput.value) {
return this.completePaymentUsingToken();
}
console.log("whoopsie");
this.handleAuthorization(); this.handleAuthorization();
}); });
} }

View File

@ -18,6 +18,8 @@
<input type="hidden" name="store_card" id="store_card"/> <input type="hidden" name="store_card" id="store_card"/>
<input type="submit" style="display: none" id="form_btn"> <input type="submit" style="display: none" id="form_btn">
<input type="hidden" name="payment_token" id="payment_token"> <input type="hidden" name="payment_token" id="payment_token">
<input type="hidden" name="last_4" id="last_4">
<input type="hidden" name="account_holder_name" id="account_holder_name">
</form> </form>
<div id="forte_errors"></div> <div id="forte_errors"></div>
@ -28,7 +30,42 @@
@include('portal.ninja2020.gateways.includes.payment_details') @include('portal.ninja2020.gateways.includes.payment_details')
@component('portal.ninja2020.components.general.card-element', ['title' => 'Pay with Bank Transfer']) @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
<ul class="list-none">
@if(count($tokens) > 0)
@foreach($tokens as $token)
<li class="py-2 cursor-pointer">
<label class="flex items-center cursor-pointer px-2">
<input
type="radio"
data-token="{{ $token->token }}"
name="payment-type"
class="form-check-input text-indigo-600 rounded-full cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ $token->meta?->last4 }}</span>
</label>
</li>
@endforeach
@endisset
<li class="py-2 cursor-pointer">
<label class="flex items-center cursor-pointer px-2">
<input
type="radio"
id="toggle-payment-with-new-bank-account"
class="form-check-input text-indigo-600 rounded-full cursor-pointer"
name="payment-type"
checked/>
<span class="ml-1 cursor-pointer">{{ __('texts.new_bank_account') }}</span>
</label>
</li>
<li>
<div id="forte-payment-container">
<div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"
style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="account-holder-name" type="text" placeholder="{{ctrans('texts.account_holder_name')}}" required>
</div>
<div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6" <div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"
style="display: flex!important; justify-content: center!important;"> style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="routing-number" type="text" placeholder="{{ctrans('texts.routing_number')}}" required> <input class="input w-full" id="routing-number" type="text" placeholder="{{ctrans('texts.routing_number')}}" required>
@ -37,8 +74,14 @@
style="display: flex!important; justify-content: center!important;"> style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="account-number" type="text" placeholder="{{ctrans('texts.account_number')}}" required> <input class="input w-full" id="account-number" type="text" placeholder="{{ctrans('texts.account_number')}}" required>
</div> </div>
</div>
</li>
</ul>
@endcomponent @endcomponent
@include('portal.ninja2020.gateways.includes.pay_now') @include('portal.ninja2020.gateways.includes.pay_now')
@endsection @endsection

View File

@ -14,6 +14,8 @@
<input type="hidden" name="store_card" id="store_card"/> <input type="hidden" name="store_card" id="store_card"/>
<input type="submit" style="display: none" id="form_btn"> <input type="submit" style="display: none" id="form_btn">
<input type="hidden" name="payment_token" id="payment_token"> <input type="hidden" name="payment_token" id="payment_token">
<input type="hidden" name="last_4" id="last_4">
<input type="hidden" name="account_holder_name" id="account_holder_name">
</form> </form>
<div id="forte_errors"></div> <div id="forte_errors"></div>
@ -24,7 +26,41 @@
@include('portal.ninja2020.gateways.includes.payment_details') @include('portal.ninja2020.gateways.includes.payment_details')
@component('portal.ninja2020.components.general.card-element', ['title' => 'Pay with Bank Transfer']) @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
<ul class="list-none">
@if(count($tokens) > 0)
@foreach($tokens as $token)
<li class="py-2 cursor-pointer">
<label class="flex items-center cursor-pointer px-2">
<input
type="radio"
data-token="{{ $token->token }}"
name="payment-type"
class="form-check-input text-indigo-600 rounded-full cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">**** {{ $token->meta?->last4 }}</span>
</label>
</li>
@endforeach
@endisset
<li class="py-2 cursor-pointer">
<label class="flex items-center cursor-pointer px-2">
<input
type="radio"
id="toggle-payment-with-new-bank-account"
class="form-check-input text-indigo-600 rounded-full cursor-pointer"
name="payment-type"
checked/>
<span class="ml-1 cursor-pointer">{{ __('texts.new_bank_account') }}</span>
</label>
</li>
<li>
<div id="forte-payment-container">
<div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"
style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="account-holder-name" type="text" placeholder="{{ctrans('texts.account_holder_name')}}" required>
</div>
<div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6" <div class="bg-white px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"
style="display: flex!important; justify-content: center!important;"> style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="routing-number" type="text" placeholder="{{ctrans('texts.routing_number')}}" required> <input class="input w-full" id="routing-number" type="text" placeholder="{{ctrans('texts.routing_number')}}" required>
@ -33,8 +69,12 @@
style="display: flex!important; justify-content: center!important;"> style="display: flex!important; justify-content: center!important;">
<input class="input w-full" id="account-number" type="text" placeholder="{{ctrans('texts.account_number')}}" required> <input class="input w-full" id="account-number" type="text" placeholder="{{ctrans('texts.account_number')}}" required>
</div> </div>
</div>
</li>
</ul>
@endcomponent @endcomponent
@include('portal.ninja2020.gateways.includes.pay_now') @include('portal.ninja2020.gateways.includes.pay_now')
</div> </div>