2020-03-26 11:11:46 +00:00
/ * *
* External dependencies
* /
2021-03-15 08:50:49 +00:00
import {
useEffect ,
useRef ,
useCallback ,
cloneElement ,
} from '@wordpress/element' ;
2020-03-26 11:11:46 +00:00
import { _ _ , sprintf } from '@wordpress/i18n' ;
2021-02-02 04:51:47 +00:00
import { usePaymentMethodDataContext } from '@woocommerce/base-context' ;
2020-03-26 11:11:46 +00:00
import RadioControl from '@woocommerce/base-components/radio-control' ;
2021-03-15 08:50:49 +00:00
import {
usePaymentMethodInterface ,
usePaymentMethods ,
2021-04-08 12:31:12 +00:00
} from '@woocommerce/base-context/hooks' ;
2020-09-18 10:27:54 +00:00
import { getPaymentMethods } from '@woocommerce/blocks-registry' ;
2020-03-26 11:11:46 +00:00
2020-05-11 13:29:57 +00:00
/ * *
* @ typedef { import ( '@woocommerce/type-defs/contexts' ) . CustomerPaymentMethod } CustomerPaymentMethod
* @ typedef { import ( '@woocommerce/type-defs/contexts' ) . PaymentStatusDispatch } PaymentStatusDispatch
* /
2020-03-26 11:11:46 +00:00
/ * *
* Returns the option object for a cc or echeck saved payment method token .
*
* @ param { CustomerPaymentMethod } savedPaymentMethod
2020-05-11 13:29:57 +00:00
* @ param { function ( string ) : void } setActivePaymentMethod
* @ param { PaymentStatusDispatch } setPaymentStatus
2020-03-26 11:11:46 +00:00
* @ return { Object } An option objects to use for RadioControl .
* /
2020-05-11 13:29:57 +00:00
const getCcOrEcheckPaymentMethodOption = (
{ method , expires , tokenId } ,
setActivePaymentMethod ,
setPaymentStatus
) => {
2020-03-26 11:11:46 +00:00
return {
2020-05-10 23:41:10 +00:00
value : tokenId + '' ,
2020-03-26 11:11:46 +00:00
label : sprintf (
2021-02-19 11:58:44 +00:00
/* translators: %1$s is referring to the payment method brand, %2$s is referring to the last 4 digits of the payment card, %3$s is referring to the expiry date. */
2020-03-26 11:11:46 +00:00
_ _ (
'%1$s ending in %2$s (expires %3$s)' ,
'woo-gutenberg-product-blocks'
) ,
method . brand ,
method . last4 ,
expires
) ,
name : ` wc-saved-payment-method-token- ${ tokenId } ` ,
2020-05-11 13:29:57 +00:00
onChange : ( token ) => {
const savedTokenKey = ` wc- ${ method . gateway } -payment-token ` ;
setActivePaymentMethod ( method . gateway ) ;
2021-03-22 14:02:36 +00:00
setPaymentStatus ( ) . started ( {
2020-05-11 13:29:57 +00:00
payment _method : method . gateway ,
2021-01-05 09:51:23 +00:00
[ savedTokenKey ] : token + '' ,
2020-06-07 20:47:16 +00:00
isSavedToken : true ,
2020-05-11 13:29:57 +00:00
} ) ;
} ,
2020-03-26 11:11:46 +00:00
} ;
} ;
/ * *
* Returns the option object for any non specific saved payment method .
*
* @ param { CustomerPaymentMethod } savedPaymentMethod
2020-05-11 13:29:57 +00:00
* @ param { function ( string ) : void } setActivePaymentMethod
* @ param { PaymentStatusDispatch } setPaymentStatus
2020-03-26 11:11:46 +00:00
*
* @ return { Object } An option objects to use for RadioControl .
* /
2020-05-11 13:29:57 +00:00
const getDefaultPaymentMethodOptions = (
{ method , tokenId } ,
setActivePaymentMethod ,
setPaymentStatus
) => {
2020-03-26 11:11:46 +00:00
return {
2020-05-10 23:41:10 +00:00
value : tokenId + '' ,
2020-03-26 11:11:46 +00:00
label : sprintf (
2021-02-19 11:58:44 +00:00
/* translators: %s is the name of the payment method gateway. */
2020-03-26 11:11:46 +00:00
_ _ ( 'Saved token for %s' , 'woo-gutenberg-products-block' ) ,
method . gateway
) ,
name : ` wc-saved-payment-method-token- ${ tokenId } ` ,
2020-05-11 13:29:57 +00:00
onChange : ( token ) => {
const savedTokenKey = ` wc- ${ method . gateway } -payment-token ` ;
setActivePaymentMethod ( method . gateway ) ;
2021-03-22 14:02:36 +00:00
setPaymentStatus ( ) . started ( {
2020-05-11 13:29:57 +00:00
payment _method : method . gateway ,
2021-01-05 09:51:23 +00:00
[ savedTokenKey ] : token + '' ,
2020-06-07 20:47:16 +00:00
isSavedToken : true ,
2020-05-11 13:29:57 +00:00
} ) ;
} ,
2020-03-26 11:11:46 +00:00
} ;
} ;
2021-02-02 04:51:47 +00:00
const SavedPaymentMethodOptions = ( ) => {
2020-03-26 11:11:46 +00:00
const {
setPaymentStatus ,
customerPaymentMethods ,
2021-02-02 04:51:47 +00:00
activePaymentMethod ,
2020-05-11 13:29:57 +00:00
setActivePaymentMethod ,
2021-02-02 04:51:47 +00:00
activeSavedToken ,
setActiveSavedToken ,
2020-03-26 11:11:46 +00:00
} = usePaymentMethodDataContext ( ) ;
2020-09-18 10:27:54 +00:00
const standardMethods = getPaymentMethods ( ) ;
2021-03-15 08:50:49 +00:00
const { paymentMethods } = usePaymentMethods ( ) ;
const paymentMethodInterface = usePaymentMethodInterface ( ) ;
2020-03-26 11:11:46 +00:00
/ * *
* @ type { Object } Options
* @ property { Array } current The current options on the type .
* /
const currentOptions = useRef ( [ ] ) ;
2020-10-12 12:43:52 +00:00
const updateToken = useCallback (
( token ) => {
2021-02-02 04:51:47 +00:00
setActiveSavedToken ( token ) ;
2020-10-12 12:43:52 +00:00
} ,
2021-03-22 14:02:36 +00:00
[ setActiveSavedToken ]
2020-10-12 12:43:52 +00:00
) ;
2020-03-26 11:11:46 +00:00
useEffect ( ( ) => {
2020-09-18 10:27:54 +00:00
const types = Object . keys ( customerPaymentMethods ) ;
const options = types
. flatMap ( ( type ) => {
const typeMethods = customerPaymentMethods [ type ] ;
return typeMethods . map ( ( paymentMethod ) => {
const option =
type === 'cc' || type === 'echeck'
? getCcOrEcheckPaymentMethodOption (
paymentMethod ,
setActivePaymentMethod ,
setPaymentStatus
)
: getDefaultPaymentMethodOptions (
paymentMethod ,
setActivePaymentMethod ,
setPaymentStatus
) ;
2021-02-02 04:51:47 +00:00
if (
! activePaymentMethod &&
paymentMethod . is _default &&
activeSavedToken === ''
) {
2020-10-12 12:43:52 +00:00
updateToken ( paymentMethod . tokenId + '' ) ;
2020-09-18 10:27:54 +00:00
option . onChange ( paymentMethod . tokenId ) ;
}
return option ;
2020-08-11 13:43:03 +00:00
} ) ;
2020-09-18 10:27:54 +00:00
} )
. filter ( Boolean ) ;
currentOptions . current = options ;
2020-05-11 13:29:57 +00:00
} , [
customerPaymentMethods ,
2020-10-12 12:43:52 +00:00
updateToken ,
2021-02-02 04:51:47 +00:00
activeSavedToken ,
activePaymentMethod ,
2020-05-11 13:29:57 +00:00
setActivePaymentMethod ,
setPaymentStatus ,
2020-09-18 10:27:54 +00:00
standardMethods ,
2020-05-11 13:29:57 +00:00
] ) ;
2020-09-18 10:27:54 +00:00
2021-03-15 08:50:49 +00:00
const savedPaymentMethodHandler =
! ! activeSavedToken &&
paymentMethods [ activePaymentMethod ] &&
paymentMethods [ activePaymentMethod ] ? . savedTokenComponent
? cloneElement (
paymentMethods [ activePaymentMethod ] ? . savedTokenComponent ,
{ token : activeSavedToken , ... paymentMethodInterface }
)
: null ;
2020-03-26 11:11:46 +00:00
return currentOptions . current . length > 0 ? (
2021-03-15 08:50:49 +00:00
< >
< RadioControl
id = { 'wc-payment-method-saved-tokens' }
selected = { activeSavedToken }
onChange = { updateToken }
options = { currentOptions . current }
/ >
{ savedPaymentMethodHandler }
< / >
2020-03-26 11:11:46 +00:00
) : null ;
} ;
export default SavedPaymentMethodOptions ;