Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Michael Iseard
Kudos-Donations
Commits
1bd98e42
Commit
1bd98e42
authored
Mar 09, 2021
by
Michael Iseard
Browse files
Initial work on checking if Mollie account can receive recurring payments
parent
d2823a54
Changes
11
Show whitespace changes
Inline
Side-by-side
app/Helpers/Settings.php
View file @
1bd98e42
...
...
@@ -255,7 +255,7 @@ class Settings {
'amount_type'
=>
'both'
,
'fixed_amounts'
=>
'1,5,20,50'
,
'campaign_goal'
=>
''
,
'donation_type'
=>
'
both
'
,
'donation_type'
=>
'
oneoff
'
,
'protected'
=>
true
,
],
],
...
...
app/Service/ActivatorService.php
View file @
1bd98e42
...
...
@@ -116,7 +116,7 @@ class ActivatorService {
}
if
(
version_compare
(
$old_version
,
'2.3.
8
'
,
'<'
)
)
{
if
(
version_compare
(
$old_version
,
'2.3.
9
'
,
'<'
)
)
{
// Setting now replaced by single 'vendor_mollie' setting
if
(
Settings
::
update_setting
(
'vendor_mollie'
,
[
...
...
app/Service/PaymentService.php
View file @
1bd98e42
...
...
@@ -325,9 +325,10 @@ class PaymentService extends AbstractService {
*/
public
function
check_api_keys
(
WP_REST_Request
$request
)
{
Settings
::
update_array
(
'vendor_mollie'
,
[
Settings
::
update_array
(
'vendor_mollie'
,
[
'connected'
=>
false
,
'recurring'
=>
false
'recurring'
=>
false
,
]
);
$mode
=
sanitize_text_field
(
$request
[
'apiMode'
]
);
...
...
@@ -342,25 +343,32 @@ class PaymentService extends AbstractService {
}
// Test the api key.
$result
=
$this
->
vendor
->
t
es
t
_api_connection
(
$api_key
);
$result
=
$this
->
vendor
->
refr
es
h
_api_connection
(
$api_key
);
if
(
$result
)
{
Settings
::
update_array
(
'vendor_mollie'
,
[
Settings
::
update_array
(
'vendor_mollie'
,
[
'mode'
=>
$mode
,
$mode
.
'_key'
=>
$api_key
,
'connected'
=>
1
,
'recurring'
=>
$this
->
vendor
->
get_payment_methods
()
->
count
>
0
??
0
'recurring'
=>
$this
->
vendor
->
get_payment_methods
()
->
count
>
0
??
0
,
]
);
wp_send_json_success
(
[
/* translators: %s: API mode */
sprintf
(
__
(
'%s API key connection was successful!'
,
'kudos-donations'
),
ucfirst
(
$mode
)
)
'message'
=>
sprintf
(
__
(
'%s API key connection was successful!'
,
'kudos-donations'
),
ucfirst
(
$mode
)
),
'setting'
=>
Settings
::
get_setting
(
'vendor_mollie'
),
]
);
}
else
{
wp_send_json_error
(
[
/* translators: %s: API mode */
sprintf
(
__
(
'Error connecting with Mollie, please check the %s API key and try again.'
,
'message'
=>
sprintf
(
__
(
'Error connecting with Mollie, please check the %s API key and try again.'
,
'kudos-donations'
),
ucfirst
(
$mode
)
)
ucfirst
(
$mode
)
),
]
);
}
}
...
...
app/Service/Vendor/AbstractVendor.php
View file @
1bd98e42
...
...
@@ -49,7 +49,7 @@ abstract class AbstractVendor extends AbstractService {
* @return bool
* @since 1.0.0
*/
abstract
public
function
t
es
t
_api_connection
(
string
$api_key
):
bool
;
abstract
public
function
refr
es
h
_api_connection
(
string
$api_key
):
bool
;
/**
* Gets specified payment
...
...
app/Service/Vendor/MollieVendor.php
View file @
1bd98e42
...
...
@@ -57,10 +57,10 @@ class MollieVendor extends AbstractVendor {
$this
->
mollie_api
=
new
MollieApiClient
();
$settings
=
Settings
::
get_setting
(
'vendor_mollie'
);
$settings
=
Settings
::
get_setting
(
'vendor_mollie'
);
$this
->
api_mode
=
$settings
[
'mode'
];
$this
->
api_key
=
isset
(
$settings
[
$this
->
api_mode
.
'_key'
])
?
$settings
[
$this
->
api_mode
.
'_key'
]
:
''
;
$this
->
api_key
=
isset
(
$settings
[
$this
->
api_mode
.
'_key'
]
)
?
$settings
[
$this
->
api_mode
.
'_key'
]
:
''
;
if
(
$this
->
api_key
)
{
try
{
...
...
@@ -128,6 +128,7 @@ class MollieVendor extends AbstractVendor {
}
catch
(
ApiException
$e
)
{
$this
->
logger
->
critical
(
$e
->
getMessage
()
);
return
false
;
}
...
...
@@ -141,7 +142,7 @@ class MollieVendor extends AbstractVendor {
* @return bool
* @since 1.0.0
*/
public
function
t
es
t
_api_connection
(
string
$api_key
):
bool
{
public
function
refr
es
h
_api_connection
(
string
$api_key
):
bool
{
if
(
!
$api_key
)
{
return
false
;
...
...
@@ -370,15 +371,15 @@ class MollieVendor extends AbstractVendor {
*
* @return BaseCollection|MethodCollection|null
*/
public
function
get_payment_methods
(
$sequenceType
=
'recurring'
)
{
public
function
get_payment_methods
(
$sequenceType
=
'recurring'
)
{
try
{
return
$this
->
mollie_api
->
methods
->
allActive
([
return
$this
->
mollie_api
->
methods
->
allActive
(
[
'sequenceType'
=>
$sequenceType
,
]);
]
);
}
catch
(
ApiException
$e
)
{
}
catch
(
ApiException
$e
)
{
$this
->
logger
->
critical
(
$e
->
getMessage
(),
[
'payment'
=>
$payment_array
]
);
return
null
;
...
...
src/js/Settings/Components/ButtonIcon.jsx
View file @
1bd98e42
...
...
@@ -69,12 +69,22 @@ const ButtonIcon = (props) => {
d
=
"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"
/>
</
svg
>
)
case
'
sync
'
:
return
(
<
svg
xmlns
=
"http://www.w3.org/2000/svg"
viewBox
=
"0 0 512 512"
>
<
path
fill
=
"currentColor"
d
=
"M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z"
/>
</
svg
>
)
}
}
return
(
<
Icon
size
=
"16"
className
=
{
props
.
className
}
icon
=
{
icon
()
}
/>
)
...
...
src/js/Settings/Components/Info.jsx
View file @
1bd98e42
const
{
Dashicon
}
=
wp
.
components
const
Info
=
(
props
)
=>
{
const
Info
=
({
level
=
"
info
"
,
children
})
=>
{
let
text
=
'
kd-text-gray-500
'
let
icon
=
'
info
'
switch
(
level
)
{
case
"
warning
"
:
text
=
'
kd-text-orange-700
'
icon
=
'
warning
'
break
;
}
return
(
<
div
className
=
"
kudos-admin-info kd-text-gray-500
kd-flex kd-items-center kd-justify-start
"
>
<
Dashicon
className
=
"kd-mr-1"
icon
=
{
props
.
icon
??
"
info
"
}
/
>
<
i
>
{
props
.
children
}<
/
i
>
<
div
className
=
{
"
kd-flex kd-items-center kd-justify-start
"
+
text
}
>
<
Dashicon
className
=
"kd-mr-1"
icon
=
{
icon
}
/>
<
i
>
{
children
}
</
i
>
</
div
>
)
...
...
src/js/Settings/Components/Panels/CampaignPanel.jsx
View file @
1bd98e42
...
...
@@ -10,6 +10,7 @@ const {
CardFooter
,
CheckboxControl
,
ClipboardButton
,
Disabled
,
RadioControl
,
TextControl
,
ToggleControl
...
...
@@ -23,6 +24,21 @@ const CampaignPanel = ({settings, campaign, removeCampaign, handleInputChange, a
setHasCopied
(
false
)
},
[
campaign
])
let
donation_type
=
<
RadioControl
selected
=
{
campaign
.
donation_type
||
'
both
'
}
disabled
=
{
settings
.
_kudos_vendor_mollie
.
recurring
?
null
:
true
}
help
=
{
__
(
'
The donation type of the form, set to "both" to allow donor to choose.
'
,
'
kudos-donations
'
)
}
options
=
{
[
{
label
:
__
(
'
One-off
'
,
'
kudos-donations
'
),
value
:
'
oneoff
'
},
{
label
:
__
(
'
Subscription
'
,
'
kudos-donations
'
),
value
:
'
recurring
'
},
{
label
:
__
(
'
Both
'
,
'
kudos-donations
'
),
value
:
'
both
'
},
]
}
onChange
=
{
(
value
)
=>
{
campaign
.
donation_type
=
value
handleInputChange
(
'
_kudos_campaigns
'
,
settings
.
_kudos_campaigns
)
}
}
/>
return
(
<
div
id
=
{
"
campaign-
"
+
campaign
.
id
}
>
<
SettingCard
title
=
{
__
(
'
General
'
,
'
kudos-donations
'
)
}
id
=
"campaignPanel"
settings
=
{
settings
}
campaign
=
{
campaign
}
handleInputChange
=
{
handleInputChange
}
>
...
...
@@ -111,19 +127,14 @@ const CampaignPanel = ({settings, campaign, removeCampaign, handleInputChange, a
<
SettingCard
title
=
{
__
(
'
Donation type
'
,
'
kudos-donations
'
)
}
>
<
RadioControl
selected
=
{
campaign
.
donation_type
||
'
both
'
}
help
=
{
__
(
'
The donation type of the form, set to "both" to allow donor to choose.
'
,
'
kudos-donations
'
)
}
options
=
{
[
{
label
:
__
(
'
One-off
'
,
'
kudos-donations
'
),
value
:
'
oneoff
'
},
{
label
:
__
(
'
Subscription
'
,
'
kudos-donations
'
),
value
:
'
recurring
'
},
{
label
:
__
(
'
Both
'
,
'
kudos-donations
'
),
value
:
'
both
'
},
]
}
onChange
=
{
(
value
)
=>
{
campaign
.
donation_type
=
value
handleInputChange
(
'
_kudos_campaigns
'
,
settings
.
_kudos_campaigns
)
}
}
/>
{
(
!
settings
.
_kudos_vendor_mollie
.
recurring
)
?
<
Disabled
>
{
donation_type
}
<
Info
level
=
"warning"
>
{
__
(
'
You need to enable SEPA Direct Debit or Credit card in your Mollie account to use supscription payments
'
,
'
kudos-donations
'
)
}
</
Info
>
</
Disabled
>
:
donation_type
}
</
SettingCard
>
...
...
src/js/Settings/Components/Panels/MollieApiModePanel.jsx
View file @
1bd98e42
import
{
Btn
}
from
"
../Btn
"
import
{
SettingCard
}
from
"
../SettingCard
"
import
{
ButtonIcon
}
from
"
../ButtonIcon
"
const
{
__
}
=
wp
.
i18n
const
{
BaseControl
,
ButtonGroup
,
PanelRow
}
=
wp
.
components
const
{
BaseControl
,
Button
,
ButtonGroup
,
PanelRow
}
=
wp
.
components
const
{
useState
}
=
wp
.
element
const
MollieApiModePanel
=
(
props
)
=>
{
const
[
isBusy
,
setIsBusy
]
=
useState
(
false
)
const
vendorMollie
=
props
.
settings
.
_kudos_vendor_mollie
const
selected
=
vendorMollie
[
'
mode
'
]
const
handleChange
=
(
id
,
value
)
=>
{
props
.
mollieChanged
()
props
.
handleInputChange
(
id
,
value
)
}
const
vendorMollie
=
props
.
settings
.
_kudos_vendor_mollie
const
selected
=
vendorMollie
[
'
mode
'
]
const
refresh
=
()
=>
{
setIsBusy
(
true
)
props
.
checkApiKey
(()
=>
setIsBusy
(
false
))
}
return
(
<
SettingCard
title
=
{
__
(
'
API mode
'
,
'
kudos-donations
'
)
}
>
...
...
@@ -53,6 +62,18 @@ const MollieApiModePanel = (props) => {
</
PanelRow
>
</
BaseControl
>
<
BaseControl
help
=
{
__
(
"
Use this if you have made changes in Mollie such as enabling SEPA Direct Debit or Credit Card.
"
,
'
kudos-donations
'
)
}
>
<
Button
isLink
icon
=
{
(<
ButtonIcon
icon
=
'sync'
className
=
{
(
isBusy
?
'
kd-animate-spin
'
:
''
)
}
/>)
}
onClick
=
{
()
=>
refresh
()
}
>
{
__
(
'
Refresh API
'
,
'
kudos-donations
'
)
}
</
Button
>
</
BaseControl
>
</
SettingCard
>
)
}
...
...
src/js/Settings/Components/Tabs/MollieTab.jsx
View file @
1bd98e42
...
...
@@ -10,6 +10,7 @@ const MollieTab = (props) => {
<
MollieApiModePanel
settings
=
{
props
.
settings
}
mollieChanged
=
{
props
.
mollieChanged
}
checkApiKey
=
{
props
.
checkApiKey
}
handleInputChange
=
{
props
.
handleInputChange
}
/>
<
CardDivider
/>
...
...
src/js/Settings/KudosAdmin.jsx
View file @
1bd98e42
...
...
@@ -66,12 +66,6 @@ class KudosAdmin extends Component {
mollieChanged
()
{
this
.
setState
({
isMollieEdited
:
true
,
settings
:
{
_kudos_vendor_mollie
:
{
...
this
.
state
.
settings
.
_kudos_vendor_mollie
,
connected
:
false
}
},
})
}
...
...
@@ -79,7 +73,8 @@ class KudosAdmin extends Component {
updateQueryParameter
(
'
tab_name
'
,
tab
)
}
checkApiKey
()
{
checkApiKey
(
callback
)
{
this
.
setState
({
checkingApi
:
true
,
isAPISaving
:
true
,
...
...
@@ -99,17 +94,24 @@ class KudosAdmin extends Component {
},
})
.
then
((
response
)
=>
{
this
.
showNotice
(
response
.
data
.
data
)
this
.
showNotice
(
response
.
data
.
data
.
message
)
this
.
setState
({
checkingApi
:
false
,
isAPISaving
:
false
,
})
if
(
response
.
data
.
success
)
{
this
.
setState
({
settings
:
{
...
this
.
state
.
settings
,
_kudos_vendor_mollie
:
{
...
this
.
state
.
settings
.
_kudos_vendor_mollie
,
connected
:
response
.
data
.
success
...
response
.
data
.
data
.
setting
}
}
},
checkingApi
:
false
,
isAPISaving
:
false
,
})
}
if
(
typeof
callback
===
"
function
"
)
{
callback
()
}
})
}
...
...
@@ -249,6 +251,8 @@ class KudosAdmin extends Component {
<
MollieTab
settings
=
{
this
.
state
.
settings
}
mollieChanged
=
{
this
.
mollieChanged
}
showNotice
=
{
this
.
showNotice
}
checkApiKey
=
{
this
.
checkApiKey
}
handleInputChange
=
{
this
.
handleInputChange
}
/>
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment