mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 21:22:58 +01:00
Merge pull request #3799 from beganovich/v2-1006-checkout-com
Checkout.com implementation
This commit is contained in:
commit
4de2e7d8d1
@ -130,7 +130,7 @@ class PaymentController extends Controller
|
||||
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod('App\\PaymentDrivers\\Stripe\\Alipay')
|
||||
->setPaymentMethod()
|
||||
->processPaymentResponse($request);
|
||||
}
|
||||
}
|
||||
|
@ -507,4 +507,9 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class SystemLog extends Model
|
||||
const TYPE_STRIPE = 301;
|
||||
const TYPE_LEDGER = 302;
|
||||
const TYPE_FAILURE = 303;
|
||||
const TYPE_CHECKOUT = 304;
|
||||
|
||||
const TYPE_QUOTA_EXCEEDED = 400;
|
||||
const TYPE_UPSTREAM_FAILURE = 401;
|
||||
|
42
app/PaymentDrivers/CheckoutCom/Utilities.php
Normal file
42
app/PaymentDrivers/CheckoutCom/Utilities.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\CheckoutCom;
|
||||
|
||||
trait Utilities
|
||||
{
|
||||
public function getPublishableKey()
|
||||
{
|
||||
return $this->company_gateway->getConfigField('publicApiKey');
|
||||
}
|
||||
|
||||
public function convertToCheckoutAmount($amount, $currency)
|
||||
{
|
||||
$cases = [
|
||||
'option_1' => ['BIF', 'DJF', 'GNF', 'ISK', 'KMF', 'XAF', 'CLF', 'XPF', 'JPY', 'PYG', 'RWF', 'KRW', 'VUV', 'VND', 'XOF'],
|
||||
'option_2' => ['BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND'],
|
||||
];
|
||||
|
||||
// https://docs.checkout.com/resources/calculating-the-value#Calculatingthevalue-Option1:Thefullvaluefullvalue
|
||||
if (in_array($currency, $cases['option_1'])) {
|
||||
return round($amount);
|
||||
}
|
||||
|
||||
// https://docs.checkout.com/resources/calculating-the-value#Calculatingthevalue-Option2:Thevaluedividedby1000valuediv1000
|
||||
if (in_array($currency, $cases['option_2'])) {
|
||||
return round($amount * 1000);
|
||||
}
|
||||
|
||||
// https://docs.checkout.com/resources/calculating-the-value#Calculatingthevalue-Option3:Thevaluedividedby100valuediv100
|
||||
return round($amount * 100);
|
||||
}
|
||||
}
|
276
app/PaymentDrivers/CheckoutComPaymentDriver.php
Normal file
276
app/PaymentDrivers/CheckoutComPaymentDriver.php
Normal file
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers;
|
||||
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Jobs\Mail\PaymentFailureMailer;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\ClientGatewayToken;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\CheckoutCom\Utilities;
|
||||
use App\Utils\Traits\SystemLogTrait;
|
||||
use Checkout\CheckoutApi;
|
||||
use Checkout\Library\Exceptions\CheckoutHttpException;
|
||||
use Checkout\Models\Payments\IdSource;
|
||||
use Checkout\Models\Payments\Payment as CheckoutPayment;
|
||||
use Checkout\Models\Payments\TokenSource;
|
||||
|
||||
class CheckoutComPaymentDriver extends BasePaymentDriver
|
||||
{
|
||||
use SystemLogTrait, Utilities;
|
||||
|
||||
/* The company gateway instance*/
|
||||
public $company_gateway;
|
||||
|
||||
/* The Invitation */
|
||||
protected $invitation;
|
||||
|
||||
/* Gateway capabilities */
|
||||
protected $refundable = true;
|
||||
|
||||
/* Token billing */
|
||||
protected $token_billing = true;
|
||||
|
||||
/* Authorise payment methods */
|
||||
protected $can_authorise_credit_card = true;
|
||||
|
||||
/** Instance of \Checkout\CheckoutApi */
|
||||
public $gateway;
|
||||
|
||||
/** Since with Checkout.com we handle only credit cards, this method should be empty. */
|
||||
public function setPaymentMethod($string = null)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$config = [
|
||||
'secret' => $this->company_gateway->getConfigField('secretApiKey'),
|
||||
'public' => $this->company_gateway->getConfigField('publicApiKey'),
|
||||
'sandbox' => $this->company_gateway->getConfigField('testMode'),
|
||||
];
|
||||
|
||||
$this->gateway = new CheckoutApi($config['secret'], $config['sandbox'], $config['public']);
|
||||
}
|
||||
|
||||
public function viewForType($gateway_type_id)
|
||||
{
|
||||
if ($gateway_type_id == GatewayType::CREDIT_CARD) {
|
||||
return 'gateways.checkout.credit_card';
|
||||
}
|
||||
|
||||
if ($gateway_type_id == GatewayType::TOKEN) {
|
||||
return 'gateways.checkout.credit_card';
|
||||
}
|
||||
}
|
||||
|
||||
public function processPaymentView(array $data)
|
||||
{
|
||||
$data['gateway'] = $this;
|
||||
$data['client'] = $this->client;
|
||||
$data['currency'] = $this->client->getCurrencyCode();
|
||||
$data['value'] = $this->convertToCheckoutAmount($data['amount_with_fee'], $this->client->getCurrencyCode());
|
||||
$data['raw_value'] = $data['amount_with_fee'];
|
||||
$data['customer_email'] = $this->client->present()->email;
|
||||
|
||||
return render($this->viewForType($data['payment_method_id']), $data);
|
||||
}
|
||||
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
$state = [
|
||||
'server_response' => json_decode($request->gateway_response),
|
||||
'value' => $request->value,
|
||||
'raw_value' => $request->raw_value,
|
||||
'currency' => $request->currency,
|
||||
];
|
||||
|
||||
$state = array_merge($state, $request->all());
|
||||
$state['store_card'] = boolval($state['store_card']);
|
||||
|
||||
if ($request->has('token') && !is_null($request->token)) {
|
||||
$method = new IdSource($state['token']);
|
||||
$payment = new CheckoutPayment($method, $state['currency']);
|
||||
$payment->capture = false;
|
||||
$payment->amount = $state['value'];
|
||||
} else {
|
||||
$method = new TokenSource($state['server_response']->cardToken);
|
||||
$payment = new CheckoutPayment($method, $state['currency']);
|
||||
$payment->amount = $state['value'];
|
||||
|
||||
if ($this->client->currency()->code === 'EUR') {
|
||||
$payment->{"3ds"} = ['enabled' => true];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->gateway->payments()->request($payment);
|
||||
$state['payment_response'] = $response;
|
||||
|
||||
if ($response->status === 'Authorized') {
|
||||
return $this->processSuccessfulPayment($state);
|
||||
}
|
||||
|
||||
if ($response->status === 'Pending') {
|
||||
return $this->processPendingPayment($state);
|
||||
}
|
||||
|
||||
if ($response->status === 'Declined') {
|
||||
return $this->processUnsuccessfulPayment($state);
|
||||
}
|
||||
} catch (CheckoutHttpException $e) {
|
||||
return $this->processInternallyFailedPayment($e, $state);
|
||||
}
|
||||
}
|
||||
|
||||
public function processSuccessfulPayment($state)
|
||||
{
|
||||
$state['charge_id'] = $state['payment_response']->id;
|
||||
|
||||
if (isset($state['store_card']) && $state['store_card']) {
|
||||
$this->saveCard($state);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'payment_method' => $state['charge_id'],
|
||||
'payment_type' => PaymentType::parseCardType($state['payment_response']->source['scheme']),
|
||||
'amount' => $state['raw_value'],
|
||||
];
|
||||
|
||||
$payment = $this->createPayment($data, Payment::STATUS_COMPLETED);
|
||||
|
||||
$this->attachInvoices($payment, $state['hashed_ids']);
|
||||
|
||||
$payment->service()->updateInvoicePayment();
|
||||
|
||||
event(new PaymentWasCreated($payment, $payment->company));
|
||||
|
||||
$logger_message = [
|
||||
'server_response' => $state['payment_response'],
|
||||
'data' => $data
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
public function processPendingPayment($state)
|
||||
{
|
||||
$state['charge_id'] = $state['payment_response']->id;
|
||||
|
||||
if (isset($state['store_card']) && $state['store_card']) {
|
||||
$this->saveCard($state);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'payment_method' => $state['charge_id'],
|
||||
'payment_type' => PaymentType::parseCardType($state['payment_response']->source['scheme']),
|
||||
'amount' => $state['raw_value'],
|
||||
];
|
||||
|
||||
$payment = $this->createPayment($data, Payment::STATUS_PENDING);
|
||||
|
||||
$this->attachInvoices($payment, $state['hashed_ids']);
|
||||
|
||||
$payment->service()->updateInvoicePayment();
|
||||
|
||||
event(new PaymentWasCreated($payment, $payment->company));
|
||||
|
||||
$logger_message = [
|
||||
'server_response' => $state['payment_response'],
|
||||
'data' => $data
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
|
||||
try {
|
||||
return redirect($state['payment_response']->_links['redirect']['href']);
|
||||
} catch (\Exception $e) {
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
|
||||
throw new \Exception('Failed to process the payment.', 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function processUnsuccessfulPayment($state)
|
||||
{
|
||||
PaymentFailureMailer::dispatch($this->client, $state['payment_response']->response_summary, $this->client->company, $state['payment_response']->amount);
|
||||
|
||||
$message = [
|
||||
'server_response' => $state['server_response'],
|
||||
'data' => $state,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
|
||||
throw new \Exception('Failed to process the payment: ' . $state['payment_response']->response_summary, 1);
|
||||
}
|
||||
|
||||
public function processInternallyFailedPayment($e, $state)
|
||||
{
|
||||
$message = json_decode($e->getBody());
|
||||
|
||||
PaymentFailureMailer::dispatch($this->client, $message->error_type, $this->client->company, $state['value']);
|
||||
|
||||
$message = [
|
||||
'server_response' => $state['server_response'],
|
||||
'data' => $message,
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_CHECKOUT, $this->client);
|
||||
|
||||
throw new \Exception('Failed to process the payment.', 1);
|
||||
}
|
||||
|
||||
public function createPayment($data, $status = Payment::STATUS_COMPLETED): Payment
|
||||
{
|
||||
$payment = parent::createPayment($data, $status);
|
||||
|
||||
$client_contact = $this->getContact();
|
||||
$client_contact_id = $client_contact ? $client_contact->id : null;
|
||||
|
||||
$payment->amount = $data['amount'];
|
||||
$payment->type_id = $data['payment_type'];
|
||||
$payment->transaction_reference = $data['payment_method'];
|
||||
$payment->client_contact_id = $client_contact_id;
|
||||
$payment->save();
|
||||
|
||||
return $payment;
|
||||
}
|
||||
|
||||
public function saveCard($state)
|
||||
{
|
||||
$company_gateway_token = new ClientGatewayToken();
|
||||
$company_gateway_token->company_id = $this->client->company->id;
|
||||
$company_gateway_token->client_id = $this->client->id;
|
||||
$company_gateway_token->token = $state['payment_response']->source['id'];
|
||||
$company_gateway_token->company_gateway_id = $this->company_gateway->id;
|
||||
$company_gateway_token->gateway_type_id = $state['payment_method_id'];
|
||||
$company_gateway_token->meta = $state['payment_response']->source;
|
||||
$company_gateway_token->save();
|
||||
|
||||
if ($this->client->gateway_tokens->count() == 1) {
|
||||
$this->client->gateway_tokens()->update(['is_default' => 0]);
|
||||
|
||||
$company_gateway_token->is_default = 1;
|
||||
$company_gateway_token->save();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers;
|
||||
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Utils\Traits\SystemLogTrait;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Omnipay\Omnipay;
|
||||
|
||||
/**
|
||||
* Class BasePaymentDriver
|
||||
* @package App\PaymentDrivers
|
||||
*
|
||||
* Minimum dataset required for payment gateways
|
||||
*
|
||||
* $data = [
|
||||
'amount' => $invoice->getRequestedAmount(),
|
||||
'currency' => $invoice->getCurrencyCode(),
|
||||
'returnUrl' => $completeUrl,
|
||||
'cancelUrl' => $this->invitation->getLink(),
|
||||
'description' => trans('texts.' . $invoice->getEntityType()) . " {$invoice->number}",
|
||||
'transactionId' => $invoice->number,
|
||||
'transactionType' => 'Purchase',
|
||||
'clientIp' => Request::getClientIp(),
|
||||
];
|
||||
|
||||
*/
|
||||
class CheckoutPaymentDriver extends BasePaymentDriver
|
||||
{
|
||||
use SystemLogTrait;
|
||||
|
||||
/* The company gateway instance*/
|
||||
protected $company_gateway;
|
||||
|
||||
/* The Omnipay payment driver instance*/
|
||||
protected $gateway;
|
||||
|
||||
/* The Invitation */
|
||||
protected $invitation;
|
||||
|
||||
/* Gateway capabilities */
|
||||
protected $refundable = true;
|
||||
|
||||
/* Token billing */
|
||||
protected $token_billing = true;
|
||||
|
||||
/* Authorise payment methods */
|
||||
protected $can_authorise_credit_card = true;
|
||||
|
||||
public function createTransactionToken($amount)
|
||||
{
|
||||
// if ($this->invoice()->getCurrencyCode() == 'BHD') {
|
||||
// $amount = $this->invoice()->getRequestedAmount() / 10;
|
||||
// } elseif ($this->invoice()->getCurrencyCode() == 'KWD') {
|
||||
// $amount = $this->invoice()->getRequestedAmount() * 10;
|
||||
// } elseif ($this->invoice()->getCurrencyCode() == 'OMR') {
|
||||
// $amount = $this->invoice()->getRequestedAmount();
|
||||
// } else
|
||||
// $amount = $this->invoice()->getRequestedAmount();
|
||||
|
||||
$response = $this->gateway()->purchase([
|
||||
'amount' => $amount,
|
||||
'currency' => $this->client->getCurrencyCode(),
|
||||
])->send();
|
||||
|
||||
if ($response->isRedirect()) {
|
||||
$token = $response->getTransactionReference();
|
||||
|
||||
session()->flash('transaction_reference', $token);
|
||||
|
||||
|
||||
// On each request, session()->flash() || sesion('', value) || session[name] ||session->flash(key, value)
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function viewForType($gateway_type_id)
|
||||
{
|
||||
switch ($gateway_type_id) {
|
||||
case GatewayType::CREDIT_CARD:
|
||||
return 'gateways.checkout.credit_card';
|
||||
break;
|
||||
case GatewayType::TOKEN:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* $data = [
|
||||
'invoices' => $invoices,
|
||||
'amount' => $amount,
|
||||
'fee' => $gateway->calcGatewayFee($amount),
|
||||
'amount_with_fee' => $amount + $gateway->calcGatewayFee($amount),
|
||||
'token' => auth()->user()->client->gateway_token($gateway->id, $payment_method_id),
|
||||
'payment_method_id' => $payment_method_id,
|
||||
'hashed_ids' => explode(",", request()->input('hashed_ids')),
|
||||
];
|
||||
*/
|
||||
public function processPaymentView(array $data)
|
||||
{
|
||||
$data['token'] = $this->createTransactionToken($data['amount']);
|
||||
$data['gateway'] = $this->gateway();
|
||||
|
||||
return render($this->viewForType($data['payment_method_id']), $data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function processPaymentResponse($request)
|
||||
{
|
||||
$data['token'] = session('transaction_reference');
|
||||
|
||||
$this->completeOffsitePurchase($data);
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Stripe;
|
||||
|
||||
trait Utilities
|
||||
|
@ -21,8 +21,8 @@
|
||||
"php": ">=7.3",
|
||||
"ext-json": "*",
|
||||
"asgrim/ofxparser": "^1.2",
|
||||
"checkout/checkout-sdk-php": "^1.0",
|
||||
"authorizenet/authorizenet": "^2.0",
|
||||
"beganovich/omnipay-checkout": "dev-master",
|
||||
"cleverit/ubl_invoice": "^1.3",
|
||||
"composer/composer": "^1.10",
|
||||
"czproject/git-php": "^3.17",
|
||||
@ -80,7 +80,8 @@
|
||||
"App\\": "app/"
|
||||
},
|
||||
"files": [
|
||||
"app/Libraries/OFX.php" ]
|
||||
"app/Libraries/OFX.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
@ -89,8 +90,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": [
|
||||
]
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
94
composer.lock
generated
94
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "6441fc634b3600e7099ae8c02d6230b0",
|
||||
"content-hash": "5197c11f0679bd4daff4669e74c36f9d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asgrim/ofxparser",
|
||||
@ -191,30 +191,29 @@
|
||||
"time": "2020-06-12T18:16:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beganovich/omnipay-checkout",
|
||||
"version": "dev-master",
|
||||
"name": "checkout/checkout-sdk-php",
|
||||
"version": "1.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beganovich/omnipay-checkout.git",
|
||||
"reference": "a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21"
|
||||
"url": "https://github.com/checkout/checkout-sdk-php.git",
|
||||
"reference": "c83ecc54e549efde8ac53cf1bc9701e800d98b0b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beganovich/omnipay-checkout/zipball/a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21",
|
||||
"reference": "a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21",
|
||||
"url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/c83ecc54e549efde8ac53cf1bc9701e800d98b0b",
|
||||
"reference": "c83ecc54e549efde8ac53cf1bc9701e800d98b0b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"omnipay/common": "^3",
|
||||
"php": "^7.1"
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"omnipay/tests": "^3"
|
||||
"phpunit/phpunit": "^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Omnipay\\Checkout\\": "src"
|
||||
"Checkout\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@ -223,18 +222,28 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Benjamin Beganović",
|
||||
"email": "ben@invoiceninja.com",
|
||||
"role": "Developer"
|
||||
"name": "Checkout.com",
|
||||
"email": "platforms@checkout.com",
|
||||
"homepage": "https://github.com/checkout/checkout-sdk-php/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Checkout driver for the Omnipay PHP payment processing library",
|
||||
"homepage": "https://github.com/beganovich/omnipay-checkout",
|
||||
"description": "Checkout.com SDK for PHP",
|
||||
"homepage": "https://github.com/checkout/checkout-sdk-php",
|
||||
"keywords": [
|
||||
"beganovich",
|
||||
"omnipay-checkout"
|
||||
"CKO",
|
||||
"GW3",
|
||||
"Reboot",
|
||||
"api",
|
||||
"checkout",
|
||||
"checkout.com",
|
||||
"checkoutcom",
|
||||
"gateway",
|
||||
"library",
|
||||
"payment",
|
||||
"php",
|
||||
"sdk"
|
||||
],
|
||||
"time": "2020-05-11T22:18:27+00:00"
|
||||
"time": "2019-07-05T16:22:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cleverit/ubl_invoice",
|
||||
@ -8697,6 +8706,52 @@
|
||||
],
|
||||
"time": "2020-05-05T10:53:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beganovich/omnipay-checkout",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/beganovich/omnipay-checkout.git",
|
||||
"reference": "a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/beganovich/omnipay-checkout/zipball/a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21",
|
||||
"reference": "a4e78bc3ce6ea39ea2c2b7da3019b3966fc86a21",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"omnipay/common": "^3",
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"omnipay/tests": "^3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Omnipay\\Checkout\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Benjamin Beganović",
|
||||
"email": "ben@invoiceninja.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Checkout driver for the Omnipay PHP payment processing library",
|
||||
"homepage": "https://github.com/beganovich/omnipay-checkout",
|
||||
"keywords": [
|
||||
"beganovich",
|
||||
"omnipay-checkout"
|
||||
],
|
||||
"time": "2020-05-11T22:18:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beyondcode/laravel-dump-server",
|
||||
"version": "1.3.0",
|
||||
@ -11049,7 +11104,6 @@
|
||||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {
|
||||
"beganovich/omnipay-checkout": 20,
|
||||
"webpatser/laravel-countries": 20
|
||||
},
|
||||
"prefer-stable": true,
|
||||
|
@ -302,18 +302,18 @@ class RandomDataSeeder extends Seeder
|
||||
// $cg->save();
|
||||
// }
|
||||
|
||||
// if(config('ninja.testvars.checkout')) {
|
||||
// $cg = new CompanyGateway;
|
||||
// $cg->company_id = $company->id;
|
||||
// $cg->user_id = $user->id;
|
||||
// $cg->gateway_key = '3758e7f7c6f4cecf0f4f348b9a00f456';
|
||||
// $cg->require_cvv = true;
|
||||
// $cg->show_billing_address = true;
|
||||
// $cg->show_shipping_address = true;
|
||||
// $cg->update_details = true;
|
||||
// $cg->config = encrypt(config('ninja.testvars.checkout'));
|
||||
// $cg->save();
|
||||
// }
|
||||
if(config('ninja.testvars.checkout')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
$cg->user_id = $user->id;
|
||||
$cg->gateway_key = '3758e7f7c6f4cecf0f4f348b9a00f456';
|
||||
$cg->require_cvv = true;
|
||||
$cg->show_billing_address = true;
|
||||
$cg->show_shipping_address = true;
|
||||
$cg->update_details = true;
|
||||
$cg->config = encrypt(config('ninja.testvars.checkout'));
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
if(config('ninja.testvars.authorize')) {
|
||||
$cg = new CompanyGateway;
|
||||
|
3
public/css/app.css
vendored
3
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/clients/payments/checkout.com.js
vendored
Normal file
2
public/js/clients/payments/checkout.com.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! For license information please see checkout.com.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=8)}({8:function(e,t,n){e.exports=n("XYrq")},XYrq:function(e,t){window.CKOConfig={publicKey:document.querySelector('meta[name="public-key"]').content,customerEmail:document.querySelector('meta[name="customer-email"]').content,value:document.querySelector('meta[name="value"]').content,currency:document.querySelector('meta[name="currency"]').content,paymentMode:"cards",cardFormMode:"cardTokenisation",cardTokenised:function(e){document.querySelector('input[name="gateway_response"]').value=JSON.stringify(e.data),document.querySelector('input[name="store_card"]').value=document.getElementById("store-card-checkbox").checked?1:0,document.getElementById("server-response").submit()}}}});
|
9
public/js/clients/payments/checkout.com.js.LICENSE.txt
Normal file
9
public/js/clients/payments/checkout.com.js.LICENSE.txt
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
2
public/js/clients/payments/process.js
vendored
2
public/js/clients/payments/process.js
vendored
@ -1,2 +1,2 @@
|
||||
/*! For license information please see process.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=10)}({10:function(e,t,n){e.exports=n("OXGg")},OXGg:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}new(function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.key=t,this.usingToken=n}var t,r,o;return t=e,(r=[{key:"setupStripe",value:function(){return this.stripe=Stripe(this.key),this.elements=this.stripe.elements(),this}},{key:"createElement",value:function(){return this.cardElement=this.elements.create("card"),this}},{key:"mountCardElement",value:function(){return this.cardElement.mount("#card-element"),this}},{key:"completePaymentUsingToken",value:function(){var e=this,t=document.getElementById("pay-now-with-token");this.stripe.handleCardPayment(t.dataset.secret,{payment_method:t.dataset.token}).then((function(t){return t.error?e.handleFailure(t.error.message):e.handleSuccess(t)}))}},{key:"completePaymentWithoutToken",value:function(){var e=this,t=document.getElementById("pay-now"),n=document.getElementById("cardholder-name");this.stripe.handleCardPayment(t.dataset.secret,this.cardElement,{payment_method_data:{billing_details:{name:n.value}}}).then((function(t){return t.error?e.handleFailure(t.error.message):e.handleSuccess(t)}))}},{key:"handleSuccess",value:function(e){document.querySelector('input[name="gateway_response"]').value=JSON.stringify(e.paymentIntent);var t=document.querySelector('input[name="token-billing-checkbox"]');t&&(document.querySelector('input[name="store_card"]').value=t.checked),document.getElementById("server-response").submit()}},{key:"handleFailure",value:function(e){var t=document.getElementById("errors");t.textContent="",t.textContent=e,t.hidden=!1}},{key:"handle",value:function(){var e=this;this.setupStripe(),this.usingToken&&document.getElementById("pay-now-with-token").addEventListener("click",(function(){return e.completePaymentUsingToken()})),this.usingToken||(this.createElement().mountCardElement(),document.getElementById("pay-now").addEventListener("click",(function(){return e.completePaymentWithoutToken()})))}}])&&n(t.prototype,r),o&&n(t,o),e}())(document.querySelector('meta[name="stripe-publishable-key"]').content,document.querySelector('meta[name="using-token"]').content).handle()}});
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=11)}({11:function(e,t,n){e.exports=n("OXGg")},OXGg:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}new(function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.key=t,this.usingToken=n}var t,r,o;return t=e,(r=[{key:"setupStripe",value:function(){return this.stripe=Stripe(this.key),this.elements=this.stripe.elements(),this}},{key:"createElement",value:function(){return this.cardElement=this.elements.create("card"),this}},{key:"mountCardElement",value:function(){return this.cardElement.mount("#card-element"),this}},{key:"completePaymentUsingToken",value:function(){var e=this,t=document.getElementById("pay-now-with-token");this.stripe.handleCardPayment(t.dataset.secret,{payment_method:t.dataset.token}).then((function(t){return t.error?e.handleFailure(t.error.message):e.handleSuccess(t)}))}},{key:"completePaymentWithoutToken",value:function(){var e=this,t=document.getElementById("pay-now"),n=document.getElementById("cardholder-name");this.stripe.handleCardPayment(t.dataset.secret,this.cardElement,{payment_method_data:{billing_details:{name:n.value}}}).then((function(t){return t.error?e.handleFailure(t.error.message):e.handleSuccess(t)}))}},{key:"handleSuccess",value:function(e){document.querySelector('input[name="gateway_response"]').value=JSON.stringify(e.paymentIntent);var t=document.querySelector('input[name="token-billing-checkbox"]');t&&(document.querySelector('input[name="store_card"]').value=t.checked),document.getElementById("server-response").submit()}},{key:"handleFailure",value:function(e){var t=document.getElementById("errors");t.textContent="",t.textContent=e,t.hidden=!1}},{key:"handle",value:function(){var e=this;this.setupStripe(),this.usingToken&&document.getElementById("pay-now-with-token").addEventListener("click",(function(){return e.completePaymentUsingToken()})),this.usingToken||(this.createElement().mountCardElement(),document.getElementById("pay-now").addEventListener("click",(function(){return e.completePaymentWithoutToken()})))}}])&&n(t.prototype,r),o&&n(t,o),e}())(document.querySelector('meta[name="stripe-publishable-key"]').content,document.querySelector('meta[name="using-token"]').content).handle()}});
|
||||
|
3
public/js/clients/quotes/action-selectors.js
vendored
3
public/js/clients/quotes/action-selectors.js
vendored
@ -1,2 +1,3 @@
|
||||
/*! For license information please see action-selectors.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=8)}({8:function(e,t,n){e.exports=n("ydWM")},ydWM:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(new(function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.parentElement=document.querySelector(".form-check-parent"),this.parentForm=document.getElementById("bulkActions")}var t,r,o;return t=e,(r=[{key:"watchCheckboxes",value:function(e){var t=this;document.querySelectorAll(".form-check-child").forEach((function(n){e.checked?(n.checked=e.checked,t.processChildItem(n,document.getElementById("bulkActions"))):(n.checked=!1,document.querySelectorAll(".child-hidden-input").forEach((function(e){return e.remove()})))}))}},{key:"processChildItem",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};n.hasOwnProperty("single")&&document.querySelectorAll(".child-hidden-input").forEach((function(e){return e.remove()}));var r=document.createElement("INPUT");r.setAttribute("name","quotes[]"),r.setAttribute("value",e.dataset.value),r.setAttribute("class","child-hidden-input"),r.hidden=!0,t.append(r)}},{key:"handle",value:function(){var e=this;this.parentElement.addEventListener("click",(function(){e.watchCheckboxes(e.parentElement)}));var t=!0,n=!1,r=void 0;try{for(var o,c=function(){var t=o.value;t.addEventListener("click",(function(){e.processChildItem(t,e.parentForm)}))},u=document.querySelectorAll(".form-check-child")[Symbol.iterator]();!(t=(o=u.next()).done);t=!0)c()}catch(e){n=!0,r=e}finally{try{t||null==u.return||u.return()}finally{if(n)throw r}}}}])&&n(t.prototype,r),o&&n(t,o),e}())).handle()}});
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=9)}({9:function(e,t,n){e.exports=n("ydWM")},ydWM:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(new(function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.parentElement=document.querySelector(".form-check-parent"),this.parentForm=document.getElementById("bulkActions")}var t,r,o;return t=e,(r=[{key:"watchCheckboxes",value:function(e){var t=this;document.querySelectorAll(".form-check-child").forEach((function(n){e.checked?(n.checked=e.checked,t.processChildItem(n,document.getElementById("bulkActions"))):(n.checked=!1,document.querySelectorAll(".child-hidden-input").forEach((function(e){return e.remove()})))}))}},{key:"processChildItem",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};n.hasOwnProperty("single")&&document.querySelectorAll(".child-hidden-input").forEach((function(e){return e.remove()}));var r=document.createElement("INPUT");r.setAttribute("name","quotes[]"),r.setAttribute("value",e.dataset.value),r.setAttribute("class","child-hidden-input"),r.hidden=!0,t.append(r)}},{key:"handle",value:function(){var e=this;this.parentElement.addEventListener("click",(function(){e.watchCheckboxes(e.parentElement)}));var t=!0,n=!1,r=void 0;try{for(var o,c=function(){var t=o.value;t.addEventListener("click",(function(){e.processChildItem(t,e.parentForm)}))},u=document.querySelectorAll(".form-check-child")[Symbol.iterator]();!(t=(o=u.next()).done);t=!0)c()}catch(e){n=!0,r=e}finally{try{t||null==u.return||u.return()}finally{if(n)throw r}}}}])&&n(t.prototype,r),o&&n(t,o),e}())).handle()}});
|
||||
|
||||
|
3
public/js/clients/quotes/approve.js
vendored
3
public/js/clients/quotes/approve.js
vendored
@ -1,2 +1,3 @@
|
||||
/*! For license information please see approve.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=9)}({9:function(e,t,n){e.exports=n("WuMn")},WuMn:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var r=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.shouldDisplaySignature=t}var t,r,o;return t=e,(r=[{key:"submitForm",value:function(){document.getElementById("approve-form").submit()}},{key:"displaySignature",value:function(){document.getElementById("displaySignatureModal").removeAttribute("style"),new SignaturePad(document.getElementById("signature-pad"),{backgroundColor:"rgb(240,240,240)",penColor:"rgb(0, 0, 0)"})}},{key:"handle",value:function(){var e=this;document.getElementById("approve-button").addEventListener("click",(function(){e.shouldDisplaySignature&&(e.displaySignature(),document.getElementById("signature-next-step").addEventListener("click",(function(){e.submitForm()}))),e.shouldDisplaySignature||e.submitForm()}))}}])&&n(t.prototype,r),o&&n(t,o),e}(),o=document.querySelector('meta[name="require-quote-signature"]').content;new r(Boolean(+o)).handle()}});
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=10)}({10:function(e,t,n){e.exports=n("WuMn")},WuMn:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var r=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.shouldDisplaySignature=t}var t,r,o;return t=e,(r=[{key:"submitForm",value:function(){document.getElementById("approve-form").submit()}},{key:"displaySignature",value:function(){document.getElementById("displaySignatureModal").removeAttribute("style"),new SignaturePad(document.getElementById("signature-pad"),{backgroundColor:"rgb(240,240,240)",penColor:"rgb(0, 0, 0)"})}},{key:"handle",value:function(){var e=this;document.getElementById("approve-button").addEventListener("click",(function(){e.shouldDisplaySignature&&(e.displaySignature(),document.getElementById("signature-next-step").addEventListener("click",(function(){e.submitForm()}))),e.shouldDisplaySignature||e.submitForm()}))}}])&&n(t.prototype,r),o&&n(t,o),e}(),o=document.querySelector('meta[name="require-quote-signature"]').content;new r(Boolean(+o)).handle()}});
|
||||
|
||||
|
3
public/js/clients/shared/pdf.js
vendored
3
public/js/clients/shared/pdf.js
vendored
File diff suppressed because one or more lines are too long
3
public/js/setup/setup.js
vendored
3
public/js/setup/setup.js
vendored
File diff suppressed because one or more lines are too long
@ -1,16 +1,17 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js?id=8b49701583f407403ddf",
|
||||
"/css/app.css": "/css/app.css?id=1b4ad8bb52ea6da03528",
|
||||
"/css/app.css": "/css/app.css?id=05d9dbe4a834b13c2fde",
|
||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=d16c0e6728b00d329cbb",
|
||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1",
|
||||
"/js/clients/payment_methods/authorize-ach.js": "/js/clients/payment_methods/authorize-ach.js?id=30a5db56b004becf4715",
|
||||
"/js/clients/payment_methods/authorize-authorize-card.js": "/js/clients/payment_methods/authorize-authorize-card.js?id=b0a1bd21a57e12cd491a",
|
||||
"/js/clients/payment_methods/authorize-stripe-card.js": "/js/clients/payment_methods/authorize-stripe-card.js?id=f4c45f0da9868d840799",
|
||||
"/js/clients/payments/alipay.js": "/js/clients/payments/alipay.js?id=04778cbf46488e8f6b5f",
|
||||
"/js/clients/payments/process.js": "/js/clients/payments/process.js?id=0bdd1a7589d74f11c66f",
|
||||
"/js/clients/payments/checkout.com.js": "/js/clients/payments/checkout.com.js?id=591618c8bcd926b7111d",
|
||||
"/js/clients/payments/process.js": "/js/clients/payments/process.js?id=be2b10b1b5e3a727f6e2",
|
||||
"/js/clients/payments/sofort.js": "/js/clients/payments/sofort.js?id=f9253aea74535bc46886",
|
||||
"/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=222bdd54bf9ed1d9b837",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=5cf5a06486e8a108adb1",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=514f558f39158d50f4c7",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=4e25e6ead22865dabbf6"
|
||||
"/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=88ff76c9ca1c15fc011b",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=9cdbe50bab63dc1dd520",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=5df2af6e8ba88b2621d9",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=cd5d37e5eddb88678da4"
|
||||
}
|
||||
|
30
resources/js/clients/payments/checkout.com.js
vendored
Normal file
30
resources/js/clients/payments/checkout.com.js
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
window.CKOConfig = {
|
||||
publicKey: document.querySelector('meta[name="public-key"]').content,
|
||||
customerEmail: document.querySelector('meta[name="customer-email"]')
|
||||
.content,
|
||||
value: document.querySelector('meta[name="value"]').content,
|
||||
currency: document.querySelector('meta[name="currency"]').content,
|
||||
paymentMode: 'cards',
|
||||
cardFormMode: 'cardTokenisation',
|
||||
cardTokenised: function(event) {
|
||||
document.querySelector(
|
||||
'input[name="gateway_response"]'
|
||||
).value = JSON.stringify(event.data);
|
||||
|
||||
document.querySelector(
|
||||
'input[name="store_card"]'
|
||||
).value = document.getElementById('store-card-checkbox').checked ? 1 : 0;
|
||||
|
||||
document.getElementById('server-response').submit();
|
||||
},
|
||||
};
|
@ -3211,6 +3211,8 @@ return [
|
||||
|
||||
'verification' => 'Verification',
|
||||
'complete_your_bank_account_verification' => 'Before using bank account they must be verified.',
|
||||
|
||||
'checkout_com' => 'Checkout.com',
|
||||
|
||||
'footer_label' => 'Copyright © :year Invoice Ninja. All rights reserved.',
|
||||
];
|
||||
|
@ -1,42 +1,97 @@
|
||||
@extends('portal.ninja2020.layout.app')
|
||||
@section('meta_title', ctrans('texts.checkout_com'))
|
||||
|
||||
<script src="https://cdn.checkout.com/sandbox/js/checkout.js"></script>
|
||||
<form class="payment-form" method="POST" action="https://merchant.com/successUrl">
|
||||
<script>
|
||||
Checkout.render({
|
||||
publicKey: 'pk_test_6ff46046-30af-41d9-bf58-929022d2cd14',
|
||||
paymentToken: 'pay_tok_SPECIMEN-000',
|
||||
customerEmail: 'user@email.com',
|
||||
value: 100,
|
||||
currency: 'GBP',
|
||||
cardFormMode: 'cardTokenisation',
|
||||
cardTokenised: function(event) {
|
||||
console.log(event.data.cardToken);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</form>
|
||||
@push('head')
|
||||
<meta name="public-key" content="{{ $gateway->getPublishableKey() }}">
|
||||
<meta name="customer-email" content="{{ $customer_email }}">
|
||||
<meta name="value" content="{{ $value }}">
|
||||
<meta name="currency" content="{{ $currency }}">
|
||||
|
||||
<!--
|
||||
Checkout.render({
|
||||
debugMode: {{ $gateway->getConfigField('testMode') ? 'true' : 'false' }},
|
||||
publicKey: '{{ $gateway->getConfigField('publicApiKey') }}',
|
||||
paymentToken: '{{ $token }}',
|
||||
customerEmail: '{{ $contact->email }}',
|
||||
customerName: '{{ $contact->getFullName() }}',
|
||||
@if( $invoice->getCurrencyCode() == 'BHD' || $invoice->getCurrencyCode() == 'KWD' || $invoice->getCurrencyCode() == 'OMR')
|
||||
value: {{ $invoice->getRequestedAmount() * 1000 }},
|
||||
@else
|
||||
value: {{ $invoice->getRequestedAmount() * 100 }},
|
||||
@endif
|
||||
currency: '{{ $invoice->getCurrencyCode() }}',
|
||||
widgetContainerSelector: '.payment-form',
|
||||
widgetColor: '#333',
|
||||
themeColor: '#3075dd',
|
||||
buttonColor:'#51c470',
|
||||
cardCharged: function(event){
|
||||
location.href = '{{ URL::to('/complete/'. $invitation->invitation_key . '/credit_card?token=' . $transactionToken) }}';
|
||||
}
|
||||
});
|
||||
<script src="{{ asset('js/clients/payments/checkout.com.js') }}"></script>
|
||||
@endpush
|
||||
|
||||
-->
|
||||
@section('body')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server-response">
|
||||
@csrf
|
||||
<input type="hidden" name="gateway_response">
|
||||
<input type="hidden" name="store_card">
|
||||
@foreach($invoices as $invoice)
|
||||
<input type="hidden" name="hashed_ids[]" value="{{ $invoice->hashed_id }}">
|
||||
@endforeach
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
|
||||
<input type="hidden" name="value" value="{{ $value }}">
|
||||
<input type="hidden" name="raw_value" value="{{ $raw_value }}">
|
||||
<input type="hidden" name="currency" value="{{ $currency }}">
|
||||
@isset($token)
|
||||
<input type="hidden" name="token" value="{{ $token->meta->id }}">
|
||||
@endisset
|
||||
</form>
|
||||
|
||||
<div class="container mx-auto">
|
||||
<div class="grid grid-cols-6 gap-4">
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{{ ctrans('texts.pay_now') }}
|
||||
</h3>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
||||
{{ ctrans('texts.complete_your_payment') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4">
|
||||
{{ ctrans('texts.payment_type') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ ctrans('texts.checkout_com') }} ({{ ctrans('texts.credit_card') }})
|
||||
</dd>
|
||||
</div>
|
||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4">
|
||||
{{ ctrans('texts.amount') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
<span class="font-bold">{{ App\Utils\Number::formatMoney($amount, $client) }}</span>
|
||||
</dd>
|
||||
</div>
|
||||
@isset($token)
|
||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
||||
{{ ctrans('texts.card_number') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
**** {{ ucfirst($token->meta->last4) }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="bg-white px-4 py-5 flex justify-end">
|
||||
<button class="button button-primary" onclick="document.getElementById('server-response').submit()">
|
||||
{{ ctrans('texts.pay_now') }}
|
||||
</button>
|
||||
</div>
|
||||
@else
|
||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4">
|
||||
{{ ctrans('texts.token_billing_checkbox') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
<input type="checkbox" id="store-card-checkbox" class="form-checkbox">
|
||||
</dd>
|
||||
</div>
|
||||
<div class="bg-white px-4 py-5 flex justify-end">
|
||||
<form class="payment-form" method="POST" action="https://merchant.com/successUrl">
|
||||
@if(app()->environment() == 'production')
|
||||
<script async src="https://cdn.checkout.com/js/checkout.js"></script>
|
||||
@else
|
||||
<script async src="https://cdn.checkout.com/sandbox/js/checkout.js"></script>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
@endisset
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@ -4,7 +4,6 @@
|
||||
@push('head')
|
||||
<meta name="stripe-publishable-key" content="{{ $gateway->getPublishableKey() }}">
|
||||
<meta name="using-token" content="{{ boolval($token) }}">
|
||||
<meta name="turbolinks-visit-control" content="reload">
|
||||
@endpush
|
||||
|
||||
@section('body')
|
||||
@ -20,14 +19,14 @@
|
||||
</form>
|
||||
<div class="container mx-auto">
|
||||
<div class="grid grid-cols-6 gap-4">
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{{ ctrans('texts.pay_now') }}
|
||||
</h3>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500" translate>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
||||
{{ ctrans('texts.complete_your_payment') }}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -27,7 +27,8 @@
|
||||
{{ ctrans('texts.type') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ ucfirst($payment_method->meta->brand) }}
|
||||
{{ optional($payment_method->meta)->brand }}
|
||||
{{ optional($payment_method->meta)->scheme }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
|
@ -35,7 +35,7 @@
|
||||
{{ ctrans('texts.method') }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ $payment->type->name }}
|
||||
{{ optional($payment->type)->name }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
@ -62,7 +62,7 @@
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
{{ ctrans('texts.invoices') }}
|
||||
</h3>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500" translate>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
||||
{{ ctrans('texts.list_of_payment_invoices') }}
|
||||
</p>
|
||||
</div>
|
||||
|
4
webpack.mix.js
vendored
4
webpack.mix.js
vendored
@ -30,6 +30,10 @@ mix.js("resources/js/app.js", "public/js")
|
||||
"resources/js/clients/payments/alipay.js",
|
||||
"public/js/clients/payments/alipay.js"
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/payments/checkout.com.js",
|
||||
"public/js/clients/payments/checkout.com.js"
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/quotes/action-selectors.js",
|
||||
"public/js/clients/quotes/action-selectors.js"
|
||||
|
Loading…
Reference in New Issue
Block a user