mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Merge pull request #7373 from kishanmnpatel/forte_payment_driver
Forte payment driver
This commit is contained in:
commit
50402559a5
@ -63,6 +63,8 @@ class Gateway extends StaticModel
|
||||
$link = 'https://applications.sagepay.com/apply/2C02C252-0F8A-1B84-E10D-CF933EFCAA99';
|
||||
} elseif ($this->id == 20 || $this->id == 56) {
|
||||
$link = 'https://dashboard.stripe.com/account/apikeys';
|
||||
} elseif ($this->id == 59) {
|
||||
$link = 'https://www.forte.net/';
|
||||
}
|
||||
|
||||
return $link;
|
||||
@ -170,6 +172,12 @@ class Gateway extends StaticModel
|
||||
GatewayType::HOSTED_PAGE => ['refund' => false, 'token_billing' => false, 'webhooks' => [' ']] // Razorpay
|
||||
];
|
||||
break;
|
||||
case 59:
|
||||
return [
|
||||
GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], // Forte
|
||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']],
|
||||
];
|
||||
break;
|
||||
default:
|
||||
return [];
|
||||
break;
|
||||
|
150
app/PaymentDrivers/Forte/ACH.php
Normal file
150
app/PaymentDrivers/Forte/ACH.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Forte;
|
||||
|
||||
use App\Models\Payment;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\PaymentDrivers\FortePaymentDriver;
|
||||
|
||||
class ACH
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public $forte;
|
||||
|
||||
private $forte_base_uri="";
|
||||
private $forte_api_access_id="";
|
||||
private $forte_secure_key="";
|
||||
private $forte_auth_organization_id="";
|
||||
private $forte_organization_id="";
|
||||
private $forte_location_id="";
|
||||
|
||||
public function __construct(FortePaymentDriver $forte)
|
||||
{
|
||||
$this->forte = $forte;
|
||||
|
||||
$this->forte_base_uri = "https://sandbox.forte.net/api/v3/";
|
||||
if($this->forte->company_gateway->getConfigField('testMode') == false){
|
||||
$this->forte_base_uri = "https://api.forte.net/v3/";
|
||||
}
|
||||
$this->forte_api_access_id = $this->forte->company_gateway->getConfigField('apiAccessId');
|
||||
$this->forte_secure_key = $this->forte->company_gateway->getConfigField('secureKey');
|
||||
$this->forte_auth_organization_id = $this->forte->company_gateway->getConfigField('authOrganizationId');
|
||||
$this->forte_organization_id = $this->forte->company_gateway->getConfigField('organizationId');
|
||||
$this->forte_location_id = $this->forte->company_gateway->getConfigField('locationId');
|
||||
}
|
||||
|
||||
public function authorizeView(array $data)
|
||||
{
|
||||
return render('gateways.forte.ach.authorize', $data);
|
||||
}
|
||||
|
||||
public function authorizeResponse(Request $request)
|
||||
{
|
||||
|
||||
$payment_meta = new \stdClass;
|
||||
$payment_meta->brand = (string)ctrans('texts.ach');
|
||||
$payment_meta->last4 = (string) $request->last_4;
|
||||
$payment_meta->exp_year = '-';
|
||||
$payment_meta->type = GatewayType::BANK_TRANSFER;
|
||||
|
||||
$data = [
|
||||
'payment_meta' => $payment_meta,
|
||||
'token' => $request->one_time_token,
|
||||
'payment_method_id' => $request->gateway_type_id,
|
||||
];
|
||||
|
||||
$this->forte->storeGatewayToken($data);
|
||||
|
||||
return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.');
|
||||
}
|
||||
|
||||
public function paymentView(array $data)
|
||||
{
|
||||
$this->forte->payment_hash->data = array_merge((array) $this->forte->payment_hash->data, $data);
|
||||
$this->forte->payment_hash->save();
|
||||
|
||||
$data['gateway'] = $this;
|
||||
return render('gateways.forte.ach.pay', $data);
|
||||
}
|
||||
|
||||
public function paymentResponse($request)
|
||||
{
|
||||
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->input('payment_hash')])->firstOrFail();
|
||||
|
||||
try {
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, array(
|
||||
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 => array(
|
||||
'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),
|
||||
'Cookie: visid_incap_621087=u18+3REYR/iISgzZxOF5s2ODW2IAAAAAQUIPAAAAAADuGqKgECQLS81FcSDrmhGe; nlbi_621087=YHngadhJ2VU+yr7/R1efXgAAAAD3mQyhqmnLls8PRu4iN58G; incap_ses_1136_621087=CVdrXUdhIlm9WJNDieLDD4QVXGIAAAAAvBwvkUcwhM0+OwvdPm2stg=='
|
||||
),
|
||||
));
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
$response=json_decode($response);
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
|
||||
if ($httpcode>299) {
|
||||
$error = Validator::make([], []);
|
||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||
return redirect('client/invoices')->withErrors($error);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'payment_method' => $request->payment_method_id,
|
||||
'payment_type' => PaymentType::ACH,
|
||||
'amount' => $payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $response->transaction_id,
|
||||
'gateway_type_id' => GatewayType::BANK_TRANSFER,
|
||||
];
|
||||
|
||||
$payment=$this->forte->createPayment($data, Payment::STATUS_COMPLETED);
|
||||
return redirect('client/invoices')->withSuccess('Invoice paid.');
|
||||
}
|
||||
}
|
160
app/PaymentDrivers/Forte/CreditCard.php
Normal file
160
app/PaymentDrivers/Forte/CreditCard.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Forte;
|
||||
|
||||
use App\Models\Payment;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\PaymentDrivers\FortePaymentDriver;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
|
||||
class CreditCard
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public $forte;
|
||||
|
||||
private $forte_base_uri="";
|
||||
private $forte_api_access_id="";
|
||||
private $forte_secure_key="";
|
||||
private $forte_auth_organization_id="";
|
||||
private $forte_organization_id="";
|
||||
private $forte_location_id="";
|
||||
|
||||
public function __construct(FortePaymentDriver $forte)
|
||||
{
|
||||
$this->forte = $forte;
|
||||
|
||||
$this->forte_base_uri = "https://sandbox.forte.net/api/v3/";
|
||||
if($this->forte->company_gateway->getConfigField('testMode') == false){
|
||||
$this->forte_base_uri = "https://api.forte.net/v3/";
|
||||
}
|
||||
$this->forte_api_access_id = $this->forte->company_gateway->getConfigField('apiAccessId');
|
||||
$this->forte_secure_key = $this->forte->company_gateway->getConfigField('secureKey');
|
||||
$this->forte_auth_organization_id = $this->forte->company_gateway->getConfigField('authOrganizationId');
|
||||
$this->forte_organization_id = $this->forte->company_gateway->getConfigField('organizationId');
|
||||
$this->forte_location_id = $this->forte->company_gateway->getConfigField('locationId');
|
||||
}
|
||||
|
||||
public function authorizeView(array $data)
|
||||
{
|
||||
return render('gateways.forte.credit_card.authorize', $data);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
$data = [
|
||||
'payment_meta' => $payment_meta,
|
||||
'token' => $request->one_time_token,
|
||||
'payment_method_id' => $request->payment_method_id,
|
||||
];
|
||||
|
||||
$this->forte->storeGatewayToken($data);
|
||||
|
||||
return redirect()->route('client.payment_methods.index')->withSuccess('Payment Method added.');
|
||||
}
|
||||
|
||||
public function paymentView(array $data)
|
||||
{
|
||||
$this->forte->payment_hash->data = array_merge((array) $this->forte->payment_hash->data, $data);
|
||||
$this->forte->payment_hash->save();
|
||||
|
||||
$data['gateway'] = $this;
|
||||
return render('gateways.forte.credit_card.pay', $data);
|
||||
}
|
||||
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->input('payment_hash')])->firstOrFail();
|
||||
$amount_with_fee = $payment_hash->data->total->amount_with_fee;
|
||||
$invoice_totals = $payment_hash->data->total->invoice_totals;
|
||||
$fee_total = 0;
|
||||
print_r($payment_hash->data->total);
|
||||
for ($i = ($invoice_totals * 100) ; $i < ($amount_with_fee * 100); $i++) {
|
||||
$calculated_fee = ( 3 * $i) / 100;
|
||||
$calculated_amount_with_fee = round(($i + $calculated_fee) / 100,2);
|
||||
if ($calculated_amount_with_fee == $amount_with_fee) {
|
||||
$fee_total = round($calculated_fee / 100,2);
|
||||
$amount_with_fee = $calculated_amount_with_fee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$curl = curl_init();
|
||||
|
||||
curl_setopt_array($curl, array(
|
||||
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":'.$amount_with_fee.',
|
||||
"service_fee_amount":'.$fee_total.',
|
||||
"billing_address":{
|
||||
"first_name":"'.$this->forte->client->name.'",
|
||||
"last_name":"'.$this->forte->client->name.'"
|
||||
},
|
||||
"card":{
|
||||
"one_time_token":"'.$request->payment_token.'"
|
||||
}
|
||||
}',
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
'Content-Type: application/json',
|
||||
'X-Forte-Auth-Organization-Id: '.$this->forte_organization_id,
|
||||
'Authorization: Basic '.base64_encode($this->forte_api_access_id.':'.$this->forte_secure_key)
|
||||
),
|
||||
));
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
$response=json_decode($response);
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
if ($httpcode>299) {
|
||||
$error = Validator::make([], []);
|
||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||
return redirect('client/invoices')->withErrors($error);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'payment_method' => $request->payment_method_id,
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($request->card_brand)) ?: PaymentType::CREDIT_CARD_OTHER,
|
||||
'amount' => $payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $response->transaction_id,
|
||||
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
||||
];
|
||||
$payment=$this->forte->createPayment($data, Payment::STATUS_COMPLETED);
|
||||
return redirect('client/invoices')->withSuccess('Invoice paid.');
|
||||
}
|
||||
}
|
90
app/PaymentDrivers/FortePaymentDriver.php
Normal file
90
app/PaymentDrivers/FortePaymentDriver.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers;
|
||||
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\GatewayType;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\PaymentDrivers\Forte\ACH;
|
||||
use App\PaymentDrivers\Forte\CreditCard;
|
||||
|
||||
class FortePaymentDriver extends BaseDriver
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public $refundable = true; //does this gateway support refunds?
|
||||
|
||||
public $token_billing = true; //does this gateway support token billing?
|
||||
|
||||
public $can_authorise_credit_card = true; //does this gateway support authorizations?
|
||||
|
||||
public $gateway; //initialized gateway
|
||||
|
||||
public $payment_method; //initialized payment method
|
||||
|
||||
public static $methods = [
|
||||
GatewayType::CREDIT_CARD => CreditCard::class,
|
||||
GatewayType::BANK_TRANSFER => ACH::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the gateway types.
|
||||
*/
|
||||
public function gatewayTypes(): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
$types[] = GatewayType::CREDIT_CARD;
|
||||
$types[] = GatewayType::BANK_TRANSFER;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_STRIPE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
|
||||
|
||||
public function setPaymentMethod($payment_method_id)
|
||||
{
|
||||
$class = self::$methods[$payment_method_id];
|
||||
$this->payment_method = new $class($this);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function authorizeView(array $data)
|
||||
{
|
||||
return $this->payment_method->authorizeView($data); //this is your custom implementation from here
|
||||
}
|
||||
|
||||
public function authorizeResponse($request)
|
||||
{
|
||||
return $this->payment_method->authorizeResponse($request); //this is your custom implementation from here
|
||||
}
|
||||
|
||||
public function processPaymentView(array $data)
|
||||
{
|
||||
return $this->payment_method->paymentView($data); //this is your custom implementation from here
|
||||
}
|
||||
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
return $this->payment_method->paymentResponse($request); //this is your custom implementation from here
|
||||
}
|
||||
|
||||
// public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||
// {
|
||||
// return $this->payment_method->yourRefundImplementationHere(); //this is your custom implementation from here
|
||||
// }
|
||||
|
||||
// public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||
// {
|
||||
// return $this->payment_method->yourTokenBillingImplmentation(); //this is your custom implementation from here
|
||||
// }
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Gateway;
|
||||
use App\Models\GatewayType;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class FortePaymentGateway extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$fields = new \stdClass;
|
||||
$fields->testMode = false;
|
||||
$fields->apiLoginId = "";
|
||||
$fields->apiAccessId = "";
|
||||
$fields->secureKey = "";
|
||||
$fields->authOrganizationId = "";
|
||||
$fields->organizationId = "";
|
||||
$fields->locationId = "";
|
||||
|
||||
$forte = new Gateway;
|
||||
$forte->id = 59;
|
||||
$forte->name = 'Forte';
|
||||
$forte->key = 'kivcvjexxvdiyqtj3mju5d6yhpeht2xs';
|
||||
$forte->provider = 'Forte';
|
||||
$forte->is_offsite = true;
|
||||
$forte->fields = \json_encode($fields);
|
||||
$forte->visible = 1;
|
||||
$forte->site_url = 'https://www.forte.net/';
|
||||
$forte->default_gateway_type_id = GatewayType::CREDIT_CARD;
|
||||
$forte->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
|
||||
Gateway::query()->update(['visible' => 0]);
|
||||
|
||||
Gateway::whereIn('id', [1,3,7,11,15,20,39,46,55,50,57,52,58])->update(['visible' => 1]);
|
||||
Gateway::whereIn('id', [1,3,7,11,15,20,39,46,55,50,57,52,58,59])->update(['visible' => 1]);
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
Gateway::whereIn('id', [20])->update(['visible' => 0]);
|
||||
|
81
public/js/clients/payments/forte-ach-payment.js
vendored
Normal file
81
public/js/clients/payments/forte-ach-payment.js
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
var __webpack_exports__ = {};
|
||||
/*!************************************************************!*\
|
||||
!*** ./resources/js/clients/payments/forte-ach-payment.js ***!
|
||||
\************************************************************/
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
var ForteAuthorizeACH = function ForteAuthorizeACH(apiLoginId) {
|
||||
var _this = this;
|
||||
|
||||
_classCallCheck(this, ForteAuthorizeACH);
|
||||
|
||||
_defineProperty(this, "handleAuthorization", function () {
|
||||
var account_number = document.getElementById('account-number').value;
|
||||
var routing_number = document.getElementById('routing-number').value;
|
||||
var data = {
|
||||
api_login_id: _this.apiLoginId,
|
||||
account_number: account_number,
|
||||
routing_number: routing_number,
|
||||
account_type: 'checking'
|
||||
};
|
||||
var payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
document.getElementById('pay-now').disabled = true;
|
||||
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||
} // console.log(data);
|
||||
|
||||
|
||||
forte.createToken(data).success(_this.successResponseHandler).error(_this.failedResponseHandler);
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "successResponseHandler", function (response) {
|
||||
document.getElementById('payment_token').value = response.onetime_token;
|
||||
document.getElementById('server_response').submit();
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "failedResponseHandler", function (response) {
|
||||
var errors = '<div class="alert alert-failure mb-4"><ul><li>' + response.response_description + '</li></ul></div>';
|
||||
document.getElementById('forte_errors').innerHTML = errors;
|
||||
document.getElementById('pay-now').disabled = false;
|
||||
document.querySelector('#pay-now > svg').classList.add('hidden');
|
||||
document.querySelector('#pay-now > span').classList.remove('hidden');
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "handle", function () {
|
||||
var payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
payNowButton.addEventListener('click', function (e) {
|
||||
_this.handleAuthorization();
|
||||
});
|
||||
}
|
||||
|
||||
return _this;
|
||||
});
|
||||
|
||||
this.apiLoginId = apiLoginId;
|
||||
};
|
||||
|
||||
var apiLoginId = document.querySelector('meta[name="forte-api-login-id"]').content;
|
||||
/** @handle */
|
||||
|
||||
new ForteAuthorizeACH(apiLoginId).handle();
|
||||
/******/ })()
|
||||
;
|
669
public/js/clients/payments/forte-card-js.min.js
vendored
Normal file
669
public/js/clients/payments/forte-card-js.min.js
vendored
Normal file
@ -0,0 +1,669 @@
|
||||
(() => {
|
||||
function t(t) {
|
||||
(this.elem = jQuery(t)),
|
||||
(this.captureName =
|
||||
!!this.elem.data('capture-name') &&
|
||||
this.elem.data('capture-name')),
|
||||
(this.iconColour =
|
||||
!!this.elem.data('icon-colour') &&
|
||||
this.elem.data('icon-colour')),
|
||||
(this.stripe =
|
||||
!!this.elem.data('stripe') && this.elem.data('stripe')),
|
||||
this.stripe && (this.captureName = !1),
|
||||
this.initCardNumberInput(),
|
||||
this.initNameInput(),
|
||||
this.initExpiryMonthInput(),
|
||||
this.initExpiryYearInput(),
|
||||
this.initCvcInput(),
|
||||
this.elem.empty(),
|
||||
this.setupCardNumberInput(),
|
||||
this.setupNameInput(),
|
||||
this.setupExpiryInput(),
|
||||
this.setupCvcInput(),
|
||||
this.iconColour && this.setIconColour(this.iconColour),
|
||||
this.refreshCreditCardTypeIcon();
|
||||
}
|
||||
!(function (e) {
|
||||
var r = {
|
||||
init: function () {
|
||||
return this.data('cardjs', new t(this)), this;
|
||||
},
|
||||
cardNumber: function () {
|
||||
return this.data('cardjs').getCardNumber();
|
||||
},
|
||||
cardType: function () {
|
||||
return this.data('cardjs').getCardType();
|
||||
},
|
||||
name: function () {
|
||||
return this.data('cardjs').getName();
|
||||
},
|
||||
expiryMonth: function () {
|
||||
return this.data('cardjs').getExpiryMonth();
|
||||
},
|
||||
expiryYear: function () {
|
||||
return this.data('cardjs').getExpiryYear();
|
||||
},
|
||||
cvc: function () {
|
||||
return this.data('cardjs').getCvc();
|
||||
},
|
||||
};
|
||||
e.fn.CardJs = function (t) {
|
||||
return r[t]
|
||||
? r[t].apply(this, Array.prototype.slice.call(arguments, 1))
|
||||
: 'object' != typeof t && t
|
||||
? void e.error(
|
||||
'Method ' + t + ' does not exist on jQuery.CardJs'
|
||||
)
|
||||
: r.init.apply(this, arguments);
|
||||
};
|
||||
})(jQuery),
|
||||
$(function () {
|
||||
$('.card-js').each(function (t, e) {
|
||||
$(e).CardJs();
|
||||
});
|
||||
}),
|
||||
(t.prototype.constructor = t),
|
||||
(t.KEYS = {
|
||||
0: 48,
|
||||
9: 57,
|
||||
NUMPAD_0: 96,
|
||||
NUMPAD_9: 105,
|
||||
DELETE: 46,
|
||||
BACKSPACE: 8,
|
||||
ARROW_LEFT: 37,
|
||||
ARROW_RIGHT: 39,
|
||||
ARROW_UP: 38,
|
||||
ARROW_DOWN: 40,
|
||||
HOME: 36,
|
||||
END: 35,
|
||||
TAB: 9,
|
||||
A: 65,
|
||||
X: 88,
|
||||
C: 67,
|
||||
V: 86,
|
||||
}),
|
||||
(t.CREDIT_CARD_NUMBER_DEFAULT_MASK = 'XXXX XXXX XXXX XXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_VISA_MASK = 'XXXX XXXX XXXX XXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_MASTERCARD_MASK = 'XXXX XXXX XXXX XXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_DISCOVER_MASK = 'XXXX XXXX XXXX XXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_JCB_MASK = 'XXXX XXXX XXXX XXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_AMEX_MASK = 'XXXX XXXXXX XXXXX'),
|
||||
(t.CREDIT_CARD_NUMBER_DINERS_MASK = 'XXXX XXXX XXXX XX'),
|
||||
(t.prototype.creditCardNumberMask = t.CREDIT_CARD_NUMBER_DEFAULT_MASK),
|
||||
(t.CREDIT_CARD_NUMBER_PLACEHOLDER = 'Card number'),
|
||||
(t.NAME_PLACEHOLDER = 'Name on card'),
|
||||
(t.EXPIRY_MASK = 'XX / XXXX'),
|
||||
(t.EXPIRY_PLACEHOLDER = 'MM / YYYY'),
|
||||
(t.EXPIRY_USE_DROPDOWNS = !1),
|
||||
(t.EXPIRY_NUMBER_OF_YEARS = 10),
|
||||
(t.CVC_MASK_3 = 'XXX'),
|
||||
(t.CVC_MASK_4 = 'XXXX'),
|
||||
(t.CVC_PLACEHOLDER = 'CVC'),
|
||||
(t.CREDIT_CARD_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="3px" width="24px" height="17px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><g><path class="svg" d="M182.385,14.258c-2.553-2.553-5.621-3.829-9.205-3.829H42.821c-3.585,0-6.653,1.276-9.207,3.829c-2.553,2.553-3.829,5.621-3.829,9.206v99.071c0,3.585,1.276,6.654,3.829,9.207c2.554,2.553,5.622,3.829,9.207,3.829H173.18c3.584,0,6.652-1.276,9.205-3.829s3.83-5.622,3.83-9.207V23.464C186.215,19.879,184.938,16.811,182.385,14.258z M175.785,122.536c0,0.707-0.258,1.317-0.773,1.834c-0.516,0.515-1.127,0.772-1.832,0.772H42.821c-0.706,0-1.317-0.258-1.833-0.773c-0.516-0.518-0.774-1.127-0.774-1.834V73h135.571V122.536z M175.785,41.713H40.214v-18.25c0-0.706,0.257-1.316,0.774-1.833c0.516-0.515,1.127-0.773,1.833-0.773H173.18c0.705,0,1.316,0.257,1.832,0.773c0.516,0.517,0.773,1.127,0.773,1.833V41.713z"/><rect class="svg" x="50.643" y="104.285" width="20.857" height="10.429"/><rect class="svg" x="81.929" y="104.285" width="31.286" height="10.429"/></g></svg>'),
|
||||
(t.LOCK_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="3px" width="24px" height="17px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><path class="svg" d="M152.646,70.067c-1.521-1.521-3.367-2.281-5.541-2.281H144.5V52.142c0-9.994-3.585-18.575-10.754-25.745c-7.17-7.17-15.751-10.755-25.746-10.755s-18.577,3.585-25.746,10.755C75.084,33.567,71.5,42.148,71.5,52.142v15.644h-2.607c-2.172,0-4.019,0.76-5.54,2.281c-1.521,1.52-2.281,3.367-2.281,5.541v46.929c0,2.172,0.76,4.019,2.281,5.54c1.521,1.52,3.368,2.281,5.54,2.281h78.214c2.174,0,4.02-0.76,5.541-2.281c1.52-1.521,2.281-3.368,2.281-5.54V75.607C154.93,73.435,154.168,71.588,152.646,70.067z M128.857,67.786H87.143V52.142c0-5.757,2.037-10.673,6.111-14.746c4.074-4.074,8.989-6.11,14.747-6.11s10.673,2.036,14.746,6.11c4.073,4.073,6.11,8.989,6.11,14.746V67.786z"/></svg>'),
|
||||
(t.CALENDAR_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="4px" width="24px" height="16px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><path class="svg" d="M172.691,23.953c-2.062-2.064-4.508-3.096-7.332-3.096h-10.428v-7.822c0-3.584-1.277-6.653-3.83-9.206c-2.554-2.553-5.621-3.83-9.207-3.83h-5.213c-3.586,0-6.654,1.277-9.207,3.83c-2.554,2.553-3.83,5.622-3.83,9.206v7.822H92.359v-7.822c0-3.584-1.277-6.653-3.83-9.206c-2.553-2.553-5.622-3.83-9.207-3.83h-5.214c-3.585,0-6.654,1.277-9.207,3.83c-2.553,2.553-3.83,5.622-3.83,9.206v7.822H50.643c-2.825,0-5.269,1.032-7.333,3.096s-3.096,4.509-3.096,7.333v104.287c0,2.823,1.032,5.267,3.096,7.332c2.064,2.064,4.508,3.096,7.333,3.096h114.714c2.824,0,5.27-1.032,7.332-3.096c2.064-2.064,3.096-4.509,3.096-7.332V31.286C175.785,28.461,174.754,26.017,172.691,23.953z M134.073,13.036c0-0.761,0.243-1.386,0.731-1.874c0.488-0.488,1.113-0.733,1.875-0.733h5.213c0.762,0,1.385,0.244,1.875,0.733c0.488,0.489,0.732,1.114,0.732,1.874V36.5c0,0.761-0.244,1.385-0.732,1.874c-0.49,0.488-1.113,0.733-1.875,0.733h-5.213c-0.762,0-1.387-0.244-1.875-0.733s-0.731-1.113-0.731-1.874V13.036z M71.501,13.036c0-0.761,0.244-1.386,0.733-1.874c0.489-0.488,1.113-0.733,1.874-0.733h5.214c0.761,0,1.386,0.244,1.874,0.733c0.488,0.489,0.733,1.114,0.733,1.874V36.5c0,0.761-0.244,1.386-0.733,1.874c-0.489,0.488-1.113,0.733-1.874,0.733h-5.214c-0.761,0-1.386-0.244-1.874-0.733c-0.488-0.489-0.733-1.113-0.733-1.874V13.036z M165.357,135.572H50.643V52.143h114.714V135.572z"/></svg>'),
|
||||
(t.USER_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="4px" width="24px" height="16px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><g><path class="svg" d="M107.999,73c8.638,0,16.011-3.056,22.12-9.166c6.111-6.11,9.166-13.483,9.166-22.12c0-8.636-3.055-16.009-9.166-22.12c-6.11-6.11-13.484-9.165-22.12-9.165c-8.636,0-16.01,3.055-22.12,9.165c-6.111,6.111-9.166,13.484-9.166,22.12c0,8.637,3.055,16.01,9.166,22.12C91.99,69.944,99.363,73,107.999,73z"/><path class="svg" d="M165.07,106.037c-0.191-2.743-0.571-5.703-1.141-8.881c-0.57-3.178-1.291-6.124-2.16-8.84c-0.869-2.715-2.037-5.363-3.504-7.943c-1.466-2.58-3.15-4.78-5.052-6.6s-4.223-3.272-6.965-4.358c-2.744-1.086-5.772-1.63-9.085-1.63c-0.489,0-1.63,0.584-3.422,1.752s-3.815,2.472-6.069,3.911c-2.254,1.438-5.188,2.743-8.799,3.909c-3.612,1.168-7.237,1.752-10.877,1.752c-3.639,0-7.264-0.584-10.876-1.752c-3.611-1.166-6.545-2.471-8.799-3.909c-2.254-1.439-4.277-2.743-6.069-3.911c-1.793-1.168-2.933-1.752-3.422-1.752c-3.313,0-6.341,0.544-9.084,1.63s-5.065,2.539-6.966,4.358c-1.901,1.82-3.585,4.02-5.051,6.6s-2.634,5.229-3.503,7.943c-0.869,2.716-1.589,5.662-2.159,8.84c-0.571,3.178-0.951,6.137-1.141,8.881c-0.19,2.744-0.285,5.554-0.285,8.433c0,6.517,1.983,11.664,5.948,15.439c3.965,3.774,9.234,5.661,15.806,5.661h71.208c6.572,0,11.84-1.887,15.806-5.661c3.966-3.775,5.948-8.921,5.948-15.439C165.357,111.591,165.262,108.78,165.07,106.037z"/></g></svg>'),
|
||||
(t.MAIL_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"x="0px" y="4px" width="24px" height="16px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><path class="svg" d="M177.171,19.472c-2.553-2.553-5.622-3.829-9.206-3.829H48.036c-3.585,0-6.654,1.276-9.207,3.829C36.276,22.025,35,25.094,35,28.679v88.644c0,3.585,1.276,6.652,3.829,9.205c2.553,2.555,5.622,3.83,9.207,3.83h119.929c3.584,0,6.653-1.275,9.206-3.83c2.554-2.553,3.829-5.621,3.829-9.205V28.679C181,25.094,179.725,22.025,177.171,19.472zM170.57,117.321c0,0.706-0.258,1.317-0.774,1.833s-1.127,0.773-1.832,0.773H48.035c-0.706,0-1.317-0.257-1.833-0.773c-0.516-0.516-0.774-1.127-0.774-1.833V54.75c1.738,1.955,3.612,3.748,5.622,5.377c14.557,11.189,26.126,20.368,34.708,27.538c2.77,2.336,5.024,4.155,6.762,5.459s4.087,2.62,7.047,3.951s5.744,1.995,8.351,1.995H108h0.081c2.606,0,5.392-0.664,8.351-1.995c2.961-1.331,5.311-2.647,7.049-3.951c1.737-1.304,3.992-3.123,6.762-5.459c8.582-7.17,20.15-16.349,34.707-27.538c2.01-1.629,3.885-3.422,5.621-5.377V117.321z M170.57,30.797v0.896c0,3.204-1.262,6.776-3.787,10.713c-2.525,3.938-5.256,7.075-8.188,9.41c-10.484,8.257-21.373,16.865-32.672,25.827c-0.326,0.271-1.277,1.073-2.852,2.403c-1.574,1.331-2.824,2.351-3.748,3.056c-0.924,0.707-2.131,1.562-3.625,2.566s-2.865,1.752-4.114,2.24s-2.417,0.732-3.503,0.732H108h-0.082c-1.086,0-2.253-0.244-3.503-0.732c-1.249-0.488-2.621-1.236-4.114-2.24c-1.493-1.004-2.702-1.859-3.625-2.566c-0.923-0.705-2.173-1.725-3.748-3.056c-1.575-1.33-2.526-2.132-2.852-2.403c-11.297-8.962-22.187-17.57-32.67-25.827c-7.985-6.3-11.977-14.013-11.977-23.138c0-0.706,0.258-1.317,0.774-1.833c0.516-0.516,1.127-0.774,1.833-0.774h119.929c0.434,0.244,0.814,0.312,1.141,0.204c0.326-0.11,0.57,0.094,0.732,0.61c0.163,0.516,0.312,0.76,0.448,0.733c0.136-0.027,0.218,0.312,0.245,1.019c0.025,0.706,0.039,1.061,0.039,1.061V30.797z"/></svg>'),
|
||||
(t.INFORMATION_SVG =
|
||||
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="4px" width="24px" height="16px" viewBox="0 0 216 146" enable-background="new 0 0 216 146" xml:space="preserve"><g><path class="svg" d="M97.571,41.714h20.859c1.411,0,2.633-0.516,3.666-1.548c1.031-1.031,1.547-2.254,1.547-3.666V20.857c0-1.412-0.516-2.634-1.549-3.667c-1.031-1.031-2.254-1.548-3.666-1.548H97.571c-1.412,0-2.634,0.517-3.666,1.548c-1.032,1.032-1.548,2.255-1.548,3.667V36.5c0,1.412,0.516,2.635,1.548,3.666C94.937,41.198,96.159,41.714,97.571,41.714z"/><path class="svg" d="M132.523,111.048c-1.031-1.032-2.254-1.548-3.666-1.548h-5.215V62.571c0-1.412-0.516-2.634-1.547-3.666c-1.033-1.032-2.255-1.548-3.666-1.548H87.143c-1.412,0-2.634,0.516-3.666,1.548c-1.032,1.032-1.548,2.254-1.548,3.666V73c0,1.412,0.516,2.635,1.548,3.666c1.032,1.032,2.254,1.548,3.666,1.548h5.215V109.5h-5.215c-1.412,0-2.634,0.516-3.666,1.548c-1.032,1.032-1.548,2.254-1.548,3.666v10.429c0,1.412,0.516,2.635,1.548,3.668c1.032,1.03,2.254,1.547,3.666,1.547h41.714c1.412,0,2.634-0.517,3.666-1.547c1.031-1.033,1.547-2.256,1.547-3.668v-10.429C134.07,113.302,133.557,112.08,132.523,111.048z"/></g></svg>'),
|
||||
(t.keyCodeFromEvent = function (t) {
|
||||
return t.which || t.keyCode;
|
||||
}),
|
||||
(t.keyIsCommandFromEvent = function (t) {
|
||||
return t.ctrlKey || t.metaKey;
|
||||
}),
|
||||
(t.keyIsNumber = function (e) {
|
||||
return t.keyIsTopNumber(e) || t.keyIsKeypadNumber(e);
|
||||
}),
|
||||
(t.keyIsTopNumber = function (e) {
|
||||
var r = t.keyCodeFromEvent(e);
|
||||
return r >= t.KEYS[0] && r <= t.KEYS[9];
|
||||
}),
|
||||
(t.keyIsKeypadNumber = function (e) {
|
||||
var r = t.keyCodeFromEvent(e);
|
||||
return r >= t.KEYS.NUMPAD_0 && r <= t.KEYS.NUMPAD_9;
|
||||
}),
|
||||
(t.keyIsDelete = function (e) {
|
||||
return t.keyCodeFromEvent(e) == t.KEYS.DELETE;
|
||||
}),
|
||||
(t.keyIsBackspace = function (e) {
|
||||
return t.keyCodeFromEvent(e) == t.KEYS.BACKSPACE;
|
||||
}),
|
||||
(t.keyIsDeletion = function (e) {
|
||||
return t.keyIsDelete(e) || t.keyIsBackspace(e);
|
||||
}),
|
||||
(t.keyIsArrow = function (e) {
|
||||
var r = t.keyCodeFromEvent(e);
|
||||
return r >= t.KEYS.ARROW_LEFT && r <= t.KEYS.ARROW_DOWN;
|
||||
}),
|
||||
(t.keyIsNavigation = function (e) {
|
||||
var r = t.keyCodeFromEvent(e);
|
||||
return r == t.KEYS.HOME || r == t.KEYS.END;
|
||||
}),
|
||||
(t.keyIsKeyboardCommand = function (e) {
|
||||
var r = t.keyCodeFromEvent(e);
|
||||
return (
|
||||
t.keyIsCommandFromEvent(e) &&
|
||||
(r == t.KEYS.A ||
|
||||
r == t.KEYS.X ||
|
||||
r == t.KEYS.C ||
|
||||
r == t.KEYS.V)
|
||||
);
|
||||
}),
|
||||
(t.keyIsTab = function (e) {
|
||||
return t.keyCodeFromEvent(e) == t.KEYS.TAB;
|
||||
}),
|
||||
(t.copyAllElementAttributes = function (t, e) {
|
||||
$.each(t[0].attributes, function (t, r) {
|
||||
e.attr(r.nodeName, r.nodeValue);
|
||||
});
|
||||
}),
|
||||
(t.numbersOnlyString = function (t) {
|
||||
for (var e = '', r = 0; r < t.length; r++) {
|
||||
var n = t.charAt(r);
|
||||
!isNaN(parseInt(n)) && (e += n);
|
||||
}
|
||||
return e;
|
||||
}),
|
||||
(t.applyFormatMask = function (t, e) {
|
||||
for (var r = '', n = 0, i = 0; i < e.length; i++) {
|
||||
var a = e[i];
|
||||
if ('X' == a) {
|
||||
if (!t.charAt(n)) break;
|
||||
(r += t.charAt(n)), n++;
|
||||
} else r += a;
|
||||
}
|
||||
return r;
|
||||
}),
|
||||
(t.cardTypeFromNumber = function (t) {
|
||||
if (((e = new RegExp('^30[0-5]')), null != t.match(e)))
|
||||
return 'Diners - Carte Blanche';
|
||||
if (((e = new RegExp('^(30[6-9]|36|38)')), null != t.match(e)))
|
||||
return 'Diners';
|
||||
if (((e = new RegExp('^35(2[89]|[3-8][0-9])')), null != t.match(e)))
|
||||
return 'JCB';
|
||||
if (((e = new RegExp('^3[47]')), null != t.match(e))) return 'AMEX';
|
||||
if (
|
||||
((e = new RegExp('^(4026|417500|4508|4844|491(3|7))')),
|
||||
null != t.match(e))
|
||||
)
|
||||
return 'Visa Electron';
|
||||
var e = new RegExp('^4');
|
||||
return null != t.match(e)
|
||||
? 'Visa'
|
||||
: ((e = new RegExp('^5[1-5]')),
|
||||
null != t.match(e)
|
||||
? 'Mastercard'
|
||||
: ((e = new RegExp(
|
||||
'^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)'
|
||||
)),
|
||||
null != t.match(e) ? 'Discover' : ''));
|
||||
}),
|
||||
(t.caretStartPosition = function (t) {
|
||||
return 'number' == typeof t.selectionStart && t.selectionStart;
|
||||
}),
|
||||
(t.caretEndPosition = function (t) {
|
||||
return 'number' == typeof t.selectionEnd && t.selectionEnd;
|
||||
}),
|
||||
(t.setCaretPosition = function (t, e) {
|
||||
if (null != t)
|
||||
if (t.createTextRange) {
|
||||
var r = t.createTextRange();
|
||||
r.move('character', e), r.select();
|
||||
} else
|
||||
t.selectionStart
|
||||
? (t.focus(), t.setSelectionRange(e, e))
|
||||
: t.focus();
|
||||
}),
|
||||
(t.normaliseCaretPosition = function (t, e) {
|
||||
var r = 0;
|
||||
if (0 > e || e > t.length) return 0;
|
||||
for (var n = 0; n < t.length; n++) {
|
||||
if (n == e) return r;
|
||||
'X' == t[n] && r++;
|
||||
}
|
||||
return r;
|
||||
}),
|
||||
(t.denormaliseCaretPosition = function (t, e) {
|
||||
var r = 0;
|
||||
if (0 > e || e > t.length) return 0;
|
||||
for (var n = 0; n < t.length; n++) {
|
||||
if (r == e) return n;
|
||||
'X' == t[n] && r++;
|
||||
}
|
||||
return t.length;
|
||||
}),
|
||||
(t.filterNumberOnlyKey = function (e) {
|
||||
var r = t.keyIsNumber(e),
|
||||
n = t.keyIsDeletion(e),
|
||||
i = t.keyIsArrow(e),
|
||||
a = t.keyIsNavigation(e),
|
||||
s = t.keyIsKeyboardCommand(e),
|
||||
p = t.keyIsTab(e);
|
||||
r || n || i || a || s || p || e.preventDefault();
|
||||
}),
|
||||
(t.digitFromKeyCode = function (e) {
|
||||
return e >= t.KEYS[0] && e <= t.KEYS[9]
|
||||
? e - t.KEYS[0]
|
||||
: e >= t.KEYS.NUMPAD_0 && e <= t.KEYS.NUMPAD_9
|
||||
? e - t.KEYS.NUMPAD_0
|
||||
: null;
|
||||
}),
|
||||
(t.handleMaskedNumberInputKey = function (e, r) {
|
||||
t.filterNumberOnlyKey(e);
|
||||
var n = e.which || e.keyCode,
|
||||
i = e.target,
|
||||
a = t.caretStartPosition(i),
|
||||
s = t.caretEndPosition(i),
|
||||
p = t.normaliseCaretPosition(r, a),
|
||||
c = t.normaliseCaretPosition(r, s),
|
||||
o = a,
|
||||
u = t.keyIsNumber(e),
|
||||
h = t.keyIsDelete(e),
|
||||
d = t.keyIsBackspace(e);
|
||||
if (u || h || d) {
|
||||
e.preventDefault();
|
||||
var l = $(i).val(),
|
||||
y = t.numbersOnlyString(l),
|
||||
m = t.digitFromKeyCode(n),
|
||||
C = c > p;
|
||||
C && (y = y.slice(0, p) + y.slice(c)),
|
||||
a != r.length &&
|
||||
(u &&
|
||||
l.length <= r.length &&
|
||||
((y = y.slice(0, p) + m + y.slice(p)),
|
||||
(o = Math.max(
|
||||
t.denormaliseCaretPosition(r, p + 1),
|
||||
t.denormaliseCaretPosition(r, p + 2) - 1
|
||||
))),
|
||||
h && (y = y.slice(0, p) + y.slice(p + 1))),
|
||||
0 != a &&
|
||||
d &&
|
||||
!C &&
|
||||
((y = y.slice(0, p - 1) + y.slice(p)),
|
||||
(o = t.denormaliseCaretPosition(r, p - 1))),
|
||||
$(i).val(t.applyFormatMask(y, r)),
|
||||
t.setCaretPosition(i, o);
|
||||
}
|
||||
}),
|
||||
(t.handleCreditCardNumberKey = function (e, r) {
|
||||
t.handleMaskedNumberInputKey(e, r);
|
||||
}),
|
||||
(t.handleCreditCardNumberChange = function (t) {}),
|
||||
(t.handleExpiryKey = function (e) {
|
||||
t.handleMaskedNumberInputKey(e, t.EXPIRY_MASK);
|
||||
}),
|
||||
(t.prototype.getCardNumber = function () {
|
||||
return this.cardNumberInput.val();
|
||||
}),
|
||||
(t.prototype.getCardType = function () {
|
||||
return t.cardTypeFromNumber(this.getCardNumber());
|
||||
}),
|
||||
(t.prototype.getName = function () {
|
||||
return this.nameInput.val();
|
||||
}),
|
||||
(t.prototype.getExpiryMonth = function () {
|
||||
return this.expiryMonthInput.val();
|
||||
}),
|
||||
(t.prototype.getExpiryYear = function () {
|
||||
return this.expiryYearInput.val();
|
||||
}),
|
||||
(t.prototype.getCvc = function () {
|
||||
return this.cvcInput.val();
|
||||
}),
|
||||
(t.prototype.setIconColour = function (t) {
|
||||
this.elem.find('.icon .svg').css({ fill: t });
|
||||
}),
|
||||
(t.prototype.setIconColour = function (t) {
|
||||
this.elem.find('.icon .svg').css({ fill: t });
|
||||
}),
|
||||
(t.prototype.refreshCreditCardTypeIcon = function () {
|
||||
this.setCardTypeIconFromNumber(
|
||||
t.numbersOnlyString(this.cardNumberInput.val())
|
||||
);
|
||||
}),
|
||||
(t.prototype.clearCardTypeIcon = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.removeClass('show');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsVisa = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show visa');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsMasterCard = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show master-card');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsAmericanExpress = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show american-express');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsDiscover = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show discover');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsDiners = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show diners');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconAsJcb = function () {
|
||||
this.elem
|
||||
.find('.card-number-wrapper .card-type-icon')
|
||||
.attr('class', 'card-type-icon show jcb');
|
||||
}),
|
||||
(t.prototype.setCardTypeIconFromNumber = function (e) {
|
||||
switch (t.cardTypeFromNumber(e)) {
|
||||
case 'Visa Electron':
|
||||
case 'Visa':
|
||||
this.setCardTypeAsVisa();
|
||||
break;
|
||||
case 'Mastercard':
|
||||
this.setCardTypeAsMasterCard();
|
||||
break;
|
||||
case 'AMEX':
|
||||
this.setCardTypeAsAmericanExpress();
|
||||
break;
|
||||
case 'Discover':
|
||||
this.setCardTypeAsDiscover();
|
||||
break;
|
||||
case 'Diners - Carte Blanche':
|
||||
case 'Diners':
|
||||
this.setCardTypeAsDiners();
|
||||
break;
|
||||
case 'JCB':
|
||||
this.setCardTypeAsJcb();
|
||||
break;
|
||||
default:
|
||||
this.clearCardType();
|
||||
}
|
||||
}),
|
||||
(t.prototype.setCardMask = function (t) {
|
||||
(this.creditCardNumberMask = t),
|
||||
this.cardNumberInput.attr('maxlength', t.length);
|
||||
}),
|
||||
(t.prototype.setCvc3 = function () {
|
||||
this.cvcInput.attr('maxlength', t.CVC_MASK_3.length);
|
||||
}),
|
||||
(t.prototype.setCvc4 = function () {
|
||||
this.cvcInput.attr('maxlength', t.CVC_MASK_4.length);
|
||||
}),
|
||||
(t.prototype.clearCardType = function () {
|
||||
this.clearCardTypeIcon(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_DEFAULT_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsVisa = function () {
|
||||
this.setCardTypeIconAsVisa(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_VISA_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsMasterCard = function () {
|
||||
this.setCardTypeIconAsMasterCard(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_MASTERCARD_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsAmericanExpress = function () {
|
||||
this.setCardTypeIconAsAmericanExpress(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_AMEX_MASK),
|
||||
this.setCvc4();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsDiscover = function () {
|
||||
this.setCardTypeIconAsDiscover(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_DISCOVER_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsDiners = function () {
|
||||
this.setCardTypeIconAsDiners(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_DINERS_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.setCardTypeAsJcb = function () {
|
||||
this.setCardTypeIconAsJcb(),
|
||||
this.setCardMask(t.CREDIT_CARD_NUMBER_JCB_MASK),
|
||||
this.setCvc3();
|
||||
}),
|
||||
(t.prototype.initCardNumberInput = function () {
|
||||
var e = this;
|
||||
(this.cardNumberInput = this.elem.find('.card-number')),
|
||||
this.cardNumberInput[0]
|
||||
? this.cardNumberInput.detach()
|
||||
: (this.cardNumberInput = $(
|
||||
"<input class='card-number' />"
|
||||
)),
|
||||
this.cardNumberInput.attr('type', 'tel'),
|
||||
this.cardNumberInput.attr('placeholder') ||
|
||||
this.cardNumberInput.attr(
|
||||
'placeholder',
|
||||
t.CREDIT_CARD_NUMBER_PLACEHOLDER
|
||||
),
|
||||
this.cardNumberInput.attr(
|
||||
'maxlength',
|
||||
this.creditCardNumberMask.length
|
||||
),
|
||||
this.cardNumberInput.attr('x-autocompletetype', 'cc-number'),
|
||||
this.cardNumberInput.attr('autocompletetype', 'cc-number'),
|
||||
this.cardNumberInput.attr('autocorrect', 'off'),
|
||||
this.cardNumberInput.attr('spellcheck', 'off'),
|
||||
this.cardNumberInput.attr('autocapitalize', 'off'),
|
||||
this.cardNumberInput.keydown(function (r) {
|
||||
t.handleCreditCardNumberKey(r, e.creditCardNumberMask);
|
||||
}),
|
||||
this.cardNumberInput.keyup(function (t) {
|
||||
e.refreshCreditCardTypeIcon();
|
||||
}),
|
||||
this.cardNumberInput.change(t.handleCreditCardNumberChange);
|
||||
}),
|
||||
(t.prototype.initNameInput = function () {
|
||||
(this.nameInput = this.elem.find('.name')),
|
||||
this.nameInput[0]
|
||||
? ((this.captureName = !0), this.nameInput.detach())
|
||||
: (this.nameInput = $("<input class='name' />")),
|
||||
this.nameInput.attr('placeholder') ||
|
||||
this.nameInput.attr('placeholder', t.NAME_PLACEHOLDER);
|
||||
}),
|
||||
(t.prototype.initExpiryMonthInput = function () {
|
||||
(this.expiryMonthInput = this.elem.find('.expiry-month')),
|
||||
this.expiryMonthInput[0]
|
||||
? this.expiryMonthInput.detach()
|
||||
: (this.expiryMonthInput = $(
|
||||
"<input class='expiry-month' />"
|
||||
));
|
||||
}),
|
||||
(t.prototype.initExpiryYearInput = function () {
|
||||
(this.expiryYearInput = this.elem.find('.expiry-year')),
|
||||
this.expiryYearInput[0]
|
||||
? this.expiryYearInput.detach()
|
||||
: (this.expiryYearInput = $(
|
||||
"<input class='expiry-year' name='expiry-year' />"
|
||||
));
|
||||
}),
|
||||
(t.prototype.initCvcInput = function () {
|
||||
(this.cvcInput = this.elem.find('.cvc')),
|
||||
this.cvcInput[0]
|
||||
? this.cvcInput.detach()
|
||||
: (this.cvcInput = $("<input class='cvc' />")),
|
||||
this.cvcInput.attr('type', 'tel'),
|
||||
this.cvcInput.attr('placeholder') ||
|
||||
this.cvcInput.attr('placeholder', t.CVC_PLACEHOLDER),
|
||||
this.cvcInput.attr('maxlength', t.CVC_MASK_3.length),
|
||||
this.cvcInput.attr('x-autocompletetype', 'cc-csc'),
|
||||
this.cvcInput.attr('autocompletetype', 'cc-csc'),
|
||||
this.cvcInput.attr('autocorrect', 'off'),
|
||||
this.cvcInput.attr('spellcheck', 'off'),
|
||||
this.cvcInput.attr('autocapitalize', 'off'),
|
||||
this.cvcInput.keydown(t.filterNumberOnlyKey);
|
||||
}),
|
||||
(t.prototype.setupCardNumberInput = function () {
|
||||
this.stripe && this.cardNumberInput.attr('data-stripe', 'number'),
|
||||
this.elem.append("<div class='card-number-wrapper'></div>");
|
||||
var e = this.elem.find('.card-number-wrapper');
|
||||
e.append(this.cardNumberInput),
|
||||
e.append("<div class='card-type-icon'></div>"),
|
||||
e.append("<div class='icon'></div>"),
|
||||
e.find('.icon').append(t.CREDIT_CARD_SVG);
|
||||
}),
|
||||
(t.prototype.setupNameInput = function () {
|
||||
if (this.captureName) {
|
||||
this.elem.append("<div class='name-wrapper'></div>");
|
||||
var e = this.elem.find('.name-wrapper');
|
||||
e.append(this.nameInput),
|
||||
e.append("<div class='icon'></div>"),
|
||||
e.find('.icon').append(t.USER_SVG);
|
||||
}
|
||||
}),
|
||||
(t.prototype.setupExpiryInput = function () {
|
||||
this.elem.append(
|
||||
"<div class='expiry-container'><div class='expiry-wrapper'></div></div>"
|
||||
);
|
||||
var e,
|
||||
r = this.elem.find('.expiry-wrapper');
|
||||
if (this.EXPIRY_USE_DROPDOWNS) {
|
||||
e = $('<div></div>');
|
||||
var n = $(
|
||||
"<select><option value='any' selected='' hidden=''>MM</option><option value='1'>01</option><option value='2'>02</option><option value='3'>03</option><option value='4'>04</option><option value='5'>05</option><option value='6'>06</option><option value='7'>07</option><option value='8'>08</option><option value='9'>09</option><option value='10'>10</option><option value='11'>11</option><option value='12'>12</option></select>"
|
||||
),
|
||||
i = this.expiryMonthInput;
|
||||
t.copyAllElementAttributes(i, n),
|
||||
this.expiryMonthInput.remove(),
|
||||
(this.expiryMonthInput = n);
|
||||
for (
|
||||
var a = $(
|
||||
"<select><option value='any' selected='' hidden=''>YY</option></select>"
|
||||
),
|
||||
s = parseInt(
|
||||
new Date().getFullYear().toString().substring(2, 4)
|
||||
),
|
||||
p = 0;
|
||||
p < t.EXPIRY_NUMBER_OF_YEARS;
|
||||
p++
|
||||
)
|
||||
a.append("<option value='" + s + "'>" + s + '</option>'),
|
||||
(s = (s + 1) % 100);
|
||||
var c = this.expiryYearInput;
|
||||
t.copyAllElementAttributes(c, a),
|
||||
this.expiryYearInput.remove(),
|
||||
(this.expiryYearInput = a),
|
||||
e.append(this.expiryMonthInput),
|
||||
e.append(this.expiryYearInput);
|
||||
} else {
|
||||
(e = $('<div></div>')),
|
||||
(this.expiryMonthInput = $(
|
||||
"<input type='hidden' name='expiry-month' />"
|
||||
)),
|
||||
(this.expiryYearInput = $(
|
||||
"<input type='hidden' name='expiry-year' />"
|
||||
)),
|
||||
this.stripe &&
|
||||
(this.expiryMonthInput.attr('data-stripe', 'exp-month'),
|
||||
this.expiryYearInput.attr('data-stripe', 'exp-year')),
|
||||
(this.expiryMonthYearInput = $("<input class='expiry' />")),
|
||||
this.expiryMonthYearInput.attr('type', 'tel'),
|
||||
this.expiryMonthYearInput.attr('placeholder') ||
|
||||
this.expiryMonthYearInput.attr(
|
||||
'placeholder',
|
||||
t.EXPIRY_PLACEHOLDER
|
||||
),
|
||||
this.expiryMonthYearInput.attr(
|
||||
'maxlength',
|
||||
t.EXPIRY_MASK.length
|
||||
),
|
||||
this.expiryMonthYearInput.attr(
|
||||
'x-autocompletetype',
|
||||
'cc-exp'
|
||||
),
|
||||
this.expiryMonthYearInput.attr(
|
||||
'autocompletetype',
|
||||
'cc-exp'
|
||||
),
|
||||
this.expiryMonthYearInput.attr('autocorrect', 'off'),
|
||||
this.expiryMonthYearInput.attr('spellcheck', 'off'),
|
||||
this.expiryMonthYearInput.attr('autocapitalize', 'off');
|
||||
var o = this;
|
||||
this.expiryMonthYearInput.keydown(function (e) {
|
||||
t.handleExpiryKey(e);
|
||||
var r = o.expiryMonthYearInput.val();
|
||||
1 == r.length &&
|
||||
parseInt(r) > 1 &&
|
||||
t.keyIsNumber(e) &&
|
||||
o.expiryMonthYearInput.val(
|
||||
t.applyFormatMask('0' + r, t.EXPIRY_MASK)
|
||||
),
|
||||
o.EXPIRY_USE_DROPDOWNS ||
|
||||
null == o.expiryMonthYearInput ||
|
||||
(o.expiryMonthInput.val(o.expiryMonth()),
|
||||
o.expiryYearInput.val(
|
||||
9 == r.length ? r.substr(5, 4) : null
|
||||
));
|
||||
}),
|
||||
this.expiryMonthYearInput.blur(function (t) {
|
||||
o.refreshExpiryMonthValidation();
|
||||
}),
|
||||
e.append(this.expiryMonthYearInput),
|
||||
e.append(this.expiryMonthInput),
|
||||
e.append(this.expiryYearInput);
|
||||
}
|
||||
r.append(e),
|
||||
r.append("<div class='icon'></div>"),
|
||||
r.find('.icon').append(t.CALENDAR_SVG);
|
||||
}),
|
||||
(t.prototype.setupCvcInput = function () {
|
||||
this.stripe && this.cvcInput.attr('data-stripe', 'cvc'),
|
||||
this.elem.append(
|
||||
"<div class='cvc-container'><div class='cvc-wrapper'></div></div>"
|
||||
);
|
||||
var e = this.elem.find('.cvc-wrapper');
|
||||
e.append(this.cvcInput),
|
||||
e.append("<div class='icon'></div>"),
|
||||
e.find('.icon').append(t.LOCK_SVG);
|
||||
}),
|
||||
(t.prototype.expiryMonth = function () {
|
||||
if (
|
||||
!this.EXPIRY_USE_DROPDOWNS &&
|
||||
null != this.expiryMonthYearInput
|
||||
) {
|
||||
var t = this.expiryMonthYearInput.val();
|
||||
return t.length >= 2 ? parseInt(t.substr(0, 2)) : null;
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
(t.isValidMonth = function (t) {
|
||||
return t >= 1 && 12 >= t;
|
||||
}),
|
||||
(t.isExpiryValid = function (e, r) {
|
||||
var n = new Date(),
|
||||
i = n.getMonth() + 1,
|
||||
a = '' + n.getFullYear();
|
||||
return (
|
||||
2 == ('' + r).length && (r = a.substring(0, 2) + '' + r),
|
||||
(i = parseInt(i)),
|
||||
(a = parseInt(a)),
|
||||
(e = parseInt(e)),
|
||||
(r = parseInt(r)),
|
||||
t.isValidMonth(e) && (r > a || (r == a && e >= i))
|
||||
);
|
||||
}),
|
||||
(t.prototype.refreshExpiryMonthValidation = function () {
|
||||
t.isExpiryValid(this.getExpiryMonth(), this.getExpiryYear())
|
||||
? this.setExpiryMonthAsValid()
|
||||
: this.setExpiryMonthAsInvalid();
|
||||
}),
|
||||
(t.prototype.setExpiryMonthAsValid = function () {
|
||||
this.EXPIRY_USE_DROPDOWNS ||
|
||||
this.expiryMonthYearInput.parent().removeClass('has-error');
|
||||
}),
|
||||
(t.prototype.setExpiryMonthAsInvalid = function () {
|
||||
this.EXPIRY_USE_DROPDOWNS ||
|
||||
this.expiryMonthYearInput.parent().addClass('has-error');
|
||||
});
|
||||
})();
|
82
public/js/clients/payments/forte-credit-card-payment.js
vendored
Normal file
82
public/js/clients/payments/forte-credit-card-payment.js
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
var __webpack_exports__ = {};
|
||||
/*!********************************************************************!*\
|
||||
!*** ./resources/js/clients/payments/forte-credit-card-payment.js ***!
|
||||
\********************************************************************/
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
var ForteAuthorizeCard = function ForteAuthorizeCard(apiLoginId) {
|
||||
var _this = this;
|
||||
|
||||
_classCallCheck(this, ForteAuthorizeCard);
|
||||
|
||||
_defineProperty(this, "handleAuthorization", function () {
|
||||
var myCard = $('#my-card');
|
||||
var data = {
|
||||
api_login_id: _this.apiLoginId,
|
||||
card_number: myCard.CardJs('cardNumber').replace(/[^\d]/g, ''),
|
||||
expire_year: myCard.CardJs('expiryYear').replace(/[^\d]/g, ''),
|
||||
expire_month: myCard.CardJs('expiryMonth').replace(/[^\d]/g, ''),
|
||||
cvv: document.getElementById('cvv').value.replace(/[^\d]/g, '')
|
||||
};
|
||||
var payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
document.getElementById('pay-now').disabled = true;
|
||||
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||
}
|
||||
|
||||
forte.createToken(data).success(_this.successResponseHandler).error(_this.failedResponseHandler);
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "successResponseHandler", function (response) {
|
||||
document.getElementById('payment_token').value = response.onetime_token;
|
||||
document.getElementById('card_brand').value = response.card_type;
|
||||
document.getElementById('server_response').submit();
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "failedResponseHandler", function (response) {
|
||||
var errors = '<div class="alert alert-failure mb-4"><ul><li>' + response.response_description + '</li></ul></div>';
|
||||
document.getElementById('forte_errors').innerHTML = errors;
|
||||
document.getElementById('pay-now').disabled = false;
|
||||
document.querySelector('#pay-now > svg').classList.add('hidden');
|
||||
document.querySelector('#pay-now > span').classList.remove('hidden');
|
||||
return false;
|
||||
});
|
||||
|
||||
_defineProperty(this, "handle", function () {
|
||||
var payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
payNowButton.addEventListener('click', function (e) {
|
||||
_this.handleAuthorization();
|
||||
});
|
||||
}
|
||||
|
||||
return _this;
|
||||
});
|
||||
|
||||
this.apiLoginId = apiLoginId;
|
||||
this.cardHolderName = document.getElementById('cardholder_name');
|
||||
};
|
||||
|
||||
var apiLoginId = document.querySelector('meta[name="forte-api-login-id"]').content;
|
||||
/** @handle */
|
||||
|
||||
new ForteAuthorizeCard(apiLoginId).handle();
|
||||
/******/ })()
|
||||
;
|
81
resources/js/clients/payments/forte-ach-payment.js
vendored
Normal file
81
resources/js/clients/payments/forte-ach-payment.js
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 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 ForteAuthorizeACH {
|
||||
constructor(apiLoginId) {
|
||||
this.apiLoginId = apiLoginId;
|
||||
}
|
||||
|
||||
handleAuthorization = () => {
|
||||
var account_number = document.getElementById('account-number').value;
|
||||
var routing_number = document.getElementById('routing-number').value;
|
||||
|
||||
var data = {
|
||||
api_login_id: this.apiLoginId,
|
||||
account_number: account_number,
|
||||
routing_number: routing_number,
|
||||
account_type: 'checking',
|
||||
};
|
||||
|
||||
let payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
document.getElementById('pay-now').disabled = true;
|
||||
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||
}
|
||||
// console.log(data);
|
||||
forte
|
||||
.createToken(data)
|
||||
.success(this.successResponseHandler)
|
||||
.error(this.failedResponseHandler);
|
||||
return false;
|
||||
};
|
||||
|
||||
successResponseHandler = (response) => {
|
||||
document.getElementById('payment_token').value = response.onetime_token;
|
||||
|
||||
document.getElementById('server_response').submit();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
failedResponseHandler = (response) => {
|
||||
var errors =
|
||||
'<div class="alert alert-failure mb-4"><ul><li>' +
|
||||
response.response_description +
|
||||
'</li></ul></div>';
|
||||
document.getElementById('forte_errors').innerHTML = errors;
|
||||
document.getElementById('pay-now').disabled = false;
|
||||
document.querySelector('#pay-now > svg').classList.add('hidden');
|
||||
document.querySelector('#pay-now > span').classList.remove('hidden');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
handle = () => {
|
||||
let payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
payNowButton.addEventListener('click', (e) => {
|
||||
this.handleAuthorization();
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
const apiLoginId = document.querySelector(
|
||||
'meta[name="forte-api-login-id"]'
|
||||
).content;
|
||||
|
||||
/** @handle */
|
||||
new ForteAuthorizeACH(apiLoginId).handle();
|
83
resources/js/clients/payments/forte-credit-card-payment.js
vendored
Normal file
83
resources/js/clients/payments/forte-credit-card-payment.js
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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 ForteAuthorizeCard {
|
||||
constructor(apiLoginId) {
|
||||
this.apiLoginId = apiLoginId;
|
||||
this.cardHolderName = document.getElementById('cardholder_name');
|
||||
}
|
||||
|
||||
handleAuthorization = () => {
|
||||
var myCard = $('#my-card');
|
||||
|
||||
var data = {
|
||||
api_login_id: this.apiLoginId,
|
||||
card_number: myCard.CardJs('cardNumber').replace(/[^\d]/g, ''),
|
||||
expire_year: myCard.CardJs('expiryYear').replace(/[^\d]/g, ''),
|
||||
expire_month: myCard.CardJs('expiryMonth').replace(/[^\d]/g, ''),
|
||||
cvv: document.getElementById('cvv').value.replace(/[^\d]/g, ''),
|
||||
};
|
||||
|
||||
let payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
document.getElementById('pay-now').disabled = true;
|
||||
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||
}
|
||||
|
||||
forte
|
||||
.createToken(data)
|
||||
.success(this.successResponseHandler)
|
||||
.error(this.failedResponseHandler);
|
||||
return false;
|
||||
};
|
||||
|
||||
successResponseHandler = (response) => {
|
||||
document.getElementById('payment_token').value = response.onetime_token;
|
||||
document.getElementById('card_brand').value = response.card_type;
|
||||
|
||||
document.getElementById('server_response').submit();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
failedResponseHandler = (response) => {
|
||||
var errors =
|
||||
'<div class="alert alert-failure mb-4"><ul><li>' +
|
||||
response.response_description +
|
||||
'</li></ul></div>';
|
||||
document.getElementById('forte_errors').innerHTML = errors;
|
||||
document.getElementById('pay-now').disabled = false;
|
||||
document.querySelector('#pay-now > svg').classList.add('hidden');
|
||||
document.querySelector('#pay-now > span').classList.remove('hidden');
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
handle = () => {
|
||||
let payNowButton = document.getElementById('pay-now');
|
||||
|
||||
if (payNowButton) {
|
||||
payNowButton.addEventListener('click', (e) => {
|
||||
this.handleAuthorization();
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
const apiLoginId = document.querySelector(
|
||||
'meta[name="forte-api-login-id"]'
|
||||
).content;
|
||||
|
||||
/** @handle */
|
||||
new ForteAuthorizeCard(apiLoginId).handle();
|
@ -0,0 +1,131 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Bank Details', 'card_title' => 'Bank Details'])
|
||||
|
||||
@section('gateway_head')
|
||||
@if($gateway->getConfigField('testMode'))
|
||||
<script type="text/javascript" src="https://sandbox.forte.net/api/js/v1"></script>
|
||||
@else
|
||||
<script type="text/javascript" src="https://api.forte.net/js/v1"></script>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
@if(session()->has('ach_error'))
|
||||
<div class="alert alert-failure mb-4">
|
||||
<p>{{ session('ach_error') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
@if(Session::has('error'))
|
||||
<div class="alert alert-failure mb-4" id="errors">{{ Session::get('error') }}</div>
|
||||
@endif
|
||||
<div id="forte_errors"></div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-failure mb-4">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::BANK_TRANSFER]) }}" method="post" id="server_response">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="gateway_type_id" value="2">
|
||||
<input type="hidden" name="gateway_response" id="gateway_response">
|
||||
<input type="hidden" name="is_default" id="is_default">
|
||||
<input type="hidden" name="last_4" id="last_4">
|
||||
<input type="hidden" name="one_time_token" id="one_time_token">
|
||||
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.account_holder_type')])
|
||||
<span class="flex items-center mr-4">
|
||||
<input class="form-radio mr-2" type="radio" value="individual" name="account-holder-type" checked>
|
||||
<span>{{ __('texts.individual_account') }}</span>
|
||||
</span>
|
||||
<span class="flex items-center">
|
||||
<input class="form-radio mr-2" type="radio" value="company" name="account-holder-type">
|
||||
<span>{{ __('texts.company_account') }}</span>
|
||||
</span>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.account_holder_name')])
|
||||
<input class="input w-full" id="account-holder-name" type="text" name="account_holder_name" placeholder="{{ ctrans('texts.name') }}" required>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.country')])
|
||||
<select name="countries" id="country" name="country" class="form-select input w-full" required>
|
||||
@foreach($countries as $country)
|
||||
<option value="{{ $country->iso_3166_2 }}" {{$country->iso_3166_2 == 'US' ? "selected" : ""}}>{{ $country->iso_3166_2 }} ({{ $country->name }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.currency')])
|
||||
<select name="currencies" id="currency" name="currency" class="form-select input w-full">
|
||||
@foreach($currencies as $currency)
|
||||
<option value="{{ $currency->code }}" {{$currency->code == 'USD' ? "selected" : ""}}>{{ $currency->code }} ({{ $currency->name }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.routing_number')])
|
||||
<input class="input w-full" id="routing-number" type="text" required>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.account_number')])
|
||||
<input class="input w-full" id="account-number" type="text" required>
|
||||
@endcomponent
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element-single')
|
||||
<input type="checkbox" class="form-checkbox mr-1" name="accept_terms" id="accept-terms" required>
|
||||
<label for="accept-terms" class="cursor-pointer">{{ ctrans('texts.ach_authorization', ['company' => auth()->user()->company->present()->name, 'email' => auth('contact')->user()->client->company->settings->email]) }}</label>
|
||||
@endcomponent
|
||||
|
||||
<div class="bg-white px-4 py-5 flex justify-end">
|
||||
<button type="button"
|
||||
onclick="submitACH()"
|
||||
class="button button-primary bg-primary {{ $class ?? '' }}">
|
||||
<svg class="animate-spin h-5 w-5 text-white hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<span>{{ $slot ?? ctrans('texts.add_payment_method') }}</span>
|
||||
</button>
|
||||
<input type="submit" style="display: none" id="form_btn">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
<script>
|
||||
function onTokenCreated(params) {
|
||||
document.getElementById('one_time_token').value=params.onetime_token;
|
||||
document.getElementById('last_4').value=params.last_4;
|
||||
let button = document.querySelector("#form_btn");
|
||||
button.click();
|
||||
}
|
||||
function onTokenFailed(params) {
|
||||
var errors = '<div class="alert alert-failure mb-4"><ul><li>'+ params.response_description +'</li></ul></div>';
|
||||
document.getElementById("forte_errors").innerHTML = errors;
|
||||
}
|
||||
function submitACH(){
|
||||
var account_number=document.getElementById('account-number').value;
|
||||
var routing_number=document.getElementById('routing-number').value;
|
||||
|
||||
var data = {
|
||||
api_login_id: '{{$gateway->getConfigField("apiLoginId")}}',
|
||||
account_number: account_number,
|
||||
routing_number: routing_number,
|
||||
account_type: "checking",
|
||||
}
|
||||
|
||||
forte.createToken(data)
|
||||
.success(onTokenCreated)
|
||||
.error(onTokenFailed);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
@endsection
|
@ -0,0 +1,53 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Bank Transfer', 'card_title' => 'Bank Transfer'])
|
||||
|
||||
@section('gateway_head')
|
||||
<meta name="forte-api-login-id" content="{{$gateway->forte->company_gateway->getConfigField("apiLoginId")}}">
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server_response">
|
||||
@csrf
|
||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->forte->company_gateway->id }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{$payment_method_id}}">
|
||||
<input type="hidden" name="gateway_response" id="gateway_response">
|
||||
<input type="hidden" name="dataValue" id="dataValue"/>
|
||||
<input type="hidden" name="dataDescriptor" id="dataDescriptor"/>
|
||||
<input type="hidden" name="token" id="token"/>
|
||||
<input type="hidden" name="store_card" id="store_card"/>
|
||||
<input type="submit" style="display: none" id="form_btn">
|
||||
</form>
|
||||
|
||||
<div id="forte_errors"></div>
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
|
||||
Bank Transfer
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.payment_details')
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => 'Pay with Bank Transfer'])
|
||||
<input type="hidden" name="payment_token" id="payment_token">
|
||||
<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="routing-number" type="text" placeholder="{{ctrans('texts.routing_number')}}" required>
|
||||
</div>
|
||||
<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-number" type="text" placeholder="{{ctrans('texts.account_number')}}" required>
|
||||
</div>
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.pay_now')
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
@if($gateway->forte->company_gateway->getConfigField('testMode'))
|
||||
<script type="text/javascript" src="https://sandbox.forte.net/api/js/v1"></script>
|
||||
@else
|
||||
<script type="text/javascript" src="https://api.forte.net/js/v1"></script>
|
||||
@endif
|
||||
|
||||
<script src="{{ asset('js/clients/payments/forte-ach-payment.js') }}"></script>
|
||||
@endsection
|
@ -0,0 +1,122 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')])
|
||||
|
||||
@section('gateway_head')
|
||||
<meta name="year-invalid" content="{{ ctrans('texts.year_invalid') }}">
|
||||
<meta name="month-invalid" content="{{ ctrans('texts.month_invalid') }}">
|
||||
<meta name="credit-card-invalid" content="{{ ctrans('texts.credit_card_invalid') }}">
|
||||
|
||||
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="{{ asset('js/clients/payments/forte-card-js.min.js') }}"></script>
|
||||
|
||||
<link href="{{ asset('css/card-js.min.css') }}" rel="stylesheet" type="text/css">
|
||||
@if($gateway->getConfigField('testMode'))
|
||||
<script type="text/javascript" src="https://sandbox.forte.net/api/js/v1"></script>
|
||||
@else
|
||||
<script type="text/javascript" src="https://api.forte.net/js/v1"></script>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::CREDIT_CARD]) }}"
|
||||
method="post" id="server_response">
|
||||
@csrf
|
||||
|
||||
<input type="hidden" name="payment_method_id" value="1">
|
||||
<input type="hidden" name="one_time_token" id="one_time_token">
|
||||
<input type="hidden" name="card_type" id="card_type">
|
||||
<input type="hidden" name="expire_year" id="expire_year">
|
||||
<input type="hidden" name="expire_month" id="expire_month">
|
||||
<input type="hidden" name="last_4" id="last_4">
|
||||
|
||||
@if(!Request::isSecure())
|
||||
<p class="alert alert-failure">{{ ctrans('texts.https_required') }}</p>
|
||||
@endif
|
||||
|
||||
|
||||
@if(Session::has('error'))
|
||||
<div class="alert alert-failure mb-4" id="errors">{{ Session::get('error') }}</div>
|
||||
@endif
|
||||
<div id="forte_errors"></div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-failure mb-4">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')])
|
||||
{{ ctrans('texts.credit_card') }}
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.forte.includes.credit_card')
|
||||
|
||||
<div class="bg-white px-4 py-5 flex justify-end">
|
||||
<button type="button"
|
||||
onclick="submitCard()"
|
||||
class="button button-primary bg-primary {{ $class ?? '' }}">
|
||||
<svg class="animate-spin h-5 w-5 text-white hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<span>{{ $slot ?? ctrans('texts.add_payment_method') }}</span>
|
||||
</button>
|
||||
<input type="submit" style="display: none" id="form_btn">
|
||||
</div>
|
||||
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
<script>
|
||||
function onTokenCreated(params) {
|
||||
document.getElementById('one_time_token').value=params.onetime_token;
|
||||
document.getElementById('last_4').value=params.last_4;
|
||||
let button = document.querySelector("#form_btn");
|
||||
button.click();
|
||||
}
|
||||
function onTokenFailed(params) {
|
||||
var errors = '<div class="alert alert-failure mb-4"><ul><li>'+ params.response_description +'</li></ul></div>';
|
||||
document.getElementById("forte_errors").innerHTML = errors;
|
||||
}
|
||||
function submitCard(){
|
||||
var doc = document.getElementsByClassName("card-number-wrapper");
|
||||
var cardType=doc[0].childNodes[1].classList[2];
|
||||
if (cardType=='master-card') {
|
||||
document.getElementById('card_type').value='mast';
|
||||
} else if(cardType=='visa') {
|
||||
document.getElementById('card_type').value='visa';
|
||||
}else if(cardType=='jcb') {
|
||||
document.getElementById('card_type').value='jcb';
|
||||
}else if(cardType=='discover') {
|
||||
document.getElementById('card_type').value='disc';
|
||||
}else if(cardType=='american-express') {
|
||||
document.getElementById('card_type').value='amex';
|
||||
}else{
|
||||
document.getElementById('card_type').value=cardType;
|
||||
}
|
||||
var month=document.querySelector('input[name=expiry-month]').value;
|
||||
var year=document.querySelector('input[name=expiry-year]').value;
|
||||
var cc=document.getElementById('card_number').value.replaceAll(' ','');
|
||||
var cvv=document.getElementById('cvv').value;
|
||||
|
||||
document.getElementById('expire_year').value=year;
|
||||
document.getElementById('expire_month').value=month;
|
||||
|
||||
var data = {
|
||||
api_login_id: '{{$gateway->getConfigField("apiLoginId")}}',
|
||||
card_number: cc,
|
||||
expire_year: year,
|
||||
expire_month: month,
|
||||
cvv: cvv,
|
||||
}
|
||||
|
||||
forte.createToken(data)
|
||||
.success(onTokenCreated)
|
||||
.error(onTokenFailed);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
@endsection
|
@ -0,0 +1,51 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => ctrans('texts.payment_type_credit_card')])
|
||||
|
||||
@section('gateway_head')
|
||||
<meta name="forte-api-login-id" content="{{$gateway->forte->company_gateway->getConfigField("apiLoginId")}}">
|
||||
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
|
||||
<script src="{{ asset('js/clients/payments/forte-card-js.min.js') }}"></script>
|
||||
|
||||
<link href="{{ asset('css/card-js.min.css') }}" rel="stylesheet" type="text/css">
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server_response">
|
||||
@csrf
|
||||
<input type="hidden" name="card_brand" id="card_brand">
|
||||
<input type="hidden" name="payment_token" id="payment_token">
|
||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->forte->company_gateway->id }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{$payment_method_id}}">
|
||||
<input type="hidden" name="gateway_response" id="gateway_response">
|
||||
<input type="hidden" name="dataValue" id="dataValue"/>
|
||||
<input type="hidden" name="dataDescriptor" id="dataDescriptor"/>
|
||||
<input type="hidden" name="token" id="token"/>
|
||||
<input type="hidden" name="store_card" id="store_card"/>
|
||||
<input type="submit" style="display: none" id="form_btn">
|
||||
</form>
|
||||
|
||||
<div id="forte_errors"></div>
|
||||
|
||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
|
||||
{{ ctrans('texts.credit_card') }}
|
||||
@endcomponent
|
||||
|
||||
@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')
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.pay_now')
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
@if($gateway->forte->company_gateway->getConfigField('testMode'))
|
||||
<script type="text/javascript" src="https://sandbox.forte.net/api/js/v1"></script>
|
||||
@else
|
||||
<script type="text/javascript" src="https://api.forte.net/js/v1"></script>
|
||||
@endif
|
||||
|
||||
<script src="{{ asset('js/clients/payments/forte-credit-card-payment.js') }}"></script>
|
||||
@endsection
|
@ -0,0 +1,12 @@
|
||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"
|
||||
style="display: flex!important; justify-content: center!important;" id="authorize--credit-card-container">
|
||||
<div class="card-js" id="my-card" data-capture-name="true">
|
||||
<input class="name" id="cardholder_name" name="card_holders_name" placeholder="{{ ctrans('texts.name')}}">
|
||||
<input class="card-number my-custom-class" id="card_number">
|
||||
<input type="hidden" name="expiry_month" id="expiration_month">
|
||||
<input type="hidden" name="expiry_year" id="expiration_year">
|
||||
<input class="cvc" name="cvc" id="cvv">
|
||||
</div>
|
||||
|
||||
<div id="errors"></div>
|
||||
</div>
|
8
webpack.mix.js
vendored
8
webpack.mix.js
vendored
@ -10,6 +10,14 @@ mix.js("resources/js/app.js", "public/js")
|
||||
"resources/js/clients/payments/authorize-credit-card-payment.js",
|
||||
"public/js/clients/payments/authorize-credit-card-payment.js"
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/payments/forte-credit-card-payment.js",
|
||||
"public/js/clients/payments/forte-credit-card-payment.js"
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/payments/forte-ach-payment.js",
|
||||
"public/js/clients/payments/forte-ach-payment.js"
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/payments/stripe-ach.js",
|
||||
"public/js/clients/payments/stripe-ach.js"
|
||||
|
Loading…
x
Reference in New Issue
Block a user