Skip to content

Commit e32d047

Browse files
Jisayantleblanc
authored andcommitted
fix(pci.projects): improve project creation (#782)
* fix(pci.projects.project.creating): redirection after creation complete * fix(pci.projects.creation): redirect to creating page when credit OK * fix(pci.projects.new): one shot payment when fraud detection * fix: allow retry when oneshot payment fail * fix(pci.projects.new): detect project status on failure * fix(pci.projects.new): fix voucher project creation
1 parent 42fad80 commit e32d047

File tree

8 files changed

+101
-23
lines changed

8 files changed

+101
-23
lines changed

packages/manager/modules/pci/src/projects/new/new.controller.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export default class PciProjectNewCtrl {
4242

4343
if (currentStep.name === 'description' && this.region !== 'US') {
4444
translationKey = 'pci_projects_new_continue';
45-
} else if (currentStep.model.mode === 'credits' || this.hasCreditToOrder()) {
45+
} else if (currentStep.model.mode === 'credits' || this.hasCreditToOrder()
46+
|| (this.paymentStatus && currentStep.model.projectId && this.newProjectInfo.order)) {
4647
translationKey = 'pci_projects_new_credit_and_create';
4748
} else if (get(currentStep.model.paymentType, 'paymentType.value') === 'BANK_ACCOUNT') {
4849
translationKey = 'pci_projects_new_add';
@@ -113,7 +114,7 @@ export default class PciProjectNewCtrl {
113114
// build from scratch to be sure that old query parameters
114115
// are reset (in case of previous payment error)
115116
const { location } = this.$window;
116-
let callbackUrlBase = `${location.protocol}//${location.host}${location.pathname}${this.getStateLink('payment')}?`;
117+
let callbackUrlBase = `${location.protocol}//${location.host}${location.pathname}${this.getStateLink('payment', false)}?`;
117118
const callbackParams = [];
118119

119120
if (this.descriptionModel.name) {
@@ -146,6 +147,10 @@ export default class PciProjectNewCtrl {
146147
this.loading.creating = true;
147148

148149
const hasCredit = this.paymentModel.mode === 'credits' && this.paymentModel.credit.value;
150+
const hasOrderCredit = this.newProjectInfo.order
151+
&& (!this.paymentStatus
152+
|| ['success', 'accepted'].includes(this.paymentStatus)
153+
|| (this.paymentStatus && this.paymentModel.projectId && this.newProjectInfo.order));
149154
const hasVoucher = this.paymentModel.voucher.valid && this.paymentModel.voucher.value;
150155
const createParams = {
151156
description: this.descriptionModel.name,
@@ -155,20 +160,19 @@ export default class PciProjectNewCtrl {
155160
createParams.voucher = this.paymentModel.voucher.value;
156161
} else if (hasCredit) {
157162
createParams.credit = this.paymentModel.credit.value;
158-
} else if (this.newProjectInfo.order
159-
&& (!this.paymentStatus || ['success', 'accepted'].includes(this.paymentStatus))) {
163+
} else if (hasOrderCredit) {
160164
createParams.credit = this.newProjectInfo.order.value;
161165
}
162166

163167
return this.PciProjectNewService
164168
.acceptAgreements(this.contracts)
165169
.then(() => this.PciProjectNewService.createNewProject(createParams))
166170
.then(({ orderId, project }) => {
167-
if (!hasCredit) {
168-
return this.onProjectCreated(project);
171+
if (!hasVoucher && (hasCredit || hasOrderCredit)) {
172+
return this.payCredit({ orderId, project });
169173
}
170174

171-
return this.payCredit({ orderId, project });
175+
return this.onProjectCreated(project);
172176
})
173177
.catch(() => {
174178
this.loading.creating = false;
@@ -251,8 +255,10 @@ export default class PciProjectNewCtrl {
251255
// if default payment or credit amount - create project
252256
if (this.paymentModel.defaultPaymentMethod
253257
|| (this.paymentModel.mode === 'credits' && this.paymentModel.credit.value)
258+
|| (this.newProjectInfo.order && ['success', 'accepted'].includes(this.paymentStatus))
259+
|| (this.paymentStatus && currentStep.model.projectId && this.newProjectInfo.order)
254260
|| (this.paymentModel.voucher.valid
255-
&& this.paymentModel.voucher.paymentMeanRequired === false)
261+
&& this.paymentModel.voucher.paymentMethodRequired === false)
256262
) {
257263
return this.createProject();
258264
}
@@ -280,7 +286,7 @@ export default class PciProjectNewCtrl {
280286
},
281287
});
282288

283-
if (this.paymentStatus === 'success' || this.paymentStatus === 'accepted') {
289+
if (['success', 'accepted'].includes(this.paymentStatus)) {
284290
// success => HiPay
285291
// accepted => PayPal
286292
if (!this.paymentModel.projectId && !this.newProjectInfo.order) {

packages/manager/modules/pci/src/projects/new/new.routing.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default /* @ngInject */ ($stateProvider) => {
5757
getStepByName: /* @ngInject */ steps => stepName => find(steps, {
5858
name: stepName,
5959
}),
60-
getStateLink: /* ngInject */ ($state, getCurrentStep) => (action) => {
60+
getStateLink: /* @ngInject */ ($state, getCurrentStep) => (action, inherit = true) => {
6161
switch (action) {
6262
case 'cancel':
6363
return $state.href('pci.projects');
@@ -68,6 +68,8 @@ export default /* @ngInject */ ($stateProvider) => {
6868
case 'payment':
6969
return $state.href('pci.projects.new.payment', {
7070
mode: null,
71+
}, {
72+
inherit,
7173
});
7274
default:
7375
if (getCurrentStep().name === 'description') {
@@ -97,8 +99,30 @@ export default /* @ngInject */ ($stateProvider) => {
9799
PCI_REDIRECT_URLS,
98100
`${coreConfig.getRegion()}.paymentMethods`,
99101
),
100-
newProjectInfo: /* @ngInject */ ($timeout, coreConfig, ovhPaymentMethod,
102+
project: /* @ngInject */ ($transition$, PciProjectNewService) => {
103+
if ($transition$.params().projectId) {
104+
return PciProjectNewService
105+
.getProject($transition$.params().projectId);
106+
}
107+
return null;
108+
},
109+
newProjectInfo: /* @ngInject */ ($timeout, $transition$, coreConfig, ovhPaymentMethod,
101110
paymentStatus, PciProjectNewService) => {
111+
const newProjectInfoThen = (response) => {
112+
const transformedResponse = response;
113+
// if there is an error when returning from HiPay
114+
// and that a projectId is present in the URL (meaning that a credit has been paid)
115+
// force error to null to avoid too many project error display
116+
if (transformedResponse.error
117+
&& paymentStatus
118+
&& get($transition$.params(), 'projectId')) {
119+
transformedResponse.error = null;
120+
}
121+
return transformedResponse;
122+
};
123+
124+
// if region is US return an empty object as API call does not exist in US
125+
// and project creation is redirected to express order
102126
if (coreConfig.isRegion('US')) {
103127
return {};
104128
}
@@ -112,11 +136,13 @@ export default /* @ngInject */ ($stateProvider) => {
112136
if (!hasDefaultPaymentMethod && iteration < 10) {
113137
return checkValidPaymentMethod(iteration + 1);
114138
}
115-
return PciProjectNewService.getNewProjectInfo();
139+
return PciProjectNewService.getNewProjectInfo()
140+
.then(newProjectInfoThen);
116141
});
117142
return checkValidPaymentMethod();
118143
}
119-
return PciProjectNewService.getNewProjectInfo();
144+
return PciProjectNewService.getNewProjectInfo()
145+
.then(newProjectInfoThen);
120146
},
121147
onDescriptionStepFormSubmit: /* @ngInject */ $state => () => $state.go('pci.projects.new.payment'),
122148
onProjectCreated: /* @ngInject */ $state => projectId => $state.go(
@@ -138,7 +164,7 @@ export default /* @ngInject */ ($stateProvider) => {
138164
voucher: {
139165
valid: false,
140166
value: null,
141-
paymentMeanRequired: null,
167+
paymentMethodRequired: null,
142168
submitted: false,
143169
},
144170
defaultPaymentMethod: null,

packages/manager/modules/pci/src/projects/new/new.service.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ export default class PciProjectNewService {
2121
return this.$q.all(acceptPromises);
2222
}
2323

24+
cancelProjectCreation(projectId) {
25+
return this.OvhApiCloud.Project()
26+
.v6()
27+
.cancelCreation({
28+
serviceName: projectId,
29+
}, {})
30+
.$promise;
31+
}
32+
2433
createNewProject(params = {}) {
2534
return this.OvhApiCloud
2635
.v6()
@@ -62,4 +71,13 @@ export default class PciProjectNewService {
6271
.createProjectInfo(params)
6372
.$promise;
6473
}
74+
75+
getProject(serviceName) {
76+
return this.OvhApiCloud.Project()
77+
.v6()
78+
.get({
79+
serviceName,
80+
})
81+
.$promise;
82+
}
6583
}

packages/manager/modules/pci/src/projects/new/payment/payment.component.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ export default {
1414
newProjectInfo: '<',
1515
hasCreditToOrder: '<',
1616
creditMinPrice: '<',
17+
project: '<',
1718
},
1819
};

packages/manager/modules/pci/src/projects/new/payment/payment.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<div data-ng-if="!$ctrl.step.loading.init">
99

10-
<div data-ng-if="!['success', 'accepted'].includes($ctrl.paymentStatus)"
10+
<div data-ng-if="!['success', 'accepted'].includes($ctrl.paymentStatus) && (!$ctrl.step.model.projectId || $ctrl.step.model.mode === 'credits')"
1111
data-ng-switch="$ctrl.step.model.mode">
1212
<div data-ng-switch-when="paymentMethod">
1313
<pci-project-new-payment-default
@@ -151,7 +151,7 @@
151151

152152
</div>
153153

154-
<div data-ng-if="['success', 'accepted'].includes($ctrl.paymentStatus) && $ctrl.newProjectInfo.order">
154+
<div data-ng-if="(['success', 'accepted'].includes($ctrl.paymentStatus) || ($ctrl.paymentStatus && $ctrl.step.model.projectId && $ctrl.step.model.mode !== 'credits')) && $ctrl.newProjectInfo.order">
155155
<h2 class="oui-heading_underline"
156156
data-translate="pci_project_new_payment_welcome">
157157
</h2>

packages/manager/modules/pci/src/projects/new/payment/payment.routing.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,22 @@ export default /* @ngInject */ ($stateProvider) => {
55
$stateProvider
66
.state('pci.projects.new.payment', {
77
url: '/payment?mode&credit&voucher&hiPayStatus&paypalAgreementStatus',
8-
onEnter: /* @ngInject */ ($transition$, $window, getStepByName) => {
8+
redirectTo: (transition) => {
9+
const { hiPayStatus, mode, projectId } = transition.params();
10+
11+
if (hiPayStatus === 'success' && mode === 'credits' && projectId) {
12+
return {
13+
state: 'pci.projects.project',
14+
params: {
15+
projectId,
16+
},
17+
};
18+
}
19+
20+
return null;
21+
},
22+
onEnter: /* @ngInject */ ($transition$, $window, getStepByName, newProjectInfo,
23+
PciProjectNewService, project) => {
924
// check for paypal response in query string
1025
if ($window.location.search.indexOf('paypalAgreementStatus') > -1) {
1126
// in that case we will redirect to pci.projects.new.payment
@@ -28,7 +43,7 @@ export default /* @ngInject */ ($stateProvider) => {
2843
const paymentModel = getStepByName('payment').model;
2944

3045
// set description step model
31-
descriptionModel.description = stateParams.description;
46+
descriptionModel.name = stateParams.description;
3247
descriptionModel.agreements = true;
3348

3449
// set payment step model
@@ -41,6 +56,16 @@ export default /* @ngInject */ ($stateProvider) => {
4156
paymentModel.credit.value = parseInt(stateParams.credit, 10);
4257
paymentModel.projectId = stateParams.projectId;
4358

59+
// if there is an error from HiPay and a projectId is setted
60+
// (in other words: if credit payment in error)
61+
// cancel project creation and redirect refresh page
62+
const { hiPayStatus, projectId } = $transition$.params();
63+
if (hiPayStatus !== 'success' && get(project, 'status') === 'creating' && projectId) {
64+
return PciProjectNewService
65+
.cancelProjectCreation(projectId)
66+
.then(() => $window.location.reload());
67+
}
68+
4469
return true;
4570
}
4671

packages/manager/modules/pci/src/projects/new/translations/Messages_fr_FR.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"pci_projects_new_add": "Ajouter",
77
"pci_projects_new_credit_and_create": "Créditer et créer mon projet",
88
"pci_projects_new_add_payment_error_message": "Une erreur est survenue lors de l'enregistrement de votre moyen de paiement. Veuillez réessayer ou choisir un autre moyen de paiement.",
9-
"pci_projects_new_add_credit_payment_error_message": "Une erreur est survenue lors du paiement de votre bon de commande de crédit.",
9+
"pci_projects_new_add_credit_payment_error_message": "Une erreur est survenue lors de la validation de votre moyen de paiement, veuillez réessayer.",
1010
"pci_projects_new_create_error_message": "Une erreur est survenue lors de la création de votre projet Public Cloud. Veuillez réessayer.",
1111
"pci_projects_new_create_credit_asterisk": "* Chaque projet Public Cloud possède un compte crédit qui lui est propre. Vos factures seront automatiquement débitées de celui-ci. Si le montant du crédit est insuffisant, vous devrez régler la somme restant due avec un moyen de paiement enregistré dans les plus brefs délais.",
1212
"pci_projects_new_create_voucher_not_submitted": "Merci de valider votre code promo avant de continuer"

packages/manager/modules/pci/src/projects/project/creating/creating.routing.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ export default /* @ngInject */ ($stateProvider) => {
55
views: {
66
'@pci': {
77
componentProvider: /* @ngInject */ projectOrder => (projectOrder ? 'pciProjectCreatingNotPaid' : 'pciProjectCreating'),
8-
// component: 'pciProjectCreating',
98
},
109
},
1110
resolve: {
1211
breadcrumb: () => null,
13-
onProjectCreated: /* @ngInject */ $state => () => $state.go('^', {}, {
14-
reload: true,
15-
}),
12+
onProjectCreated: /* @ngInject */ ($state, $window, projectId) => () => {
13+
$window.location.replace($state.href('pci.projects.project', {
14+
projectId,
15+
}));
16+
$window.location.reload();
17+
},
1618
projectOrder: /* @ngInject */ (project, projectCreating, projectOrderStatus) => {
1719
if (project.orderId && projectOrderStatus === 'notPaid') {
1820
return projectCreating

0 commit comments

Comments
 (0)