Commit 20ef8174 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Create a copy of PaymentMethod cmp with GQL

parent 08e85680
<script>
import ProgressBar from 'ee/registrations/components/progress_bar.vue';
import { STEPS, SUBSCRIPTON_FLOW_STEPS } from 'ee/registrations/constants';
import STATE_QUERY from 'ee/subscriptions/graphql/queries/state.query.graphql';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import { s__ } from '~/locale';
import BillingAddress from './checkout/billing_address.vue';
import SubscriptionDetails from './checkout/subscription_details.vue';
import PaymentMethod from './checkout/payment_method.vue';
export default {
components: { ProgressBar, SubscriptionDetails, BillingAddress },
components: { ProgressBar, SubscriptionDetails, BillingAddress, PaymentMethod },
props: {
plans: {
type: Array,
......@@ -16,7 +17,7 @@ export default {
},
apollo: {
isNewUser: {
query: STATE_QUERY,
query: stateQuery,
},
},
currentStep: STEPS.checkout,
......@@ -37,6 +38,7 @@ export default {
<h2 class="gl-mt-6 gl-mb-7 gl-mb-lg-5">{{ $options.i18n.checkout }}</h2>
<subscription-details :plans="plans" />
<billing-address />
<payment-method />
</div>
</div>
</template>
<script>
import { GlSprintf } from '@gitlab/ui';
import { STEPS } from 'ee/subscriptions/constants';
import STATE_QUERY from 'ee/subscriptions/graphql/queries/state.query.graphql';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { sprintf, s__ } from '~/locale';
import Zuora from './zuora.vue';
export default {
components: {
GlSprintf,
Step,
Zuora,
},
apollo: {
paymentMethod: {
query: STATE_QUERY,
update: (data) => data.paymentMethod,
},
},
computed: {
isValid() {
return Boolean(this.paymentMethod.id);
},
expirationDate() {
return sprintf(this.$options.i18n.expirationDate, {
expirationMonth: this.paymentMethod.creditCardExpirationMonth,
expirationYear: this.paymentMethod.creditCardExpirationYear.toString(10).slice(-2),
});
},
},
i18n: {
stepTitle: s__('Checkout|Payment method'),
paymentMethod: s__('Checkout|%{cardType} ending in %{lastFourDigits}'),
expirationDate: s__('Checkout|Exp %{expirationMonth}/%{expirationYear}'),
},
stepId: STEPS[2].id,
};
</script>
<template>
<step :step-id="$options.stepId" :title="$options.i18n.stepTitle" :is-valid="isValid">
<template #body="props">
<zuora :active="props.active" />
</template>
<template #summary>
<div class="js-summary-line-1">
<gl-sprintf :message="$options.i18n.paymentMethod">
<template #cardType>
{{ paymentMethod.creditCardType }}
</template>
<template #lastFourDigits>
<strong>{{ paymentMethod.creditCardMaskNumber.slice(-4) }}</strong>
</template>
</gl-sprintf>
</div>
<div class="js-summary-line-2">
{{ expirationDate }}
</div>
</template>
</step>
</template>
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import { pick } from 'lodash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import Api from 'ee/api';
import {
ERROR_LOADING_PAYMENT_FORM,
ZUORA_SCRIPT_URL,
ZUORA_IFRAME_OVERRIDE_PARAMS,
PAYMENT_FORM_ID,
} from 'ee/subscriptions/constants';
import createFlash from '~/flash';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import updateStateMutation from 'ee/subscriptions/graphql/mutations/update_state.mutation.graphql';
export default {
components: {
GlLoadingIcon,
},
props: {
active: {
type: Boolean,
required: true,
},
},
data() {
return {
isLoading: false,
paymentFormParams: null,
zuoraLoaded: false,
zuoraScriptEl: null,
};
},
computed: {
shouldShowZuoraFrame() {
return this.active && this.zuoraLoaded && !this.isLoading;
},
},
watch: {
// The Zuora script has loaded and the parameters for rendering the iframe have been fetched.
paymentFormParams() {
this.renderZuoraIframe();
},
},
mounted() {
this.loadZuoraScript();
},
beforeDestroy() {
document.head.removeChild(this.zuoraScriptEl);
},
methods: {
zuoraIframeRendered() {
this.isLoading = false;
this.zuoraLoaded = true;
},
fetchPaymentFormParams() {
this.isLoading = true;
return Api.fetchPaymentFormParams(PAYMENT_FORM_ID)
.then(({ data }) => {
this.paymentFormParams = data;
this.renderZuoraIframe();
})
.catch(() => {
createFlash({ message: ERROR_LOADING_PAYMENT_FORM });
});
},
loadZuoraScript() {
this.isLoading = true;
if (!this.zuoraScriptEl) {
this.zuoraScriptEl = document.createElement('script');
this.zuoraScriptEl.type = 'text/javascript';
this.zuoraScriptEl.async = true;
this.zuoraScriptEl.onload = this.fetchPaymentFormParams;
this.zuoraScriptEl.src = ZUORA_SCRIPT_URL;
document.head.appendChild(this.zuoraScriptEl);
}
},
paymentFormSubmitted({ refId }) {
this.isLoading = true;
return Api.fetchPaymentMethodDetails(refId)
.then(({ data }) => {
return pick(
data,
'id',
'credit_card_expiration_month',
'credit_card_expiration_year',
'credit_card_type',
'credit_card_mask_number',
);
})
.then((paymentMethod) => convertObjectPropsToCamelCase(paymentMethod))
.then((paymentMethod) => this.updateState({ paymentMethod }))
.then(() => this.activateNextStep())
.catch((error) =>
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true }),
)
.finally(() => {
this.isLoading = false;
});
},
renderZuoraIframe() {
const params = { ...this.paymentFormParams, ...ZUORA_IFRAME_OVERRIDE_PARAMS };
window.Z.runAfterRender(this.zuoraIframeRendered);
window.Z.render(params, {}, this.paymentFormSubmitted);
},
activateNextStep() {
return this.$apollo
.mutate({
mutation: activateNextStepMutation,
})
.catch((error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
});
},
updateState(payload) {
return this.$apollo
.mutate({
mutation: updateStateMutation,
variables: {
input: payload,
},
})
.catch((error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
});
},
},
};
</script>
<template>
<div>
<gl-loading-icon v-if="isLoading" size="lg" />
<div v-show="shouldShowZuoraFrame" id="zuora_payment"></div>
</div>
</template>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment