mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 01:47:32 -05:00 
			
		
		
		
	Add Support for Klarna
This commit is contained in:
		
							parent
							
								
									9a08eb0940
								
							
						
					
					
						commit
						701344947f
					
				@ -134,13 +134,14 @@ class Gateway extends StaticModel
 | 
				
			|||||||
                    GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']],
 | 
					                    GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']],
 | 
				
			||||||
                ];
 | 
					                ];
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 56:
 | 
					            case 56: //Stripe
 | 
				
			||||||
                return [
 | 
					                return [
 | 
				
			||||||
                    GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => ['payment_intent.succeeded']],
 | 
					                    GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => ['payment_intent.succeeded']],
 | 
				
			||||||
                    GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
					                    GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
				
			||||||
                    GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
 | 
					                    GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
 | 
				
			||||||
                    GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false],
 | 
					                    GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false],
 | 
				
			||||||
                    GatewayType::SOFORT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], //Stripe
 | 
					                    GatewayType::SOFORT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
 | 
					                    GatewayType::KLARNA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
                    GatewayType::SEPA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
					                    GatewayType::SEPA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
                    GatewayType::PRZELEWY24 => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
					                    GatewayType::PRZELEWY24 => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
                    GatewayType::GIROPAY => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
					                    GatewayType::GIROPAY => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,8 @@ class GatewayType extends StaticModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const FPX = 22;
 | 
					    const FPX = 22;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const KLARNA = 23;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function gateway()
 | 
					    public function gateway()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->belongsTo(Gateway::class);
 | 
					        return $this->belongsTo(Gateway::class);
 | 
				
			||||||
@ -116,6 +118,8 @@ class GatewayType extends StaticModel
 | 
				
			|||||||
                return ctrans('texts.payment_type_instant_bank_pay');
 | 
					                return ctrans('texts.payment_type_instant_bank_pay');
 | 
				
			||||||
            case self::FPX:
 | 
					            case self::FPX:
 | 
				
			||||||
                return ctrans('texts.fpx');
 | 
					                return ctrans('texts.fpx');
 | 
				
			||||||
 | 
					            case self::KLARNA:
 | 
				
			||||||
 | 
					                return ctrans('texts.klarna');
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return ' ';
 | 
					                return ' ';
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,7 @@ class PaymentType extends StaticModel
 | 
				
			|||||||
    const ACSS = 44;
 | 
					    const ACSS = 44;
 | 
				
			||||||
    const INSTANT_BANK_PAY = 45;
 | 
					    const INSTANT_BANK_PAY = 45;
 | 
				
			||||||
    const FPX = 46;
 | 
					    const FPX = 46;
 | 
				
			||||||
 | 
					    const KLARNA = 47;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function parseCardType($cardName)
 | 
					    public static function parseCardType($cardName)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										154
									
								
								app/PaymentDrivers/Stripe/Klarna.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								app/PaymentDrivers/Stripe/Klarna.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\PaymentDrivers\Stripe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Exceptions\PaymentFailed;
 | 
				
			||||||
 | 
					use App\Jobs\Util\SystemLogger;
 | 
				
			||||||
 | 
					use App\Models\GatewayType;
 | 
				
			||||||
 | 
					use App\Models\Payment;
 | 
				
			||||||
 | 
					use App\Models\PaymentType;
 | 
				
			||||||
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
 | 
					use App\PaymentDrivers\StripePaymentDriver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Klarna
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /** @var StripePaymentDriver */
 | 
				
			||||||
 | 
					    public StripePaymentDriver $stripe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(StripePaymentDriver $stripe)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->stripe = $stripe;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function authorizeView($data)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return render('gateways.stripe.klarna.authorize', $data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function paymentView(array $data)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->stripe->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data['gateway'] = $this->stripe;
 | 
				
			||||||
 | 
					        $data['return_url'] = $this->buildReturnUrl();
 | 
				
			||||||
 | 
					        $data['stripe_amount'] = $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency());
 | 
				
			||||||
 | 
					        $data['client'] = $this->stripe->client;
 | 
				
			||||||
 | 
					        $data['customer'] = $this->stripe->findOrCreateCustomer()->id;
 | 
				
			||||||
 | 
					        $data['country'] = $this->stripe->client->country->iso_3166_2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $amount = $data['total']['amount_with_fee'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoice_numbers = collect($data['invoices'])->pluck('invoice_number');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($invoice_numbers.length > 0) {
 | 
				
			||||||
 | 
					            $description = ctrans('texts.payment_provider_paymenttext', ['invoicenumber' => $invoice_numbers->implode(', '), 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $description = ctrans('texts.payment_prvoder_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $intent = \Stripe\PaymentIntent::create([
 | 
				
			||||||
 | 
					            'amount' => $data['stripe_amount'],
 | 
				
			||||||
 | 
					            'currency' => 'eur',
 | 
				
			||||||
 | 
					            'payment_method_types' => ['klarna'],
 | 
				
			||||||
 | 
					            'customer' => $this->stripe->findOrCreateCustomer(),
 | 
				
			||||||
 | 
					            'description' => $description,
 | 
				
			||||||
 | 
					            'metadata' => [
 | 
				
			||||||
 | 
					                'payment_hash' => $this->stripe->payment_hash->hash,
 | 
				
			||||||
 | 
					                'gateway_type_id' => GatewayType::GIROPAY,
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ], $this->stripe->stripe_connect_auth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data['pi_client_secret'] = $intent->client_secret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['stripe_amount' => $data['stripe_amount']]);
 | 
				
			||||||
 | 
					        $this->stripe->payment_hash->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return render('gateways.stripe.klarna.pay', $data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function buildReturnUrl(): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return route('client.payments.response', [
 | 
				
			||||||
 | 
					            'company_gateway_id' => $this->stripe->company_gateway->id,
 | 
				
			||||||
 | 
					            'payment_hash' => $this->stripe->payment_hash->hash,
 | 
				
			||||||
 | 
					            'payment_method_id' => GatewayType::KLARNA,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function paymentResponse($request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, $request->all());
 | 
				
			||||||
 | 
					        $this->stripe->payment_hash->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array($request->redirect_status,  ['succeeded','pending'])) {
 | 
				
			||||||
 | 
					            return $this->processSuccessfulPayment($request->payment_intent);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->processUnsuccessfulPayment();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processSuccessfulPayment(string $payment_intent)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->stripe->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //catch duplicate submissions.
 | 
				
			||||||
 | 
					        if (Payment::where('transaction_reference', $payment_intent)->exists()) {
 | 
				
			||||||
 | 
					            return redirect()->route('client.payments.index');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'payment_method' => $payment_intent,
 | 
				
			||||||
 | 
					            'payment_type' => PaymentType::GIROPAY,
 | 
				
			||||||
 | 
					            'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
 | 
				
			||||||
 | 
					            'transaction_reference' => $payment_intent,
 | 
				
			||||||
 | 
					            'gateway_type_id' => GatewayType::KLARNA,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->stripe->createPayment($data, Payment::STATUS_PENDING);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SystemLogger::dispatch(
 | 
				
			||||||
 | 
					            ['response' => $this->stripe->payment_hash->data, 'data' => $data],
 | 
				
			||||||
 | 
					            SystemLog::CATEGORY_GATEWAY_RESPONSE,
 | 
				
			||||||
 | 
					            SystemLog::EVENT_GATEWAY_SUCCESS,
 | 
				
			||||||
 | 
					            SystemLog::TYPE_STRIPE,
 | 
				
			||||||
 | 
					            $this->stripe->client,
 | 
				
			||||||
 | 
					            $this->stripe->client->company,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return redirect()->route('client.payments.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function processUnsuccessfulPayment()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $server_response = $this->stripe->payment_hash->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->stripe->sendFailureMail($server_response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $message = [
 | 
				
			||||||
 | 
					            'server_response' => $server_response,
 | 
				
			||||||
 | 
					            'data' => $this->stripe->payment_hash->data,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SystemLogger::dispatch(
 | 
				
			||||||
 | 
					            $message,
 | 
				
			||||||
 | 
					            SystemLog::CATEGORY_GATEWAY_RESPONSE,
 | 
				
			||||||
 | 
					            SystemLog::EVENT_GATEWAY_FAILURE,
 | 
				
			||||||
 | 
					            SystemLog::TYPE_STRIPE,
 | 
				
			||||||
 | 
					            $this->stripe->client,
 | 
				
			||||||
 | 
					            $this->stripe->client->company,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        throw new PaymentFailed(ctrans('texts.payment_provider_failed_process_payment'), 500);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -410,7 +410,7 @@ class StripePaymentDriver extends BaseDriver
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->init();
 | 
					        $this->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $params = [];
 | 
					        $params = ['usage' => 'off_session'];
 | 
				
			||||||
        $meta = $this->stripe_connect_auth;
 | 
					        $meta = $this->stripe_connect_auth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return SetupIntent::create($params, $meta);
 | 
					        return SetupIntent::create($params, $meta);
 | 
				
			||||||
@ -669,14 +669,22 @@ class StripePaymentDriver extends BaseDriver
 | 
				
			|||||||
                ], $this->stripe_connect_auth);
 | 
					                ], $this->stripe_connect_auth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ($charge->captured) {
 | 
					                if ($charge->captured) {
 | 
				
			||||||
                    $payment = Payment::query()
 | 
					
 | 
				
			||||||
                        ->where('transaction_reference', $transaction['payment_intent'])
 | 
					                    $payment = false;
 | 
				
			||||||
                        ->where('company_id', $request->getCompany()->id)
 | 
					
 | 
				
			||||||
                        ->where(function ($query) use ($transaction) {
 | 
					                    if(isset($transaction['payment_intent']))
 | 
				
			||||||
                            $query->where('transaction_reference', $transaction['payment_intent'])
 | 
					                    {
 | 
				
			||||||
                                  ->orWhere('transaction_reference', $transaction['id']);
 | 
					                        $payment = Payment::query()
 | 
				
			||||||
                        })
 | 
					                            ->where('transaction_reference', $transaction['payment_intent'])
 | 
				
			||||||
                        ->first();
 | 
					                            ->where('company_id', $request->getCompany()->id)
 | 
				
			||||||
 | 
					                            ->first();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    elseif(isset($transaction['id'])) {
 | 
				
			||||||
 | 
					                        $payment = Payment::query()
 | 
				
			||||||
 | 
					                            ->where('transaction_reference', $transaction['id'])
 | 
				
			||||||
 | 
					                            ->where('company_id', $request->getCompany()->id)
 | 
				
			||||||
 | 
					                            ->first();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if ($payment) {
 | 
					                    if ($payment) {
 | 
				
			||||||
                        $payment->status_id = Payment::STATUS_COMPLETED;
 | 
					                        $payment->status_id = Payment::STATUS_COMPLETED;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								database/migrations/2022_05_12_56879_add_stripe_klarna.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								database/migrations/2022_05_12_56879_add_stripe_klarna.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\GatewayType;
 | 
				
			||||||
 | 
					use App\Models\PaymentType;
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return new class extends Migration {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('payment_types', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $type = new PaymentType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $type->id = 47;
 | 
				
			||||||
 | 
					            $type->name = 'Klarna';
 | 
				
			||||||
 | 
					            $type->gateway_type_id = GatewayType::KLARNA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $type->save();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        $type = new GatewayType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $type->id = 23;
 | 
				
			||||||
 | 
					        $type->alias = 'klarna';
 | 
				
			||||||
 | 
					        $type->name = 'Klarna';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $type->save();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -2822,11 +2822,11 @@ $LANG = array(
 | 
				
			|||||||
    'invalid_url' => 'Invalid URL',
 | 
					    'invalid_url' => 'Invalid URL',
 | 
				
			||||||
    'workflow_settings' => 'Workflow Settings',
 | 
					    'workflow_settings' => 'Workflow Settings',
 | 
				
			||||||
    'auto_email_invoice' => 'Auto Email',
 | 
					    'auto_email_invoice' => 'Auto Email',
 | 
				
			||||||
    'auto_email_invoice_help' => 'Automatically email recurring invoices when they are created.',
 | 
					    'auto_email_invoice_help' => 'Automatically email recurring invoices when created.',
 | 
				
			||||||
    'auto_archive_invoice' => 'Auto Archive',
 | 
					    'auto_archive_invoice' => 'Auto Archive',
 | 
				
			||||||
    'auto_archive_invoice_help' => 'Automatically archive invoices when they are paid.',
 | 
					    'auto_archive_invoice_help' => 'Automatically archive invoices when paid.',
 | 
				
			||||||
    'auto_archive_quote' => 'Auto Archive',
 | 
					    'auto_archive_quote' => 'Auto Archive',
 | 
				
			||||||
    'auto_archive_quote_help' => 'Automatically archive quotes when they are converted.',
 | 
					    'auto_archive_quote_help' => 'Automatically archive quotes when converted to invoice.',
 | 
				
			||||||
    'require_approve_quote' => 'Require approve quote',
 | 
					    'require_approve_quote' => 'Require approve quote',
 | 
				
			||||||
    'require_approve_quote_help' => 'Require clients to approve quotes.',
 | 
					    'require_approve_quote_help' => 'Require clients to approve quotes.',
 | 
				
			||||||
    'allow_approve_expired_quote' => 'Allow approve expired quote',
 | 
					    'allow_approve_expired_quote' => 'Allow approve expired quote',
 | 
				
			||||||
@ -3414,7 +3414,7 @@ $LANG = array(
 | 
				
			|||||||
    'credit_number_counter' => 'Credit Number Counter',
 | 
					    'credit_number_counter' => 'Credit Number Counter',
 | 
				
			||||||
    'reset_counter_date' => 'Reset Counter Date',
 | 
					    'reset_counter_date' => 'Reset Counter Date',
 | 
				
			||||||
    'counter_padding' => 'Counter Padding',
 | 
					    'counter_padding' => 'Counter Padding',
 | 
				
			||||||
    'shared_invoice_quote_counter' => 'Shared Invoice Quote Counter',
 | 
					    'shared_invoice_quote_counter' => 'Share Invoice Quote Counter',
 | 
				
			||||||
    'default_tax_name_1' => 'Default Tax Name 1',
 | 
					    'default_tax_name_1' => 'Default Tax Name 1',
 | 
				
			||||||
    'default_tax_rate_1' => 'Default Tax Rate 1',
 | 
					    'default_tax_rate_1' => 'Default Tax Rate 1',
 | 
				
			||||||
    'default_tax_name_2' => 'Default Tax Name 2',
 | 
					    'default_tax_name_2' => 'Default Tax Name 2',
 | 
				
			||||||
@ -3688,7 +3688,7 @@ $LANG = array(
 | 
				
			|||||||
    'force_update_help' => 'You are running the latest version but there may be pending fixes available.',
 | 
					    'force_update_help' => 'You are running the latest version but there may be pending fixes available.',
 | 
				
			||||||
    'mark_paid_help' => 'Track the expense has been paid',
 | 
					    'mark_paid_help' => 'Track the expense has been paid',
 | 
				
			||||||
    'mark_invoiceable_help' => 'Enable the expense to be invoiced',
 | 
					    'mark_invoiceable_help' => 'Enable the expense to be invoiced',
 | 
				
			||||||
    'add_documents_to_invoice_help' => 'Make the documents visible',
 | 
					    'add_documents_to_invoice_help' => 'Make the documents visible to client',
 | 
				
			||||||
    'convert_currency_help' => 'Set an exchange rate',
 | 
					    'convert_currency_help' => 'Set an exchange rate',
 | 
				
			||||||
    'expense_settings' => 'Expense Settings',
 | 
					    'expense_settings' => 'Expense Settings',
 | 
				
			||||||
    'clone_to_recurring' => 'Clone to Recurring',
 | 
					    'clone_to_recurring' => 'Clone to Recurring',
 | 
				
			||||||
@ -4061,7 +4061,7 @@ $LANG = array(
 | 
				
			|||||||
     'save_payment_method_details' => 'Save payment method details',
 | 
					     'save_payment_method_details' => 'Save payment method details',
 | 
				
			||||||
     'new_card' => 'New card',
 | 
					     'new_card' => 'New card',
 | 
				
			||||||
     'new_bank_account' => 'New bank account',
 | 
					     'new_bank_account' => 'New bank account',
 | 
				
			||||||
     'company_limit_reached' => 'Limit of 10 companies per account.',
 | 
					     'company_limit_reached' => 'Limit of :limit companies per account.',
 | 
				
			||||||
     'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
 | 
					     'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
 | 
				
			||||||
     'credit_number_taken' => 'Credit number already taken',
 | 
					     'credit_number_taken' => 'Credit number already taken',
 | 
				
			||||||
     'credit_not_found' => 'Credit not found',
 | 
					     'credit_not_found' => 'Credit not found',
 | 
				
			||||||
@ -4199,7 +4199,7 @@ $LANG = array(
 | 
				
			|||||||
     'client_id_number' => 'Client ID Number',
 | 
					     'client_id_number' => 'Client ID Number',
 | 
				
			||||||
     'count_minutes' => ':count Minutes',
 | 
					     'count_minutes' => ':count Minutes',
 | 
				
			||||||
     'password_timeout' => 'Password Timeout',
 | 
					     'password_timeout' => 'Password Timeout',
 | 
				
			||||||
     'shared_invoice_credit_counter' => 'Shared Invoice/Credit Counter',
 | 
					     'shared_invoice_credit_counter' => 'Share Invoice/Credit Counter',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'activity_80' => ':user created subscription :subscription',
 | 
					    'activity_80' => ':user created subscription :subscription',
 | 
				
			||||||
    'activity_81' => ':user updated subscription :subscription',
 | 
					    'activity_81' => ':user updated subscription :subscription',
 | 
				
			||||||
@ -4219,7 +4219,7 @@ $LANG = array(
 | 
				
			|||||||
    'max_companies_desc' => 'You have reached your maximum number of companies. Delete existing companies to migrate new ones.',
 | 
					    'max_companies_desc' => 'You have reached your maximum number of companies. Delete existing companies to migrate new ones.',
 | 
				
			||||||
    'migration_already_completed' => 'Company already migrated',
 | 
					    'migration_already_completed' => 'Company already migrated',
 | 
				
			||||||
    'migration_already_completed_desc' => 'Looks like you already migrated <b> :company_name </b>to the V5 version of the Invoice Ninja. In case you want to start over, you can force migrate to wipe existing data.',
 | 
					    'migration_already_completed_desc' => 'Looks like you already migrated <b> :company_name </b>to the V5 version of the Invoice Ninja. In case you want to start over, you can force migrate to wipe existing data.',
 | 
				
			||||||
    'payment_method_cannot_be_authorized_first' => 'This payment method can be can saved for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.',
 | 
					    'payment_method_cannot_be_authorized_first' => 'This payment method can be can saved for future use, once you complete your first transaction. Don\'t forget to check "Store details" during payment process.',
 | 
				
			||||||
    'new_account' => 'New account',
 | 
					    'new_account' => 'New account',
 | 
				
			||||||
    'activity_100' => ':user created recurring invoice :recurring_invoice',
 | 
					    'activity_100' => ':user created recurring invoice :recurring_invoice',
 | 
				
			||||||
    'activity_101' => ':user updated recurring invoice :recurring_invoice',
 | 
					    'activity_101' => ':user updated recurring invoice :recurring_invoice',
 | 
				
			||||||
@ -4254,7 +4254,7 @@ $LANG = array(
 | 
				
			|||||||
    'auto_bill_disabled' => 'Auto Bill Disabled',
 | 
					    'auto_bill_disabled' => 'Auto Bill Disabled',
 | 
				
			||||||
    'select_payment_method' => 'Select a payment method:',
 | 
					    'select_payment_method' => 'Select a payment method:',
 | 
				
			||||||
    'login_without_password' => 'Log in without password',
 | 
					    'login_without_password' => 'Log in without password',
 | 
				
			||||||
    'email_sent' => 'E-mail sent, please check your inbox.',
 | 
					    'email_sent' => 'Email me when an invoice is <b>sent</b>',
 | 
				
			||||||
    'one_time_purchases' => 'One time purchases',
 | 
					    'one_time_purchases' => 'One time purchases',
 | 
				
			||||||
    'recurring_purchases' => 'Recurring purchases',
 | 
					    'recurring_purchases' => 'Recurring purchases',
 | 
				
			||||||
    'you_might_be_interested_in_following' => 'You might be interested in the following',
 | 
					    'you_might_be_interested_in_following' => 'You might be interested in the following',
 | 
				
			||||||
@ -4540,7 +4540,7 @@ $LANG = array(
 | 
				
			|||||||
    'reminder_message' => 'Reminder for invoice :number for :balance',
 | 
					    'reminder_message' => 'Reminder for invoice :number for :balance',
 | 
				
			||||||
    'gmail_credentials_invalid_subject' => 'Send with GMail invalid credentials',
 | 
					    'gmail_credentials_invalid_subject' => 'Send with GMail invalid credentials',
 | 
				
			||||||
    'gmail_credentials_invalid_body' => 'Your GMail credentials are not correct, please log into the administrator portal and navigate to Settings > User Details and disconnect and reconnect your GMail account. We will send you this notification daily until this issue is resolved',
 | 
					    'gmail_credentials_invalid_body' => 'Your GMail credentials are not correct, please log into the administrator portal and navigate to Settings > User Details and disconnect and reconnect your GMail account. We will send you this notification daily until this issue is resolved',
 | 
				
			||||||
    'notification_invoice_sent' => 'Invoice Sent',
 | 
					    'notification_invoice_sent' => 'The following client :client was emailed Invoice :invoice for :amount.',
 | 
				
			||||||
    'total_columns' => 'Total Fields',
 | 
					    'total_columns' => 'Total Fields',
 | 
				
			||||||
    'view_task' => 'View Task',
 | 
					    'view_task' => 'View Task',
 | 
				
			||||||
    'cancel_invoice' => 'Cancel',
 | 
					    'cancel_invoice' => 'Cancel',
 | 
				
			||||||
@ -4573,13 +4573,13 @@ $LANG = array(
 | 
				
			|||||||
    'tax_amount3' => 'Tax Amount 3',
 | 
					    'tax_amount3' => 'Tax Amount 3',
 | 
				
			||||||
    'update_project' => 'Update Project',
 | 
					    'update_project' => 'Update Project',
 | 
				
			||||||
    'auto_archive_invoice_cancelled' => 'Auto Archive Cancelled Invoice',
 | 
					    'auto_archive_invoice_cancelled' => 'Auto Archive Cancelled Invoice',
 | 
				
			||||||
    'auto_archive_invoice_cancelled_help' => 'Automatically archive invoices when they are cancelled',
 | 
					    'auto_archive_invoice_cancelled_help' => 'Automatically archive invoices when cancelled',
 | 
				
			||||||
    'no_invoices_found' => 'No invoices found',
 | 
					    'no_invoices_found' => 'No invoices found',
 | 
				
			||||||
    'created_record' => 'Successfully created record',
 | 
					    'created_record' => 'Successfully created record',
 | 
				
			||||||
    'auto_archive_paid_invoices' => 'Auto Archive Paid',
 | 
					    'auto_archive_paid_invoices' => 'Auto Archive Paid',
 | 
				
			||||||
    'auto_archive_paid_invoices_help' => 'Automatically archive invoices when they are paid.',
 | 
					    'auto_archive_paid_invoices_help' => 'Automatically archive invoices when they are paid.',
 | 
				
			||||||
    'auto_archive_cancelled_invoices' => 'Auto Archive Cancelled',
 | 
					    'auto_archive_cancelled_invoices' => 'Auto Archive Cancelled',
 | 
				
			||||||
    'auto_archive_cancelled_invoices_help' => 'Automatically archive invoices when they are cancelled.',
 | 
					    'auto_archive_cancelled_invoices_help' => 'Automatically archive invoices when cancelled.',
 | 
				
			||||||
    'alternate_pdf_viewer' => 'Alternate PDF Viewer',
 | 
					    'alternate_pdf_viewer' => 'Alternate PDF Viewer',
 | 
				
			||||||
    'alternate_pdf_viewer_help' => 'Improve scrolling over the PDF preview [BETA]',
 | 
					    'alternate_pdf_viewer_help' => 'Improve scrolling over the PDF preview [BETA]',
 | 
				
			||||||
    'currency_cayman_island_dollar' => 'Cayman Island Dollar',
 | 
					    'currency_cayman_island_dollar' => 'Cayman Island Dollar',
 | 
				
			||||||
@ -4777,6 +4777,80 @@ $LANG = array(
 | 
				
			|||||||
    'invoice_task_project' => 'Invoice Task Project',
 | 
					    'invoice_task_project' => 'Invoice Task Project',
 | 
				
			||||||
    'invoice_task_project_help' => 'Add the project to the invoice line items',
 | 
					    'invoice_task_project_help' => 'Add the project to the invoice line items',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'bulk_action' => 'Bulk Action',
 | 
				
			||||||
 | 
					    'phone_validation_error' => 'This mobile/cell phone number is not valid, please enter in E.164 format',
 | 
				
			||||||
 | 
					    'transaction' => 'Transaction',
 | 
				
			||||||
 | 
					    'disable_2fa' => 'Disable 2FA',
 | 
				
			||||||
 | 
					    'change_number' => 'Change Number',
 | 
				
			||||||
 | 
					    'resend_code' => 'Resend Code',
 | 
				
			||||||
 | 
					    'base_type' => 'Base Type',
 | 
				
			||||||
 | 
					    'category_type' => 'Category Type',
 | 
				
			||||||
 | 
					    'bank_transaction' => 'Transaction',
 | 
				
			||||||
 | 
					    'bulk_print' => 'Print PDF',
 | 
				
			||||||
 | 
					    'vendor_postal_code' => 'Vendor Postal Code',
 | 
				
			||||||
 | 
					    'preview_location' => 'Preview Location',
 | 
				
			||||||
 | 
					    'bottom' => 'Bottom',
 | 
				
			||||||
 | 
					    'side' => 'Side',
 | 
				
			||||||
 | 
					    'pdf_preview' => 'PDF Preview',
 | 
				
			||||||
 | 
					    'long_press_to_select' => 'Long Press to Select',
 | 
				
			||||||
 | 
					    'purchase_order_item' => 'Purchase Order Item',
 | 
				
			||||||
 | 
					    'would_you_rate_the_app' => 'Would you like to rate the app?',
 | 
				
			||||||
 | 
					    'include_deleted' => 'Include Deleted',
 | 
				
			||||||
 | 
					    'include_deleted_help' => 'Include deleted records in reports',
 | 
				
			||||||
 | 
					    'due_on' => 'Due On',
 | 
				
			||||||
 | 
					    'browser_pdf_viewer' => 'Use Browser PDF Viewer',
 | 
				
			||||||
 | 
					    'browser_pdf_viewer_help' => 'Warning: Prevents interacting with app over the PDF',
 | 
				
			||||||
 | 
					    'converted_transactions' => 'Successfully converted transactions',
 | 
				
			||||||
 | 
					    'default_category' => 'Default Category',
 | 
				
			||||||
 | 
					    'connect_accounts' => 'Connect Accounts',
 | 
				
			||||||
 | 
					    'manage_rules' => 'Manage Rules',
 | 
				
			||||||
 | 
					    'search_category' => 'Search 1 Category',
 | 
				
			||||||
 | 
					    'search_categories' => 'Search :count Categories',
 | 
				
			||||||
 | 
					    'min_amount' => 'Min Amount',
 | 
				
			||||||
 | 
					    'max_amount' => 'Max Amount',
 | 
				
			||||||
 | 
					    'converted_transaction' => 'Successfully converted transaction',
 | 
				
			||||||
 | 
					    'convert_to_payment' => 'Convert to Payment',
 | 
				
			||||||
 | 
					    'deposit' => 'Deposit',
 | 
				
			||||||
 | 
					    'withdrawal' => 'Withdrawal',
 | 
				
			||||||
 | 
					    'deposits' => 'Deposits',
 | 
				
			||||||
 | 
					    'withdrawals' => 'Withdrawals',
 | 
				
			||||||
 | 
					    'matched' => 'Matched',
 | 
				
			||||||
 | 
					    'unmatched' => 'Unmatched',
 | 
				
			||||||
 | 
					    'create_credit' => 'Create Credit',
 | 
				
			||||||
 | 
					    'transactions' => 'Transactions',
 | 
				
			||||||
 | 
					    'new_transaction' => 'New Transaction',
 | 
				
			||||||
 | 
					    'edit_transaction' => 'Edit Transaction',
 | 
				
			||||||
 | 
					    'created_transaction' => 'Successfully created transaction',
 | 
				
			||||||
 | 
					    'updated_transaction' => 'Successfully updated transaction',
 | 
				
			||||||
 | 
					    'archived_transaction' => 'Successfully archived transaction',
 | 
				
			||||||
 | 
					    'deleted_transaction' => 'Successfully deleted transaction',
 | 
				
			||||||
 | 
					    'removed_transaction' => 'Successfully removed transaction',
 | 
				
			||||||
 | 
					    'restored_transaction' => 'Successfully restored transaction',
 | 
				
			||||||
 | 
					    'search_transaction' => 'Search Transaction',
 | 
				
			||||||
 | 
					    'search_transactions' => 'Search :count Transactions',
 | 
				
			||||||
 | 
					    'deleted_bank_account' => 'Successfully deleted bank account',
 | 
				
			||||||
 | 
					    'removed_bank_account' => 'Successfully removed bank account',
 | 
				
			||||||
 | 
					    'restored_bank_account' => 'Successfully restored bank account',
 | 
				
			||||||
 | 
					    'search_bank_account' => 'Search Bank Account',
 | 
				
			||||||
 | 
					    'search_bank_accounts' => 'Search :count Bank Accounts',
 | 
				
			||||||
 | 
					    'code_was_sent_to' => 'A code has been sent via SMS to :number',
 | 
				
			||||||
 | 
					    'verify_phone_number_2fa_help' => 'Please verify your phone number for 2FA backup',
 | 
				
			||||||
 | 
					    'enable_applying_payments_later' => 'Enable Applying Payments Later',
 | 
				
			||||||
 | 
					    'line_item_tax_rates' => 'Line Item Tax Rates',
 | 
				
			||||||
 | 
					    'show_tasks_in_client_portal' => 'Show Tasks in Client Portal',
 | 
				
			||||||
 | 
					    'notification_quote_expired_subject' => 'Quote :invoice has expired for :client',
 | 
				
			||||||
 | 
					    'notification_quote_expired' => 'The following Quote :invoice for client :client and :amount has now expired.',
 | 
				
			||||||
 | 
					    'auto_sync' => 'Auto Sync',
 | 
				
			||||||
 | 
					    'refresh_accounts' => 'Refresh Accounts',
 | 
				
			||||||
 | 
					    'upgrade_to_connect_bank_account' => 'Upgrade to Enterprise to connect your bank account',
 | 
				
			||||||
 | 
					    'click_here_to_connect_bank_account' => 'Click here to connect your bank account',
 | 
				
			||||||
 | 
					    'include_tax' => 'Include tax',
 | 
				
			||||||
 | 
					    'email_template_change' => 'E-mail template body can be changed on',
 | 
				
			||||||
 | 
					    'task_update_authorization_error' => 'Insufficient permissions, or task may be locked',
 | 
				
			||||||
 | 
					    'cash_vs_accrual' => 'Accrual accounting',
 | 
				
			||||||
 | 
					    'cash_vs_accrual_help' => 'Turn on for accrual reporting, turn off for cash basis reporting.',
 | 
				
			||||||
 | 
					    'expense_paid_report' => 'Expensed reporting',
 | 
				
			||||||
 | 
					    'expense_paid_report_help' => 'Turn on for reporting all expenses, turn off for reporting only paid expenses',
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return $LANG;
 | 
					return $LANG;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										68
									
								
								resources/js/clients/payments/stripe-klarna.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								resources/js/clients/payments/stripe-klarna.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProcessKlarna {
 | 
				
			||||||
 | 
					    constructor(key, stripeConnect) {
 | 
				
			||||||
 | 
					        this.key = key;
 | 
				
			||||||
 | 
					        this.errors = document.getElementById('errors');
 | 
				
			||||||
 | 
					        this.stripeConnect = stripeConnect;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setupStripe = () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.stripeConnect){
 | 
				
			||||||
 | 
					           // this.stripe.stripeAccount = this.stripeConnect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           this.stripe = Stripe(this.key, {
 | 
				
			||||||
 | 
					              stripeAccount: this.stripeConnect,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            this.stripe = Stripe(this.key);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    handle = () => {
 | 
				
			||||||
 | 
					        document.getElementById('pay-now').addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					            let errors = document.getElementById('errors');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            document.getElementById('pay-now').disabled = true;
 | 
				
			||||||
 | 
					            document.querySelector('#pay-now > svg').classList.remove('hidden');
 | 
				
			||||||
 | 
					            document.querySelector('#pay-now > span').classList.add('hidden');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.stripe.confirmKlarnaPayment(
 | 
				
			||||||
 | 
					                document.querySelector('meta[name=pi-client-secret').content,
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    payment_method: {
 | 
				
			||||||
 | 
					                        billing_details: {
 | 
				
			||||||
 | 
					                            name: document.getElementById("giropay-name").value,
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    return_url: document.querySelector(
 | 
				
			||||||
 | 
					                        'meta[name="return-url"]'
 | 
				
			||||||
 | 
					                    ).content,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const publishableKey = document.querySelector(
 | 
				
			||||||
 | 
					    'meta[name="stripe-publishable-key"]'
 | 
				
			||||||
 | 
					)?.content ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const stripeConnect =
 | 
				
			||||||
 | 
					    document.querySelector('meta[name="stripe-account-id"]')?.content ?? '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					new ProcessKlarna(publishableKey, stripeConnect).setupStripe().handle();
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.bank_account'), 'card_title' => ctrans('texts.bank_account')])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section('gateway_content')
 | 
				
			||||||
 | 
					    @component('portal.ninja2020.components.general.card-element-single', ['title' => ctrans('texts.bank_account'), 'show_title' => false])
 | 
				
			||||||
 | 
					        {{ __('texts.sofort_authorize_label') }}
 | 
				
			||||||
 | 
					    @endcomponent
 | 
				
			||||||
 | 
					@endsection
 | 
				
			||||||
@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Klarna', 'card_title' => 'Klarna'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section('gateway_head')
 | 
				
			||||||
 | 
					    @if($gateway->company_gateway->getConfigField('account_id'))
 | 
				
			||||||
 | 
					    <meta name="stripe-account-id" content="{{ $gateway->company_gateway->getConfigField('account_id') }}">
 | 
				
			||||||
 | 
					    <meta name="stripe-publishable-key" content="{{ config('ninja.ninja_stripe_publishable_key') }}">
 | 
				
			||||||
 | 
					    @else
 | 
				
			||||||
 | 
					    <meta name="stripe-publishable-key" content="{{ $gateway->company_gateway->getPublishableKey() }}">
 | 
				
			||||||
 | 
					    @endif
 | 
				
			||||||
 | 
					    <meta name="return-url" content="{{ $return_url }}">
 | 
				
			||||||
 | 
					    <meta name="amount" content="{{ $stripe_amount }}">
 | 
				
			||||||
 | 
					    <meta name="country" content="{{ $country }}">
 | 
				
			||||||
 | 
					    <meta name="customer" content="{{ $customer }}">
 | 
				
			||||||
 | 
					    <meta name="pi-client-secret" content="{{ $pi_client_secret }}">
 | 
				
			||||||
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section('gateway_content')
 | 
				
			||||||
 | 
					    <div class="alert alert-failure mb-4" hidden id="errors"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @include('portal.ninja2020.gateways.includes.payment_details')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
 | 
				
			||||||
 | 
					        {{ ctrans('texts.klarna') }} ({{ ctrans('texts.bank_transfer') }})
 | 
				
			||||||
 | 
					    @endcomponent
 | 
				
			||||||
 | 
					    @include('portal.ninja2020.gateways.includes.pay_now')
 | 
				
			||||||
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@push('footer')
 | 
				
			||||||
 | 
					    <script src="https://js.stripe.com/v3/"></script>
 | 
				
			||||||
 | 
					    <script src="{{ asset('js/clients/payments/stripe-klarna.js') }}"></script>
 | 
				
			||||||
 | 
					@endpush
 | 
				
			||||||
							
								
								
									
										4
									
								
								webpack.mix.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								webpack.mix.js
									
									
									
									
										vendored
									
									
								
							@ -22,6 +22,10 @@ mix.js("resources/js/app.js", "public/js")
 | 
				
			|||||||
        "resources/js/clients/payments/stripe-ach.js",
 | 
					        "resources/js/clients/payments/stripe-ach.js",
 | 
				
			||||||
        "public/js/clients/payments/stripe-ach.js"
 | 
					        "public/js/clients/payments/stripe-ach.js"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    .js(
 | 
				
			||||||
 | 
					        "resources/js/clients/payments/stripe-klarna.js",
 | 
				
			||||||
 | 
					        "public/js/clients/payments/stripe-klarna.js"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    .js(
 | 
					    .js(
 | 
				
			||||||
        "resources/js/clients/invoices/action-selectors.js",
 | 
					        "resources/js/clients/invoices/action-selectors.js",
 | 
				
			||||||
        "public/js/clients/invoices/action-selectors.js"
 | 
					        "public/js/clients/invoices/action-selectors.js"
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user