diff --git a/assets/css/style.css b/assets/css/style.css deleted file mode 100755 index e6b7932c..00000000 --- a/assets/css/style.css +++ /dev/null @@ -1,7 +0,0 @@ -.reepay-logos { - display: table-cell; } - -.reepay-logo { - float: left; - display: inline-block; - padding: 5px; } diff --git a/assets/css/style.min.css b/assets/css/style.min.css index d7afdaca..b5ea5eb7 100755 --- a/assets/css/style.min.css +++ b/assets/css/style.min.css @@ -1,2 +1 @@ -.reepay-logos{display:table-cell}.reepay-logo{float:left;display:inline-block;padding:5px} -/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FDQyxRQUFTLFdBRVYsYUFDQyxNQUFPLEtBQ1AsUUFBUyxhQUNULFFBQVMiLCJmaWxlIjoic3R5bGUubWluLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5yZWVwYXktbG9nb3Mge1xuXHRkaXNwbGF5OiB0YWJsZS1jZWxsO1xufVxuLnJlZXBheS1sb2dvIHtcblx0ZmxvYXQ6IGxlZnQ7XG5cdGRpc3BsYXk6IGlubGluZS1ibG9jaztcblx0cGFkZGluZzogNXB4O1xufVxuIl19 */ +.reepay-logos{display:table-cell}.reepay-logo{float:left;display:inline-block;padding:5px}.reepay-admin-section-li-header{width:100%;font-weight:700}.reepay-admin-section-li-header-small{width:100%;font-weight:700;font-size:small;margin-bottom:0}.reepay-admin-section-li{width:100%}.reepay-admin-section-li-small{width:100%;font-size:small;margin-top:0}.reepay-full-width,.reepay-full-width .button{width:100%;display:block;text-align:center;clear:both}.reepay-balance{margin-bottom:0}.reepay-balance.last{margin-bottom:5px}.reepay-balance:after{clear:both;content:"";display:table}.reepay-balance__amount,.reepay-balance__label{background-color:#f9f9f9;box-sizing:border-box;float:left;padding:7px 10px;text-transform:uppercase;font-size:10px;color:#8a8a8a}.reepay-balance__label{font-weight:700;width:60%;border-right:2.5px solid #fff}.reepay-balance__amount{border-right:0;width:40%;border-left:2.5px solid #fff;display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.reepay-balance__currency{margin-right:10px}.reepay-balance.last .reepay-balance__currency{margin-right:0}.reepay-admin-card-logo{text-align:center;margin-right:25px;max-width:100px}.reepay-partly_capture_amount{background-color:#f9f9f9;box-sizing:border-box;float:left;padding:4px 10px;text-transform:uppercase;font-size:10px;color:#8a8a8a;border-right:0;width:40%;border-left:2.5px solid #fff;display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.reepay-capture_partly_amount-field{font-size:small;max-height:20px;min-height:1px!important;text-align:center} \ No newline at end of file diff --git a/assets/css/style.scss b/assets/css/style.scss index 7d1c27e3..0dfdb463 100755 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -1,8 +1,115 @@ .reepay-logos { - display: table-cell; -} + display: table-cell; } + .reepay-logo { + float: left; + display: inline-block; + padding: 5px; } + +.reepay-admin-section-li-header { + width: 100%; + font-weight: bold; +} + +.reepay-admin-section-li-header-small { + width: 100%; + font-weight: bold; + font-size: small; + margin-bottom: 0px; +} + +.reepay-admin-section-li { + width: 100%; +} + +.reepay-admin-section-li-small { + width: 100%; + font-size: small; + margin-top: 0px; +} + +.reepay-full-width, .reepay-full-width .button { + width: 100%; + display: block; + text-align: center; + clear: both; +} + +.reepay-balance { + margin-bottom: 0; +} + +.reepay-balance.last { + margin-bottom: 5px; +} + +.reepay-balance:after { + clear: both; + content: ""; + display: table; +} + +.reepay-balance__label, +.reepay-balance__amount { + background-color: #f9f9f9; + box-sizing: border-box; + float: left; + padding: 7px 10px; + text-transform: uppercase; + font-size: 10px; + color: #8a8a8a; +} + +.reepay-balance__label { + font-weight: bold; + width: 60%; + border-right: 2.5px solid #FFF; +} +.reepay-balance__amount { + border-right: 0; + width: 40%; + border-left: 2.5px solid #FFF; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.reepay-balance__currency { + margin-right: 10px; +} + +.reepay-balance.last .reepay-balance__currency { + margin-right: 0; +} + +.reepay-admin-card-logo { + text-align: center; + margin-right: 25px; + max-width: 100px; +} + +.reepay-partly_capture_amount { + background-color: #f9f9f9; + box-sizing: border-box; float: left; - display: inline-block; - padding: 5px; + padding: 4px 10px; + text-transform: uppercase; + font-size: 10px; + color: #8a8a8a; + + border-right: 0; + width: 40%; + border-left: 2.5px solid #FFF; + display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6, BB7 */ + display: -ms-flexbox; /* TWEENER - IE 10 */ + display: -webkit-flex; /* NEW - Safari 6.1+. iOS 7.1+, BB10 */ + display: flex; /* NEW, Spec - Firefox, Chrome, Opera */ } + +.reepay-capture_partly_amount-field { + font-size: small; + max-height: 20px; + min-height: 1px !important; + text-align: center; +} \ No newline at end of file diff --git a/assets/images/cup.png b/assets/images/cup.png new file mode 100644 index 00000000..fd3b4c5a Binary files /dev/null and b/assets/images/cup.png differ diff --git a/assets/images/paypal.png b/assets/images/paypal.png new file mode 100644 index 00000000..3b60c4d4 Binary files /dev/null and b/assets/images/paypal.png differ diff --git a/assets/images/resurs.png b/assets/images/resurs.png new file mode 100644 index 00000000..6da3b2c1 Binary files /dev/null and b/assets/images/resurs.png differ diff --git a/assets/js/admin.js b/assets/js/admin.js index 2ca8e428..a8ebabd2 100755 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -1,10 +1,10 @@ jQuery(document).ready(function ($) { $(document).on('click', '#reepay_capture', function (e) { e.preventDefault(); - var nonce = $(this).data('nonce'); var order_id = $(this).data('order-id'); var self = $(this); + $.ajax({ url : Reepay_Admin.ajax_url, type : 'POST', @@ -22,7 +22,6 @@ jQuery(document).ready(function ($) { self.html(self.data('text')); self.prop('disabled', false); if (!response.success) { - alert(response.data); return false; } @@ -62,4 +61,124 @@ jQuery(document).ready(function ($) { } }); }); + + $(document).on('click', '#reepay_refund', function (e) { + e.preventDefault(); + var nonce = $(this).data('nonce'); + var order_id = $(this).data('order-id'); + var amount = $(this).data('amount'); + var self = $(this); + $.ajax({ + url : Reepay_Admin.ajax_url, + type : 'POST', + data : { + action : 'reepay_refund', + nonce : nonce, + order_id : order_id, + amount : amount + }, + beforeSend: function () { + self.data('text', self.html()); + self.html(Reepay_Admin.text_wait); + self.prop('disabled', true); + }, + success : function (response) { + self.html(self.data('text')); + self.prop('disabled', false); + if (!response.success) { + alert(response.data); + return false; + } + + window.location.href = location.href; + }, + error : function (response) { + alert(response); + } + }); + }); + + $(document).on('click', '#reepay_capture_partly', function (e) { + e.preventDefault(); + var nonce = $(this).data('nonce'); + var order_id = $(this).data('order-id'); + var amount = $("#reepay-capture_partly_amount-field").val(); + var self = $(this); + + $.ajax({ + url : Reepay_Admin.ajax_url, + type : 'POST', + data : { + action : 'reepay_capture_partly', + nonce : nonce, + order_id : order_id, + amount : amount + }, + beforeSend: function () { + self.data('text', self.html()); + self.html(Reepay_Admin.text_wait); + self.prop('disabled', true); + }, + success : function (response) { + self.html(self.data('text')); + self.prop('disabled', false); + if (!response.success) { + alert(response); + alert(response.data); + return false; + } + window.location.href = location.href; + }, + error : function (response) { + alert("error response: " + JSON.stringify(response)); + } + }); + }); + + $(document).on('click', '#reepay_refund_partly', function (e) { + e.preventDefault(); + var nonce = $(this).data('nonce'); + var order_id = $(this).data('order-id'); + var amount = $("#reepay-refund_partly_amount-field").val(); + var self = $(this); + + $.ajax({ + url : Reepay_Admin.ajax_url, + type : 'POST', + data : { + action : 'reepay_refund_partly', + nonce : nonce, + order_id : order_id, + amount : amount + }, + beforeSend: function () { + self.data('text', self.html()); + self.html(Reepay_Admin.text_wait); + self.prop('disabled', true); + }, + success : function (response) { + self.html(self.data('text')); + self.prop('disabled', false); + if (!response.success) { + alert(response); + alert(response.data); + return false; + } + window.location.href = location.href; + }, + error : function (response) { + alert("error response: " + JSON.stringify(response)); + } + }); + }); + + $(document).on('blur', '#reepay-capture_partly_amount-field', function (e) { + var val = parseFloat($(this).val().replace(",", ".")); + $(this).val(val.toFixed(2).replace(".", ",")); + }); + + $(document).on('blur', '#reepay-refund_partly_amount-field', function (e) { + var val = parseFloat($(this).val().replace(",", ".")); + $(this).val(val.toFixed(2).replace(".", ",")); + }); }); diff --git a/assets/js/admin.min.js b/assets/js/admin.min.js index 4de6a275..a48ac581 100755 --- a/assets/js/admin.min.js +++ b/assets/js/admin.min.js @@ -1,2 +1 @@ -jQuery(document).ready(function(e){e(document).on("click","#reepay_capture",function(t){t.preventDefault();var a=e(this).data("nonce"),n=e(this).data("order-id"),d=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_capture",nonce:a,order_id:n},beforeSend:function(){d.data("text",d.html()),d.html(Reepay_Admin.text_wait),d.prop("disabled",!0)},success:function(e){if(d.html(d.data("text")),d.prop("disabled",!1),!e.success)return alert(e.data),!1;window.location.href=location.href}})}),e(document).on("click","#reepay_cancel",function(t){t.preventDefault();var a=e(this).data("nonce"),n=e(this).data("order-id"),d=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_cancel",nonce:a,order_id:n},beforeSend:function(){d.data("text",d.html()),d.html(Reepay_Admin.text_wait),d.prop("disabled",!0)},success:function(e){if(d.html(d.data("text")),d.prop("disabled",!1),!e.success)return alert(e.data),!1;window.location.href=location.href}})})}); -//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFkbWluLmpzIl0sIm5hbWVzIjpbImpRdWVyeSIsImRvY3VtZW50IiwicmVhZHkiLCIkIiwib24iLCJlIiwicHJldmVudERlZmF1bHQiLCJub25jZSIsInRoaXMiLCJkYXRhIiwib3JkZXJfaWQiLCJzZWxmIiwiYWpheCIsInVybCIsIlJlZXBheV9BZG1pbiIsImFqYXhfdXJsIiwidHlwZSIsImFjdGlvbiIsImJlZm9yZVNlbmQiLCJodG1sIiwidGV4dF93YWl0IiwicHJvcCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsImFsZXJ0Iiwid2luZG93IiwibG9jYXRpb24iLCJocmVmIl0sIm1hcHBpbmdzIjoiQUFBQUEsT0FBT0MsVUFBVUMsTUFBTSxTQUFVQyxHQUNoQ0EsRUFBRUYsVUFBVUcsR0FBRyxRQUFTLGtCQUFtQixTQUFVQyxHQUNwREEsRUFBRUMsaUJBRUYsSUFBSUMsRUFBUUosRUFBRUssTUFBTUMsS0FBSyxTQUNyQkMsRUFBV1AsRUFBRUssTUFBTUMsS0FBSyxZQUN4QkUsRUFBT1IsRUFBRUssTUFDYkwsRUFBRVMsS0FBSyxDQUNOQyxJQUFZQyxhQUFhQyxTQUN6QkMsS0FBWSxPQUNaUCxLQUFZLENBQ1hRLE9BQWdCLGlCQUNoQlYsTUFBZ0JBLEVBQ2hCRyxTQUFnQkEsR0FFakJRLFdBQVksV0FDWFAsRUFBS0YsS0FBSyxPQUFRRSxFQUFLUSxRQUN2QlIsRUFBS1EsS0FBS0wsYUFBYU0sV0FDdkJULEVBQUtVLEtBQUssWUFBWSxJQUV2QkMsUUFBWSxTQUFVQyxHQUdyQixHQUZBWixFQUFLUSxLQUFLUixFQUFLRixLQUFLLFNBQ3BCRSxFQUFLVSxLQUFLLFlBQVksSUFDakJFLEVBQVNELFFBRWIsT0FEQUUsTUFBTUQsRUFBU2QsT0FDUixFQUdSZ0IsT0FBT0MsU0FBU0MsS0FBT0QsU0FBU0MsVUFLbkN4QixFQUFFRixVQUFVRyxHQUFHLFFBQVMsaUJBQWtCLFNBQVVDLEdBQ25EQSxFQUFFQyxpQkFFRixJQUFJQyxFQUFRSixFQUFFSyxNQUFNQyxLQUFLLFNBQ3JCQyxFQUFXUCxFQUFFSyxNQUFNQyxLQUFLLFlBQ3hCRSxFQUFPUixFQUFFSyxNQUNiTCxFQUFFUyxLQUFLLENBQ05DLElBQVlDLGFBQWFDLFNBQ3pCQyxLQUFZLE9BQ1pQLEtBQVksQ0FDWFEsT0FBZ0IsZ0JBQ2hCVixNQUFnQkEsRUFDaEJHLFNBQWdCQSxHQUVqQlEsV0FBWSxXQUNYUCxFQUFLRixLQUFLLE9BQVFFLEVBQUtRLFFBQ3ZCUixFQUFLUSxLQUFLTCxhQUFhTSxXQUN2QlQsRUFBS1UsS0FBSyxZQUFZLElBRXZCQyxRQUFZLFNBQVVDLEdBR3JCLEdBRkFaLEVBQUtRLEtBQUtSLEVBQUtGLEtBQUssU0FDcEJFLEVBQUtVLEtBQUssWUFBWSxJQUNqQkUsRUFBU0QsUUFFYixPQURBRSxNQUFNRCxFQUFTZCxPQUNSLEVBR1JnQixPQUFPQyxTQUFTQyxLQUFPRCxTQUFTQyIsImZpbGUiOiJhZG1pbi5taW4uanMiLCJzb3VyY2VzQ29udGVudCI6WyJqUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgkKSB7XG5cdCQoZG9jdW1lbnQpLm9uKCdjbGljaycsICcjcmVlcGF5X2NhcHR1cmUnLCBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblxuXHRcdHZhciBub25jZSA9ICQodGhpcykuZGF0YSgnbm9uY2UnKTtcblx0XHR2YXIgb3JkZXJfaWQgPSAkKHRoaXMpLmRhdGEoJ29yZGVyLWlkJyk7XG5cdFx0dmFyIHNlbGYgPSAkKHRoaXMpO1xuXHRcdCQuYWpheCh7XG5cdFx0XHR1cmwgICAgICAgOiBSZWVwYXlfQWRtaW4uYWpheF91cmwsXG5cdFx0XHR0eXBlICAgICAgOiAnUE9TVCcsXG5cdFx0XHRkYXRhICAgICAgOiB7XG5cdFx0XHRcdGFjdGlvbiAgICAgICAgOiAncmVlcGF5X2NhcHR1cmUnLFxuXHRcdFx0XHRub25jZSAgICAgICAgIDogbm9uY2UsXG5cdFx0XHRcdG9yZGVyX2lkICAgICAgOiBvcmRlcl9pZFxuXHRcdFx0fSxcblx0XHRcdGJlZm9yZVNlbmQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0c2VsZi5kYXRhKCd0ZXh0Jywgc2VsZi5odG1sKCkpO1xuXHRcdFx0XHRzZWxmLmh0bWwoUmVlcGF5X0FkbWluLnRleHRfd2FpdCk7XG5cdFx0XHRcdHNlbGYucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcblx0XHRcdH0sXG5cdFx0XHRzdWNjZXNzICAgOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0XHRcdFx0c2VsZi5odG1sKHNlbGYuZGF0YSgndGV4dCcpKTtcblx0XHRcdFx0c2VsZi5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcblx0XHRcdFx0aWYgKCFyZXNwb25zZS5zdWNjZXNzKSB7XG5cdFx0XHRcdFx0YWxlcnQocmVzcG9uc2UuZGF0YSk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0d2luZG93LmxvY2F0aW9uLmhyZWYgPSBsb2NhdGlvbi5ocmVmO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcblxuXHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnI3JlZXBheV9jYW5jZWwnLCBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblxuXHRcdHZhciBub25jZSA9ICQodGhpcykuZGF0YSgnbm9uY2UnKTtcblx0XHR2YXIgb3JkZXJfaWQgPSAkKHRoaXMpLmRhdGEoJ29yZGVyLWlkJyk7XG5cdFx0dmFyIHNlbGYgPSAkKHRoaXMpO1xuXHRcdCQuYWpheCh7XG5cdFx0XHR1cmwgICAgICAgOiBSZWVwYXlfQWRtaW4uYWpheF91cmwsXG5cdFx0XHR0eXBlICAgICAgOiAnUE9TVCcsXG5cdFx0XHRkYXRhICAgICAgOiB7XG5cdFx0XHRcdGFjdGlvbiAgICAgICAgOiAncmVlcGF5X2NhbmNlbCcsXG5cdFx0XHRcdG5vbmNlICAgICAgICAgOiBub25jZSxcblx0XHRcdFx0b3JkZXJfaWQgICAgICA6IG9yZGVyX2lkXG5cdFx0XHR9LFxuXHRcdFx0YmVmb3JlU2VuZDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRzZWxmLmRhdGEoJ3RleHQnLCBzZWxmLmh0bWwoKSk7XG5cdFx0XHRcdHNlbGYuaHRtbChSZWVwYXlfQWRtaW4udGV4dF93YWl0KTtcblx0XHRcdFx0c2VsZi5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuXHRcdFx0fSxcblx0XHRcdHN1Y2Nlc3MgICA6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHRcdFx0XHRzZWxmLmh0bWwoc2VsZi5kYXRhKCd0ZXh0JykpO1xuXHRcdFx0XHRzZWxmLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xuXHRcdFx0XHRpZiAoIXJlc3BvbnNlLnN1Y2Nlc3MpIHtcblx0XHRcdFx0XHRhbGVydChyZXNwb25zZS5kYXRhKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR3aW5kb3cubG9jYXRpb24uaHJlZiA9IGxvY2F0aW9uLmhyZWY7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0pO1xufSk7XG4iXX0= +jQuery(document).ready(function(e){e(document).on("click","#reepay_capture",function(t){t.preventDefault();var a=e(this).data("nonce"),r=e(this).data("order-id"),n=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_capture",nonce:a,order_id:r},beforeSend:function(){n.data("text",n.html()),n.html(Reepay_Admin.text_wait),n.prop("disabled",!0)},success:function(e){if(n.html(n.data("text")),n.prop("disabled",!1),!e.success)return!1;window.location.href=location.href}})}),e(document).on("click","#reepay_cancel",function(t){t.preventDefault();var a=e(this).data("nonce"),r=e(this).data("order-id"),n=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_cancel",nonce:a,order_id:r},beforeSend:function(){n.data("text",n.html()),n.html(Reepay_Admin.text_wait),n.prop("disabled",!0)},success:function(e){if(n.html(n.data("text")),n.prop("disabled",!1),!e.success)return alert(e.data),!1;window.location.href=location.href}})}),e(document).on("click","#reepay_refund",function(t){t.preventDefault();var a=e(this).data("nonce"),r=e(this).data("order-id"),n=e(this).data("amount"),o=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_refund",nonce:a,order_id:r,amount:n},beforeSend:function(){o.data("text",o.html()),o.html(Reepay_Admin.text_wait),o.prop("disabled",!0)},success:function(e){if(o.html(o.data("text")),o.prop("disabled",!1),!e.success)return alert(e.data),!1;window.location.href=location.href},error:function(e){alert(e)}})}),e(document).on("click","#reepay_capture_partly",function(t){t.preventDefault();var a=e(this).data("nonce"),r=e(this).data("order-id"),n=e("#reepay-capture_partly_amount-field").val(),o=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_capture_partly",nonce:a,order_id:r,amount:n},beforeSend:function(){o.data("text",o.html()),o.html(Reepay_Admin.text_wait),o.prop("disabled",!0)},success:function(e){if(o.html(o.data("text")),o.prop("disabled",!1),!e.success)return alert(e),alert(e.data),!1;window.location.href=location.href},error:function(e){alert("error response: "+JSON.stringify(e))}})}),e(document).on("click","#reepay_refund_partly",function(t){t.preventDefault();var a=e(this).data("nonce"),r=e(this).data("order-id"),n=e("#reepay-refund_partly_amount-field").val(),o=e(this);e.ajax({url:Reepay_Admin.ajax_url,type:"POST",data:{action:"reepay_refund_partly",nonce:a,order_id:r,amount:n},beforeSend:function(){o.data("text",o.html()),o.html(Reepay_Admin.text_wait),o.prop("disabled",!0)},success:function(e){if(o.html(o.data("text")),o.prop("disabled",!1),!e.success)return alert(e),alert(e.data),!1;window.location.href=location.href},error:function(e){alert("error response: "+JSON.stringify(e))}})}),e(document).on("blur","#reepay-capture_partly_amount-field",function(t){var a=parseFloat(e(this).val().replace(",","."));e(this).val(a.toFixed(2).replace(".",","))}),e(document).on("blur","#reepay-refund_partly_amount-field",function(t){var a=parseFloat(e(this).val().replace(",","."));e(this).val(a.toFixed(2).replace(".",","))})}); \ No newline at end of file diff --git a/includes/abstracts/abstract-wc-payment-gateway-reepay.php b/includes/abstracts/abstract-wc-payment-gateway-reepay.php index 8d22231c..60d3ffa9 100755 --- a/includes/abstracts/abstract-wc-payment-gateway-reepay.php +++ b/includes/abstracts/abstract-wc-payment-gateway-reepay.php @@ -27,16 +27,34 @@ public function can_capture( $order, $amount = FALSE ) { if ( ! $amount ) { $amount = $order->get_total(); } - + + //$this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "Amount to capture: " . $amount ) ); + $handle = $this->get_order_handle( $order ); try { + $result = $this->request( 'GET', 'https://api.reepay.com/v1/invoice/' . $handle ); + //$this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, var_export($result, true) ) ); + //exit(); } catch (Exception $e) { return FALSE; } - - return $result['state'] === 'authorized'; + + $authorizedAmount = $result['authorized_amount']; + $settledAmount = $result['settled_amount']; + $refundedAmount = $result['refunded_amount']; + + // $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "STATE: " . $result['state'] ) ); + $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "authorizedAmount: " . $authorizedAmount ) ); + $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "settledAmount: " . $settledAmount ) ); + $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "amount: " . $amount ) ); + + //exit(); + return ( + ( $result['state'] === 'authorized' ) || + ( $result['state'] === 'settled' && $authorizedAmount >= $settledAmount + $amount ) + ); } /** @@ -58,12 +76,16 @@ public function can_cancel( $order ) { $handle = $this->get_order_handle( $order ); try { + //$this->log( sprintf( '%s::%s Try to cancel %s', __CLASS__, __METHOD__, $order ) ); $result = $this->request( 'GET', 'https://api.reepay.com/v1/invoice/' . $handle ); + $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, json_encode($result) ) ); } catch (Exception $e) { return FALSE; } - return $result['state'] === 'authorized'; + // return $result['state'] === 'authorized' || ( $result['state'] === "settled" && $result["settled_amount"] < $result["authorized_amount"] ); + // can only cancel payments when the state is authorized (partly void is not supported yet) + return ( $result['state'] === 'authorized' ); } /** @@ -77,6 +99,13 @@ public function can_refund( $order, $amount = FALSE ) { if ( is_int( $order ) ) { $order = wc_get_order( $order ); } + + // + // Check if hte order is cancelled - if so - then return as nothing has happened + // + if ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ) { + return; + } if ( $order->get_payment_method() !== $this->id ) { return FALSE; @@ -110,6 +139,13 @@ public function capture_payment( $order, $amount = FALSE ) { if ( is_int( $order ) ) { $order = wc_get_order( $order ); } + + // + // Check if hte order is cancelled - if so - then return as nothing has happened + // + if ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ) { + return; + } if ( ! $amount ) { $amount = $order->get_total(); @@ -130,22 +166,24 @@ public function capture_payment( $order, $amount = FALSE ) { ]; $result = $this->request( 'POST', 'https://api.reepay.com/v1/charge/' . $handle . '/settle', $params ); } catch ( Exception $e ) { - throw new Exception( sprintf( 'API Error: %s', $e->getMessage() ) ); + throw new Exception( sprintf( 'API Error (capture_payment): %s', $e->getMessage() ) ); } - + update_post_meta( $order->get_id(), '_reepay_capture_transaction', $result['transaction'] ); $order->set_transaction_id( $result['transaction'] ); $order->save(); + + if ( !$amount) { + $order->payment_complete( $result['transaction'] ); - $order->payment_complete( $result['transaction'] ); + if (defined('REEPAY_STATUS_SETTLED')) { + $order->set_status( REEPAY_STATUS_SETTLED ); + $order->save(); + } - if (defined('REEPAY_STATUS_SETTLED')) { - $order->set_status( REEPAY_STATUS_SETTLED ); - $order->save(); + $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); } - - $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); } /** @@ -160,6 +198,13 @@ public function cancel_payment( $order ) { if ( is_int( $order ) ) { $order = wc_get_order( $order ); } + + // + // Check if hte order is cancelled - if so - then return as nothing has happened + // + if ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ) { + return; + } if ( ! $this->can_cancel( $order ) ) { throw new Exception( 'Payment can\'t be cancelled.' ); @@ -173,7 +218,7 @@ public function cancel_payment( $order ) { try { $result = $this->request( 'POST', 'https://api.reepay.com/v1/charge/' . $handle . '/cancel' ); } catch ( Exception $e ) { - throw new Exception( sprintf( 'API Error: %s', $e->getMessage() ) ); + throw new Exception( sprintf( 'API Error (cancel_payment): %s', $e->getMessage() ) ); } update_post_meta($order->get_id(), '_reepay_cancel_transaction', $result['transaction'] ); @@ -200,6 +245,13 @@ public function refund_payment( $order, $amount = FALSE, $reason = '' ) { if ( is_int( $order ) ) { $order = wc_get_order( $order ); } + + // + // Check if hte order is cancelled - if so - then return as nothing has happened + // + if ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ) { + return; + } if ( ! $this->can_refund( $order, $amount ) ) { throw new Exception( 'Payment can\'t be refunded.' ); @@ -217,7 +269,7 @@ public function refund_payment( $order, $amount = FALSE, $reason = '' ) { ]; $result = $this->request( 'POST', 'https://api.reepay.com/v1/refund', $params ); } catch ( Exception $e ) { - throw new Exception( sprintf( 'API Error: %s', $e->getMessage() ) ); + throw new Exception( sprintf( 'API Error (refund_payment): %s', $e->getMessage() ) ); } // Save Credit Note ID @@ -490,7 +542,7 @@ public function request($method, $url, $params = array()) { return $result; } - throw new Exception(sprintf('API Error: %s. HTTP Code: %s', $body, $info['http_code'])); + throw new Exception(sprintf('API Error (request): %s. HTTP Code: %s', $body, $info['http_code'])); default: throw new Exception(sprintf('Invalid HTTP Code: %s', $info['http_code'])); } @@ -972,4 +1024,24 @@ public function get_language() { return 'en_US'; } + + public function get_invoice_data( $order ) { + if ( is_int( $order ) ) { + $order = wc_get_order( $order ); + } + + if ( $order->get_payment_method() !== $this->id ) { + return FALSE; + } + + $handle = $this->get_order_handle( $order ); + + try { + + $result = $this->request( 'GET', 'https://api.reepay.com/v1/invoice/' . $handle ); + return $result; + } catch (Exception $e) { + return FALSE; + } + } } diff --git a/includes/class-wc-gateway-reepay-checkout.php b/includes/class-wc-gateway-reepay-checkout.php index 483b6942..8967e17f 100755 --- a/includes/class-wc-gateway-reepay-checkout.php +++ b/includes/class-wc-gateway-reepay-checkout.php @@ -40,7 +40,9 @@ class WC_Gateway_Reepay_Checkout extends WC_Payment_Gateway_Reepay { * Settle * @var string */ - public $settle = 'yes'; + public $settle = array( + 'online_virtual', 'physical', 'recurring' + ); /** * Debug Mode @@ -123,6 +125,10 @@ public function __construct() { if ( $this->save_cc !== 'yes' && ($key = array_search('add_payment_method', $this->supports)) !== false ) { unset($this->supports[$key]); } + + if (!is_array($this->settle)) { + $this->settle = array(); + } add_action( 'admin_notices', array( $this, 'admin_notice_warning' ) ); @@ -250,12 +256,17 @@ public function init_form_fields() { ), 'default' => $this->payment_type ), - 'settle' => array( - 'title' => __( 'Instant Settle', 'woocommerce-gateway-reepay-checkout' ), - 'type' => 'checkbox', - 'label' => __( 'Enable instant settle', 'woocommerce-gateway-reepay-checkout' ), + 'settle' => array( + 'title' => __( 'Instant Settle', 'woocommerce-gateway-reepay-checkout' ), 'description' => __( 'Instant Settle will charge your customers right away', 'woocommerce-gateway-reepay-checkout' ), - 'default' => $this->settle + 'type' => 'multiselect', + 'css' => 'height: 150px', + 'options' => array( + 'online_virtual' => __( 'Instant Settle online / virtualproducts', 'woocommerce-gateway-reepay-checkout' ), + 'physical' => __( 'Instant Settle physical products', 'woocommerce-gateway-reepay-checkout' ), + 'recurring' => __( 'Instant Settle recurring (subscription) products', 'woocommerce-gateway-reepay-checkout' ), + ), + 'select_buttons' => TRUE, ), 'language' => array( 'title' => __( 'Language In Payment Window', 'woocommerce-gateway-reepay-checkout' ), @@ -732,11 +743,16 @@ public function process_payment( $order_id ) { 'cancel_url' => $order->get_cancel_order_url() ); } - + + // + // Calculate if the order is to be settled instantly (from products and configuration) + // + $instant_settle_ary = $this->order_instant_settle( $order ); + // Initialize Payment $params = [ 'locale' => $this->get_language(), - 'settle' => $this->settle === 'yes', + 'settle' => $settleInstant, 'recurring' => $maybe_save_card || self::order_contains_subscription( $order ) || self::wcs_is_payment_change(), 'order' => [ 'handle' => $this->get_order_handle( $order ), @@ -801,6 +817,9 @@ public function process_payment( $order_id ) { } } + //$this->log( sprintf( '%s::%s Charge params %s', __CLASS__, __METHOD__, var_export( $params, true ) ) ); + //return; + $result = $this->request('POST', 'https://checkout-api.reepay.com/v1/session/charge', $params); $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, var_export( $result, true ) ) ); @@ -832,6 +851,102 @@ public function process_payment( $order_id ) { 'cancel_url' => $order->get_cancel_order_url() ); } + + /** + * Validates if an order is to be settled instantly based by the order items + * @Param $order - is the WooCommerce order object + * @Param $order_settle_amount - is a reference to the variable which will contain the calculated settle amount. That value is used if the entire order cannot be captured + * @return bool - set to true if the order is to be settled instantly + */ + public function order_instant_settle( $order ) { + $instant_settle = false; + // + // 3 x different states if an order should be settled instant + // + $orderCanInstantSettle = array( + "online_virtual" => true, + "physical" => true, + "recurring" => true + ); + + // + // flag if the product is recurring + // + $isRecurring = self::order_contains_subscription( $order ); + + // + // Increment this value with the amount to settle + // + $instant_settle_amount = 0; + + // + // Total number products + // + $order_products_count = 0; + + // + // + // + $instant_settle_products_count = 0; + + // + // Now walk through the order-lines and check per order if it is virtual, downloadable, recurring or physical + // if any of the items doesn't match the reepay instant settle configuration, the flag is set as false + // + foreach ( $order->get_items() as $item ) { + $quantity = $item->get_quantity(); + $_product = $order->get_product_from_item( $item ); // fetch product details from the order + $isVirtual = $_product->is_virtual(); // flag if the product is virtual + $isDownload = $_product->is_downloadable(); // flag if the product is downloadable + $productAmount = ( $quantity * $_product->price * 100 ); // get the product price; + + //echo "is download: " . $isDownload; exit(); + //$this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "product: " . var_export($_product, true) ) ); + + // + // Invalidate options if mitch match + // + if ( $isVirtual && !in_array("online_virtual", $this->settle ) ) { + $orderCanInstantSettle["online_virtual"] = false; + $productAmount = 0; + break; + } else if ( $isDownload && !in_array("online_virtual", $this->settle ) ) { + $orderCanInstantSettle["online_virtual"] = false; + $productAmount = 0; + break; + } else if ( $isRecurring && !in_array( "recurring", $this->settle ) ) { + $orderCanInstantSettle["recurring"] = false; + $productAmount = 0; + break; + } else if ( !$isVirtual && !$isDownload && !in_array( "physical", $this->settle ) ) { + $orderCanInstantSettle["physical"] = false; + $productAmount = 0; + break; + } + + if ($productAmount > 0) $instant_settle_products_count++; + $instant_settle_amount += $productAmount; + $order_products_count++; + } + + // + // Only instant settle if all variations are true + // + $instant_settle = ((bool) ( + $orderCanInstantSettle["online_virtual"] && + $orderCanInstantSettle["physical"] && + $orderCanInstantSettle["recurring"] + )); + + $this->log( sprintf( '%s::%s Result %s', __CLASS__, __METHOD__, "instant settle (" . $instant_settle . ") amount: " . $instant_settle_amount . ", order items: " . count( $order->get_items() ) ) ); + + return array ( + "instant_settle" => $instant_settle, + "instant_settle_amount" => $instant_settle_amount, + "order_products_count" => $order_products_count, + "instant_settle_products_count" => $instant_settle_products_count + ); + } /** * Payment confirm action @@ -892,7 +1007,7 @@ public function payment_confirm() { do { usleep( 500 ); $attempts++; - if ( $attempts > 12 ) { + if ( $attempts > 30 ) { $status_failback = true; break; } @@ -901,8 +1016,11 @@ public function payment_confirm() { $order = wc_get_order( $order_id ); } while ( $order->has_status( apply_filters( 'woocommerce_default_order_status', 'pending' ) ) ); +//$this->process_instant_settle( $order ); +//exit(); // Update order status if ( $status_failback ) { + $this->log( sprintf( '%s::%s Processing status_fallback ', __CLASS__, __METHOD__ ) ); try { $result = $this->request( 'GET', 'https://api.reepay.com/v1/invoice/' . wc_clean( $_GET['invoice'] ) ); $this->log( sprintf( '%s::%s Invoice data %s', __CLASS__, __METHOD__, var_export( $result, true ) ) ); @@ -911,9 +1029,11 @@ public function payment_confirm() { return; } + $this->log( sprintf( '%s::%s status_fallback state %s ', __CLASS__, __METHOD__, $result['state'] ) ); switch ($result['state']) { case 'authorized': $this->set_authorized_status( $order ); + $this->process_instant_settle( $order ); break; case 'settled': $order->payment_complete(); @@ -935,6 +1055,68 @@ public function payment_confirm() { // Lock payment confirmation //update_post_meta( $order->get_id(), '_reepay_payment_confirmed', 1 ); } + + public function process_instant_settle( $order ) { + // + // Calculate if the order is to be instant settled + // + $instant_settle_ary = (object)$this->order_instant_settle( $order ); + + $this->log( sprintf( '%s::%s instant-settle-array calculated %s', __CLASS__, __METHOD__, var_export( $instant_settle_ary, true ) ) ); + + $settle_amount = 0; + + if ( count( $order->get_items() ) == $instant_settle_ary->instant_settle_products_count ) { + $settle_amount = $order->get_total() * 100; + } else { + $settle_amount = $instant_settle_ary->instant_settle_amount; + } + + $this->log( sprintf( '%s::%s Settle amount %s', __CLASS__, __METHOD__, $settle_amount ) ); + + // + // If settle + // + if ($settle_amount > 0) { + $this->log( sprintf( '%s::%s Settle amount towards reepay %s', __CLASS__, __METHOD__, $settle_amount ) ); + $params = array ( + "amount" => $settle_amount + ); + // + // + // + try { + $result = $this->request( 'POST', 'https://api.reepay.com/v1/charge/order-' . $order->get_id() . '/settle', $params ); + //$this->log( sprintf( '%s::%s Invoice settled success %s', __CLASS__, __METHOD__, var_export( $result, true ) ) ); + } catch (Exception $e) { + $this->log( sprintf( '%s::%s API Error: %s', __CLASS__, __METHOD__, var_export( $e->getMessage(), true ) ) ); + return false; + } + + // + // If entire order is settled - go and mark as complete + // + if ( ( $order->get_total() * 100) == $settle_amount) { + // + // Log the order has been fully settled + // + $order->add_order_note( __( 'Transaction settled with amount ' . number_format( $settle_amount / 100, 2, wc_get_price_decimal_separator(), '' ) . '.', 'woocommerce-gateway-reepay-checkout' ) ); + // + // Set the order as settled + // + // $order->payment_complete(); + } else { + // + // Partly settle + // Log the amout + // + $order->add_order_note( __( 'Transaction partly settled with amount ' . number_format( $settle_amount / 100, 2, wc_get_price_decimal_separator(), '' ) . '.', 'woocommerce-gateway-reepay-checkout' ) ); + } + } + + //print_r($instant_settle_ary); exit(); + return true; + } /** * WebHook Callback @@ -995,6 +1177,9 @@ public function return_handler() { if ( ! $order_stock_reduced ) { wc_reduce_stock_levels( $order->get_id() ); } + + // process instant settle + $this->process_instant_settle( $order ); $this->set_authorized_status( $order ); @@ -1024,8 +1209,16 @@ public function return_handler() { return; } - $order->payment_complete( $data['transaction'] ); - $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); + // + // Only complete the order if... partly settle is disabled + // + $instant_settle_ary = (object)$this->order_instant_settle( $order ); + if ( $instant_settle_ary->instant_settle_amount == 0 ) { + $order->payment_complete( $data['transaction'] ); + $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); + } else { + // $order->add_order_note( __( 'Transaction already partly settled.', 'woocommerce-gateway-reepay-checkout' ) ); + } update_post_meta( $order->get_id(), '_reepay_capture_transaction', $data['transaction'] ); $this->log( sprintf( 'WebHook: Success event type: %s', $data['event_type'] ) ); @@ -1486,14 +1679,20 @@ public function maybe_render_subscription_payment_method( $payment_method_to_dis */ protected function reepay_charge( $order, $token, $amount = null ) { + // @todo Use order lines instead of amount try { + // + // Calculate if the order is to be instant settled + // + //$instant_settle_ary = $this->order_instant_settle( $order ); + $params = [ 'handle' => $this->get_order_handle( $order ), 'amount' => round(100 * $amount), 'currency' => $order->get_currency(), 'source' => $token->get_token(), - 'settle' => $this->settle === 'yes', + // 'settle' => $instantSettle, 'recurring' => $this->order_contains_subscription( $order ), 'customer' => [ 'test' => $this->test_mode === 'yes', @@ -1563,9 +1762,12 @@ protected function reepay_charge( $order, $token, $amount = null ) update_post_meta( $order->get_id(), 'reepay_charge', '0' ); break; case 'settled': - $order->payment_complete( $result['transaction'] ); - $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); - update_post_meta( $order->get_id(), 'reepay_charge', '1' ); + $instant_settle_ary = (object)$this->order_instant_settle( $order ); + if ($instant_settle_ary->instant_settle_amount == 0) { + $order->payment_complete( $result['transaction'] ); + $order->add_order_note( __( 'Transaction settled.', 'woocommerce-gateway-reepay-checkout' ) ); + update_post_meta( $order->get_id(), 'reepay_charge', '1' ); + } break; default: throw new Exception( 'Generic error' ); diff --git a/includes/class-wc-reepay-order-statuses.php b/includes/class-wc-reepay-order-statuses.php index 370e22d0..563919bf 100755 --- a/includes/class-wc-reepay-order-statuses.php +++ b/includes/class-wc-reepay-order-statuses.php @@ -309,6 +309,7 @@ public function reepay_authorized_order_status( $status, $order_id, $order ) { * @param WC_Order $order */ public static function order_status_changed( $order_id, $from, $to, $order ) { + $payment_method = $order->get_payment_method(); if ( ! in_array( $payment_method, WC_ReepayCheckout::PAYMENT_METHODS ) ) { return; @@ -346,8 +347,12 @@ public static function order_status_changed( $order_id, $from, $to, $order ) { case REEPAY_STATUS_SETTLED: // Capture payment if ( $gateway->can_capture( $order ) ) { + + $order_data = $gateway->get_invoice_data( $order ); + $amount = $order_data["authorized_amount"] - $order_data["settled_amount"]; + $amount = (float)((float)$amount / 100); try { - $gateway->capture_payment( $order ); + $gateway->capture_payment( $order, $amount ); } catch ( Exception $e ) { $message = $e->getMessage(); WC_Admin_Meta_Boxes::add_error( $message ); diff --git a/reepay-woocommerce-payment.php b/reepay-woocommerce-payment.php index 78d1d536..4aacc9d2 100755 --- a/reepay-woocommerce-payment.php +++ b/reepay-woocommerce-payment.php @@ -45,7 +45,7 @@ public function __construct() { //add_action( 'add_meta_boxes', __CLASS__ . '::add_meta_boxes' ); // Add action buttons - add_action( 'woocommerce_order_item_add_action_buttons', __CLASS__ . '::add_action_buttons', 10, 1 ); + //add_action( 'woocommerce_order_item_add_action_buttons', __CLASS__ . '::add_action_buttons', 10, 1 ); // Add scripts and styles for admin add_action( 'admin_enqueue_scripts', __CLASS__ . '::admin_enqueue_scripts' ); @@ -63,11 +63,29 @@ public function __construct() { $this, 'ajax_reepay_cancel' ) ); + + add_action( 'wp_ajax_reepay_refund', array( + $this, + 'ajax_reepay_refund' + ) ); + + add_action( 'wp_ajax_reepay_capture_partly', array( + $this, + 'ajax_reepay_capture_partly' + ) ); + + add_action( 'wp_ajax_reepay_refund_partly', array( + $this, + 'ajax_reepay_refund_partly' + ) ); $this->includes(); // Add admin menu add_action( 'admin_menu', array( &$this, 'admin_menu' ), 99 ); + + // add meta boxes + add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] ); } /** @@ -203,7 +221,7 @@ public function add_valid_order_statuses( $statuses, $order ) { * @return void */ public static function add_meta_boxes() { - global $post_id; + /*global $post_id; if ( $order = wc_get_order( $post_id ) ) { $payment_method = $order->get_payment_method(); if ( in_array( $payment_method, self::PAYMENT_METHODS ) ) { @@ -216,6 +234,26 @@ public static function add_meta_boxes() { 'default' ); } + }*/ + + global $post; + $screen = get_current_screen(); + $post_types = [ 'shop_order', 'shop_subscription' ]; + + if ( in_array( $screen->id, $post_types, true ) && in_array( $post->post_type, $post_types, true ) ) { + if ( $order = wc_get_order( $post->ID ) ) { + $payment_method = $order->get_payment_method(); + if ( in_array( $payment_method, self::PAYMENT_METHODS ) ) { + add_meta_box( 'reepay-payment-actions', __( 'Reepay Payment', 'woocommerce-gateway-reepay-checkout' ), [ + &$this, + 'meta_box_payment', + ], 'shop_order', 'side', 'high' ); + add_meta_box( 'reepay-payment-actions', __( 'Reepay Subscription', 'woocommerce-gateway-reepay-checkout' ), [ + &$this, + 'meta_box_subscription', + ], 'shop_subscription', 'side', 'high' ); + } + } } } @@ -283,6 +321,7 @@ public static function admin_enqueue_scripts( $hook ) { // Scripts $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; wp_register_script( 'reepay-admin-js', plugin_dir_url( __FILE__ ) . 'assets/js/admin' . $suffix . '.js' ); + wp_enqueue_style( 'wc-gateway-reepay-checkout', plugins_url( '/assets/css/style' . $suffix . '.css', __FILE__ ), array(), FALSE, 'all' ); // Localize the script $translation_array = array( @@ -332,6 +371,15 @@ public function ajax_reepay_cancel() { $order_id = (int) $_REQUEST['order_id']; $order = wc_get_order( $order_id ); + + // + // Check if the order is already cancelled + // ensure no more actions are made + // + if ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ) { + wp_send_json_success( __( 'Order already cancelled.', 'woocommerce-gateway-reepay-checkout' ) ); + return; + } try { // Get Payment Gateway @@ -340,8 +388,112 @@ public function ajax_reepay_cancel() { /** @var WC_Gateway_Reepay_Checkout $gateway */ $gateway = $gateways[ $payment_method ]; - $gateway->cancel_payment( $order ); - wp_send_json_success( __( 'Capture success.', 'woocommerce-gateway-reepay-checkout' ) ); + + // Check if the payment can be cancelled + // $order->update_meta_data( '_' . $key, $value ); + // order->get_meta( '_reepay_token', true ) + if ($gateway->can_cancel( $order )) { + $gateway->cancel_payment( $order ); + } + + // + // Mark the order as cancelled - no more communciation to reepay is done! + // + $order->update_meta_data( '_reepay_order_cancelled', 1 ); + $order->save_meta_data(); + + // Return success + wp_send_json_success( __( 'Cancel success.', 'woocommerce-gateway-reepay-checkout' ) ); + } catch ( Exception $e ) { + $message = $e->getMessage(); + wp_send_json_error( $message ); + } + } + + /** + * Action for Cancel + */ + public function ajax_reepay_refund() { + if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'reepay' ) ) { + exit( 'No naughty business' ); + } + + + $amount = (int) $_REQUEST['amount']; + $order_id = (int) $_REQUEST['order_id']; + $order = wc_get_order( $order_id ); + + try { + // Get Payment Gateway + $payment_method = $order->get_payment_method(); + $gateways = WC()->payment_gateways()->get_available_payment_gateways(); + + /** @var WC_Gateway_Reepay_Checkout $gateway */ + $gateway = $gateways[ $payment_method ]; + $gateway->refund_payment( $order, $amount ); + wp_send_json_success( __( 'Refund success.', 'woocommerce-gateway-reepay-checkout' ) ); + } catch ( Exception $e ) { + $message = $e->getMessage(); + wp_send_json_error( $message ); + } + } + + /** + * Action for Cancel + */ + public function ajax_reepay_capture_partly() { + + if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'reepay' ) ) { + exit( 'No naughty business' ); + } + + $amount = $_REQUEST['amount']; + $order_id = (int) $_REQUEST['order_id']; + $order = wc_get_order( $order_id ); + + $amount = str_replace(",", "", $amount); + $amount = str_replace(".", "", $amount); + + try { + // Get Payment Gateway + $payment_method = $order->get_payment_method(); + $gateways = WC()->payment_gateways()->get_available_payment_gateways(); + + /** @var WC_Gateway_Reepay_Checkout $gateway */ + $gateway = $gateways[ $payment_method ]; + $gateway->capture_payment( $order, (float)((float)$amount / 100) ); + wp_send_json_success( __( 'Capture partly success.', 'woocommerce-gateway-reepay-checkout' ) ); + } catch ( Exception $e ) { + $message = $e->getMessage(); + wp_send_json_error( $message ); + } + } + + /** + * Action for Cancel + */ + public function ajax_reepay_refund_partly() { + + if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'reepay' ) ) { + exit( 'No naughty business' ); + } + + $amount = $_REQUEST['amount']; + $order_id = (int) $_REQUEST['order_id']; + $order = wc_get_order( $order_id ); + + $amount = str_replace(",", "", $amount); + $amount = str_replace(".", "", $amount); + + try { + // Get Payment Gateway + $payment_method = $order->get_payment_method(); + $gateways = WC()->payment_gateways()->get_available_payment_gateways(); + + /** @var WC_Gateway_Reepay_Checkout $gateway */ + $gateway = $gateways[ $payment_method ]; + $gateway->refund_payment( $order, (float)((float)$amount / 100) ); + wp_send_json_success( __( 'Refund partly success.', 'woocommerce-gateway-reepay-checkout' ) ); } catch ( Exception $e ) { $message = $e->getMessage(); wp_send_json_error( $message ); @@ -393,6 +545,210 @@ public static function upgrade_notice() { ID ) ) { + + $payment_method = $order->get_payment_method(); + if ( in_array( $payment_method, self::PAYMENT_METHODS ) ) { + + do_action( 'woocommerce_reepay_meta_box_payment_before_content', $order ); + if ( true ) { + + $state = null; + try { + // + // Fetch the gateway and order data + // + $gateways = WC()->payment_gateways()->get_available_payment_gateways(); + $gateway = $gateways[ $payment_method ]; + $order_data = $gateway->get_invoice_data( $order ); + + // + // Calculate if hte user has cancelled the payment + // + $order_is_cancelled = ( $order->get_meta( '_reepay_order_cancelled', true ) === "1" ); + + // + // Header payment information + // + echo ""; + } catch ( Exception $e ) { + echo ""; + } + } + } + } + } + + /* + * Formats a minor unit value into float with two decimals + * @priceMinor is the amount to format + * @return the nicely formatted value + */ + public function format_price_decimals( $priceMinor ) { + return number_format( $priceMinor / 100, 2, wc_get_price_decimal_separator(), '' ); + } + + /* + * Formats a credit card nicely + * @cc is the card number to format nicely + * @return the nicely formatted value + */ + public function formatCreditCard( $cc ) { + $cc = str_replace(array('-', ' '), '', $cc); + $cc_length = strlen($cc); + $newCreditCard = substr($cc, -4); + + for ( $i = $cc_length - 5; $i >= 0; $i-- ) { + if ( (($i + 1) - $cc_length) % 4 == 0 ) { + $newCreditCard = ' ' . $newCreditCard; + } + $newCreditCard = $cc[$i] . $newCreditCard; + } + + for ( $i = 7; $i < $cc_length - 4; $i++ ) { + if ( $newCreditCard[$i] == ' ' ) { + continue; + } + $newCreditCard[$i] = 'X'; + } + + return $newCreditCard; + } + + /* + * Converts a Reepay card_type into a logo + * @card_type is the Reepay card type + * @returns the logo + */ + public function get_logo( $card_type ) { + $image = null; + switch ( $card_type ) { + case 'visa': { + $image = 'visa.png'; break; + } + case 'mc': { + $image = 'mastercard.png'; break; + } + case 'dankort': { + $image = 'dankort.png'; break; + } + case 'visa_dk': { + $image = 'dankort.png'; break; + } + case 'ffk': { + $image = 'forbrugsforeningen.png'; break; + } + case 'visa_elec': { + $image = 'visa-electron.png'; break; + } + case 'maestro': { + $image = 'maestro.png'; break; + } + case 'amex': { + $image = 'american-express.png'; break; + } + case 'diners': { + $image = 'diners.png'; break; + } + case 'discover': { + $image = 'discover.png'; break; + } + case 'jcb': { + $image = 'jcb.png'; break; + } + case 'mobilepay': { + $image = 'mobilepay.png'; break; + } + case 'viabill': { + $image = 'viabill.png'; break; + } + case 'klarna_pay_later': { + $image = 'klarna.png'; break; + } + case 'klarna_pay_now': { + $image = 'klarna.png'; break; + } + case 'resurs': { + $image = 'resurs.png'; break; + } + case 'china_union_pay': { + $image = 'cup.png'; break; + } + case 'paypal': { + $image = 'paypal.png'; break; + } + case 'applepay': { + $image = 'applepay.png'; break; + } + default: { + $image = 'reepay.png'; break; + } + } + + return WP_PLUGIN_URL . "/reepay-checkout-gateway/assets/images/" . $image; + } + } new WC_ReepayCheckout(); diff --git a/templates/admin/action-buttons.php b/templates/admin/action-buttons.php index eb2ac251..2a727ce5 100755 --- a/templates/admin/action-buttons.php +++ b/templates/admin/action-buttons.php @@ -8,7 +8,7 @@ ?> -can_capture( $order ) ): ?> +can_capture( $order ) || true ): ?>