initial docker setup
@@ -0,0 +1 @@
|
||||
# Klarna Checkout for WooCommerce plugin
|
||||
@@ -0,0 +1,162 @@
|
||||
@font-face {
|
||||
font-family: Klarna;
|
||||
src: url("../fonts/KlarnaSans-Regular.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: KlarnaHeadline;
|
||||
font-weight: bold;
|
||||
src: url("../fonts/KlarnaHeadline-Bold.otf") format("opentype");
|
||||
}
|
||||
|
||||
/* Banner */
|
||||
#klarna-banner {
|
||||
background-image: url("../img/admin-banner.jpg");
|
||||
background-position: center center;
|
||||
background-size: 100% auto;
|
||||
padding: 30px;
|
||||
margin: 0 20px 20px 0;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#kb-spacer {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#klarna-banner > div {
|
||||
text-align: center;
|
||||
padding: 0 60px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
font-family: Klarna, sans-serif;
|
||||
}
|
||||
|
||||
#klarna-banner h1 {
|
||||
font-size: 32px;
|
||||
line-height: 1.2;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
font-family: KlarnaHeadline, sans-serif;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#klarna-banner p {
|
||||
margin-bottom: 1em;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.2px;
|
||||
}
|
||||
|
||||
#kb-image {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
a.kb-button {
|
||||
display: inline-block;
|
||||
background: #eb6f93;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
padding: 0.75em 2em;
|
||||
-webkit-border-radius: 0.5em;
|
||||
-moz-border-radius: 0.5em;
|
||||
border-radius: 0.5em;
|
||||
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.kb-dismiss {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
}
|
||||
.kb-dismiss:hover {
|
||||
color: #eb6f93;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
#klarna-banner {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#klarna-banner > div {
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#klarna-banner > div > * {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 799px) {
|
||||
#klarna-banner > div {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sidebar */
|
||||
@media (min-width: 880px) {
|
||||
#klarna-wrapper:after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#klarna-main {
|
||||
width: 70%;
|
||||
float: left;
|
||||
padding: 0 2% 0 0;
|
||||
border-right: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#klarna-sidebar {
|
||||
width: 28%;
|
||||
max-width: 350px;
|
||||
margin-left: 2%;
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-family: Klarna, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
#klarna-settings-logo {
|
||||
display: block;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
#klarna-sidebar h3 {
|
||||
font-family: KlarnaHeadline, sans-serif;
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#klarna-sidebar p {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
#klarna-sidebar img {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.kb-sidebar-section {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.wc-settings-sub-title a, .wc-settings-sub-title a:hover, .wc-settings-sub-title a:click, .wc-settings-sub-title a:visited, .wc-settings-sub-title a:focus {
|
||||
border:none;
|
||||
outline:none;
|
||||
text-decoration:none;
|
||||
color:black;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#kco-wrapper {
|
||||
overflow: hidden;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
#kco-order-review {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.product-name .quantity {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#kco-order-review table.woocommerce-checkout-review-order-table .product-name {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media only screen and (min-width : 769px) {
|
||||
#kco-order-review {
|
||||
float: left;
|
||||
width: 40%;
|
||||
padding-right: 20px;
|
||||
font-size: 0.9em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#kco-iframe {
|
||||
float: right;
|
||||
width: 60%;
|
||||
padding-left: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#kco-wrapper{overflow:hidden;padding:20px 0}#kco-order-review{margin-bottom:50px}.product-name .quantity{display:inline-block}#kco-order-review table.woocommerce-checkout-review-order-table .product-name{width:auto}@media only screen and (min-width :769px){#kco-order-review{float:left;width:40%;padding-right:20px;font-size:.9em;box-sizing:border-box}#kco-iframe{float:right;width:60%;padding-left:20px;box-sizing:border-box}}
|
||||
|
After Width: | Height: | Size: 313 KiB |
@@ -0,0 +1,28 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="480" width="640" viewBox="0 0 640 480">
|
||||
<defs>
|
||||
<g id="d">
|
||||
<g id="b">
|
||||
<path d="M0-1l-.31.95.477.156z" id="a"/>
|
||||
<use transform="scale(-1 1)" xlink:href="#a"/>
|
||||
</g>
|
||||
<g id="c">
|
||||
<use transform="rotate(72)" xlink:href="#b"/>
|
||||
<use transform="rotate(144)" xlink:href="#b"/>
|
||||
</g>
|
||||
<use transform="scale(-1 1)" xlink:href="#c"/>
|
||||
</g>
|
||||
</defs>
|
||||
<path fill="#039" d="M0 0h640v480H0z"/>
|
||||
<g transform="translate(320 242.263) scale(23.7037)" fill="#fc0">
|
||||
<use height="100%" width="100%" xlink:href="#d" y="-6"/>
|
||||
<use height="100%" width="100%" xlink:href="#d" y="6"/>
|
||||
<g id="e">
|
||||
<use height="100%" width="100%" xlink:href="#d" x="-6"/>
|
||||
<use height="100%" width="100%" xlink:href="#d" transform="rotate(-144 -2.344 -2.11)"/>
|
||||
<use height="100%" width="100%" xlink:href="#d" transform="rotate(144 -2.11 -2.344)"/>
|
||||
<use height="100%" width="100%" xlink:href="#d" transform="rotate(72 -4.663 -2.076)"/>
|
||||
<use height="100%" width="100%" xlink:href="#d" transform="rotate(72 -5.076 .534)"/>
|
||||
</g>
|
||||
<use height="100%" width="100%" xlink:href="#e" transform="scale(-1 1)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
|
||||
<g fill-rule="evenodd" transform="scale(.9375)">
|
||||
<g stroke-width="1pt">
|
||||
<path d="M0 0h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#bd3d44"/>
|
||||
<path d="M0 39.385h972.81V78.77H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#fff"/>
|
||||
</g>
|
||||
<path fill="#192f5d" d="M0 0h389.12v275.69H0z"/>
|
||||
<g fill="#fff">
|
||||
<path d="M32.427 11.8l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 39.37l3.54 10.896h11.458L70.583 57l3.542 10.897-9.27-6.734-9.269 6.734L59.126 57l-9.269-6.734h11.458zm64.852 0l3.54 10.896h11.457L135.435 57l3.54 10.897-9.268-6.734-9.27 6.734L123.978 57l-9.27-6.734h11.458zm64.855 0l3.54 10.896h11.458L200.29 57l3.541 10.897-9.27-6.734-9.268 6.734L188.833 57l-9.269-6.734h11.457zm64.855 0l3.54 10.896h11.458L265.145 57l3.541 10.897-9.269-6.734-9.27 6.734L253.69 57l-9.27-6.734h11.458zm64.852 0l3.54 10.896h11.457L329.997 57l3.54 10.897-9.268-6.734-9.27 6.734L318.54 57l-9.27-6.734h11.458zM32.427 66.939l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 94.508l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zM32.427 122.078l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 149.647l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
|
||||
<g>
|
||||
<path d="M32.427 177.217l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 204.786l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M32.427 232.356l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,42 @@
|
||||
jQuery( function($) {
|
||||
'use strict';
|
||||
var location = kco_admin_params.location;
|
||||
var titles = $('h3.wc-settings-sub-title');
|
||||
var tables = $('h3.wc-settings-sub-title + table.form-table');
|
||||
var submit = $('.wrap.woocommerce p.submit');
|
||||
|
||||
titles.append(' <a href="#" style="font-size:12px; font-weight: normal; text-decoration: none"><span class="dashicons dashicons-arrow-down-alt2"></span></a>');
|
||||
tables.css('marginLeft', '20px').hide();
|
||||
if(location === 'EU') {
|
||||
var title = $('#woocommerce_kco_credentials_eu');
|
||||
$('#woocommerce_kco_credentials_us').find('a').addClass('collapsed');
|
||||
title.find('a').html('<span class="dashicons dashicons-arrow-up-alt2">');
|
||||
title.next().show();
|
||||
} else if( location === 'US') {
|
||||
var title = $('#woocommerce_kco_credentials_us');
|
||||
$('#woocommerce_kco_credentials_eu').find('a').addClass('collapsed');
|
||||
title.find('a').html('<span class="dashicons dashicons-arrow-up-alt2">');
|
||||
title.next().show();
|
||||
} else {
|
||||
var title = titles;
|
||||
}
|
||||
$('#woocommerce_kco_color_settings_title').find('a').addClass('collapsed');
|
||||
|
||||
titles.find('a').click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ($(this).hasClass('collapsed')) {
|
||||
$(this).parent().next().show();
|
||||
$(this).removeClass('collapsed');
|
||||
$(this).html('<span class="dashicons dashicons-arrow-up-alt2"></span>');
|
||||
} else {
|
||||
$(this).parent().next().hide();
|
||||
$(this).addClass('collapsed');
|
||||
$(this).html('<span class="dashicons dashicons-arrow-down-alt2"></span>');
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
titles.before('<hr style="margin-top:2em;margin-bottom:2em" />');
|
||||
submit.before('<hr style="margin-top:2em;margin-bottom:2em" />');
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
jQuery(function(e){"use strict";var t=e("h3.wc-settings-sub-title"),s=e("h3.wc-settings-sub-title + table.form-table"),a=e(".wrap.woocommerce p.submit");t.append(' <a href="#" style="font-size:12px; font-weight: normal; text-decoration: none">[expand]</a>'),s.css("marginLeft","20px").hide(),t.find("a").addClass("collapsed"),t.find("a").click(function(t){t.preventDefault(),e(this).hasClass("collapsed")?(e(this).parent().next().show(),e(this).removeClass("collapsed"),e(this).text("[collapse]")):(e(this).parent().next().hide(),e(this).addClass("collapsed"),e(this).text("[expand]"))}),t.before('<hr style="margin-top:2em;margin-bottom:2em" />'),a.before('<hr style="margin-top:2em;margin-bottom:2em" />')});
|
||||
@@ -0,0 +1,395 @@
|
||||
/* global kco_params */
|
||||
jQuery(function($) {
|
||||
// Check if we have params.
|
||||
if ( typeof kco_params === 'undefined' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var kco_wc = {
|
||||
bodyEl: $('body'),
|
||||
checkoutFormSelector: 'form.checkout',
|
||||
|
||||
// Order notes
|
||||
orderNotesValue: '',
|
||||
orderNotesSelector: 'textarea#order_comments',
|
||||
orderNotesEl: $('textarea#order_comments'),
|
||||
|
||||
// Order notes
|
||||
extraFieldsValues: {},
|
||||
extraFieldsSelectorText: 'div#kco-extra-fields input[type="text"], div#kco-extra-fields input[type="password"], div#kco-extra-fields textarea',
|
||||
extraFieldsSelectorNonText: 'div#kco-extra-fields select, div#kco-extra-fields input[type="radio"], div#kco-extra-fields input[type="checkbox"], div#kco-extra-fields input.checkout-date-picker, input#terms input[type="checkbox"]',
|
||||
|
||||
// Payment method
|
||||
paymentMethodEl: $('input[name="payment_method"]'),
|
||||
paymentMethod: '',
|
||||
selectAnotherSelector: '#klarna-checkout-select-other',
|
||||
|
||||
// Form fields
|
||||
formFields: [],
|
||||
|
||||
documentReady: function() {
|
||||
kco_wc.log(kco_params);
|
||||
kco_wc.setFormData();
|
||||
if (kco_wc.paymentMethodEl.length > 0) {
|
||||
kco_wc.paymentMethod = kco_wc.paymentMethodEl.filter(':checked').val();
|
||||
} else {
|
||||
kco_wc.paymentMethod = 'kco';
|
||||
}
|
||||
|
||||
kco_wc.confirmLoading();
|
||||
},
|
||||
|
||||
kcoSuspend: function () {
|
||||
if (window._klarnaCheckout) {
|
||||
window._klarnaCheckout(function (api) {
|
||||
api.suspend();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
kcoResume: function () {
|
||||
if (window._klarnaCheckout) {
|
||||
window._klarnaCheckout(function (api) {
|
||||
api.resume();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
confirmLoading: function () {
|
||||
$('#kco-confirm-loading')
|
||||
.css('minHeight', '300px')
|
||||
.block({
|
||||
message: null,
|
||||
overlayCSS: {
|
||||
background: '#fff',
|
||||
opacity: 0.6
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateCart: function () {
|
||||
kco_wc.kcoSuspend();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: kco_params.update_cart_url,
|
||||
data: {
|
||||
checkout: $('form.checkout').serialize(),
|
||||
nonce: kco_params.update_cart_nonce
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
},
|
||||
error: function(data) {
|
||||
},
|
||||
complete: function(data) {
|
||||
$('body').trigger('update_checkout');
|
||||
kco_wc.kcoResume();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateExtraFields: function() {
|
||||
var elementName = $(this).attr('name');
|
||||
if( elementName === 'terms' ) {
|
||||
var updatedValue = ( $("input#terms:checked").length === 1 ) ? 1 : '';
|
||||
} else {
|
||||
var updatedValue = $(this).val();
|
||||
}
|
||||
kco_wc.log('value');
|
||||
kco_wc.log(updatedValue);
|
||||
kco_wc.log('name');
|
||||
kco_wc.log(elementName);
|
||||
kco_wc.log(typeof kco_wc.extraFieldsValues);
|
||||
kco_wc.log(kco_wc.extraFieldsValues);
|
||||
|
||||
if (null === kco_wc.extraFieldsValues && '' === updatedValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== kco_wc.extraFieldsValues && elementName in kco_wc.extraFieldsValues && updatedValue === kco_wc.extraFieldsValues) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === kco_wc.extraFieldsValues) {
|
||||
kco_wc.extraFieldsValues = {};
|
||||
}
|
||||
|
||||
kco_wc.log('update');
|
||||
|
||||
kco_wc.extraFieldsValues[elementName] = updatedValue;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: kco_params.update_extra_fields_url,
|
||||
data: {
|
||||
extra_fields_values: kco_wc.extraFieldsValues,
|
||||
nonce: kco_params.update_extra_fields_nonce
|
||||
},
|
||||
success: function (data) {},
|
||||
error: function (data) {},
|
||||
complete: function (data) {
|
||||
kco_wc.log('complete', data);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateOrderNotes: function() {
|
||||
if (kco_wc.orderNotesEl.val() !== kco_wc.orderNotesValue) {
|
||||
kco_wc.orderNotesValue = kco_wc.orderNotesEl.val();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: kco_params.update_order_notes_url,
|
||||
data: {
|
||||
order_notes: kco_wc.orderNotesValue,
|
||||
nonce: kco_params.update_order_notes_nonce
|
||||
},
|
||||
success: function (data) {},
|
||||
error: function (data) {},
|
||||
complete: function (data) {
|
||||
kco_wc.log('complete', data);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updateKlarnaOrder: function() {
|
||||
if ('kco' === kco_wc.paymentMethod) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: kco_params.update_klarna_order_url,
|
||||
data: {
|
||||
nonce: kco_params.update_klarna_order_nonce
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
},
|
||||
error: function(data) {
|
||||
},
|
||||
complete: function(data) {
|
||||
kco_wc.kcoResume();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// When "Change to another payment method" is clicked.
|
||||
changeFromKco: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$(kco_wc.checkoutFormSelector).block({
|
||||
message: null,
|
||||
overlayCSS: {
|
||||
background: '#fff',
|
||||
opacity: 0.6
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
kco: false,
|
||||
nonce: kco_params.change_payment_method_nonce
|
||||
},
|
||||
url: kco_params.change_payment_method_url,
|
||||
success: function (data) {},
|
||||
error: function (data) {},
|
||||
complete: function (data) {
|
||||
kco_wc.log(data.responseJSON);
|
||||
window.location.href = data.responseJSON.data.redirect;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// When payment method is changed to KCO in regular WC Checkout page.
|
||||
maybeChangeToKco: function() {
|
||||
kco_wc.log($(this).val());
|
||||
|
||||
if ( 'kco' === $(this).val() ) {
|
||||
$('.woocommerce-info').remove();
|
||||
|
||||
$(kco_wc.checkoutFormSelector).block({
|
||||
message: null,
|
||||
overlayCSS: {
|
||||
background: '#fff',
|
||||
opacity: 0.6
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
data: {
|
||||
kco: true,
|
||||
nonce: kco_params.change_payment_method_nonce
|
||||
},
|
||||
dataType: 'json',
|
||||
url: kco_params.change_payment_method_url,
|
||||
success: function (data) {},
|
||||
error: function (data) {},
|
||||
complete: function (data) {
|
||||
kco_wc.log(data.responseJSON);
|
||||
window.location.href = data.responseJSON.data.redirect;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
checkoutError: function() {
|
||||
if ('kco' === kco_wc.paymentMethod) {
|
||||
var error_message = $( ".woocommerce-NoticeGroup-checkout" ).text();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
kco: false,
|
||||
error_message: error_message,
|
||||
nonce: kco_params.checkout_error_nonce
|
||||
},
|
||||
url: kco_params.checkout_error_url,
|
||||
success: function (data) {
|
||||
},
|
||||
error: function (data) {
|
||||
},
|
||||
complete: function (data) {
|
||||
kco_wc.log(data.responseJSON);
|
||||
window.location.href = data.responseJSON.data.redirect;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
log: function(message) {
|
||||
if (kco_params.logging) {
|
||||
console.log(message);
|
||||
}
|
||||
},
|
||||
|
||||
setFormData: function() {
|
||||
var form = $('form[name="checkout"] input');
|
||||
var i;
|
||||
var newForm = [];
|
||||
for ( i = 0; i < form.length; i++ ) {
|
||||
if ( form[i]['name'] !== '' ) {
|
||||
var name = form[i]['name'];
|
||||
var field = $('*[name="' + name + '"]');
|
||||
var id = field.attr('id');
|
||||
var label = $('label[for="' + id + '"]');
|
||||
var check = ( label.has( "abbr" ).length ? true : ( id === 'terms' ) ? true : false );
|
||||
if ( check === true ) {
|
||||
var value = ( ! field.is(':checkbox') ) ? form[i].value : ( field.is(":checked") ) ? form[i].value : '';
|
||||
if( form[i].name === 'terms' ) {
|
||||
value = ( $("input#terms:checked").length === 1 ) ? 1 : '';
|
||||
}
|
||||
newForm.push({
|
||||
name: form[i].name,
|
||||
value: value,
|
||||
required: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
kco_wc.formFields = newForm;
|
||||
kco_wc.saveFormData();
|
||||
},
|
||||
|
||||
saveFormData: function() {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: kco_params.save_form_data,
|
||||
data: {
|
||||
form: kco_wc.formFields,
|
||||
nonce: kco_params.save_form_data_nonce
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
},
|
||||
error: function(data) {
|
||||
},
|
||||
complete: function(data) {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
init: function () {
|
||||
$(document).ready(kco_wc.documentReady);
|
||||
|
||||
kco_wc.bodyEl.on('update_checkout', kco_wc.kcoSuspend);
|
||||
kco_wc.bodyEl.on('updated_checkout', kco_wc.updateKlarnaOrder);
|
||||
kco_wc.bodyEl.on('checkout_error', kco_wc.checkoutError);
|
||||
kco_wc.bodyEl.on('change', 'input.qty', kco_wc.updateCart);
|
||||
kco_wc.bodyEl.on('blur', kco_wc.extraFieldsSelectorText, kco_wc.setFormData);
|
||||
kco_wc.bodyEl.on('change', kco_wc.extraFieldsSelectorNonText, kco_wc.setFormData);
|
||||
kco_wc.bodyEl.on('blur', kco_wc.extraFieldsSelectorText, kco_wc.updateExtraFields);
|
||||
kco_wc.bodyEl.on('change', kco_wc.extraFieldsSelectorNonText, kco_wc.updateExtraFields);
|
||||
kco_wc.bodyEl.on('change', 'input[name="payment_method"]', kco_wc.maybeChangeToKco);
|
||||
kco_wc.bodyEl.on('click', kco_wc.selectAnotherSelector, kco_wc.changeFromKco);
|
||||
kco_wc.bodyEl.on('click', 'input#terms', kco_wc.setFormData)
|
||||
kco_wc.bodyEl.on('click', 'input#terms', kco_wc.updateExtraFields)
|
||||
|
||||
if (typeof window._klarnaCheckout === 'function') {
|
||||
window._klarnaCheckout(function (api) {
|
||||
api.on({
|
||||
'shipping_address_change': function(data) {
|
||||
kco_wc.log('shipping_address_change');
|
||||
kco_wc.log(data);
|
||||
|
||||
$('.woocommerce-checkout-review-order-table').block({
|
||||
message: null,
|
||||
overlayCSS: {
|
||||
background: '#fff',
|
||||
opacity: 0.6
|
||||
}
|
||||
});
|
||||
kco_wc.kcoSuspend();
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
url: kco_params.iframe_shipping_address_change_url,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
data: data,
|
||||
nonce: kco_params.iframe_shipping_address_change_nonce
|
||||
},
|
||||
success: function (response) {
|
||||
kco_wc.log(response);
|
||||
$('.woocommerce-checkout-review-order-table').replaceWith(response.data.html);
|
||||
},
|
||||
error: function (response) {
|
||||
kco_wc.log(response);
|
||||
},
|
||||
complete: function() {
|
||||
$('.woocommerce-checkout-review-order-table').unblock();
|
||||
kco_wc.kcoResume();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
'change': function(data) {
|
||||
kco_wc.log('change', data);
|
||||
},
|
||||
'order_total_change': function(data) {
|
||||
kco_wc.log('order_total_change', data);
|
||||
},
|
||||
'shipping_option_change': function(data) {
|
||||
kco_wc.log('shipping_option_change', data);
|
||||
},
|
||||
'can_not_complete_order': function(data) {
|
||||
kco_wc.log('can_not_complete_order', data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
kco_wc.init();
|
||||
$('body').on('blur', kco_wc.setFormData );
|
||||
$(document).on("keypress", "#kco-order-review", function(event) {
|
||||
if (event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error messages depending on
|
||||
*
|
||||
* @class Collector_Checkout_Admin_Notices
|
||||
* @version 1.0
|
||||
* @package Collector_Checkout/Classes
|
||||
* @category Class
|
||||
* @author Krokedil
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Admin_Notices {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Checks if KCO gateway is enabled.
|
||||
*
|
||||
* @var $enabled
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collector_Checkout_Admin_Notices constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
$this->enabled = $settings['enabled'];
|
||||
|
||||
add_action( 'admin_init', array( $this, 'check_settings' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the settings.
|
||||
*/
|
||||
public function check_settings() {
|
||||
if ( ! empty( $_POST ) ) {
|
||||
add_action( 'woocommerce_settings_saved', array( $this, 'check_terms' ) );
|
||||
} else {
|
||||
add_action( 'admin_notices', array( $this, 'check_terms' ) );
|
||||
add_action( 'admin_notices', array( $this, 'check_https' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if terms page is set.
|
||||
*/
|
||||
public function check_terms() {
|
||||
if ( 'yes' !== $this->enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Terms page.
|
||||
if ( ! wc_get_page_id( 'terms' ) || wc_get_page_id( 'terms' ) < 0 ) {
|
||||
echo '<div class="notice notice-error">';
|
||||
echo '<p>' . esc_html( __( 'You need to specify a terms page in WooCommerce Settings to be able to use Klarna Checkout.', 'klarna-checkout-for-woocommerce' ) ) . '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if https is configured.
|
||||
*/
|
||||
public function check_https() {
|
||||
if ( 'yes' !== $this->enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_ssl() ) {
|
||||
echo '<div class="notice notice-error">';
|
||||
echo '<p>' . esc_html( __( 'You need to enable and configure https to be able to use Klarna Checkout.', 'klarna-checkout-for-woocommerce' ) ) . '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_Admin_Notices::get_instance();
|
||||
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_AJAX class.
|
||||
*
|
||||
* Registers AJAX actions for Klarna Checkout for WooCommerce.
|
||||
*
|
||||
* @extends WC_AJAX
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_AJAX extends WC_AJAX {
|
||||
|
||||
/**
|
||||
* Hook in ajax handlers.
|
||||
*/
|
||||
public static function init() {
|
||||
self::add_ajax_events();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook in methods - uses WordPress ajax handlers (admin-ajax).
|
||||
*/
|
||||
public static function add_ajax_events() {
|
||||
$ajax_events = array(
|
||||
'kco_wc_update_cart' => true,
|
||||
'kco_wc_update_shipping' => true,
|
||||
'kco_wc_update_extra_fields' => true,
|
||||
'kco_wc_change_payment_method' => true,
|
||||
'kco_wc_update_klarna_order' => true,
|
||||
'kco_wc_iframe_shipping_address_change' => true,
|
||||
'kco_wc_checkout_error' => true,
|
||||
'kco_wc_save_form_data' => true,
|
||||
);
|
||||
|
||||
foreach ( $ajax_events as $ajax_event => $nopriv ) {
|
||||
add_action( 'wp_ajax_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) );
|
||||
if ( $nopriv ) {
|
||||
add_action( 'wp_ajax_nopriv_woocommerce_' . $ajax_event, array( __CLASS__, $ajax_event ) );
|
||||
// WC AJAX can be used for frontend ajax requests.
|
||||
add_action( 'wc_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cart quantity update function.
|
||||
*/
|
||||
public static function kco_wc_update_cart() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_update_cart' ) ) {
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
$values = array();
|
||||
parse_str( $_POST['checkout'], $values );
|
||||
$cart = $values['cart'];
|
||||
|
||||
foreach ( $cart as $cart_key => $cart_value ) {
|
||||
$new_quantity = (int) $cart_value['qty'];
|
||||
WC()->cart->set_quantity( $cart_key, $new_quantity, false );
|
||||
}
|
||||
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_fees();
|
||||
WC()->cart->calculate_totals();
|
||||
KCO_WC()->api->request_pre_update_order();
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update shipping method function.
|
||||
*/
|
||||
public static function kco_wc_update_shipping() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_update_shipping' ) ) {
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );
|
||||
|
||||
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||
|
||||
if ( isset( $_POST['shipping'] ) && is_array( $_POST['shipping'] ) ) {
|
||||
foreach ( $_POST['shipping'] as $i => $value ) {
|
||||
$chosen_shipping_methods[ $i ] = wc_clean( $value );
|
||||
}
|
||||
}
|
||||
|
||||
WC()->session->set( 'chosen_shipping_methods', $chosen_shipping_methods );
|
||||
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_fees();
|
||||
WC()->cart->calculate_totals();
|
||||
KCO_WC()->api->request_pre_update_order();
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save order notes value to session and use it when creating the order.
|
||||
*/
|
||||
public static function kco_wc_update_extra_fields() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_update_extra_fields' ) ) {
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( is_array( $_POST['extra_fields_values'] ) ) {
|
||||
$update_values = array_map( 'sanitize_textarea_field', $_POST['extra_fields_values'] );
|
||||
$session_values = WC()->session->get( 'kco_wc_extra_fields_values', array() );
|
||||
|
||||
// Update session array, instead of overwriting it.
|
||||
foreach ( $update_values as $update_key => $update_value ) {
|
||||
$session_values[ $update_key ] = $update_value;
|
||||
}
|
||||
|
||||
WC()->session->set( 'kco_wc_extra_fields_values', $session_values );
|
||||
}
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh checkout fragment.
|
||||
*/
|
||||
public static function kco_wc_change_payment_method() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_change_payment_method' ) ) {
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();
|
||||
|
||||
if ( 'false' === $_POST['kco'] ) {
|
||||
// Set chosen payment method to first gateway that is not Klarna Checkout for WooCommerce.
|
||||
$first_gateway = reset( $available_gateways );
|
||||
if ( 'kco' !== $first_gateway->id ) {
|
||||
WC()->session->set( 'chosen_payment_method', $first_gateway->id );
|
||||
} else {
|
||||
$second_gateway = next( $available_gateways );
|
||||
WC()->session->set( 'chosen_payment_method', $second_gateway->id );
|
||||
}
|
||||
} else {
|
||||
WC()->session->set( 'chosen_payment_method', 'kco' );
|
||||
}
|
||||
|
||||
WC()->payment_gateways()->set_current_gateway( $available_gateways );
|
||||
|
||||
$redirect = wc_get_checkout_url();
|
||||
$data = array(
|
||||
'redirect' => $redirect,
|
||||
);
|
||||
|
||||
wp_send_json_success( $data );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Klarna order.
|
||||
*/
|
||||
public static function kco_wc_update_klarna_order() {
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
$klarna_order_id = KCO_WC()->api->get_order_id_from_session();
|
||||
$klarna_order = KCO_WC()->api->request_pre_retrieve_order( $klarna_order_id );
|
||||
|
||||
if ( 'checkout_incomplete' === $klarna_order->status ) {
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_fees();
|
||||
WC()->cart->calculate_totals();
|
||||
KCO_WC()->api->request_pre_update_order();
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iframe change callback function.
|
||||
*/
|
||||
public static function kco_wc_iframe_shipping_address_change() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_iframe_shipping_address_change' ) ) {
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['data'] ) && is_array( $_REQUEST['data'] ) ) {
|
||||
$address = array_map( 'sanitize_text_field', $_REQUEST['data'] );
|
||||
}
|
||||
|
||||
$customer_data = array();
|
||||
|
||||
if ( isset( $address['email'] ) ) {
|
||||
$customer_data['email'] = $address['email'];
|
||||
$customer_data['billing_email'] = $address['email'];
|
||||
}
|
||||
|
||||
if ( isset( $address['postal_code'] ) ) {
|
||||
$customer_data['postcode'] = $address['postal_code'];
|
||||
$customer_data['billing_postcode'] = $address['postal_code'];
|
||||
$customer_data['shipping_postcode'] = $address['postal_code'];
|
||||
}
|
||||
|
||||
if ( isset( $address['given_name'] ) ) {
|
||||
$customer_data['first_name'] = $address['given_name'];
|
||||
$customer_data['billing_first_name'] = $address['given_name'];
|
||||
$customer_data['shipping_first_name'] = $address['given_name'];
|
||||
}
|
||||
|
||||
if ( isset( $address['family_name'] ) ) {
|
||||
$customer_data['last_name'] = $address['family_name'];
|
||||
$customer_data['billing_last_name'] = $address['family_name'];
|
||||
$customer_data['shipping_last_name'] = $address['family_name'];
|
||||
}
|
||||
|
||||
if ( isset( $address['region'] ) ) {
|
||||
$customer_data['state'] = $address['region'];
|
||||
$customer_data['billing_state'] = $address['region'];
|
||||
$customer_data['shipping_state'] = $address['region'];
|
||||
}
|
||||
|
||||
if ( isset( $address['country'] ) && kco_wc_country_code_converter( $address['country'] ) ) {
|
||||
$country = kco_wc_country_code_converter( $address['country'] );
|
||||
$customer_data['country'] = $country;
|
||||
$customer_data['billing_country'] = $country;
|
||||
$customer_data['shipping_country'] = $country;
|
||||
}
|
||||
|
||||
WC()->customer->set_props( $customer_data );
|
||||
WC()->customer->save();
|
||||
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_totals();
|
||||
|
||||
KCO_WC()->api->request_pre_update_order();
|
||||
|
||||
ob_start();
|
||||
woocommerce_order_review();
|
||||
$html = ob_get_clean();
|
||||
|
||||
wp_send_json_success( array( 'html' => $html ) );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles WooCommerce checkout error, after Klarna order has already been created.
|
||||
*/
|
||||
public static function kco_wc_checkout_error() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_checkout_error' ) ) { // Input var okay.
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['error_message'] ) ) { // Input var okay.
|
||||
$error_message = 'Error message: ' . sanitize_text_field( trim( $_POST['error_message'] ) );
|
||||
} else {
|
||||
$error_message = 'Error message could not be retreived';
|
||||
}
|
||||
|
||||
KCO_WC()->logger->log( 'Checkout form submission failed. Starting fallback order creation.... ' . $error_message );
|
||||
krokedil_log_events( null, 'Checkout form submission failed', $error_message );
|
||||
|
||||
if ( ! empty( $_GET['kco_wc_order_id'] ) ) { // Input var okay.
|
||||
$klarna_order_id = $_GET['kco_wc_order_id'];
|
||||
} else {
|
||||
$klarna_order_id = KCO_WC()->api->get_order_id_from_session();
|
||||
}
|
||||
|
||||
// Create order via fallback sequence
|
||||
$order = Klarna_Checkout_For_WooCommerce_Create_Local_Order_Fallback::create( $klarna_order_id, $error_message );
|
||||
|
||||
if( is_object( $order ) ) {
|
||||
KCO_WC()->logger->log( 'Fallback order creation done. Redirecting customer to thank you page.' );
|
||||
krokedil_log_events( null, 'Fallback order creation done. Redirecting customer to thank you page.', '' );
|
||||
$note = sprintf( __( 'This order was made as a fallback due to an error in the checkout (%s). Please verify the order with Klarna.', 'klarna-checkout-for-woocommerce' ), $error_message );
|
||||
$order->add_order_note( $note );
|
||||
$redirect_url = $order->get_checkout_order_received_url();
|
||||
} else {
|
||||
KCO_WC()->logger->log( 'Fallback order creation ERROR. Redirecting customer to simplified thank you page.' . json_decode( $order ) );
|
||||
krokedil_log_events( null, 'Fallback order creation ERROR. Redirecting customer to simplified thank you page.', $order );
|
||||
$redirect_url = wc_get_endpoint_url( 'order-received', '', wc_get_page_permalink( 'checkout' ) );
|
||||
$redirect_url = add_query_arg( 'kco_wc', 'true', $redirect_url );
|
||||
}
|
||||
|
||||
wp_send_json_success( array( 'redirect' => $redirect_url ) );
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the saving of form data to transient.
|
||||
*/
|
||||
public static function kco_wc_save_form_data() {
|
||||
if ( ! wp_verify_nonce( $_POST['nonce'], 'kco_wc_save_form_data' ) ) { // Input var okay.
|
||||
wp_send_json_error( 'bad_nonce' );
|
||||
exit;
|
||||
}
|
||||
$form = $_POST['form'];
|
||||
set_transient( WC()->session->get( 'kco_wc_order_id' ), $form, 60 * 60 * 24 );
|
||||
|
||||
wp_send_json_success();
|
||||
wp_die();
|
||||
}
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_AJAX::init();
|
||||
@@ -0,0 +1,462 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_API_Callbacks class.
|
||||
*
|
||||
* Class that handles KCO API callbacks.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_API_Callbacks {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_API_Callbacks constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_api_kco_wc_push', array( $this, 'push_cb' ) );
|
||||
add_action( 'woocommerce_api_kco_wc_notification', array( $this, 'notification_cb' ) );
|
||||
// add_action( 'woocommerce_api_kco_wc_country_change', array( $this, 'country_change_cb' ) );
|
||||
add_action( 'woocommerce_api_kco_wc_validation', array( $this, 'validation_cb' ) );
|
||||
add_action( 'woocommerce_api_kco_wc_shipping_option_update', array( $this, 'shipping_option_update_cb' ) );
|
||||
add_action( 'woocommerce_api_kco_wc_address_update', array( $this, 'address_update_cb' ) );
|
||||
add_action( 'kco_wc_punted_notification', array( $this, 'kco_wc_punted_notification_cb' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Push callback function.
|
||||
*/
|
||||
public function push_cb() {
|
||||
/**
|
||||
* 1. Handle POST request
|
||||
* 2. Request the order from Klarna
|
||||
* 3. Backup order creation
|
||||
* 4. Acknowledge the order
|
||||
* 5. Send merchant_reference1
|
||||
*/
|
||||
|
||||
// Do nothing if there's no Klarna Checkout order ID.
|
||||
if ( ! $_GET['kco_wc_order_id'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$klarna_order_id = sanitize_key( $_GET['kco_wc_order_id'] );
|
||||
|
||||
$query_args = array(
|
||||
'fields' => 'ids',
|
||||
'post_type' => wc_get_order_types(),
|
||||
'post_status' => array_keys( wc_get_order_statuses() ),
|
||||
'meta_key' => '_wc_klarna_order_id',
|
||||
'meta_value' => $klarna_order_id,
|
||||
);
|
||||
|
||||
$orders = get_posts( $query_args );
|
||||
|
||||
// If zero matching orders were found, create backup order.
|
||||
if ( empty( $orders ) ) {
|
||||
// Backup order creation.
|
||||
$this->backup_order_creation( $klarna_order_id );
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = $orders[0];
|
||||
$order = wc_get_order( $order_id );
|
||||
|
||||
if ( $order ) {
|
||||
// The order was already created. Check if order status was set (in thankyou page).
|
||||
if ( ! $order->has_status( array( 'on-hold', 'processing', 'completed' ) ) ) {
|
||||
|
||||
$response = KCO_WC()->api->request_post_get_order( $klarna_order_id );
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
krokedil_log_events( $order_id, 'Klarna push callback. Updating order status.', $klarna_order );
|
||||
|
||||
if ( 'ACCEPTED' === $klarna_order->fraud_status ) {
|
||||
$order->payment_complete( $klarna_order_id );
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Payment via Klarna Checkout, order ID: %s', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->add_order_note( $note );
|
||||
} elseif ( 'REJECTED' === $klarna_order->fraud_status ) {
|
||||
$order->update_status( 'on-hold', __( 'Klarna Checkout order was rejected.', 'klarna-checkout-for-woocommerce' ) );
|
||||
} elseif ( 'PENDING' === $klarna_order->fraud_status ) {
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Klarna order is under review, order ID: %s.', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->update_status( 'on-hold', $note );
|
||||
}
|
||||
KCO_WC()->api->request_post_acknowledge_order( $klarna_order_id );
|
||||
KCO_WC()->api->request_post_set_merchant_reference(
|
||||
$klarna_order_id,
|
||||
array(
|
||||
'merchant_reference1' => $order->get_order_number(),
|
||||
'merchant_reference2' => $order->get_id(),
|
||||
)
|
||||
);
|
||||
|
||||
} else {
|
||||
krokedil_log_events( $order_id, 'Klarna push callback. Order status already set to On hold/Processing/Completed.', $klarna_order );
|
||||
}
|
||||
|
||||
} else {
|
||||
// Backup order creation.
|
||||
$this->backup_order_creation( $klarna_order_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification callback function, used for pending orders.
|
||||
*/
|
||||
public function notification_cb() {
|
||||
/**
|
||||
* Notification callback URL has Klarna Order ID (kco_wc_order_id) in it.
|
||||
*
|
||||
* 1. Get Klarna Order ID
|
||||
* 2. Try to find matching WooCommerce order, to see if it was created
|
||||
* 3. If WooCommerce order does not exist, that means regular creation failed AND confirmation callback
|
||||
* either hasn't happened yet or failed. In this case, schedule a single event, 5 minutes from now
|
||||
* and try to get WooCommerce order then.
|
||||
* 4. If WooCommerce order does exist, fire the hook.
|
||||
*/
|
||||
|
||||
|
||||
$order_id = '';
|
||||
|
||||
if ( $_GET['kco_wc_order_id'] ) { // KCO.
|
||||
$klarna_order_id = sanitize_key( $_GET['kco_wc_order_id'] );
|
||||
$query_args = array(
|
||||
'fields' => 'ids',
|
||||
'post_type' => wc_get_order_types(),
|
||||
'post_status' => array_keys( wc_get_order_statuses() ),
|
||||
'meta_key' => '_wc_klarna_order_id',
|
||||
'meta_value' => $klarna_order_id,
|
||||
);
|
||||
|
||||
$orders = get_posts( $query_args );
|
||||
|
||||
// If zero matching orders were found, return.
|
||||
if ( ! empty( $orders ) ) {
|
||||
$order_id = $orders[0];
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' !== $order_id ) {
|
||||
do_action( 'wc_klarna_notification_listener' );
|
||||
} else {
|
||||
$post_body = file_get_contents( 'php://input' );
|
||||
$data = json_decode( $post_body, true );
|
||||
krokedil_log_events( $order_id, 'Klarna notification callback data', $data );
|
||||
wp_schedule_single_event( time() + 300, 'kco_wc_punted_notification', array( $klarna_order_id, $data ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Punted notification callback.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*/
|
||||
public function kco_wc_punted_notification_cb( $klarna_order_id, $data ) {
|
||||
do_action( 'wc_klarna_notification_listener', $klarna_order_id, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Order validation callback function.
|
||||
* Response must be sent to Klarna API.
|
||||
*
|
||||
* @link https://developers.klarna.com/api/#checkout-api-callbacks-order-validation
|
||||
*/
|
||||
public function validation_cb() {
|
||||
$post_body = file_get_contents( 'php://input' );
|
||||
$data = json_decode( $post_body, true );
|
||||
krokedil_log_events( null, 'Klarna validation callback data', $data );
|
||||
$all_in_stock = true;
|
||||
$shipping_chosen = false;
|
||||
|
||||
$form_data = get_transient( $data['order_id'] );
|
||||
$has_required_data = true;
|
||||
$failed_required_check = array();
|
||||
foreach ( $form_data as $form_row ) {
|
||||
if ( isset( $form_row['required'] ) && '' === $form_row['value'] ) {
|
||||
$has_required_data = false;
|
||||
wc_add_notice( 'test', 'error' );
|
||||
$failed_required_check[] = $form_row['name'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check stock for each item and shipping method.
|
||||
$cart_items = $data['order_lines'];
|
||||
|
||||
foreach ( $cart_items as $cart_item ) {
|
||||
if ( 'physical' === $cart_item['type'] ) {
|
||||
// Get product by SKU or ID.
|
||||
if ( wc_get_product_id_by_sku( $cart_item['reference'] ) ) {
|
||||
$cart_item_product = wc_get_product( wc_get_product_id_by_sku( $cart_item['reference'] ) );
|
||||
} else {
|
||||
$cart_item_product = wc_get_product( $cart_item['reference'] );
|
||||
}
|
||||
|
||||
if ( $cart_item_product ) {
|
||||
if ( ! $cart_item_product->has_enough_stock( $cart_item['quantity'] ) ) {
|
||||
$all_in_stock = false;
|
||||
}
|
||||
if( ! $cart_item_product->is_virtual() ) {
|
||||
$needs_shipping = true;
|
||||
}
|
||||
}
|
||||
} elseif ( 'shipping_fee' === $cart_item['type'] ) {
|
||||
$shipping_chosen = true;
|
||||
}
|
||||
}
|
||||
|
||||
do_action( 'kco_validate_checkout', $data, $all_in_stock, $shipping_chosen );
|
||||
if ( $all_in_stock && $shipping_chosen && $has_required_data ) {
|
||||
header( 'HTTP/1.0 200 OK' );
|
||||
} else {
|
||||
header( 'HTTP/1.0 303 See Other' );
|
||||
if ( ! $all_in_stock ) {
|
||||
$logger = new WC_Logger();
|
||||
$logger->add( 'klarna-checkout-for-woocommerce', 'Stock validation failed for SKU ' . $cart_item['reference'] );
|
||||
header( 'Location: ' . wc_get_cart_url() . '?stock_validate_failed' );
|
||||
} elseif ( ! $shipping_chosen && $needs_shipping ) {
|
||||
header( 'Location: ' . wc_get_checkout_url() . '?no_shipping' );
|
||||
} elseif ( ! $has_required_data ) {
|
||||
$validation_hash = base64_encode( json_encode( $failed_required_check ) );
|
||||
header( 'Location: ' . wc_get_checkout_url() . '?required_fields=' . $validation_hash );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipping option update callback function.
|
||||
* Response must be sent to Klarna API.
|
||||
*
|
||||
* @link https://developers.klarna.com/api/#checkout-api-callbacks-shipping-option-update
|
||||
*/
|
||||
public function shipping_option_update_cb() {
|
||||
// Send back order amount, order tax amount, order lines, purchase currency and status 200
|
||||
}
|
||||
|
||||
/**
|
||||
* Address update callback function.
|
||||
* Response must be sent to Klarna API.
|
||||
*
|
||||
* @link https://developers.klarna.com/api/#checkout-api-callbacks-address-update
|
||||
* @ref https://github.com/mmartche/coach/blob/30022c266089fc7499c54e149883e951c288dc9f/catalog/controller/extension/payment/klarna_checkout.php#L509
|
||||
*/
|
||||
public function address_update_cb() {
|
||||
// Currently disabled, because of how response body needs to be calculated in WooCommerce.
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup order creation, in case checkout process failed.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
public function backup_order_creation( $klarna_order_id ) {
|
||||
$response = KCO_WC()->api->request_post_get_order( $klarna_order_id );
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
|
||||
// Process customer data.
|
||||
$this->process_customer_data( $klarna_order );
|
||||
|
||||
// Process customer data.
|
||||
$this->process_cart( $klarna_order );
|
||||
|
||||
// Process order.
|
||||
$this->process_order( $klarna_order );
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes customer data on backup order creation.
|
||||
*
|
||||
* @param Klarna_Checkout_Order $klarna_order Klarna order.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
private function process_customer_data( $klarna_order ) {
|
||||
// First name.
|
||||
WC()->customer->set_billing_first_name( sanitize_text_field( $klarna_order->billing_address->given_name ) );
|
||||
WC()->customer->set_shipping_first_name( sanitize_text_field( $klarna_order->shipping_address->given_name ) );
|
||||
|
||||
// Last name.
|
||||
WC()->customer->set_billing_last_name( sanitize_text_field( $klarna_order->billing_address->family_name ) );
|
||||
WC()->customer->set_shipping_last_name( sanitize_text_field( $klarna_order->shipping_address->family_name ) );
|
||||
|
||||
// Country.
|
||||
WC()->customer->set_billing_country( sanitize_text_field( $klarna_order->billing_address->country ) );
|
||||
WC()->customer->set_shipping_country( sanitize_text_field( $klarna_order->shipping_address->country ) );
|
||||
|
||||
// Street address 1.
|
||||
WC()->customer->set_billing_address_1( sanitize_text_field( $klarna_order->billing_address->street_address ) );
|
||||
WC()->customer->set_shipping_address_1( sanitize_text_field( $klarna_order->shipping_address->street_address ) );
|
||||
|
||||
// Street address 2.
|
||||
WC()->customer->set_billing_address_2( sanitize_text_field( $klarna_order->billing_address->street_address2 ) );
|
||||
WC()->customer->set_shipping_address_2( sanitize_text_field( $klarna_order->shipping_address->street_address2 ) );
|
||||
|
||||
// City.
|
||||
WC()->customer->set_billing_city( sanitize_text_field( $klarna_order->billing_address->city ) );
|
||||
WC()->customer->set_shipping_city( sanitize_text_field( $klarna_order->shipping_address->city ) );
|
||||
|
||||
// County/State.
|
||||
WC()->customer->set_billing_state( sanitize_text_field( $klarna_order->billing_address->region ) );
|
||||
WC()->customer->set_shipping_state( sanitize_text_field( $klarna_order->shipping_address->region ) );
|
||||
|
||||
// Postcode.
|
||||
WC()->customer->set_billing_postcode( sanitize_text_field( $klarna_order->billing_address->postal_code ) );
|
||||
WC()->customer->set_shipping_postcode( sanitize_text_field( $klarna_order->shipping_address->postal_code ) );
|
||||
|
||||
// Phone.
|
||||
WC()->customer->set_billing_phone( sanitize_text_field( $klarna_order->billing_address->phone ) );
|
||||
|
||||
// Email.
|
||||
WC()->customer->set_billing_email( sanitize_text_field( $klarna_order->billing_address->email ) );
|
||||
|
||||
WC()->customer->save();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes cart contents on backup order creation.
|
||||
*
|
||||
* @param Klarna_Checkout_Order $klarna_order Klarna order.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
private function process_cart( $klarna_order ) {
|
||||
WC()->cart->empty_cart();
|
||||
|
||||
foreach ( $klarna_order->order_lines as $cart_item ) {
|
||||
if ( 'physical' === $cart_item->type ) {
|
||||
if ( wc_get_product_id_by_sku( $cart_item->reference ) ) {
|
||||
$id = wc_get_product_id_by_sku( $cart_item->reference );
|
||||
} else {
|
||||
$id = $cart_item->reference;
|
||||
}
|
||||
|
||||
try {
|
||||
WC()->cart->add_to_cart( $id, $cart_item->quantity );
|
||||
} catch ( Exception $e ) {
|
||||
$logger = new WC_Logger();
|
||||
$logger->add( 'klarna-checkout-for-woocommerce', 'Backup order creation error add to cart error: ' . $e->getCode() . ' - ' . $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_fees();
|
||||
WC()->cart->calculate_totals();
|
||||
|
||||
// Check cart items (quantity, coupon validity etc).
|
||||
if ( ! WC()->cart->check_cart_items() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
WC()->cart->check_cart_coupons();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes WooCommerce order on backup order creation.
|
||||
*
|
||||
* @param Klarna_Checkout_Order $klarna_order Klarna order.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
private function process_order( $klarna_order ) {
|
||||
try {
|
||||
$order = new WC_Order();
|
||||
|
||||
$order->set_billing_first_name( sanitize_text_field( $klarna_order->billing_address->given_name ) );
|
||||
$order->set_billing_last_name( sanitize_text_field( $klarna_order->billing_address->family_name ) );
|
||||
$order->set_billing_country( sanitize_text_field( $klarna_order->billing_address->country ) );
|
||||
$order->set_billing_address_1( sanitize_text_field( $klarna_order->billing_address->street_address ) );
|
||||
$order->set_billing_address_2( sanitize_text_field( $klarna_order->billing_address->street_address2 ) );
|
||||
$order->set_billing_city( sanitize_text_field( $klarna_order->billing_address->city ) );
|
||||
$order->set_billing_state( sanitize_text_field( $klarna_order->billing_address->region ) );
|
||||
$order->set_billing_postcode( sanitize_text_field( $klarna_order->billing_address->postal_code ) );
|
||||
$order->set_billing_phone( sanitize_text_field( $klarna_order->billing_address->phone ) );
|
||||
$order->set_billing_email( sanitize_text_field( $klarna_order->billing_address->email ) );
|
||||
|
||||
$order->set_shipping_first_name( sanitize_text_field( $klarna_order->shipping_address->given_name ) );
|
||||
$order->set_shipping_last_name( sanitize_text_field( $klarna_order->shipping_address->family_name ) );
|
||||
$order->set_shipping_country( sanitize_text_field( $klarna_order->shipping_address->country ) );
|
||||
$order->set_shipping_address_1( sanitize_text_field( $klarna_order->shipping_address->street_address ) );
|
||||
$order->set_shipping_address_2( sanitize_text_field( $klarna_order->shipping_address->street_address2 ) );
|
||||
$order->set_shipping_city( sanitize_text_field( $klarna_order->shipping_address->city ) );
|
||||
$order->set_shipping_state( sanitize_text_field( $klarna_order->shipping_address->region ) );
|
||||
$order->set_shipping_postcode( sanitize_text_field( $klarna_order->shipping_address->postal_code ) );
|
||||
|
||||
$order->set_created_via( 'klarna_checkout_backup_order_creation' );
|
||||
$order->set_currency( sanitize_text_field( $klarna_order->purchase_currency ) );
|
||||
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
|
||||
$order->set_payment_method( 'kco' );
|
||||
|
||||
$order->set_shipping_total( WC()->cart->get_shipping_total() );
|
||||
$order->set_discount_total( WC()->cart->get_discount_total() );
|
||||
$order->set_discount_tax( WC()->cart->get_discount_tax() );
|
||||
$order->set_cart_tax( WC()->cart->get_cart_contents_tax() + WC()->cart->get_fee_tax() );
|
||||
$order->set_shipping_tax( WC()->cart->get_shipping_tax() );
|
||||
$order->set_total( WC()->cart->get_total( 'edit' ) );
|
||||
|
||||
WC()->checkout()->create_order_line_items( $order, WC()->cart );
|
||||
WC()->checkout()->create_order_fee_lines( $order, WC()->cart );
|
||||
WC()->checkout()->create_order_shipping_lines( $order, WC()->session->get( 'chosen_shipping_methods' ), WC()->shipping->get_packages() );
|
||||
WC()->checkout()->create_order_tax_lines( $order, WC()->cart );
|
||||
WC()->checkout()->create_order_coupon_lines( $order, WC()->cart );
|
||||
|
||||
$order->save();
|
||||
|
||||
if ( 'ACCEPTED' === $klarna_order->fraud_status ) {
|
||||
$order->payment_complete( $klarna_order->order_id );
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Payment via Klarna Checkout, order ID: %s', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->add_order_note( $note );
|
||||
} elseif ( 'REJECTED' === $klarna_order->fraud_status ) {
|
||||
$order->update_status( 'on-hold', __( 'Klarna Checkout order was rejected.', 'klarna-checkout-for-woocommerce' ) );
|
||||
} elseif ( 'PENDING' === $klarna_order->fraud_status ) {
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Klarna order is under review, order ID: %s.', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->update_status( 'on-hold', $note );
|
||||
}
|
||||
KCO_WC()->api->request_post_acknowledge_order( $klarna_order->order_id );
|
||||
KCO_WC()->api->request_post_set_merchant_reference(
|
||||
$klarna_order->order_id,
|
||||
array(
|
||||
'merchant_reference1' => $order->get_order_number(),
|
||||
'merchant_reference2' => $order->get_id(),
|
||||
)
|
||||
);
|
||||
|
||||
if ( (int) round( $order->get_total() * 100 ) !== (int) $klarna_order->order_amount ) {
|
||||
$order->update_status( 'on-hold', sprintf(__( 'Order needs manual review, WooCommerce total and Klarna total do not match. Klarna order total: %s.', 'klarna-checkout-for-woocommerce' ), $klarna_order->order_amount ) );
|
||||
}
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
$logger = new WC_Logger();
|
||||
$logger->add( 'klarna-checkout-for-woocommerce', 'Backup order creation error: ' . $e->getCode() . ' - ' . $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_API_Callbacks::get_instance();
|
||||
@@ -0,0 +1,703 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_API class.
|
||||
*
|
||||
* Class that talks to KCO API, wrapper for V2 and V3.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_API {
|
||||
|
||||
/**
|
||||
* Klarna Checkout for WooCommerce settings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $settings = array();
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_API constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->settings = get_option( 'woocommerce_kco_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Klarna Checkout order.
|
||||
*
|
||||
* @return array|mixed|object|WP_Error
|
||||
*/
|
||||
public function request_pre_create_order() {
|
||||
$request_url = $this->get_api_url_base() . 'checkout/v3/orders';
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
'body' => $this->get_request_body( 'create' ),
|
||||
);
|
||||
$log_array = array(
|
||||
'headers' => $request_args['headers'],
|
||||
'user-agent' => $request_args['user-agent'],
|
||||
'body' => json_decode( $request_args['body'] ),
|
||||
);
|
||||
KCO_WC()->logger->log( 'Create Klarna order (' . $request_url . ') ' . json_encode( $request_args ) );
|
||||
krokedil_log_events( null, 'Pre Create Order request args', $log_array );
|
||||
$response = wp_safe_remote_post( $request_url, $request_args );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $this->extract_error_messages( $response );
|
||||
}
|
||||
|
||||
if ( $response['response']['code'] >= 200 && $response['response']['code'] <= 299 ) {
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
$this->save_order_id_to_session( sanitize_key( $klarna_order->order_id ) );
|
||||
$this->save_order_api_to_session( $klarna_order );
|
||||
$log_order = clone $klarna_order;
|
||||
$log_order->html_snippet = '';
|
||||
krokedil_log_events( null, 'Pre Create Order response', $log_order );
|
||||
return $klarna_order;
|
||||
} else if( $response['response']['code'] === 405 ) {
|
||||
$error = $response['response']['message'];
|
||||
return $error;
|
||||
} else {
|
||||
$error = $this->extract_error_messages( $response );
|
||||
krokedil_log_events( null, 'Pre Create Order response', $error );
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve ongoing Klarna order.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*
|
||||
* @return object $klarna_order Klarna order.
|
||||
*/
|
||||
public function request_pre_retrieve_order( $klarna_order_id ) {
|
||||
$request_url = $this->get_api_url_base() . 'checkout/v3/orders/' . $klarna_order_id;
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
);
|
||||
krokedil_log_events( null, 'Pre Retrieve Order request args', $request_args );
|
||||
KCO_WC()->logger->log( 'Retrieve ongoing Klarna order (' . $request_url . ') ' . json_encode( $request_args ) );
|
||||
|
||||
$response = wp_safe_remote_get( $request_url, $request_args );
|
||||
|
||||
if ( $response['response']['code'] >= 200 && $response['response']['code'] <= 299 ) {
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
$log_order = clone $klarna_order;
|
||||
$log_order->html_snippet = '';
|
||||
krokedil_log_events( null, 'Pre Retrieve Order response', $log_order );
|
||||
return $klarna_order;
|
||||
} else {
|
||||
$error = $this->extract_error_messages( $response );
|
||||
krokedil_log_events( null, 'Pre Retrieve Order response', $error );
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ongoing Klarna order.
|
||||
*
|
||||
* @return object $klarna_order Klarna order.
|
||||
*/
|
||||
public function request_pre_update_order() {
|
||||
$klarna_order_id = $this->get_order_id_from_session();
|
||||
$request_url = $this->get_api_url_base() . 'checkout/v3/orders/' . $klarna_order_id;
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
'body' => $this->get_request_body(),
|
||||
);
|
||||
$log_array = array(
|
||||
'headers' => $request_args['headers'],
|
||||
'user-agent' => $request_args['user-agent'],
|
||||
'body' => json_decode( $request_args['body'] ),
|
||||
);
|
||||
// No update if nothing changed in data being sent to Klarna.
|
||||
if ( WC()->session->get( 'kco_wc_update_md5' ) && WC()->session->get( 'kco_wc_update_md5' ) === md5( serialize( $request_args ) ) ) {
|
||||
return;
|
||||
}
|
||||
krokedil_log_events( null, 'Pre Update Order request args', $log_array );
|
||||
KCO_WC()->logger->log( 'Update ongoing Klarna order (' . $request_url . ') ' . json_encode( $request_args ) );
|
||||
|
||||
$response = wp_safe_remote_post( $request_url, $request_args );
|
||||
|
||||
if ( $response['response']['code'] >= 200 && $response['response']['code'] <= 299 ) {
|
||||
WC()->session->set( 'kco_wc_update_md5', md5( serialize( $request_args ) ) );
|
||||
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
$log_order = clone $klarna_order;
|
||||
$log_order->html_snippet = '';
|
||||
krokedil_log_events( null, 'Pre Update Order response', $log_order );
|
||||
return $klarna_order;
|
||||
} else {
|
||||
WC()->session->__unset( 'kco_wc_update_md5' );
|
||||
WC()->session->__unset( 'kco_wc_order_id' );
|
||||
$error = $this->extract_error_messages( $response );
|
||||
krokedil_log_events( null, 'Pre Update Order response', $error );
|
||||
return $error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Acknowledges Klarna Checkout order.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*
|
||||
* @return WP_Error|array $response
|
||||
*/
|
||||
public function request_post_get_order( $klarna_order_id ) {
|
||||
$request_url = $this->get_api_url_base() . 'ordermanagement/v1/orders/' . $klarna_order_id;
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
);
|
||||
$response = wp_safe_remote_get( $request_url, $request_args );
|
||||
krokedil_log_events( null, 'Post Get Order response', stripslashes_deep( $response ) );
|
||||
KCO_WC()->logger->log( 'Post Get Order response (' . $request_url . ') ' . stripslashes_deep( json_encode( $response ) ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledges Klarna Checkout order.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*
|
||||
* @return WP_Error|array $response
|
||||
*/
|
||||
public function request_post_acknowledge_order( $klarna_order_id ) {
|
||||
$request_url = $this->get_api_url_base() . 'ordermanagement/v1/orders/' . $klarna_order_id . '/acknowledge';
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
);
|
||||
|
||||
$response = wp_safe_remote_post( $request_url, $request_args );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds WooCommerce order ID to Klarna order as merchant_reference. And clear Klarna order ID value from WC session.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
* @param array $merchant_references Array of merchant references.
|
||||
*
|
||||
* @return WP_Error|array $response
|
||||
*/
|
||||
public function request_post_set_merchant_reference( $klarna_order_id, $merchant_references ) {
|
||||
$request_url = $this->get_api_url_base() . 'ordermanagement/v1/orders/' . $klarna_order_id . '/merchant-references';
|
||||
$request_args = array(
|
||||
'headers' => $this->get_request_headers(),
|
||||
'user-agent' => $this->get_user_agent(),
|
||||
'method' => 'PATCH',
|
||||
'body' => wp_json_encode( array(
|
||||
'merchant_reference1' => $merchant_references['merchant_reference1'],
|
||||
'merchant_reference2' => $merchant_references['merchant_reference2'],
|
||||
) ),
|
||||
);
|
||||
|
||||
$response = wp_safe_remote_request( $request_url, $request_args );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API URL base.
|
||||
*/
|
||||
public function get_api_url_base() {
|
||||
$base_location = wc_get_base_location();
|
||||
$country_string = 'US' === $base_location['country'] ? '-na' : '';
|
||||
$test_string = 'yes' === $this->settings['testmode'] ? '.playground' : '';
|
||||
|
||||
return 'https://api' . $country_string . $test_string . '.klarna.com/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna order from WC_Session
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function get_order_id_from_session() {
|
||||
return WC()->session->get( 'kco_wc_order_id' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves Klarna order ID to WooCommerce session.
|
||||
*
|
||||
* @param string $order_id Klarna order ID.
|
||||
*/
|
||||
public function save_order_id_to_session( $order_id ) {
|
||||
WC()->session->set( 'kco_wc_order_id', $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves Klarna order API to WooCommerce session.
|
||||
*
|
||||
* 'na' or 'eu', used for order updates, to avoid trying to switch API when updating KCO Global orders.
|
||||
*
|
||||
* @param string $klarna_order Klarna order.
|
||||
*/
|
||||
public function save_order_api_to_session() {
|
||||
if ( 'US' === $this->get_purchase_country() ) {
|
||||
$api = 'US';
|
||||
} else {
|
||||
$api = 'EU';
|
||||
}
|
||||
|
||||
WC()->session->set( 'kco_wc_order_api', $api );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna Checkout order.
|
||||
*
|
||||
* If WC_Session value for Klarna order ID exists, attempt to retrieve that order.
|
||||
* If this fails, create a new one and retrieve it.
|
||||
* If WC_Session value for Klarna order ID does not exist, create a new order and retrieve it.
|
||||
*
|
||||
* @return Klarna_Checkout_Order $order Klarna order.
|
||||
*/
|
||||
public function get_order() {
|
||||
$order_id = $this->get_order_id_from_session();
|
||||
|
||||
if ( $order_id ) {
|
||||
$order = $this->request_pre_retrieve_order( $order_id );
|
||||
|
||||
if ( ! $order || is_wp_error( $order ) ) {
|
||||
$order = $this->request_pre_create_order();
|
||||
} elseif ( 'checkout_incomplete' === $order->status ) {
|
||||
// Only update order if its status is incomplete.
|
||||
$this->request_pre_update_order();
|
||||
}
|
||||
} else {
|
||||
if ( is_order_received_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$order = $this->request_pre_create_order();
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets KCO iframe snippet from KCO order.
|
||||
*
|
||||
* @param Klarna_Order $order Klarna Checkout order.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_snippet( $order ) {
|
||||
if ( ! is_wp_error( $order ) ) {
|
||||
$this->maybe_clear_session_values( $order );
|
||||
|
||||
return $order->html_snippet;
|
||||
}
|
||||
|
||||
return $order->get_error_message();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear WooCommerce session values if Klarna Checkout order is completed.
|
||||
*
|
||||
* @param Klarna_Order $order Klarna Checkout order.
|
||||
*/
|
||||
public function maybe_clear_session_values( $order ) {
|
||||
if ( 'checkout_complete' === $order->status ) {
|
||||
WC()->session->__unset( 'kco_wc_update_md5' );
|
||||
WC()->session->__unset( 'kco_wc_order_id' );
|
||||
WC()->session->__unset( 'kco_wc_order_notes' );
|
||||
WC()->session->__unset( 'kco_wc_order_api' );
|
||||
WC()->session->__unset( 'kco_wc_extra_fields_values' );
|
||||
WC()->session->__unset( 'kco_wc_prefill_consent' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna merchant ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_merchant_id() {
|
||||
$credentials = KCO_WC()->credentials->get_credentials_from_session();
|
||||
|
||||
return $credentials['merchant_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna shared secret.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_shared_secret() {
|
||||
$credentials = KCO_WC()->credentials->get_credentials_from_session();
|
||||
|
||||
return $credentials['shared_secret'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets country for Klarna purchase.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_purchase_country() {
|
||||
$base_location = wc_get_base_location();
|
||||
$country = $base_location['country'];
|
||||
|
||||
return $country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets currency for Klarna purchase.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_purchase_currency() {
|
||||
return get_woocommerce_currency();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets locale for Klarna purchase.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_purchase_locale() {
|
||||
|
||||
if ( defined( 'ICL_LANGUAGE_CODE' ) ) {
|
||||
$locale = ICL_LANGUAGE_CODE;
|
||||
} else {
|
||||
$locale = explode('_', get_locale());
|
||||
$locale = $locale[0];
|
||||
}
|
||||
|
||||
switch ( WC()->checkout()->get_value( 'billing_country' ) ) {
|
||||
case 'AT':
|
||||
if ( 'de' == $locale ) {
|
||||
$klarna_locale = 'de-at';
|
||||
} else {
|
||||
$klarna_locale = 'en-at';
|
||||
}
|
||||
break;
|
||||
case 'DE':
|
||||
if ( 'de' == $locale ) {
|
||||
$klarna_locale = 'de-de';
|
||||
} else {
|
||||
$klarna_locale = 'en-de';
|
||||
}
|
||||
break;
|
||||
case 'DK':
|
||||
if ( 'da' == $locale ) {
|
||||
$klarna_locale = 'da-dk';
|
||||
} else {
|
||||
$klarna_locale = 'en-dk';
|
||||
}
|
||||
break;
|
||||
case 'FI':
|
||||
if ( 'fi' == $locale ) {
|
||||
$klarna_locale = 'fi-fi';
|
||||
} elseif( 'sv' == $locale ) {
|
||||
$klarna_locale = 'sv-fi';
|
||||
} else {
|
||||
$klarna_locale = 'en-fi';
|
||||
}
|
||||
break;
|
||||
case 'NL':
|
||||
if ( 'nl' == $locale ) {
|
||||
$klarna_locale = 'nl-nl';
|
||||
} else {
|
||||
$klarna_locale = 'en-nl';
|
||||
}
|
||||
break;
|
||||
case 'NO':
|
||||
if ( 'nb' == $locale || 'nn' == $locale ) {
|
||||
$klarna_locale = 'nb-no';
|
||||
} else {
|
||||
$klarna_locale = 'en-no';
|
||||
}
|
||||
break;
|
||||
case 'SE':
|
||||
if ( 'sv' == $locale ) {
|
||||
$klarna_locale = 'sv-se';
|
||||
} else {
|
||||
$klarna_locale = 'en-se';
|
||||
}
|
||||
break;
|
||||
case 'GB':
|
||||
$klarna_locale = 'en-gb';
|
||||
break;
|
||||
case 'US':
|
||||
$klarna_locale = 'en-us';
|
||||
break;
|
||||
default:
|
||||
$klarna_locale = 'en-us';
|
||||
} // End switch().
|
||||
|
||||
return $klarna_locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets merchant URLs for Klarna purchase.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_merchant_urls() {
|
||||
return KCO_WC()->merchant_urls->get_urls();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API request headers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_request_headers() {
|
||||
$request_headers = array(
|
||||
'Authorization' => 'Basic ' . base64_encode( $this->get_merchant_id() . ':' . $this->get_shared_secret() ),
|
||||
'Content-Type' => 'application/json',
|
||||
);
|
||||
|
||||
return $request_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API request headers.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_user_agent() {
|
||||
$user_agent = apply_filters( 'http_headers_useragent', 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ) ) . ' - KCO:' . KCO_WC_VERSION . ' - PHP Version: ' . phpversion() . ' - Krokedil';
|
||||
|
||||
return $user_agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API request body.
|
||||
*
|
||||
* @TODO: Clean this up by using maybe_add functions.
|
||||
*
|
||||
* @param string $request_type Type of request.
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function get_request_body( $request_type = null ) {
|
||||
KCO_WC()->order_lines->process_data();
|
||||
|
||||
$request_args = array(
|
||||
'purchase_country' => $this->get_purchase_country(),
|
||||
'purchase_currency' => $this->get_purchase_currency(),
|
||||
'locale' => $this->get_purchase_locale(),
|
||||
'merchant_urls' => $this->get_merchant_urls(),
|
||||
'order_amount' => KCO_WC()->order_lines->get_order_amount(),
|
||||
'order_tax_amount' => KCO_WC()->order_lines->get_order_tax_amount(),
|
||||
'order_lines' => KCO_WC()->order_lines->get_order_lines(),
|
||||
'shipping_countries' => $this->get_shipping_countries(),
|
||||
);
|
||||
|
||||
if ( kco_wc_prefill_allowed() ) {
|
||||
$request_args['billing_address'] = array(
|
||||
'email' => WC()->checkout()->get_value( 'billing_email' ),
|
||||
'postal_code' => WC()->checkout()->get_value( 'billing_postcode' ),
|
||||
'country' => WC()->checkout()->get_value( 'billing_country' ),
|
||||
'phone' => WC()->checkout()->get_value( 'billing_phone' ),
|
||||
'given_name' => WC()->checkout()->get_value( 'billing_first_name' ),
|
||||
'family_name' => WC()->checkout()->get_value( 'billing_last_name' ),
|
||||
'street_address' => WC()->checkout()->get_value( 'billing_address_1' ),
|
||||
'street_address2' => WC()->checkout()->get_value( 'billing_address_2' ),
|
||||
'city' => WC()->checkout()->get_value( 'billing_city' ),
|
||||
'region' => WC()->checkout()->get_value( 'billing_state' ),
|
||||
);
|
||||
}
|
||||
|
||||
$request_args['options']['title_mandatory'] = $this->get_title_mandatory();
|
||||
$request_args['options'] = array();
|
||||
$request_args['options']['allow_separate_shipping_address'] = $this->get_allow_separate_shipping_address();
|
||||
$request_args['options']['date_of_birth_mandatory'] = $this->get_dob_mandatory();
|
||||
$request_args['options']['national_identification_number_mandatory'] = $this->get_dob_mandatory();
|
||||
$request_args['options']['title_mandatory'] = $this->get_title_mandatory();
|
||||
|
||||
if ( $this->get_iframe_colors() ) {
|
||||
$request_args['options'] = array_merge( $request_args['options'], $this->get_iframe_colors() );
|
||||
}
|
||||
|
||||
if ( $this->get_shipping_details() ) {
|
||||
$request_args['options']['shipping_details'] = $this->get_shipping_details();
|
||||
}
|
||||
|
||||
// Allow external payment method plugin to do its thing.
|
||||
// @TODO: Extract this into a hooked function.
|
||||
if ( 'create' === $request_type ) {
|
||||
if ( in_array( $this->get_purchase_country(), array( 'SE', 'NO', 'FI' ), true ) ) {
|
||||
if ( isset( $this->settings['allowed_customer_types'] ) ) {
|
||||
$customer_types_setting = $this->settings['allowed_customer_types'];
|
||||
|
||||
switch ( $customer_types_setting ) {
|
||||
case 'B2B':
|
||||
$allowed_customer_types = array( 'organization' );
|
||||
$customer_type = 'organization';
|
||||
break;
|
||||
case 'B2BC':
|
||||
$allowed_customer_types = array( 'person', 'organization' );
|
||||
$customer_type = 'organization';
|
||||
break;
|
||||
case 'B2CB':
|
||||
$allowed_customer_types = array( 'person', 'organization' );
|
||||
$customer_type = 'person';
|
||||
break;
|
||||
default:
|
||||
$allowed_customer_types = array( 'person' );
|
||||
$customer_type = 'person';
|
||||
}
|
||||
|
||||
$request_args['options']['allowed_customer_types'] = $allowed_customer_types;
|
||||
$request_args['customer']['type'] = $customer_type;
|
||||
}
|
||||
}
|
||||
|
||||
$request_args = apply_filters( 'kco_wc_create_order', $request_args );
|
||||
}
|
||||
|
||||
$request_body = wp_json_encode( apply_filters( 'kco_wc_api_request_args', $request_args ) );
|
||||
|
||||
return $request_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets shipping countries formatted for Klarna.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_shipping_countries() {
|
||||
$wc_countries = new WC_Countries();
|
||||
|
||||
return array_keys( $wc_countries->get_shipping_countries() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets allowed separate shipping details option.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_allow_separate_shipping_address() {
|
||||
$allow_separate_shipping = array_key_exists( 'allow_separate_shipping', $this->settings ) && 'yes' === $this->settings['allow_separate_shipping'];
|
||||
|
||||
return $allow_separate_shipping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date of birth mandatory option.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_dob_mandatory() {
|
||||
$dob_mandatory = array_key_exists( 'dob_mandatory', $this->settings ) && 'yes' === $this->settings['dob_mandatory'];
|
||||
|
||||
return $dob_mandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date of birth mandatory option.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_title_mandatory() {
|
||||
$title_mandatory = array_key_exists( 'title_mandatory', $this->settings ) && 'yes' === $this->settings['title_mandatory'];
|
||||
|
||||
return $title_mandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets shipping details note.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function get_shipping_details() {
|
||||
if ( array_key_exists( 'shipping_details', $this->settings ) ) {
|
||||
return $this->settings['shipping_details'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets iframe color settings.
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
private function get_iframe_colors() {
|
||||
$color_settings = array();
|
||||
|
||||
if ( $this->check_option_field( 'color_button' ) ) {
|
||||
$color_settings['color_button'] = $this->check_option_field( 'color_button' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'color_button_text' ) ) {
|
||||
$color_settings['color_button_text'] = $this->check_option_field( 'color_button_text' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'color_checkbox' ) ) {
|
||||
$color_settings['color_checkbox'] = $this->check_option_field( 'color_checkbox' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'color_checkbox_checkmark' ) ) {
|
||||
$color_settings['color_checkbox_checkmark'] = $this->check_option_field( 'color_checkbox_checkmark' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'color_header' ) ) {
|
||||
$color_settings['color_header'] = $this->check_option_field( 'color_header' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'color_link' ) ) {
|
||||
$color_settings['color_link'] = $this->check_option_field( 'color_link' );
|
||||
}
|
||||
|
||||
if ( $this->check_option_field( 'radius_border' ) ) {
|
||||
$color_settings['radius_border'] = $this->check_option_field( 'radius_border' );
|
||||
}
|
||||
|
||||
if ( count( $color_settings ) > 0 ) {
|
||||
return $color_settings;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function check_option_field( $field ) {
|
||||
if ( array_key_exists( $field, $this->settings ) && '' !== $this->settings[ $field ] ) {
|
||||
return $this->settings[ $field ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts error messages from Klarna's response.
|
||||
*
|
||||
* @param mixed $response Klarna API response.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function extract_error_messages( $response ) {
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response_body = json_decode( $response['body'] );
|
||||
$error = new WP_Error();
|
||||
|
||||
if ( ! empty( $response_body->error_messages ) && is_array( $response_body->error_messages ) ) {
|
||||
KCO_WC()->logger->log( var_export( $response_body, true ) );
|
||||
|
||||
foreach ( $response_body->error_messages as $error_message ) {
|
||||
$error->add( 'kco', $error_message );
|
||||
}
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Confirmation class.
|
||||
*
|
||||
* Handles Klarna Checkout confirmation page.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Confirmation {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Confirmation constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_head', array( $this, 'maybe_hide_checkout_form' ) );
|
||||
add_action( 'woocommerce_before_checkout_form', array( $this, 'maybe_populate_wc_checkout' ) );
|
||||
add_action( 'wp_footer', array( $this, 'maybe_submit_wc_checkout' ), 999 );
|
||||
add_filter( 'the_title', array( $this, 'confirm_page_title' ) );
|
||||
add_filter( 'woocommerce_checkout_fields', array( $this, 'unrequire_fields' ), 99 );
|
||||
add_filter( 'woocommerce_checkout_posted_data', array( $this, 'unrequire_posted_data' ), 99 );
|
||||
add_action( 'woocommerce_checkout_after_order_review', array( $this, 'add_kco_order_id_field' ) );
|
||||
add_action( 'woocommerce_checkout_create_order', array( $this, 'save_kco_order_id_field' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Checkout page title in confirmation page.
|
||||
*
|
||||
* @param $title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function confirm_page_title( $title ) {
|
||||
if ( ! is_admin() && is_main_query() && in_the_loop() && is_page() && is_checkout() && isset( $_GET['confirm'] ) && 'yes' === $_GET['confirm'] ) {
|
||||
$title = __( 'Please wait while we process your order.', 'klarna-checkout-for-woocommerce' );
|
||||
remove_filter( 'the_title', array( $this, 'confirm_page_title' ) );
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides WooCommerce checkout form in KCO confirmation page.
|
||||
*/
|
||||
public function maybe_hide_checkout_form() {
|
||||
if ( ! $this->is_kco_confirmation() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<style>form.woocommerce-checkout,div.woocommerce-info{display:none!important}</style>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates WooCommerce checkout form in KCO confirmation page.
|
||||
*/
|
||||
public function maybe_populate_wc_checkout( $checkout ) {
|
||||
if ( ! $this->is_kco_confirmation() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<div id="kco-confirm-loading"></div>';
|
||||
|
||||
$klarna_order_id = WC()->session->get( 'kco_wc_order_id' );
|
||||
$response = KCO_WC()->api->request_post_get_order( $klarna_order_id );
|
||||
$klarna_order = apply_filters( 'kco_wc_klarna_order_pre_submit', json_decode( $response['body'] ) );
|
||||
|
||||
$this->save_customer_data( $klarna_order );
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits WooCommerce checkout form in KCO confirmation page.
|
||||
*/
|
||||
public function maybe_submit_wc_checkout() {
|
||||
if ( ! $this->is_kco_confirmation() ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<script>
|
||||
jQuery(function ($) {
|
||||
$('input#terms').prop('checked', true);
|
||||
|
||||
// If order value = 0, payment method fields will not be in the page, so we need to
|
||||
if (!$('input#payment_method_kco').length) {
|
||||
$('#order_review').append('<input id="payment_method_kco" type="radio" class="input-radio" name="payment_method" value="kco" checked="checked" />');
|
||||
}
|
||||
|
||||
$('input#payment_method_kco').prop('checked', true);
|
||||
|
||||
<?php
|
||||
$extra_field_values = WC()->session->get( 'kco_wc_extra_fields_values', array() );
|
||||
|
||||
foreach ( $extra_field_values as $field_name => $field_value ) { ?>
|
||||
|
||||
var elementName = "<?php echo $field_name; ?>";
|
||||
var elementValue = <?php echo wp_json_encode( $field_value ); ?>;
|
||||
var element = $('*[name="' + elementName + '"]');
|
||||
|
||||
console.log(elementName);
|
||||
console.log(elementValue);
|
||||
console.log(element);
|
||||
console.log(element.type);
|
||||
|
||||
if (element.length) {
|
||||
if (element.is('select')) { // Select.
|
||||
var selectedOption = element.find('option[value="' + elementValue + '"]');
|
||||
selectedOption.prop('selected', true);
|
||||
} else if ('radio' === element.get(0).type) { // Radio.
|
||||
var checkedRadio = $('*[name="' + elementName + '"][value="' + elementValue + '"]');
|
||||
checkedRadio.prop('checked', true);
|
||||
} else if ('checkbox' === element.get(0).type) { // Checkbox.
|
||||
if (elementValue) {
|
||||
element.prop('checked', true);
|
||||
}
|
||||
} else { // Text and textarea.
|
||||
element.val(elementValue);
|
||||
}
|
||||
}
|
||||
|
||||
<?php
|
||||
}
|
||||
do_action( 'kco_wc_before_submit' );
|
||||
?>
|
||||
|
||||
$('.validate-required').removeClass('validate-required');
|
||||
$('form.woocommerce-checkout').submit();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if in KCO confirmation page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_kco_confirmation() {
|
||||
if ( isset( $_GET['confirm'] ) && 'yes' === $_GET['confirm'] && isset( $_GET['kco_wc_order_id'] ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves customer data from Klarna order into WC()->customer.
|
||||
*
|
||||
* @param $klarna_order
|
||||
*/
|
||||
private function save_customer_data( $klarna_order ) {
|
||||
// First name.
|
||||
WC()->customer->set_billing_first_name( sanitize_text_field( $klarna_order->billing_address->given_name ) );
|
||||
WC()->customer->set_shipping_first_name( sanitize_text_field( $klarna_order->shipping_address->given_name ) );
|
||||
|
||||
// Last name.
|
||||
WC()->customer->set_billing_last_name( sanitize_text_field( $klarna_order->billing_address->family_name ) );
|
||||
WC()->customer->set_shipping_last_name( sanitize_text_field( $klarna_order->shipping_address->family_name ) );
|
||||
|
||||
// Country.
|
||||
WC()->customer->set_billing_country( strtoupper( sanitize_text_field( $klarna_order->billing_address->country ) ) );
|
||||
WC()->customer->set_shipping_country( strtoupper( sanitize_text_field( $klarna_order->shipping_address->country ) ) );
|
||||
|
||||
// Street address 1.
|
||||
WC()->customer->set_billing_address_1( sanitize_text_field( $klarna_order->billing_address->street_address ) );
|
||||
WC()->customer->set_shipping_address_1( sanitize_text_field( $klarna_order->shipping_address->street_address ) );
|
||||
|
||||
// Street address 2.
|
||||
if ( isset( $klarna_order->billing_address->street_address2 ) ) {
|
||||
WC()->customer->set_billing_address_2( sanitize_text_field( $klarna_order->billing_address->street_address2 ) );
|
||||
WC()->customer->set_shipping_address_2( sanitize_text_field( $klarna_order->shipping_address->street_address2 ) );
|
||||
}
|
||||
|
||||
// City.
|
||||
WC()->customer->set_billing_city( sanitize_text_field( $klarna_order->billing_address->city ) );
|
||||
WC()->customer->set_shipping_city( sanitize_text_field( $klarna_order->shipping_address->city ) );
|
||||
|
||||
// County/State.
|
||||
WC()->customer->set_billing_state( sanitize_text_field( $klarna_order->billing_address->region ) );
|
||||
WC()->customer->set_shipping_state( sanitize_text_field( $klarna_order->shipping_address->region ) );
|
||||
|
||||
// Postcode.
|
||||
WC()->customer->set_billing_postcode( sanitize_text_field( $klarna_order->billing_address->postal_code ) );
|
||||
WC()->customer->set_shipping_postcode( sanitize_text_field( $klarna_order->shipping_address->postal_code ) );
|
||||
|
||||
// Phone.
|
||||
WC()->customer->set_billing_phone( sanitize_text_field( $klarna_order->billing_address->phone ) );
|
||||
|
||||
// Email.
|
||||
WC()->customer->set_billing_email( sanitize_text_field( $klarna_order->billing_address->email ) );
|
||||
|
||||
WC()->customer->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* When checking out using KCO, we need to make sure none of the WooCommerce are required, in case Klarna
|
||||
* does not return info for some of them.
|
||||
*
|
||||
* @param array $fields WooCommerce checkout fields.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function unrequire_fields( $fields ) {
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
foreach ( $fields as $fieldset_key => $fieldset ) {
|
||||
foreach ( $fieldset as $key => $field ) {
|
||||
$fields[ $fieldset_key ][ $key ]['required'] = '';
|
||||
$fields[ $fieldset_key ][ $key ]['wooccm_required'] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure there's no empty data sent for validation.
|
||||
*
|
||||
* @param array $data Posted data.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function unrequire_posted_data( $data ) {
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
foreach ( $data as $key => $value ) {
|
||||
if ( '' === $value ) {
|
||||
unset( $data[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds hidden field to WooCommerce checkout form, holding Klarna Checkout order ID.
|
||||
*/
|
||||
public function add_kco_order_id_field() {
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) && isset( $_GET['confirm'] ) && 'yes' === $_GET['confirm'] ) {
|
||||
if ( isset( $_GET['kco_wc_order_id'] ) ) { // Input var okay.
|
||||
$klarna_order_id = esc_attr( sanitize_text_field( $_GET['kco_wc_order_id'] ) );
|
||||
echo '<input type="hidden" id="kco_order_id" name="kco_order_id" value="' . $klarna_order_id . '" />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves KCO order ID to WooCommerce order as meta field.
|
||||
*
|
||||
* @param WC_Order $order WooCommerce order.
|
||||
* @param array $data Posted data.
|
||||
*/
|
||||
public function save_kco_order_id_field( $order, $data ) {
|
||||
if ( isset( $_POST['kco_order_id'] ) ) {
|
||||
$kco_order_id = sanitize_text_field( $_POST['kco_order_id'] );
|
||||
|
||||
update_post_meta( $order->get_id(), '_wc_klarna_order_id', sanitize_key( $kco_order_id ) );
|
||||
update_post_meta( $order->get_id(), '_transaction_id', sanitize_key( $kco_order_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_Confirmation::get_instance();
|
||||
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Create_Local_Order_Fallback class.
|
||||
*
|
||||
* Class that handles fallback order creation in Woocommerce if checkout form submission fails.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Create_Local_Order_Fallback {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Create_Local_Order_Fallback constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fallbck order creation, in case checkout process failed.
|
||||
*
|
||||
* @param string $klarna_order_id Klarna order ID.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
public static function create( $klarna_order_id ) {
|
||||
$response = KCO_WC()->api->request_post_get_order( $klarna_order_id );
|
||||
$klarna_order = json_decode( $response['body'] );
|
||||
|
||||
// Create order
|
||||
$order = wc_create_order();
|
||||
|
||||
try {
|
||||
$order_id = $order->get_id();
|
||||
|
||||
$cart_hash = md5( json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total );
|
||||
|
||||
$order->set_created_via( 'checkout' );
|
||||
$order->set_cart_hash( $cart_hash );
|
||||
$order->set_customer_id( apply_filters( 'woocommerce_checkout_customer_id', get_current_user_id() ) );
|
||||
$order->set_currency( get_woocommerce_currency() );
|
||||
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
|
||||
$order->set_customer_ip_address( WC_Geolocation::get_ip_address() );
|
||||
$order->set_customer_user_agent( wc_get_user_agent() );
|
||||
$order->set_shipping_total( WC()->cart->shipping_total );
|
||||
$order->set_discount_total( WC()->cart->get_cart_discount_total() );
|
||||
$order->set_discount_tax( WC()->cart->get_cart_discount_tax_total() );
|
||||
$order->set_cart_tax( WC()->cart->tax_total );
|
||||
$order->set_shipping_tax( WC()->cart->shipping_tax_total );
|
||||
$order->set_total( WC()->cart->total );
|
||||
|
||||
update_post_meta( $order_id, '_created_via_klarna_fallback', 'yes' );
|
||||
|
||||
//Add payment method
|
||||
self::add_order_payment_method( $order );
|
||||
|
||||
// Process customer data.
|
||||
self::process_customer_data( $order, $klarna_order );
|
||||
|
||||
// Process customer data.
|
||||
self::create_order_line_items( $order, WC()->cart );
|
||||
|
||||
//Add fees to order.
|
||||
self::create_order_fee_lines( $order, WC()->cart );
|
||||
|
||||
// Add shipping
|
||||
self::create_order_shipping_lines( $order );
|
||||
|
||||
// Tax
|
||||
self::create_order_tax_lines( $order, WC()->cart );
|
||||
|
||||
// Coupons
|
||||
self::create_order_coupon_lines( $order, WC()->cart );
|
||||
|
||||
// Save the order.
|
||||
$order->save();
|
||||
|
||||
return $order;
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'checkout-error', $e->getMessage() );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set payment method.
|
||||
*
|
||||
* @param WC_Order $order WooCommerce order.
|
||||
*
|
||||
*/
|
||||
public static function add_order_payment_method( $order ) {
|
||||
$available_gateways = WC()->payment_gateways->payment_gateways();
|
||||
$payment_method = $available_gateways['kco'];
|
||||
$order->set_payment_method( $payment_method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes customer data on fallback order creation.
|
||||
*
|
||||
* @param WC_Order $order WooCommerce order.
|
||||
* @param Klarna_Checkout_Order $klarna_order Klarna order.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
private static function process_customer_data( $order, $klarna_order ) {
|
||||
// First name.
|
||||
$order->set_billing_first_name( sanitize_text_field( $klarna_order->billing_address->given_name ) );
|
||||
$order->set_shipping_first_name( sanitize_text_field( $klarna_order->shipping_address->given_name ) );
|
||||
|
||||
// Last name.
|
||||
$order->set_billing_last_name( sanitize_text_field( $klarna_order->billing_address->family_name ) );
|
||||
$order->set_shipping_last_name( sanitize_text_field( $klarna_order->shipping_address->family_name ) );
|
||||
|
||||
// Country.
|
||||
$order->set_billing_country( sanitize_text_field( $klarna_order->billing_address->country ) );
|
||||
$order->set_shipping_country( sanitize_text_field( $klarna_order->shipping_address->country ) );
|
||||
|
||||
// Street address 1.
|
||||
$order->set_billing_address_1( sanitize_text_field( $klarna_order->billing_address->street_address ) );
|
||||
$order->set_shipping_address_1( sanitize_text_field( $klarna_order->shipping_address->street_address ) );
|
||||
|
||||
// Street address 2.
|
||||
$order->set_billing_address_2( sanitize_text_field( $klarna_order->billing_address->street_address2 ) );
|
||||
$order->set_shipping_address_2( sanitize_text_field( $klarna_order->shipping_address->street_address2 ) );
|
||||
|
||||
// City.
|
||||
$order->set_billing_city( sanitize_text_field( $klarna_order->billing_address->city ) );
|
||||
$order->set_shipping_city( sanitize_text_field( $klarna_order->shipping_address->city ) );
|
||||
|
||||
// County/State.
|
||||
$order->set_billing_state( sanitize_text_field( $klarna_order->billing_address->region ) );
|
||||
$order->set_shipping_state( sanitize_text_field( $klarna_order->shipping_address->region ) );
|
||||
|
||||
// Postcode.
|
||||
$order->set_billing_postcode( sanitize_text_field( $klarna_order->billing_address->postal_code ) );
|
||||
$order->set_shipping_postcode( sanitize_text_field( $klarna_order->shipping_address->postal_code ) );
|
||||
|
||||
// Phone.
|
||||
$order->set_billing_phone( sanitize_text_field( $klarna_order->billing_address->phone ) );
|
||||
|
||||
// Email.
|
||||
$order->set_billing_email( sanitize_text_field( $klarna_order->billing_address->email ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes cart contents on fallback order creation.
|
||||
*
|
||||
* @paramWC_Order $order WooCommerce order.
|
||||
*
|
||||
* @throws Exception WC_Data_Exception.
|
||||
*/
|
||||
private static function create_order_line_items( &$order, $cart ) {
|
||||
|
||||
// Remove items as to stop the item lines from being duplicated.
|
||||
$order->remove_order_items();
|
||||
|
||||
foreach ( $cart->get_cart() as $cart_item_key => $values ) {
|
||||
$product = $values['data'];
|
||||
$item = new WC_Order_Item_Product();
|
||||
$item->legacy_values = $values; // @deprecated For legacy actions.
|
||||
$item->legacy_cart_item_key = $cart_item_key; // @deprecated For legacy actions.
|
||||
$item->set_props( array(
|
||||
'quantity' => $values['quantity'],
|
||||
'variation' => $values['variation'],
|
||||
'subtotal' => $values['line_subtotal'],
|
||||
'total' => $values['line_total'],
|
||||
'subtotal_tax' => $values['line_subtotal_tax'],
|
||||
'total_tax' => $values['line_tax'],
|
||||
'taxes' => $values['line_tax_data'],
|
||||
) );
|
||||
if ( $product ) {
|
||||
$item->set_props( array(
|
||||
'name' => $product->get_name(),
|
||||
'tax_class' => $product->get_tax_class(),
|
||||
'product_id' => $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id(),
|
||||
'variation_id' => $product->is_type( 'variation' ) ? $product->get_id() : 0,
|
||||
) );
|
||||
}
|
||||
$item->set_backorder_meta();
|
||||
/**
|
||||
* Action hook to adjust item before save.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
do_action( 'woocommerce_checkout_create_order_line_item', $item, $cart_item_key, $values, $order );
|
||||
// Add item to order and save.
|
||||
$order->add_item( $item );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fees to the order.
|
||||
*
|
||||
* @param WC_Order $order
|
||||
*/
|
||||
public static function create_order_fee_lines( &$order, $cart ) {
|
||||
foreach ( $cart->get_fees() as $fee_key => $fee ) {
|
||||
$item = new WC_Order_Item_Fee();
|
||||
$item->legacy_fee = $fee; // @deprecated For legacy actions.
|
||||
$item->legacy_fee_key = $fee_key; // @deprecated For legacy actions.
|
||||
$item->set_props( array(
|
||||
'name' => $fee->name,
|
||||
'tax_class' => $fee->taxable ? $fee->tax_class : 0,
|
||||
'total' => $fee->amount,
|
||||
'total_tax' => $fee->tax,
|
||||
'taxes' => array(
|
||||
'total' => $fee->tax_data,
|
||||
),
|
||||
) );
|
||||
/**
|
||||
* Action hook to adjust item before save.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
do_action( 'woocommerce_checkout_create_order_fee_item', $item, $fee_key, $fee, $order );
|
||||
// Add item to order and save.
|
||||
$order->add_item( $item );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add shipping lines to the order.
|
||||
*
|
||||
* @param WC_Order $order
|
||||
*/
|
||||
public static function create_order_shipping_lines( &$order ) {
|
||||
|
||||
if ( ! defined( 'WOOCOMMERCE_CART' ) ) {
|
||||
define( 'WOOCOMMERCE_CART', true );
|
||||
}
|
||||
$order_id = $order->get_id() ;
|
||||
$this_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
|
||||
WC()->cart->calculate_shipping();
|
||||
// Store shipping for all packages.
|
||||
foreach ( WC()->shipping->get_packages() as $package_key => $package ) {
|
||||
if ( isset( $package['rates'][ $this_shipping_methods[ $package_key ] ] ) ) {
|
||||
$item_id = $order->add_shipping( $package['rates'][ $this_shipping_methods[ $package_key ] ] );
|
||||
if ( ! $item_id ) {
|
||||
KCO_WC()->logger->log( 'Error: Unable to add shipping item in Create Local Order Fallback.' );
|
||||
krokedil_log_events( null, 'Error: Unable to add shipping item in Create Local Order Fallback.', '' );
|
||||
}
|
||||
// Allows plugins to add order item meta to shipping.
|
||||
do_action( 'woocommerce_add_shipping_order_item', $order_id, $item_id, $package_key );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add tax lines to the order.
|
||||
*
|
||||
* @param WC_Order $order
|
||||
*/
|
||||
public static function create_order_tax_lines( &$order, $cart ) {
|
||||
foreach ( array_keys( $cart->taxes + $cart->shipping_taxes ) as $tax_rate_id ) {
|
||||
if ( $tax_rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) {
|
||||
$item = new WC_Order_Item_Tax();
|
||||
$item->set_props( array(
|
||||
'rate_id' => $tax_rate_id,
|
||||
'tax_total' => $cart->get_tax_amount( $tax_rate_id ),
|
||||
'shipping_tax_total' => $cart->get_shipping_tax_amount( $tax_rate_id ),
|
||||
'rate_code' => WC_Tax::get_rate_code( $tax_rate_id ),
|
||||
'label' => WC_Tax::get_rate_label( $tax_rate_id ),
|
||||
'compound' => WC_Tax::is_compound( $tax_rate_id ),
|
||||
) );
|
||||
/**
|
||||
* Action hook to adjust item before save.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
do_action( 'woocommerce_checkout_create_order_tax_item', $item, $tax_rate_id, $order );
|
||||
// Add item to order and save.
|
||||
$order->add_item( $item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add coupon lines to the order.
|
||||
*
|
||||
* @param WC_Order $order
|
||||
*/
|
||||
public static function create_order_coupon_lines( &$order, $cart ) {
|
||||
foreach ( $cart->get_coupons() as $code => $coupon ) {
|
||||
$item = new WC_Order_Item_Coupon();
|
||||
$item->set_props( array(
|
||||
'code' => $code,
|
||||
'discount' => $cart->get_coupon_discount_amount( $code ),
|
||||
'discount_tax' => $cart->get_coupon_discount_tax_amount( $code ),
|
||||
) );
|
||||
/**
|
||||
* Action hook to adjust item before save.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
do_action( 'woocommerce_checkout_create_order_coupon_item', $item, $code, $coupon, $order );
|
||||
// Add item to order and save.
|
||||
$order->add_item( $item );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_Create_Local_Order_Fallback::get_instance();
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Credentials class.
|
||||
*
|
||||
* Gets correct credentials based on customer country, store country and test/live mode.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Credentials {
|
||||
|
||||
/**
|
||||
* Klarna Checkout for WooCommerce settings.
|
||||
*
|
||||
* @var $settings
|
||||
*/
|
||||
public $settings = array();
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Credentials constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->settings = get_option( 'woocommerce_kco_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API credentials (merchant ID and shared secret) from user session.
|
||||
*
|
||||
* @return bool|array $credentials
|
||||
*/
|
||||
public function get_credentials_from_session() {
|
||||
$base_location = wc_get_base_location();
|
||||
|
||||
if ( 'US' === $base_location['country'] ) {
|
||||
$country_string = 'us';
|
||||
} else {
|
||||
$country_string = 'eu';
|
||||
}
|
||||
|
||||
$test_string = 'yes' === $this->settings['testmode'] ? 'test_' : '';
|
||||
$merchant_id = $this->settings[ $test_string . 'merchant_id_' . $country_string ];
|
||||
$shared_secret = $this->settings[ $test_string . 'shared_secret_' . $country_string ];
|
||||
|
||||
// Merchant id and/or shared secret not found for matching country.
|
||||
if ( '' === $merchant_id || '' === $shared_secret ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$credentials = array(
|
||||
'merchant_id' => $this->settings[ $test_string . 'merchant_id_' . $country_string ],
|
||||
'shared_secret' => htmlspecialchars_decode( $this->settings[ $test_string . 'shared_secret_' . $country_string ] ),
|
||||
);
|
||||
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Klarna API credentials (merchant ID and shared secret) from a completed WC order.
|
||||
*/
|
||||
public function get_credentials_from_order() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Extra_Checkout_Fields class.
|
||||
*
|
||||
* Class that handles extra checkout fields displayed when Klarna Checkout is the selected payment option.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Extra_Checkout_Fields {
|
||||
|
||||
/**
|
||||
* Returns array of all WooCommerce Checkout fields.
|
||||
*/
|
||||
public function get_all_checkout_fields() {
|
||||
$default_billing_fields = WC()->checkout()->get_checkout_fields( 'billing' );
|
||||
$default_shipping_fields = WC()->checkout()->get_checkout_fields( 'shipping' );
|
||||
$default_account_fields = WC()->checkout()->get_checkout_fields( 'account' );
|
||||
$default_order_fields = WC()->checkout()->get_checkout_fields( 'order' );
|
||||
|
||||
return array(
|
||||
'billing' => $default_billing_fields,
|
||||
'shipping' => $default_shipping_fields,
|
||||
'account' => $default_account_fields,
|
||||
'order' => $default_order_fields,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of WooCommerce checkout fields that can be populated using information from Klarna.
|
||||
*/
|
||||
public function get_klarna_checkout_fields() {
|
||||
$klarna_fields = array(
|
||||
'billing' => array(
|
||||
'billing_first_name',
|
||||
'billing_last_name',
|
||||
'billing_country',
|
||||
'billing_address_1',
|
||||
'billing_address_2',
|
||||
'billing_city',
|
||||
'billing_state',
|
||||
'billing_postcode',
|
||||
'billing_phone',
|
||||
'billing_email',
|
||||
),
|
||||
'shipping' => array(
|
||||
'shipping_first_name',
|
||||
'shipping_last_name',
|
||||
'shipping_country',
|
||||
'shipping_address_1',
|
||||
'shipping_address_2',
|
||||
'shipping_city',
|
||||
'shipping_state',
|
||||
'shipping_postcode',
|
||||
),
|
||||
);
|
||||
|
||||
return apply_filters( 'kco_wc_klarna_checkout_fields', $klarna_fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of WooCommerce checkout fields that can NOT be populated using information from Klarna.
|
||||
*/
|
||||
public function get_remaining_checkout_fields() {
|
||||
$all_fields = $this->get_all_checkout_fields();
|
||||
$klarna_fields = $this->get_klarna_checkout_fields();
|
||||
|
||||
foreach ( $klarna_fields['billing'] as $field ) {
|
||||
if ( array_key_exists( $field, $all_fields['billing'] ) ) {
|
||||
unset( $all_fields['billing'][ $field ] );
|
||||
}
|
||||
|
||||
unset( $all_fields['billing']['billing_company'] ); // B2C only for now.
|
||||
}
|
||||
|
||||
foreach ( $klarna_fields['shipping'] as $field ) {
|
||||
if ( array_key_exists( $field, $all_fields['shipping'] ) ) {
|
||||
unset( $all_fields['shipping'][ $field ] );
|
||||
}
|
||||
|
||||
unset( $all_fields['shipping']['shipping_company'] ); // B2C only for now.
|
||||
}
|
||||
|
||||
return $all_fields;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Fields class.
|
||||
*
|
||||
* Klarna Checkout for WooCommerce settings fields.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Fields {
|
||||
|
||||
/**
|
||||
* Returns the fields.
|
||||
*/
|
||||
public static function fields() {
|
||||
$settings = array(
|
||||
'enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Enable Klarna Checkout', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => '',
|
||||
'default' => 'no',
|
||||
),
|
||||
'title' => array(
|
||||
'title' => __( 'Title', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Payment method title.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'Klarna',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'description' => array(
|
||||
'title' => __( 'Description', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'textarea',
|
||||
'description' => __( 'Payment method description.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'allow_separate_shipping' => array(
|
||||
'title' => __( 'Separate shipping address', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Allow separate shipping address', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'If this option is checked, customers will be able to enter shipping address different than their billing address in checkout.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'select_another_method_text' => array(
|
||||
'title' => __( 'Other payment method button text', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Customize the <em>Select another payment method</em> button text that is displayed in checkout if using other payment methods than Klarna Checkout. Leave blank to use the default (and translatable) text.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'shipping_details' => array(
|
||||
'title' => __( 'Shipping details', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Shipping details note shown to customer', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Will be shown to customer in thank you page.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => false,
|
||||
),
|
||||
'allowed_customer_types' => array(
|
||||
'title' => __( 'Allowed Customer Types', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'B2C' => __( 'B2C only', 'klarna-checkout-for-woocommerce' ),
|
||||
'B2B' => __( 'B2B only', 'klarna-checkout-for-woocommerce' ),
|
||||
'B2CB' => __( 'B2C & B2B (defaults to B2C)', 'klarna-checkout-for-woocommerce' ),
|
||||
'B2BC' => __( 'B2B & B2C (defaults to B2B)', 'klarna-checkout-for-woocommerce' ),
|
||||
),
|
||||
'description' => sprintf( __( 'Select if you want to sell both to consumers and companies or only to one of them (available for SE, NO and FI). Learn more and <a href="%s" target="_blank">sign up for Klarna Checkout B2B here</a>.', 'klarna-checkout-for-woocommerce' ), 'https://www.klarna.com/se/foretag/klarna-checkout/klarna-checkout-foretag-form' ),
|
||||
'default' => 'B2C',
|
||||
'desc_tip' => false
|
||||
),
|
||||
'send_product_urls' => array(
|
||||
'title' => __( 'Product URLs', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Send product and product image URLs to Klarna', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'yes',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'logging' => array(
|
||||
'title' => __( 'Logging', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Log debug messages', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'Save debug messages to the WooCommerce System Status log.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'testmode' => array(
|
||||
'title' => __( 'Test mode', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Enable Test Mode', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'Place the payment gateway in test mode using test API keys.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'yes',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'dob_mandatory' => array(
|
||||
'title' => __( 'Date of birth mandatory', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Make customer date of birth mandatory', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'If checked, the customer cannot skip date of birth.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
// EU.
|
||||
'credentials_eu' => array(
|
||||
'title' => '<img src="' . plugins_url( 'assets/img/flags/eu.svg', KCO_WC_MAIN_FILE ) . '" height="12" /> API Credentials Europe',
|
||||
'type' => 'title',
|
||||
),
|
||||
'merchant_id_eu' => array(
|
||||
'title' => __( 'Production Username (UID)', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for Europe.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'shared_secret_eu' => array(
|
||||
'title' => __( 'Production Password', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for Europe.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'test_merchant_id_eu' => array(
|
||||
'title' => __( 'Test Username (UID)', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for Europe.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'test_shared_secret_eu' => array(
|
||||
'title' => __( 'Test Password', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for Europe.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'title_mandatory' => array(
|
||||
'title' => __( 'Title mandatory (GB)', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Make customer title mandatory', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'If unchecked, title becomes optional. Only available for orders for country GB.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'yes',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'prefill_consent' => array(
|
||||
'title' => __( 'Show prefill consent notice', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Only applicable for stores based in Germany and Austria', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => 'yes',
|
||||
),
|
||||
// US.
|
||||
'credentials_us' => array(
|
||||
'title' => '<img src="' . plugins_url( 'assets/img/flags/us.svg', KCO_WC_MAIN_FILE ) . '" height="12" /> API Credentials United States',
|
||||
'type' => 'title',
|
||||
),
|
||||
'merchant_id_us' => array(
|
||||
'title' => __( 'Production Username (UID)', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for US.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'shared_secret_us' => array(
|
||||
'title' => __( 'Production Password', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for US.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'test_merchant_id_us' => array(
|
||||
'title' => __( 'Test Username (UID)', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for US.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'test_shared_secret_us' => array(
|
||||
'title' => __( 'Test Password', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'text',
|
||||
'description' => __( 'Get your API keys from your Klarna Checkout merchant account for US.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
// Checkout iframe settings.
|
||||
'color_settings_title' => array(
|
||||
'title' => __( 'Color Settings', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'title',
|
||||
),
|
||||
'color_button' => array(
|
||||
'title' => __( 'Checkout button color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page button color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'color_button_text' => array(
|
||||
'title' => __( 'Checkout button text color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page button text color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'color_checkbox' => array(
|
||||
'title' => __( 'Checkout checkbox color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page checkbox color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'color_checkbox_checkmark' => array(
|
||||
'title' => __( 'Checkout checkbox checkmark color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page checkbox checkmark color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'color_header' => array(
|
||||
'title' => __( 'Checkout header color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page header color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'color_link' => array(
|
||||
'title' => __( 'Checkout link color', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'color',
|
||||
'description' => __( 'Checkout page link color', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
'radius_border' => array(
|
||||
'title' => __( 'Checkout radius border (px)', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'number',
|
||||
'description' => __( 'Checkout page radius border in pixels', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => '',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
);
|
||||
$wc_version = defined( 'WC_VERSION' ) && WC_VERSION ? WC_VERSION : null;
|
||||
|
||||
if ( version_compare( $wc_version, '3.4', '>=' ) ) {
|
||||
$new_settings = array();
|
||||
foreach ( $settings as $key => $value ) {
|
||||
$new_settings[ $key ] = $value;
|
||||
if ( 'dob_mandatory' === $key ) {
|
||||
$new_settings['display_privacy_policy_text'] = array(
|
||||
'title' => __( 'Checkout privacy policy text', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Select if you want to show the <em>Checkout privacy policy</em> text on the checkout page, and where you want to display it.', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'select',
|
||||
'default' => 'no',
|
||||
'options' => array(
|
||||
'no' => __( 'Do not display', 'klarna-checkout-for-woocommerce' ),
|
||||
'above' => __( 'Display above checkout', 'klarna-checkout-for-woocommerce' ),
|
||||
'below' => __( 'Display below checkout', 'klarna-checkout-for-woocommerce' ),
|
||||
),
|
||||
);
|
||||
$new_settings['add_terms_and_conditions_checkbox'] = array(
|
||||
'title' => __( 'Terms and conditions checkbox', 'klarna-checkout-for-woocommerce' ),
|
||||
'label' => __( 'Add a terms and conditions checkbox inside Klarna checkout iframe', 'klarna-checkout-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'description' => __( 'To change the text navigate to → Appearance → Customize → WooCommerce → Checkout.', 'klarna-checkout-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
'desc_tip' => false,
|
||||
);
|
||||
}
|
||||
}
|
||||
$settings = $new_settings;
|
||||
}
|
||||
return apply_filters( 'kco_wc_gateway_settings', $settings );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Gateway class.
|
||||
*
|
||||
* @extends WC_Payment_Gateway
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Gateway extends WC_Payment_Gateway {
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Gateway constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->id = 'kco';
|
||||
$this->method_title = __( 'Klarna Checkout', 'klarna-checkout-for-woocommerce' );
|
||||
$this->method_description = __( 'Klarna Checkout replaces standard WooCommerce checkout page.', 'klarna-checkout-for-woocommerce' );
|
||||
$this->has_fields = false;
|
||||
$this->supports = apply_filters( 'kco_wc_supports', array( 'products' ) );
|
||||
|
||||
// Load the form fields.
|
||||
$this->init_form_fields();
|
||||
|
||||
// Load the settings.
|
||||
$this->init_settings();
|
||||
|
||||
$this->title = $this->get_option( 'title' );
|
||||
$this->description = $this->get_option( 'description' );
|
||||
|
||||
$this->enabled = $this->get_option( 'enabled' );
|
||||
$this->testmode = 'yes' === $this->get_option( 'testmode' );
|
||||
$this->logging = 'yes' === $this->get_option( 'logging' );
|
||||
|
||||
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array(
|
||||
$this,
|
||||
'process_admin_options',
|
||||
) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'show_thank_you_snippet' ) );
|
||||
add_action( 'woocommerce_admin_order_data_after_billing_address', array( $this, 'address_notice' ) );
|
||||
add_action( 'woocommerce_checkout_init', array( $this, 'prefill_consent' ) );
|
||||
add_action( 'woocommerce_checkout_init', array( $this, 'show_log_in_notice' ) );
|
||||
|
||||
// Remove WooCommerce footer text from our settings page.
|
||||
add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 999 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gateway icon.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_icon() {
|
||||
$icon_src = 'https://cdn.klarna.com/1.0/shared/image/generic/logo/en_us/basic/logo_black.png?width=100';
|
||||
$icon_html = '<img src="' . $icon_src . '" alt="Klarna Checkout" style="border-radius:0px"/>';
|
||||
return apply_filters( 'wc_klarna_checkout_icon_html', $icon_html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the payment and return the result.
|
||||
*
|
||||
* @param int $order_id WooCommerce order ID.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function process_payment( $order_id ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
krokedil_set_order_gateway_version( $order_id, KCO_WC_VERSION );
|
||||
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $this->get_return_url( $order ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This plugin doesn't handle order management, but it allows Klarna Order Management plugin to process refunds
|
||||
* and then return true or false.
|
||||
*
|
||||
* @param int $order_id WooCommerce order ID.
|
||||
* @param null|int $amount Refund amount.
|
||||
* @param string $reason Reason for refund.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
||||
return apply_filters( 'wc_klarna_checkout_process_refund', false, $order_id, $amount, $reason );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise settings fields.
|
||||
*/
|
||||
public function init_form_fields() {
|
||||
$this->form_fields = Klarna_Checkout_For_WooCommerce_Fields::fields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if method should be available.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_available() {
|
||||
if ( 'yes' !== $this->enabled ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we can't retrieve a set of credentials, disable KCO.
|
||||
if ( is_checkout() && ! KCO_WC()->credentials->get_credentials_from_session() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sidebar to the settings page.
|
||||
*/
|
||||
public function admin_options() {
|
||||
ob_start();
|
||||
parent::admin_options();
|
||||
$parent_options = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
WC_Klarna_Banners::settings_sidebar( $parent_options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue payment scripts.
|
||||
*
|
||||
* @hook wp_enqueue_scripts
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
if ( ! is_checkout() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( is_order_received_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! kco_wc_prefill_allowed() ) {
|
||||
add_thickbox();
|
||||
}
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
wp_register_script(
|
||||
'kco',
|
||||
plugins_url( 'assets/js/klarna-checkout-for-woocommerce' . $suffix . '.js', KCO_WC_MAIN_FILE ),
|
||||
array( 'jquery', 'wc-cart' ),
|
||||
KCO_WC_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'kco',
|
||||
plugins_url( 'assets/css/klarna-checkout-for-woocommerce' . $suffix . '.css', KCO_WC_MAIN_FILE ),
|
||||
array(),
|
||||
KCO_WC_VERSION
|
||||
);
|
||||
|
||||
$form = array();
|
||||
if ( false !== get_transient( WC()->session->get( 'kco_wc_order_id' ) ) ) {
|
||||
$form = get_transient( WC()->session->get( 'kco_wc_order_id' ) );
|
||||
}
|
||||
|
||||
$checkout_localize_params = array(
|
||||
'update_cart_url' => WC_AJAX::get_endpoint( 'kco_wc_update_cart' ),
|
||||
'update_cart_nonce' => wp_create_nonce( 'kco_wc_update_cart' ),
|
||||
'update_shipping_url' => WC_AJAX::get_endpoint( 'kco_wc_update_shipping' ),
|
||||
'update_shipping_nonce' => wp_create_nonce( 'kco_wc_update_shipping' ),
|
||||
'update_extra_fields_url' => WC_AJAX::get_endpoint( 'kco_wc_update_extra_fields' ),
|
||||
'update_extra_fields_nonce' => wp_create_nonce( 'kco_wc_update_extra_fields' ),
|
||||
'change_payment_method_url' => WC_AJAX::get_endpoint( 'kco_wc_change_payment_method' ),
|
||||
'change_payment_method_nonce' => wp_create_nonce( 'kco_wc_change_payment_method' ),
|
||||
'update_klarna_order_url' => WC_AJAX::get_endpoint( 'kco_wc_update_klarna_order' ),
|
||||
'update_klarna_order_nonce' => wp_create_nonce( 'kco_wc_update_klarna_order' ),
|
||||
'iframe_shipping_address_change_url' => WC_AJAX::get_endpoint( 'kco_wc_iframe_shipping_address_change' ),
|
||||
'iframe_shipping_address_change_nonce' => wp_create_nonce( 'kco_wc_iframe_shipping_address_change' ),
|
||||
'checkout_error_url' => WC_AJAX::get_endpoint( 'kco_wc_checkout_error' ),
|
||||
'checkout_error_nonce' => wp_create_nonce( 'kco_wc_checkout_error' ),
|
||||
'logging' => $this->logging,
|
||||
'save_form_data' => WC_AJAX::get_endpoint( 'kco_wc_save_form_data' ),
|
||||
'save_form_data_nonce' => wp_create_nonce( 'kco_wc_save_form_data' ),
|
||||
'form' => $form,
|
||||
);
|
||||
|
||||
wp_localize_script( 'kco', 'kco_params', $checkout_localize_params );
|
||||
|
||||
wp_enqueue_script( 'kco' );
|
||||
wp_enqueue_style( 'kco' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts.
|
||||
*
|
||||
* @param string $hook Admin page hook.
|
||||
*
|
||||
* @hook admin_enqueue_scripts
|
||||
*/
|
||||
public function admin_enqueue_scripts( $hook ) {
|
||||
if ( 'woocommerce_page_wc-settings' !== $hook ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_GET['section'] ) || 'kco' !== $_GET['section'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
$store_base_location = wc_get_base_location();
|
||||
if ( 'US' === $store_base_location['country'] ) {
|
||||
$location = 'US';
|
||||
} else {
|
||||
$location = $this->check_if_eu( $store_base_location['country'] );
|
||||
}
|
||||
|
||||
wp_register_script(
|
||||
'kco_admin',
|
||||
plugins_url( 'assets/js/klarna-checkout-for-woocommerce-admin.js', KCO_WC_MAIN_FILE ),
|
||||
array(),
|
||||
KCO_WC_VERSION
|
||||
);
|
||||
$admin_localize_params = array(
|
||||
'location' => $location,
|
||||
);
|
||||
wp_localize_script( 'kco_admin', 'kco_admin_params', $admin_localize_params );
|
||||
wp_enqueue_script( 'kco_admin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if EU country.
|
||||
*
|
||||
* @param string $store_base_location The WooCommerce stores base country.
|
||||
*/
|
||||
private function check_if_eu( $store_base_location ) {
|
||||
$eu_countries = array(
|
||||
'AL', 'AD', 'AM', 'AT', 'BY', 'BE', 'BA', 'BG', 'CH', 'CY', 'CZ', 'DE',
|
||||
'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GE', 'GI', 'GR', 'HU', 'HR',
|
||||
'IE', 'IS', 'IT', 'LT', 'LU', 'LV', 'MC', 'MK', 'MT', 'NO', 'NL', 'PL',
|
||||
'PT', 'RO', 'RU', 'SE', 'SI', 'SK', 'SM', 'TR', 'UA', 'VA',
|
||||
);
|
||||
|
||||
if( in_array( $store_base_location, $eu_countries ) ) {
|
||||
return 'EU';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays Klarna Checkout thank you iframe and clears Klarna order ID value from WC session.
|
||||
*
|
||||
* @param int $order_id WooCommerce order ID.
|
||||
*/
|
||||
public function show_thank_you_snippet( $order_id = null ) {
|
||||
if ( ! WC()->session->get( 'kco_wc_order_id' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$klarna_order = KCO_WC()->api->get_order();
|
||||
echo KCO_WC()->api->get_snippet( $klarna_order );
|
||||
|
||||
if ( $order_id ) {
|
||||
// Set WC order transaction ID.
|
||||
$order = wc_get_order( $order_id );
|
||||
|
||||
update_post_meta( $order_id, '_wc_klarna_order_id', sanitize_key( $klarna_order->order_id ) );
|
||||
update_post_meta( $order_id, '_transaction_id', sanitize_key( $klarna_order->order_id ) );
|
||||
|
||||
$environment = $this->testmode ? 'test' : 'live';
|
||||
update_post_meta( $order_id, '_wc_klarna_environment', $environment );
|
||||
|
||||
$klarna_country = WC()->checkout()->get_value( 'billing_country' );
|
||||
update_post_meta( $order_id, '_wc_klarna_country', $klarna_country );
|
||||
|
||||
krokedil_log_events( $order_id, 'Klarna order in show_thank_you_snippet', $klarna_order );
|
||||
|
||||
$response = KCO_WC()->api->request_post_get_order( $klarna_order->order_id );
|
||||
$klarna_post_order = json_decode( $response['body'] );
|
||||
krokedil_log_events( $order_id, 'Klarna post_order in show_thank_you_snippet', $klarna_post_order );
|
||||
|
||||
if ( 'ACCEPTED' === $klarna_post_order->fraud_status ) {
|
||||
$order->payment_complete();
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Payment via Klarna Checkout, order ID: %s', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->add_order_note( $note );
|
||||
} elseif ( 'REJECTED' === $klarna_post_order->fraud_status ) {
|
||||
$order->update_status( 'on-hold', __( 'Klarna Checkout order was rejected.', 'klarna-checkout-for-woocommerce' ) );
|
||||
} elseif ( 'PENDING' === $klarna_post_order->fraud_status ) {
|
||||
// translators: Klarna order ID.
|
||||
$note = sprintf( __( 'Klarna order is under review, order ID: %s.', 'klarna-checkout-for-woocommerce' ), sanitize_key( $klarna_order->order_id ) );
|
||||
$order->update_status( 'on-hold', $note );
|
||||
}
|
||||
KCO_WC()->api->request_post_acknowledge_order( $klarna_order->order_id );
|
||||
KCO_WC()->api->request_post_set_merchant_reference(
|
||||
$klarna_order->order_id,
|
||||
array(
|
||||
'merchant_reference1' => $order->get_order_number(),
|
||||
'merchant_reference2' => $order->get_id(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes footer text in KCO settings page.
|
||||
*
|
||||
* @TODO: Get a URL to link to.
|
||||
*
|
||||
* @param string $text Footer text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function admin_footer_text( $text ) {
|
||||
if ( isset( $_GET['section'] ) && 'kco' === $_GET['section'] ) {
|
||||
$text = 'If you like Klarna Checkout for WooCommerce, please consider <strong>assigning Krokedil as your integration partner.</strong>.';
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds can't edit address notice to KP EU orders.
|
||||
*
|
||||
* @param WC_Order $order WooCommerce order object.
|
||||
*/
|
||||
public function address_notice( $order ) {
|
||||
if ( $this->id === $order->get_payment_method() ) {
|
||||
echo '<div style="margin: 10px 0; padding: 10px; border: 1px solid #B33A3A; font-size: 12px">';
|
||||
esc_html_e( 'Order address should not be changed and any changes you make will not be reflected in Klarna system.', 'klarna-checkout-for-woocommerce' );
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notice that tells customers they need to log in.
|
||||
*/
|
||||
public function show_log_in_notice() {
|
||||
if ( isset( $_GET['login_required'] ) && 'yes' === $_GET['login_required'] ) {
|
||||
wc_add_notice(
|
||||
sanitize_textarea_field( __(
|
||||
'An account is already registered with your email address. Please log in.',
|
||||
'klarna-checkout-for-woocommerce'
|
||||
) ),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds prefill consent to WC session.
|
||||
*/
|
||||
public function prefill_consent() {
|
||||
if ( isset( $_GET['prefill_consent'] ) ) { // Input var okay.
|
||||
if ( 'yes' === sanitize_text_field( $_GET['prefill_consent'] ) ) {
|
||||
WC()->session->set( 'kco_wc_prefill_consent', true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
/**
|
||||
* Compliance with European Union's General Data Protection Regulation.
|
||||
*
|
||||
* @class Klarna_Checkout_For_Woocommerce_GDPR
|
||||
* @version 1.0.0
|
||||
* @package Klarna_Checkout/Classes
|
||||
* @category Class
|
||||
* @author Krokedil
|
||||
*/
|
||||
class Klarna_Checkout_For_Woocommerce_GDPR {
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_init', array( $this, 'privacy_declarations' ) );
|
||||
add_action( 'init', array( $this, 'maybe_add_privacy_policy_text' ) );
|
||||
add_filter( 'kco_wc_api_request_args', array( $this, 'maybe_add_checkbox' ) );
|
||||
}
|
||||
/**
|
||||
* Privacy declarations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function privacy_declarations() {
|
||||
if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
|
||||
$content =
|
||||
__(
|
||||
'When you place an order in the webstore with Klarna Checkout as the choosen payment method, ' .
|
||||
'information about the products in the order (name, price, quantity, SKU) is sent to Klarna. ' .
|
||||
'When the purchase is finalized Klarna sends your billing and shipping address back to the webstore. ' .
|
||||
'This data plus an unique identifier for the purchase is then stored as billing and shipping data in the order in WooCommerce.',
|
||||
'klarna-checkout-for-woocommerce'
|
||||
);
|
||||
wp_add_privacy_policy_content(
|
||||
'Klarna Checkout for WooCommerce',
|
||||
wp_kses_post( wpautop( $content ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe adds the terms checkbox to the checkout.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_add_privacy_policy_text() {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
$display_privacy_policy_text = $settings['display_privacy_policy_text'];
|
||||
|
||||
if ( 'above' == $display_privacy_policy_text ) {
|
||||
add_action( 'kco_wc_before_snippet', array( $this, 'kco_wc_display_privacy_policy_text' ) );
|
||||
} elseif ( 'below' == $display_privacy_policy_text ) {
|
||||
add_action( 'kco_wc_after_snippet', array( $this, 'kco_wc_display_privacy_policy_text' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the terms template.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function kco_wc_display_privacy_policy_text() {
|
||||
if ( function_exists( 'wc_checkout_privacy_policy_text' ) ) {
|
||||
echo wc_checkout_privacy_policy_text();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe adds a checkbox to the Klarna iFrame.
|
||||
*
|
||||
* @param array $args The arguments array for the Klarna request.
|
||||
* @return array $args The arguments array for the Klarna request.
|
||||
*/
|
||||
public function maybe_add_checkbox( $args ) {
|
||||
if ( function_exists( 'wc_terms_and_conditions_checkbox_enabled' ) ) {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
$add_checkbox = $settings['add_terms_and_conditions_checkbox'];
|
||||
if ( 'yes' === $add_checkbox && wc_terms_and_conditions_checkbox_enabled() ) {
|
||||
$args['options']['additional_checkbox']['text'] = wc_replace_policy_page_link_placeholders( wc_get_terms_and_conditions_checkbox_text() );
|
||||
$args['options']['additional_checkbox']['checked'] = false;
|
||||
$args['options']['additional_checkbox']['required'] = true;
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
new Klarna_Checkout_For_Woocommerce_GDPR();
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_AJAX class.
|
||||
*
|
||||
* Registers AJAX actions for Klarna Checkout for WooCommerce.
|
||||
*
|
||||
* @extends WC_AJAX
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Logging {
|
||||
|
||||
/** @var WC_Logger Logger instance */
|
||||
private $logger = false;
|
||||
|
||||
/**
|
||||
* Logging function.
|
||||
*
|
||||
* @param string $message Error message.
|
||||
* @param string $level Error level.
|
||||
*/
|
||||
public function log( $message, $level = 'info' ) {
|
||||
if ( $this->log_enabled() ) {
|
||||
if ( empty( $this->logger ) ) {
|
||||
$this->logger = wc_get_logger();
|
||||
}
|
||||
|
||||
$this->logger->log( $level, $message, array( 'source' => 'klarna-checkout-for-woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if logging is enabled in plugin settings.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function log_enabled() {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
|
||||
return ( null !== $settings['logging'] && 'yes' === $settings['logging'] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Merchant_URLs class.
|
||||
*
|
||||
* Class that formats gets merchant URLs Klarna API.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Merchant_URLs {
|
||||
|
||||
/**
|
||||
* Gets formatted merchant URLs array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_urls() {
|
||||
$merchant_urls = array(
|
||||
'terms' => $this->get_terms_url(), // Required.
|
||||
'checkout' => $this->get_checkout_url(), // Required.
|
||||
'confirmation' => $this->get_confirmation_url(), // Required.
|
||||
'push' => $this->get_push_url(), // Required.
|
||||
'validation' => $this->get_validation_url(), // HTTPS.
|
||||
'shipping_option_update' => $this->get_shipping_option_update_url(), // HTTPS.
|
||||
// 'address_update' => $this->get_address_update_url(), // HTTPS.
|
||||
'notification' => $this->get_notification_url(),
|
||||
// 'country_change' => $this->get_country_change_url(), // HTTPS.
|
||||
);
|
||||
|
||||
return $merchant_urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terms URL.
|
||||
*
|
||||
* Required. URL of merchant terms and conditions. Should be different than checkout, confirmation and push URLs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_terms_url() {
|
||||
$terms_url = get_permalink( wc_get_page_id( 'terms' ) );
|
||||
return $terms_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkout URL.
|
||||
*
|
||||
* Required. URL of merchant checkout page. Should be different than terms, confirmation and push URLs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_checkout_url() {
|
||||
$checkout_url = wc_get_checkout_url();
|
||||
return $checkout_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation URL.
|
||||
*
|
||||
* Required. URL of merchant confirmation page. Should be different than checkout and confirmation URLs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_confirmation_url() {
|
||||
$confirmation_url = wc_get_checkout_url() . '?confirm=yes&kco_wc_order_id={checkout.order.id}';
|
||||
return $confirmation_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push URL.
|
||||
*
|
||||
* Required. URL of merchant confirmation page. Should be different than checkout and confirmation URLs.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_push_url() {
|
||||
$push_url = get_home_url() . '/wc-api/KCO_WC_Push/?kco_wc_order_id={checkout.order.id}';
|
||||
return $push_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation URL.
|
||||
*
|
||||
* URL that will be requested for final merchant validation, must be https.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_validation_url() {
|
||||
$validation_url = get_home_url() . '/wc-api/KCO_WC_Validation/?kco_wc_order_id={checkout.order.id}';
|
||||
return str_replace( 'http:', 'https:', $validation_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipping option update URL.
|
||||
*
|
||||
* URL for shipping option update, must be https.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_shipping_option_update_url() {
|
||||
$shipping_option_update_url = get_home_url() . '/wc-api/KCO_WC_Shipping_Option_Update/';
|
||||
return str_replace( 'http:', 'https:', $shipping_option_update_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Address update URL.
|
||||
*
|
||||
* URL for shipping, tax and purchase currency updates. Will be called on address changes, must be https.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_address_update_url() {
|
||||
$address_update_url = get_home_url() . '/wc-api/KCO_WC_Address_Update/?kco_wc_order_id={checkout.order.id}';
|
||||
return str_replace( 'http:', 'https:', $address_update_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification URL.
|
||||
*
|
||||
* URL for notifications on pending orders.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_notification_url() {
|
||||
$notification_url = get_home_url() . '/wc-api/KCO_WC_Notification/?kco_wc_order_id={checkout.order.id}';
|
||||
return $notification_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Country change URL.
|
||||
*
|
||||
* URL for shipping, tax and purchase currency updates. Will be called on purchase country changes, must be https.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_country_change_url() {
|
||||
$country_change_url = get_home_url() . '/wp-json/kcowc/v1/address/{checkout.order.id}';
|
||||
return str_replace( 'http:', 'https:', $country_change_url );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,592 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Order_Lines class.
|
||||
*
|
||||
* Class that formats WooCommerce cart contents for Klarna API.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Order_Lines {
|
||||
|
||||
/**
|
||||
* Formatted order lines.
|
||||
*
|
||||
* @var $order_lines
|
||||
*/
|
||||
public $order_lines = array();
|
||||
|
||||
/**
|
||||
* Shop country.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $shop_country;
|
||||
|
||||
/**
|
||||
* Send sales tax as separate item (US merchants).
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $separate_sales_tax = false;
|
||||
|
||||
/**
|
||||
* WC_Klarna_Payments_Order_Lines constructor.
|
||||
*
|
||||
* @param bool|string $shop_country Shop country.
|
||||
*/
|
||||
public function __construct( $shop_country = null ) {
|
||||
if ( ! $shop_country ) {
|
||||
$base_location = wc_get_base_location();
|
||||
$shop_country = $base_location['country'];
|
||||
}
|
||||
|
||||
$this->shop_country = $shop_country;
|
||||
|
||||
if ( 'US' === $this->shop_country ) {
|
||||
$this->separate_sales_tax = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes cart data
|
||||
*/
|
||||
public function process_data() {
|
||||
// @TODO: Process fees
|
||||
$this->process_cart();
|
||||
$this->process_shipping();
|
||||
$this->process_sales_tax();
|
||||
$this->process_coupons();
|
||||
$this->process_fees();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets formatted order lines from WooCommerce cart.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_order_lines() {
|
||||
return $this->order_lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets order amount for Klarna API.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_order_amount() {
|
||||
return round( WC()->cart->total * 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets order tax amount for Klarna API.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_order_tax_amount() {
|
||||
return round( ( WC()->cart->tax_total + WC()->cart->shipping_tax_total ) * 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process WooCommerce cart to Klarna Payments order lines.
|
||||
*/
|
||||
public function process_cart() {
|
||||
foreach ( WC()->cart->get_cart() as $cart_item ) {
|
||||
if ( $cart_item['quantity'] ) {
|
||||
if ( $cart_item['variation_id'] ) {
|
||||
$product = wc_get_product( $cart_item['variation_id'] );
|
||||
} else {
|
||||
$product = wc_get_product( $cart_item['product_id'] );
|
||||
}
|
||||
$klarna_item = array(
|
||||
'reference' => $this->get_item_reference( $product ),
|
||||
'name' => $this->get_item_name( $cart_item ),
|
||||
'quantity' => $this->get_item_quantity( $cart_item ),
|
||||
'unit_price' => $this->get_item_price( $cart_item ),
|
||||
'tax_rate' => $this->get_item_tax_rate( $cart_item, $product ),
|
||||
'total_amount' => $this->get_item_total_amount( $cart_item ),
|
||||
'total_tax_amount' => $this->get_item_tax_amount( $cart_item ),
|
||||
'total_discount_amount' => $this->get_item_discount_amount( $cart_item ),
|
||||
);
|
||||
|
||||
// Add images.
|
||||
$klarna_checkout_settings = get_option( 'woocommerce_kco_settings' );
|
||||
if ( array_key_exists( 'send_product_urls', $klarna_checkout_settings ) && 'yes' === $klarna_checkout_settings['send_product_urls'] ) {
|
||||
$klarna_item['product_url'] = $this->get_item_product_url( $product );
|
||||
if ( $this->get_item_image_url( $product ) ) {
|
||||
$klarna_item['image_url'] = $this->get_item_image_url( $product );
|
||||
}
|
||||
}
|
||||
|
||||
$this->order_lines[] = $klarna_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process WooCommerce shipping to Klarna Payments order lines.
|
||||
*/
|
||||
public function process_shipping() {
|
||||
if ( WC()->shipping->get_packages() && WC()->session->get( 'chosen_shipping_methods' )[0] ) {
|
||||
$shipping = array(
|
||||
'type' => 'shipping_fee',
|
||||
'reference' => $this->get_shipping_reference(),
|
||||
'name' => $this->get_shipping_name(),
|
||||
'quantity' => 1,
|
||||
'unit_price' => $this->get_shipping_amount(),
|
||||
'tax_rate' => $this->get_shipping_tax_rate(),
|
||||
'total_amount' => $this->get_shipping_amount(),
|
||||
'total_tax_amount' => $this->get_shipping_tax_amount(),
|
||||
);
|
||||
$this->order_lines[] = $shipping;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sales tax for US.
|
||||
*/
|
||||
public function process_sales_tax() {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$sales_tax_amount = round( ( WC()->cart->tax_total + WC()->cart->shipping_tax_total ) * 100 );
|
||||
// Add sales tax line item.
|
||||
$sales_tax = array(
|
||||
'type' => 'sales_tax',
|
||||
'reference' => __( 'Sales Tax', 'klarna-checkout-for-woocommerce' ),
|
||||
'name' => __( 'Sales Tax', 'klarna-checkout-for-woocommerce' ),
|
||||
'quantity' => 1,
|
||||
'unit_price' => $sales_tax_amount,
|
||||
'tax_rate' => 0,
|
||||
'total_amount' => $sales_tax_amount,
|
||||
'total_discount_amount' => 0,
|
||||
'total_tax_amount' => 0,
|
||||
);
|
||||
$this->order_lines[] = $sales_tax;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process smart coupons.
|
||||
*/
|
||||
public function process_coupons() {
|
||||
if ( ! empty( WC()->cart->get_coupons() ) ) {
|
||||
foreach ( WC()->cart->get_coupons() as $coupon_key => $coupon ) {
|
||||
$coupon_reference = '';
|
||||
$coupon_amount = 0;
|
||||
$coupon_tax_amount = '';
|
||||
// Smart coupons are processed as real line items, cart and product discounts sent for reference only.
|
||||
if ( 'smart_coupon' === $coupon->get_discount_type() ) {
|
||||
$coupon_amount = - WC()->cart->get_coupon_discount_amount( $coupon_key ) * 100;
|
||||
$coupon_tax_amount = - WC()->cart->get_coupon_discount_tax_amount( $coupon_key ) * 100;
|
||||
$coupon_reference = 'Discount';
|
||||
} else {
|
||||
if ( 'US' === $this->shop_country ) {
|
||||
$coupon_amount = 0;
|
||||
$coupon_tax_amount = 0;
|
||||
if ( $coupon->is_type( 'fixed_cart' ) || $coupon->is_type( 'percent' ) ) {
|
||||
$coupon_type = 'Cart discount';
|
||||
} elseif ( $coupon->is_type( 'fixed_product' ) || $coupon->is_type( 'percent_product' ) ) {
|
||||
$coupon_type = 'Product discount';
|
||||
} else {
|
||||
$coupon_type = 'Discount';
|
||||
}
|
||||
$coupon_reference = $coupon_type . ' (amount: ' . WC()->cart->get_coupon_discount_amount( $coupon_key ) . ', tax amount: ' . WC()->cart->get_coupon_discount_tax_amount( $coupon_key ) . ')';
|
||||
}
|
||||
}
|
||||
// Add separate discount line item, but only if it's a smart coupon or country is US.
|
||||
if ( 'US' === $this->shop_country || 'smart_coupon' === $coupon->get_discount_type() ) {
|
||||
$discount = array(
|
||||
'type' => 'discount',
|
||||
'reference' => $coupon_reference,
|
||||
'name' => $coupon_key,
|
||||
'quantity' => 1,
|
||||
'unit_price' => $coupon_amount,
|
||||
'tax_rate' => 0,
|
||||
'total_amount' => $coupon_amount,
|
||||
'total_discount_amount' => 0,
|
||||
'total_tax_amount' => $coupon_tax_amount,
|
||||
);
|
||||
$this->order_lines[] = $discount;
|
||||
}
|
||||
} // End foreach().
|
||||
} // End if().
|
||||
}
|
||||
|
||||
/**
|
||||
* Process cart fees.
|
||||
*/
|
||||
public function process_fees() {
|
||||
if ( ! empty( WC()->cart->get_fees() ) ) {
|
||||
foreach ( WC()->cart->get_fees() as $fee_key => $fee ) {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$fee_tax_rate = 0;
|
||||
$fee_tax_amount = 0;
|
||||
$fee_amount = round( $fee->amount * 100 );
|
||||
} else {
|
||||
$fee_tax_amount = round( $fee->tax * 100 );
|
||||
$fee_amount = round( ( $fee->amount + $fee->tax ) * 100 );
|
||||
|
||||
$_tax = new WC_Tax();
|
||||
$tmp_rates = $_tax->get_rates( $fee->tax_class );
|
||||
$vat = array_shift( $tmp_rates );
|
||||
|
||||
if ( isset( $vat['rate'] ) ) {
|
||||
$fee_tax_rate = round( $vat['rate'] * 100 );
|
||||
} else {
|
||||
$fee_tax_rate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Add separate discount line item, but only if it's a smart coupon or country is US.
|
||||
$fee_item = array(
|
||||
'type' => 'shipping_fee',
|
||||
'reference' => $fee->id,
|
||||
'name' => $fee->name,
|
||||
'quantity' => 1,
|
||||
'unit_price' => $fee_amount,
|
||||
'tax_rate' => $fee_tax_rate,
|
||||
'total_amount' => $fee_amount,
|
||||
'total_discount_amount' => 0,
|
||||
'total_tax_amount' => $fee_tax_amount,
|
||||
);
|
||||
|
||||
$this->order_lines[] = $fee_item;
|
||||
} // End foreach().
|
||||
} // End if().
|
||||
}
|
||||
|
||||
// Helpers.
|
||||
|
||||
/**
|
||||
* Get cart item name.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return string $item_name Cart item name.
|
||||
*/
|
||||
public function get_item_name( $cart_item ) {
|
||||
$cart_item_data = $cart_item['data'];
|
||||
$item_name = $cart_item_data->get_name();
|
||||
|
||||
return strip_tags( $item_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate item tax percentage.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_tax_amount Item tax amount.
|
||||
*/
|
||||
public function get_item_tax_amount( $cart_item ) {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$item_tax_amount = 0;
|
||||
} else {
|
||||
$item_tax_amount = $cart_item['line_tax'] * 100;
|
||||
}
|
||||
|
||||
return round( $item_tax_amount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate item tax percentage.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
* @param object $product Product object.
|
||||
*
|
||||
* @return integer $item_tax_rate Item tax percentage formatted for Klarna.
|
||||
*/
|
||||
public function get_item_tax_rate( $cart_item, $product ) {
|
||||
if ( $product->is_taxable() && $cart_item['line_subtotal_tax'] > 0 ) {
|
||||
// Calculate tax rate.
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$item_tax_rate = 0;
|
||||
} else {
|
||||
$_tax = new WC_Tax();
|
||||
$tmp_rates = $_tax->get_rates( $product->get_tax_class() );
|
||||
$vat = array_shift( $tmp_rates );
|
||||
if ( isset( $vat['rate'] ) ) {
|
||||
$item_tax_rate = round( $vat['rate'] * 100 );
|
||||
} else {
|
||||
$item_tax_rate = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$item_tax_rate = 0;
|
||||
}
|
||||
|
||||
return round( $item_tax_rate );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item price.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_price Cart item price.
|
||||
*/
|
||||
public function get_item_price( $cart_item ) {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$item_subtotal = $cart_item['line_subtotal'];
|
||||
} else {
|
||||
$item_subtotal = $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
|
||||
}
|
||||
$item_price = $item_subtotal * 100 / $cart_item['quantity'];
|
||||
|
||||
return round( $item_price );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item quantity.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_quantity Cart item quantity.
|
||||
*/
|
||||
public function get_item_quantity( $cart_item ) {
|
||||
return round( $cart_item['quantity'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item reference.
|
||||
*
|
||||
* Returns SKU or product ID.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param object $product Product object.
|
||||
*
|
||||
* @return string $item_reference Cart item reference.
|
||||
*/
|
||||
public function get_item_reference( $product ) {
|
||||
if ( $product->get_sku() ) {
|
||||
$item_reference = $product->get_sku();
|
||||
} else {
|
||||
$item_reference = $product->get_id();
|
||||
}
|
||||
|
||||
return substr( (string) $item_reference, 0, 64 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item discount.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_discount_amount Cart item discount.
|
||||
*/
|
||||
public function get_item_discount_amount( $cart_item ) {
|
||||
if ( $cart_item['line_subtotal'] > $cart_item['line_total'] ) {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$item_discount_amount = $cart_item['line_subtotal'] - $cart_item['line_total'];
|
||||
} else {
|
||||
$item_discount_amount = $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'] - $cart_item['line_total'] - $cart_item['line_tax'];
|
||||
}
|
||||
$item_discount_amount = $item_discount_amount * 100;
|
||||
} else {
|
||||
$item_discount_amount = 0;
|
||||
}
|
||||
|
||||
return round( $item_discount_amount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item product URL.
|
||||
*
|
||||
* @since 1.1
|
||||
* @access public
|
||||
*
|
||||
* @param WC_Product $product Product.
|
||||
*
|
||||
* @return string $item_product_url Cart item product URL.
|
||||
*/
|
||||
public function get_item_product_url( $product ) {
|
||||
return $product->get_permalink();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item product image URL.
|
||||
*
|
||||
* @since 1.1
|
||||
* @access public
|
||||
*
|
||||
* @param WC_Product $product Product.
|
||||
*
|
||||
* @return string $item_product_image_url Cart item product image URL.
|
||||
*/
|
||||
public function get_item_image_url( $product ) {
|
||||
$image_url = false;
|
||||
if ( $product->get_image_id() > 0 ) {
|
||||
$image_id = $product->get_image_id();
|
||||
$image_url = wp_get_attachment_image_url( $image_id, 'shop_thumbnail', false );
|
||||
}
|
||||
|
||||
return $image_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item discount rate.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_discount_rate Cart item discount rate.
|
||||
*/
|
||||
public function get_item_discount_rate( $cart_item ) {
|
||||
$item_discount_rate = ( 1 - ( $cart_item['line_total'] / $cart_item['line_subtotal'] ) ) * 100 * 100;
|
||||
|
||||
return round( $item_discount_rate );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart item total amount.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $cart_item Cart item.
|
||||
*
|
||||
* @return integer $item_total_amount Cart item total amount.
|
||||
*/
|
||||
public function get_item_total_amount( $cart_item ) {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$item_total_amount = ( $cart_item['line_total'] * 100 );
|
||||
} else {
|
||||
$item_total_amount = ( ( $cart_item['line_total'] + $cart_item['line_tax'] ) * 100 );
|
||||
}
|
||||
|
||||
return round( $item_total_amount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping method name.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string $shipping_name Name for selected shipping method.
|
||||
*/
|
||||
public function get_shipping_name() {
|
||||
$shipping_packages = WC()->shipping->get_packages();
|
||||
foreach ( $shipping_packages as $i => $package ) {
|
||||
$chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : '';
|
||||
if ( '' !== $chosen_method ) {
|
||||
$package_rates = $package['rates'];
|
||||
foreach ( $package_rates as $rate_key => $rate_value ) {
|
||||
if ( $rate_key === $chosen_method ) {
|
||||
$shipping_name = $rate_value->label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! isset( $shipping_name ) ) {
|
||||
$shipping_name = __( 'Shipping', 'klarna-checkout-for-woocommerce' );
|
||||
}
|
||||
|
||||
return (string) $shipping_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping reference.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string $shipping_reference Reference for selected shipping method.
|
||||
*/
|
||||
public function get_shipping_reference() {
|
||||
$shipping_packages = WC()->shipping->get_packages();
|
||||
foreach ( $shipping_packages as $i => $package ) {
|
||||
$chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : '';
|
||||
if ( '' !== $chosen_method ) {
|
||||
$package_rates = $package['rates'];
|
||||
foreach ( $package_rates as $rate_key => $rate_value ) {
|
||||
if ( $rate_key === $chosen_method ) {
|
||||
$shipping_reference = $rate_value->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! isset( $shipping_reference ) ) {
|
||||
$shipping_reference = __( 'Shipping', 'klarna-checkout-for-woocommerce' );
|
||||
}
|
||||
|
||||
return (string) $shipping_reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping method amount.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return integer $shipping_amount Amount for selected shipping method.
|
||||
*/
|
||||
public function get_shipping_amount() {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$shipping_amount = (int) number_format( WC()->cart->shipping_total * 100, 0, '', '' );
|
||||
} else {
|
||||
$shipping_amount = (int) number_format( ( WC()->cart->shipping_total + WC()->cart->shipping_tax_total ) * 100, 0, '', '' );
|
||||
}
|
||||
|
||||
return $shipping_amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping method tax rate.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return integer $shipping_tax_rate Tax rate for selected shipping method.
|
||||
*/
|
||||
public function get_shipping_tax_rate() {
|
||||
if ( WC()->cart->shipping_tax_total > 0 && ! $this->separate_sales_tax ) {
|
||||
$shipping_tax_rate = round( WC()->cart->shipping_tax_total / WC()->cart->shipping_total, 2 ) * 100 * 100;
|
||||
} else {
|
||||
$shipping_tax_rate = 0;
|
||||
}
|
||||
|
||||
return round( $shipping_tax_rate );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping method tax amount.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return integer $shipping_tax_amount Tax amount for selected shipping method.
|
||||
*/
|
||||
public function get_shipping_tax_amount() {
|
||||
if ( $this->separate_sales_tax ) {
|
||||
$shipping_tax_amount = 0;
|
||||
} else {
|
||||
$shipping_tax_amount = WC()->cart->shipping_tax_total * 100;
|
||||
}
|
||||
|
||||
return round( $shipping_tax_amount );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce status page extension
|
||||
*
|
||||
* @class Klarna_Checkout_For_WooCommerce_Status
|
||||
* @version 0.8.0
|
||||
* @package Klarna_Checkout_For_WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author Krokedil
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
class Klarna_Checkout_For_WooCommerce_Status {
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_system_status_report', array( $this, 'add_status_page_box' ) );
|
||||
}
|
||||
public function add_status_page_box() {
|
||||
include_once( KCO_WC_PLUGIN_PATH . '/includes/klarna-checkout-for-woocommerce-status-report.php' );
|
||||
}
|
||||
}
|
||||
$wc_collector_checkout_status = new Klarna_Checkout_For_WooCommerce_Status();
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
/**
|
||||
* Klarna_Checkout_For_WooCommerce_Templates class.
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce_Templates {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin actions.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Override template if Klarna Checkout page.
|
||||
add_filter( 'woocommerce_locate_template', array( $this, 'override_template' ), 10, 3 );
|
||||
|
||||
// Template hooks.
|
||||
add_action( 'kco_wc_before_checkout_form', 'kco_wc_print_notices' );
|
||||
add_action( 'kco_wc_before_checkout_form', 'kco_wc_calculate_totals', 1 );
|
||||
add_action( 'kco_wc_before_checkout_form', 'woocommerce_checkout_login_form', 10 );
|
||||
add_action( 'kco_wc_before_checkout_form', 'woocommerce_checkout_coupon_form', 20 );
|
||||
add_action( 'kco_wc_after_order_review', 'kco_wc_show_extra_fields', 10 );
|
||||
add_action( 'kco_wc_after_order_review', 'kco_wc_show_another_gateway_button', 20 );
|
||||
add_action( 'kco_wc_before_snippet', 'kco_wc_prefill_consent', 10 );
|
||||
add_action( 'kco_wc_after_snippet', 'kco_wc_show_payment_method_field', 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Override checkout form template if Klarna Checkout is the selected payment method.
|
||||
*
|
||||
* @param string $template Template.
|
||||
* @param string $template_name Template name.
|
||||
* @param string $template_path Template path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function override_template( $template, $template_name, $template_path ) {
|
||||
if ( is_checkout() ) {
|
||||
// Klarna Checkout.
|
||||
if ( 'checkout/form-checkout.php' === $template_name ) {
|
||||
$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();
|
||||
|
||||
if ( locate_template( 'woocommerce/klarna-checkout.php' ) ) {
|
||||
$klarna_checkout_template = locate_template( 'woocommerce/klarna-checkout.php' );
|
||||
} else {
|
||||
$klarna_checkout_template = KCO_WC_PLUGIN_PATH . '/templates/klarna-checkout.php';
|
||||
}
|
||||
|
||||
// Klarna checkout page.
|
||||
if ( array_key_exists( 'kco', $available_gateways ) ) {
|
||||
// If chosen payment method exists.
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
if ( ! isset( $_GET['confirm'] ) ) {
|
||||
$template = $klarna_checkout_template;
|
||||
}
|
||||
}
|
||||
|
||||
// If chosen payment method does not exist and KCO is the first gateway.
|
||||
if ( null === WC()->session->get( 'chosen_payment_method' ) || '' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
reset( $available_gateways );
|
||||
|
||||
if ( 'kco' === key( $available_gateways ) ) {
|
||||
if ( ! isset( $_GET['confirm'] ) ) {
|
||||
$template = $klarna_checkout_template;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If another gateway is saved in session, but has since become unavailable.
|
||||
if ( WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
if ( ! array_key_exists( WC()->session->get( 'chosen_payment_method' ), $available_gateways ) ) {
|
||||
reset( $available_gateways );
|
||||
|
||||
if ( 'kco' === key( $available_gateways ) ) {
|
||||
if ( ! isset( $_GET['confirm'] ) ) {
|
||||
$template = $klarna_checkout_template;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback Klarna Order Received, used when WooCommerce checkout form submission fails.
|
||||
if ( 'checkout/thankyou.php' === $template_name ) {
|
||||
if ( isset( $_GET['kco_wc'] ) && 'true' === $_GET['kco_wc'] ) {
|
||||
$template = KCO_WC_PLUGIN_PATH . '/templates/klarna-checkout-order-received.php';
|
||||
}
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce_Templates::get_instance();
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if ( ! class_exists( 'WC_Klarna_Banners' ) ) {
|
||||
/**
|
||||
* Displays merchant information in the backend.
|
||||
*/
|
||||
class WC_Klarna_Banners {
|
||||
/**
|
||||
* WC_Klarna_Banners constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'in_admin_header', array( $this, 'klarna_banner' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_css' ) );
|
||||
add_action( 'wp_ajax_hide_klarna_banner', array( $this, 'hide_klarna_banner' ) );
|
||||
add_action( 'wp_ajax_nopriv_hide_klarna_banner', array( $this, 'hide_klarna_banner' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads admin CSS file, has to be done here instead of gateway class, because
|
||||
* it is required in all admin pages.
|
||||
*/
|
||||
public function load_admin_css() {
|
||||
wp_enqueue_style(
|
||||
'klarna_payments_admin',
|
||||
plugins_url( 'assets/css/klarna-checkout-admin.css?v=120320182113', KCO_WC_MAIN_FILE )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Klarna banner in admin pages.
|
||||
*/
|
||||
public function klarna_banner() {
|
||||
$kco_settings = get_option( 'woocommerce_kco_settings' );
|
||||
$show_banner = false;
|
||||
|
||||
// Always show banner in testmode.
|
||||
if ( isset( $kco_settings['testmode'] ) && 'yes' === $kco_settings['testmode'] ) {
|
||||
$show_banner = true;
|
||||
}
|
||||
|
||||
// Go through countries and check if at least one has credentials configured.
|
||||
$countries = array( 'eu', 'us' );
|
||||
$country_set = false;
|
||||
foreach ( $countries as $country ) {
|
||||
if ( '' !== $kco_settings[ 'merchant_id_' . $country ] && '' !== $kco_settings[ 'shared_secret_' . $country ] ) {
|
||||
$country_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $country_set ) {
|
||||
$show_banner = true;
|
||||
}
|
||||
|
||||
if ( $show_banner && false === get_transient( 'klarna_hide_banner' ) ) {
|
||||
?>
|
||||
<div id="kb-spacer"></div>
|
||||
<div id="klarna-banner">
|
||||
<div id="kb-left">
|
||||
<h1>Go live</h1>
|
||||
<p>Before you can start to sell with Klarna you need your store to be approved by Klarna. When the installation is done and you are ready to go live, Klarna will need to verify the integration. Then you can go live with your store! If you wish to switch Klarna products then you’ll need the Klarna team to approve your store again.</p>
|
||||
<a class="kb-button"
|
||||
href="https://www.klarna.com/international/business/woocommerce/?utm_source=woo-backend&utm_medium=referral&utm_campaign=woo&utm_content=banner"
|
||||
target="_blank">Go live with Klarna</a>
|
||||
</div>
|
||||
<div id="kb-right">
|
||||
<h1>Currently using Klarna?</h1>
|
||||
<p>Pay now, Pay later and Slice it. Klarna is entering a new world of smoooth. We would love for you to join us on the ride and to do so, you will need to upgrade your Klarna products to a new integration. You will then always get the latest features that Klarna develops and you’ll keep your current agreement along with your price settings.</p>
|
||||
<a class="kb-button"
|
||||
href="https://hello.klarna.com/product-upgrade?utm_source=woo-backend&utm_medium=referral&utm_campaign=woo&utm_content=banner"
|
||||
target="_blank">Upgrade your contract with Klarna</a>
|
||||
</div>
|
||||
<img id="kb-image"
|
||||
src="<?php echo esc_url( KCO_WC_PLUGIN_URL ); ?>/assets/img/klarna_logo_white.png"
|
||||
alt="Klarna logo" width="110"/>
|
||||
<span class="kb-dismiss dashicons dashicons-dismiss"></span>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
jQuery(document).ready(function($){
|
||||
|
||||
jQuery('.kb-dismiss').click(function(){
|
||||
jQuery('#klarna-banner').slideUp();
|
||||
jQuery.post(
|
||||
ajaxurl,
|
||||
{
|
||||
action : 'hide_klarna_banner',
|
||||
_wpnonce : '<?php echo wp_create_nonce('hide-klarna-banner'); ?>',
|
||||
},
|
||||
function(response){
|
||||
console.log('Success hide kco banner');
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parent_options
|
||||
*/
|
||||
public static function settings_sidebar( $parent_options ) {
|
||||
?>
|
||||
<img id="klarna-settings-logo"
|
||||
src="<?php echo esc_url( KCO_WC_PLUGIN_URL ); ?>/assets/img/klarna_logo_black.png" width="200"/>
|
||||
|
||||
<div id="klarna-wrapper">
|
||||
<div id="klarna-main">
|
||||
<?php echo $parent_options; ?>
|
||||
</div>
|
||||
<div id="klarna-sidebar">
|
||||
<div class="kb-sidebar-section">
|
||||
<img src="<?php echo esc_url( KCO_WC_PLUGIN_URL ); ?>/assets/img/icon_reminder.png" width="64"/>
|
||||
<h3>Go live</h3>
|
||||
<p>Before you can start to sell with Klarna you need your store to be approved by Klarna. When the installation is done and you are ready to go live, Klarna will need to verify the integration. Then you can go live with your store! If you wish to switch Klarna products then you’ll need the Klarna team to approve your store again.</p>
|
||||
<a class="kb-button"
|
||||
href="https://www.klarna.com/international/business/woocommerce/?utm_source=woo-backend&utm_medium=referral&utm_campaign=woo&utm_content=kco"
|
||||
target="_blank">Go live with Klarna</a>
|
||||
</div>
|
||||
|
||||
<div class="kb-sidebar-section">
|
||||
<div>
|
||||
<img src="<?php echo esc_url( KCO_WC_PLUGIN_URL ); ?>/assets/img/klarna_icons.png"
|
||||
width="192"/>
|
||||
</div>
|
||||
<h3>Currently using Klarna?</h3>
|
||||
<p>Pay now, Pay later and Slice it. Klarna is entering a new world of smoooth. We would love for you to join us on the ride and to do so, you will need to upgrade your Klarna products to a new integration. You will then always get the latest features that Klarna develops and you’ll keep your current agreement along with your price settings.</p>
|
||||
<a class="kb-button"
|
||||
href="https://hello.klarna.com/product-upgrade?utm_source=woo-backend&utm_medium=referral&utm_campaign=woo&utm_content=kco"
|
||||
target="_blank">Upgrade your contract with Klarna</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide Klarna banner in admin pages for.
|
||||
*/
|
||||
public function hide_klarna_banner() {
|
||||
set_transient( 'klarna_hide_banner', '1', 5 * DAY_IN_SECONDS );
|
||||
wp_send_json_success( 'Hejä' );
|
||||
wp_die();
|
||||
}
|
||||
}
|
||||
|
||||
new WC_Klarna_Banners();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes Klarna Checkout iframe snippet.
|
||||
*/
|
||||
function kco_wc_show_snippet() {
|
||||
$klarna_order = KCO_WC()->api->get_order();
|
||||
echo KCO_WC()->api->get_snippet( $klarna_order );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows order notes field in Klarna Checkout page.
|
||||
*/
|
||||
function kco_wc_show_order_notes() {
|
||||
$order_fields = WC()->checkout()->get_checkout_fields( 'order' );
|
||||
$key = 'order_comments';
|
||||
if ( array_key_exists( $key, $order_fields ) ) {
|
||||
$order_notes_field = $order_fields[ $key ];
|
||||
woocommerce_form_field( $key, $order_notes_field, WC()->checkout()->get_value( $key ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows extra fields in Klarna Checkout page.
|
||||
*/
|
||||
function kco_wc_show_extra_fields() {
|
||||
// Clear extra fields session values on reload.
|
||||
// WC()->session->__unset( 'kco_wc_extra_fields_values' );
|
||||
|
||||
echo '<div id="kco-extra-fields">';
|
||||
|
||||
$extra_fields_values = WC()->session->get( 'kco_wc_extra_fields_values', array() );
|
||||
$kco_wc_extra_checkout_fields = new Klarna_Checkout_For_WooCommerce_Extra_Checkout_Fields;
|
||||
$extra_fields = $kco_wc_extra_checkout_fields->get_remaining_checkout_fields();
|
||||
|
||||
// Billing.
|
||||
do_action( 'woocommerce_before_checkout_billing_form', WC()->checkout() );
|
||||
foreach ( $extra_fields['billing'] as $key => $field ) {
|
||||
if ( isset( $field['country_field'], $default_billing_fields[ $field['country_field'] ] ) ) {
|
||||
$field['country'] = WC()->checkout()->get_value( $field['country_field'] );
|
||||
}
|
||||
$key_value = array_key_exists( $key, $extra_fields_values ) ? $extra_fields_values[ $key ] : '';
|
||||
woocommerce_form_field( $key, $field, $key_value );
|
||||
}
|
||||
do_action( 'woocommerce_after_checkout_billing_form', WC()->checkout() );
|
||||
|
||||
if ( ! is_user_logged_in() && WC()->checkout()->is_registration_enabled() ) { ?>
|
||||
<div class="woocommerce-account-fields">
|
||||
<?php if ( ! WC()->checkout()->is_registration_required() ) { ?>
|
||||
<p class="form-row form-row-wide create-account">
|
||||
<label class="woocommerce-form__label woocommerce-form__label-for-checkbox checkbox">
|
||||
<input class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox"
|
||||
id="createaccount" <?php checked( ( true === WC()->checkout()->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true ) ?>
|
||||
type="checkbox" name="createaccount" value="1"/>
|
||||
<span><?php _e( 'Create an account?', 'klarna-checkout-for-woocommerce' ); ?></span>
|
||||
</label>
|
||||
</p>
|
||||
<?php } ?>
|
||||
|
||||
<?php do_action( 'woocommerce_before_checkout_registration_form', WC()->checkout() ); ?>
|
||||
|
||||
<?php if ( WC()->checkout()->get_checkout_fields( 'account' ) ) { ?>
|
||||
|
||||
<div class="create-account">
|
||||
<?php foreach ( WC()->checkout()->get_checkout_fields( 'account' ) as $key => $field ) { ?>
|
||||
<?php woocommerce_form_field( $key, $field, WC()->checkout()->get_value( $key ) ); ?>
|
||||
<?php } ?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<?php do_action( 'woocommerce_after_checkout_registration_form', WC()->checkout() ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Shipping.
|
||||
do_action( 'woocommerce_before_checkout_shipping_form', WC()->checkout() );
|
||||
foreach ( $extra_fields['shipping'] as $key => $field ) {
|
||||
if ( isset( $field['country_field'], $default_shipping_fields[ $field['country_field'] ] ) ) {
|
||||
$field['country'] = WC()->checkout()->get_value( $field['country_field'] );
|
||||
}
|
||||
$key_value = array_key_exists( $key, $extra_fields_values ) ? $extra_fields_values[ $key ] : '';
|
||||
woocommerce_form_field( $key, $field, $key_value );
|
||||
}
|
||||
do_action( 'woocommerce_after_checkout_shipping_form', WC()->checkout() );
|
||||
|
||||
// Order.
|
||||
do_action( 'woocommerce_before_order_notes', WC()->checkout() );
|
||||
if ( apply_filters( 'woocommerce_enable_order_notes_field', true ) ) {
|
||||
foreach ( $extra_fields['order'] as $key => $field ) {
|
||||
$key_value = array_key_exists( $key, $extra_fields_values ) ? $extra_fields_values[ $key ] : '';
|
||||
woocommerce_form_field( $key, $field, $key_value );
|
||||
}
|
||||
}
|
||||
do_action( 'woocommerce_after_order_notes', WC()->checkout() );
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows select another payment method button in Klarna Checkout page.
|
||||
*/
|
||||
function kco_wc_show_another_gateway_button() {
|
||||
$available_gateways = WC()->payment_gateways()->get_available_payment_gateways();
|
||||
|
||||
if ( count( $available_gateways ) > 1 ) {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
$select_another_method_text = isset( $settings['select_another_method_text'] ) && '' !== $settings['select_another_method_text'] ? $settings['select_another_method_text'] : __( 'Select another payment method', 'klarna-checkout-for-woocommerce' );
|
||||
|
||||
?>
|
||||
<p style="margin-top:30px">
|
||||
<a class="checkout-button button" href="#" id="klarna-checkout-select-other">
|
||||
<?php echo $select_another_method_text; ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it OK to prefill customer data?
|
||||
*/
|
||||
function kco_wc_prefill_allowed() {
|
||||
$base_location = wc_get_base_location();
|
||||
|
||||
if ( 'DE' === $base_location['country'] || 'AT' === $base_location['country'] ) {
|
||||
$settings = get_option( 'woocommerce_kco_settings' );
|
||||
$consent_setting_checked = ( isset( $settings['prefill_consent'] ) && 'yes' === $settings['prefill_consent'] );
|
||||
|
||||
if ( $consent_setting_checked && is_user_logged_in() && WC()->session->get( 'kco_wc_prefill_consent', false ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates cart totals.
|
||||
*/
|
||||
function kco_wc_calculate_totals() {
|
||||
WC()->cart->calculate_fees();
|
||||
WC()->cart->calculate_shipping();
|
||||
WC()->cart->calculate_totals();
|
||||
}
|
||||
|
||||
function kco_wc_show_payment_method_field() {
|
||||
?>
|
||||
<input style="display:none" type="radio" name="payment_method" value="kco"/>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows prefill consent text.
|
||||
*/
|
||||
function kco_wc_prefill_consent() {
|
||||
if ( ! kco_wc_prefill_allowed() && is_user_logged_in() ) {
|
||||
$consent_url = add_query_arg(
|
||||
[ 'prefill_consent' => 'yes' ],
|
||||
wc_get_checkout_url()
|
||||
);
|
||||
|
||||
$credentials = KCO_WC()->credentials->get_credentials_from_session();
|
||||
$merchant_id = $credentials['merchant_id'];
|
||||
|
||||
if ( 'de_DE' === get_locale() ) {
|
||||
$button_text = 'Meine Adressdaten vorausfüllen';
|
||||
$link_text = 'Es gelten die Nutzungsbedingungen zur Datenübertragung';
|
||||
$popup_text = 'In unserem Kassenbereich nutzen wir Klarna Checkout. Dazu werden Ihre Daten, wie E-Mail-Adresse, Vor- und
|
||||
Nachname, Geburtsdatum, Adresse und Telefonnummer, soweit erforderlich, automatisch an Klarna AB übertragen,
|
||||
sobald Sie in den Kassenbereich gelangen. Die Nutzungsbedingungen für Klarna Checkout finden Sie hier:
|
||||
<a href="https://cdn.klarna.com/1.0/shared/content/legal/terms/' . $merchant_id . '/de_de/checkout" target="_blank">https://cdn.klarna.com/1.0/shared/content/legal/terms/' . $merchant_id . '/de_de/checkout</a>';
|
||||
} else {
|
||||
$button_text = 'Meine Adressdaten vorausfüllen';
|
||||
$link_text = 'Es gelten die Nutzungsbedingungen zur Datenübertragung';
|
||||
$popup_text = 'We use Klarna Checkout as our checkout, which offers a simplified purchase experience. When you choose to go to the checkout, your email address, first name, last name, date of birth, address and phone number may be automatically transferred to Klarna AB, enabling the provision of Klarna Checkout. These User Terms apply for the use of Klarna Checkout is available here:
|
||||
<a target="_blank" href="https://cdn.klarna.com/1.0/shared/content/legal/terms/' . $merchant_id . '/en_us/checkout">https://cdn.klarna.com/1.0/shared/content/legal/terms/' . $merchant_id . '/en_us/checkout</a>';
|
||||
}
|
||||
?>
|
||||
<p><a class="button" href="<?php echo $consent_url; ?>"><?php echo $button_text; ?></a></p>
|
||||
<p><a href="#TB_inline?width=600&height=550&inlineId=consent-text"
|
||||
class="thickbox"><?php echo $link_text; ?></a>
|
||||
</p>
|
||||
<div id="consent-text" style="display:none;">
|
||||
<p><?php echo $popup_text; ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts 3-letter ISO returned from Klarna to 2-letter code used in WooCommerce.
|
||||
*
|
||||
* @param $country
|
||||
*/
|
||||
function kco_wc_country_code_converter( $country ) {
|
||||
$countries = array(
|
||||
'AF' => 'AFG', // Afghanistan.
|
||||
'AX' => 'ALA', // Aland Islands.
|
||||
'AL' => 'ALB', // Albania.
|
||||
'DZ' => 'DZA', // Algeria.
|
||||
'AS' => 'ASM', // American Samoa.
|
||||
'AD' => 'AND', // Andorra.
|
||||
'AO' => 'AGO', // Angola.
|
||||
'AI' => 'AIA', // Anguilla.
|
||||
'AQ' => 'ATA', // Antarctica.
|
||||
'AG' => 'ATG', // Antigua and Barbuda.
|
||||
'AR' => 'ARG', // Argentina.
|
||||
'AM' => 'ARM', // Armenia.
|
||||
'AW' => 'ABW', // Aruba.
|
||||
'AU' => 'AUS', // Australia.
|
||||
'AT' => 'AUT', // Austria.
|
||||
'AZ' => 'AZE', // Azerbaijan.
|
||||
'BS' => 'BHS', // Bahamas.
|
||||
'BH' => 'BHR', // Bahrain.
|
||||
'BD' => 'BGD', // Bangladesh.
|
||||
'BB' => 'BRB', // Barbados.
|
||||
'BY' => 'BLR', // Belarus.
|
||||
'BE' => 'BEL', // Belgium.
|
||||
'BZ' => 'BLZ', // Belize.
|
||||
'BJ' => 'BEN', // Benin.
|
||||
'BM' => 'BMU', // Bermuda.
|
||||
'BT' => 'BTN', // Bhutan.
|
||||
'BO' => 'BOL', // Bolivia.
|
||||
'BQ' => 'BES', // Bonaire, Saint Estatius and Saba.
|
||||
'BA' => 'BIH', // Bosnia and Herzegovina.
|
||||
'BW' => 'BWA', // Botswana.
|
||||
'BV' => 'BVT', // Bouvet Islands.
|
||||
'BR' => 'BRA', // Brazil.
|
||||
'IO' => 'IOT', // British Indian Ocean Territory.
|
||||
'BN' => 'BRN', // Brunei.
|
||||
'BG' => 'BGR', // Bulgaria.
|
||||
'BF' => 'BFA', // Burkina Faso.
|
||||
'BI' => 'BDI', // Burundi.
|
||||
'KH' => 'KHM', // Cambodia.
|
||||
'CM' => 'CMR', // Cameroon.
|
||||
'CA' => 'CAN', // Canada.
|
||||
'CV' => 'CPV', // Cape Verde.
|
||||
'KY' => 'CYM', // Cayman Islands.
|
||||
'CF' => 'CAF', // Central African Republic.
|
||||
'TD' => 'TCD', // Chad.
|
||||
'CL' => 'CHL', // Chile.
|
||||
'CN' => 'CHN', // China.
|
||||
'CX' => 'CXR', // Christmas Island.
|
||||
'CC' => 'CCK', // Cocos (Keeling) Islands.
|
||||
'CO' => 'COL', // Colombia.
|
||||
'KM' => 'COM', // Comoros.
|
||||
'CG' => 'COG', // Congo.
|
||||
'CD' => 'COD', // Congo, Democratic Republic of the.
|
||||
'CK' => 'COK', // Cook Islands.
|
||||
'CR' => 'CRI', // Costa Rica.
|
||||
'CI' => 'CIV', // Côte d\'Ivoire.
|
||||
'HR' => 'HRV', // Croatia.
|
||||
'CU' => 'CUB', // Cuba.
|
||||
'CW' => 'CUW', // Curaçao.
|
||||
'CY' => 'CYP', // Cyprus.
|
||||
'CZ' => 'CZE', // Czech Republic.
|
||||
'DK' => 'DNK', // Denmark.
|
||||
'DJ' => 'DJI', // Djibouti.
|
||||
'DM' => 'DMA', // Dominica.
|
||||
'DO' => 'DOM', // Dominican Republic.
|
||||
'EC' => 'ECU', // Ecuador.
|
||||
'EG' => 'EGY', // Egypt.
|
||||
'SV' => 'SLV', // El Salvador.
|
||||
'GQ' => 'GNQ', // Equatorial Guinea.
|
||||
'ER' => 'ERI', // Eritrea.
|
||||
'EE' => 'EST', // Estonia.
|
||||
'ET' => 'ETH', // Ethiopia.
|
||||
'FK' => 'FLK', // Falkland Islands.
|
||||
'FO' => 'FRO', // Faroe Islands.
|
||||
'FJ' => 'FIJ', // Fiji.
|
||||
'FI' => 'FIN', // Finland.
|
||||
'FR' => 'FRA', // France.
|
||||
'GF' => 'GUF', // French Guiana.
|
||||
'PF' => 'PYF', // French Polynesia.
|
||||
'TF' => 'ATF', // French Southern Territories.
|
||||
'GA' => 'GAB', // Gabon.
|
||||
'GM' => 'GMB', // Gambia.
|
||||
'GE' => 'GEO', // Georgia.
|
||||
'DE' => 'DEU', // Germany.
|
||||
'GH' => 'GHA', // Ghana.
|
||||
'GI' => 'GIB', // Gibraltar.
|
||||
'GR' => 'GRC', // Greece.
|
||||
'GL' => 'GRL', // Greenland.
|
||||
'GD' => 'GRD', // Grenada.
|
||||
'GP' => 'GLP', // Guadeloupe.
|
||||
'GU' => 'GUM', // Guam.
|
||||
'GT' => 'GTM', // Guatemala.
|
||||
'GG' => 'GGY', // Guernsey.
|
||||
'GN' => 'GIN', // Guinea.
|
||||
'GW' => 'GNB', // Guinea-Bissau.
|
||||
'GY' => 'GUY', // Guyana.
|
||||
'HT' => 'HTI', // Haiti.
|
||||
'HM' => 'HMD', // Heard Island and McDonald Islands.
|
||||
'VA' => 'VAT', // Holy See (Vatican City State).
|
||||
'HN' => 'HND', // Honduras.
|
||||
'HK' => 'HKG', // Hong Kong.
|
||||
'HU' => 'HUN', // Hungary.
|
||||
'IS' => 'ISL', // Iceland.
|
||||
'IN' => 'IND', // India.
|
||||
'ID' => 'IDN', // Indonesia.
|
||||
'IR' => 'IRN', // Iran.
|
||||
'IQ' => 'IRQ', // Iraq.
|
||||
'IE' => 'IRL', // Republic of Ireland.
|
||||
'IM' => 'IMN', // Isle of Man.
|
||||
'IL' => 'ISR', // Israel.
|
||||
'IT' => 'ITA', // Italy.
|
||||
'JM' => 'JAM', // Jamaica.
|
||||
'JP' => 'JPN', // Japan.
|
||||
'JE' => 'JEY', // Jersey.
|
||||
'JO' => 'JOR', // Jordan.
|
||||
'KZ' => 'KAZ', // Kazakhstan.
|
||||
'KE' => 'KEN', // Kenya.
|
||||
'KI' => 'KIR', // Kiribati.
|
||||
'KP' => 'PRK', // Korea, Democratic People's Republic of.
|
||||
'KR' => 'KOR', // Korea, Republic of (South).
|
||||
'KW' => 'KWT', // Kuwait.
|
||||
'KG' => 'KGZ', // Kyrgyzstan.
|
||||
'LA' => 'LAO', // Laos.
|
||||
'LV' => 'LVA', // Latvia.
|
||||
'LB' => 'LBN', // Lebanon.
|
||||
'LS' => 'LSO', // Lesotho.
|
||||
'LR' => 'LBR', // Liberia.
|
||||
'LY' => 'LBY', // Libya.
|
||||
'LI' => 'LIE', // Liechtenstein.
|
||||
'LT' => 'LTU', // Lithuania.
|
||||
'LU' => 'LUX', // Luxembourg.
|
||||
'MO' => 'MAC', // Macao S.A.R., China.
|
||||
'MK' => 'MKD', // Macedonia.
|
||||
'MG' => 'MDG', // Madagascar.
|
||||
'MW' => 'MWI', // Malawi.
|
||||
'MY' => 'MYS', // Malaysia.
|
||||
'MV' => 'MDV', // Maldives.
|
||||
'ML' => 'MLI', // Mali.
|
||||
'MT' => 'MLT', // Malta.
|
||||
'MH' => 'MHL', // Marshall Islands.
|
||||
'MQ' => 'MTQ', // Martinique.
|
||||
'MR' => 'MRT', // Mauritania.
|
||||
'MU' => 'MUS', // Mauritius.
|
||||
'YT' => 'MYT', // Mayotte.
|
||||
'MX' => 'MEX', // Mexico.
|
||||
'FM' => 'FSM', // Micronesia.
|
||||
'MD' => 'MDA', // Moldova.
|
||||
'MC' => 'MCO', // Monaco.
|
||||
'MN' => 'MNG', // Mongolia.
|
||||
'ME' => 'MNE', // Montenegro.
|
||||
'MS' => 'MSR', // Montserrat.
|
||||
'MA' => 'MAR', // Morocco.
|
||||
'MZ' => 'MOZ', // Mozambique.
|
||||
'MM' => 'MMR', // Myanmar.
|
||||
'NA' => 'NAM', // Namibia.
|
||||
'NR' => 'NRU', // Nauru.
|
||||
'NP' => 'NPL', // Nepal.
|
||||
'NL' => 'NLD', // Netherlands.
|
||||
'AN' => 'ANT', // Netherlands Antilles.
|
||||
'NC' => 'NCL', // New Caledonia.
|
||||
'NZ' => 'NZL', // New Zealand.
|
||||
'NI' => 'NIC', // Nicaragua.
|
||||
'NE' => 'NER', // Niger.
|
||||
'NG' => 'NGA', // Nigeria.
|
||||
'NU' => 'NIU', // Niue.
|
||||
'NF' => 'NFK', // Norfolk Island.
|
||||
'MP' => 'MNP', // Northern Mariana Islands.
|
||||
'NO' => 'NOR', // Norway.
|
||||
'OM' => 'OMN', // Oman.
|
||||
'PK' => 'PAK', // Pakistan.
|
||||
'PW' => 'PLW', // Palau.
|
||||
'PS' => 'PSE', // Palestinian Territory.
|
||||
'PA' => 'PAN', // Panama.
|
||||
'PG' => 'PNG', // Papua New Guinea.
|
||||
'PY' => 'PRY', // Paraguay.
|
||||
'PE' => 'PER', // Peru.
|
||||
'PH' => 'PHL', // Philippines.
|
||||
'PN' => 'PCN', // Pitcairn.
|
||||
'PL' => 'POL', // Poland.
|
||||
'PT' => 'PRT', // Portugal.
|
||||
'PR' => 'PRI', // Puerto Rico.
|
||||
'QA' => 'QAT', // Qatar.
|
||||
'RE' => 'REU', // Reunion.
|
||||
'RO' => 'ROU', // Romania.
|
||||
'RU' => 'RUS', // Russia.
|
||||
'RW' => 'RWA', // Rwanda.
|
||||
'BL' => 'BLM', // Saint Bartholemy.
|
||||
'SH' => 'SHN', // Saint Helena.
|
||||
'KN' => 'KNA', // Saint Kitts and Nevis.
|
||||
'LC' => 'LCA', // Saint Lucia.
|
||||
'MF' => 'MAF', // Saint Martin (French part).
|
||||
'SX' => 'SXM', // Sint Maarten / Saint Martin (Dutch part).
|
||||
'PM' => 'SPM', // Saint Pierre and Miquelon.
|
||||
'VC' => 'VCT', // Saint Vincent and the Grenadines.
|
||||
'WS' => 'WSM', // Samoa.
|
||||
'SM' => 'SMR', // San Marino.
|
||||
'ST' => 'STP', // Sso Tome and Principe.
|
||||
'SA' => 'SAU', // Saudi Arabia.
|
||||
'SN' => 'SEN', // Senegal.
|
||||
'RS' => 'SRB', // Serbia.
|
||||
'SC' => 'SYC', // Seychelles.
|
||||
'SL' => 'SLE', // Sierra Leone.
|
||||
'SG' => 'SGP', // Singapore.
|
||||
'SK' => 'SVK', // Slovakia.
|
||||
'SI' => 'SVN', // Slovenia.
|
||||
'SB' => 'SLB', // Solomon Islands.
|
||||
'SO' => 'SOM', // Somalia.
|
||||
'ZA' => 'ZAF', // South Africa.
|
||||
'GS' => 'SGS', // South Georgia/Sandwich Islands.
|
||||
'SS' => 'SSD', // South Sudan.
|
||||
'ES' => 'ESP', // Spain.
|
||||
'LK' => 'LKA', // Sri Lanka.
|
||||
'SD' => 'SDN', // Sudan.
|
||||
'SR' => 'SUR', // Suriname.
|
||||
'SJ' => 'SJM', // Svalbard and Jan Mayen.
|
||||
'SZ' => 'SWZ', // Swaziland.
|
||||
'SE' => 'SWE', // Sweden.
|
||||
'CH' => 'CHE', // Switzerland.
|
||||
'SY' => 'SYR', // Syria.
|
||||
'TW' => 'TWN', // Taiwan.
|
||||
'TJ' => 'TJK', // Tajikistan.
|
||||
'TZ' => 'TZA', // Tanzania.
|
||||
'TH' => 'THA', // Thailand.
|
||||
'TL' => 'TLS', // Timor-Leste.
|
||||
'TG' => 'TGO', // Togo.
|
||||
'TK' => 'TKL', // Tokelau.
|
||||
'TO' => 'TON', // Tonga.
|
||||
'TT' => 'TTO', // Trinidad and Tobago.
|
||||
'TN' => 'TUN', // Tunisia.
|
||||
'TR' => 'TUR', // Turkey.
|
||||
'TM' => 'TKM', // Turkmenistan.
|
||||
'TC' => 'TCA', // Turks and Caicos Islands.
|
||||
'TV' => 'TUV', // Tuvalu.
|
||||
'UG' => 'UGA', // Uganda.
|
||||
'UA' => 'UKR', // Ukraine.
|
||||
'AE' => 'ARE', // United Arab Emirates.
|
||||
'GB' => 'GBR', // United Kingdom.
|
||||
'US' => 'USA', // United States.
|
||||
'UM' => 'UMI', // United States Minor Outlying Islands.
|
||||
'UY' => 'URY', // Uruguay.
|
||||
'UZ' => 'UZB', // Uzbekistan.
|
||||
'VU' => 'VUT', // Vanuatu.
|
||||
'VE' => 'VEN', // Venezuela.
|
||||
'VN' => 'VNM', // Vietnam.
|
||||
'VG' => 'VGB', // Virgin Islands, British.
|
||||
'VI' => 'VIR', // Virgin Island, U.S..
|
||||
'WF' => 'WLF', // Wallis and Futuna.
|
||||
'EH' => 'ESH', // Western Sahara.
|
||||
'YE' => 'YEM', // Yemen.
|
||||
'ZM' => 'ZMB', // Zambia.
|
||||
'ZW' => 'ZWE', // Zimbabwe.
|
||||
);
|
||||
|
||||
return array_search( strtoupper( $country ), $countries, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints error notices if needed.
|
||||
*/
|
||||
function kco_wc_print_notices() {
|
||||
if ( isset( $_GET['stock_validate_failed'] ) ) {
|
||||
wc_add_notice( __( 'Not all products are in stock.', 'klarna-checkout-for-woocommerce' ), 'error' );
|
||||
} elseif ( isset( $_GET['no_shipping'] ) ) {
|
||||
wc_add_notice( __( 'No shipping was selected.', 'klarna-checkout-for-woocommerce' ), 'error' );
|
||||
} elseif ( isset( $_GET['required_fields'] ) ) {
|
||||
$failed_fields = json_decode( base64_decode( $_GET['required_fields'] ) );
|
||||
$fields_string = '';
|
||||
foreach ( $failed_fields as $field ) {
|
||||
$fields_string = $fields_string . ' ' . $field;
|
||||
}
|
||||
wc_add_notice( __( sprintf( 'The following fields are required:%s.', $fields_string ), 'klarna-checkout-for-woocommerce' ), 'error' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin View: Page - Status Report.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
<table class="wc_status_table widefat" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3" data-export-label="Klarna Checkout">
|
||||
<h2><?php _e( 'Klarna Checkout', 'klarna-checkout-for-woocommerce' ); ?><?php echo wc_help_tip( __( 'Klarna Checkout System Status.', 'klarna-checkout-for-woocommerce' ) ); ?></h2>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-export-label="Orders created via API callback"><?php _e( 'Orders created via API callback', 'klarna-checkout-for-woocommerce' ); ?>:</td>
|
||||
<td class="help"><?php echo wc_help_tip( __( 'Displays the number of orders created via the API callback feature during the last month.', 'klarna-checkout-for-woocommerce' ) ); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$query = new WC_Order_Query( array(
|
||||
'limit' => -1,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'return' => 'ids',
|
||||
'payment_method' => 'kco',
|
||||
'date_created' => '>' . ( time() - MONTH_IN_SECONDS )
|
||||
) );
|
||||
$orders = $query->get_orders();
|
||||
$amont_of_klarna_orders = count( $orders );
|
||||
$amont_of_api_callback_orders = 0;
|
||||
foreach( $orders as $order_id ) {
|
||||
|
||||
if( 'klarna_checkout_backup_order_creation' == get_post_meta( $order_id, '_created_via', true ) ) {
|
||||
$amont_of_api_callback_orders++;
|
||||
}
|
||||
}
|
||||
if( $amont_of_api_callback_orders > 0 ) {
|
||||
$percent_of_orders = round( ($amont_of_api_callback_orders/$amont_of_klarna_orders) * 100 );
|
||||
} else {
|
||||
$percent_of_orders = 0;
|
||||
}
|
||||
if( $percent_of_orders >= 10 ) {
|
||||
$status = 'error';
|
||||
} else {
|
||||
$status = 'yes';
|
||||
}
|
||||
|
||||
echo '<strong><mark class="' . $status . '">' . $percent_of_orders . '% (' . $amont_of_api_callback_orders . ' of ' . $amont_of_klarna_orders . ')</mark></strong> of all orders payed via Klarna Checkout was created via API callback during the last month. This is a fallback order creation feature. You should aim for 0%.';
|
||||
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
/*
|
||||
* Plugin Name: Klarna Checkout for WooCommerce
|
||||
* Plugin URI: https://krokedil.com/klarna/
|
||||
* Description: Klarna Checkout payment gateway for WooCommerce.
|
||||
* Author: Krokedil
|
||||
* Author URI: https://krokedil.com/
|
||||
* Version: 1.5.2
|
||||
* Text Domain: klarna-checkout-for-woocommerce
|
||||
* Domain Path: /languages
|
||||
*
|
||||
* WC requires at least: 3.0
|
||||
* WC tested up to: 3.4.0
|
||||
*
|
||||
* Copyright (c) 2017-2018 Krokedil
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required minimums and constants
|
||||
*/
|
||||
define( 'KCO_WC_VERSION', '1.5.2' );
|
||||
define( 'KCO_WC_MIN_PHP_VER', '5.3.0' );
|
||||
define( 'KCO_WC_MIN_WC_VER', '2.5.0' );
|
||||
define( 'KCO_WC_MAIN_FILE', __FILE__ );
|
||||
define( 'KCO_WC_PLUGIN_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
||||
define( 'KCO_WC_PLUGIN_URL', untrailingslashit( plugin_dir_url( __FILE__ ) ) );
|
||||
define( 'KROKEDIL_LOGGER_GATEWAY', 'kco' );
|
||||
|
||||
if ( ! class_exists( 'Klarna_Checkout_For_WooCommerce' ) ) {
|
||||
/**
|
||||
* Class Klarna_Checkout_For_WooCommerce
|
||||
*/
|
||||
class Klarna_Checkout_For_WooCommerce {
|
||||
|
||||
/**
|
||||
* The reference the *Singleton* instance of this class.
|
||||
*
|
||||
* @var $instance
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Reference to API class.
|
||||
*
|
||||
* @var $api
|
||||
*/
|
||||
public $api;
|
||||
|
||||
/**
|
||||
* Reference to merchant URLs class.
|
||||
*
|
||||
* @var $merchant_urls
|
||||
*/
|
||||
public $merchant_urls;
|
||||
|
||||
/**
|
||||
* Reference to order lines class.
|
||||
*
|
||||
* @var $order_lines
|
||||
*/
|
||||
public $order_lines;
|
||||
|
||||
/**
|
||||
* Reference to credentials class.
|
||||
*
|
||||
* @var $credentials
|
||||
*/
|
||||
public $credentials;
|
||||
|
||||
/**
|
||||
* Reference to logging class.
|
||||
*
|
||||
* @var $log
|
||||
*/
|
||||
public $logger;
|
||||
|
||||
/**
|
||||
* Returns the *Singleton* instance of this class.
|
||||
*
|
||||
* @return self::$instance The *Singleton* instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private clone method to prevent cloning of the instance of the
|
||||
* *Singleton* instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function __clone() {
|
||||
wc_doing_it_wrong( __FUNCTION__, __( 'Nope' ), '1.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Private unserialize method to prevent unserializing of the *Singleton*
|
||||
* instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function __wakeup() {
|
||||
wc_doing_it_wrong( __FUNCTION__, __( 'Nope' ), '1.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notices (array)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $notices = array();
|
||||
|
||||
/**
|
||||
* Protected constructor to prevent creating a new instance of the
|
||||
* *Singleton* via the `new` operator from outside of this class.
|
||||
*/
|
||||
protected function __construct() {
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
|
||||
add_action( 'plugins_loaded', array( $this, 'init' ) );
|
||||
add_action( 'admin_notices', array( $this, 'order_management_check' ) );
|
||||
|
||||
// Add quantity button in woocommerce_order_review() function.
|
||||
add_filter( 'woocommerce_checkout_cart_item_quantity', array( $this, 'add_quantity_field' ), 10, 3 );
|
||||
$KCO_options = get_option( 'woocommerce_kco_settings' );
|
||||
if ( 'yes' === $KCO_options['logging'] ) {
|
||||
define( 'KROKEDIL_LOGGER_ON', true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the plugin after plugins_loaded so environment variables are set.
|
||||
*/
|
||||
public function init() {
|
||||
// Init the gateway itself.
|
||||
$this->init_gateways();
|
||||
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds plugin action links
|
||||
*
|
||||
* @param array $links Plugin action link before filtering.
|
||||
*
|
||||
* @return array Filtered links.
|
||||
*/
|
||||
public function plugin_action_links( $links ) {
|
||||
$setting_link = $this->get_setting_link();
|
||||
$plugin_links = array(
|
||||
'<a href="' . $setting_link . '">' . __( 'Settings', 'klarna-checkout-for-woocommerce' ) . '</a>',
|
||||
'<a href="http://krokedil.se/">' . __( 'Support', 'klarna-checkout-for-woocommerce' ) . '</a>',
|
||||
);
|
||||
|
||||
return array_merge( $plugin_links, $links );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting link.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string Setting link
|
||||
*/
|
||||
public function get_setting_link() {
|
||||
$section_slug = 'kco';
|
||||
|
||||
return admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $section_slug );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show admin notice if Order Management plugin is not active.
|
||||
*/
|
||||
public function order_management_check() {
|
||||
/**
|
||||
* Check if file exists
|
||||
* - yes: check if activated
|
||||
* - yes: all good
|
||||
* - no: show activate button
|
||||
* - no: show install button
|
||||
*/
|
||||
|
||||
$plugin_slug = 'klarna-order-management-for-woocommerce';
|
||||
|
||||
// If plugin file exists.
|
||||
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_slug . '/' . $plugin_slug . '.php' ) ) {
|
||||
// If plugin is not active show Activate button.
|
||||
if ( ! is_plugin_active( $plugin_slug . '/' . $plugin_slug . '.php' ) && current_user_can( 'activate_plugins' ) ) {
|
||||
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||
$plugin = plugins_api( 'plugin_information', array(
|
||||
'slug' => $plugin_slug,
|
||||
) );
|
||||
$plugin = (array) $plugin;
|
||||
$status = install_plugin_install_status( $plugin );
|
||||
$name = wp_kses( $plugin['name'], array() );
|
||||
$url = add_query_arg( array(
|
||||
'_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ),
|
||||
'action' => 'activate',
|
||||
'plugin' => $status['file'],
|
||||
), network_admin_url( 'plugins.php' ) );
|
||||
$description = $name . ' is not active. Please activate it so you can capture, cancel, update and refund Klarna orders.';
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<p>
|
||||
<?php echo esc_html( $description ); ?>
|
||||
<a class="install-now button" data-slug="<?php esc_attr_e( $plugin_slug ); ?>"
|
||||
href="<?php echo esc_url( $url ); ?>"
|
||||
aria-label="Activate <?php esc_attr_e( $name ); ?> now"
|
||||
data-name="<?php esc_attr_e( $name ); ?>"><?php _e( 'Activate Now', 'klarna-checkout-for-woocommerce' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
} else { // If plugin file does not exist, show Install button.
|
||||
if ( current_user_can( 'install_plugins' ) ) {
|
||||
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||
$plugin = plugins_api( 'plugin_information', array(
|
||||
'slug' => $plugin_slug,
|
||||
) );
|
||||
$plugin = (array) $plugin;
|
||||
$status = install_plugin_install_status( $plugin );
|
||||
if ( 'install' === $status['status'] && $status['url'] ) {
|
||||
$name = wp_kses( $plugin['name'], array() );
|
||||
$url = $status['url'];
|
||||
$description = $name . ' is not installed. Please install and activate it so you can capture, cancel, update and refund Klarna orders.';
|
||||
?>
|
||||
<div class="notice notice-warning">
|
||||
<p>
|
||||
<?php echo esc_html( $description ); ?>
|
||||
<a class="install-now button" data-slug="<?php esc_attr_e( $plugin_slug ); ?>"
|
||||
href="<?php echo esc_url( $url ); ?>"
|
||||
aria-label="Install <?php esc_attr_e( $name ); ?> now"
|
||||
data-name="<?php esc_attr_e( $name ); ?>"><?php _e( 'Install Now', 'klarna-checkout-for-woocommerce' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} // End if().
|
||||
}
|
||||
|
||||
/**
|
||||
* Display any notices we've collected thus far (e.g. for connection, disconnection)
|
||||
*/
|
||||
public function admin_notices() {
|
||||
foreach ( (array) $this->notices as $notice_key => $notice ) {
|
||||
echo "<div class='" . esc_attr( $notice['class'] ) . "'><p>";
|
||||
echo wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) );
|
||||
echo '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the gateway. Called very early - in the context of the plugins_loaded action
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function init_gateways() {
|
||||
if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-gateway.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-api.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-api-callbacks.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-templates.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-ajax.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-order-lines.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-merchant-urls.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-credentials.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-logging.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-fields.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-confirmation.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-extra-checkout-fields.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-status.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-create-local-order-fallback.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-gdpr.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/klarna-checkout-for-woocommerce-functions.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/vendor/autoload.php';
|
||||
|
||||
if ( is_admin() ) {
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-klarna-checkout-for-woocommerce-admin-notices.php';
|
||||
include_once KCO_WC_PLUGIN_PATH . '/includes/class-wc-klarna-banners.php';
|
||||
}
|
||||
|
||||
$this->api = new Klarna_Checkout_For_WooCommerce_API();
|
||||
$this->merchant_urls = new Klarna_Checkout_For_WooCommerce_Merchant_URLs();
|
||||
$this->order_lines = new Klarna_Checkout_For_WooCommerce_Order_Lines();
|
||||
$this->credentials = new Klarna_Checkout_For_WooCommerce_Credentials();
|
||||
$this->logger = new Klarna_Checkout_For_WooCommerce_Logging();
|
||||
|
||||
load_plugin_textdomain( 'klarna-checkout-for-woocommerce', false, plugin_basename( __DIR__ ) . '/languages' );
|
||||
add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the gateways to WooCommerce
|
||||
*
|
||||
* @param array $methods Payment methods.
|
||||
*
|
||||
* @return array $methods Payment methods.
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function add_gateways( $methods ) {
|
||||
$methods[] = 'Klarna_Checkout_For_WooCommerce_Gateway';
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters cart item quantity output.
|
||||
*
|
||||
* @param string $output HTML output.
|
||||
* @param array $cart_item Cart item.
|
||||
* @param string $cart_item_key Cart item key.
|
||||
*
|
||||
* @return string $output
|
||||
*/
|
||||
public function add_quantity_field( $output, $cart_item, $cart_item_key ) {
|
||||
if ( 'kco' === WC()->session->get( 'chosen_payment_method' ) ) {
|
||||
foreach ( WC()->cart->get_cart() as $cart_key => $cart_value ) {
|
||||
if ( $cart_key === $cart_item_key ) {
|
||||
$_product = $cart_item['data'];
|
||||
|
||||
if ( $_product->is_sold_individually() ) {
|
||||
$return_value = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_key );
|
||||
} else {
|
||||
$return_value = woocommerce_quantity_input( array(
|
||||
'input_name' => 'cart[' . $cart_key . '][qty]',
|
||||
'input_value' => $cart_item['quantity'],
|
||||
'max_value' => $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(),
|
||||
'min_value' => '1',
|
||||
), $_product, false );
|
||||
}
|
||||
|
||||
$output = $return_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Klarna_Checkout_For_WooCommerce::get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main instance Klarna_Checkout_For_WooCommerce WooCommerce.
|
||||
*
|
||||
* Returns the main instance of Klarna_Checkout_For_WooCommerce.
|
||||
*
|
||||
* @return Klarna_Checkout_For_WooCommerce
|
||||
*/
|
||||
function KCO_WC() {
|
||||
return Klarna_Checkout_For_WooCommerce::get_instance();
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
# Copyright (C) 2018 klarna-checkout-for-woocommerce
|
||||
# This file is distributed under the same license as the klarna-checkout-for-woocommerce package.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: klarna-checkout-for-woocommerce\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language-Team: Krokedil <info@krokedil.se>\n"
|
||||
"Last-Translator: Krokedil <info@krokedil.se>\n"
|
||||
"Report-Msgid-Bugs-To: http://krokedil.se\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-SearchPathExcluded-0: *.js\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-admin-notices.php:77
|
||||
msgid "You need to specify a terms page in WooCommerce Settings to be able to use Klarna Checkout."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-admin-notices.php:92
|
||||
msgid "You need to enable and configure https to be able to use Klarna Checkout."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-ajax.php:278
|
||||
msgid "This order was made as a fallback due to an error in the checkout (%s). Please verify the order with Klarna."
|
||||
msgstr ""
|
||||
|
||||
#. translators: Klarna order ID.
|
||||
#. translators: Klarna order ID.
|
||||
#. translators: Klarna order ID.
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:97, ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:432, ../includes/class-klarna-checkout-for-woocommerce-gateway.php:279
|
||||
msgid "Payment via Klarna Checkout, order ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:100, ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:435, ../includes/class-klarna-checkout-for-woocommerce-gateway.php:282
|
||||
msgid "Klarna Checkout order was rejected."
|
||||
msgstr ""
|
||||
|
||||
#. translators: Klarna order ID.
|
||||
#. translators: Klarna order ID.
|
||||
#. translators: Klarna order ID.
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:103, ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:438, ../includes/class-klarna-checkout-for-woocommerce-gateway.php:285
|
||||
msgid "Klarna order is under review, order ID: %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-api-callbacks.php:451
|
||||
msgid "Order needs manual review, WooCommerce total and Klarna total do not match. Klarna order total: %s."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-confirmation.php:56
|
||||
msgid "Please wait while we process your order."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:19
|
||||
msgid "Enable/Disable"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:20
|
||||
msgid "Enable Klarna Checkout"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:26
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:28
|
||||
msgid "Payment method title."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:33
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:35
|
||||
msgid "Payment method description."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:40
|
||||
msgid "Separate shipping address"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:41
|
||||
msgid "Allow separate shipping address"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:43
|
||||
msgid "If this option is checked, customers will be able to enter shipping address different than their billing address in checkout."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:48
|
||||
msgid "Other payment method button text"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:50
|
||||
msgid "Customize the <em>Select another payment method</em> button text that is displayed in checkout if using other payment methods than Klarna Checkout. Leave blank to use the default (and translatable) text."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:55
|
||||
msgid "Shipping details"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:56
|
||||
msgid "Shipping details note shown to customer"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:58
|
||||
msgid "Will be shown to customer in thank you page."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:63
|
||||
msgid "Allowed Customer Types"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:66
|
||||
msgid "B2C only"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:67
|
||||
msgid "B2B only"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:68
|
||||
msgid "B2C & B2B (defaults to B2C)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:69
|
||||
msgid "B2B & B2C (defaults to B2B)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:71
|
||||
msgid "Select if you want to sell both to consumers and companies or only to one of them (available for SE, NO and FI). Learn more and <a href=\"%s\" target=\"_blank\">sign up for Klarna Checkout B2B here</a>."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:76
|
||||
msgid "Product URLs"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:78
|
||||
msgid "Send product and product image URLs to Klarna"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:83
|
||||
msgid "Logging"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:84
|
||||
msgid "Log debug messages"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:86
|
||||
msgid "Save debug messages to the WooCommerce System Status log."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:91
|
||||
msgid "Test mode"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:92
|
||||
msgid "Enable Test Mode"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:94
|
||||
msgid "Place the payment gateway in test mode using test API keys."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:99
|
||||
msgid "Date of birth mandatory"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:100
|
||||
msgid "Make customer date of birth mandatory"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:102
|
||||
msgid "If checked, the customer cannot skip date of birth. "
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:107
|
||||
msgid "Show terms and conditions"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:108
|
||||
msgid "Select if you want to show terms and conditions on checkout page, and where you want to display them."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:112
|
||||
msgid "Do not display"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:113
|
||||
msgid "Display above checkout"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:114
|
||||
msgid "Display below checkout"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:123, ../includes/class-klarna-checkout-for-woocommerce-fields.php:170
|
||||
msgid "Production Username (UID)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:125, ../includes/class-klarna-checkout-for-woocommerce-fields.php:132, ../includes/class-klarna-checkout-for-woocommerce-fields.php:139, ../includes/class-klarna-checkout-for-woocommerce-fields.php:146
|
||||
msgid "Get your API keys from your Klarna Checkout merchant account for Europe."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:130, ../includes/class-klarna-checkout-for-woocommerce-fields.php:177
|
||||
msgid "Production Password"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:137, ../includes/class-klarna-checkout-for-woocommerce-fields.php:184
|
||||
msgid "Test Username (UID)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:144, ../includes/class-klarna-checkout-for-woocommerce-fields.php:191
|
||||
msgid "Test Password"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:151
|
||||
msgid "Title mandatory (GB)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:152
|
||||
msgid "Make customer title mandatory"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:154
|
||||
msgid "If unchecked, title becomes optional. Only available for orders for country GB."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:159
|
||||
msgid "Show prefill consent notice"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:160
|
||||
msgid "Only applicable for stores based in Germany and Austria"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:172, ../includes/class-klarna-checkout-for-woocommerce-fields.php:179, ../includes/class-klarna-checkout-for-woocommerce-fields.php:186, ../includes/class-klarna-checkout-for-woocommerce-fields.php:193
|
||||
msgid "Get your API keys from your Klarna Checkout merchant account for US."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:199
|
||||
msgid "Color Settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:203
|
||||
msgid "Checkout button color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:205
|
||||
msgid "Checkout page button color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:210
|
||||
msgid "Checkout button text color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:212
|
||||
msgid "Checkout page button text color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:217
|
||||
msgid "Checkout checkbox color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:219
|
||||
msgid "Checkout page checkbox color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:224
|
||||
msgid "Checkout checkbox checkmark color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:226
|
||||
msgid "Checkout page checkbox checkmark color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:231
|
||||
msgid "Checkout header color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:233
|
||||
msgid "Checkout page header color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:238
|
||||
msgid "Checkout link color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:240
|
||||
msgid "Checkout page link color"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:245
|
||||
msgid "Checkout radius border (px)"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-fields.php:247
|
||||
msgid "Checkout page radius border in pixels"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-gateway.php:19, ../includes/klarna-checkout-for-woocommerce-status-report.php:15
|
||||
msgid "Klarna Checkout"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-gateway.php:20
|
||||
msgid "Klarna Checkout replaces standard WooCommerce checkout page."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-gateway.php:324
|
||||
msgid "Order address should not be changed and any changes you make will not be reflected in Klarna system."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-gateway.php:335
|
||||
msgid "An account is already registered with your email address. Please log in."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-gdpr.php:30, ../includes/klarna-checkout-for-woocommerce-functions.php:474
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-order-lines.php:155, ../includes/class-klarna-checkout-for-woocommerce-order-lines.php:156
|
||||
msgid "Sales Tax"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/class-klarna-checkout-for-woocommerce-order-lines.php:504, ../includes/class-klarna-checkout-for-woocommerce-order-lines.php:532
|
||||
msgid "Shipping"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-functions.php:58
|
||||
msgid "Create an account?"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-functions.php:113
|
||||
msgid "Select another payment method"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-functions.php:465
|
||||
msgid "Not all products are in stock."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-functions.php:467
|
||||
msgid "No shipping was selected."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-status-report.php:15
|
||||
msgid "Klarna Checkout System Status."
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-status-report.php:21
|
||||
msgid "Orders created via API callback"
|
||||
msgstr ""
|
||||
|
||||
#: ../includes/klarna-checkout-for-woocommerce-status-report.php:22
|
||||
msgid "Displays the number of orders created via the API callback feature during the last month."
|
||||
msgstr ""
|
||||
|
||||
#: ../klarna-checkout-for-woocommerce.php:170
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../klarna-checkout-for-woocommerce.php:171
|
||||
msgid "Support"
|
||||
msgstr ""
|
||||
|
||||
#: ../klarna-checkout-for-woocommerce.php:228
|
||||
msgid "Activate Now"
|
||||
msgstr ""
|
||||
|
||||
#: ../klarna-checkout-for-woocommerce.php:252
|
||||
msgid "Install Now"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,152 @@
|
||||
=== Klarna Checkout for WooCommerce ===
|
||||
Contributors: klarna, krokedil, automattic
|
||||
Tags: woocommerce, klarna, ecommerce, e-commerce, checkout
|
||||
Donate link: https://klarna.com
|
||||
Requires at least: 4.0
|
||||
Tested up to: 4.9.6
|
||||
Requires PHP: 5.6
|
||||
WC requires at least: 3.0.0
|
||||
WC tested up to: 3.4.0
|
||||
Stable tag: trunk
|
||||
License: GPLv3 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
== DESCRIPTION ==
|
||||
|
||||
*A full checkout experience embedded on your site with Pay Now, Pay Later and Slice It. No credit card numbers, no passwords, no worries.*
|
||||
|
||||
https://www.youtube.com/watch?v=XayUzOUkyDQ
|
||||
|
||||
Our complete checkout is a seamless and mobile optimized solution that delivers a best-in-class user experience that comes with all our payment methods. It also identifies the customer and enables one-click repeat purchases across Klarna’s merchant network, resulting in increased average order value, conversions, and loyalty.
|
||||
|
||||
This official Klarna extension also makes it easy for you to handle orders in WooCommerce after a purchase is complete. With a single click of a button, you can activate, update, refund and cancel orders directly from WooCommerce without logging into the Klarna administration.
|
||||
|
||||
=== Pay Now (direct payments) ===
|
||||
Customers who want to pay in full at checkout can do it quickly and securely with a credit/debit card. Friction-free direct purchases while maximising the value for your business thanks to guaranteed payments. If they have a Klarna account they can save their details and enjoy one-click purchases from then on.
|
||||
|
||||
=== Pay later (invoice) ===
|
||||
Try it first, pay it later. Delayed payments for customers who like low friction purchases and to pay after delivery.
|
||||
|
||||
=== Slice it (installments) ===
|
||||
Installment, revolving and other flexible financing plans let customers pay when they can and when they want.
|
||||
|
||||
=== How to Get Started ===
|
||||
* [Sign up for Klarna](https://www.klarna.com/international/business/woocommerce/).
|
||||
* [Install the plugin](https://wordpress.org/plugins/klarna-checkout-for-woocommerce/) on your site. During this process you will be asked to download [Klarna Order Management](https://wordpress.org/plugins/klarna-order-management-for-woocommerce/) so you can handle orders in Klarna directly from WooCommerce.
|
||||
* Get your store approved by Klarna, and start selling.
|
||||
|
||||
=== What's the difference between Klarna Checkout and Klarna Payments? ===
|
||||
Klarna as your single payment provider keeps everything under one roof. You’ll have one agreement, one point of contact, one settlement file, one payout with __Klarna Checkout__. It only takes a single integration to deliver the full Klarna hosted checkout experience through a widget placed on your site.
|
||||
|
||||
__Klarna Payments__ removes the headaches of payments, for both consumers and merchants. Complement your checkout with a Klarna hosted widget located in your existing checkout which offers payment options for customers with a smooth user experience.
|
||||
|
||||
|
||||
== Installation ==
|
||||
1. Upload plugin folder to to the "/wp-content/plugins/" directory.
|
||||
2. Activate the plugin through the "Plugins" menu in WordPress.
|
||||
3. Go WooCommerce Settings –> Payment Gateways and configure your Klarna Checkout settings.
|
||||
4. Read more about the configuration process in the [plugin documentation](https://docs.woocommerce.com/document/klarna-checkout/).
|
||||
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
= Which countries does this payment gateway support? =
|
||||
Klarna Checkout works for merchants in Sweden, Finland, Norway, Germany, Austria, the Netherlands, UK and United States.
|
||||
|
||||
= Where can I find Klarna Checkout for WooCommerce documentation? =
|
||||
For help setting up and configuring Klarna Payments for WooCommerce please refer to our [documentation](https://docs.woocommerce.com/document/klarna-checkout/).
|
||||
|
||||
= Are there any specific requirements? =
|
||||
* WooCommerce 3.0 or newer is required.
|
||||
* PHP 5.6 or higher is required.
|
||||
* A SSL Certificate is required.
|
||||
* This plugin integrates with Klarnas V3 platform. You need an agreement with Klarna specific to the V3 platform to use this plugin.
|
||||
|
||||
== Changelog ==
|
||||
= 2018.05.29 - version 1.5.2 =
|
||||
* Fix - Fixed error in get_purchase_locale() (caused checkout to be rendered in English even if local lang was used in store).
|
||||
|
||||
= 2018.05.25 - version 1.5.1 =
|
||||
* Fix - Fixed a check on a definition.
|
||||
* Fix - Fixed minor spelling error in privacy policy text.
|
||||
* Fix - Prevent default on customer pressing enter on checkout page to prevent accidental order submit.
|
||||
|
||||
= 2018.05.24 - version 1.5.0 =
|
||||
* Feature - Added support for validation of required WooCommerce checkout fields displayed in kco_wc_show_extra_fields().
|
||||
* Feature - Added support for wp_add_privacy_policy_content (for GDPR compliance). More info: https://core.trac.wordpress.org/attachment/ticket/43473/PRIVACY-POLICY-CONTENT-HOOK.md.
|
||||
* Feature - Added setting for displaying privacy policy checkout text (above or below KCO iframe).
|
||||
* Feature - Possibility to add terms checkbox inside KCO iframe via plugin settings (GDPR compliance for some companies).
|
||||
* Tweak - Changed what we base purchase locale on. Adds better support for WPML compatibility.
|
||||
* Tweak - Added support for handling cart with virtual products in validation callback (check if order needs shipping).
|
||||
* Tweak - Added Klarna icon next to payment method title in regular checkout page.
|
||||
* Fix - Fixed issue in validation callback logic (where purchase could be finalized without a valid shipping method).
|
||||
|
||||
= 2018.04.27 - version 1.4.0 =
|
||||
* Feature - Added facllback order creation if checkout form submission fails.
|
||||
* Tweak - Acknowledge Klarna order and set WC order to Processing in thankyou page if possible.
|
||||
* Tweak - Improved UI in settings page.
|
||||
* Tweak - Improved logging.
|
||||
* Tweak - Added error handling in 405 response from Klarna.
|
||||
* Tweak - Updated Krokedil logger.
|
||||
* Tweak - Change standard log event type to INFO (previously ERROR).
|
||||
* Tweak - Function for hiding Klarna banner (displayed when in test mode).
|
||||
* Tweak - Added PHP version to user agent sent in orders to Klarna.
|
||||
|
||||
= 2018.03.29 - version 1.3.0 =
|
||||
* Update - Adds Krokedil logger class.
|
||||
* Update - Adds status report on Woocommerce status page.
|
||||
* Enhancement - Adds verify_national_identification_number alongside with national_identification_number_mandatory setting in order data sent to Klarna.
|
||||
* Enhancement - Improved order note for orders created via API callback.
|
||||
* Enhancement - Improved messaging in order note when order totals doesn’t match.
|
||||
* Enhancement - Display admin notice if https isn’t enabled.
|
||||
* Fix - Spelling fix in banner.
|
||||
|
||||
= 2018.03.14 - version 1.2.6 =
|
||||
* Fix - Fixes how product name is fetched for Klarna.
|
||||
* Update - Adds new mandatory PNO field.
|
||||
* Update - Adds dashboard banners and Klarna information.
|
||||
* Update - Adds exception error code to logger, in addition to error message.
|
||||
* Update - Changes CSS selector from table to generic class for cart widget.
|
||||
|
||||
= 2018.02.26 - version 1.2.5 =
|
||||
* Feature - Allows Klarna Checkout to be overwritten from the theme.
|
||||
* Fix - Keeps extra checkout fields values on checkout page reload.
|
||||
* Enhancement - Cleans up template files.
|
||||
* Enhancement - Adds WC required and tested up to data to main plugin file.
|
||||
* Enhancement - Allows English locale for non-english countries.
|
||||
* Dev - Adds Gulp task for .pot file processing.
|
||||
|
||||
= 2018.01.31 - version 1.2.4 =
|
||||
* Fix - Fixes backup order creation process to check for product SKU.
|
||||
* Enhancement - Adds admin notice if Terms URL is not set in WooCommerce settings.
|
||||
|
||||
= 2018.01.29 - version 1.2.3 =
|
||||
* Fix - Cleans up translation strings.
|
||||
* Enhancement - Adds woocommerce_enable_order_notes_field to KCO checkout template.
|
||||
|
||||
= 2018.01.26 - version 1.2.2 =
|
||||
* Fix - Removes email check on validation CB.
|
||||
* Enhancement - Cleans up template files.
|
||||
|
||||
= 2018.01.25 - version 1.2.1 =
|
||||
* Tweak - Saves KCO as payment method for orders with total equals zero.
|
||||
* Tweak - Checks if email already exists when guest checkout is disabled and forces users to log in before checking out.
|
||||
* Fix - Fixes empty JSON AJAX response.
|
||||
* Enhancement - Improves order query to only retrieve IDs.
|
||||
|
||||
= 2018.01.22 - version 1.2 =
|
||||
* Tweak - Switches to using store base country as purchase country in all cases.
|
||||
* Tweak - Switches from using 'change' to 'shipping_address_change' for storing customer data.
|
||||
* Fix - Prevents Klarna Checkout order update after iframe has been submitted.
|
||||
|
||||
= 2018.01.11 - version 1.1.1 =
|
||||
* Tweak - Makes datepicker extra field work in checkout.
|
||||
* Fix - Acknowledge order & set merchant reference in Klarnas system during backup order creation (on push notification).
|
||||
* Fix - Fixes storing WC_Customer postal code.
|
||||
|
||||
= 2017.12.20 - version 1.1 =
|
||||
* Tweak - Allows external payment method plugin to work.
|
||||
* Tweak - Adds border-box to floated elements in KCO page.
|
||||
* Fix - Adds 3-letter to 2-letter country code translation.
|
||||
|
||||
= 1.0 =
|
||||
* Initial release.
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/**
|
||||
* Klarna Checkout fallback order received page, used when WC checkout form submission fails.
|
||||
*
|
||||
* Overrides /checkout/thankyou.php.
|
||||
*
|
||||
* @package klarna-checkout-for-woocommerce
|
||||
*/
|
||||
|
||||
if ( ! WC()->session->get( 'kco_wc_order_id' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wc_empty_cart();
|
||||
kco_wc_show_snippet();
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Klarna Checkout page
|
||||
*
|
||||
* Overrides /checkout/form-checkout.php.
|
||||
*
|
||||
* @package klarna-checkout-for-woocommerce
|
||||
*/
|
||||
wc_print_notices();
|
||||
|
||||
do_action( 'kco_wc_before_checkout_form' );
|
||||
?>
|
||||
|
||||
<form name="checkout" class="checkout woocommerce-checkout">
|
||||
<div id="kco-wrapper">
|
||||
<div id="kco-order-review">
|
||||
<?php do_action( 'kco_wc_before_order_review' ); ?>
|
||||
<?php woocommerce_order_review(); ?>
|
||||
<?php do_action( 'kco_wc_after_order_review' ); ?>
|
||||
</div>
|
||||
|
||||
<div id="kco-iframe">
|
||||
<?php do_action( 'kco_wc_before_snippet' ); ?>
|
||||
<?php kco_wc_show_snippet(); ?>
|
||||
<?php do_action( 'kco_wc_after_snippet' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php do_action( 'kco_wc_after_checkout_form' ); ?>
|
||||
7
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit03353625f04afb51760eeb064c3f6a02::getLoader();
|
||||
445
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
private $classMapAuthoritative = false;
|
||||
private $missingClasses = array();
|
||||
private $apcuPrefix;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath.'\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
21
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
10
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/autoload_files.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'cad43f73916476d83565191d54c1f14b' => $vendorDir . '/krokedil/krokedil-logger/src/krokedil-order-event-log.php',
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
9
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
70
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit03353625f04afb51760eeb064c3f6a02
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit03353625f04afb51760eeb064c3f6a02', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit03353625f04afb51760eeb064c3f6a02', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit03353625f04afb51760eeb064c3f6a02::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit03353625f04afb51760eeb064c3f6a02::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire03353625f04afb51760eeb064c3f6a02($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire03353625f04afb51760eeb064c3f6a02($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
19
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit03353625f04afb51760eeb064c3f6a02
|
||||
{
|
||||
public static $files = array (
|
||||
'cad43f73916476d83565191d54c1f14b' => __DIR__ . '/..' . '/krokedil/krokedil-logger/src/krokedil-order-event-log.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
48
backend/wp-content/plugins/klarna-checkout-for-woocommerce/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
[
|
||||
{
|
||||
"name": "krokedil/krokedil-logger",
|
||||
"version": "1.0.6",
|
||||
"version_normalized": "1.0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/krokedil/krokedil-logger.git",
|
||||
"reference": "68fca237f3d53720d223373827531488d5ef7b21"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/krokedil/krokedil-logger/zipball/68fca237f3d53720d223373827531488d5ef7b21",
|
||||
"reference": "68fca237f3d53720d223373827531488d5ef7b21",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"time": "2018-03-29T13:59:58+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/krokedil-order-event-log.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Krokedil",
|
||||
"email": "info@krokedil.se",
|
||||
"homepage": "https://www.krokedil.se",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Logging for WooCommerce Gateways",
|
||||
"homepage": "https://www.krokedil.se",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
"woocommerce"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,52 @@
|
||||
# krokedil-logger
|
||||
## Installation
|
||||
Install with [Composer](getcomposer.org).
|
||||
|
||||
Add these lines to your composer.json:
|
||||
```
|
||||
{
|
||||
"require": {
|
||||
"krokedil/krokedil-logger": "^1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
### Log event
|
||||
Use the function **krokedil_log_events**.
|
||||
```
|
||||
Example: krokedil_log_events( $order_id, $title, $data );
|
||||
```
|
||||
$order_id = The WooCommerce order id. Can be sent as null if you want to log events before an order exists.
|
||||
|
||||
$title = The title that you wish to have for the event.
|
||||
|
||||
$data = An **array** of the data that you want to log.
|
||||
|
||||
### Set the version used for order
|
||||
|
||||
Use the function **krokedil_set_order_gateway_version**.
|
||||
```
|
||||
Example: krokedil_set_order_gateway_version( $order_id, $version );
|
||||
```
|
||||
$order_id = The WooCommerce order id.
|
||||
|
||||
$version = The version that you want to log for the order.
|
||||
|
||||
Use this function at a point where an order exists, for example thank you page or process_order.
|
||||
|
||||
### Set display on/off
|
||||
To switch between showing and not showing the logs on the order add a define for **KROKEDIL_LOGGER_ON** to turn it on.
|
||||
```
|
||||
Example: define( 'KROKEDIL_LOGGER_ON', true );
|
||||
```
|
||||
|
||||
### Set gateway filter
|
||||
You need to set what gateway the meta box should be allowed for. Do this using the define **KROKEDIL_LOGGER_GATEWAY**.
|
||||
```
|
||||
Example: define( 'KROKEDIL_LOGGER_GATEWAY', '$string' );
|
||||
```
|
||||
$string = A string or substring of the gateway id.
|
||||
|
||||
### Recognition
|
||||
This plugin uses the renderjson JavaScript created by GitHub user [Caldwell](https://github.com/caldwell/). It can be found here: [RenderJSON](https://github.com/caldwell/renderjson).
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "krokedil/krokedil-logger",
|
||||
"type": "library",
|
||||
"description": "Logging for WooCommerce Gateways",
|
||||
"keywords": ["log","logging", "woocommerce"],
|
||||
"homepage": "https://www.krokedil.se",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Krokedil",
|
||||
"email": "info@krokedil.se",
|
||||
"homepage": "https://www.krokedil.se",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"autoload": {
|
||||
"files": ["src/krokedil-order-event-log.php"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
.krokedil_event {
|
||||
margin:5px;
|
||||
background-color:#f9f9f9;
|
||||
overflow-x:auto;
|
||||
}
|
||||
.krokedil_event_header * {
|
||||
display:inline-block;
|
||||
margin:5px;
|
||||
}
|
||||
.krokedil_event_header {
|
||||
padding:5px;
|
||||
background-color:#f1f1f1;
|
||||
}
|
||||
.krokedil_event_header h5 {
|
||||
float:right;
|
||||
}
|
||||
.krokedil_hidden {
|
||||
display:none;
|
||||
}
|
||||
.krokedil_shown{
|
||||
clear:both;
|
||||
display:block;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
jQuery( function( $ ) {
|
||||
var krokedil_event_log = {
|
||||
renderJson: function() {
|
||||
$(".krokedil_json").each(function(){
|
||||
var string = $( this ).html();
|
||||
var json = JSON.parse( string );
|
||||
renderjson;
|
||||
$( this ).html( renderjson.set_show_to_level( '2' )( json ) )
|
||||
});
|
||||
},
|
||||
toggleJson: function( event_nr ){
|
||||
console.log( 'in function');
|
||||
var event_id = '#krokedil_event_nr_' + event_nr;
|
||||
console.log( event_id );
|
||||
if( $( event_id ).hasClass( 'krokedil_hidden' ) ) {
|
||||
$( event_id ).removeClass( 'krokedil_hidden' );
|
||||
$( event_id ).addClass( 'krokedil_shown' );
|
||||
} else {
|
||||
$( event_id ).removeClass( 'krokedil_shown' );
|
||||
$( event_id ).addClass( 'krokedil_hidden' );
|
||||
}
|
||||
}
|
||||
}
|
||||
$( document ).ready(function() {
|
||||
krokedil_event_log.renderJson();
|
||||
});
|
||||
$('body').on('click', '.krokedil_timestamp', function() {
|
||||
console.log( 'click' );
|
||||
var event_nr = $(this).data('event-nr');
|
||||
console.log(event_nr)
|
||||
console.log($(this));
|
||||
krokedil_event_log.toggleJson( event_nr );
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,208 @@
|
||||
// Copyright © 2013-2017 David Caldwell <david@porkrind.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// Usage
|
||||
// -----
|
||||
// The module exports one entry point, the `renderjson()` function. It takes in
|
||||
// the JSON you want to render as a single argument and returns an HTML
|
||||
// element.
|
||||
//
|
||||
// Options
|
||||
// -------
|
||||
// renderjson.set_icons("+", "-")
|
||||
// This Allows you to override the disclosure icons.
|
||||
//
|
||||
// renderjson.set_show_to_level(level)
|
||||
// Pass the number of levels to expand when rendering. The default is 0, which
|
||||
// starts with everything collapsed. As a special case, if level is the string
|
||||
// "all" then it will start with everything expanded.
|
||||
//
|
||||
// renderjson.set_max_string_length(length)
|
||||
// Strings will be truncated and made expandable if they are longer than
|
||||
// `length`. As a special case, if `length` is the string "none" then
|
||||
// there will be no truncation. The default is "none".
|
||||
//
|
||||
// renderjson.set_sort_objects(sort_bool)
|
||||
// Sort objects by key (default: false)
|
||||
//
|
||||
// renderjson.set_replacer(replacer_function)
|
||||
// Equivalent of JSON.stringify() `replacer` argument when it's a function
|
||||
//
|
||||
// renderjson.set_property_list(property_list)
|
||||
// Equivalent of JSON.stringify() `replacer` argument when it's an array
|
||||
//
|
||||
// Theming
|
||||
// -------
|
||||
// The HTML output uses a number of classes so that you can theme it the way
|
||||
// you'd like:
|
||||
// .disclosure ("⊕", "⊖")
|
||||
// .syntax (",", ":", "{", "}", "[", "]")
|
||||
// .string (includes quotes)
|
||||
// .number
|
||||
// .boolean
|
||||
// .key (object key)
|
||||
// .keyword ("null", "undefined")
|
||||
// .object.syntax ("{", "}")
|
||||
// .array.syntax ("[", "]")
|
||||
|
||||
var module, window, define, renderjson=(function() {
|
||||
var themetext = function(/* [class, text]+ */) {
|
||||
var spans = [];
|
||||
while (arguments.length)
|
||||
spans.push(append(span(Array.prototype.shift.call(arguments)),
|
||||
text(Array.prototype.shift.call(arguments))));
|
||||
return spans;
|
||||
};
|
||||
var append = function(/* el, ... */) {
|
||||
var el = Array.prototype.shift.call(arguments);
|
||||
for (var a=0; a<arguments.length; a++)
|
||||
if (arguments[a].constructor == Array)
|
||||
append.apply(this, [el].concat(arguments[a]));
|
||||
else
|
||||
el.appendChild(arguments[a]);
|
||||
return el;
|
||||
};
|
||||
var prepend = function(el, child) {
|
||||
el.insertBefore(child, el.firstChild);
|
||||
return el;
|
||||
}
|
||||
var isempty = function(obj, pl) { var keys = pl || Object.keys(obj);
|
||||
for (var i in keys) if (Object.hasOwnProperty.call(obj, keys[i])) return false;
|
||||
return true; }
|
||||
var text = function(txt) { return document.createTextNode(txt) };
|
||||
var div = function() { return document.createElement("div") };
|
||||
var span = function(classname) { var s = document.createElement("span");
|
||||
if (classname) s.className = classname;
|
||||
return s; };
|
||||
var A = function A(txt, classname, callback) { var a = document.createElement("a");
|
||||
if (classname) a.className = classname;
|
||||
a.appendChild(text(txt));
|
||||
a.href = '#';
|
||||
a.onclick = function(e) { callback(); if (e) e.stopPropagation(); return false; };
|
||||
return a; };
|
||||
|
||||
function _renderjson(json, indent, dont_indent, show_level, options) {
|
||||
var my_indent = dont_indent ? "" : indent;
|
||||
|
||||
var disclosure = function(open, placeholder, close, type, builder) {
|
||||
var content;
|
||||
var empty = span(type);
|
||||
var show = function() { if (!content) append(empty.parentNode,
|
||||
content = prepend(builder(),
|
||||
A(options.hide, "disclosure",
|
||||
function() { content.style.display="none";
|
||||
empty.style.display="inline"; } )));
|
||||
content.style.display="inline";
|
||||
empty.style.display="none"; };
|
||||
append(empty,
|
||||
A(options.show, "disclosure", show),
|
||||
themetext(type+ " syntax", open),
|
||||
A(placeholder, null, show),
|
||||
themetext(type+ " syntax", close));
|
||||
|
||||
var el = append(span(), text(my_indent.slice(0,-1)), empty);
|
||||
if (show_level > 0 && type != "string")
|
||||
show();
|
||||
return el;
|
||||
};
|
||||
|
||||
if (json === null) return themetext(null, my_indent, "keyword", "null");
|
||||
if (json === void 0) return themetext(null, my_indent, "keyword", "undefined");
|
||||
|
||||
if (typeof(json) == "string" && json.length > options.max_string_length)
|
||||
return disclosure('"', json.substr(0,options.max_string_length)+" ...", '"', "string", function () {
|
||||
return append(span("string"), themetext(null, my_indent, "string", JSON.stringify(json)));
|
||||
});
|
||||
|
||||
if (typeof(json) != "object" || [Number, String, Boolean, Date].indexOf(json.constructor) >= 0) // Strings, numbers and bools
|
||||
return themetext(null, my_indent, typeof(json), JSON.stringify(json));
|
||||
|
||||
if (json.constructor == Array) {
|
||||
if (json.length == 0) return themetext(null, my_indent, "array syntax", "[]");
|
||||
|
||||
return disclosure("[", " ... ", "]", "array", function () {
|
||||
var as = append(span("array"), themetext("array syntax", "[", null, "\n"));
|
||||
for (var i=0; i<json.length; i++)
|
||||
append(as,
|
||||
_renderjson(options.replacer.call(json, i, json[i]), indent+" ", false, show_level-1, options),
|
||||
i != json.length-1 ? themetext("syntax", ",") : [],
|
||||
text("\n"));
|
||||
append(as, themetext(null, indent, "array syntax", "]"));
|
||||
return as;
|
||||
});
|
||||
}
|
||||
|
||||
// object
|
||||
if (isempty(json, options.property_list))
|
||||
return themetext(null, my_indent, "object syntax", "{}");
|
||||
|
||||
return disclosure("{", "...", "}", "object", function () {
|
||||
var os = append(span("object"), themetext("object syntax", "{", null, "\n"));
|
||||
for (var k in json) var last = k;
|
||||
var keys = options.property_list || Object.keys(json);
|
||||
if (options.sort_objects)
|
||||
keys = keys.sort();
|
||||
for (var i in keys) {
|
||||
var k = keys[i];
|
||||
if (!(k in json)) continue;
|
||||
append(os, themetext(null, indent+" ", "key", '"'+k+'"', "object syntax", ': '),
|
||||
_renderjson(options.replacer.call(json, k, json[k]), indent+" ", true, show_level-1, options),
|
||||
k != last ? themetext("syntax", ",") : [],
|
||||
text("\n"));
|
||||
}
|
||||
append(os, themetext(null, indent, "object syntax", "}"));
|
||||
return os;
|
||||
});
|
||||
}
|
||||
|
||||
var renderjson = function renderjson(json)
|
||||
{
|
||||
var options = Object.assign({}, renderjson.options);
|
||||
options.replacer = typeof(options.replacer) == "function" ? options.replacer : function(k,v) { return v; };
|
||||
var pre = append(document.createElement("pre"), _renderjson(json, "", false, options.show_to_level, options));
|
||||
pre.className = "renderjson";
|
||||
return pre;
|
||||
}
|
||||
renderjson.set_icons = function(show, hide) { renderjson.options.show = show;
|
||||
renderjson.options.hide = hide;
|
||||
return renderjson; };
|
||||
renderjson.set_show_to_level = function(level) { renderjson.options.show_to_level = typeof level == "string" &&
|
||||
level.toLowerCase() === "all" ? Number.MAX_VALUE
|
||||
: level;
|
||||
return renderjson; };
|
||||
renderjson.set_max_string_length = function(length) { renderjson.options.max_string_length = typeof length == "string" &&
|
||||
length.toLowerCase() === "none" ? Number.MAX_VALUE
|
||||
: length;
|
||||
return renderjson; };
|
||||
renderjson.set_sort_objects = function(sort_bool) { renderjson.options.sort_objects = sort_bool;
|
||||
return renderjson; };
|
||||
renderjson.set_replacer = function(replacer) { renderjson.options.replacer = replacer;
|
||||
return renderjson; };
|
||||
renderjson.set_property_list = function(prop_list) { renderjson.options.property_list = prop_list;
|
||||
return renderjson; };
|
||||
// Backwards compatiblity. Use set_show_to_level() for new code.
|
||||
renderjson.set_show_by_default = function(show) { renderjson.options.show_to_level = show ? Number.MAX_VALUE : 0;
|
||||
return renderjson; };
|
||||
renderjson.options = {};
|
||||
renderjson.set_icons('⊕', '⊖');
|
||||
renderjson.set_show_by_default(false);
|
||||
renderjson.set_sort_objects(false);
|
||||
renderjson.set_max_string_length("none");
|
||||
renderjson.set_replacer(void 0);
|
||||
renderjson.set_property_list(void 0);
|
||||
return renderjson;
|
||||
})();
|
||||
|
||||
if (define) define({renderjson:renderjson})
|
||||
else (module||{}).exports = (window||{}).renderjson = renderjson;
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
if( ! function_exists( 'krokedil_log_events' ) ) {
|
||||
define( 'KROKEDIL_LOGGER_VERSION', '1.0.4' );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', 'krokedi_load_admin_scripts' );
|
||||
if ( defined( 'KROKEDIL_LOGGER_ON' ) ) {
|
||||
add_action( 'add_meta_boxes', 'krokedil_meta_box' );
|
||||
}
|
||||
add_action( 'woocommerce_new_order', 'krokedil_add_sessions_to_events', 10, 1 );
|
||||
|
||||
function krokedi_load_admin_scripts() {
|
||||
wp_register_script(
|
||||
'krokedil_event_log',
|
||||
plugins_url( 'assets/js/krokedil-event-log.js', __FILE__ ),
|
||||
array( 'jquery' ),
|
||||
KROKEDIL_LOGGER_VERSION
|
||||
);
|
||||
|
||||
$params = array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
);
|
||||
|
||||
wp_localize_script( 'krokedil_event_log', 'krokedil_event_log_params', $params );
|
||||
|
||||
wp_enqueue_script( 'krokedil_event_log' );
|
||||
|
||||
wp_register_script(
|
||||
'render_json',
|
||||
plugins_url( 'assets/js/renderjson.js', __FILE__ ),
|
||||
array( 'jquery' ),
|
||||
KROKEDIL_LOGGER_VERSION
|
||||
);
|
||||
|
||||
$params = array();
|
||||
|
||||
wp_localize_script( 'render_json', 'render_json_params', $params );
|
||||
|
||||
wp_enqueue_script( 'render_json' );
|
||||
|
||||
wp_register_style(
|
||||
'krokedil_events_style',
|
||||
plugin_dir_url( __FILE__ ) . 'assets/css/krokedil-event-log.css',
|
||||
array(),
|
||||
KROKEDIL_LOGGER_VERSION
|
||||
);
|
||||
wp_enqueue_style( 'krokedil_events_style' );
|
||||
}
|
||||
|
||||
function krokedil_log_events( $order_id, $title, $data ) {
|
||||
if ( WC()->session ) {
|
||||
if ( null === $order_id ) {
|
||||
if ( WC()->session->get( '_krokedil_events_session' ) ) {
|
||||
$events = WC()->session->get( '_krokedil_events_session' );
|
||||
} else {
|
||||
$events = array();
|
||||
}
|
||||
$event = array(
|
||||
'title' => $title,
|
||||
'data' => $data,
|
||||
'timestamp' => current_time( 'Y-m-d H:i:s' )
|
||||
);
|
||||
$events[] = $event;
|
||||
WC()->session->set( '_krokedil_events_session', $events );
|
||||
} else {
|
||||
if ( get_post_meta( $order_id, '_krokedil_order_events' ) ) {
|
||||
$events = get_post_meta( $order_id, '_krokedil_order_events', true );
|
||||
} else {
|
||||
$events = array();
|
||||
}
|
||||
|
||||
$event = array(
|
||||
'title' => $title,
|
||||
'data' => $data,
|
||||
'timestamp' => current_time( 'Y-m-d H:i:s' )
|
||||
);
|
||||
|
||||
$events[] = $event;
|
||||
update_post_meta( $order_id, '_krokedil_order_events', $events );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function krokedil_log_response( $order_id, $response ) {
|
||||
if ( WC()->session ) {
|
||||
if ( null === $order_id ) {
|
||||
$events = WC()->session->get( '_krokedil_events_session' );
|
||||
end( $events );
|
||||
$event = key( $events );
|
||||
$events[ $event ]['response'] = $response;
|
||||
WC()->session->set( '_krokedil_events_session', $events );
|
||||
} else {
|
||||
$events = get_post_meta( $order_id, '_krokedil_order_events', true );
|
||||
end( $events );
|
||||
$event = key( $events );
|
||||
$events[ $event ]['response'] = $response;
|
||||
update_post_meta( $order_id, '_krokedil_order_events', $events );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function krokedil_add_sessions_to_events( $order_id ) {
|
||||
if ( WC()->session ) {
|
||||
if ( WC()->session->get( '_krokedil_events_session' ) ) {
|
||||
$session_events = WC()->session->get( '_krokedil_events_session' );
|
||||
update_post_meta( $order_id, '_krokedil_order_events', $session_events );
|
||||
WC()->session->__unset( '_krokedil_events_session' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function krokedil_get_events() {
|
||||
return get_post_meta( get_the_ID(), '_krokedil_order_events', true );
|
||||
}
|
||||
|
||||
function krokedil_meta_box( $post_type ) {
|
||||
if ( 'shop_order' === $post_type ) {
|
||||
$order_id = get_the_ID();
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( false !== strpos( $order->get_payment_method(), KROKEDIL_LOGGER_GATEWAY ) ) {
|
||||
if ( get_post_meta( $order_id, '_krokedil_order_events' ) ) {
|
||||
add_meta_box( 'krokedil_order_events', __( 'Events', 'krokedil-for-woocommerce' ), 'krokedil_meta_contents', 'shop_order', 'normal', 'core' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function krokedil_set_order_gateway_version( $order_id, $version ) {
|
||||
update_post_meta( $order_id, '_krokedil_order_gateway_version', $version );
|
||||
}
|
||||
|
||||
function krokedil_get_order_version() {
|
||||
$order_id = get_the_ID();
|
||||
|
||||
return get_post_meta( $order_id, '_krokedil_order_gateway_version', true );
|
||||
}
|
||||
|
||||
function krokedil_meta_contents() {
|
||||
$events = krokedil_get_events();
|
||||
$i = 0;
|
||||
foreach ( $events as $event ) {
|
||||
$i += 1;
|
||||
echo '<div class="krokedil_event">';
|
||||
echo '<div class="krokedil_event_header">';
|
||||
echo '<h4>' . $event['title'] . '</h4>';
|
||||
echo '<h5 class="krokedil_timestamp" data-event-nr="' . $i . '"><a href="#krokedil_event_nr_' . $i . '">Time: ' . $event['timestamp'] . '</a></h5>';
|
||||
echo '</div>';
|
||||
echo '<div class="krokedil_json krokedil_hidden" id="krokedil_event_nr_' . $i . '">' . json_encode( $event['data'] ) . '</div>';
|
||||
echo '</div>';
|
||||
}
|
||||
echo '<small>Version of plugin used for order: ' . krokedil_get_order_version() . '</small>';
|
||||
}
|
||||
}
|
||||