diff --git a/VERSION.txt b/VERSION.txt index 686411917aea..e0178fd19665 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.10.21 \ No newline at end of file +5.10.22 \ No newline at end of file diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index dd84001f872e..e7ea1efd83d4 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -232,7 +232,7 @@ class BaseDriver extends AbstractPaymentDriver * * @param ClientGatewayToken $cgt The client gateway token object * @param PaymentHash $payment_hash The Payment hash containing the payment meta data - * @return void The payment response + * @return ?Payment|bool The payment response */ public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) { @@ -433,7 +433,7 @@ class BaseDriver extends AbstractPaymentDriver $invoice_item->tax_name2 = $fees_and_limits->fee_tax_name2; $invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3; $invoice_item->tax_name3 = $fees_and_limits->fee_tax_name3; - $invoice_item->tax_id = \App\Models\Product::PRODUCT_TYPE_OVERRIDE_TAX; + $invoice_item->tax_id = (string)\App\Models\Product::PRODUCT_TYPE_OVERRIDE_TAX; } $invoice->line_items = $invoice_items; diff --git a/app/PaymentDrivers/Factory/ForteCustomerFactory.php b/app/PaymentDrivers/Factory/ForteCustomerFactory.php index 613870fe42e2..e7c535221627 100644 --- a/app/PaymentDrivers/Factory/ForteCustomerFactory.php +++ b/app/PaymentDrivers/Factory/ForteCustomerFactory.php @@ -17,6 +17,54 @@ use App\Models\Company; class ForteCustomerFactory { + + public function convertToForte(Client $client): array + { + + return [ + "first_name" => $client->present()->first_name(), + "last_name" => $client->present()->last_name(), + "company_name" => $client->present()->name(), + "addresses" => [ + [ + "label" => "Billing Address", + "first_name" => $client->present()->first_name(), + "last_name" => $client->present()->last_name(), + "company_name" => $client->present()->name(), + "phone" => $client->present()->phone(), + "email" => $client->present()->email(), + "shipping_address_type" => "commercial", + "address_type" => "default_shipping", + "physical_address" => [ + "street_line1" => $client->address2, + "street_line2" => $client->address1, + "locality" => $client->city, + "region" => $client->state, + "postal_code" => $client->postal_code + ] + ], + // [ + // "label" => "Brown Billing", + // "first_name" => "Emmett", + // "last_name" => "Brown", + // "company_name" => "Brown Associates", + // "phone" => "444-444-4444", + // "email" => "e.brown@forte.net", + // "shipping_address_type" => "commercial", + // "address_type" => "default_billing", + // "physical_address" => [ + // "street_line1" => "500 Delorean Dr", + // "street_line2" => "Suite 200", + // "locality" => "Hill Valley", + // "region" => "CA", + // "postal_code" => "95420" + // ] + // ] + ] + ]; + + } + public function convertToNinja(array $customer, Company $company): array { return diff --git a/app/PaymentDrivers/Forte/CreditCard.php b/app/PaymentDrivers/Forte/CreditCard.php index 5a317f4ec8a7..16ceb030fdf0 100644 --- a/app/PaymentDrivers/Forte/CreditCard.php +++ b/app/PaymentDrivers/Forte/CreditCard.php @@ -12,6 +12,7 @@ namespace App\PaymentDrivers\Forte; +use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; @@ -59,22 +60,99 @@ class CreditCard public function authorizeResponse($request) { - $payment_meta = new \stdClass(); - $payment_meta->exp_month = (string) $request->expire_month; - $payment_meta->exp_year = (string) $request->expire_year; - $payment_meta->brand = (string) $request->card_type; - $payment_meta->last4 = (string) $request->last_4; - $payment_meta->type = GatewayType::CREDIT_CARD; + $cst = $this->forte->findOrCreateCustomer(); $data = [ - 'payment_meta' => $payment_meta, - 'token' => $request->one_time_token, - 'payment_method_id' => $request->payment_method_id, + "label" => $request->card_holders_name." " .$request->card_type, + "notes" => $request->card_holders_name." " .$request->card_type, + "card" => [ + "one_time_token" => $request->one_time_token, + "name_on_card" => $request->card_holders_name + ], ]; - $this->forte->storeGatewayToken($data); + $response = $this->forte->stubRequest() + ->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/customers/{$cst}/paymethods", $data); + + if($response->successful()){ + + $token = $response->object(); + + $payment_meta = new \stdClass(); + $payment_meta->exp_month = (string) $request->expire_month; + $payment_meta->exp_year = (string) $request->expire_year; + $payment_meta->brand = (string) $request->card_brand; + $payment_meta->last4 = (string) $request->last_4; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $token->paymethod_token, + 'payment_method_id' => $request->payment_method_id, + ]; + + $this->forte->storeGatewayToken($data, ['gateway_customer_reference' => $cst]); + + return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.'); + + } + + $error = $response->object(); + $message = [ + 'server_message' => $error->response->response_desc, + 'server_response' => $response->json(), + 'data' => $data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_FORTE, + $this->client, + $this->client->company, + ); + + throw new \App\Exceptions\PaymentFailed("Unable to store payment method: {$error->response->response_desc}", 400); + + } + + private function createPaymentToken($request) + { + $cst = $this->forte->findOrCreateCustomer(); + + $data = [ + "label" => $this->forte->client->present()->name(), + "notes" => $this->forte->client->present()->name(), + "card" => [ + "one_time_token" => $request->payment_token, + "name_on_card" => $this->forte->client->present()->first_name(). " ". $this->forte->client->present()->last_name() + ], + ]; + + $response = $this->forte->stubRequest() + ->post("{$this->forte->baseUri()}/organizations/{$this->forte->getOrganisationId()}/locations/{$this->forte->getLocationId()}/customers/{$cst}/paymethods", $data); + + if($response->successful()){ + + $token = $response->object(); + + $payment_meta = new \stdClass(); + $payment_meta->exp_month = (string) $request->expire_month; + $payment_meta->exp_year = (string) $request->expire_year; + $payment_meta->brand = (string) $request->card_brand; + $payment_meta->last4 = (string) $request->last_4; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $token->paymethod_token, + 'payment_method_id' => $request->payment_method_id, + ]; + + $this->forte->storeGatewayToken($data, ['gateway_customer_reference' => $cst]); + } - return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.'); } public function paymentView(array $data) @@ -88,7 +166,20 @@ class CreditCard public function paymentResponse(PaymentResponseRequest $request) { + $payment_hash = PaymentHash::where('hash', $request->input('payment_hash'))->firstOrFail(); + + if(strlen($request->token ?? '') > 3){ + + + $cgt = \App\Models\ClientGatewayToken::find($this->decodePrimaryKey($request->token)); + + $payment = $this->forte->tokenBilling($cgt, $payment_hash); + + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + + } + $amount_with_fee = $payment_hash->data->total->amount_with_fee; $invoice_totals = $payment_hash->data->total->invoice_totals; $fee_total = null; @@ -126,8 +217,8 @@ class CreditCard "authorization_amount":'.$amount_with_fee.', "service_fee_amount":'.$fee_total.', "billing_address":{ - "first_name":"'.$this->forte->client->name.'", - "last_name":"'.$this->forte->client->name.'" + "first_name":"'.$this->forte->client->present()->first_name().'", + "last_name":"'.$this->forte->client->present()->last_name().'" }, "card":{ "one_time_token":"'.$request->payment_token.'" @@ -146,6 +237,7 @@ class CreditCard curl_close($curl); $response = json_decode($response); + } catch (\Throwable $th) { throw $th; } @@ -187,7 +279,11 @@ class CreditCard 'gateway_type_id' => GatewayType::CREDIT_CARD, ]; $payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED); - // return redirect('client/invoices')->withSuccess('Invoice paid.'); + + if($request->store_card) { + $this->createPaymentToken($request); + } + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); } diff --git a/app/PaymentDrivers/FortePaymentDriver.php b/app/PaymentDrivers/FortePaymentDriver.php index 902b4a62e46f..90efcfa0c18b 100644 --- a/app/PaymentDrivers/FortePaymentDriver.php +++ b/app/PaymentDrivers/FortePaymentDriver.php @@ -11,6 +11,7 @@ namespace App\PaymentDrivers; +use App\Exceptions\PaymentFailed; use App\Models\Payment; use App\Models\SystemLog; use App\Models\GatewayType; @@ -224,7 +225,7 @@ class FortePaymentDriver extends BaseDriver return $forte_base_uri; } - private function getOrganisationId(): string + public function getOrganisationId(): string { return $this->company_gateway->getConfigField('organizationId'); } @@ -247,12 +248,90 @@ class FortePaymentDriver extends BaseDriver private function getClient(?string $email) { + if(!$email) + return false; + return ClientContact::query() ->where('company_id', $this->company_gateway->company_id) ->where('email', $email) ->first(); } + public function tokenBilling(\App\Models\ClientGatewayToken $cgt, \App\Models\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->client->present()->first_name(), + "last_name" => $this->client->present()->last_name() + ], + ]; + + if($fee_total > 0){ + $data["service_fee_amount"] = $fee_total; + } + + $response = $this->stubRequest() + ->post("{$this->baseUri()}/organizations/{$this->getOrganisationId()}/locations/{$this->getLocationId()}/transactions", $data); + + $forte_response = $response->object(); + + if($response->successful()){ + + $data = [ + 'payment_method' => $cgt->gateway_type_id, + 'payment_type' => $cgt->gateway_type_id == 2 ? \App\Models\PaymentType::ACH : \App\Models\PaymentType::CREDIT_CARD_OTHER, + 'amount' => $payment_hash->data->amount_with_fee, + 'transaction_reference' => $forte_response->transaction_id, + 'gateway_type_id' => $cgt->gateway_type_id, + ]; + + $payment = $this->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->client, + $this->client->company, + ); + + return $payment; + } + + $message = [ + 'server_message' => $forte_response->response->response_desc, + 'server_response' => $response->json(), + 'data' => $data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_FORTE, + $this->client, + $this->client->company, + ); + + throw new PaymentFailed($forte_response->response->response_desc, 500); + + } + public function getLocation() { @@ -264,6 +343,8 @@ class FortePaymentDriver extends BaseDriver return $response->json(); } + // return $response->body(); + return false; } @@ -297,6 +378,43 @@ class FortePaymentDriver extends BaseDriver } + public function findOrCreateCustomer() + { + + $client_gateway_token = \App\Models\ClientGatewayToken::query() + ->where('client_id', $this->client->id) + ->where('company_gateway_id', $this->company_gateway->id) + ->whereNotLike('token', 'ott_%') + ->first(); + + if($client_gateway_token){ + return $client_gateway_token->gateway_customer_reference; + } + else { + + $factory = new ForteCustomerFactory(); + $data = $factory->convertToForte($this->client); + + $response = $this->stubRequest() + ->post("{$this->baseUri()}/organizations/{$this->getOrganisationId()}/locations/{$this->getLocationId()}/customers/", $data); + + + //create customer + if($response->successful()){ + $customer = $response->object(); + nlog($customer); + return $customer->customer_token; + } + + nlog($response->body()); + + throw new PaymentFailed("Unable to create customer in Forte", 400); + + //@todo add syslog here + } + + } + public function importCustomers() { diff --git a/app/Services/Invoice/AddGatewayFee.php b/app/Services/Invoice/AddGatewayFee.php index 73e7064fe265..fc1365e92337 100644 --- a/app/Services/Invoice/AddGatewayFee.php +++ b/app/Services/Invoice/AddGatewayFee.php @@ -81,7 +81,7 @@ class AddGatewayFee extends AbstractService $invoice_item->tax_name2 = $fees_and_limits->fee_tax_name2; $invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3; $invoice_item->tax_name3 = $fees_and_limits->fee_tax_name3; - $invoice_item->tax_id = Product::PRODUCT_TYPE_OVERRIDE_TAX; + $invoice_item->tax_id = (string)Product::PRODUCT_TYPE_OVERRIDE_TAX; } $invoice_items = (array) $this->invoice->line_items; diff --git a/config/ninja.php b/config/ninja.php index 3044b8fc662a..b646985bb879 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.10.21'), - 'app_tag' => env('APP_TAG', '5.10.21'), + 'app_version' => env('APP_VERSION', '5.10.22'), + 'app_tag' => env('APP_TAG', '5.10.22'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), diff --git a/public/build/assets/forte-credit-card-payment-b605ccf2.js b/public/build/assets/forte-credit-card-payment-b605ccf2.js deleted file mode 100644 index 563ebe666f15..000000000000 --- a/public/build/assets/forte-credit-card-payment-b605ccf2.js +++ /dev/null @@ -1,9 +0,0 @@ -var a=Object.defineProperty;var d=(n,e,t)=>e in n?a(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var r=(n,e,t)=>(d(n,typeof e!="symbol"?e+"":e,t),t);/** - * 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 o{constructor(e){r(this,"handleAuthorization",()=>{var e=$("#my-card"),t={api_login_id:this.apiLoginId,card_number:e.CardJs("cardNumber").replace(/[^\d]/g,""),expire_year:e.CardJs("expiryYear").replace(/[^\d]/g,""),expire_month:e.CardJs("expiryMonth").replace(/[^\d]/g,""),cvv:document.getElementById("cvv").value.replace(/[^\d]/g,"")};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(t).success(this.successResponseHandler).error(this.failedResponseHandler),!1});r(this,"successResponseHandler",e=>(document.getElementById("payment_token").value=e.onetime_token,document.getElementById("card_brand").value=e.card_type,document.getElementById("server_response").submit(),!1));r(this,"failedResponseHandler",e=>{var t='
";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});r(this,"handle",()=>{let e=document.getElementById("pay-now");return e&&e.addEventListener("click",t=>{this.handleAuthorization()}),this});this.apiLoginId=e,this.cardHolderName=document.getElementById("cardholder_name")}}const s=document.querySelector('meta[name="forte-api-login-id"]').content;new o(s).handle(); diff --git a/public/build/assets/forte-credit-card-payment-d2571506.js b/public/build/assets/forte-credit-card-payment-d2571506.js new file mode 100644 index 000000000000..f83e7ebe4209 --- /dev/null +++ b/public/build/assets/forte-credit-card-payment-d2571506.js @@ -0,0 +1,9 @@ +var r=Object.defineProperty;var l=(n,e,t)=>e in n?r(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var d=(n,e,t)=>(l(n,typeof e!="symbol"?e+"":e,t),t);/** + * 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){d(this,"handleAuthorization",()=>{var e=$("#my-card"),t={api_login_id:this.apiLoginId,card_number:e.CardJs("cardNumber").replace(/[^\d]/g,""),expire_year:e.CardJs("expiryYear").replace(/[^\d]/g,""),expire_month:e.CardJs("expiryMonth").replace(/[^\d]/g,""),cvv:document.getElementById("cvv").value.replace(/[^\d]/g,"")};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(t).success(this.successResponseHandler).error(this.failedResponseHandler),!1});d(this,"successResponseHandler",e=>{document.getElementById("payment_token").value=e.onetime_token,document.getElementById("card_brand").value=e.card_type,document.getElementById("expire_year").value=e.expire_year,document.getElementById("expire_month").value=e.expire_month,document.getElementById("last_4").value=e.last_4;let t=document.querySelector("input[name=token-billing-checkbox]:checked");return t&&(document.getElementById("store_card").value=t.value),document.getElementById("server_response").submit(),!1});d(this,"failedResponseHandler",e=>{var t='
";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});d(this,"handle",()=>{Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(o=>o.addEventListener("click",a=>{document.getElementById("save-card--container").style.display="none",document.getElementById("forte--credit-card-container").style.display="none",document.getElementById("token").value=a.target.dataset.token}));let e=document.getElementById("toggle-payment-with-credit-card");e&&e.addEventListener("click",()=>{document.getElementById("save-card--container").style.display="grid",document.getElementById("forte--credit-card-container").style.display="flex",document.getElementById("token").value=null});let t=document.getElementById("pay-now");return t&&t.addEventListener("click",o=>{let a=document.getElementById("token");a.value?this.handlePayNowAction(a.value):this.handleAuthorization()}),this});this.apiLoginId=e,this.cardHolderName=document.getElementById("cardholder_name")}handlePayNowAction(e){document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),document.getElementById("token").value=e,document.getElementById("server_response").submit()}}const i=document.querySelector('meta[name="forte-api-login-id"]').content;new c(i).handle(); diff --git a/public/build/manifest.json b/public/build/manifest.json index 954c5b5476eb..1d965290072b 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -86,7 +86,7 @@ "src": "resources/js/clients/payments/forte-ach-payment.js" }, "resources/js/clients/payments/forte-credit-card-payment.js": { - "file": "assets/forte-credit-card-payment-b605ccf2.js", + "file": "assets/forte-credit-card-payment-d2571506.js", "isEntry": true, "src": "resources/js/clients/payments/forte-credit-card-payment.js" }, diff --git a/resources/js/clients/payments/forte-credit-card-payment.js b/resources/js/clients/payments/forte-credit-card-payment.js index 0139356a4daa..e406d2153911 100644 --- a/resources/js/clients/payments/forte-credit-card-payment.js +++ b/resources/js/clients/payments/forte-credit-card-payment.js @@ -41,8 +41,18 @@ class ForteAuthorizeCard { }; successResponseHandler = (response) => { + document.getElementById('payment_token').value = response.onetime_token; - document.getElementById('card_brand').value = response.card_type; + document.getElementById('card_brand').value = response.card_brand; + document.getElementById('expire_year').value = response.expire_year; + document.getElementById('expire_month').value = response.expire_month; + document.getElementById('last_4').value = response.last_4; + + let storeCard = document.querySelector('input[name=token-billing-checkbox]:checked'); + + if (storeCard) { + document.getElementById("store_card").value = storeCard.value; + } document.getElementById('server_response').submit(); @@ -62,17 +72,94 @@ class ForteAuthorizeCard { return false; }; + + handlePayNowAction(token_hashed_id) { + document.getElementById('pay-now').disabled = true; + document.querySelector('#pay-now > svg').classList.remove('hidden'); + document.querySelector('#pay-now > span').classList.add('hidden'); + + document.getElementById("token").value = token_hashed_id; + document.getElementById("server_response").submit(); + } + + handle = () => { + Array + .from(document.getElementsByClassName('toggle-payment-with-token')) + .forEach((element) => element.addEventListener('click', (e) => { + document + .getElementById('save-card--container').style.display = 'none'; + document + .getElementById('forte--credit-card-container').style.display = 'none'; + + document + .getElementById('token').value = e.target.dataset.token; + })); + + let payWithCreditCardToggle = document.getElementById('toggle-payment-with-credit-card'); + + if (payWithCreditCardToggle) { + payWithCreditCardToggle + .addEventListener('click', () => { + document + .getElementById('save-card--container').style.display = 'grid'; + document + .getElementById('forte--credit-card-container').style.display = 'flex'; + + document + .getElementById('token').value = null; + }); + } + let payNowButton = document.getElementById('pay-now'); if (payNowButton) { - payNowButton.addEventListener('click', (e) => { - this.handleAuthorization(); - }); + payNowButton + .addEventListener('click', (e) => { + let token = document.getElementById('token'); + + token.value + ? this.handlePayNowAction(token.value) + : this.handleAuthorization(); + }); } return this; - }; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } const apiLoginId = document.querySelector( diff --git a/resources/views/portal/ninja2020/gateways/forte/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/forte/credit_card/pay.blade.php index 7f54fc61251d..bb5901a58230 100644 --- a/resources/views/portal/ninja2020/gateways/forte/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/forte/credit_card/pay.blade.php @@ -12,6 +12,9 @@
@csrf + + + @@ -32,10 +35,39 @@ @include('portal.ninja2020.gateways.includes.payment_details') - @component('portal.ninja2020.components.general.card-element', ['title' => 'Pay with Credit Card']) - @include('portal.ninja2020.gateways.forte.includes.credit_card') + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) + @endcomponent + @include('portal.ninja2020.gateways.includes.save_card') + @include('portal.ninja2020.gateways.forte.includes.credit_card') @include('portal.ninja2020.gateways.includes.pay_now') @endsection diff --git a/resources/views/portal/ninja2020/gateways/forte/includes/credit_card.blade.php b/resources/views/portal/ninja2020/gateways/forte/includes/credit_card.blade.php index 5183e72986ed..b15c3332764a 100644 --- a/resources/views/portal/ninja2020/gateways/forte/includes/credit_card.blade.php +++ b/resources/views/portal/ninja2020/gateways/forte/includes/credit_card.blade.php @@ -1,5 +1,5 @@
+ style="display: flex!important; justify-content: center!important;" id="forte--credit-card-container">
diff --git a/resources/views/portal/ninja2020/gateways/stripe/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/stripe/credit_card/pay.blade.php index 4b693f89d15e..9042dc94d991 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/credit_card/pay.blade.php @@ -51,10 +51,10 @@ @include('portal.ninja2020.gateways.includes.payment_details') @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) -
    +
      @if(count($tokens) > 0) @foreach($tokens as $token) -
    • +