(payment) change to checkout payment in user page

This commit is contained in:
Julien Calixte
2020-02-23 12:33:28 +01:00
parent def7452a60
commit d72677df6e
9 changed files with 74 additions and 143 deletions

34
package-lock.json generated
View File

@@ -3375,7 +3375,6 @@
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": { "requires": {
"color-convert": "^1.9.0" "color-convert": "^1.9.0"
}, },
@@ -3384,7 +3383,6 @@
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
} }
@@ -4616,7 +4614,6 @@
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": { "requires": {
"ansi-styles": "^3.2.1", "ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
@@ -5017,8 +5014,7 @@
"color-name": { "color-name": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
"dev": true
}, },
"color-string": { "color-string": {
"version": "0.2.4", "version": "0.2.4",
@@ -6512,8 +6508,7 @@
"escape-string-regexp": { "escape-string-regexp": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
"dev": true
}, },
"escodegen": { "escodegen": {
"version": "1.14.1", "version": "1.14.1",
@@ -8004,8 +7999,7 @@
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
"dev": true
}, },
"has-own-property-x": { "has-own-property-x": {
"version": "3.2.0", "version": "3.2.0",
@@ -10169,7 +10163,8 @@
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
}, },
"lodash-es": { "lodash-es": {
"version": "4.17.15", "version": "4.17.15",
@@ -11460,6 +11455,14 @@
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
"dev": true "dev": true
}, },
"package-lock-only": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/package-lock-only/-/package-lock-only-0.0.4.tgz",
"integrity": "sha512-fV1YHeTMWH5LKmdVqfWskm2/SG0iF2IrxJn3ziaPVx9CnpecGJzt8xXtLV+CYINENZwPFMtbxO5qupz0asNz1A==",
"requires": {
"chalk": "^2.4.1"
}
},
"pako": { "pako": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
@@ -14350,7 +14353,6 @@
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": { "requires": {
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
@@ -15548,12 +15550,12 @@
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.3.tgz", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.3.tgz",
"integrity": "sha512-8iSa4mGNXBjyuSZFCCO4fiKfvzqk+mhL0lnKuGcQtO1eoj8nq3CmbEG8FwK5QqoqwDgsjsf1GDuisDX4cdb/aQ==" "integrity": "sha512-8iSa4mGNXBjyuSZFCCO4fiKfvzqk+mhL0lnKuGcQtO1eoj8nq3CmbEG8FwK5QqoqwDgsjsf1GDuisDX4cdb/aQ=="
}, },
"vue-stripe-elements-plus": { "vue-stripe-checkout": {
"version": "0.3.2", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/vue-stripe-elements-plus/-/vue-stripe-elements-plus-0.3.2.tgz", "resolved": "https://registry.npmjs.org/vue-stripe-checkout/-/vue-stripe-checkout-3.1.6.tgz",
"integrity": "sha512-Cuo+guUye1bHrwgQyU4Yb9mIEH+IKiz/QKNW7I70z1BWSIU0OjCgDHWcdBUDIgzLGip4/8FQqSa8IICKT+Lzmg==", "integrity": "sha512-2LKZ6EEcgSv2vA2q9eB5mKQlTO3GT7Yz1/SF1sUwJl1egHAcr+Zbqwif98gXDG+iZettEFjlXBqX62IXiPqlyA==",
"requires": { "requires": {
"lodash": "^4.17.11" "package-lock-only": "0.0.4"
} }
}, },
"vue-style-loader": { "vue-style-loader": {

View File

@@ -34,7 +34,7 @@
"vue-i18n": "^8.15.0", "vue-i18n": "^8.15.0",
"vue-property-decorator": "^8.3.0", "vue-property-decorator": "^8.3.0",
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vue-stripe-elements-plus": "^0.3.2", "vue-stripe-checkout": "^3.1.6",
"vuex": "^3.1.1", "vuex": "^3.1.1",
"vuex-class": "^0.3.2", "vuex-class": "^0.3.2",
"vuex-persist": "^2.1.0" "vuex-persist": "^2.1.0"

View File

@@ -30,7 +30,6 @@
name="keywords" name="keywords"
content="budget,friends,family,vacation,holidays,shopping" content="budget,friends,family,vacation,holidays,shopping"
/> />
<script src="https://js.stripe.com/v3/"></script>
</head> </head>
<body> <body>

View File

@@ -1,72 +0,0 @@
{
"name": "Vaquant",
"short_name": "Vaquant",
"description": "Gérer vos budgets de groupe en toute simplicité !",
"icons": [
{
"src": "./img/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-60x60.png",
"sizes": "60x60",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-76x76.png",
"sizes": "76x76",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-120x120.png",
"sizes": "120x120",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon-180x180.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "./img/icons/apple-touch-icon.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "./img/icons/favicon-16x16.png",
"sizes": "16x16",
"type": "image/png"
},
{
"src": "./img/icons/favicon-32x32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "./img/icons/msapplication-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "./img/icons/mstile-150x150.png",
"sizes": "150x150",
"type": "image/png"
}
],
"start_url": "/",
"scope": "/",
"display": "standalone",
"background_color": "#3f4fa6",
"theme_color": "#3f4fa6"
}

View File

@@ -1,62 +1,65 @@
<template> <template>
<div class="payment"> <div class="payment">
<Card <stripe-checkout
ref="stripeCard" ref="checkoutRef"
class="stripe-card" :pk="publishableKey"
:class="{ complete }" :items="items"
stripe="pk_test_CO1FMasxNSwIX0P9FgzmDMyp" :successUrl="successUrl"
@change="complete = $event.complete" :cancelUrl="cancelUrl"
/> :clientReferenceId="clientReferenceId"
<button class="button is-primary" @click="pay" :disabled="!complete"> :customerEmail="email"
Payer par carte bleue >
</button> <template slot="checkout-button">
<button class="button is-primary" @click="pay">
Payer par carte bleue
</button>
</template>
</stripe-checkout>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Prop, Vue } from 'vue-property-decorator'
import { import { Action, Getter } from 'vuex-class'
Card, import { StripeCheckout } from 'vue-stripe-checkout'
createToken, import IUser from '@/models/IUser'
confirmPaymentIntent,
instance as Stripe
} from 'vue-stripe-elements-plus'
import IPaymentIntent from '@/models/IPaymentIntent' import IPaymentIntent from '@/models/IPaymentIntent'
import IPayment from '@/models/IPayment' import IPayment from '@/models/IPayment'
import notif from '@/utils/notif' import notif from '@/utils/notif'
@Component({ @Component({
components: { components: {
Card StripeCheckout
} }
}) })
export default class Payment extends Vue { export default class Payment extends Vue {
private complete: boolean = false @Getter
public user!: IUser | null
private publishableKey = 'pk_test_CO1FMasxNSwIX0P9FgzmDMyp'
private successUrl = window.location.href
private cancelUrl = window.location.href
private items = [
{
plan: 'plan_GmrqYW6obrGUE6',
quantity: 1
}
]
private checkoutRef: any = null
public async mounted() {
this.checkoutRef = this.$refs.checkoutRef
}
private async pay() { private async pay() {
const paymentIntentResponse = await fetch('http://localhost:9000/payment') this.checkoutRef.redirectToCheckout()
const paymentIntent: IPaymentIntent = await paymentIntentResponse.json() }
const data: IPayment | null = await createToken() private get clientReferenceId() {
return this.user?.userId ?? ''
}
if (paymentIntent && data) { private get email() {
try { return this.user?.email ?? ''
const result = await Stripe.confirmCardPayment(
paymentIntent.clientSecret,
{
payment_method: {
card: (this.$refs.stripeCard as any).$refs.element._element,
billing_details: {
name: 'Julien Calixte',
email: 'juliencalixte@gmail.com'
}
}
}
)
} catch (error) {
notif.error('une erreur est survenue lors de votre paiement')
}
}
} }
} }
</script> </script>

View File

@@ -29,8 +29,8 @@
<div class="plan-header">Premium</div> <div class="plan-header">Premium</div>
Vaquant sans aucune limite ! Vaquant sans aucune limite !
<div class="plan-price"> <div class="plan-price">
<span class="plan-price-amount" <span class="plan-price-amount">
><span class="plan-price-currency">€</span>3</span <span class="plan-price-currency">€</span>2</span
>/mois >/mois
</div> </div>
<div class="plan-items"> <div class="plan-items">
@@ -39,11 +39,10 @@
<div class="plan-item"> <div class="plan-item">
<awe-icon icon="infinity" /> dépenses/compte <awe-icon icon="infinity" /> dépenses/compte
</div> </div>
<div class="plan-item">150+ devises</div>
<div class="plan-item">pièces jointes disponibles</div> <div class="plan-item">pièces jointes disponibles</div>
</div> </div>
<div class="plan-footer"> <div class="plan-footer">
<button class="button is-fullwidth" @click="choose('premium')" disabled> <button class="button is-fullwidth" @click="choose('premium')">
Bientôt disponible Bientôt disponible
<!-- <span v-if="plan !== 'premium'">Passer en premium</span> <!-- <span v-if="plan !== 'premium'">Passer en premium</span>
<span v-else>Sélectionné</span> --> <span v-else>Sélectionné</span> -->

2
src/shims-vue.d.ts vendored
View File

@@ -9,4 +9,4 @@ declare module 'crypto-js/aes'
declare module 'crypto-js/enc-utf8' declare module 'crypto-js/enc-utf8'
declare module '@xkeshi/vue-qrcode' declare module '@xkeshi/vue-qrcode'
declare module 'font-color-contrast' declare module 'font-color-contrast'
declare module 'vue-stripe-elements-plus' declare module 'vue-stripe-checkout'

View File

@@ -1,6 +1,5 @@
<template> <template>
<div class="about no-margin"> <div class="about no-margin">
<Payment />
<img class="logo" src="../assets/logo.svg" title="logo Vaquant" /> <img class="logo" src="../assets/logo.svg" title="logo Vaquant" />
<p class="simple-description" v-t="'about.description'"></p> <p class="simple-description" v-t="'about.description'"></p>
<hr /> <hr />
@@ -10,12 +9,10 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import Payment from '@/components/Payment.vue'
@Component({ @Component({
components: { components: {
'app-resume': () => import('@/components/AppResume.vue'), 'app-resume': () => import('@/components/AppResume.vue')
Payment
} }
}) })
export default class About extends Vue {} export default class About extends Vue {}

View File

@@ -20,9 +20,9 @@
@click="purge" @click="purge"
v-t="'user.purge'" v-t="'user.purge'"
></button> ></button>
<confirm-button class="is-danger" @confirm="remove">{{ <confirm-button class="is-danger" @confirm="remove">
$t('user.delete') {{ $t('user.delete') }}
}}</confirm-button> </confirm-button>
</div> </div>
</div> </div>
</div> </div>
@@ -32,6 +32,8 @@
<h3 class="subtitle is-3">Comptes cloturés</h3> <h3 class="subtitle is-3">Comptes cloturés</h3>
<account-list :archived="true" /> <account-list :archived="true" />
</div> </div>
<pricing-table />
<payment-checkout :email="user.email" />
</div> </div>
<div v-else> <div v-else>
<div class="tabs is-centered is-fullwidth"> <div class="tabs is-centered is-fullwidth">
@@ -243,7 +245,8 @@ const enableAnonymous: boolean = false
LangChanger, LangChanger,
'account-list': () => import('@/components/AccountList.vue'), 'account-list': () => import('@/components/AccountList.vue'),
'confirm-button': () => import('@/components/ConfirmButton.vue'), 'confirm-button': () => import('@/components/ConfirmButton.vue'),
'pricing-table': () => import('@/components/PricingTable.vue') 'pricing-table': () => import('@/components/PricingTable.vue'),
'payment-checkout': () => import('@/components/Payment.vue')
} }
}) })
export default class User extends Vue { export default class User extends Vue {