2020-03-26 11:11:46 +00:00
/ * *
* External dependencies
* /
import { useEffect , useState , useRef , useCallback } from '@wordpress/element' ;
import { _ _ , sprintf } from '@wordpress/i18n' ;
2020-04-15 00:05:01 +00:00
import {
useEditorContext ,
usePaymentMethodDataContext ,
} from '@woocommerce/base-context' ;
2020-03-26 11:11:46 +00:00
import RadioControl from '@woocommerce/base-components/radio-control' ;
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 (
2020-09-26 19:38:17 +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 ) ;
setPaymentStatus ( ) . success ( {
payment _method : method . gateway ,
[ 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 (
2020-09-26 19:38:17 +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 ) ;
setPaymentStatus ( ) . success ( {
payment _method : method . gateway ,
[ 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
} ;
} ;
const SavedPaymentMethodOptions = ( { onSelect } ) => {
2020-04-15 00:05:01 +00:00
const { isEditor } = useEditorContext ( ) ;
2020-03-26 11:11:46 +00:00
const {
setPaymentStatus ,
customerPaymentMethods ,
2020-05-11 13:29:57 +00:00
setActivePaymentMethod ,
2020-03-26 11:11:46 +00:00
} = usePaymentMethodDataContext ( ) ;
2020-05-10 23:41:10 +00:00
const [ selectedToken , setSelectedToken ] = useState ( '' ) ;
2020-09-18 10:27:54 +00:00
const standardMethods = getPaymentMethods ( ) ;
2020-03-26 11:11:46 +00:00
/ * *
* @ type { Object } Options
* @ property { Array } current The current options on the type .
* /
const currentOptions = useRef ( [ ] ) ;
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 method =
standardMethods [ paymentMethod . method . gateway ] ;
if ( ! method ? . supports ? . savePaymentInfo ) {
return null ;
}
const option =
type === 'cc' || type === 'echeck'
? getCcOrEcheckPaymentMethodOption (
paymentMethod ,
setActivePaymentMethod ,
setPaymentStatus
)
: getDefaultPaymentMethodOptions (
paymentMethod ,
setActivePaymentMethod ,
setPaymentStatus
) ;
if ( paymentMethod . is _default && selectedToken === '' ) {
setSelectedToken ( paymentMethod . tokenId + '' ) ;
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 ,
selectedToken ,
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
2020-03-26 11:11:46 +00:00
const updateToken = useCallback (
( token ) => {
2020-05-11 13:29:57 +00:00
if ( token === '0' ) {
2020-03-26 11:11:46 +00:00
setPaymentStatus ( ) . started ( ) ;
}
2020-05-10 23:41:10 +00:00
setSelectedToken ( token ) ;
onSelect ( token ) ;
2020-03-26 11:11:46 +00:00
} ,
2020-05-11 13:29:57 +00:00
[ setSelectedToken , setPaymentStatus , onSelect ]
2020-03-26 11:11:46 +00:00
) ;
useEffect ( ( ) => {
if ( selectedToken && currentOptions . current . length > 0 ) {
updateToken ( selectedToken ) ;
}
} , [ selectedToken , updateToken ] ) ;
2020-04-15 00:05:01 +00:00
// In the editor, show `Use a new payment method` option as selected.
2020-05-10 23:41:10 +00:00
const selectedOption = isEditor ? '0' : selectedToken + '' ;
2020-09-18 10:27:54 +00:00
const newPaymentMethodOption = {
value : '0' ,
label : _ _ ( 'Use a new payment method' , 'woo-gutenberg-product-blocks' ) ,
name : ` wc-saved-payment-method-token-new ` ,
} ;
2020-03-26 11:11:46 +00:00
return currentOptions . current . length > 0 ? (
< RadioControl
2020-05-11 13:29:57 +00:00
id = { 'wc-payment-method-saved-tokens' }
2020-04-15 00:05:01 +00:00
selected = { selectedOption }
2020-03-26 11:11:46 +00:00
onChange = { updateToken }
2020-09-18 10:27:54 +00:00
options = { [ ... currentOptions . current , newPaymentMethodOption ] }
2020-03-26 11:11:46 +00:00
/ >
) : null ;
} ;
export default SavedPaymentMethodOptions ;