Merge add/wc-pay to master, enabled for development only (https://github.com/woocommerce/woocommerce-admin/pull/4022)

* Add feature flag for wcpay (https://github.com/woocommerce/woocommerce-admin/pull/3958)

* Add card to payments task for WooCommerce Payments (https://github.com/woocommerce/woocommerce-admin/pull/3978)

* Add card to payments task for WooCommerce Payments

* Add missing plugin and settings PHP constants for woocommerce payments

* Add endpoint to return url to kick off wcpay

* Fix incorrect option name

* I can haz purple with white text, plz

* Linkify TOS, settings

* Recommend wcpay when visible; move wcpay to list top

* Test for wcpay feature flag

* Improved handling of feature flag

* If the user is an agency, include wcpay docs link on card

* Reverse agency logic, LOL

* Camel case fillRule etc

* Turn off wcpay for core and plugin for now
This commit is contained in:
Allen Snook 2020-03-27 16:24:32 -07:00 committed by GitHub
parent 85f5a7c927
commit 078de3e9c0
11 changed files with 351 additions and 11 deletions

View File

@ -437,6 +437,20 @@
}
}
.woocommerce-task-payment-wcpay.woocommerce-task-payment-not-configured {
background-color: $studio-woocommerce-purple-60;
.woocommerce-task-payment__title {
color: $studio-white;
}
.woocommerce-task-payment__content {
color: $studio-white;
a {
color: $studio-white;
}
}
}
.woocommerce-task-appearance {
.woocommerce-image-upload {
margin-bottom: $gap-smallest;

View File

@ -0,0 +1,28 @@
export default () => (
<svg
width="100"
height="64"
viewBox="-10 0 120 64"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.78073 0.5H91.1787C96.3299 0.5 100.5 4.77335 100.5 10.0522V41.8929C100.5 47.1717 96.3299 51.4451 91.1787 51.4451H61.9883L65.9948 61.5L48.3742 51.4451H9.82161C4.67036 51.4451 0.500298 47.1717 0.500298 41.8929V10.0522C0.459415 4.81524 4.62947 0.5 9.78073 0.5Z"
fill="#7F54B3"
/>
<path
d="M5.48791 9.1725C6.06028 8.37648 6.91882 7.95752 8.06354 7.87373C10.1486 7.70615 11.3342 8.71165 11.6204 10.8902C12.8877 19.6464 14.2778 27.0619 15.7495 33.1368L24.7029 15.6663C25.5206 14.0743 26.5426 13.2364 27.7691 13.1526C29.568 13.0269 30.6718 14.2 31.1215 16.6718C32.1436 22.2439 33.4519 26.9781 35.0054 31.0001C36.0684 20.3586 37.8672 12.6917 40.402 7.95753C41.0152 6.78445 41.9146 6.19791 43.1002 6.11412C44.0405 6.03033 44.8991 6.3236 45.6759 6.95203C46.4526 7.58047 46.8615 8.37648 46.9432 9.34008C46.9841 10.0942 46.8615 10.7226 46.5344 11.3511C44.94 14.3676 43.6317 19.4369 42.5688 26.4754C41.5467 33.3044 41.1787 38.6251 41.424 42.4376C41.5058 43.485 41.3423 44.4067 40.9334 45.2027C40.4428 46.1244 39.707 46.6272 38.7666 46.711C37.7037 46.7948 36.5998 46.292 35.5369 45.1608C31.7348 41.1807 28.7094 35.2316 26.5018 27.3133C23.8444 32.6759 21.882 36.6979 20.6146 39.3792C18.2025 44.1134 16.1584 46.5434 14.4413 46.6691C13.3374 46.7529 12.3971 45.7893 11.5795 43.7783C9.49445 38.2899 7.24589 27.6904 4.83379 11.9795C4.71114 10.8902 4.91555 9.92662 5.48791 9.1725Z"
fill="white"
/>
<path
d="M93.3864 15.7499C91.9146 13.1105 89.7478 11.5185 86.8451 10.89C86.0683 10.7225 85.3324 10.6387 84.6374 10.6387C80.7127 10.6387 77.5238 12.7335 75.0299 16.923C72.904 20.4841 71.8411 24.4223 71.8411 28.7376C71.8411 31.9635 72.4952 34.7286 73.8034 37.0329C75.2752 39.6723 77.442 41.2644 80.3447 41.8928C81.1215 42.0604 81.8574 42.1442 82.5524 42.1442C86.518 42.1442 89.7069 40.0494 92.1599 35.8598C94.2858 32.2568 95.3488 28.3186 95.3488 24.0034C95.3488 20.7355 94.6946 18.0123 93.3864 15.7499ZM88.2351 27.355C87.6628 30.1201 86.6407 32.173 85.128 33.5556C83.9424 34.6449 82.8386 35.1057 81.8165 34.8962C80.8353 34.6868 80.0177 33.8069 79.4044 32.173C78.9138 30.8742 78.6685 29.5755 78.6685 28.3605C78.6685 27.3131 78.7503 26.2657 78.9547 25.3021C79.3226 23.5844 80.0177 21.9086 81.1215 20.3166C82.4706 18.2637 83.9015 17.4258 85.3733 17.719C86.3545 17.9285 87.1722 18.8083 87.7854 20.4422C88.276 21.741 88.5213 23.0398 88.5213 24.2547C88.5213 25.344 88.3987 26.3914 88.2351 27.355Z"
fill="white"
/>
<path
d="M67.7528 15.7499C66.281 13.1105 64.0734 11.5185 61.2116 10.89C60.4348 10.7225 59.6989 10.6387 59.0039 10.6387C55.0791 10.6387 51.8903 12.7335 49.3964 16.923C47.2705 20.4841 46.2075 24.4223 46.2075 28.7376C46.2075 31.9635 46.8616 34.7286 48.1699 37.0329C49.6417 39.6723 51.8085 41.2644 54.7112 41.8928C55.488 42.0604 56.2238 42.1442 56.9189 42.1442C60.8845 42.1442 64.0734 40.0494 66.5263 35.8598C68.6523 32.2568 69.7152 28.3186 69.7152 24.0034C69.7152 20.7355 69.0611 18.0123 67.7528 15.7499ZM62.6016 27.355C62.0292 30.1201 61.0071 32.173 59.4945 33.5556C58.3089 34.6449 57.205 35.1057 56.183 34.8962C55.2018 34.6868 54.3841 33.8069 53.7709 32.173C53.2803 30.8742 53.035 29.5755 53.035 28.3605C53.035 27.3131 53.1167 26.2657 53.3212 25.3021C53.6891 23.5844 54.3841 21.9086 55.4879 20.3166C56.8371 18.2637 58.268 17.4258 59.7398 17.719C60.721 17.9285 61.5386 18.8083 62.1519 20.4422C62.6425 21.741 62.8878 23.0398 62.8878 24.2547C62.8878 25.344 62.806 26.3914 62.6016 27.355Z"
fill="white"
/>
</svg>
);

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import classnames from 'classnames';
import { cloneElement, Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { Button, FormToggle } from '@wordpress/components';
@ -41,6 +42,12 @@ class Payments extends Component {
};
this.recommendedMethod = 'stripe';
methods.forEach( ( method ) => {
if ( method.key === 'wcpay' && method.visible ) {
this.recommendedMethod = 'wcpay';
}
} );
this.completeTask = this.completeTask.bind( this );
this.markConfigured = this.markConfigured.bind( this );
this.skipTask = this.skipTask.bind( this );
@ -233,11 +240,16 @@ class Payments extends Component {
return null;
}
const classes = classnames(
'woocommerce-task-payment',
'is-narrow',
! isConfigured &&
'woocommerce-task-payment-not-configured',
'woocommerce-task-payment-' + key
);
return (
<Card
key={ key }
className="woocommerce-task-payment is-narrow"
>
<Card key={ key } className={ classes }>
<div className="woocommerce-task-payment__before">
{ key === this.recommendedMethod &&
! isConfigured && (
@ -332,6 +344,7 @@ export default compose(
const profileItems = getProfileItems();
const options = getOptions( [
'woocommerce_default_country',
'woocommerce_woocommerce_payments_settings',
'woocommerce_stripe_settings',
'woocommerce_ppec_paypal_settings',
'woocommerce_payfast_settings',

View File

@ -5,6 +5,7 @@
import { __ } from '@wordpress/i18n';
import { Fragment } from '@wordpress/element';
import { filter, some } from 'lodash';
import interpolateComponents from 'interpolate-components';
/**
* WooCommerce dependencies
@ -13,6 +14,7 @@ import {
getSetting,
WC_ASSET_URL as wcAssetUrl,
} from '@woocommerce/wc-admin-settings';
import { Link } from '@woocommerce/components';
/**
* Internal dependencies
@ -22,6 +24,8 @@ import BacsIcon from './images/bacs';
import CodIcon from './images/cod';
import Stripe from './stripe';
import Square from './square';
import WCPay from './wcpay';
import WCPayIcon from './images/wcpay';
import PayPal from './paypal';
import Klarna from './klarna';
import PayFast from './payfast';
@ -41,7 +45,90 @@ export function getPaymentMethods( {
slug: 'cbd-other-hemp-derived-products',
} ) || false;
const methods = [
const methods = [];
if ( window.wcAdminFeatures.wcpay ) {
const tosLink = (
<Link
href={ 'https://wordpress.com/tos/' }
target="_blank"
type="external"
/>
);
const tosPrompt = interpolateComponents( {
mixedString: __(
'By clicking "Set up," you agree to the {{link}}Terms of Service{{/link}}',
'woocommerce-admin'
),
components: {
link: tosLink,
},
} );
const wcPayDocLink = (
<Link
href={ 'https://docs.woocommerce.com/document/payments/' }
target="_blank"
type="external"
/>
);
const wcPayDocPrompt = interpolateComponents( {
mixedString: __(
'Setting up a store for a client? {{link}}Start here{{/link}}',
'woocommerce-admin'
),
components: {
link: wcPayDocLink,
},
} );
const wcPaySettingsLink = (
<Link
href={
'/wp-admin/admin.php?page=wc-settings&tab=checkout&section=woocommerce_payments'
}
>
{ __( 'Settings', 'woocommerce-admin' ) }
</Link>
);
// @todo This should check actual connection information.
const wcPayIsConfigured = activePlugins.includes(
'woocommerce-payments'
);
methods.push( {
key: 'wcpay',
title: __( 'WooCommerce Payments', 'woocommerce-admin' ),
content: (
<Fragment>
{ __(
'Accept credit card payments the easy way! No setup fees. No ' +
'monthly fees. Just 2.9% + $0.30 per transaction ' +
'on U.S. issued cards. ',
'woocommerce-admin'
) }
{ wcPayIsConfigured && wcPaySettingsLink }
{ ! wcPayIsConfigured && <p>{ tosPrompt }</p> }
{ profileItems.setup_client && <p>{ wcPayDocPrompt }</p> }
</Fragment>
),
before: <WCPayIcon />,
visible: [ 'US' ].includes( countryCode ) && ! hasCbdIndustry,
plugins: [ 'woocommerce-payments' ],
container: <WCPay />,
isConfigured: wcPayIsConfigured,
isEnabled:
options.woocommerce_woocommerce_payments_settings &&
options.woocommerce_woocommerce_payments_settings.enabled ===
'yes',
optionName: 'woocommerce_woocommerce_payments_settings',
} );
}
methods.push(
{
key: 'stripe',
title: __(
@ -250,8 +337,8 @@ export function getPaymentMethods( {
options.woocommerce_bacs_settings &&
options.woocommerce_bacs_settings.enabled === 'yes',
optionName: 'woocommerce_bacs_settings',
},
];
}
);
return filter( methods, ( method ) => method.visible );
}

View File

@ -0,0 +1,153 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component, Fragment } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
import { Button } from '@wordpress/components';
import { withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
/**
* WooCommerce dependencies
*/
import { getQuery } from '@woocommerce/navigation';
import { WC_ADMIN_NAMESPACE } from 'wc-api/constants';
import withSelect from 'wc-api/with-select';
import { Stepper } from '@woocommerce/components';
class WCPay extends Component {
constructor( props ) {
super( props );
this.state = {
isPending: false,
};
this.connect = this.connect.bind( this );
}
componentDidMount() {
const { createNotice, markConfigured } = this.props;
const query = getQuery();
// Handle redirect back from WCPay on-boarding
if ( query[ 'wcpay-connect' ] ) {
if ( query[ 'wcpay-connect' ] === '1' ) {
createNotice(
'success',
__(
'WooCommerce Payments connected successfully.',
'woocommerce-admin'
)
);
markConfigured( 'wcpay' );
}
}
}
async connect() {
const { createNotice, options, updateOptions } = this.props;
this.setState( { isPending: true } );
updateOptions( {
woocommerce_woocommerce_payments_settings: {
...options.woocommerce_woocommerce_payments_settings,
enabled: 'yes',
},
} );
const errorMessage = __(
'There was an error connecting to WooCommerce Payments. Please try again or skip to connect later in store settings.',
'woocommerce-admin'
);
try {
// Fetch the business verification (connect) URL (Stripe KYC) from the backend
const result = await apiFetch( {
path: WC_ADMIN_NAMESPACE + '/onboarding/plugins/connect-wcpay',
method: 'POST',
} );
if ( ! result || ! result.connectUrl ) {
this.setState( { isPending: false } );
createNotice( 'error', errorMessage );
return;
}
this.setState( { isPending: true } );
window.location = result.connectUrl;
} catch ( error ) {
this.setState( { isPending: false } );
createNotice( 'error', errorMessage );
}
}
render() {
const { installStep } = this.props;
const { isPending } = this.state;
return (
<Stepper
isVertical
isPending={ ! installStep.isComplete || isPending }
currentStep={ installStep.isComplete ? 'connect' : 'install' }
steps={ [
installStep,
{
key: 'connect',
label: __(
'Verify business details',
'woocommerce-admin'
),
description: __(
'Verify your business details with our payment partner, Stripe.',
'woocommerce-admin'
),
content: (
<Fragment>
<Button
isPrimary
isDefault
isBusy={ isPending }
onClick={ this.connect }
>
{ __(
'Verify details',
'woocommerce-admin'
) }
</Button>
</Fragment>
),
},
] }
/>
);
}
}
export default compose(
withSelect( ( select ) => {
const { getOptions, isGetOptionsRequesting } = select( 'wc-api' );
const options = getOptions( [
'woocommerce_woocommerce_payments_settings',
] );
const optionsIsRequesting = Boolean(
isGetOptionsRequesting( [
'woocommerce_woocommerce_payments_settings',
] )
);
return {
options,
optionsIsRequesting,
};
} ),
withDispatch( ( dispatch ) => {
const { createNotice } = dispatch( 'core/notices' );
const { updateOptions } = dispatch( 'wc-api' );
return {
createNotice,
updateOptions,
};
} )
)( WCPay );

View File

@ -36,6 +36,10 @@ export const pluginNames = {
'WooCommerce PayFast',
'woocommerce-admin'
),
'woocommerce-payments': __(
'WooCommerce Payments',
'woocommerce-admin'
),
'woocommerce-services': __( 'WooCommerce Services', 'woocommerce-admin' ),
'woocommerce-shipstation-integration': __(
'WooCommerce ShipStation Gateway',

View File

@ -6,7 +6,8 @@
"analytics-dashboard/customizable": true,
"devdocs": false,
"onboarding": true,
"shipping-label-banner": true,
"store-alerts": true,
"shipping-label-banner": true
"wcpay": false
}
}

View File

@ -6,7 +6,8 @@
"analytics-dashboard/customizable": true,
"devdocs": true,
"onboarding": true,
"shipping-label-banner": true,
"store-alerts": true,
"shipping-label-banner": true
"wcpay": true
}
}

View File

@ -6,7 +6,8 @@
"analytics-dashboard/customizable": true,
"devdocs": false,
"onboarding": true,
"shipping-label-banner": true,
"store-alerts": true,
"shipping-label-banner": true
"wcpay": false
}
}

View File

@ -129,6 +129,19 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
)
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/connect-wcpay',
array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( $this, 'connect_wcpay' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
),
'schema' => array( $this, 'get_connect_schema' ),
)
);
register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/connect-square',
@ -497,7 +510,7 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
}
if ( $has_cbd_industry ) {
$url = 'https://squareup.com/t/f_partnerships/d_referrals/p_woocommerce/c_general/o_none/l_us/dt_alldevice/pr_payments/?route=/solutions/cbd';
$url = 'https://squareup.com/t/f_partnerships/d_referrals/p_woocommerce/c_general/o_none/l_us/dt_alldevice/pr_payments/?route=/solutions/cbd';
} else {
$url = \WooCommerce\Square\Handlers\Connection::CONNECT_URL_PRODUCTION;
}
@ -531,6 +544,29 @@ class OnboardingPlugins extends \WC_REST_Data_Controller {
) );
}
/**
* Returns a URL that can be used to by WCPay to verify business details with Stripe.
*
* @return WP_Error|array Connect URL.
*/
public function connect_wcpay() {
if ( ! class_exists( 'WC_Payments_Account' ) ) {
return new WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error communicating with the WooCommerce Payments plugin.', 'woocommerce-admin' ), 500 );
}
$connect_url = add_query_arg(
array(
'wcpay-connect' => 'WCADMIN_PAYMENT_TASK',
'_wpnonce' => wp_create_nonce( 'wcpay-connect' ),
),
admin_url()
);
return( array(
'connectUrl' => $connect_url,
) );
}
/**
* Get the schema, conforming to JSON Schema.
*

View File

@ -509,6 +509,7 @@ class Onboarding {
$options[] = 'woocommerce_cod_settings';
$options[] = 'woocommerce_bacs_settings';
$options[] = 'woocommerce_bacs_accounts';
$options[] = 'woocommerce_woocommerce_payments_settings';
return $options;
}
@ -607,6 +608,7 @@ class Onboarding {
'woocommerce-square' => 'woocommerce-square/woocommerce-square.php',
'woocommerce-shipstation-integration' => 'woocommerce-shipstation-integration/woocommerce-shipstation.php',
'woocommerce-payfast-gateway' => 'woocommerce-payfast-gateway/gateway-payfast.php',
'woocommerce-payments' => 'woocommerce-payments/woocommerce-payments.php',
)
);
}