mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-02 22:57:33 -05:00 
			
		
		
		
	Fixes for Klarna
This commit is contained in:
		
							parent
							
								
									bba2adf5cd
								
							
						
					
					
						commit
						bad7b242e1
					
				@ -115,6 +115,7 @@ class Gateway extends StaticModel
 | 
				
			|||||||
                    GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
					                    GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
				
			||||||
                    GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
					                    GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
				
			||||||
                    GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
					                    GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']],
 | 
				
			||||||
 | 
					                    GatewayType::KLARNA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']],
 | 
				
			||||||
                    GatewayType::FPX => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], ];
 | 
					                    GatewayType::FPX => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], ];
 | 
				
			||||||
            case 39:
 | 
					            case 39:
 | 
				
			||||||
                return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']]]; //Checkout
 | 
					                return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']]]; //Checkout
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,8 @@ use App\Models\Payment;
 | 
				
			|||||||
use App\Models\PaymentType;
 | 
					use App\Models\PaymentType;
 | 
				
			||||||
use App\Models\SystemLog;
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
use App\PaymentDrivers\StripePaymentDriver;
 | 
					use App\PaymentDrivers\StripePaymentDriver;
 | 
				
			||||||
 | 
					use App\Utils\Number;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Klarna
 | 
					class Klarna
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -50,10 +52,10 @@ class Klarna
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $invoice_numbers = collect($data['invoices'])->pluck('invoice_number');
 | 
					        $invoice_numbers = collect($data['invoices'])->pluck('invoice_number');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($invoice_numbers > 0) {
 | 
					        if ($invoice_numbers->count() > 0) {
 | 
				
			||||||
            $description = ctrans('texts.payment_provider_paymenttext', ['invoicenumber' => $invoice_numbers->implode(', '), 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
					            $description = ctrans('texts.stripe_paymenttext', ['invoicenumber' => $invoice_numbers->implode(', '), 'amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $description = ctrans('texts.payment_prvoder_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
					            $description = ctrans('texts.stripe_paymenttext_without_invoice', ['amount' => Number::formatMoney($amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $intent = \Stripe\PaymentIntent::create([
 | 
					        $intent = \Stripe\PaymentIntent::create([
 | 
				
			||||||
@ -149,6 +151,6 @@ class Klarna
 | 
				
			|||||||
            $this->stripe->client->company,
 | 
					            $this->stripe->client->company,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        throw new PaymentFailed(ctrans('texts.payment_provider_failed_process_payment'), 500);
 | 
					        throw new PaymentFailed(ctrans('texts.gateway_error'), 500);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@
 | 
				
			|||||||
    "/js/clients/payments/forte-credit-card-payment.js": "/js/clients/payments/forte-credit-card-payment.js?id=f42dd0caddb3603e71db061924c4b172",
 | 
					    "/js/clients/payments/forte-credit-card-payment.js": "/js/clients/payments/forte-credit-card-payment.js?id=f42dd0caddb3603e71db061924c4b172",
 | 
				
			||||||
    "/js/clients/payments/forte-ach-payment.js": "/js/clients/payments/forte-ach-payment.js?id=b8173c7c0dee76bf9ae6312a963ae0e4",
 | 
					    "/js/clients/payments/forte-ach-payment.js": "/js/clients/payments/forte-ach-payment.js?id=b8173c7c0dee76bf9ae6312a963ae0e4",
 | 
				
			||||||
    "/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=207f218c44553470287f35f33a7eb154",
 | 
					    "/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=207f218c44553470287f35f33a7eb154",
 | 
				
			||||||
 | 
					    "/js/clients/payments/stripe-klarna.js": "/js/clients/payments/stripe-klarna.js?id=1c248bc1f4f45310cd585a95a5055375",
 | 
				
			||||||
    "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=404b7ee18e420de0e73f5402b7e39122",
 | 
					    "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=404b7ee18e420de0e73f5402b7e39122",
 | 
				
			||||||
    "/js/clients/purchase_orders/action-selectors.js": "/js/clients/purchase_orders/action-selectors.js?id=2f0c4e3bab30a98e33ac768255113174",
 | 
					    "/js/clients/purchase_orders/action-selectors.js": "/js/clients/purchase_orders/action-selectors.js?id=2f0c4e3bab30a98e33ac768255113174",
 | 
				
			||||||
    "/js/clients/purchase_orders/accept.js": "/js/clients/purchase_orders/accept.js?id=9bb483a89a887f753e49c0b635d6276a",
 | 
					    "/js/clients/purchase_orders/accept.js": "/js/clients/purchase_orders/accept.js?id=9bb483a89a887f753e49c0b635d6276a",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								resources/js/clients/payments/stripe-klarna.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								resources/js/clients/payments/stripe-klarna.js
									
									
									
									
										vendored
									
									
								
							@ -33,6 +33,16 @@ class ProcessKlarna {
 | 
				
			|||||||
        return this;
 | 
					        return this;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    handleError = (message) => {
 | 
				
			||||||
 | 
					        document.getElementById('pay-now').disabled = false;
 | 
				
			||||||
 | 
					        document.querySelector('#pay-now > svg').classList.add('hidden');
 | 
				
			||||||
 | 
					        document.querySelector('#pay-now > span').classList.remove('hidden');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.errors.textContent = '';
 | 
				
			||||||
 | 
					        this.errors.textContent = message;
 | 
				
			||||||
 | 
					        this.errors.hidden = false;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    handle = () => {
 | 
					    handle = () => {
 | 
				
			||||||
        document.getElementById('pay-now').addEventListener('click', (e) => {
 | 
					        document.getElementById('pay-now').addEventListener('click', (e) => {
 | 
				
			||||||
            let errors = document.getElementById('errors');
 | 
					            let errors = document.getElementById('errors');
 | 
				
			||||||
@ -46,14 +56,28 @@ class ProcessKlarna {
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    payment_method: {
 | 
					                    payment_method: {
 | 
				
			||||||
                        billing_details: {
 | 
					                        billing_details: {
 | 
				
			||||||
                            name: document.getElementById("giropay-name").value,
 | 
					                            name: document.getElementById("klarna-name").value,
 | 
				
			||||||
 | 
					                            email: document.querySelector('meta[name=email').content,
 | 
				
			||||||
 | 
					                            address: {
 | 
				
			||||||
 | 
					                              line1: document.querySelector('input[name=address1]').value,
 | 
				
			||||||
 | 
					                              line2: document.querySelector('input[name=address2]').value,
 | 
				
			||||||
 | 
					                              city: document.querySelector('input[name=city]').value,
 | 
				
			||||||
 | 
					                              postal_code: document.querySelector('input[name=postal_code]').value,
 | 
				
			||||||
 | 
					                              state: document.querySelector('input[name=state]').value,
 | 
				
			||||||
 | 
					                              country: document.querySelector('meta[name=country').content,
 | 
				
			||||||
 | 
					                            }      
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    return_url: document.querySelector(
 | 
					                    return_url: document.querySelector(
 | 
				
			||||||
                        'meta[name="return-url"]'
 | 
					                        'meta[name="return-url"]'
 | 
				
			||||||
                    ).content,
 | 
					                    ).content,
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            );
 | 
					            ).then((result) => {
 | 
				
			||||||
 | 
					                if (result.hasOwnProperty('error')) {
 | 
				
			||||||
 | 
					                    return this.handleError(result.error.message);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            });;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					<div id="stripe--payment-container">
 | 
				
			||||||
 | 
					    @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.name')])
 | 
				
			||||||
 | 
					        <div class="form-group mb-[10px]">
 | 
				
			||||||
 | 
					            <input class="input w-full" id="klarna-name" type="text" placeholder="{{ ctrans('texts.bank_account_holder') }}" value="{{ $gateway->client->present()->name()}}" required>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="form-group mb-[10px]">
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					                    type="text"
 | 
				
			||||||
 | 
					                    class="input w-full m-0"
 | 
				
			||||||
 | 
					                    id="address2"
 | 
				
			||||||
 | 
					                    placeholder="{{ ctrans('texts.address2') }}"
 | 
				
			||||||
 | 
					                    name="address2"
 | 
				
			||||||
 | 
					                    value="{{$gateway->client->address2}}"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="form-group mb-[10px]">
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					                    type="text"
 | 
				
			||||||
 | 
					                    class="input w-full m-0"
 | 
				
			||||||
 | 
					                    id="address1"
 | 
				
			||||||
 | 
					                    placeholder="{{ ctrans('texts.address1') }}"
 | 
				
			||||||
 | 
					                    name="address1"
 | 
				
			||||||
 | 
					                    value="{{$gateway->client->address1}}"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					                class="flex form-group flex justify-center gap-[13px] mb-[10px]"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <div class="w-full gap-x-2 md:w-1/3">
 | 
				
			||||||
 | 
					                <div class="form-group">
 | 
				
			||||||
 | 
					                    <input
 | 
				
			||||||
 | 
					                            type="text"
 | 
				
			||||||
 | 
					                            class="input w-full m-0"
 | 
				
			||||||
 | 
					                            id="city"
 | 
				
			||||||
 | 
					                            placeholder="{{ ctrans('texts.city') }}"
 | 
				
			||||||
 | 
					                            name="city"
 | 
				
			||||||
 | 
					                            value="{{$gateway->client->city}}"
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="w-full gap-x-2 md:w-1/3">
 | 
				
			||||||
 | 
					                <div class="form-group">
 | 
				
			||||||
 | 
					                    <input
 | 
				
			||||||
 | 
					                            type="text"
 | 
				
			||||||
 | 
					                            class="input w-full m-0"
 | 
				
			||||||
 | 
					                            id="state"
 | 
				
			||||||
 | 
					                            placeholder="{{ ctrans('texts.state') }}"
 | 
				
			||||||
 | 
					                            name="state"
 | 
				
			||||||
 | 
					                            value="{{$gateway->client->state}}"
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="w-full gap-x-2 md:w-1/3">
 | 
				
			||||||
 | 
					                <div class="form-group">
 | 
				
			||||||
 | 
					                    <input
 | 
				
			||||||
 | 
					                            type="text"
 | 
				
			||||||
 | 
					                            class="input w-full m-0"
 | 
				
			||||||
 | 
					                            id="postal_code"
 | 
				
			||||||
 | 
					          placeholder="{{ ctrans('texts.postal_code') }}"
 | 
				
			||||||
 | 
					                            name="postal_code"
 | 
				
			||||||
 | 
					          value="{{$gateway->client->postal_code}}"
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @endcomponent
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
    <meta name="amount" content="{{ $stripe_amount }}">
 | 
					    <meta name="amount" content="{{ $stripe_amount }}">
 | 
				
			||||||
    <meta name="country" content="{{ $country }}">
 | 
					    <meta name="country" content="{{ $country }}">
 | 
				
			||||||
    <meta name="customer" content="{{ $customer }}">
 | 
					    <meta name="customer" content="{{ $customer }}">
 | 
				
			||||||
 | 
					    <meta name="email" content="{{ $gateway->client->present()->email() }}">
 | 
				
			||||||
    <meta name="pi-client-secret" content="{{ $pi_client_secret }}">
 | 
					    <meta name="pi-client-secret" content="{{ $pi_client_secret }}">
 | 
				
			||||||
@endsection
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,6 +23,7 @@
 | 
				
			|||||||
    @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
 | 
					    @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')])
 | 
				
			||||||
        {{ ctrans('texts.klarna') }} ({{ ctrans('texts.bank_transfer') }})
 | 
					        {{ ctrans('texts.klarna') }} ({{ ctrans('texts.bank_transfer') }})
 | 
				
			||||||
    @endcomponent
 | 
					    @endcomponent
 | 
				
			||||||
 | 
					    @include('portal.ninja2020.gateways.stripe.klarna.klarna')
 | 
				
			||||||
    @include('portal.ninja2020.gateways.includes.pay_now')
 | 
					    @include('portal.ninja2020.gateways.includes.pay_now')
 | 
				
			||||||
@endsection
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user