Skip to content

Commit

Permalink
Merge pull request #468 from Automattic/update/change-cancel-purchase…
Browse files Browse the repository at this point in the history
…-flow

Purchases: Change cancel flow for non-refundable purchases

Fixes #276.
  • Loading branch information
gziolo committed Nov 23, 2015
2 parents 6f6c64e + 2c6cc46 commit 5dd3a82
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 68 deletions.
1 change: 1 addition & 0 deletions client/lib/purchases/assembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function createPurchasesArray( dataTransferObject ) {
active: Boolean( purchase.active ),
amount: Number( purchase.amount ),
attachedToPurchaseId: Number( purchase.attached_to_purchase_id ),
canDisableAutoRenew: Boolean( purchase.can_disable_auto_renew ),
currencyCode: purchase.currency_code,
currencySymbol: purchase.currency_symbol,
domain: purchase.domain,
Expand Down
36 changes: 27 additions & 9 deletions client/lib/purchases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ function getPurchasesBySite( purchases ) {
}, [] );
}

function getName( purchase ) {
if ( isDomainRegistration( purchase ) ) {
return purchase.meta;
}

return purchase.productName;
}

function getSubscriptionEndDate( purchase ) {
return purchase.expiryMoment.format( 'LL' );
}

function hasPaymentMethod( purchase ) {
return isPaidWithPaypal( purchase ) || isPaidWithCreditCard( purchase );
}
Expand All @@ -44,6 +56,18 @@ function hasPrivateRegistration( purchase ) {
return purchase.hasPrivateRegistration;
}

function isCancelable( purchase ) {
if ( isRefundable( purchase ) ) {
return true;
}

if ( isIncludedWithPlan( purchase ) ) {
return false;
}

return purchase.canDisableAutoRenew;
}

function isExpired( purchase ) {
return 'expired' === purchase.expiryStatus;
}
Expand Down Expand Up @@ -133,14 +157,6 @@ function purchaseType( purchase ) {
return null;
}

function purchaseTitle( purchase ) {
if ( isDomainRegistration( purchase ) ) {
return purchase.meta;
}

return purchase.productName;
}

function showCreditCardExpiringWarning( purchase ) {
return ! isIncludedWithPlan( purchase ) &&
isPaidWithCreditCard( purchase ) &&
Expand All @@ -154,9 +170,12 @@ function showEditPaymentDetails( purchase ) {

export {
creditCardExpiresBeforeSubscription,
getName,
getPurchasesBySite,
getSubscriptionEndDate,
hasPaymentMethod,
hasPrivateRegistration,
isCancelable,
isPaidWithCreditCard,
isPaidWithPaypal,
isExpired,
Expand All @@ -169,7 +188,6 @@ export {
isRenewing,
paymentLogoType,
purchaseType,
purchaseTitle,
showCreditCardExpiringWarning,
showEditPaymentDetails
}
2 changes: 1 addition & 1 deletion client/lib/purchases/test/assembler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import moment from 'moment';
/**
* Internal dependencies
*/
import { createPurchasesArray } from '../assembler.js';
import { createPurchasesArray } from '../assembler';

describe( 'Purchases assembler', () => {
it( 'should be a function', () => {
Expand Down
11 changes: 11 additions & 0 deletions client/lib/upgrades/actions/purchases.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ const debug = debugFactory( 'calypso:upgrades:actions:purchases' ),

const PURCHASES_FETCH_ERROR_MESSAGE = i18n.translate( 'There was an error retrieving purchases.' );

function cancelPurchase( purchaseId, onComplete ) {
wpcom.cancelPurchase( purchaseId, ( error, data ) => {
debug( error, data );

const success = ! error && data.success;

onComplete( success );
} );
}

function cancelPrivateRegistration( purchaseId, onComplete ) {
Dispatcher.handleViewAction( {
type: ActionTypes.PURCHASES_PRIVATE_REGISTRATION_CANCEL,
Expand Down Expand Up @@ -142,6 +152,7 @@ function fetchUserPurchases() {
}

export {
cancelPurchase,
cancelPrivateRegistration,
deleteStoredCard,
fetchSitePurchases,
Expand Down
96 changes: 77 additions & 19 deletions client/me/purchases/cancel-purchase/button.jsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,99 @@
/**
* External Dependencies
*/
import page from 'page';
import React from 'react';

/**
* Internal Dependencies
*/
import { purchaseTitle } from 'lib/purchases';
import Button from 'components/button';
import { cancelPurchase } from 'lib/upgrades/actions';
import { getName, getSubscriptionEndDate, isRefundable } from 'lib/purchases';
import notices from 'notices';
import paths from 'me/purchases/paths';

const CancelPurchaseButton = React.createClass( {
propTypes: {
purchase: React.PropTypes.object.isRequired
},

render() {
return (
<button type="button"
onClick={ this.props.onClick }
className="button">
{ this.renderText() }
</button>
);
getInitialState() {
return {
disabled: false
};
},

renderText() {
const { isRefundable } = this.props.purchase,
productName = purchaseTitle( this.props.purchase );
goToCancelConfirmation() {
const { domain, id } = this.props.purchase;

if ( isRefundable ) {
return this.translate( 'Cancel and Refund %(productName)s', {
args: { productName }
} );
}
page( paths.confirmCancelPurchase( domain, id ) );
},

return this.translate( 'Cancel %(productName)s', {
args: { productName }
cancelPurchase() {
const { purchase } = this.props,
{ id } = purchase;

this.toggleDisabled();

cancelPurchase( id, ( success ) => {
const purchaseName = getName( purchase ),
subscriptionEndDate = getSubscriptionEndDate( purchase );

if ( success ) {
notices.success( this.translate(
'%(purchaseName)s was successfully cancelled. It will be available for use until it expires on %(subscriptionEndDate)s.',
{
args: {
purchaseName,
subscriptionEndDate
}
}
), { persistent: true } );
page( paths.list() );
} else {
notices.error( this.translate(
'There was a problem canceling %(purchaseName)s. ' +
'Please try again later or contact support.',
{
args: { purchaseName }
}
) );
this.toggleDisabled();
}
} );
},

toggleDisabled() {
this.setState( {
disabled: ! this.state.disabled
} );
},

render() {
const { purchase } = this.props,
purchaseName = getName( purchase );

if ( isRefundable( purchase ) ) {
return (
<Button type="button"
onClick={ this.goToCancelConfirmation }>
{ this.translate( 'Cancel and Refund %(purchaseName)s', {
args: { purchaseName }
} ) }
</Button>
);
}

return (
<Button type="button"
disabled={ this.state.disabled }
onClick={ this.cancelPurchase }>
{ this.translate( 'Cancel %(purchaseName)s', {
args: { purchaseName }
} ) }
</Button>
);
}
} );

Expand Down
13 changes: 6 additions & 7 deletions client/me/purchases/cancel-purchase/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import CompactCard from 'components/card/compact';
import HeaderCake from 'components/header-cake';
import Main from 'components/main';
import paths from '../paths';
import { purchaseTitle } from 'lib/purchases';
import { getName, isCancelable } from 'lib/purchases';
import purchasesMixin from '../purchases-mixin';

const CancelPurchase = React.createClass( {
Expand Down Expand Up @@ -54,9 +54,9 @@ const CancelPurchase = React.createClass( {

<Card className="cancel-purchase__card">
<h2>
{ this.translate( 'Cancel %(productName)s', {
{ this.translate( 'Cancel %(purchaseName)s', {
args: {
productName: purchaseTitle( purchase )
purchaseName: getName( purchase )
}
} ) }
</h2>
Expand Down Expand Up @@ -87,8 +87,7 @@ const CancelPurchase = React.createClass( {

<CompactCard className="cancel-purchase__footer">
<CancelPurchaseButton
purchase={ purchase }
onClick={ this.goToCancelConfirmation } />
purchase={ purchase } />
</CompactCard>
</Main>
);
Expand All @@ -102,9 +101,9 @@ const CancelPurchase = React.createClass( {
const purchase = this.getPurchase();

if ( purchase ) {
const { domain, id, isCancelable } = purchase;
const { domain, id } = purchase;

if ( ! isCancelable ) {
if ( ! isCancelable( purchase ) ) {
page.redirect( paths.managePurchase( domain, id ) );
}
} else {
Expand Down
12 changes: 9 additions & 3 deletions client/me/purchases/cancel-purchase/refund-information.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
*/
import React from 'react';

/**
* Internal Dependencies
*/
import { getSubscriptionEndDate, isRefundable } from 'lib/purchases';

const CancelPurchaseRefundInformation = React.createClass( {
propTypes: {
purchase: React.PropTypes.object.isRequired
},

render() {
const { expiryDate, isRefundable, priceText, refundPeriodInDays } = this.props.purchase,
const purchase = this.props.purchase,
{ priceText, refundPeriodInDays } = purchase,
refundsSupportLink = <a href="https://support.wordpress.com/refunds/" target="_blank" />;

if ( isRefundable ) {
if ( isRefundable( purchase ) ) {
return (
<p>{ this.translate(
'Yes! You are canceling this purchase within the %(refundPeriodInDays)d day refund period. ' +
Expand All @@ -38,7 +44,7 @@ const CancelPurchaseRefundInformation = React.createClass( {
'{{a}}Learn more.{{/a}}',
{
args: {
subscriptionEndDate: this.moment( expiryDate ).format( 'LL' ),
subscriptionEndDate: getSubscriptionEndDate( purchase ),
refundPeriodInDays
},
components: {
Expand Down
3 changes: 2 additions & 1 deletion client/me/purchases/confirm-cancel-purchase/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ const ConfirmCancelPurchase = React.createClass( {
handleSubmit( error, response ) {
if ( error ) {
notices.error( this.translate(
"Something went wrong and we couldn't cancel your subscription."
'There was a problem canceling this purchase. ' +
'Please try again later or contact support.'
) );
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function submitForm( { form, onSubmit, selectedPurchase, selectedSite } ) {

button.disabled = true;

wpcom.cancelProduct( selectedPurchase.id, formData, ( error, response ) => {
wpcom.cancelAndRefundPurchase( selectedPurchase.id, formData, ( error, response ) => {
if ( error ) {
button.disabled = false;
onSubmit( error );
Expand Down
4 changes: 2 additions & 2 deletions client/me/purchases/list/item/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import paths from '../../paths';
import CompactCard from 'components/card/compact';
import Flag from 'components/flag';
import {
getName,
isExpired,
isExpiring,
isRenewing,
isIncludedWithPlan,
isOneTimePurchase,
purchaseType,
purchaseTitle,
showCreditCardExpiringWarning
} from 'lib/purchases';

Expand Down Expand Up @@ -119,7 +119,7 @@ const PurchaseItem = React.createClass( {
content = (
<span>
<div className="purchase-item__title">
{ purchaseTitle( this.props.purchase ) }
{ getName( this.props.purchase ) }
</div>
<div className="purchase-item__purchase-type">{ purchaseType( this.props.purchase ) }</div>
<div className="purchase-item__purchase-date">
Expand Down
Loading

0 comments on commit 5dd3a82

Please sign in to comment.