mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge branch 'v5-develop' of https://github.com/invoiceninja/invoiceninja into feature-inbound-email-expenses
This commit is contained in:
commit
befbdc399d
@ -52,6 +52,10 @@ class DbQuery extends GenericMixedMetric
|
|||||||
|
|
||||||
public $string_metric7 = 'ip_address';
|
public $string_metric7 = 'ip_address';
|
||||||
|
|
||||||
|
public $string_metric8 = 'client_version';
|
||||||
|
|
||||||
|
public $string_metric9 = 'platform';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The counter
|
* The counter
|
||||||
* set to 1.
|
* set to 1.
|
||||||
|
@ -32,7 +32,6 @@ use App\Models\BankIntegration;
|
|||||||
use App\Models\BankTransaction;
|
use App\Models\BankTransaction;
|
||||||
use App\Models\ExpenseCategory;
|
use App\Models\ExpenseCategory;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
use App\DataMapper\EDoc\Schema\RO;
|
|
||||||
use App\Models\BankTransactionRule;
|
use App\Models\BankTransactionRule;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use App\Transformers\ArraySerializer;
|
use App\Transformers\ArraySerializer;
|
||||||
@ -42,6 +41,7 @@ use Illuminate\Database\Eloquent\Builder;
|
|||||||
use League\Fractal\Serializer\JsonApiSerializer;
|
use League\Fractal\Serializer\JsonApiSerializer;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||||
|
use Invoiceninja\Einvoice\Decoder\Schema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BaseController.
|
* Class BaseController.
|
||||||
@ -890,7 +890,6 @@ class BaseController extends Controller
|
|||||||
/** @phpstan-ignore-next-line **/
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection();// @phpstan-ignore-line
|
$query = $paginator->getCollection();// @phpstan-ignore-line
|
||||||
|
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
}
|
}
|
||||||
@ -998,8 +997,8 @@ class BaseController extends Controller
|
|||||||
|
|
||||||
if(request()->has('einvoice')){
|
if(request()->has('einvoice')){
|
||||||
|
|
||||||
$ro = new RO();
|
$ro = new Schema();
|
||||||
$response_data['einvoice_schema'] = $ro();
|
$response_data['einvoice_schema'] = $ro('FACT1');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,22 @@ class QueryLogging
|
|||||||
$ip = $request->ip();
|
$ip = $request->ip();
|
||||||
}
|
}
|
||||||
|
|
||||||
LightLogs::create(new DbQuery($request->method(), substr(urldecode($request->url()), 0, 180), $count, $time, $ip))
|
$client_version = $request->server('HTTP_USER_AGENT');
|
||||||
|
$platform = '';
|
||||||
|
|
||||||
|
if ($request->hasHeader('X-CLIENT-PLATFORM')) {
|
||||||
|
$platform = $request->header('X-CLIENT-PLATFORM');
|
||||||
|
}
|
||||||
|
elseif($request->hasHeader('X-React')){
|
||||||
|
$platform = 'react';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->hasHeader('X-CLIENT-VERSION'))
|
||||||
|
{
|
||||||
|
$client_version = $request->header('X-CLIENT-VERSION');
|
||||||
|
}
|
||||||
|
|
||||||
|
LightLogs::create(new DbQuery($request->method(), substr(urldecode($request->url()), 0, 180), $count, $time, $ip, $client_version, $platform))
|
||||||
->batch();
|
->batch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ use App\Http\ValidationRules\Company\ValidSubdomain;
|
|||||||
use App\Http\ValidationRules\ValidSettingsRule;
|
use App\Http\ValidationRules\ValidSettingsRule;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Invoiceninja\Einvoice\Models\FatturaPA\FatturaElettronica;
|
||||||
|
|
||||||
class UpdateCompanyRequest extends Request
|
class UpdateCompanyRequest extends Request
|
||||||
{
|
{
|
||||||
@ -120,6 +121,11 @@ class UpdateCompanyRequest extends Request
|
|||||||
$input['smtp_verify_peer'] == 'true' ? true : false;
|
$input['smtp_verify_peer'] == 'true' ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(isset($input['e_invoice'])){
|
||||||
|
// nlog("am i set?");
|
||||||
|
// $r = FatturaElettronica::validate($input['e_invoice']);
|
||||||
|
// }
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +241,32 @@ class CompanyImport implements ShouldQueue
|
|||||||
CompanyGateway::class => [
|
CompanyGateway::class => [
|
||||||
'always_show_required_fields',
|
'always_show_required_fields',
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
'5.8.57' => [
|
||||||
|
Company::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
|
Invoice::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
|
Quote::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
|
Credit::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
|
PurchaseOrder::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
|
Expense::class => [
|
||||||
|
'einvoice',
|
||||||
|
'e_invoice',
|
||||||
|
],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
62
app/Jobs/EDocument/MergeEDocument.php
Normal file
62
app/Jobs/EDocument/MergeEDocument.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs\EDocument;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use horstoeko\zugferd\ZugferdDocumentPdfBuilder;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
|
||||||
|
class MergeEDocument implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
use InteractsWithQueue;
|
||||||
|
use Queueable;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public $deleteWhenMissingModels = true;
|
||||||
|
|
||||||
|
public function __construct(private mixed $document, private string $pdf_file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function handle(): string
|
||||||
|
{
|
||||||
|
$settings_entity = ($this->document instanceof PurchaseOrder) ? $this->document->vendor : $this->document->client;
|
||||||
|
|
||||||
|
$e_document_type = strlen($settings_entity->getSetting('e_invoice_type')) > 2 ? $settings_entity->getSetting('e_invoice_type') : "XInvoice_3_0";
|
||||||
|
|
||||||
|
if ($this->document instanceof Invoice){
|
||||||
|
switch ($e_document_type) {
|
||||||
|
case "EN16931":
|
||||||
|
case "XInvoice_3_0":
|
||||||
|
case "XInvoice_2_3":
|
||||||
|
case "XInvoice_2_2":
|
||||||
|
case "XInvoice_2_1":
|
||||||
|
case "XInvoice_2_0":
|
||||||
|
case "XInvoice_1_0":
|
||||||
|
case "XInvoice-Extended":
|
||||||
|
case "XInvoice-BasicWL":
|
||||||
|
case "XInvoice-Basic":
|
||||||
|
$xml = (new CreateEDocument($this->document, true))->handle();
|
||||||
|
return(new ZugferdDocumentPdfBuilder($xml, $this->pdf_file))->generateDocument()->downloadString("Invoice.pdf");
|
||||||
|
default:
|
||||||
|
return $this->pdf_file;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $this->pdf_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Jobs\Entity;
|
namespace App\Jobs\Entity;
|
||||||
|
|
||||||
use App\Exceptions\FilePermissionsFailure;
|
use App\Exceptions\FilePermissionsFailure;
|
||||||
|
use App\Jobs\EDocument\MergeEDocument;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
@ -95,6 +96,9 @@ class CreateRawPdf
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FilePermissionsFailure
|
||||||
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
/** Testing this override to improve PDF generation performance */
|
/** Testing this override to improve PDF generation performance */
|
||||||
@ -104,11 +108,15 @@ class CreateRawPdf
|
|||||||
"{$this->entity_string}s" => [$this->entity],
|
"{$this->entity_string}s" => [$this->entity],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$pdf = $ps->boot()->getPdf();
|
try {
|
||||||
nlog("pdf timer = ". $ps->execution_time);
|
$pdf = $ps->boot()->getPdf();
|
||||||
|
} catch (\Exception) {
|
||||||
|
throw new FilePermissionsFailure('Unable to generate the raw PDF');
|
||||||
|
}
|
||||||
|
if ($this->entity_string == "invoice" && $this->entity->getSetting("merge_e_invoice_to_pdf")){
|
||||||
|
$pdf = (new MergeEDocument($this->entity, $pdf))->handle();
|
||||||
|
}
|
||||||
return $pdf;
|
return $pdf;
|
||||||
|
|
||||||
throw new FilePermissionsFailure('Unable to generate the raw PDF');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function failed($e)
|
public function failed($e)
|
||||||
|
@ -136,8 +136,8 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
|
|
||||||
$mailable = $this->nmo->mailable;
|
$mailable = $this->nmo->mailable;
|
||||||
|
|
||||||
/** May need to re-build it here */
|
/** May need to re-build it here @todo explain why we need this? */
|
||||||
if (Ninja::isHosted() && method_exists($mailable, 'build')) {
|
if (Ninja::isHosted() && method_exists($mailable, 'build') && $this->nmo->settings->email_style != "custom") {
|
||||||
$mailable->build();
|
$mailable->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,13 +116,17 @@ class EmailPayment implements ShouldQueue
|
|||||||
|
|
||||||
$invoice->invitations->each(function ($invite) use ($email_builder) {
|
$invoice->invitations->each(function ($invite) use ($email_builder) {
|
||||||
|
|
||||||
|
|
||||||
|
$cloned_mailable = unserialize(serialize($email_builder));
|
||||||
|
|
||||||
$nmo = new NinjaMailerObject();
|
$nmo = new NinjaMailerObject();
|
||||||
$nmo->mailable = new TemplateEmail($email_builder, $invite->contact, $invite);
|
$nmo->mailable = new TemplateEmail($cloned_mailable, $invite->contact, $invite);
|
||||||
$nmo->to_user = $invite->contact;
|
$nmo->to_user = $invite->contact;
|
||||||
$nmo->settings = $this->settings;
|
$nmo->settings = $this->settings;
|
||||||
$nmo->company = $this->company;
|
$nmo->company = $this->company;
|
||||||
$nmo->entity = $this->payment;
|
$nmo->entity = $this->payment;
|
||||||
(new NinjaMailerJob($nmo))->handle();
|
(new NinjaMailerJob($nmo))->handle();
|
||||||
|
$nmo = null;
|
||||||
|
|
||||||
event(new PaymentWasEmailed($this->payment, $this->payment->company, $invite->contact, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new PaymentWasEmailed($this->payment, $this->payment->company, $invite->contact, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
$reminder_template = $invoice->calculateTemplate('invoice');
|
$reminder_template = $invoice->calculateTemplate('invoice');
|
||||||
nrlog("reminder template = {$reminder_template}");
|
nrlog("#{$invoice->number} => reminder template = {$reminder_template}");
|
||||||
$invoice->service()->touchReminder($reminder_template)->save();
|
$invoice->service()->touchReminder($reminder_template)->save();
|
||||||
$fees = $this->calcLateFee($invoice, $reminder_template);
|
$fees = $this->calcLateFee($invoice, $reminder_template);
|
||||||
|
|
||||||
|
@ -134,10 +134,6 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
|||||||
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->invoice->numberFormatter().'.pdf']]);
|
$this->setAttachments([['file' => base64_encode($pdf), 'name' => $this->invoice->numberFormatter().'.pdf']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// $hash = Str::uuid();
|
|
||||||
// $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
|
|
||||||
// Cache::put($hash, $url, now()->addHour());
|
|
||||||
|
|
||||||
//attach third party documents
|
//attach third party documents
|
||||||
if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
|
if ($this->client->getSetting('document_email_attachment') !== false && $this->invoice->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
|
||||||
if ($this->invoice->recurring_invoice()->exists()) {
|
if ($this->invoice->recurring_invoice()->exists()) {
|
||||||
|
@ -99,7 +99,6 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
->setViewLink('')
|
->setViewLink('')
|
||||||
->setViewText('');
|
->setViewText('');
|
||||||
|
|
||||||
|
|
||||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||||
|
|
||||||
$template_in_use = false;
|
$template_in_use = false;
|
||||||
|
@ -31,6 +31,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* App\Models\Account
|
* App\Models\Account
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property int $email_quota
|
||||||
* @property string|null $plan
|
* @property string|null $plan
|
||||||
* @property string|null $plan_term
|
* @property string|null $plan_term
|
||||||
* @property string|null $plan_started
|
* @property string|null $plan_started
|
||||||
|
@ -380,6 +380,7 @@ class Company extends BaseModel
|
|||||||
'smtp_encryption',
|
'smtp_encryption',
|
||||||
'smtp_local_domain',
|
'smtp_local_domain',
|
||||||
'smtp_verify_peer',
|
'smtp_verify_peer',
|
||||||
|
'e_invoice',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
@ -404,6 +405,7 @@ class Company extends BaseModel
|
|||||||
'e_invoice_certificate_passphrase' => EncryptedCast::class,
|
'e_invoice_certificate_passphrase' => EncryptedCast::class,
|
||||||
'smtp_username' => 'encrypted',
|
'smtp_username' => 'encrypted',
|
||||||
'smtp_password' => 'encrypted',
|
'smtp_password' => 'encrypted',
|
||||||
|
'e_invoice' => 'object',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $with = [];
|
protected $with = [];
|
||||||
|
@ -155,6 +155,7 @@ class CompanyGateway extends BaseModel
|
|||||||
'b9886f9257f0c6ee7c302f1c74475f6c' => 321, //GoCardless
|
'b9886f9257f0c6ee7c302f1c74475f6c' => 321, //GoCardless
|
||||||
'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9' => 322,
|
'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9' => 322,
|
||||||
'80af24a6a691230bbec33e930ab40666' => 323,
|
'80af24a6a691230bbec33e930ab40666' => 323,
|
||||||
|
'vpyfbmdrkqcicpkjqdusgjfluebftuva' => 324, //BTPay
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $touches = [];
|
protected $touches = [];
|
||||||
|
@ -28,6 +28,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* App\Models\Credit
|
* App\Models\Credit
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property object|null $e_invoice
|
||||||
* @property int $client_id
|
* @property int $client_id
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property int|null $assigned_user_id
|
* @property int|null $assigned_user_id
|
||||||
@ -179,6 +180,7 @@ class Credit extends BaseModel
|
|||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
'is_amount_discount' => 'bool',
|
'is_amount_discount' => 'bool',
|
||||||
|
'e_invoice' => 'object',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* App\Models\Expense
|
* App\Models\Expense
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property object|null $e_invoice
|
||||||
* @property int|null $created_at
|
* @property int|null $created_at
|
||||||
* @property int|null $updated_at
|
* @property int|null $updated_at
|
||||||
* @property int|null $deleted_at
|
* @property int|null $deleted_at
|
||||||
@ -141,6 +142,7 @@ class Expense extends BaseModel
|
|||||||
'updated_at' => 'timestamp',
|
'updated_at' => 'timestamp',
|
||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
|
'e_invoice' => 'object',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $touches = [];
|
protected $touches = [];
|
||||||
|
@ -32,6 +32,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* App\Models\Invoice
|
* App\Models\Invoice
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property object|null $e_invoice
|
||||||
* @property int $client_id
|
* @property int $client_id
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property int|null $assigned_user_id
|
* @property int|null $assigned_user_id
|
||||||
@ -209,6 +210,7 @@ class Invoice extends BaseModel
|
|||||||
'custom_surcharge_tax2' => 'bool',
|
'custom_surcharge_tax2' => 'bool',
|
||||||
'custom_surcharge_tax3' => 'bool',
|
'custom_surcharge_tax3' => 'bool',
|
||||||
'custom_surcharge_tax4' => 'bool',
|
'custom_surcharge_tax4' => 'bool',
|
||||||
|
'e_invoice' => 'object',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $with = [];
|
protected $with = [];
|
||||||
|
@ -83,9 +83,9 @@ class CompanyPresenter extends EntityPresenter
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (strlen($settings->company_logo) >= 1 && (strpos($settings->company_logo, 'http') !== false)) {
|
if (strlen($settings->company_logo) >= 1 && (strpos($settings->company_logo, 'http') !== false)) {
|
||||||
return "data:image/png;base64, ". base64_encode(@file_get_contents($settings->company_logo, false, stream_context_create($context_options)));
|
return "data:image/png;base64,". base64_encode(@file_get_contents($settings->company_logo, false, stream_context_create($context_options)));
|
||||||
} elseif (strlen($settings->company_logo) >= 1) {
|
} elseif (strlen($settings->company_logo) >= 1) {
|
||||||
return "data:image/png;base64, ". base64_encode(@file_get_contents(url('') . $settings->company_logo, false, stream_context_create($context_options)));
|
return "data:image/png;base64,". base64_encode(@file_get_contents(url('') . $settings->company_logo, false, stream_context_create($context_options)));
|
||||||
} else {
|
} else {
|
||||||
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
|
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use Illuminate\Support\Carbon;
|
|||||||
* App\Models\PurchaseOrder
|
* App\Models\PurchaseOrder
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property object|null $e_invoice
|
||||||
* @property int|null $client_id
|
* @property int|null $client_id
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property int|null $assigned_user_id
|
* @property int|null $assigned_user_id
|
||||||
@ -187,7 +188,7 @@ class PurchaseOrder extends BaseModel
|
|||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
'is_amount_discount' => 'bool',
|
'is_amount_discount' => 'bool',
|
||||||
|
'e_invoice' => 'object',
|
||||||
];
|
];
|
||||||
|
|
||||||
public const STATUS_DRAFT = 1;
|
public const STATUS_DRAFT = 1;
|
||||||
|
@ -27,6 +27,7 @@ use Laracasts\Presenter\PresentableTrait;
|
|||||||
* App\Models\Quote
|
* App\Models\Quote
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
|
* @property object|null $e_invoice
|
||||||
* @property int $client_id
|
* @property int $client_id
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property int|null $assigned_user_id
|
* @property int|null $assigned_user_id
|
||||||
@ -174,6 +175,7 @@ class Quote extends BaseModel
|
|||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
'is_deleted' => 'boolean',
|
'is_deleted' => 'boolean',
|
||||||
'is_amount_discount' => 'bool',
|
'is_amount_discount' => 'bool',
|
||||||
|
'e_invoice' => 'object',
|
||||||
];
|
];
|
||||||
|
|
||||||
public const STATUS_DRAFT = 1;
|
public const STATUS_DRAFT = 1;
|
||||||
|
@ -152,6 +152,8 @@ class SystemLog extends Model
|
|||||||
|
|
||||||
public const TYPE_PAYPAL_PPCP = 323;
|
public const TYPE_PAYPAL_PPCP = 323;
|
||||||
|
|
||||||
|
public const TYPE_BTC_PAY = 324;
|
||||||
|
|
||||||
public const TYPE_QUOTA_EXCEEDED = 400;
|
public const TYPE_QUOTA_EXCEEDED = 400;
|
||||||
|
|
||||||
public const TYPE_UPSTREAM_FAILURE = 401;
|
public const TYPE_UPSTREAM_FAILURE = 401;
|
||||||
|
@ -67,7 +67,7 @@ class AuthorizePaymentDriver extends BaseDriver
|
|||||||
public function getClientRequiredFields(): array
|
public function getClientRequiredFields(): array
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
['name' => 'client_name', 'label' => ctrans('texts.name'), 'type' => 'text', 'validation' => 'required|min:2'],
|
// ['name' => 'client_name', 'label' => ctrans('texts.name'), 'type' => 'text', 'validation' => 'required|min:2'],
|
||||||
['name' => 'client_phone', 'label' => ctrans('texts.phone'), 'type' => 'text', 'validation' => 'required'],
|
['name' => 'client_phone', 'label' => ctrans('texts.phone'), 'type' => 'text', 'validation' => 'required'],
|
||||||
['name' => 'contact_email', 'label' => ctrans('texts.email'), 'type' => 'text', 'validation' => 'required|email:rfc'],
|
['name' => 'contact_email', 'label' => ctrans('texts.email'), 'type' => 'text', 'validation' => 'required|email:rfc'],
|
||||||
['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'],
|
['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'],
|
||||||
|
426
app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php
Normal file
426
app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\PaymentDrivers\PayPal;
|
||||||
|
|
||||||
|
use Str;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
use App\Models\GatewayType;
|
||||||
|
use App\Models\PaymentType;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Exceptions\PaymentFailed;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
|
use App\PaymentDrivers\BaseDriver;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use App\PaymentDrivers\PayPal\PayPalWebhook;
|
||||||
|
|
||||||
|
class PayPalBasePaymentDriver extends BaseDriver
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
public $token_billing = true;
|
||||||
|
|
||||||
|
public $can_authorise_credit_card = false;
|
||||||
|
|
||||||
|
public float $fee = 0;
|
||||||
|
|
||||||
|
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
||||||
|
|
||||||
|
public string $api_endpoint_url = '';
|
||||||
|
|
||||||
|
public string $paypal_payment_method = '';
|
||||||
|
|
||||||
|
public ?int $gateway_type_id = null;
|
||||||
|
|
||||||
|
public mixed $access_token = null;
|
||||||
|
|
||||||
|
public ?Carbon $token_expiry = null;
|
||||||
|
|
||||||
|
public array $funding_options = [
|
||||||
|
3 => 'paypal',
|
||||||
|
1 => 'card',
|
||||||
|
25 => 'venmo',
|
||||||
|
29 => 'paypal_advanced_cards',
|
||||||
|
// 9 => 'sepa',
|
||||||
|
// 12 => 'bancontact',
|
||||||
|
// 17 => 'eps',
|
||||||
|
// 15 => 'giropay',
|
||||||
|
// 13 => 'ideal',
|
||||||
|
// 26 => 'mercadopago',
|
||||||
|
// 27 => 'mybank',
|
||||||
|
28 => 'paylater',
|
||||||
|
// 16 => 'p24',
|
||||||
|
// 7 => 'sofort'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function gatewayTypes()
|
||||||
|
{
|
||||||
|
|
||||||
|
$funding_options =
|
||||||
|
|
||||||
|
collect($this->company_gateway->fees_and_limits)
|
||||||
|
->filter(function ($fee) {
|
||||||
|
return $fee->is_enabled;
|
||||||
|
})->map(function ($fee, $key) {
|
||||||
|
return (int)$key;
|
||||||
|
})->toArray();
|
||||||
|
|
||||||
|
/** Parse funding options and remove card option if advanced cards is enabled. */
|
||||||
|
if(in_array(1, $funding_options) && in_array(29, $funding_options)){
|
||||||
|
|
||||||
|
if (($key = array_search(1, $funding_options)) !== false)
|
||||||
|
unset($funding_options[$key]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $funding_options;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentMethod($gateway_type_id): int
|
||||||
|
{
|
||||||
|
$method = PaymentType::PAYPAL;
|
||||||
|
|
||||||
|
match($gateway_type_id) {
|
||||||
|
"1" => $method = PaymentType::CREDIT_CARD_OTHER,
|
||||||
|
"3" => $method = PaymentType::PAYPAL,
|
||||||
|
"25" => $method = PaymentType::VENMO,
|
||||||
|
"28" => $method = PaymentType::PAY_LATER,
|
||||||
|
"29" => $method = PaymentType::CREDIT_CARD_OTHER,
|
||||||
|
};
|
||||||
|
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
|
||||||
|
|
||||||
|
$secret = $this->company_gateway->getConfigField('secret');
|
||||||
|
$client_id = $this->company_gateway->getConfigField('clientId');
|
||||||
|
|
||||||
|
if($this->access_token && $this->token_expiry && $this->token_expiry->isFuture()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = Http::withBasicAuth($client_id, $secret)
|
||||||
|
->withHeaders(['Content-Type' => 'application/x-www-form-urlencoded'])
|
||||||
|
->withQueryParameters(['grant_type' => 'client_credentials'])
|
||||||
|
->post("{$this->api_endpoint_url}/v1/oauth2/token");
|
||||||
|
|
||||||
|
if($response->successful()) {
|
||||||
|
$this->access_token = $response->json()['access_token'];
|
||||||
|
$this->token_expiry = now()->addSeconds($response->json()['expires_in'] - 60);
|
||||||
|
} else {
|
||||||
|
throw new PaymentFailed('Unable to gain access token from Paypal. Check your configuration', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getFundingOptions
|
||||||
|
*
|
||||||
|
* Hosted fields requires this.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFundingOptions(): string
|
||||||
|
{
|
||||||
|
|
||||||
|
$enums = [
|
||||||
|
1 => 'card',
|
||||||
|
3 => 'paypal',
|
||||||
|
25 => 'venmo',
|
||||||
|
28 => 'paylater',
|
||||||
|
// 9 => 'sepa',
|
||||||
|
// 12 => 'bancontact',
|
||||||
|
// 17 => 'eps',
|
||||||
|
// 15 => 'giropay',
|
||||||
|
// 13 => 'ideal',
|
||||||
|
// 26 => 'mercadopago',
|
||||||
|
// 27 => 'mybank',
|
||||||
|
// 28 => 'paylater',
|
||||||
|
// 16 => 'p24',
|
||||||
|
// 7 => 'sofort'
|
||||||
|
];
|
||||||
|
|
||||||
|
$funding_options = '';
|
||||||
|
|
||||||
|
foreach($this->company_gateway->fees_and_limits as $key => $value) {
|
||||||
|
|
||||||
|
if($value->is_enabled) {
|
||||||
|
|
||||||
|
$funding_options .= $enums[$key].',';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtrim($funding_options, ',');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShippingAddress(): ?array
|
||||||
|
{
|
||||||
|
return $this->company_gateway->require_shipping_address ?
|
||||||
|
[
|
||||||
|
"address" =>
|
||||||
|
[
|
||||||
|
"address_line_1" => strlen($this->client->shipping_address1) > 1 ? $this->client->shipping_address1 : $this->client->address1,
|
||||||
|
"address_line_2" => $this->client->shipping_address2,
|
||||||
|
"admin_area_2" => strlen($this->client->shipping_city) > 1 ? $this->client->shipping_city : $this->client->city,
|
||||||
|
"admin_area_1" => strlen($this->client->shipping_state) > 1 ? $this->client->shipping_state : $this->client->state,
|
||||||
|
"postal_code" => strlen($this->client->shipping_postal_code) > 1 ? $this->client->shipping_postal_code : $this->client->postal_code,
|
||||||
|
"country_code" => $this->client->present()->shipping_country_code(),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
: [
|
||||||
|
"name" => [
|
||||||
|
"full_name" => $this->client->present()->name()
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBillingAddress(): array
|
||||||
|
{
|
||||||
|
return
|
||||||
|
[
|
||||||
|
"address_line_1" => $this->client->address1,
|
||||||
|
"address_line_2" => $this->client->address2,
|
||||||
|
"admin_area_2" => $this->client->city,
|
||||||
|
"admin_area_1" => $this->client->state,
|
||||||
|
"postal_code" => $this->client->postal_code,
|
||||||
|
"country_code" => $this->client->country->iso_3166_2,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentSource(): array
|
||||||
|
{
|
||||||
|
//@todo - roll back here for advanced payments vs hosted card fields.
|
||||||
|
if($this->gateway_type_id == GatewayType::PAYPAL_ADVANCED_CARDS) {
|
||||||
|
|
||||||
|
return [
|
||||||
|
"card" => [
|
||||||
|
"attributes" => [
|
||||||
|
"verification" => [
|
||||||
|
"method" => "SCA_WHEN_REQUIRED", //SCA_ALWAYS
|
||||||
|
// "method" => "SCA_ALWAYS", //SCA_ALWAYS
|
||||||
|
],
|
||||||
|
"vault" => [
|
||||||
|
"store_in_vault" => "ON_SUCCESS", //must listen to this webhook - VAULT.PAYMENT-TOKEN.CREATED webhook.
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"experience_context" => [
|
||||||
|
"shipping_preference" => "SET_PROVIDED_ADDRESS"
|
||||||
|
],
|
||||||
|
"stored_credential" => [
|
||||||
|
// "payment_initiator" => "MERCHANT", //"CUSTOMER" who initiated the transaction?
|
||||||
|
"payment_initiator" => "CUSTOMER", //"" who initiated the transaction?
|
||||||
|
"payment_type" => "UNSCHEDULED", //UNSCHEDULED
|
||||||
|
"usage"=> "DERIVED",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = [
|
||||||
|
"paypal" => [
|
||||||
|
"name" => [
|
||||||
|
"given_name" => $this->client->present()->first_name(),
|
||||||
|
"surname" => $this->client->present()->last_name(),
|
||||||
|
],
|
||||||
|
"email_address" => $this->client->present()->email(),
|
||||||
|
"experience_context" => [
|
||||||
|
"user_action" => "PAY_NOW"
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/** If we have a complete address, add it to the order, otherwise leave it blank! */
|
||||||
|
if(
|
||||||
|
strlen($this->client->shipping_address1 ?? '') > 2 &&
|
||||||
|
strlen($this->client->shipping_city ?? '') > 2 &&
|
||||||
|
strlen($this->client->shipping_state ?? '') >= 2 &&
|
||||||
|
strlen($this->client->shipping_postal_code ?? '') > 2 &&
|
||||||
|
strlen($this->client->shipping_country->iso_3166_2 ?? '') >= 2
|
||||||
|
) {
|
||||||
|
$order['paypal']['address'] = [
|
||||||
|
"address_line_1" => $this->client->shipping_address1,
|
||||||
|
"address_line_2" => $this->client->shipping_address2,
|
||||||
|
"admin_area_2" => $this->client->shipping_city,
|
||||||
|
"admin_area_1" => $this->client->shipping_state,
|
||||||
|
"postal_code" => $this->client->shipping_postal_code,
|
||||||
|
"country_code" => $this->client->present()->shipping_country_code(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
elseif(
|
||||||
|
strlen($this->client->address1 ?? '') > 2 &&
|
||||||
|
strlen($this->client->city ?? '') > 2 &&
|
||||||
|
strlen($this->client->state ?? '') >= 2 &&
|
||||||
|
strlen($this->client->postal_code ?? '') > 2 &&
|
||||||
|
strlen($this->client->country->iso_3166_2 ?? '') >= 2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$order['paypal']['address'] = [
|
||||||
|
"address_line_1" => $this->client->address1,
|
||||||
|
"address_line_2" => $this->client->address2,
|
||||||
|
"admin_area_2" => $this->client->city,
|
||||||
|
"admin_area_1" => $this->client->state,
|
||||||
|
"postal_code" => $this->client->postal_code,
|
||||||
|
"country_code" => $this->client->country->iso_3166_2,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment method setter
|
||||||
|
*
|
||||||
|
* @param mixed $payment_method_id
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setPaymentMethod($payment_method_id): self
|
||||||
|
{
|
||||||
|
if(!$payment_method_id) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->gateway_type_id = $payment_method_id;
|
||||||
|
|
||||||
|
$this->paypal_payment_method = $this->funding_options[$payment_method_id];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authorizeView($payment_method)
|
||||||
|
{
|
||||||
|
// PayPal doesn't support direct authorization.
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authorizeResponse($request)
|
||||||
|
{
|
||||||
|
// PayPal doesn't support direct authorization.
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the gateway request
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* @param string $verb
|
||||||
|
* @param array $data
|
||||||
|
* @param ?array $headers
|
||||||
|
* @return \Illuminate\Http\Client\Response
|
||||||
|
*/
|
||||||
|
public function gatewayRequest(string $uri, string $verb, array $data, ?array $headers = [])
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
$r = Http::withToken($this->access_token)
|
||||||
|
->withHeaders($this->getHeaders($headers))
|
||||||
|
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
||||||
|
|
||||||
|
if($r->successful()) {
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
['response' => $r->body()],
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
|
SystemLog::TYPE_PAYPAL,
|
||||||
|
$this->client,
|
||||||
|
$this->client->company ?? $this->company_gateway->company,
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the request headers
|
||||||
|
*
|
||||||
|
* @param array $headers
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getHeaders(array $headers = []): array
|
||||||
|
{
|
||||||
|
return array_merge([
|
||||||
|
'Accept' => 'application/json',
|
||||||
|
'Content-type' => 'application/json',
|
||||||
|
'Accept-Language' => 'en_US',
|
||||||
|
'PayPal-Partner-Attribution-Id' => 'invoiceninja_SP_PPCP',
|
||||||
|
'PayPal-Request-Id' => Str::uuid()->toString(),
|
||||||
|
], $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a client token for the payment form.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getClientToken(): string
|
||||||
|
{
|
||||||
|
|
||||||
|
$r = $this->gatewayRequest('/v1/identity/generate-token', 'post', ['body' => '']);
|
||||||
|
|
||||||
|
if($r->successful()) {
|
||||||
|
return $r->json()['client_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new PaymentFailed('Unable to gain client token from Paypal. Check your configuration', 401);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function auth(): bool
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->init()->getClientToken();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(\Exception $e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importCustomers()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processWebhookRequest(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
PayPalWebhook::dispatch($request->all(), $request->headers->all(), $this->access_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -21,188 +21,34 @@ use Illuminate\Http\Request;
|
|||||||
use App\Jobs\Util\SystemLogger;
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Exceptions\PaymentFailed;
|
use App\Exceptions\PaymentFailed;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use App\PaymentDrivers\PayPal\PayPalWebhook;
|
use App\PaymentDrivers\PayPal\PayPalWebhook;
|
||||||
|
use App\PaymentDrivers\PayPal\PayPalBasePaymentDriver;
|
||||||
|
|
||||||
class PayPalPPCPPaymentDriver extends BaseDriver
|
class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
|
||||||
public $token_billing = false;
|
///v1/customer/partners/merchant-accounts/{merchant_id}/capabilities - test if advanced cards is available.
|
||||||
|
// {
|
||||||
public $can_authorise_credit_card = false;
|
// "capabilities": [
|
||||||
|
// {
|
||||||
private $omnipay_gateway;
|
// "name": "ADVANCED_CARD_PAYMENTS",
|
||||||
|
// "status": "ENABLED"
|
||||||
private float $fee = 0;
|
// },
|
||||||
|
// {
|
||||||
|
// "name": "VAULTING",
|
||||||
|
// "status": "ENABLED"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL_PPCP;
|
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL_PPCP;
|
||||||
|
|
||||||
private string $api_endpoint_url = '';
|
|
||||||
|
|
||||||
private string $paypal_payment_method = '';
|
|
||||||
|
|
||||||
private ?int $gateway_type_id = null;
|
|
||||||
|
|
||||||
protected mixed $access_token = null;
|
|
||||||
|
|
||||||
protected ?Carbon $token_expiry = null;
|
|
||||||
|
|
||||||
private array $funding_options = [
|
|
||||||
3 => 'paypal',
|
|
||||||
1 => 'card',
|
|
||||||
25 => 'venmo',
|
|
||||||
// 9 => 'sepa',
|
|
||||||
// 12 => 'bancontact',
|
|
||||||
// 17 => 'eps',
|
|
||||||
// 15 => 'giropay',
|
|
||||||
// 13 => 'ideal',
|
|
||||||
// 26 => 'mercadopago',
|
|
||||||
// 27 => 'mybank',
|
|
||||||
28 => 'paylater',
|
|
||||||
// 16 => 'p24',
|
|
||||||
// 7 => 'sofort'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of
|
* Checks whether payments are enabled on the merchant account
|
||||||
* enabled gateway payment methods
|
*
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function gatewayTypes(): array
|
|
||||||
{
|
|
||||||
|
|
||||||
return collect($this->company_gateway->fees_and_limits)
|
|
||||||
->filter(function ($fee) {
|
|
||||||
return $fee->is_enabled;
|
|
||||||
})->map(function ($fee, $key) {
|
|
||||||
return (int)$key;
|
|
||||||
})->toArray();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPaymentMethod($gateway_type_id): int
|
|
||||||
{
|
|
||||||
$method = PaymentType::PAYPAL;
|
|
||||||
|
|
||||||
match($gateway_type_id) {
|
|
||||||
"1" => $method = PaymentType::CREDIT_CARD_OTHER,
|
|
||||||
"3" => $method = PaymentType::PAYPAL,
|
|
||||||
"25" => $method = PaymentType::VENMO,
|
|
||||||
"28" => $method = PaymentType::PAY_LATER,
|
|
||||||
};
|
|
||||||
|
|
||||||
return $method;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getFundingOptions(): string
|
|
||||||
{
|
|
||||||
|
|
||||||
$enums = [
|
|
||||||
1 => 'card',
|
|
||||||
3 => 'paypal',
|
|
||||||
25 => 'venmo',
|
|
||||||
28 => 'paylater',
|
|
||||||
// 9 => 'sepa',
|
|
||||||
// 12 => 'bancontact',
|
|
||||||
// 17 => 'eps',
|
|
||||||
// 15 => 'giropay',
|
|
||||||
// 13 => 'ideal',
|
|
||||||
// 26 => 'mercadopago',
|
|
||||||
// 27 => 'mybank',
|
|
||||||
// 28 => 'paylater',
|
|
||||||
// 16 => 'p24',
|
|
||||||
// 7 => 'sofort'
|
|
||||||
];
|
|
||||||
|
|
||||||
$funding_options = '';
|
|
||||||
|
|
||||||
foreach($this->company_gateway->fees_and_limits as $key => $value) {
|
|
||||||
|
|
||||||
if($value->is_enabled) {
|
|
||||||
|
|
||||||
$funding_options .= $enums[$key].',';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtrim($funding_options, ',');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the Paypal gateway.
|
|
||||||
*
|
|
||||||
* Attempt to generate and return the access token.
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public function init(): self
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->api_endpoint_url = 'https://api-m.paypal.com';
|
|
||||||
// $this->api_endpoint_url = 'https://api-m.sandbox.paypal.com';
|
|
||||||
$secret = config('ninja.paypal.secret');
|
|
||||||
$client_id = config('ninja.paypal.client_id');
|
|
||||||
|
|
||||||
if($this->access_token && $this->token_expiry && $this->token_expiry->isFuture()) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = Http::withBasicAuth($client_id, $secret)
|
|
||||||
->withHeaders(['Content-Type' => 'application/x-www-form-urlencoded'])
|
|
||||||
->withQueryParameters(['grant_type' => 'client_credentials'])
|
|
||||||
->post("{$this->api_endpoint_url}/v1/oauth2/token");
|
|
||||||
|
|
||||||
if($response->successful()) {
|
|
||||||
$this->access_token = $response->json()['access_token'];
|
|
||||||
$this->token_expiry = now()->addSeconds($response->json()['expires_in'] - 60);
|
|
||||||
} else {
|
|
||||||
throw new PaymentFailed('Unable to gain access token from Paypal. Check your configuration', 401);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Payment method setter
|
|
||||||
*
|
|
||||||
* @param mixed $payment_method_id
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public function setPaymentMethod($payment_method_id): self
|
|
||||||
{
|
|
||||||
if(!$payment_method_id) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->gateway_type_id = $payment_method_id;
|
|
||||||
|
|
||||||
$this->paypal_payment_method = $this->funding_options[$payment_method_id];
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function authorizeView($payment_method)
|
|
||||||
{
|
|
||||||
// PayPal doesn't support direct authorization.
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function authorizeResponse($request)
|
|
||||||
{
|
|
||||||
// PayPal doesn't support direct authorization.
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether payments are enabled on the account
|
|
||||||
*
|
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
private function checkPaymentsReceivable(): self
|
private function checkPaymentsReceivable(): self
|
||||||
@ -252,7 +98,10 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
$data['merchantId'] = $this->company_gateway->getConfigField('merchantId');
|
$data['merchantId'] = $this->company_gateway->getConfigField('merchantId');
|
||||||
$data['currency'] = $this->client->currency()->code;
|
$data['currency'] = $this->client->currency()->code;
|
||||||
|
|
||||||
return render('gateways.paypal.ppcp.pay', $data);
|
if($this->gateway_type_id == 29)
|
||||||
|
return render('gateways.paypal.ppcp.card', $data);
|
||||||
|
else
|
||||||
|
return render('gateways.paypal.ppcp.pay', $data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +117,10 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
|
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
|
||||||
$response = json_decode($request['gateway_response'], true);
|
$response = json_decode($request['gateway_response'], true);
|
||||||
|
|
||||||
|
if($request->has('token') && strlen($request->input('token')) > 2) {
|
||||||
|
return $this->processTokenPayment($request, $response);
|
||||||
|
}
|
||||||
|
|
||||||
//capture
|
//capture
|
||||||
$orderID = $response['orderID'];
|
$orderID = $response['orderID'];
|
||||||
|
|
||||||
@ -335,7 +188,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
['response' => $response, 'data' => $data],
|
['response' => $response, 'data' => $data],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
SystemLog::TYPE_PAYPAL,
|
SystemLog::TYPE_PAYPAL_PPCP,
|
||||||
$this->client,
|
$this->client,
|
||||||
$this->client->company,
|
$this->client->company,
|
||||||
);
|
);
|
||||||
@ -352,7 +205,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
['response' => $response],
|
['response' => $response],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
SystemLog::TYPE_PAYPAL,
|
SystemLog::TYPE_PAYPAL_PPCP,
|
||||||
$this->client,
|
$this->client,
|
||||||
$this->client->company,
|
$this->client->company,
|
||||||
);
|
);
|
||||||
@ -372,74 +225,13 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
return $r->json();
|
return $r->json();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a client token for the payment form.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getClientToken(): string
|
|
||||||
{
|
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v1/identity/generate-token', 'post', ['body' => '']);
|
|
||||||
|
|
||||||
if($r->successful()) {
|
|
||||||
return $r->json()['client_token'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new PaymentFailed('Unable to gain client token from Paypal. Check your configuration', 401);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the payment request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function paymentSource(): array
|
|
||||||
{
|
|
||||||
/** we only need to support paypal as payment source until as we are only using hosted payment buttons */
|
|
||||||
return $this->injectPayPalPaymentSource();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function injectPayPalPaymentSource(): array
|
|
||||||
{
|
|
||||||
|
|
||||||
$order = [
|
|
||||||
"paypal" => [
|
|
||||||
"name" => [
|
|
||||||
"given_name" => $this->client->present()->first_name(),
|
|
||||||
"surname" => $this->client->present()->last_name(),
|
|
||||||
],
|
|
||||||
"email_address" => $this->client->present()->email(),
|
|
||||||
"experience_context" => [
|
|
||||||
"user_action" => "PAY_NOW"
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
if(
|
|
||||||
strlen($this->client->address1 ?? '') > 2 &&
|
|
||||||
strlen($this->client->city ?? '') > 2 &&
|
|
||||||
strlen($this->client->state ?? '') >= 2 &&
|
|
||||||
strlen($this->client->postal_code ?? '') > 2 &&
|
|
||||||
strlen($this->client->country->iso_3166_2 ?? '') >= 2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$order["paypal"]["address"] = $this->getBillingAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the PayPal Order object
|
* Creates the PayPal Order object
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function createOrder(array $data): string
|
public function createOrder(array $data): string
|
||||||
{
|
{
|
||||||
|
|
||||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||||
@ -453,7 +245,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
$order = [
|
$order = [
|
||||||
|
|
||||||
"intent" => "CAPTURE",
|
"intent" => "CAPTURE",
|
||||||
"payment_source" => $this->paymentSource(),
|
"payment_source" => $this->getPaymentSource(),
|
||||||
"purchase_units" => [
|
"purchase_units" => [
|
||||||
[
|
[
|
||||||
"custom_id" => $this->payment_hash->hash,
|
"custom_id" => $this->payment_hash->hash,
|
||||||
@ -465,7 +257,6 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
"payment_instruction" => [
|
"payment_instruction" => [
|
||||||
"disbursement_mode" => "INSTANT",
|
"disbursement_mode" => "INSTANT",
|
||||||
],
|
],
|
||||||
$this->getShippingAddress(),
|
|
||||||
"amount" => [
|
"amount" => [
|
||||||
"value" => (string)$data['amount_with_fee'],
|
"value" => (string)$data['amount_with_fee'],
|
||||||
"currency_code" => $this->client->currency()->code,
|
"currency_code" => $this->client->currency()->code,
|
||||||
@ -496,125 +287,76 @@ class PayPalPPCPPaymentDriver extends BaseDriver
|
|||||||
$order['purchase_units'][0]["shipping"] = $shipping;
|
$order['purchase_units'][0]["shipping"] = $shipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isset($data['payment_source'])) {
|
||||||
|
$order['payment_source'] = $data['payment_source'];
|
||||||
|
}
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
||||||
|
|
||||||
return $r->json()['id'];
|
return $r->json()['id'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getBillingAddress(): array
|
|
||||||
{
|
|
||||||
return
|
|
||||||
[
|
|
||||||
"address_line_1" => $this->client->address1,
|
|
||||||
"address_line_2" => $this->client->address2,
|
|
||||||
"admin_area_2" => $this->client->city,
|
|
||||||
"admin_area_1" => $this->client->state,
|
|
||||||
"postal_code" => $this->client->postal_code,
|
|
||||||
"country_code" => $this->client->country->iso_3166_2,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getShippingAddress(): ?array
|
|
||||||
{
|
|
||||||
return $this->company_gateway->require_shipping_address ?
|
|
||||||
[
|
|
||||||
"address" =>
|
|
||||||
[
|
|
||||||
"address_line_1" => strlen($this->client->shipping_address1 ?? '') > 1 ? $this->client->shipping_address1 : $this->client->address1,
|
|
||||||
"address_line_2" => $this->client->shipping_address2,
|
|
||||||
"admin_area_2" => strlen($this->client->shipping_city ?? '') > 1 ? $this->client->shipping_city : $this->client->city,
|
|
||||||
"admin_area_1" => strlen($this->client->shipping_state ?? '') > 1 ? $this->client->shipping_state : $this->client->state,
|
|
||||||
"postal_code" => strlen($this->client->shipping_postal_code ?? '') > 1 ? $this->client->shipping_postal_code : $this->client->postal_code,
|
|
||||||
"country_code" => $this->client->present()->shipping_country_code(),
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
: null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the gateway request
|
* processTokenPayment
|
||||||
*
|
*
|
||||||
* @param string $uri
|
* With PayPal and token payments, the order needs to be
|
||||||
* @param string $verb
|
* deleted and then created with the payment source that
|
||||||
* @param array $data
|
* has been selected by the client.
|
||||||
* @param ?array $headers
|
*
|
||||||
* @return \Illuminate\Http\Client\Response
|
* This method handle the deletion of the current paypal order,
|
||||||
|
* and the automatic payment of the order with the selected payment source.
|
||||||
|
*
|
||||||
|
* @param mixed $request
|
||||||
|
* @param array $response
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function gatewayRequest(string $uri, string $verb, array $data, ?array $headers = [])
|
public function processTokenPayment($request, array $response) {
|
||||||
{
|
|
||||||
$this->init();
|
|
||||||
|
|
||||||
$r = Http::withToken($this->access_token)
|
$cgt = ClientGatewayToken::where('client_id', $this->client->id)
|
||||||
->withHeaders($this->getHeaders($headers))
|
->where('token', $request['token'])
|
||||||
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
->firstOrFail();
|
||||||
|
|
||||||
if($r->successful()) {
|
$orderId = $response['orderID'];
|
||||||
return $r;
|
$r = $this->gatewayRequest("/v1/checkout/orders/{$orderId}/", 'delete', ['body' => '']);
|
||||||
}
|
|
||||||
|
$data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee;
|
||||||
|
$data["payment_source"] = [
|
||||||
|
"card" => [
|
||||||
|
"vault_id" => $cgt->token,
|
||||||
|
"stored_credential" => [
|
||||||
|
"payment_initiator" => "MERCHANT",
|
||||||
|
"payment_type" => "UNSCHEDULED",
|
||||||
|
"usage" => "SUBSEQUENT",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$orderId = $this->createOrder($data);
|
||||||
|
|
||||||
|
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderId}", 'get', ['body' => '']);
|
||||||
|
|
||||||
|
$response = $r->json();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'payment_type' => $this->getPaymentMethod($request->gateway_type_id),
|
||||||
|
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
||||||
|
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
||||||
|
'gateway_type_id' => $this->gateway_type_id,
|
||||||
|
];
|
||||||
|
|
||||||
|
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
['response' => $r->body()],
|
['response' => $response, 'data' => $data],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
SystemLog::TYPE_PAYPAL,
|
SystemLog::TYPE_PAYPAL_PPCP,
|
||||||
$this->client,
|
$this->client,
|
||||||
$this->client->company,
|
$this->client->company,
|
||||||
);
|
);
|
||||||
|
|
||||||
throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
|
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Generates the request headers
|
|
||||||
*
|
|
||||||
* @param array $headers
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getHeaders(array $headers = []): array
|
|
||||||
{
|
|
||||||
return array_merge([
|
|
||||||
'Accept' => 'application/json',
|
|
||||||
'Content-type' => 'application/json',
|
|
||||||
'Accept-Language' => 'en_US',
|
|
||||||
'PayPal-Partner-Attribution-Id' => 'invoiceninja_SP_PPCP',
|
|
||||||
'PayPal-Request-Id' => Str::uuid()->toString(),
|
|
||||||
], $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processWebhookRequest(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
// nlog(json_encode($request->all()));
|
|
||||||
$this->init();
|
|
||||||
|
|
||||||
PayPalWebhook::dispatch($request->all(), $request->headers->all(), $this->access_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function auth(): bool
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->init()->getClientToken();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch(\Exception $e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function importCustomers()
|
|
||||||
{
|
|
||||||
|
|
||||||
// $response = $this->gatewayRequest('/v1/reporting/transactions', 'get', ['fields' => 'all','page_size' => 500,'start_date' => '2024-02-01T00:00:00-0000', 'end_date' => '2024-03-01T00:00:00-0000']);
|
|
||||||
|
|
||||||
// nlog($response->json());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,147 +12,22 @@
|
|||||||
|
|
||||||
namespace App\PaymentDrivers;
|
namespace App\PaymentDrivers;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Omnipay\Omnipay;
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Models\GatewayType;
|
use App\Models\GatewayType;
|
||||||
use App\Models\PaymentType;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use App\Jobs\Util\SystemLogger;
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Exceptions\PaymentFailed;
|
use App\Exceptions\PaymentFailed;
|
||||||
use App\Models\ClientGatewayToken;
|
use App\Models\ClientGatewayToken;
|
||||||
use Illuminate\Support\Facades\Http;
|
use App\PaymentDrivers\PayPal\PayPalBasePaymentDriver;
|
||||||
|
|
||||||
class PayPalRestPaymentDriver extends BaseDriver
|
class PayPalRestPaymentDriver extends PayPalBasePaymentDriver
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
|
||||||
public $token_billing = false;
|
|
||||||
|
|
||||||
public $can_authorise_credit_card = false;
|
|
||||||
|
|
||||||
private $omnipay_gateway;
|
|
||||||
|
|
||||||
private float $fee = 0;
|
|
||||||
|
|
||||||
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
public const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
|
||||||
|
|
||||||
private string $api_endpoint_url = '';
|
|
||||||
|
|
||||||
private string $paypal_payment_method = '';
|
|
||||||
|
|
||||||
private ?int $gateway_type_id = null;
|
|
||||||
|
|
||||||
protected mixed $access_token = null;
|
|
||||||
|
|
||||||
protected ?Carbon $token_expiry = null;
|
|
||||||
|
|
||||||
private array $funding_options = [
|
|
||||||
3 => 'paypal',
|
|
||||||
1 => 'card',
|
|
||||||
25 => 'venmo',
|
|
||||||
29 => 'paypal_advanced_cards',
|
|
||||||
// 9 => 'sepa',
|
|
||||||
// 12 => 'bancontact',
|
|
||||||
// 17 => 'eps',
|
|
||||||
// 15 => 'giropay',
|
|
||||||
// 13 => 'ideal',
|
|
||||||
// 26 => 'mercadopago',
|
|
||||||
// 27 => 'mybank',
|
|
||||||
28 => 'paylater',
|
|
||||||
// 16 => 'p24',
|
|
||||||
// 7 => 'sofort'
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
public function gatewayTypes()
|
|
||||||
{
|
|
||||||
|
|
||||||
$funding_options = [];
|
|
||||||
|
|
||||||
foreach ($this->company_gateway->fees_and_limits as $key => $value) {
|
|
||||||
if ($value->is_enabled) {
|
|
||||||
$funding_options[] = $key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $funding_options;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
|
|
||||||
|
|
||||||
$secret = $this->company_gateway->getConfigField('secret');
|
|
||||||
$client_id = $this->company_gateway->getConfigField('clientId');
|
|
||||||
|
|
||||||
if($this->access_token && $this->token_expiry && $this->token_expiry->isFuture()) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = Http::withBasicAuth($client_id, $secret)
|
|
||||||
->withHeaders(['Content-Type' => 'application/x-www-form-urlencoded'])
|
|
||||||
->withQueryParameters(['grant_type' => 'client_credentials'])
|
|
||||||
->post("{$this->api_endpoint_url}/v1/oauth2/token");
|
|
||||||
|
|
||||||
if($response->successful()) {
|
|
||||||
$this->access_token = $response->json()['access_token'];
|
|
||||||
$this->token_expiry = now()->addSeconds($response->json()['expires_in'] - 60);
|
|
||||||
} else {
|
|
||||||
throw new PaymentFailed('Unable to gain access token from Paypal. Check your configuration', 401);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPaymentMethod($gateway_type_id): int
|
|
||||||
{
|
|
||||||
$method = PaymentType::PAYPAL;
|
|
||||||
|
|
||||||
match($gateway_type_id) {
|
|
||||||
"1" => $method = PaymentType::CREDIT_CARD_OTHER,
|
|
||||||
"3" => $method = PaymentType::PAYPAL,
|
|
||||||
"25" => $method = PaymentType::VENMO,
|
|
||||||
"28" => $method = PaymentType::PAY_LATER,
|
|
||||||
"29" => $method = PaymentType::CREDIT_CARD_OTHER,
|
|
||||||
};
|
|
||||||
|
|
||||||
return $method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPaymentMethod($payment_method_id): self
|
|
||||||
{
|
|
||||||
if(!$payment_method_id) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->gateway_type_id = $payment_method_id;
|
|
||||||
|
|
||||||
$this->paypal_payment_method = $this->funding_options[$payment_method_id];
|
|
||||||
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function authorizeView($payment_method)
|
|
||||||
{
|
|
||||||
// PayPal doesn't support direct authorization.
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function authorizeResponse($request)
|
|
||||||
{
|
|
||||||
// PayPal doesn't support direct authorization.
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processPaymentView($data)
|
public function processPaymentView($data)
|
||||||
{
|
{
|
||||||
$this->init();
|
$this->init();
|
||||||
@ -169,110 +44,20 @@ class PayPalRestPaymentDriver extends BaseDriver
|
|||||||
$data['gateway_type_id'] = $this->gateway_type_id;
|
$data['gateway_type_id'] = $this->gateway_type_id;
|
||||||
$data['currency'] = $this->client->currency()->code;
|
$data['currency'] = $this->client->currency()->code;
|
||||||
|
|
||||||
|
if($this->gateway_type_id == 29)
|
||||||
// return render('gateways.paypal.ppcp.card', $data);
|
return render('gateways.paypal.ppcp.card', $data);
|
||||||
|
else
|
||||||
return render('gateways.paypal.pay', $data);
|
return render('gateways.paypal.pay', $data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFundingOptions(): string
|
|
||||||
{
|
/**
|
||||||
|
* processPaymentResponse
|
||||||
$enums = [
|
*
|
||||||
3 => 'paypal',
|
* @param mixed $request
|
||||||
1 => 'card',
|
* @return void
|
||||||
25 => 'venmo',
|
*/
|
||||||
// 9 => 'sepa',
|
|
||||||
// 12 => 'bancontact',
|
|
||||||
// 17 => 'eps',
|
|
||||||
// 15 => 'giropay',
|
|
||||||
// 13 => 'ideal',
|
|
||||||
// 26 => 'mercadopago',
|
|
||||||
// 27 => 'mybank',
|
|
||||||
// 28 => 'paylater',
|
|
||||||
// 16 => 'p24',
|
|
||||||
// 7 => 'sofort'
|
|
||||||
];
|
|
||||||
|
|
||||||
$funding_options = '';
|
|
||||||
|
|
||||||
foreach($this->company_gateway->fees_and_limits as $key => $value) {
|
|
||||||
|
|
||||||
if($value->is_enabled) {
|
|
||||||
|
|
||||||
$funding_options .= $enums[$key].',';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtrim($funding_options, ',');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processTokenPayment($request, array $response) {
|
|
||||||
|
|
||||||
$cgt = ClientGatewayToken::where('client_id', $this->client->id)
|
|
||||||
->where('token', $request['token'])
|
|
||||||
->firstOrFail();
|
|
||||||
nlog("process token");
|
|
||||||
|
|
||||||
nlog($request->all());
|
|
||||||
nlog($response);
|
|
||||||
|
|
||||||
$orderId = $response['orderID'];
|
|
||||||
$r = $this->gatewayRequest("/v1/checkout/orders/{$orderId}/", 'delete', ['body' => '']);
|
|
||||||
|
|
||||||
nlog($r);
|
|
||||||
|
|
||||||
$data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee;
|
|
||||||
$data["payment_source"] = [
|
|
||||||
"card" => [
|
|
||||||
"vault_id" => $cgt->token,
|
|
||||||
"stored_credential" => [
|
|
||||||
"payment_initiator" => "MERCHANT",
|
|
||||||
"payment_type" => "UNSCHEDULED",
|
|
||||||
"usage" => "SUBSEQUENT",
|
|
||||||
// "previous_transaction_reference" => $cgt->gateway_customer_reference,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$orderId = $this->createOrder($data);
|
|
||||||
|
|
||||||
nlog("post order creation");
|
|
||||||
nlog($orderId);
|
|
||||||
|
|
||||||
|
|
||||||
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderId}", 'get', ['body' => '']);
|
|
||||||
nlog($r);
|
|
||||||
|
|
||||||
$response = $r->json();
|
|
||||||
nlog($response);
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'payment_type' => $this->getPaymentMethod($request->gateway_type_id),
|
|
||||||
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
|
||||||
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
|
||||||
'gateway_type_id' => $this->gateway_type_id,
|
|
||||||
];
|
|
||||||
|
|
||||||
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
|
||||||
['response' => $response, 'data' => $data],
|
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
|
||||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
|
||||||
SystemLog::TYPE_PAYPAL,
|
|
||||||
$this->client,
|
|
||||||
$this->client->company,
|
|
||||||
);
|
|
||||||
|
|
||||||
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processPaymentResponse($request)
|
public function processPaymentResponse($request)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -280,12 +65,10 @@ return render('gateways.paypal.pay', $data);
|
|||||||
|
|
||||||
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
|
$request['gateway_response'] = str_replace("Error: ", "", $request['gateway_response']);
|
||||||
$response = json_decode($request['gateway_response'], true);
|
$response = json_decode($request['gateway_response'], true);
|
||||||
nlog($request->all());
|
|
||||||
|
|
||||||
if($request->has('token') && strlen($request->input('token')) > 2)
|
if($request->has('token') && strlen($request->input('token')) > 2)
|
||||||
return $this->processTokenPayment($request, $response);
|
return $this->processTokenPayment($request, $response);
|
||||||
|
|
||||||
// nlog($response);
|
|
||||||
//capture
|
//capture
|
||||||
$orderID = $response['orderID'];
|
$orderID = $response['orderID'];
|
||||||
|
|
||||||
@ -339,6 +122,9 @@ return render('gateways.paypal.pay', $data);
|
|||||||
|
|
||||||
$response = $r;
|
$response = $r;
|
||||||
|
|
||||||
|
nlog("Process response =>");
|
||||||
|
nlog($response->json());
|
||||||
|
|
||||||
if(isset($response['status']) && $response['status'] == 'COMPLETED' && isset($response['purchase_units'])) {
|
if(isset($response['status']) && $response['status'] == 'COMPLETED' && isset($response['purchase_units'])) {
|
||||||
|
|
||||||
return $this->createNinjaPayment($request, $response);
|
return $this->createNinjaPayment($request, $response);
|
||||||
@ -367,8 +153,6 @@ return render('gateways.paypal.pay', $data);
|
|||||||
|
|
||||||
private function createNinjaPayment($request, $response) {
|
private function createNinjaPayment($request, $response) {
|
||||||
|
|
||||||
nlog($response->json());
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'payment_type' => $this->getPaymentMethod($request->gateway_type_id),
|
'payment_type' => $this->getPaymentMethod($request->gateway_type_id),
|
||||||
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
||||||
@ -401,7 +185,6 @@ return render('gateways.paypal.pay', $data);
|
|||||||
$data['token'] = $token;
|
$data['token'] = $token;
|
||||||
$data['payment_method_id'] = GatewayType::PAYPAL_ADVANCED_CARDS;
|
$data['payment_method_id'] = GatewayType::PAYPAL_ADVANCED_CARDS;
|
||||||
$data['payment_meta'] = $payment_meta;
|
$data['payment_meta'] = $payment_meta;
|
||||||
// $data['payment_method_id'] = GatewayType::CREDIT_CARD;
|
|
||||||
|
|
||||||
$additional['gateway_customer_reference'] = $gateway_customer_reference;
|
$additional['gateway_customer_reference'] = $gateway_customer_reference;
|
||||||
|
|
||||||
@ -423,116 +206,7 @@ return render('gateways.paypal.pay', $data);
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getClientToken(): string
|
public function createOrder(array $data): string
|
||||||
{
|
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v1/identity/generate-token', 'post', ['body' => '']);
|
|
||||||
|
|
||||||
if($r->successful()) {
|
|
||||||
return $r->json()['client_token'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new PaymentFailed('Unable to gain client token from Paypal. Check your configuration', 401);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPaymentSource(): array
|
|
||||||
{
|
|
||||||
//@todo - roll back here for advanced payments vs hosted card fields.
|
|
||||||
if($this->gateway_type_id == GatewayType::PAYPAL_ADVANCED_CARDS) {
|
|
||||||
|
|
||||||
return [
|
|
||||||
"card" => [
|
|
||||||
"attributes" => [
|
|
||||||
"verification" => [
|
|
||||||
"method" => "SCA_WHEN_REQUIRED", //SCA_ALWAYS
|
|
||||||
// "method" => "SCA_ALWAYS", //SCA_ALWAYS
|
|
||||||
],
|
|
||||||
"vault" => [
|
|
||||||
"store_in_vault" => "ON_SUCCESS", //must listen to this webhook - VAULT.PAYMENT-TOKEN.CREATED webhook.
|
|
||||||
],
|
|
||||||
],
|
|
||||||
"experience_context" => [
|
|
||||||
"shipping_preference" => "SET_PROVIDED_ADDRESS"
|
|
||||||
],
|
|
||||||
// "name" => $this->client->present()->primary_contact_name(),
|
|
||||||
// "email_address" => $this->client->present()->email(),
|
|
||||||
// "address" => [
|
|
||||||
// "address_line_1" => $this->client->address1,
|
|
||||||
// "address_line_2" => $this->client->address2,
|
|
||||||
// "admin_area_2" => $this->client->city,
|
|
||||||
// "admin_area_1" => $this->client->state,
|
|
||||||
// "postal_code" => $this->client->postal_code,
|
|
||||||
// "country_code" => $this->client->country->iso_3166_2,
|
|
||||||
// ],
|
|
||||||
// "experience_context" => [
|
|
||||||
// "user_action" => "PAY_NOW"
|
|
||||||
// ],
|
|
||||||
"stored_credential" => [
|
|
||||||
// "payment_initiator" => "MERCHANT", //"CUSTOMER" who initiated the transaction?
|
|
||||||
"payment_initiator" => "CUSTOMER", //"" who initiated the transaction?
|
|
||||||
"payment_type" => "UNSCHEDULED", //UNSCHEDULED
|
|
||||||
"usage"=> "DERIVED",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$order = [
|
|
||||||
"paypal" => [
|
|
||||||
"name" => [
|
|
||||||
"given_name" => $this->client->present()->first_name(),
|
|
||||||
"surname" => $this->client->present()->last_name(),
|
|
||||||
],
|
|
||||||
"email_address" => $this->client->present()->email(),
|
|
||||||
"experience_context" => [
|
|
||||||
"user_action" => "PAY_NOW"
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
/** If we have a complete address, add it to the order, otherwise leave it blank! */
|
|
||||||
if(
|
|
||||||
strlen($this->client->shipping_address1 ?? '') > 2 &&
|
|
||||||
strlen($this->client->shipping_city ?? '') > 2 &&
|
|
||||||
strlen($this->client->shipping_state ?? '') >= 2 &&
|
|
||||||
strlen($this->client->shipping_postal_code ?? '') > 2 &&
|
|
||||||
strlen($this->client->shipping_country->iso_3166_2 ?? '') >= 2
|
|
||||||
) {
|
|
||||||
$order['paypal']['address'] = [
|
|
||||||
"address_line_1" => $this->client->shipping_address1,
|
|
||||||
"address_line_2" => $this->client->shipping_address2,
|
|
||||||
"admin_area_2" => $this->client->shipping_city,
|
|
||||||
"admin_area_1" => $this->client->shipping_state,
|
|
||||||
"postal_code" => $this->client->shipping_postal_code,
|
|
||||||
"country_code" => $this->client->present()->shipping_country_code(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
elseif(
|
|
||||||
strlen($this->client->address1 ?? '') > 2 &&
|
|
||||||
strlen($this->client->city ?? '') > 2 &&
|
|
||||||
strlen($this->client->state ?? '') >= 2 &&
|
|
||||||
strlen($this->client->postal_code ?? '') > 2 &&
|
|
||||||
strlen($this->client->country->iso_3166_2 ?? '') >= 2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$order['paypal']['address'] = [
|
|
||||||
"address_line_1" => $this->client->address1,
|
|
||||||
"address_line_2" => $this->client->address2,
|
|
||||||
"admin_area_2" => $this->client->city,
|
|
||||||
"admin_area_1" => $this->client->state,
|
|
||||||
"postal_code" => $this->client->postal_code,
|
|
||||||
"country_code" => $this->client->country->iso_3166_2,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function createOrder(array $data): string
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
$_invoice = collect($this->payment_hash->data->invoices)->first();
|
||||||
@ -576,126 +250,81 @@ return render('gateways.paypal.pay', $data);
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
if($shipping = $this->getShippingAddress()) {
|
if($shipping = $this->getShippingAddress()) {
|
||||||
$order['purchase_units'][0]["shipping"] = $shipping;
|
$order['purchase_units'][0]["shipping"] = $shipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($data['payment_source']))
|
if(isset($data['payment_source']))
|
||||||
$order['payment_source'] = $data['payment_source'];
|
$order['payment_source'] = $data['payment_source'];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
|
||||||
|
|
||||||
return $r->json()['id'];
|
return $r->json()['id'];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getShippingAddress(): ?array
|
/**
|
||||||
{
|
* processTokenPayment
|
||||||
return $this->company_gateway->require_shipping_address ?
|
*
|
||||||
[
|
* With PayPal and token payments, the order needs to be
|
||||||
"address" =>
|
* deleted and then created with the payment source that
|
||||||
[
|
* has been selected by the client.
|
||||||
"address_line_1" => strlen($this->client->shipping_address1) > 1 ? $this->client->shipping_address1 : $this->client->address1,
|
*
|
||||||
"address_line_2" => $this->client->shipping_address2,
|
* This method handle the deletion of the current paypal order,
|
||||||
"admin_area_2" => strlen($this->client->shipping_city) > 1 ? $this->client->shipping_city : $this->client->city,
|
* and the automatic payment of the order with the selected payment source.
|
||||||
"admin_area_1" => strlen($this->client->shipping_state) > 1 ? $this->client->shipping_state : $this->client->state,
|
*
|
||||||
"postal_code" => strlen($this->client->shipping_postal_code) > 1 ? $this->client->shipping_postal_code : $this->client->postal_code,
|
* @param mixed $request
|
||||||
"country_code" => $this->client->present()->shipping_country_code(),
|
* @param array $response
|
||||||
],
|
* @return void
|
||||||
]
|
*/
|
||||||
|
public function processTokenPayment($request, array $response) {
|
||||||
|
|
||||||
: [
|
$cgt = ClientGatewayToken::where('client_id', $this->client->id)
|
||||||
"name" => [
|
->where('token', $request['token'])
|
||||||
"full_name" => $this->client->present()->name()
|
->firstOrFail();
|
||||||
]
|
|
||||||
|
$orderId = $response['orderID'];
|
||||||
|
$r = $this->gatewayRequest("/v1/checkout/orders/{$orderId}/", 'delete', ['body' => '']);
|
||||||
|
|
||||||
|
$data['amount_with_fee'] = $this->payment_hash->data->amount_with_fee;
|
||||||
|
$data["payment_source"] = [
|
||||||
|
"card" => [
|
||||||
|
"vault_id" => $cgt->token,
|
||||||
|
"stored_credential" => [
|
||||||
|
"payment_initiator" => "MERCHANT",
|
||||||
|
"payment_type" => "UNSCHEDULED",
|
||||||
|
"usage" => "SUBSEQUENT",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$orderId = $this->createOrder($data);
|
||||||
|
|
||||||
|
$r = $this->gatewayRequest("/v2/checkout/orders/{$orderId}", 'get', ['body' => '']);
|
||||||
|
|
||||||
|
$response = $r->json();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'payment_type' => $this->getPaymentMethod($request->gateway_type_id),
|
||||||
|
'amount' => $response['purchase_units'][0]['payments']['captures'][0]['amount']['value'],
|
||||||
|
'transaction_reference' => $response['purchase_units'][0]['payments']['captures'][0]['id'],
|
||||||
|
'gateway_type_id' => $this->gateway_type_id,
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the gateway request
|
|
||||||
*
|
|
||||||
* @param string $uri
|
|
||||||
* @param string $verb
|
|
||||||
* @param array $data
|
|
||||||
* @param ?array $headers
|
|
||||||
* @return \Illuminate\Http\Client\Response
|
|
||||||
*/
|
|
||||||
public function gatewayRequest(string $uri, string $verb, array $data, ?array $headers = [])
|
|
||||||
{
|
|
||||||
$this->init();
|
|
||||||
|
|
||||||
$r = Http::withToken($this->access_token)
|
|
||||||
->withHeaders($this->getHeaders($headers))
|
|
||||||
->{$verb}("{$this->api_endpoint_url}{$uri}", $data);
|
|
||||||
|
|
||||||
if($r->successful()) {
|
|
||||||
return $r;
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
['response' => $r->body()],
|
['response' => $response, 'data' => $data],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
SystemLog::TYPE_PAYPAL,
|
SystemLog::TYPE_PAYPAL,
|
||||||
$this->client,
|
$this->client,
|
||||||
$this->client->company ?? $this->company_gateway->company,
|
$this->client->company,
|
||||||
);
|
);
|
||||||
|
|
||||||
throw new PaymentFailed("Gateway failure - {$r->body()}", 401);
|
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getHeaders(array $headers = []): array
|
|
||||||
{
|
|
||||||
return array_merge([
|
|
||||||
'Accept' => 'application/json',
|
|
||||||
'Content-type' => 'application/json',
|
|
||||||
'Accept-Language' => 'en_US',
|
|
||||||
'PayPal-Partner-Attribution-Id' => 'invoiceninja_SP_PPCP',
|
|
||||||
'PayPal-Request-Id' => Str::uuid()->toString(),
|
|
||||||
], $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function feeCalc($invoice, $invoice_total)
|
|
||||||
{
|
|
||||||
$invoice->service()->removeUnpaidGatewayFees();
|
|
||||||
$invoice = $invoice->fresh();
|
|
||||||
|
|
||||||
$balance = floatval($invoice->balance);
|
|
||||||
|
|
||||||
$_updated_invoice = $invoice->service()->addGatewayFee($this->company_gateway, GatewayType::PAYPAL, $invoice_total)->save();
|
|
||||||
|
|
||||||
if (floatval($_updated_invoice->balance) > $balance) {
|
|
||||||
$fee = floatval($_updated_invoice->balance) - $balance;
|
|
||||||
|
|
||||||
$this->payment_hash->fee_total = $fee;
|
|
||||||
$this->payment_hash->save();
|
|
||||||
|
|
||||||
return $fee;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function auth(): bool
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->init()->getClientToken();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch(\Exception $e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function importCustomers()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ class TaskRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
|
|
||||||
if(isset($time_log[0][0])) {
|
if(isset($time_log[0][0])) {
|
||||||
return \Carbon\Carbon::createFromTimestamp($time_log[0][0]);
|
return \Carbon\Carbon::createFromTimestamp($time_log[0][0])->addSeconds($task->company->utc_offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
|
|
||||||
namespace App\Services\EDocument\Standards;
|
namespace App\Services\EDocument\Standards;
|
||||||
|
|
||||||
|
use App\DataMapper\InvoiceItem;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\PurchaseOrder;
|
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Services\AbstractService;
|
use App\Services\AbstractService;
|
||||||
use horstoeko\zugferd\codelists\ZugferdDutyTaxFeeCategories;
|
use horstoeko\zugferd\codelists\ZugferdDutyTaxFeeCategories;
|
||||||
@ -56,6 +56,7 @@ class ZugferdEDokument extends AbstractService
|
|||||||
->setDocumentSeller($company->getSetting('name'))
|
->setDocumentSeller($company->getSetting('name'))
|
||||||
->setDocumentSellerAddress($company->getSetting("address1"), $company->getSetting("address2"), "", $company->getSetting("postal_code"), $company->getSetting("city"), $company->country()->iso_3166_2, $company->getSetting("state"))
|
->setDocumentSellerAddress($company->getSetting("address1"), $company->getSetting("address2"), "", $company->getSetting("postal_code"), $company->getSetting("city"), $company->country()->iso_3166_2, $company->getSetting("state"))
|
||||||
->setDocumentSellerContact($this->document->user->present()->getFullName(), "", $this->document->user->present()->phone(), "", $this->document->user->email)
|
->setDocumentSellerContact($this->document->user->present()->getFullName(), "", $this->document->user->present()->phone(), "", $this->document->user->email)
|
||||||
|
->setDocumentSellerCommunication("EM", $this->document->user->email)
|
||||||
->setDocumentBuyer($client->present()->name(), $client->number)
|
->setDocumentBuyer($client->present()->name(), $client->number)
|
||||||
->setDocumentBuyerAddress($client->address1, "", "", $client->postal_code, $client->city, $client->country->iso_3166_2, $client->state)
|
->setDocumentBuyerAddress($client->address1, "", "", $client->postal_code, $client->city, $client->country->iso_3166_2, $client->state)
|
||||||
->setDocumentBuyerContact($client->present()->primary_contact_name(), "", $client->present()->phone(), "", $client->present()->email())
|
->setDocumentBuyerContact($client->present()->primary_contact_name(), "", $client->present()->phone(), "", $client->present()->email())
|
||||||
@ -71,13 +72,15 @@ class ZugferdEDokument extends AbstractService
|
|||||||
// Probably wrong file code https://github.com/horstoeko/zugferd/blob/master/src/codelists/ZugferdInvoiceType.php
|
// Probably wrong file code https://github.com/horstoeko/zugferd/blob/master/src/codelists/ZugferdInvoiceType.php
|
||||||
if (empty($this->document->number)) {
|
if (empty($this->document->number)) {
|
||||||
$this->xdocument->setDocumentInformation("DRAFT", "84", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation("DRAFT", "84", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
|
$this->xdocument->setIsTestDocument();
|
||||||
} else {
|
} else {
|
||||||
$this->xdocument->setDocumentInformation($this->document->number, "84", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation($this->document->number, "84", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
};
|
}
|
||||||
break;
|
break;
|
||||||
case Invoice::class:
|
case Invoice::class:
|
||||||
if (empty($this->document->number)) {
|
if (empty($this->document->number)) {
|
||||||
$this->xdocument->setDocumentInformation("DRAFT", "380", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation("DRAFT", "380", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
|
$this->xdocument->setIsTestDocument();
|
||||||
} else {
|
} else {
|
||||||
$this->xdocument->setDocumentInformation($this->document->number, "380", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation($this->document->number, "380", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
}
|
}
|
||||||
@ -85,6 +88,7 @@ class ZugferdEDokument extends AbstractService
|
|||||||
case Credit::class:
|
case Credit::class:
|
||||||
if (empty($this->document->number)) {
|
if (empty($this->document->number)) {
|
||||||
$this->xdocument->setDocumentInformation("DRAFT", "389", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation("DRAFT", "389", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
|
$this->xdocument->setIsTestDocument();
|
||||||
} else {
|
} else {
|
||||||
$this->xdocument->setDocumentInformation($this->document->number, "389", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
$this->xdocument->setDocumentInformation($this->document->number, "389", date_create($this->document->date ?? now()->format('Y-m-d')), $client->getCurrencyCode());
|
||||||
}
|
}
|
||||||
@ -92,11 +96,13 @@ class ZugferdEDokument extends AbstractService
|
|||||||
if (isset($this->document->po_number)) {
|
if (isset($this->document->po_number)) {
|
||||||
$this->xdocument->setDocumentBuyerOrderReferencedDocument($this->document->po_number);
|
$this->xdocument->setDocumentBuyerOrderReferencedDocument($this->document->po_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($client->routing_id)) {
|
if (empty($client->routing_id)) {
|
||||||
$this->xdocument->setDocumentBuyerReference(ctrans("texts.xinvoice_no_buyers_reference"));
|
|
||||||
|
$this->xdocument->setDocumentBuyerReference(ctrans("texts.xinvoice_no_buyers_reference"))
|
||||||
|
->setDocumentSellerCommunication("EM", $client->present()->email());
|
||||||
} else {
|
} else {
|
||||||
$this->xdocument->setDocumentBuyerReference($client->routing_id);
|
$this->xdocument->setDocumentBuyerReference($client->routing_id)
|
||||||
|
->setDocumentBuyerCommunication("0204", $client->routing_id);
|
||||||
}
|
}
|
||||||
if (isset($client->shipping_address1) && $client->shipping_country) {
|
if (isset($client->shipping_address1) && $client->shipping_country) {
|
||||||
$this->xdocument->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state);
|
$this->xdocument->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state);
|
||||||
@ -113,15 +119,18 @@ class ZugferdEDokument extends AbstractService
|
|||||||
$this->xdocument->addDocumentSellerTaxRegistration("FC", $company->getSetting('vat_number'));
|
$this->xdocument->addDocumentSellerTaxRegistration("FC", $company->getSetting('vat_number'));
|
||||||
} else {
|
} else {
|
||||||
$this->xdocument->addDocumentSellerTaxRegistration("VA", $company->getSetting('vat_number'));
|
$this->xdocument->addDocumentSellerTaxRegistration("VA", $company->getSetting('vat_number'));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!empty($client->vat_number)){
|
||||||
|
$this->xdocument->addDocumentBuyerTaxRegistration("VA", $client->vat_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
$invoicing_data = $this->document->calc();
|
$invoicing_data = $this->document->calc();
|
||||||
|
|
||||||
//Create line items and calculate taxes
|
//Create line items and calculate taxes
|
||||||
foreach ($this->document->line_items as $index => $item) {
|
foreach ($this->document->line_items as $index => $item) {
|
||||||
/** @var \App\DataMapper\InvoiceItem $item **/
|
/** @var InvoiceItem $item **/
|
||||||
$this->xdocument->addNewPosition($index)
|
$this->xdocument->addNewPosition($index)
|
||||||
->setDocumentPositionGrossPrice($item->gross_line_total)
|
->setDocumentPositionGrossPrice($item->gross_line_total+$item->discount)
|
||||||
->setDocumentPositionNetPrice($item->line_total);
|
->setDocumentPositionNetPrice($item->line_total);
|
||||||
if (!empty($item->product_key)) {
|
if (!empty($item->product_key)) {
|
||||||
if (!empty($item->notes)) {
|
if (!empty($item->notes)) {
|
||||||
@ -141,56 +150,90 @@ class ZugferdEDokument extends AbstractService
|
|||||||
} else {
|
} else {
|
||||||
$this->xdocument->setDocumentPositionQuantity($item->quantity, "H87");
|
$this->xdocument->setDocumentPositionQuantity($item->quantity, "H87");
|
||||||
}
|
}
|
||||||
$linenetamount = $item->line_total;
|
$line_discount = 0.0;
|
||||||
if ($item->discount > 0) {
|
if ($item->discount > 0) {
|
||||||
if ($this->document->is_amount_discount) {
|
if ($this->document->is_amount_discount) {
|
||||||
$linenetamount -= $item->discount;
|
$line_discount -= $item->discount;
|
||||||
} else {
|
} else {
|
||||||
$linenetamount -= $linenetamount * ($item->discount / 100);
|
$line_discount -= $item->line_total * ($item->discount / 100);
|
||||||
}
|
}
|
||||||
|
$this->xdocument->addDocumentPositionGrossPriceAllowanceCharge( abs($line_discount), false);
|
||||||
}
|
}
|
||||||
$this->xdocument->setDocumentPositionLineSummation($linenetamount);
|
|
||||||
|
$this->xdocument->setDocumentPositionLineSummation($item->line_total);
|
||||||
// According to european law, each line item can only have one tax rate
|
// According to european law, each line item can only have one tax rate
|
||||||
if (!(empty($item->tax_name1) && empty($item->tax_name2) && empty($item->tax_name3))) {
|
if (!(empty($item->tax_name1) && empty($item->tax_name2) && empty($item->tax_name3))) {
|
||||||
$taxtype = $this->getTaxType($item->tax_id);
|
$taxtype = $this->getTaxType($item->tax_id);
|
||||||
if (!empty($item->tax_name1)) {
|
if (!empty($item->tax_name1)) {
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate1);
|
if ($taxtype == ZugferdDutyTaxFeeCategories::VAT_EXEMPT_FOR_EEA_INTRACOMMUNITY_SUPPLY_OF_GOODS_AND_SERVICES){
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate1);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate1, exemptionReason: ctrans('texts.intracommunity_tax_info'));
|
||||||
|
} else {
|
||||||
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate1);
|
||||||
|
}
|
||||||
|
$this->addtoTaxMap($taxtype, $item->line_total, $item->tax_rate1);
|
||||||
} elseif (!empty($item->tax_name2)) {
|
} elseif (!empty($item->tax_name2)) {
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate2);
|
if ($taxtype == ZugferdDutyTaxFeeCategories::VAT_EXEMPT_FOR_EEA_INTRACOMMUNITY_SUPPLY_OF_GOODS_AND_SERVICES){
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate2);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate2, exemptionReason: ctrans('texts.intracommunity_tax_info'));
|
||||||
|
} else {
|
||||||
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate2);
|
||||||
|
}
|
||||||
|
$this->addtoTaxMap($taxtype, $item->line_total, $item->tax_rate2);
|
||||||
} elseif (!empty($item->tax_name3)) {
|
} elseif (!empty($item->tax_name3)) {
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3);
|
if ($taxtype == ZugferdDutyTaxFeeCategories::VAT_EXEMPT_FOR_EEA_INTRACOMMUNITY_SUPPLY_OF_GOODS_AND_SERVICES){
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $item->tax_rate3);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3, exemptionReason: ctrans('texts.intracommunity_tax_info'));
|
||||||
|
} else {
|
||||||
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $item->tax_rate3);
|
||||||
|
}
|
||||||
|
$this->addtoTaxMap($taxtype, $item->line_total, $item->tax_rate3);
|
||||||
} else {
|
} else {
|
||||||
// nlog("Can't add correct tax position");
|
nlog("Can't add correct tax position");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!empty($this->document->tax_name1)) {
|
if (!empty($this->document->tax_name1)) {
|
||||||
$taxtype = $this->getTaxType($this->document->tax_name1);
|
$taxtype = $this->getTaxType($this->document->tax_name1);
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate1);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate1);
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $this->document->tax_rate1);
|
$this->addtoTaxMap($taxtype, $item->line_total, $this->document->tax_rate1);
|
||||||
} elseif (!empty($this->document->tax_name2)) {
|
} elseif (!empty($this->document->tax_name2)) {
|
||||||
$taxtype = $this->getTaxType($this->document->tax_name2);
|
$taxtype = $this->getTaxType($this->document->tax_name2);
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate2);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate2);
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $this->document->tax_rate2);
|
$this->addtoTaxMap($taxtype, $item->line_total, $this->document->tax_rate2);
|
||||||
} elseif (!empty($this->document->tax_name3)) {
|
} elseif (!empty($this->document->tax_name3)) {
|
||||||
$taxtype = $this->getTaxType($this->document->tax_name3);
|
$taxtype = $this->getTaxType($this->document->tax_name3);
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate3);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', $this->document->tax_rate3);
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, $this->document->tax_rate3);
|
$this->addtoTaxMap($taxtype, $item->line_total, $this->document->tax_rate3);
|
||||||
} else {
|
} else {
|
||||||
$taxtype = ZugferdDutyTaxFeeCategories::ZERO_RATED_GOODS;
|
$taxtype = ZugferdDutyTaxFeeCategories::ZERO_RATED_GOODS;
|
||||||
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', 0);
|
$this->xdocument->addDocumentPositionTax($taxtype, 'VAT', 0);
|
||||||
$this->addtoTaxMap($taxtype, $linenetamount, 0);
|
$this->addtoTaxMap($taxtype, $item->line_total, 0);
|
||||||
// nlog("Can't add correct tax position");
|
// nlog("Can't add correct tax position");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($this->document->is_amount_discount) {
|
||||||
|
$document_discount = abs($this->document->discount);
|
||||||
|
} else {
|
||||||
|
$document_discount = $this->document->amount * $this->document->discount / 100;
|
||||||
|
}
|
||||||
|
|
||||||
$this->xdocument->setDocumentSummation($this->document->amount, $this->document->balance, $invoicing_data->getSubTotal(), $invoicing_data->getTotalSurcharges(), $invoicing_data->getTotalDiscount(), $invoicing_data->getSubTotal(), $invoicing_data->getItemTotalTaxes(), 0.0, $this->document->amount - $this->document->balance);
|
$this->xdocument->setDocumentSummation($this->document->amount, $this->document->balance, $invoicing_data->getSubTotal(), $invoicing_data->getTotalSurcharges(), $document_discount, $invoicing_data->getSubTotal()-$document_discount, $invoicing_data->getItemTotalTaxes(), 0.0, $this->document->amount - $this->document->balance);
|
||||||
|
|
||||||
foreach ($this->tax_map as $item) {
|
foreach ($this->tax_map as $item) {
|
||||||
|
if ($document_discount > 0){
|
||||||
|
if ($item["net_amount"] >= $document_discount) {
|
||||||
|
$item["net_amount"] -= $document_discount;
|
||||||
|
$this->xdocument->addDocumentAllowanceCharge($document_discount, false, $item["tax_type"], "VAT", $item["tax_rate"] * 100);
|
||||||
|
} else {
|
||||||
|
$document_discount -= $item["net_amount"];
|
||||||
|
$this->xdocument->addDocumentAllowanceCharge($item["net_amount"], false, $item["tax_type"], "VAT", $item["tax_rate"] * 100);
|
||||||
|
$item["net_amount"] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($item["tax_type"] == ZugferdDutyTaxFeeCategories::VAT_EXEMPT_FOR_EEA_INTRACOMMUNITY_SUPPLY_OF_GOODS_AND_SERVICES){
|
||||||
|
$this->xdocument->addDocumentTax($item["tax_type"], "VAT", $item["net_amount"], $item["tax_rate"] * $item["net_amount"], $item["tax_rate"] * 100, ctrans('texts.intracommunity_tax_info'));
|
||||||
|
} else {
|
||||||
$this->xdocument->addDocumentTax($item["tax_type"], "VAT", $item["net_amount"], $item["tax_rate"] * $item["net_amount"], $item["tax_rate"] * 100);
|
$this->xdocument->addDocumentTax($item["tax_type"], "VAT", $item["net_amount"], $item["tax_rate"] * $item["net_amount"], $item["tax_rate"] * 100);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The validity can be checked using https://portal3.gefeg.com/invoice/validation or https://e-rechnung.bayern.de/app/#/upload
|
// The validity can be checked using https://portal3.gefeg.com/invoice/validation or https://e-rechnung.bayern.de/app/#/upload
|
||||||
|
@ -314,7 +314,7 @@ class Email implements ShouldQueue
|
|||||||
$this->logMailError($e->getMessage(), $this->company->clients()->first());
|
$this->logMailError($e->getMessage(), $this->company->clients()->first());
|
||||||
$this->cleanUpMailers();
|
$this->cleanUpMailers();
|
||||||
|
|
||||||
$this->entityEmailFailed($message);
|
$this->entityEmailFailed($message);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'smtp_password' => $company->smtp_password ? '********' : '',
|
'smtp_password' => $company->smtp_password ? '********' : '',
|
||||||
'smtp_local_domain' => (string) $company->smtp_local_domain ?? '',
|
'smtp_local_domain' => (string) $company->smtp_local_domain ?? '',
|
||||||
'smtp_verify_peer' => (bool) $company->smtp_verify_peer,
|
'smtp_verify_peer' => (bool) $company->smtp_verify_peer,
|
||||||
|
'e_invoice' => $company->e_invoice ?: new \stdClass(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,7 @@ class CreditTransformer extends EntityTransformer
|
|||||||
'subscription_id' => $this->encodePrimaryKey($credit->subscription_id),
|
'subscription_id' => $this->encodePrimaryKey($credit->subscription_id),
|
||||||
'invoice_id' => $credit->invoice_id ? $this->encodePrimaryKey($credit->invoice_id) : '',
|
'invoice_id' => $credit->invoice_id ? $this->encodePrimaryKey($credit->invoice_id) : '',
|
||||||
'tax_info' => $credit->tax_data ?: new \stdClass(),
|
'tax_info' => $credit->tax_data ?: new \stdClass(),
|
||||||
|
'e_invoice' => $credit->e_invoice ?: new \stdClass(),
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,8 @@ class ExpenseTransformer extends EntityTransformer
|
|||||||
'uses_inclusive_taxes' => (bool) $expense->uses_inclusive_taxes,
|
'uses_inclusive_taxes' => (bool) $expense->uses_inclusive_taxes,
|
||||||
'calculate_tax_by_amount' => (bool) $expense->calculate_tax_by_amount,
|
'calculate_tax_by_amount' => (bool) $expense->calculate_tax_by_amount,
|
||||||
'entity_type' => 'expense',
|
'entity_type' => 'expense',
|
||||||
|
'e_invoice' => $expense->e_invoice ?: new \stdClass(),
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,8 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
'subscription_id' => $this->encodePrimaryKey($invoice->subscription_id),
|
'subscription_id' => $this->encodePrimaryKey($invoice->subscription_id),
|
||||||
'auto_bill_enabled' => (bool) $invoice->auto_bill_enabled,
|
'auto_bill_enabled' => (bool) $invoice->auto_bill_enabled,
|
||||||
'tax_info' => $invoice->tax_data ?: new \stdClass(),
|
'tax_info' => $invoice->tax_data ?: new \stdClass(),
|
||||||
|
'e_invoice' => $invoice->e_invoice ?: new \stdClass(),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (request()->has('reminder_schedule') && request()->query('reminder_schedule') == 'true') {
|
if (request()->has('reminder_schedule') && request()->query('reminder_schedule') == 'true') {
|
||||||
|
@ -150,6 +150,8 @@ class PurchaseOrderTransformer extends EntityTransformer
|
|||||||
'expense_id' => $this->encodePrimaryKey($purchase_order->expense_id),
|
'expense_id' => $this->encodePrimaryKey($purchase_order->expense_id),
|
||||||
'currency_id' => $purchase_order->currency_id ? (string) $purchase_order->currency_id : '',
|
'currency_id' => $purchase_order->currency_id ? (string) $purchase_order->currency_id : '',
|
||||||
'tax_info' => $purchase_order->tax_data ?: new \stdClass(),
|
'tax_info' => $purchase_order->tax_data ?: new \stdClass(),
|
||||||
|
'e_invoice' => $purchase_order->e_invoice ?: new \stdClass(),
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,8 @@ class QuoteTransformer extends EntityTransformer
|
|||||||
'project_id' => $this->encodePrimaryKey($quote->project_id),
|
'project_id' => $this->encodePrimaryKey($quote->project_id),
|
||||||
'subscription_id' => $this->encodePrimaryKey($quote->subscription_id),
|
'subscription_id' => $this->encodePrimaryKey($quote->subscription_id),
|
||||||
'tax_info' => $quote->tax_data ?: new \stdClass(),
|
'tax_info' => $quote->tax_data ?: new \stdClass(),
|
||||||
|
'e_invoice' => $quote->e_invoice ?: new \stdClass(),
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,10 +561,19 @@ class HtmlEngine
|
|||||||
|
|
||||||
$data['$spc_qr_code'] = ['value' => $this->company->present()->getSpcQrCode($this->client->currency()->code, $this->entity->number, $this->entity->balance, $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client)), 'label' => ''];
|
$data['$spc_qr_code'] = ['value' => $this->company->present()->getSpcQrCode($this->client->currency()->code, $this->entity->number, $this->entity->balance, $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client)), 'label' => ''];
|
||||||
|
|
||||||
$logo = $this->company->present()->logo_base64($this->settings);
|
if(Ninja::isHosted())
|
||||||
|
$logo = $this->company->present()->logo($this->settings);
|
||||||
|
else
|
||||||
|
$logo = $this->company->present()->logo_base64($this->settings);
|
||||||
|
|
||||||
|
$logo_url = $this->company->present()->logo($this->settings);
|
||||||
|
|
||||||
|
|
||||||
$data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
|
$data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
|
||||||
$data['$company_logo'] = &$data['$company.logo'];
|
$data['$company_logo'] = &$data['$company.logo'];
|
||||||
|
|
||||||
|
$data['$company.logo_url'] = ['value' => $logo_url ?: ' ', 'label' => ctrans('texts.logo')];
|
||||||
|
|
||||||
$data['$company1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company1')];
|
$data['$company1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company1', $this->settings->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company1')];
|
||||||
$data['$company2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company2', $this->settings->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company2')];
|
$data['$company2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company2', $this->settings->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company2')];
|
||||||
$data['$company3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company3', $this->settings->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company3')];
|
$data['$company3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'company3', $this->settings->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'company3')];
|
||||||
|
44
composer.lock
generated
44
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "da485c7cec773404ffe59d450b6505cf",
|
"content-hash": "1356155e46e797b140685c105df97b8e",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adrienrn/php-mimetyper",
|
"name": "adrienrn/php-mimetyper",
|
||||||
@ -3221,26 +3221,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
"version": "v6.10.0",
|
"version": "v6.10.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/firebase/php-jwt.git",
|
"url": "https://github.com/firebase/php-jwt.git",
|
||||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff"
|
"reference": "500501c2ce893c824c801da135d02661199f60c5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff",
|
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5",
|
||||||
"reference": "a49db6f0a5033aef5143295342f1c95521b075ff",
|
"reference": "500501c2ce893c824c801da135d02661199f60c5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4||^8.0"
|
"php": "^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"guzzlehttp/guzzle": "^6.5||^7.4",
|
"guzzlehttp/guzzle": "^7.4",
|
||||||
"phpspec/prophecy-phpunit": "^2.0",
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
"phpunit/phpunit": "^9.5",
|
"phpunit/phpunit": "^9.5",
|
||||||
"psr/cache": "^1.0||^2.0",
|
"psr/cache": "^2.0||^3.0",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"psr/http-factory": "^1.0"
|
"psr/http-factory": "^1.0"
|
||||||
},
|
},
|
||||||
@ -3278,9 +3278,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||||
"source": "https://github.com/firebase/php-jwt/tree/v6.10.0"
|
"source": "https://github.com/firebase/php-jwt/tree/v6.10.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-01T16:26:39+00:00"
|
"time": "2024-05-18T18:05:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "fruitcake/php-cors",
|
"name": "fruitcake/php-cors",
|
||||||
@ -3602,23 +3602,23 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/apiclient-services",
|
"name": "google/apiclient-services",
|
||||||
"version": "v0.355.0",
|
"version": "v0.356.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||||
"reference": "235e6a45ecafd77accc102b5ab6d529aab54da23"
|
"reference": "8e22b0a6f661f2db3f99abb6ee5a1dcf28d370e7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/235e6a45ecafd77accc102b5ab6d529aab54da23",
|
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/8e22b0a6f661f2db3f99abb6ee5a1dcf28d370e7",
|
||||||
"reference": "235e6a45ecafd77accc102b5ab6d529aab54da23",
|
"reference": "8e22b0a6f661f2db3f99abb6ee5a1dcf28d370e7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4||^8.0"
|
"php": "^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7||^8.5.13"
|
"phpunit/phpunit": "^9.6"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@ -3640,9 +3640,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.355.0"
|
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.356.0"
|
||||||
},
|
},
|
||||||
"time": "2024-05-11T01:02:11+00:00"
|
"time": "2024-05-18T01:10:18+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/auth",
|
"name": "google/auth",
|
||||||
@ -5034,12 +5034,12 @@
|
|||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/invoiceninja/einvoice.git",
|
"url": "https://github.com/invoiceninja/einvoice.git",
|
||||||
"reference": "6028038ff94e6c0090ba5c444bd0be56a65bc0bc"
|
"reference": "39aec367c528ba66d923dc1d9e5c96f673bb46c7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/invoiceninja/einvoice/zipball/6028038ff94e6c0090ba5c444bd0be56a65bc0bc",
|
"url": "https://api.github.com/repos/invoiceninja/einvoice/zipball/39aec367c528ba66d923dc1d9e5c96f673bb46c7",
|
||||||
"reference": "6028038ff94e6c0090ba5c444bd0be56a65bc0bc",
|
"reference": "39aec367c528ba66d923dc1d9e5c96f673bb46c7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -5075,7 +5075,7 @@
|
|||||||
"source": "https://github.com/invoiceninja/einvoice/tree/main",
|
"source": "https://github.com/invoiceninja/einvoice/tree/main",
|
||||||
"issues": "https://github.com/invoiceninja/einvoice/issues"
|
"issues": "https://github.com/invoiceninja/einvoice/issues"
|
||||||
},
|
},
|
||||||
"time": "2024-05-18T12:35:18+00:00"
|
"time": "2024-05-20T11:42:32+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "invoiceninja/inspector",
|
"name": "invoiceninja/inspector",
|
||||||
|
@ -27,6 +27,7 @@ class AccountFactory extends Factory
|
|||||||
'default_company_id' => 1,
|
'default_company_id' => 1,
|
||||||
'key' => Str::random(32),
|
'key' => Str::random(32),
|
||||||
'report_errors' => 1,
|
'report_errors' => 1,
|
||||||
|
'referral_code' => Str::lower(Str::random(32)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,28 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
$gateway = new Gateway;
|
if(!Gateway::find(62))
|
||||||
$gateway->name = 'BTCPay';
|
{
|
||||||
$gateway->key = 'vpyfbmdrkqcicpkjqdusgjfluebftuva';
|
$gateway = new Gateway;
|
||||||
$gateway->provider = 'BTCPay';
|
$gateway->id = 62;
|
||||||
$gateway->is_offsite = true;
|
$gateway->name = 'BTCPay';
|
||||||
|
$gateway->key = 'vpyfbmdrkqcicpkjqdusgjfluebftuva';
|
||||||
|
$gateway->provider = 'BTCPay';
|
||||||
|
$gateway->is_offsite = true;
|
||||||
|
|
||||||
$btcpayFieds = new \stdClass;
|
$btcpayFieds = new \stdClass;
|
||||||
$btcpayFieds->btcpayUrl = "";
|
$btcpayFieds->btcpayUrl = "";
|
||||||
$btcpayFieds->apiKey = "";
|
$btcpayFieds->apiKey = "";
|
||||||
$btcpayFieds->storeId = "";
|
$btcpayFieds->storeId = "";
|
||||||
$btcpayFieds->webhookSecret = "";
|
$btcpayFieds->webhookSecret = "";
|
||||||
$gateway->fields = \json_encode($btcpayFieds);
|
$gateway->fields = \json_encode($btcpayFieds);
|
||||||
|
|
||||||
|
|
||||||
$gateway->visible = true;
|
$gateway->visible = true;
|
||||||
$gateway->site_url = 'https://btcpayserver.org';
|
$gateway->site_url = 'https://btcpayserver.org';
|
||||||
$gateway->default_gateway_type_id = GatewayType::CRYPTO;
|
$gateway->default_gateway_type_id = GatewayType::CRYPTO;
|
||||||
$gateway->save();
|
$gateway->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,4 +43,4 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
Schema::table('companies', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('invoices', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('quotes', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('credits', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('purchase_orders', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('expenses', function (Blueprint $table) {
|
||||||
|
$table->mediumText('e_invoice')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Schema::table('accounts', function (Blueprint $table) {
|
||||||
|
$table->integer('email_quota')->default(20)->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice Ninja (https://invoiceninja.com).
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
*
|
*
|
||||||
@ -8,6 +9,7 @@
|
|||||||
*
|
*
|
||||||
* @license https://www.elastic.co/licensing/elastic-license
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\Gateway;
|
use App\Models\Gateway;
|
||||||
@ -85,12 +87,13 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
['id' => 59, 'name' => 'Forte', 'provider' => 'Forte', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'kivcvjexxvdiyqtj3mju5d6yhpeht2xs', 'fields' => '{"testMode":false,"apiLoginId":"","apiAccessId":"","secureKey":"","authOrganizationId":"","organizationId":"","locationId":""}'],
|
['id' => 59, 'name' => 'Forte', 'provider' => 'Forte', 'is_offsite' => false, 'sort_order' => 21, 'key' => 'kivcvjexxvdiyqtj3mju5d6yhpeht2xs', 'fields' => '{"testMode":false,"apiLoginId":"","apiAccessId":"","secureKey":"","authOrganizationId":"","organizationId":"","locationId":""}'],
|
||||||
['id' => 60, 'name' => 'PayPal REST', 'provider' => 'PayPal_Rest', 'key' => '80af24a6a691230bbec33e930ab40665', 'fields' => '{"clientId":"","secret":"","signature":"","testMode":false}'],
|
['id' => 60, 'name' => 'PayPal REST', 'provider' => 'PayPal_Rest', 'key' => '80af24a6a691230bbec33e930ab40665', 'fields' => '{"clientId":"","secret":"","signature":"","testMode":false}'],
|
||||||
['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'],
|
['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'],
|
||||||
|
['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey:"", "storeId":"", "webhookSecret":""}'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($gateways as $gateway) {
|
foreach ($gateways as $gateway) {
|
||||||
$record = Gateway::whereName($gateway['name'])
|
$record = Gateway::whereName($gateway['name'])
|
||||||
->whereProvider($gateway['provider'])
|
->whereProvider($gateway['provider'])
|
||||||
->first();
|
->first();
|
||||||
if ($record) {
|
if ($record) {
|
||||||
$record->fill($gateway);
|
$record->fill($gateway);
|
||||||
$record->save();
|
$record->save();
|
||||||
@ -101,13 +104,13 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
|
|
||||||
Gateway::query()->update(['visible' => 0]);
|
Gateway::query()->update(['visible' => 0]);
|
||||||
|
|
||||||
Gateway::whereIn('id', [1,3,7,11,15,20,39,46,55,50,57,52,58,59,60])->update(['visible' => 1]);
|
Gateway::whereIn('id', [1, 3, 7, 11, 15, 20, 39, 46, 55, 50, 57, 52, 58, 59, 60, 62])->update(['visible' => 1]);
|
||||||
|
|
||||||
if (Ninja::isHosted()) {
|
if (Ninja::isHosted()) {
|
||||||
Gateway::whereIn('id', [20,49])->update(['visible' => 0]);
|
Gateway::whereIn('id', [20, 49])->update(['visible' => 0]);
|
||||||
Gateway::whereIn('id', [56,61])->update(['visible' => 1]);
|
Gateway::whereIn('id', [56, 61])->update(['visible' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gateway::all()->each(function ($gateway) {
|
Gateway::all()->each(function ($gateway) {
|
||||||
$gateway->site_url = $gateway->getHelp();
|
$gateway->site_url = $gateway->getHelp();
|
||||||
$gateway->save();
|
$gateway->save();
|
||||||
|
@ -252,7 +252,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
|
|
||||||
$invoice->service()->createInvitations()->markSent()->save();
|
$invoice->service()->createInvitations()->markSent()->save();
|
||||||
|
|
||||||
$invoice->ledger()->updateInvoiceBalance($invoice->balance);
|
$invoice->ledger()->update_invoiceBalance($invoice->balance);
|
||||||
|
|
||||||
if (rand(0, 1)) {
|
if (rand(0, 1)) {
|
||||||
$payment = Payment::create([
|
$payment = Payment::create([
|
||||||
@ -277,7 +277,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
|
|
||||||
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
|
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
|
||||||
|
|
||||||
// $payment->service()->updateInvoicePayment($payment_hash);
|
// $payment->service()->update_invoicePayment($payment_hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5322,6 +5322,11 @@ $lang = array(
|
|||||||
'task_round_to_nearest' => 'Round To Nearest',
|
'task_round_to_nearest' => 'Round To Nearest',
|
||||||
'bulk_updated' => 'Successfully updated data',
|
'bulk_updated' => 'Successfully updated data',
|
||||||
'bulk_update' => 'Bulk Update',
|
'bulk_update' => 'Bulk Update',
|
||||||
|
'calculate' => 'Calculate',
|
||||||
|
'sum' => 'Sum',
|
||||||
|
'money' => 'Money',
|
||||||
|
'web_app' => 'Web App',
|
||||||
|
'desktop_app' => 'Desktop App',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $lang;
|
return $lang;
|
||||||
|
@ -5297,6 +5297,26 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
|
|||||||
'local_domain_help' => 'Domaine EHLO (facultatif)',
|
'local_domain_help' => 'Domaine EHLO (facultatif)',
|
||||||
'port_help' => 'ex. 25,587,465',
|
'port_help' => 'ex. 25,587,465',
|
||||||
'host_help' => 'ex. smtp.gmail.com',
|
'host_help' => 'ex. smtp.gmail.com',
|
||||||
|
'always_show_required_fields' => 'Permet l\'affichage des champs requis d\'un formulaire',
|
||||||
|
'always_show_required_fields_help' => 'Affiche toujours les champs requis d\'un formulaire au paiement',
|
||||||
|
'advanced_cards' => 'Cartes avancées',
|
||||||
|
'activity_140' => 'État de compte envoyé à :client',
|
||||||
|
'invoice_net_amount' => 'Montant net de la facture',
|
||||||
|
'round_to_minutes' => 'Arrondir aux minutes',
|
||||||
|
'1_minute' => '1 minute',
|
||||||
|
'5_minutes' => '5 minutes',
|
||||||
|
'15_minutes' => '15 minutes',
|
||||||
|
'30_minutes' => '30 minutes',
|
||||||
|
'1_hour' => '1 heure',
|
||||||
|
'1_day' => '1 jour',
|
||||||
|
'round_tasks' => 'Arrondir les tâches',
|
||||||
|
'round_tasks_help' => 'Arrondir les intervales à la sauvegarde des tâches',
|
||||||
|
'direction' => 'Direction',
|
||||||
|
'round_up' => 'Arrondir à hausse',
|
||||||
|
'round_down' => 'Arrondir à la baisse',
|
||||||
|
'task_round_to_nearest' => 'Arrondir au plus près',
|
||||||
|
'bulk_updated' => 'Les données ont été mises à jour',
|
||||||
|
'bulk_update' => 'Mise à jour groupée',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $lang;
|
return $lang;
|
||||||
|
@ -700,7 +700,7 @@ $lang = array(
|
|||||||
'total_invoiced' => 'Total Invoiced',
|
'total_invoiced' => 'Total Invoiced',
|
||||||
'open_balance' => 'Open Balance',
|
'open_balance' => 'Open Balance',
|
||||||
'verify_email' => 'Please visit the link in the account confirmation email to verify your email address.',
|
'verify_email' => 'Please visit the link in the account confirmation email to verify your email address.',
|
||||||
'basic_settings' => 'Basic Settings',
|
'basic_settings' => '基本設定',
|
||||||
'pro' => 'Pro',
|
'pro' => 'Pro',
|
||||||
'gateways' => 'ペイメントゲートウェイ',
|
'gateways' => 'ペイメントゲートウェイ',
|
||||||
'next_send_on' => 'Send Next: :date',
|
'next_send_on' => 'Send Next: :date',
|
||||||
@ -1344,7 +1344,7 @@ $lang = array(
|
|||||||
'auto_bill_payment_method_credit_card' => 'クレジットカード',
|
'auto_bill_payment_method_credit_card' => 'クレジットカード',
|
||||||
'auto_bill_payment_method_paypal' => 'PayPal アカウント',
|
'auto_bill_payment_method_paypal' => 'PayPal アカウント',
|
||||||
'auto_bill_notification_placeholder' => 'この請求書は、期日にて登録されているクレジットカードに自動的に請求されます。',
|
'auto_bill_notification_placeholder' => 'この請求書は、期日にて登録されているクレジットカードに自動的に請求されます。',
|
||||||
'payment_settings' => 'Payment Settings',
|
'payment_settings' => '支払い設定',
|
||||||
|
|
||||||
'on_send_date' => '発送日',
|
'on_send_date' => '発送日',
|
||||||
'on_due_date' => '支払期日',
|
'on_due_date' => '支払期日',
|
||||||
@ -5300,6 +5300,26 @@ $lang = array(
|
|||||||
'local_domain_help' => 'EHLO domain (optional)',
|
'local_domain_help' => 'EHLO domain (optional)',
|
||||||
'port_help' => 'ie. 25,587,465',
|
'port_help' => 'ie. 25,587,465',
|
||||||
'host_help' => 'ie. smtp.gmail.com',
|
'host_help' => 'ie. smtp.gmail.com',
|
||||||
|
'always_show_required_fields' => 'Allows show required fields form',
|
||||||
|
'always_show_required_fields_help' => 'Displays the required fields form always at checkout',
|
||||||
|
'advanced_cards' => 'Advanced Cards',
|
||||||
|
'activity_140' => 'Statement sent to :client',
|
||||||
|
'invoice_net_amount' => 'Invoice Net Amount',
|
||||||
|
'round_to_minutes' => 'Round To Minutes',
|
||||||
|
'1_minute' => '1 Minute',
|
||||||
|
'5_minutes' => '5 Minutes',
|
||||||
|
'15_minutes' => '15 Minutes',
|
||||||
|
'30_minutes' => '30 Minutes',
|
||||||
|
'1_hour' => '1 Hour',
|
||||||
|
'1_day' => '1 Day',
|
||||||
|
'round_tasks' => 'Round Tasks',
|
||||||
|
'round_tasks_help' => 'Round time intervals when saving tasks',
|
||||||
|
'direction' => 'Direction',
|
||||||
|
'round_up' => 'Round Up',
|
||||||
|
'round_down' => 'Round Down',
|
||||||
|
'task_round_to_nearest' => 'Round To Nearest',
|
||||||
|
'bulk_updated' => 'Successfully updated data',
|
||||||
|
'bulk_update' => 'Bulk Update',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $lang;
|
return $lang;
|
||||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"resources/js/app.js": {
|
"resources/js/app.js": {
|
||||||
"file": "assets/app-bfac6a32.js",
|
"file": "assets/app-a52d5f77.js",
|
||||||
"imports": [
|
"imports": [
|
||||||
"_index-08e160a7.js",
|
"_index-08e160a7.js",
|
||||||
"__commonjsHelpers-725317a4.js"
|
"__commonjsHelpers-725317a4.js"
|
||||||
|
602
public/flutter_service_worker.js
vendored
602
public/flutter_service_worker.js
vendored
@ -3,313 +3,313 @@ const MANIFEST = 'flutter-app-manifest';
|
|||||||
const TEMP = 'flutter-temp-cache';
|
const TEMP = 'flutter-temp-cache';
|
||||||
const CACHE_NAME = 'flutter-app-cache';
|
const CACHE_NAME = 'flutter-app-cache';
|
||||||
|
|
||||||
const RESOURCES = {"canvaskit/canvaskit.js": "c86fbd9e7b17accae76e5ad116583dc4",
|
const RESOURCES = {"canvaskit/skwasm.worker.js": "bfb704a6c714a75da9ef320991e88b03",
|
||||||
"canvaskit/skwasm.worker.js": "bfb704a6c714a75da9ef320991e88b03",
|
"canvaskit/skwasm.js": "445e9e400085faead4493be2224d95aa",
|
||||||
"canvaskit/skwasm.js.symbols": "741d50ffba71f89345996b0aa8426af8",
|
|
||||||
"canvaskit/canvaskit.wasm": "3d2a2d663e8c5111ac61a46367f751ac",
|
"canvaskit/canvaskit.wasm": "3d2a2d663e8c5111ac61a46367f751ac",
|
||||||
"canvaskit/chromium/canvaskit.js": "43787ac5098c648979c27c13c6f804c3",
|
"canvaskit/canvaskit.js.symbols": "38cba9233b92472a36ff011dc21c2c9f",
|
||||||
|
"canvaskit/skwasm.js.symbols": "741d50ffba71f89345996b0aa8426af8",
|
||||||
|
"canvaskit/skwasm.wasm": "e42815763c5d05bba43f9d0337fa7d84",
|
||||||
|
"canvaskit/canvaskit.js": "c86fbd9e7b17accae76e5ad116583dc4",
|
||||||
"canvaskit/chromium/canvaskit.wasm": "f5934e694f12929ed56a671617acd254",
|
"canvaskit/chromium/canvaskit.wasm": "f5934e694f12929ed56a671617acd254",
|
||||||
"canvaskit/chromium/canvaskit.js.symbols": "4525682ef039faeb11f24f37436dca06",
|
"canvaskit/chromium/canvaskit.js.symbols": "4525682ef039faeb11f24f37436dca06",
|
||||||
"canvaskit/skwasm.js": "445e9e400085faead4493be2224d95aa",
|
"canvaskit/chromium/canvaskit.js": "43787ac5098c648979c27c13c6f804c3",
|
||||||
"canvaskit/skwasm.wasm": "e42815763c5d05bba43f9d0337fa7d84",
|
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||||
"canvaskit/canvaskit.js.symbols": "38cba9233b92472a36ff011dc21c2c9f",
|
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||||
"flutter.js": "c71a09214cb6f5f8996a531350400a9a",
|
|
||||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
|
||||||
"/": "6da89ef00decd8861b95827eacf0294f",
|
|
||||||
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
|
||||||
"assets/AssetManifest.bin": "bf3be26e7055ad9a32f66b3a56138224",
|
|
||||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "3759b2f7a51e83c64a58cfe07b96a8ee",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mh.png": "18dda388ef5c1cf37cae5e7d5fef39bc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ck.png": "39f343868a8dc8ca95d27b27a5caf480",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fm.png": "d571b8bc4b80980a81a5edbde788b6d2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cx.png": "8efa3231c8a3900a78f2b51d829f8c52",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tv.png": "c57025ed7ae482210f29b9da86b0d211",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dk.png": "abcd01bdbcc02b4a29cbac237f29cd1d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/jm.png": "074400103847c56c37425a73f9d23665",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bz.png": "fd2d7d27a5ddabe4eb9a10b1d3a433e4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mp.png": "87351c30a529071ee9a4bb67765fea4f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hu.png": "281582a753e643b46bdd894047db08bb",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dm.png": "8886b222ed9ccd00f67e8bcf86dadcc2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dz.png": "132ceca353a95c8214676b2e94ecd40f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ca.png": "76f2fac1d3b2cc52ba6695c2e2941632",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gt.png": "706a0c3b5e0b589c843e2539e813839e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/at.png": "570c070177a5ea0fe03e20107ebf5283",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/rs.png": "9dff535d2d08c504be63062f39eff0b7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/si.png": "24237e53b34752554915e71e346bb405",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pa.png": "78e3e4fd56f0064837098fe3f22fb41b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ml.png": "0c50dfd539e87bb4313da0d4556e2d13",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ai.png": "ce5e91ed1725f0499b9231b69a7fd448",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ng.png": "aedbe364bd1543832e88e64b5817e877",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-nir.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lr.png": "b92c75e18dd97349c75d6a43bd17ee94",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/uz.png": "3adad3bac322220cac8abc1c7cbaacac",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-sct.png": "75106a5e49e3e16da76cb33bdac102ab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mm.png": "32e5293d6029d8294c7dfc3c3835c222",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bm.png": "b366ba84cbc8286c830f392bb9086be5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cl.png": "6735e0e2d88c119e9ed1533be5249ef1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lt.png": "7df2cd6566725685f7feb2051f916a3e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/so.png": "1ce20d052f9d057250be96f42647513b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/rw.png": "d1aae0647a5b1ab977ae43ab894ce2c3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sm.png": "a8d6801cb7c5360e18f0a2ed146b396d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sr.png": "9f912879f2829a625436ccd15e643e39",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cm.png": "42d52fa71e8b4dbb182ff431749e8d0d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dj.png": "078bd37d41f746c3cb2d84c1e9611c55",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pe.png": "4d9249aab70a26fadabb14380b3b55d2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hm.png": "72be14316f0af3903cdca7a726c0c589",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/az.png": "6ffa766f6883d2d3d350cdc22a062ca3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/qa.png": "eb9b3388e554cf85aea1e739247548df",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sc.png": "e969fd5afb1eb5902675b6bcf49a8c2e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mo.png": "849848a26bbfc87024017418ad7a6233",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/im.png": "7c9ccb825f0fca557d795c4330cf4f50",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kr.png": "a3b7da3b76b20a70e9cd63cc2315b51b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ht.png": "630f7f8567d87409a32955107ad11a86",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/md.png": "8911d3d821b95b00abbba8771e997eb3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bs.png": "2b9540c4fa514f71911a48de0bd77e71",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/as.png": "d9c1da515c6f945c2e2554592a9dfaae",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lv.png": "53105fea0cc9cc554e0ceaabc53a2d5d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ke.png": "cf5aae3699d3cacb39db9803edae172b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pr.png": "b97b2f4432c430bc340d893f36527e31",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tm.png": "0980fb40ec450f70896f2c588510f933",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mr.png": "f2a62602d43a1ee14625af165b96ce2f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/is.png": "907840430252c431518005b562707831",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ls.png": "2bca756f9313957347404557acb532b0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/af.png": "ba710b50a060b5351381b55366396c30",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sy.png": "24186a0f4ce804a16c91592db5a16a3a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/au.png": "72be14316f0af3903cdca7a726c0c589",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mn.png": "16086e8d89c9067d29fd0f2ea7021a45",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mu.png": "c5228d1e94501d846b5bf203f038ae49",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ve.png": "893391d65cbd10ca787a73578c77d3a7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mz.png": "1ab1ac750fbbb453d33e9f25850ac2a0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hr.png": "69711b2ea009a3e7c40045b538768d4e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/jo.png": "c01cb41f74f9db0cf07ba20f0af83011",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ne.png": "a20724c177e86d6a27143aa9c9664a6f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/uy.png": "da4247b21fcbd9e30dc2b3f7c5dccb64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cd.png": "5b5f832ed6cd9f9240cb31229d8763dc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bn.png": "ed650de06fff61ff27ec92a872197948",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mc.png": "90c2ad7f144d73d4650cbea9dd621275",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sb.png": "296ecedbd8d1c2a6422c3ba8e5cd54bd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tz.png": "56ec99c7e0f68b88a2210620d873683a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nz.png": "65c811e96eb6c9da65538f899c110895",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bf.png": "63f1c67fca7ce8b52b3418a90af6ad37",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gr.png": "ec11281d7decbf07b81a23a72a609b59",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bw.png": "fac8b90d7404728c08686dc39bab4fb3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sl.png": "61b9d992c8a6a83abc4d432069617811",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nf.png": "1c2069b299ce3660a2a95ec574dfde25",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mg.png": "0ef6271ad284ebc0069ff0aeb5a3ad1e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vg.png": "fc095e11f5b58604d6f4d3c2b43d167f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-wls.png": "d7d7c77c72cd425d993bdc50720f4d04",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/za.png": "b28280c6c3eb4624c18b5455d4a1b1ff",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cf.png": "263583ffdf7a888ce4fba8487d1da0b2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bh.png": "a1acd86ef0e19ea5f0297bbe1de6cfd4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/iq.png": "bc3e6f68c5188dbf99b473e2bea066f2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nl.png": "3649c177693bfee9c2fcc63c191a51f1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cv.png": "9b1f31f9fc0795d728328dedd33eb1c0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hk.png": "4b5ec424348c98ec71a46ad3dce3931d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mt.png": "f3119401ae0c3a9d6e2dc23803928c06",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ga.png": "b0e5b2fa1b7106c7652a955db24c11c4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ws.png": "f206322f3e22f175869869dbfadb6ce8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gq.png": "4286e56f388a37f64b21eb56550c06d9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cy.png": "7b36f4af86257a3f15f5a5a16f4a2fcd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/co.png": "e3b1be16dcdae6cb72e9c238fdddce3c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lu.png": "6274fd1cae3c7a425d25e4ccb0941bb8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/re.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/km.png": "5554c8746c16d4f482986fb78ffd9b36",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cw.png": "6c598eb0d331d6b238da57055ec00d33",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pt.png": "eba93d33545c78cc67915d9be8323661",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tn.png": "6612e9fec4bef022cbd45cbb7c02b2b6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/to.png": "1cdd716b5b5502f85d6161dac6ee6c5b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ee.png": "e242645cae28bd5291116ea211f9a566",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kw.png": "3ca448e219d0df506fb2efd5b91be092",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mk.png": "835f2263974de523fa779d29c90595bf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cn.png": "040539c2cdb60ebd9dc8957cdc6a8ad0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/me.png": "590284bc85810635ace30a173e615ca4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cu.png": "f41715bd51f63a9aebf543788543b4c4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/br.png": "5093e0cd8fd3c094664cd17ea8a36fd1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pk.png": "7a6a621f7062589677b3296ca16c6718",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/na.png": "cdc00e9267a873609b0abea944939ff7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nu.png": "f4169998548e312584c67873e0d9352d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pm.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ph.png": "e4025d1395a8455f1ba038597a95228c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/va.png": "c010bf145f695d5c8fb551bafc081f77",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ni.png": "e398dc23e79d9ccd702546cc25f126bf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lb.png": "f80cde345f0d9bd0086531808ce5166a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ci.png": "7f5ca3779d5ff6ce0c803a6efa0d2da7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ki.png": "14db0fc29398730064503907bd696176",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gi.png": "446aa44aaa063d240adab88243b460d3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/td.png": "009303b6188ca0e30bd50074b16f0b16",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gh.png": "b35464dca793fa33e51bf890b5f3d92b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sa.png": "7c95c1a877148e2aa21a213d720ff4fd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tw.png": "b1101fd5f871a9ffe7c9ad191a7d3304",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/li.png": "ecdf7b3fe932378b110851674335d9ab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bb.png": "a8473747387e4e7a8450c499529f1c93",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/th.png": "11ce0c9f8c738fd217ea52b9bc29014b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tf.png": "b2c044b86509e7960b5ba66b094ea285",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ua.png": "b4b10d893611470661b079cb30473871",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ie.png": "1d91912afc591dd120b47b56ea78cdbf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sj.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/yt.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/aw.png": "a93ddf8e32d246dc47f6631f38e0ed92",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bg.png": "1d24bc616e3389684ed2c9f18bcb0209",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tt.png": "a8e1fc5c65dc8bc362a9453fadf9c4b3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tg.png": "7f91f02b26b74899ff882868bd611714",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kg.png": "c4aa6d221d9a9d332155518d6b82dbc7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ba.png": "d415bad33b35de3f095177e8e86cbc82",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sv.png": "217b691efbef7a0f48cdd53e91997f0e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ps.png": "52a25a48658ca9274830ffa124a8c1db",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bv.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vu.png": "3f201fdfb6d669a64c35c20a801016d1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/be.png": "7e5e1831cdd91935b38415479a7110eb",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ar.png": "3bd245f8c28f70c9ef9626dae27adc65",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/eh.png": "515a9cf2620c802e305b5412ac81aed2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vc.png": "da3ca14a978717467abbcdece05d3544",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vn.png": "32ff65ccbf31a707a195be2a5141a89b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/do.png": "ed35983a9263bb5713be37d9a52caddc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bt.png": "3cfe1440e952bc7266d71f7f1454fa23",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pn.png": "0b0641b356af4c3e3489192ff4b0be77",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fk.png": "da8b0fe48829aae2c8feb4839895de63",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/je.png": "288f8dca26098e83ff0455b08cceca1b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/my.png": "f7f962e8a074387fd568c9d4024e0959",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sh.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cg.png": "eca97338cc1cb5b5e91bec72af57b3d4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sz.png": "d1829842e45c2b2b29222c1b7e201591",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ma.png": "057ea2e08587f1361b3547556adae0c2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vi.png": "3f317c56f31971b3179abd4e03847036",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/by.png": "beabf61e94fb3a4f7c7a7890488b213d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/se.png": "25dd5434891ac1ca2ad1af59cda70f80",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nr.png": "1316f3a8a419d8be1975912c712535ea",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/io.png": "83d45bbbff087d47b2b39f1c20598f52",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gd.png": "7a4864ccfa2a0564041c2d1f8a13a8c9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ug.png": "9a0f358b1eb19863e21ae2063fab51c0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bj.png": "6fdc6449f73d23ad3f07060f92db4423",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/il.png": "1e06ad7783f24332405d36561024cc4c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fo.png": "2c7d9233582e83a86927e634897a2a90",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ae.png": "792efc5eb6c31d780bd34bf4bad69f3f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/eg.png": "311d780e8e3dd43f87e6070f6feb74c7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/np.png": "6e099fb1e063930bdd00e8df5cef73d4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/la.png": "e8cd9c3ee6e134adcbe3e986e1974e4a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/zw.png": "078a3267ea8eabf88b2d43fe4aed5ce5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cz.png": "73ecd64c6144786c4d03729b1dd9b1f3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lc.png": "8c1a03a592aa0a99fcaf2b81508a87eb",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ly.png": "8d65057351859065d64b4c118ff9e30e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ao.png": "5f0a372aa3aa7150a3dafea97acfc10d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pl.png": "f20e9ef473a9ed24176f5ad74dd0d50a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tk.png": "60428ff1cdbae680e5a0b8cde4677dd5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pg.png": "0f7e03465a93e0b4e3e1c9d3dd5814a4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ms.png": "9c955a926cf7d57fccb450a97192afa7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gw.png": "05606b9a6393971bd87718b809e054f9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/de.png": "5d9561246523cf6183928756fd605e25",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/an.png": "4e4b90fbca1275d1839ca5b44fc51071",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/no.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/us.png": "83b065848d14d33c0d10a13e01862f34",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ax.png": "ec2062c36f09ed8fb90ac8992d010024",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ad.png": "384e9845debe9aca8f8586d9bedcb7e6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hn.png": "9ecf68aed83c4a9b3f1e6275d96bfb04",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ye.png": "4cf73209d90e9f02ead1565c8fdf59e5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sg.png": "bc772e50b8c79f08f3c2189f5d8ce491",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pw.png": "2e697cc6907a7b94c7f94f5d9b3bdccc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ec.png": "c1ae60d080be91f3be31e92e0a2d9555",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fr.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kh.png": "d48d51e8769a26930da6edfc15de97fe",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/eu.png": "c58ece3931acb87faadc5b940d4f7755",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tj.png": "c73b793f2acd262e71b9236e64c77636",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tr.png": "27feab1a5ca390610d07e0c6bd4720d5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bd.png": "86a0e4bd8787dc8542137a407e0f987f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/om.png": "cebd9ab4b9ab071b2142e21ae2129efc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/am.png": "aaa39141fbc80205bebaa0200b55a13a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bo.png": "3ccf6fa7f9cbc27949b8418925e4e89c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/zm.png": "81cec35b715f227328cad8f314acd797",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ch.png": "a251702f7760b0aac141428ed60b7b66",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gn.png": "b2287c03c88a72d968aa796a076ba056",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sk.png": "2a1ee716d4b41c017ff1dbf3fd3ffc64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mq.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kz.png": "cb3b0095281c9d7e7fb5ce1716ef8ee5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gm.png": "7148d3715527544c2e7d8d6f4a445bb6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/al.png": "722cf9e5c7a1d9c9e4608fb44dbb427d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/er.png": "8ca78e10878a2e97c1371b38c5d258a7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gg.png": "eed435d25bd755aa7f9cd7004b9ed49d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fj.png": "1c6a86752578eb132390febf12789cd6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gs.png": "419dd57836797a3f1bf6258ea6589f9a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ag.png": "41c11d5668c93ba6e452f811defdbb24",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sx.png": "9c19254973d8acf81581ad95b408c7e6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/jp.png": "25ac778acd990bedcfdc02a9b4570045",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tl.png": "c80876dc80cda5ab6bb8ef078bc6b05d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gu.png": "2acb614b442e55864411b6e418df6eab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/wf.png": "6f1644b8f907d197c0ff7ed2f366ad64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gl.png": "b79e24ee1889b7446ba3d65564b86810",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/st.png": "fef62c31713ff1063da2564df3f43eea",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gp.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-eng.png": "0d9f2a6775fd52b79e1d78eb1dda10cf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sn.png": "68eaa89bbc83b3f356e1ba2096b09b3c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/it.png": "5c8e910e6a33ec63dfcda6e8960dd19c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ir.png": "37f67c3141e9843196cb94815be7bd37",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kn.png": "f318e2fd87e5fd2cabefe9ff252bba46",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/et.png": "57edff61c7fddf2761a19948acef1498",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ky.png": "38e39eba673e82c48a1f25bd103a7e97",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ss.png": "b0120cb000b31bb1a5c801c3592139bc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ro.png": "85af99741fe20664d9a7112cfd8d9722",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mv.png": "d9245f74e34d5c054413ace4b86b4f16",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/es.png": "654965f9722f6706586476fb2f5d30dd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/aq.png": "0c586e7b91aa192758fdd0f03adb84d8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bq.png": "3649c177693bfee9c2fcc63c191a51f1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bl.png": "dae94f5465d3390fdc5929e4f74d3f5f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nc.png": "cb36e0c945b79d56def11b23c6a9c7e9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/in.png": "1dec13ba525529cffd4c7f8a35d51121",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kp.png": "e1c8bb52f31fca22d3368d8f492d8f27",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cr.png": "bfd8b41e63fc3cc829c72c4b2e170532",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/xk.png": "079259fbcb1f3c78dafa944464295c16",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ge.png": "6fbd41f07921fa415347ebf6dff5b0f7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cc.png": "31a475216e12fef447382c97b42876ce",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bi.png": "adda8121501f0543f1075244a1acc275",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/id.png": "80bb82d11d5bc144a21042e77972bca9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mx.png": "84b12a569b209e213daccfcbdd1fc799",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mw.png": "ffc1f18eeedc1dfbb1080aa985ce7d05",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/um.png": "8fe7c4fed0a065fdfb9bd3125c6ecaa1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gy.png": "159a260bf0217128ea7475ba5b272b6a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sd.png": "65ce270762dfc87475ea99bd18f79025",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lk.png": "5a3a063cfff4a92fb0ba6158e610e025",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ru.png": "6974dcb42ad7eb3add1009ea0c6003e3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/py.png": "154d4add03b4878caf00bd3249e14f40",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tc.png": "d728d6763c17c520ad6bcf3c24282a29",
|
|
||||||
"assets/packages/window_manager/images/ic_chrome_unmaximize.png": "4a90c1909cb74e8f0d35794e2f61d8bf",
|
|
||||||
"assets/packages/window_manager/images/ic_chrome_minimize.png": "4282cd84cb36edf2efb950ad9269ca62",
|
|
||||||
"assets/packages/window_manager/images/ic_chrome_close.png": "75f4b8ab3608a05461a31fc18d6b47c2",
|
|
||||||
"assets/packages/window_manager/images/ic_chrome_maximize.png": "af7499d7657c8b69d23b85156b60298c",
|
|
||||||
"assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4",
|
|
||||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
|
||||||
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
|
||||||
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
|
||||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
|
||||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
|
||||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
|
||||||
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
|
||||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
|
||||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
|
||||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
|
||||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
|
||||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
|
||||||
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
|
||||||
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
|
||||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
|
||||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
|
||||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
|
||||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
|
||||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
|
||||||
"assets/AssetManifest.bin.json": "611449d46e56c96b3baef404bfc56246",
|
|
||||||
"assets/shaders/ink_sparkle.frag": "ecc85a2e95f5e9f53123dcaf8cb9b6ce",
|
|
||||||
"assets/NOTICES": "412b336cf9e33e70058d612857effae1",
|
|
||||||
"assets/fonts/MaterialIcons-Regular.otf": "a57618538ab8b4c4081d4491870ac333",
|
|
||||||
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
|
|
||||||
"main.dart.js": "bd68d64a60de3a8c0afbd24c36cfcdac",
|
|
||||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||||
"version.json": "4dada3a779a2983f2adddf16b9f4015e",
|
"version.json": "4dada3a779a2983f2adddf16b9f4015e",
|
||||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35"};
|
"/": "cde2c9fecf78946ae6d89dadc614e946",
|
||||||
|
"main.dart.js": "468dd28262bf65628c11ca1edbd0ee09",
|
||||||
|
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mn.png": "16086e8d89c9067d29fd0f2ea7021a45",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vi.png": "3f317c56f31971b3179abd4e03847036",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cv.png": "9b1f31f9fc0795d728328dedd33eb1c0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tv.png": "c57025ed7ae482210f29b9da86b0d211",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bo.png": "3ccf6fa7f9cbc27949b8418925e4e89c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ch.png": "a251702f7760b0aac141428ed60b7b66",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sl.png": "61b9d992c8a6a83abc4d432069617811",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ne.png": "a20724c177e86d6a27143aa9c9664a6f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ck.png": "39f343868a8dc8ca95d27b27a5caf480",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ve.png": "893391d65cbd10ca787a73578c77d3a7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lv.png": "53105fea0cc9cc554e0ceaabc53a2d5d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tz.png": "56ec99c7e0f68b88a2210620d873683a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ug.png": "9a0f358b1eb19863e21ae2063fab51c0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ma.png": "057ea2e08587f1361b3547556adae0c2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eh.png": "515a9cf2620c802e305b5412ac81aed2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/as.png": "d9c1da515c6f945c2e2554592a9dfaae",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/al.png": "722cf9e5c7a1d9c9e4608fb44dbb427d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pe.png": "4d9249aab70a26fadabb14380b3b55d2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lt.png": "7df2cd6566725685f7feb2051f916a3e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fo.png": "2c7d9233582e83a86927e634897a2a90",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cd.png": "5b5f832ed6cd9f9240cb31229d8763dc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ls.png": "2bca756f9313957347404557acb532b0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mw.png": "ffc1f18eeedc1dfbb1080aa985ce7d05",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kh.png": "d48d51e8769a26930da6edfc15de97fe",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mq.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ng.png": "aedbe364bd1543832e88e64b5817e877",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tg.png": "7f91f02b26b74899ff882868bd611714",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gr.png": "ec11281d7decbf07b81a23a72a609b59",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bn.png": "ed650de06fff61ff27ec92a872197948",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sc.png": "e969fd5afb1eb5902675b6bcf49a8c2e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kg.png": "c4aa6d221d9a9d332155518d6b82dbc7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/no.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ws.png": "f206322f3e22f175869869dbfadb6ce8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/er.png": "8ca78e10878a2e97c1371b38c5d258a7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cn.png": "040539c2cdb60ebd9dc8957cdc6a8ad0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/zw.png": "078a3267ea8eabf88b2d43fe4aed5ce5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sm.png": "a8d6801cb7c5360e18f0a2ed146b396d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gu.png": "2acb614b442e55864411b6e418df6eab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/am.png": "aaa39141fbc80205bebaa0200b55a13a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cr.png": "bfd8b41e63fc3cc829c72c4b2e170532",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/af.png": "ba710b50a060b5351381b55366396c30",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sg.png": "bc772e50b8c79f08f3c2189f5d8ce491",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kr.png": "a3b7da3b76b20a70e9cd63cc2315b51b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gt.png": "706a0c3b5e0b589c843e2539e813839e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/uy.png": "da4247b21fcbd9e30dc2b3f7c5dccb64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sn.png": "68eaa89bbc83b3f356e1ba2096b09b3c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/va.png": "c010bf145f695d5c8fb551bafc081f77",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/my.png": "f7f962e8a074387fd568c9d4024e0959",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cz.png": "73ecd64c6144786c4d03729b1dd9b1f3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mv.png": "d9245f74e34d5c054413ace4b86b4f16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bz.png": "fd2d7d27a5ddabe4eb9a10b1d3a433e4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lk.png": "5a3a063cfff4a92fb0ba6158e610e025",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ps.png": "52a25a48658ca9274830ffa124a8c1db",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cx.png": "8efa3231c8a3900a78f2b51d829f8c52",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb.png": "98773db151c150cabe845183241bfe6b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/wf.png": "6f1644b8f907d197c0ff7ed2f366ad64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cf.png": "263583ffdf7a888ce4fba8487d1da0b2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gs.png": "419dd57836797a3f1bf6258ea6589f9a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/au.png": "72be14316f0af3903cdca7a726c0c589",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/re.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ly.png": "8d65057351859065d64b4c118ff9e30e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lb.png": "f80cde345f0d9bd0086531808ce5166a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ca.png": "76f2fac1d3b2cc52ba6695c2e2941632",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ht.png": "630f7f8567d87409a32955107ad11a86",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dz.png": "132ceca353a95c8214676b2e94ecd40f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dm.png": "8886b222ed9ccd00f67e8bcf86dadcc2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kz.png": "cb3b0095281c9d7e7fb5ce1716ef8ee5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-nir.png": "98773db151c150cabe845183241bfe6b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bm.png": "b366ba84cbc8286c830f392bb9086be5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/si.png": "24237e53b34752554915e71e346bb405",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mg.png": "0ef6271ad284ebc0069ff0aeb5a3ad1e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mx.png": "84b12a569b209e213daccfcbdd1fc799",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/jp.png": "25ac778acd990bedcfdc02a9b4570045",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sv.png": "217b691efbef7a0f48cdd53e91997f0e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ee.png": "e242645cae28bd5291116ea211f9a566",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ga.png": "b0e5b2fa1b7106c7652a955db24c11c4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fr.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/to.png": "1cdd716b5b5502f85d6161dac6ee6c5b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nr.png": "1316f3a8a419d8be1975912c712535ea",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/jo.png": "c01cb41f74f9db0cf07ba20f0af83011",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pg.png": "0f7e03465a93e0b4e3e1c9d3dd5814a4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tn.png": "6612e9fec4bef022cbd45cbb7c02b2b6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bh.png": "a1acd86ef0e19ea5f0297bbe1de6cfd4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/zm.png": "81cec35b715f227328cad8f314acd797",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/xk.png": "079259fbcb1f3c78dafa944464295c16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ag.png": "41c11d5668c93ba6e452f811defdbb24",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sr.png": "9f912879f2829a625436ccd15e643e39",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gm.png": "7148d3715527544c2e7d8d6f4a445bb6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lu.png": "6274fd1cae3c7a425d25e4ccb0941bb8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/na.png": "cdc00e9267a873609b0abea944939ff7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ge.png": "6fbd41f07921fa415347ebf6dff5b0f7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fk.png": "da8b0fe48829aae2c8feb4839895de63",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cg.png": "eca97338cc1cb5b5e91bec72af57b3d4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gi.png": "446aa44aaa063d240adab88243b460d3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/is.png": "907840430252c431518005b562707831",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sa.png": "7c95c1a877148e2aa21a213d720ff4fd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/im.png": "7c9ccb825f0fca557d795c4330cf4f50",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eu.png": "c58ece3931acb87faadc5b940d4f7755",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ro.png": "85af99741fe20664d9a7112cfd8d9722",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/it.png": "5c8e910e6a33ec63dfcda6e8960dd19c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tf.png": "b2c044b86509e7960b5ba66b094ea285",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ai.png": "ce5e91ed1725f0499b9231b69a7fd448",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/np.png": "6e099fb1e063930bdd00e8df5cef73d4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tr.png": "27feab1a5ca390610d07e0c6bd4720d5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/om.png": "cebd9ab4b9ab071b2142e21ae2129efc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ad.png": "384e9845debe9aca8f8586d9bedcb7e6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nz.png": "65c811e96eb6c9da65538f899c110895",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/et.png": "57edff61c7fddf2761a19948acef1498",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/py.png": "154d4add03b4878caf00bd3249e14f40",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ss.png": "b0120cb000b31bb1a5c801c3592139bc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mr.png": "f2a62602d43a1ee14625af165b96ce2f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bq.png": "3649c177693bfee9c2fcc63c191a51f1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pl.png": "f20e9ef473a9ed24176f5ad74dd0d50a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-eng.png": "0d9f2a6775fd52b79e1d78eb1dda10cf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vn.png": "32ff65ccbf31a707a195be2a5141a89b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/aw.png": "a93ddf8e32d246dc47f6631f38e0ed92",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mh.png": "18dda388ef5c1cf37cae5e7d5fef39bc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mm.png": "32e5293d6029d8294c7dfc3c3835c222",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/es.png": "654965f9722f6706586476fb2f5d30dd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nu.png": "f4169998548e312584c67873e0d9352d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sb.png": "296ecedbd8d1c2a6422c3ba8e5cd54bd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-sct.png": "75106a5e49e3e16da76cb33bdac102ab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ci.png": "7f5ca3779d5ff6ce0c803a6efa0d2da7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/th.png": "11ce0c9f8c738fd217ea52b9bc29014b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pm.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mk.png": "835f2263974de523fa779d29c90595bf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gd.png": "7a4864ccfa2a0564041c2d1f8a13a8c9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bf.png": "63f1c67fca7ce8b52b3418a90af6ad37",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bd.png": "86a0e4bd8787dc8542137a407e0f987f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bg.png": "1d24bc616e3389684ed2c9f18bcb0209",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bi.png": "adda8121501f0543f1075244a1acc275",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ms.png": "9c955a926cf7d57fccb450a97192afa7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bj.png": "6fdc6449f73d23ad3f07060f92db4423",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ml.png": "0c50dfd539e87bb4313da0d4556e2d13",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sx.png": "9c19254973d8acf81581ad95b408c7e6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sk.png": "2a1ee716d4b41c017ff1dbf3fd3ffc64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mo.png": "849848a26bbfc87024017418ad7a6233",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pk.png": "7a6a621f7062589677b3296ca16c6718",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/se.png": "25dd5434891ac1ca2ad1af59cda70f80",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hm.png": "72be14316f0af3903cdca7a726c0c589",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ir.png": "37f67c3141e9843196cb94815be7bd37",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/je.png": "288f8dca26098e83ff0455b08cceca1b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ye.png": "4cf73209d90e9f02ead1565c8fdf59e5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sj.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/la.png": "e8cd9c3ee6e134adcbe3e986e1974e4a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gh.png": "b35464dca793fa33e51bf890b5f3d92b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kp.png": "e1c8bb52f31fca22d3368d8f492d8f27",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sd.png": "65ce270762dfc87475ea99bd18f79025",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dj.png": "078bd37d41f746c3cb2d84c1e9611c55",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pt.png": "eba93d33545c78cc67915d9be8323661",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/jm.png": "074400103847c56c37425a73f9d23665",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/yt.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/td.png": "009303b6188ca0e30bd50074b16f0b16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sz.png": "d1829842e45c2b2b29222c1b7e201591",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tj.png": "c73b793f2acd262e71b9236e64c77636",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kw.png": "3ca448e219d0df506fb2efd5b91be092",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gw.png": "05606b9a6393971bd87718b809e054f9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eg.png": "311d780e8e3dd43f87e6070f6feb74c7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nc.png": "cb36e0c945b79d56def11b23c6a9c7e9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/at.png": "570c070177a5ea0fe03e20107ebf5283",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vu.png": "3f201fdfb6d669a64c35c20a801016d1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ph.png": "e4025d1395a8455f1ba038597a95228c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lr.png": "b92c75e18dd97349c75d6a43bd17ee94",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cc.png": "31a475216e12fef447382c97b42876ce",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bb.png": "a8473747387e4e7a8450c499529f1c93",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/by.png": "beabf61e94fb3a4f7c7a7890488b213d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mz.png": "1ab1ac750fbbb453d33e9f25850ac2a0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mt.png": "f3119401ae0c3a9d6e2dc23803928c06",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mu.png": "c5228d1e94501d846b5bf203f038ae49",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lc.png": "8c1a03a592aa0a99fcaf2b81508a87eb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/us.png": "83b065848d14d33c0d10a13e01862f34",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hn.png": "9ecf68aed83c4a9b3f1e6275d96bfb04",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/rs.png": "9dff535d2d08c504be63062f39eff0b7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hr.png": "69711b2ea009a3e7c40045b538768d4e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hk.png": "4b5ec424348c98ec71a46ad3dce3931d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pa.png": "78e3e4fd56f0064837098fe3f22fb41b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ki.png": "14db0fc29398730064503907bd696176",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fm.png": "d571b8bc4b80980a81a5edbde788b6d2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ke.png": "cf5aae3699d3cacb39db9803edae172b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tm.png": "0980fb40ec450f70896f2c588510f933",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ba.png": "d415bad33b35de3f095177e8e86cbc82",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nf.png": "1c2069b299ce3660a2a95ec574dfde25",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tk.png": "60428ff1cdbae680e5a0b8cde4677dd5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ao.png": "5f0a372aa3aa7150a3dafea97acfc10d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/in.png": "1dec13ba525529cffd4c7f8a35d51121",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/br.png": "5093e0cd8fd3c094664cd17ea8a36fd1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pw.png": "2e697cc6907a7b94c7f94f5d9b3bdccc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ae.png": "792efc5eb6c31d780bd34bf4bad69f3f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/me.png": "590284bc85810635ace30a173e615ca4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nl.png": "3649c177693bfee9c2fcc63c191a51f1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cw.png": "6c598eb0d331d6b238da57055ec00d33",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bs.png": "2b9540c4fa514f71911a48de0bd77e71",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/km.png": "5554c8746c16d4f482986fb78ffd9b36",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sh.png": "98773db151c150cabe845183241bfe6b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tw.png": "b1101fd5f871a9ffe7c9ad191a7d3304",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/iq.png": "bc3e6f68c5188dbf99b473e2bea066f2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tt.png": "a8e1fc5c65dc8bc362a9453fadf9c4b3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hu.png": "281582a753e643b46bdd894047db08bb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/za.png": "b28280c6c3eb4624c18b5455d4a1b1ff",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pr.png": "b97b2f4432c430bc340d893f36527e31",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kn.png": "f318e2fd87e5fd2cabefe9ff252bba46",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/be.png": "7e5e1831cdd91935b38415479a7110eb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gl.png": "b79e24ee1889b7446ba3d65564b86810",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gp.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sy.png": "24186a0f4ce804a16c91592db5a16a3a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/qa.png": "eb9b3388e554cf85aea1e739247548df",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/st.png": "fef62c31713ff1063da2564df3f43eea",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cy.png": "7b36f4af86257a3f15f5a5a16f4a2fcd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ar.png": "3bd245f8c28f70c9ef9626dae27adc65",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bt.png": "3cfe1440e952bc7266d71f7f1454fa23",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/li.png": "ecdf7b3fe932378b110851674335d9ab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vc.png": "da3ca14a978717467abbcdece05d3544",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cm.png": "42d52fa71e8b4dbb182ff431749e8d0d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/aq.png": "0c586e7b91aa192758fdd0f03adb84d8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cl.png": "6735e0e2d88c119e9ed1533be5249ef1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cu.png": "f41715bd51f63a9aebf543788543b4c4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gq.png": "4286e56f388a37f64b21eb56550c06d9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ru.png": "6974dcb42ad7eb3add1009ea0c6003e3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bl.png": "dae94f5465d3390fdc5929e4f74d3f5f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gg.png": "eed435d25bd755aa7f9cd7004b9ed49d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mc.png": "90c2ad7f144d73d4650cbea9dd621275",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/io.png": "83d45bbbff087d47b2b39f1c20598f52",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ax.png": "ec2062c36f09ed8fb90ac8992d010024",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/co.png": "e3b1be16dcdae6cb72e9c238fdddce3c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/de.png": "5d9561246523cf6183928756fd605e25",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/do.png": "ed35983a9263bb5713be37d9a52caddc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ie.png": "1d91912afc591dd120b47b56ea78cdbf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dk.png": "abcd01bdbcc02b4a29cbac237f29cd1d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pn.png": "0b0641b356af4c3e3489192ff4b0be77",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gy.png": "159a260bf0217128ea7475ba5b272b6a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/so.png": "1ce20d052f9d057250be96f42647513b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/md.png": "8911d3d821b95b00abbba8771e997eb3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fj.png": "1c6a86752578eb132390febf12789cd6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vg.png": "fc095e11f5b58604d6f4d3c2b43d167f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/il.png": "1e06ad7783f24332405d36561024cc4c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ua.png": "b4b10d893611470661b079cb30473871",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ni.png": "e398dc23e79d9ccd702546cc25f126bf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tl.png": "c80876dc80cda5ab6bb8ef078bc6b05d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/rw.png": "d1aae0647a5b1ab977ae43ab894ce2c3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tc.png": "d728d6763c17c520ad6bcf3c24282a29",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bv.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bw.png": "fac8b90d7404728c08686dc39bab4fb3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/um.png": "8fe7c4fed0a065fdfb9bd3125c6ecaa1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gn.png": "b2287c03c88a72d968aa796a076ba056",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/id.png": "80bb82d11d5bc144a21042e77972bca9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/az.png": "6ffa766f6883d2d3d350cdc22a062ca3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ec.png": "c1ae60d080be91f3be31e92e0a2d9555",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/an.png": "4e4b90fbca1275d1839ca5b44fc51071",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mp.png": "87351c30a529071ee9a4bb67765fea4f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-wls.png": "d7d7c77c72cd425d993bdc50720f4d04",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/uz.png": "3adad3bac322220cac8abc1c7cbaacac",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ky.png": "38e39eba673e82c48a1f25bd103a7e97",
|
||||||
|
"assets/packages/window_manager/images/ic_chrome_close.png": "75f4b8ab3608a05461a31fc18d6b47c2",
|
||||||
|
"assets/packages/window_manager/images/ic_chrome_minimize.png": "4282cd84cb36edf2efb950ad9269ca62",
|
||||||
|
"assets/packages/window_manager/images/ic_chrome_maximize.png": "af7499d7657c8b69d23b85156b60298c",
|
||||||
|
"assets/packages/window_manager/images/ic_chrome_unmaximize.png": "4a90c1909cb74e8f0d35794e2f61d8bf",
|
||||||
|
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "3759b2f7a51e83c64a58cfe07b96a8ee",
|
||||||
|
"assets/shaders/ink_sparkle.frag": "ecc85a2e95f5e9f53123dcaf8cb9b6ce",
|
||||||
|
"assets/AssetManifest.bin.json": "611449d46e56c96b3baef404bfc56246",
|
||||||
|
"assets/fonts/MaterialIcons-Regular.otf": "a57618538ab8b4c4081d4491870ac333",
|
||||||
|
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||||
|
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||||
|
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||||
|
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||||
|
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
||||||
|
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||||
|
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
||||||
|
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||||
|
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||||
|
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||||
|
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||||
|
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||||
|
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||||
|
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
||||||
|
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
||||||
|
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||||
|
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||||
|
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
||||||
|
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||||
|
"assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4",
|
||||||
|
"assets/NOTICES": "412b336cf9e33e70058d612857effae1",
|
||||||
|
"assets/AssetManifest.bin": "bf3be26e7055ad9a32f66b3a56138224",
|
||||||
|
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
||||||
|
"flutter.js": "c71a09214cb6f5f8996a531350400a9a"};
|
||||||
// The application shell files that are downloaded before a service worker can
|
// The application shell files that are downloaded before a service worker can
|
||||||
// start.
|
// start.
|
||||||
const CORE = ["main.dart.js",
|
const CORE = ["main.dart.js",
|
||||||
|
176259
public/main.dart.js
vendored
176259
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
174895
public/main.foss.dart.js
vendored
174895
public/main.foss.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
16868
public/main.profile.dart.js
vendored
16868
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -171,15 +171,10 @@ class SquareCreditCard {
|
|||||||
document.querySelector('input[name=token]').value = '';
|
document.querySelector('input[name=token]').value = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
// let toggleWithToken = document.querySelector(
|
|
||||||
// '.toggle-payment-with-token'
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (!toggleWithToken) {
|
|
||||||
document.getElementById('loader').classList.add('hidden');
|
document.getElementById('loader').classList.add('hidden');
|
||||||
document.getElementById('payment-list').classList.remove('hidden');
|
document.getElementById('payment-list').classList.remove('hidden');
|
||||||
document.getElementById('toggle-payment-with-credit-card')?.click();
|
document.getElementById('toggle-payment-with-credit-card')?.click();
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => ''])
|
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' => ''])
|
||||||
|
@php
|
||||||
|
$gateway_instance = $gateway instanceof \App\Models\CompanyGateway ? $gateway : $gateway->company_gateway;
|
||||||
|
$token_billing_string = 'true';
|
||||||
|
|
||||||
|
if($gateway_instance->token_billing == 'off' || $gateway_instance->token_billing == 'optin'){
|
||||||
|
$token_billing_string = 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($pre_payment) && $pre_payment == '1' && isset($is_recurring) && $is_recurring == '1') {
|
||||||
|
$token_billing_string = 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@endphp
|
||||||
@section('gateway_head')
|
@section('gateway_head')
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
@ -12,7 +25,7 @@
|
|||||||
<input type="hidden" name="gateway_type_id" id="gateway_type_id" value="{{ $gateway_type_id }}">
|
<input type="hidden" name="gateway_type_id" id="gateway_type_id" value="{{ $gateway_type_id }}">
|
||||||
<input type="hidden" name="gateway_response" id="gateway_response">
|
<input type="hidden" name="gateway_response" id="gateway_response">
|
||||||
<input type="hidden" name="amount_with_fee" id="amount_with_fee" value="{{ $total['amount_with_fee'] }}"/>
|
<input type="hidden" name="amount_with_fee" id="amount_with_fee" value="{{ $total['amount_with_fee'] }}"/>
|
||||||
<input type="hidden" name="store_card" id="store_card">
|
<input type="hidden" name="store_card" id="store_card" value="{{ $token_billing_string }}">
|
||||||
<input type="hidden" name="token" value="" id="token">
|
<input type="hidden" name="token" value="" id="token">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@ -44,6 +57,7 @@
|
|||||||
<div id="checkout-form">
|
<div id="checkout-form">
|
||||||
<!-- Containers for Card Fields hosted by PayPal -->
|
<!-- Containers for Card Fields hosted by PayPal -->
|
||||||
<div id="card-number-field-container"></div>
|
<div id="card-number-field-container"></div>
|
||||||
|
<div id="card-name-field-container"></div>
|
||||||
<div class="expcvv" style="display:flex;">
|
<div class="expcvv" style="display:flex;">
|
||||||
<div id="card-expiry-field-container" style="width:50%"></div>
|
<div id="card-expiry-field-container" style="width:50%"></div>
|
||||||
<div id="card-cvv-field-container" style="width:50%"></div>
|
<div id="card-cvv-field-container" style="width:50%"></div>
|
||||||
@ -62,8 +76,12 @@
|
|||||||
|
|
||||||
@push('footer')
|
@push('footer')
|
||||||
<link rel="stylesheet" type="text/css" href=https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css />
|
<link rel="stylesheet" type="text/css" href=https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css />
|
||||||
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&components=card-fields" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
|
|
||||||
|
|
||||||
|
@if(isset($merchantId))
|
||||||
|
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&merchantId={!! $merchantId !!}&components=card-fields" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
|
||||||
|
@else
|
||||||
|
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&components=card-fields" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
|
||||||
|
@endif
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const clientId = "{{ $client_id }}";
|
const clientId = "{{ $client_id }}";
|
||||||
@ -129,9 +147,6 @@
|
|||||||
},
|
},
|
||||||
onError: function(error) {
|
onError: function(error) {
|
||||||
|
|
||||||
// console.log("on error")
|
|
||||||
// console.log(error);
|
|
||||||
|
|
||||||
document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`;
|
document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`;
|
||||||
document.getElementById('errors').hidden = false;
|
document.getElementById('errors').hidden = false;
|
||||||
|
|
||||||
@ -144,6 +159,9 @@
|
|||||||
|
|
||||||
// Render each field after checking for eligibility
|
// Render each field after checking for eligibility
|
||||||
if (cardField.isEligible()) {
|
if (cardField.isEligible()) {
|
||||||
|
|
||||||
|
const nameField = cardField.NameField();
|
||||||
|
nameField.render("#card-name-field-container");
|
||||||
|
|
||||||
const numberField = cardField.NumberField({
|
const numberField = cardField.NumberField({
|
||||||
inputEvents: {
|
inputEvents: {
|
||||||
@ -152,6 +170,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
numberField.render("#card-number-field-container");
|
numberField.render("#card-number-field-container");
|
||||||
|
|
||||||
const cvvField = cardField.CVVField({
|
const cvvField = cardField.CVVField({
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
namespace Tests\Integration\Einvoice;
|
namespace Tests\Integration\Einvoice;
|
||||||
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
use Sabre\Xml\Reader;
|
||||||
|
use Sabre\Xml\Service;
|
||||||
use Invoiceninja\Einvoice\Models\FACT1\Invoice;
|
use Invoiceninja\Einvoice\Models\FACT1\Invoice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,54 +22,182 @@ use Invoiceninja\Einvoice\Models\FACT1\Invoice;
|
|||||||
class FACT1Test extends TestCase
|
class FACT1Test extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public array $set = [];
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testValidationFact1()
|
public function testValidationFact1()
|
||||||
{
|
{
|
||||||
|
|
||||||
$files = [
|
$files = [
|
||||||
'tests/Integration/Einvoice/samples/fact1.xml',
|
'tests/Integration/Einvoice/samples/fact1_no_prefixes.xml',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($files as $f) {
|
foreach($files as $f) {
|
||||||
|
|
||||||
$xmlstring = file_get_contents($f);
|
$xml = file_get_contents($f);
|
||||||
|
|
||||||
// nlog($xmlstring);
|
$xml = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA);
|
||||||
|
|
||||||
$xml = simplexml_load_string($xmlstring, "SimpleXMLElement");
|
|
||||||
$json = json_encode($xml);
|
$json = json_encode($xml);
|
||||||
$payload = json_decode($json, true);
|
$array = json_decode($json, true);
|
||||||
|
|
||||||
nlog($xml);
|
$i = Invoice::from($array);
|
||||||
nlog($payload);
|
|
||||||
$validation_array = false;
|
$rules = Invoice::getValidationRules($array);
|
||||||
try {
|
|
||||||
$rules = Invoice::getValidationRules($payload);
|
|
||||||
nlog($rules);
|
|
||||||
|
|
||||||
$this->assertIsArray($rules);
|
$this->assertIsArray($rules);
|
||||||
|
|
||||||
$payload = Invoice::from($payload)->toArray();
|
|
||||||
nlog($payload);
|
|
||||||
$this->assertIsArray($payload);
|
|
||||||
|
|
||||||
$validation_array = Invoice::validate($payload);
|
$validation_array = Invoice::validate($array);
|
||||||
|
|
||||||
$this->assertIsArray($validation_array);
|
|
||||||
|
|
||||||
} catch(\Illuminate\Validation\ValidationException $e) {
|
|
||||||
|
|
||||||
nlog($e->errors());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertIsArray($validation_array);
|
$this->assertIsArray($validation_array);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function removeNamespacesFromArray($data)
|
||||||
|
{
|
||||||
|
if (is_array($data)) {
|
||||||
|
foreach ($data as &$item) {
|
||||||
|
if (isset($item['name'])) {
|
||||||
|
// Remove the namespace from the name
|
||||||
|
$item['name'] = preg_replace('/^\{\}(.+)/', '$1', $item['name']);
|
||||||
|
}
|
||||||
|
if (isset($item['value']) && is_array($item['value'])) {
|
||||||
|
// Recursively process child elements
|
||||||
|
$item['value'] = $this->removeNamespacesFromArray($item['value']);
|
||||||
|
}
|
||||||
|
if (isset($item['attributes'])) {
|
||||||
|
unset($item['attributes']);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// function convertToKeyValue($data)
|
||||||
|
// {
|
||||||
|
// $result = [];
|
||||||
|
// foreach ($data as $item) {
|
||||||
|
// // Remove namespace prefix if present
|
||||||
|
// $name = preg_replace('/^\{\}(.+)/', '$1', $item['name']);
|
||||||
|
// $result[$name] = $item['value'];
|
||||||
|
// }
|
||||||
|
// return $result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public function keyValueDeserializer(Reader $reader)
|
||||||
|
// {
|
||||||
|
// $values = [];
|
||||||
|
// $reader->read();
|
||||||
|
// $reader->next();
|
||||||
|
// foreach ($reader->parseGetElements() as $element) {
|
||||||
|
// // Strip the namespace prefix
|
||||||
|
// echo "merp".PHP_EOL;
|
||||||
|
// $name = preg_replace('/^\{\}.*/', '', $element['name']);
|
||||||
|
// $values[$name] = $element['value'];
|
||||||
|
// }
|
||||||
|
// return $values;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public function testFactToArray()
|
||||||
|
// {
|
||||||
|
|
||||||
|
// $xml = file_get_contents('tests/Integration/Einvoice/samples/fact1_no_prefixes.xml');
|
||||||
|
// $service = new Service();
|
||||||
|
|
||||||
|
// // $service->elementMap = [
|
||||||
|
// // '{}' => 'Sabre\Xml\Deserializer\keyValue',
|
||||||
|
// // ];
|
||||||
|
|
||||||
|
// // $service->elementMap = [
|
||||||
|
// // '{}*' => function (Reader $reader) use ($service) {
|
||||||
|
// // return $this->keyValueDeserializer($reader);
|
||||||
|
// // }
|
||||||
|
// // ];
|
||||||
|
|
||||||
|
|
||||||
|
// $result = $this->removeNamespacesFromArray($service->parse($xml));
|
||||||
|
|
||||||
|
|
||||||
|
// // Convert parsed XML to key-value array
|
||||||
|
// if (isset($result['value']) && is_array($result['value'])) {
|
||||||
|
// $keyValueArray = $this->convertToKeyValue($result['value']);
|
||||||
|
// } else {
|
||||||
|
// $keyValueArray = [];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Output the result
|
||||||
|
// nlog($keyValueArray);
|
||||||
|
|
||||||
|
|
||||||
|
// // nlog($cleanedArray);
|
||||||
|
// nlog($service->parse($xml));
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Output the result
|
||||||
|
// ($xmlWithoutNamespaces);
|
||||||
|
|
||||||
|
// $reader = new Reader();
|
||||||
|
// $service = new Service();
|
||||||
|
|
||||||
|
// $service->elementMap = [
|
||||||
|
// '*' => 'Sabre\Xml\Deserializer\keyValue',
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// nlog($service->parse($xmlstring));
|
||||||
|
|
||||||
|
// $payload ='';
|
||||||
|
|
||||||
|
// // $reader->xml($xmlstring);
|
||||||
|
// // $payload = $reader->parse();
|
||||||
|
|
||||||
|
// // nlog($payload);
|
||||||
|
// $validation_array = false;
|
||||||
|
// try {
|
||||||
|
// $rules = Invoice::getValidationRules($payload);
|
||||||
|
// nlog($rules);
|
||||||
|
|
||||||
|
// $this->assertIsArray($rules);
|
||||||
|
|
||||||
|
// $payload = Invoice::from($payload)->toArray();
|
||||||
|
// nlog($payload);
|
||||||
|
// $this->assertIsArray($payload);
|
||||||
|
|
||||||
|
// $validation_array = Invoice::validate($payload);
|
||||||
|
|
||||||
|
// $this->assertIsArray($validation_array);
|
||||||
|
|
||||||
|
// } catch(\Illuminate\Validation\ValidationException $e) {
|
||||||
|
|
||||||
|
// nlog($e->errors());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $this->assertIsArray($validation_array);
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private function extractName($name): string
|
||||||
|
// {
|
||||||
|
|
||||||
|
// $pattern = '/\{[^{}]*\}([^{}]*)/';
|
||||||
|
|
||||||
|
// if (preg_match($pattern, $name, $matches)) {
|
||||||
|
// $extracted = $matches[1];
|
||||||
|
// return $extracted;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $name;
|
||||||
|
// }
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
113
tests/Integration/Einvoice/samples/fact1_no_prefixes.xml
Normal file
113
tests/Integration/Einvoice/samples/fact1_no_prefixes.xml
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<Invoice>
|
||||||
|
<UBLVersionID>2.1</UBLVersionID>
|
||||||
|
<CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:efactura.mfinante.ro:CIUS-RO:1.0.1</CustomizationID>
|
||||||
|
<ID>ABC 0020</ID>
|
||||||
|
<IssueDate>2024-01-01</IssueDate>
|
||||||
|
<DueDate>2024-01-15</DueDate>
|
||||||
|
<InvoiceTypeCode>384</InvoiceTypeCode>
|
||||||
|
<DocumentCurrencyCode>RON</DocumentCurrencyCode>
|
||||||
|
<TaxCurrencyCode>RON</TaxCurrencyCode>
|
||||||
|
<AccountingSupplierParty>
|
||||||
|
<Party>
|
||||||
|
<PartyIdentification>
|
||||||
|
<ID>234234234</ID>
|
||||||
|
</PartyIdentification>
|
||||||
|
<PostalAddress>
|
||||||
|
<StreetName>This can be the full address , not just the street and street nr.</StreetName>
|
||||||
|
<CityName>SECTOR2</CityName>
|
||||||
|
<CountrySubentity>RO-B</CountrySubentity>
|
||||||
|
<Country>
|
||||||
|
<IdentificationCode>RO</IdentificationCode>
|
||||||
|
</Country>
|
||||||
|
</PostalAddress>
|
||||||
|
<PartyTaxScheme>
|
||||||
|
<CompanyID>RO234234234</CompanyID>
|
||||||
|
<TaxScheme>
|
||||||
|
<ID>VAT</ID>
|
||||||
|
</TaxScheme>
|
||||||
|
</PartyTaxScheme>
|
||||||
|
<PartyLegalEntity>
|
||||||
|
<RegistrationName>Some Copany Name</RegistrationName>
|
||||||
|
<CompanyID>J40/2222/2009</CompanyID>
|
||||||
|
</PartyLegalEntity>
|
||||||
|
<Contact>
|
||||||
|
<Name>Someone</Name>
|
||||||
|
<Telephone>88282819832</Telephone>
|
||||||
|
<ElectronicMail>some@email.com</ElectronicMail>
|
||||||
|
</Contact>
|
||||||
|
</Party>
|
||||||
|
</AccountingSupplierParty>
|
||||||
|
<AccountingCustomerParty>
|
||||||
|
<Party>
|
||||||
|
<PartyIdentification>
|
||||||
|
<ID>646546549</ID>
|
||||||
|
</PartyIdentification>
|
||||||
|
<PostalAddress>
|
||||||
|
<StreetName>This can be the full address , not just the street and street nr.</StreetName>
|
||||||
|
<CityName>SECTOR3</CityName>
|
||||||
|
<CountrySubentity>RO-B</CountrySubentity>
|
||||||
|
<Country>
|
||||||
|
<IdentificationCode>RO</IdentificationCode>
|
||||||
|
</Country>
|
||||||
|
</PostalAddress>
|
||||||
|
<PartyLegalEntity>
|
||||||
|
<RegistrationName>Some Comapny</RegistrationName>
|
||||||
|
<CompanyID>646546549</CompanyID>
|
||||||
|
</PartyLegalEntity>
|
||||||
|
<Contact>
|
||||||
|
<Name>Someone</Name>
|
||||||
|
<Telephone>88282819832</Telephone>
|
||||||
|
<ElectronicMail>some@email.com</ElectronicMail>
|
||||||
|
</Contact>
|
||||||
|
</Party>
|
||||||
|
</AccountingCustomerParty>
|
||||||
|
<PaymentMeans>
|
||||||
|
<PaymentMeansCode>42</PaymentMeansCode>
|
||||||
|
<PayeeFinancialAccount>
|
||||||
|
<ID>some account nr</ID>
|
||||||
|
<Name>Bank name</Name>
|
||||||
|
</PayeeFinancialAccount>
|
||||||
|
</PaymentMeans>
|
||||||
|
<TaxTotal>
|
||||||
|
<TaxAmount currencyID="RON">63.65</TaxAmount>
|
||||||
|
<TaxSubtotal>
|
||||||
|
<TaxableAmount currencyID="RON">335.00</TaxableAmount>
|
||||||
|
<TaxAmount currencyID="RON">63.65</TaxAmount>
|
||||||
|
<TaxCategory>
|
||||||
|
<ID>S</ID> // this is a speciffic identifier for the VAT type <Percent>
|
||||||
|
19</Percent>
|
||||||
|
<TaxScheme>
|
||||||
|
<ID>VAT</ID>
|
||||||
|
</TaxScheme>
|
||||||
|
</TaxCategory>
|
||||||
|
</TaxSubtotal>
|
||||||
|
</TaxTotal>
|
||||||
|
<LegalMonetaryTotal>
|
||||||
|
<LineExtensionAmount currencyID="RON">335.00</LineExtensionAmount>
|
||||||
|
<TaxExclusiveAmount currencyID="RON">335.00</TaxExclusiveAmount>
|
||||||
|
<TaxInclusiveAmount currencyID="RON">398.65</TaxInclusiveAmount>
|
||||||
|
<AllowanceTotalAmount currencyID="RON">0.00</AllowanceTotalAmount>
|
||||||
|
<PayableAmount currencyID="RON">398.65</PayableAmount>
|
||||||
|
</LegalMonetaryTotal>
|
||||||
|
<InvoiceLine>
|
||||||
|
<ID>1</ID>
|
||||||
|
<InvoicedQuantity unitCode="H87">1</InvoicedQuantity> // unitcode is a speciffic
|
||||||
|
identifier for the type of product <LineExtensionAmount currencyID="RON">
|
||||||
|
335.00</LineExtensionAmount>
|
||||||
|
<Item>
|
||||||
|
<Description>Some Description</Description>
|
||||||
|
<Name>Some product</Name>
|
||||||
|
<ClassifiedTaxCategory>
|
||||||
|
<ID>S</ID> // this is a speciffic identifier for the VAT type <Percent>
|
||||||
|
19</Percent>
|
||||||
|
<TaxScheme>
|
||||||
|
<ID>VAT</ID>
|
||||||
|
</TaxScheme>
|
||||||
|
</ClassifiedTaxCategory>
|
||||||
|
</Item>
|
||||||
|
<Price>
|
||||||
|
<PriceAmount currencyID="RON">335</PriceAmount>
|
||||||
|
</Price>
|
||||||
|
</InvoiceLine>
|
||||||
|
</Invoice>
|
Loading…
x
Reference in New Issue
Block a user