mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-08 08:04:40 -04:00
Merge pull request #8059 from LarsK1/patch-stripe-klarna
Change Klarna intregration to comply with Klarna's rules
This commit is contained in:
commit
37865e8802
@ -35,4 +35,8 @@ class Country extends StaticModel
|
|||||||
{
|
{
|
||||||
return trans('texts.country_'.$this->name);
|
return trans('texts.country_'.$this->name);
|
||||||
}
|
}
|
||||||
|
public function getID() :string
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use App\Http\Requests\Request;
|
|||||||
use App\Jobs\Util\SystemLogger;
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Models\ClientGatewayToken;
|
use App\Models\ClientGatewayToken;
|
||||||
use App\Models\GatewayType;
|
use App\Models\GatewayType;
|
||||||
|
use App\Models\Country;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\PaymentHash;
|
use App\Models\PaymentHash;
|
||||||
use App\Models\PaymentType;
|
use App\Models\PaymentType;
|
||||||
@ -240,12 +241,19 @@ class StripePaymentDriver extends BaseDriver
|
|||||||
}
|
}
|
||||||
if ($this->client
|
if ($this->client
|
||||||
&& $this->client->currency()
|
&& $this->client->currency()
|
||||||
&& in_array($this->client->currency()->code, ['EUR', 'DKK', 'GBP', 'NOK', 'SEK', 'USD', 'AUD', 'NZD', 'CAD', 'PLN', 'CHF'])
|
&& in_array($this->client->currency()->code, ['EUR', 'DKK', 'GBP', 'NOK', 'SEK', 'AUD', 'NZD', 'CAD', 'PLN', 'CHF'])
|
||||||
&& isset($this->client->country)
|
&& isset($this->client->country)
|
||||||
|
&& in_array($this->client->country->iso_3166_3, ['AUT','BEL','DNK','FIN','FRA','DEU','IRL','ITA','NLD','NOR','ESP','SWE','GBR'])) {
|
||||||
|
$types[] = GatewayType::KLARNA;
|
||||||
|
}
|
||||||
|
if ($this->client
|
||||||
|
&& $this->client->currency()
|
||||||
|
&& in_array($this->client->currency()->code, ['EUR', 'DKK', 'GBP', 'NOK', 'SEK', 'AUD', 'NZD', 'CAD', 'PLN', 'CHF', 'USD'])
|
||||||
|
&& isset($this->client->country)
|
||||||
|
&& in_array($this->client->company->country()->getID(), ['840'])
|
||||||
&& in_array($this->client->country->iso_3166_3, ['AUT','BEL','DNK','FIN','FRA','DEU','IRL','ITA','NLD','NOR','ESP','SWE','GBR','USA'])) {
|
&& in_array($this->client->country->iso_3166_3, ['AUT','BEL','DNK','FIN','FRA','DEU','IRL','ITA','NLD','NOR','ESP','SWE','GBR','USA'])) {
|
||||||
$types[] = GatewayType::KLARNA;
|
$types[] = GatewayType::KLARNA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$this->client
|
$this->client
|
||||||
&& isset($this->client->country)
|
&& isset($this->client->country)
|
||||||
|
@ -2503,6 +2503,7 @@ $LANG = array(
|
|||||||
'alipay' => 'Alipay',
|
'alipay' => 'Alipay',
|
||||||
'sofort' => 'Sofort',
|
'sofort' => 'Sofort',
|
||||||
'sepa' => 'SEPA Direct Debit',
|
'sepa' => 'SEPA Direct Debit',
|
||||||
|
'name_without_special_characters' => 'Please enter a name with only the letters a-z and whitespaces',
|
||||||
'enable_alipay' => 'Accept Alipay',
|
'enable_alipay' => 'Accept Alipay',
|
||||||
'enable_sofort' => 'Accept EU bank transfers',
|
'enable_sofort' => 'Accept EU bank transfers',
|
||||||
'stripe_alipay_help' => 'These gateways also need to be activated in :link.',
|
'stripe_alipay_help' => 'These gateways also need to be activated in :link.',
|
||||||
|
2
public/js/clients/payments/stripe-klarna.js
vendored
Normal file
2
public/js/clients/payments/stripe-klarna.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/*! For license information please see stripe-klarna.js.LICENSE.txt */
|
||||||
|
(()=>{var e,t,n,r;function o(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function a(e,t,n){return t&&o(e.prototype,t),n&&o(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var i=a((function e(t,n){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),c(this,"setupStripe",(function(){return r.stripeConnect?r.stripe=Stripe(r.key,{stripeAccount:r.stripeConnect}):r.stripe=Stripe(r.key),r})),c(this,"handleError",(function(e){document.getElementById("pay-now").disabled=!1,document.querySelector("#pay-now > svg").classList.add("hidden"),document.querySelector("#pay-now > span").classList.remove("hidden"),r.errors.textContent="",r.errors.textContent=e,r.errors.hidden=!1})),c(this,"handle",(function(){document.getElementById("pay-now").addEventListener("click",(function(e){var t=document.getElementById("errors"),n=document.getElementById("klarna-name").value;/^[A-Za-z\s]*$/.test(n)?(document.getElementById("pay-now").disabled=!0,document.querySelector("#pay-now > svg").classList.remove("hidden"),document.querySelector("#pay-now > span").classList.add("hidden"),r.stripe.confirmKlarnaPayment(document.querySelector("meta[name=pi-client-secret").content,{payment_method:{billing_details:{name:n,email:document.querySelector("meta[name=email]").content,address:{line1:document.querySelector("meta[name=address-1]").content,line2:document.querySelector("meta[name=address-2]").content,city:document.querySelector("meta[name=city]").content,postal_code:document.querySelector("meta[name=postal_code]").content,state:document.querySelector("meta[name=state]").content,country:document.querySelector("meta[name=country]").content}}},return_url:document.querySelector('meta[name="return-url"]').content}).then((function(e){if(e.hasOwnProperty("error"))return r.handleError(e.error.message)}))):(document.getElementById("klarna-name-correction").hidden=!1,document.getElementById("klarna-name").textContent=n.replace(/^[A-Za-z\s]*$/,""),document.getElementById("klarna-name").focus(),t.textContent=document.querySelector("meta[name=translation-name-without-special-characters]").content,t.hidden=!1)}))})),this.key=t,this.errors=document.getElementById("errors"),this.stripeConnect=n}));new i(null!==(e=null===(t=document.querySelector('meta[name="stripe-publishable-key"]'))||void 0===t?void 0:t.content)&&void 0!==e?e:"",null!==(n=null===(r=document.querySelector('meta[name="stripe-account-id"]'))||void 0===r?void 0:r.content)&&void 0!==n?n:"").setupStripe().handle()})();
|
9
public/js/clients/payments/stripe-klarna.js.LICENSE.txt
Normal file
9
public/js/clients/payments/stripe-klarna.js.LICENSE.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
31
resources/js/clients/payments/stripe-klarna.js
vendored
31
resources/js/clients/payments/stripe-klarna.js
vendored
@ -46,25 +46,34 @@ class ProcessKlarna {
|
|||||||
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');
|
||||||
|
let name = document.getElementById("klarna-name").value;
|
||||||
|
if (! /^[A-Za-z\s]*$/.test(name)){
|
||||||
|
document.getElementById('klarna-name-correction').hidden = false;
|
||||||
|
document.getElementById('klarna-name').textContent = name.replace(/^[A-Za-z\s]*$/, "")
|
||||||
|
document.getElementById('klarna-name').focus();
|
||||||
|
errors.textContent = document.querySelector(
|
||||||
|
'meta[name=translation-name-without-special-characters]'
|
||||||
|
).content;
|
||||||
|
errors.hidden = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
document.getElementById('pay-now').disabled = true;
|
document.getElementById('pay-now').disabled = true;
|
||||||
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
document.querySelector('#pay-now > svg').classList.remove('hidden');
|
||||||
document.querySelector('#pay-now > span').classList.add('hidden');
|
document.querySelector('#pay-now > span').classList.add('hidden');
|
||||||
|
|
||||||
this.stripe.confirmKlarnaPayment(
|
this.stripe.confirmKlarnaPayment(
|
||||||
document.querySelector('meta[name=pi-client-secret').content,
|
document.querySelector('meta[name=pi-client-secret').content,
|
||||||
{
|
{
|
||||||
payment_method: {
|
payment_method: {
|
||||||
billing_details: {
|
billing_details: {
|
||||||
name: document.getElementById("klarna-name").value,
|
name: name,
|
||||||
email: document.querySelector('meta[name=email').content,
|
email: document.querySelector('meta[name=email]').content,
|
||||||
address: {
|
address: {
|
||||||
line1: document.querySelector('input[name=address1]').value,
|
line1: document.querySelector('meta[name=address-1]').content,
|
||||||
line2: document.querySelector('input[name=address2]').value,
|
line2: document.querySelector('meta[name=address-2]').content,
|
||||||
city: document.querySelector('input[name=city]').value,
|
city: document.querySelector('meta[name=city]').content,
|
||||||
postal_code: document.querySelector('input[name=postal_code]').value,
|
postal_code: document.querySelector('meta[name=postal_code]').content,
|
||||||
state: document.querySelector('input[name=state]').value,
|
state: document.querySelector('meta[name=state]').content,
|
||||||
country: document.querySelector('meta[name=country').content,
|
country: document.querySelector('meta[name=country]').content,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -77,7 +86,7 @@ class ProcessKlarna {
|
|||||||
return this.handleError(result.error.message);
|
return this.handleError(result.error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
});;
|
});}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,68 +1,7 @@
|
|||||||
<div id="stripe--payment-container">
|
<div id="klarna-name-correction" hidden>
|
||||||
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.name')])
|
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.name')])
|
||||||
<div class="form-group mb-[10px]">
|
<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>
|
<input class="input w-full" id="klarna-name" type="text" placeholder="{{ ctrans('texts.bank_account_holder') }}" value="{{ $gateway->client->present()->name()}}">
|
||||||
</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>
|
</div>
|
||||||
|
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
@ -12,7 +12,13 @@
|
|||||||
<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="email" content="{{ $gateway->client->present()->email() }}">
|
||||||
|
<meta name="address-2" content="{{ $gateway->client->address2 }}">
|
||||||
|
<meta name="address-1" content="{{ $gateway->client->address1 }}">
|
||||||
|
<meta name="city" content="{{ $gateway->client->city }}">
|
||||||
|
<meta name="state" content="{{ $gateway->client->state }}">
|
||||||
|
<meta name="postal_code" content="{{ $gateway->client->postal_code }}">
|
||||||
<meta name="pi-client-secret" content="{{ $pi_client_secret }}">
|
<meta name="pi-client-secret" content="{{ $pi_client_secret }}">
|
||||||
|
<meta name="translation-name-without-special-characters" content="{{ ctrans('texts.name_without_special_characters') }}">
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('gateway_content')
|
@section('gateway_content')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user