diff --git a/README.md b/README.md
index 580a154..8ab5a3d 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,56 @@
# Vue Storefront Adyen Payment Module
-Use at Your own risk.
+This module allows payments through Adyen Payments from Vue Storefront using Magento as backend.
+The module follows [Adyen's recomendations](https://docs.adyen.com/plugins/magento-2/magento-pwa-storefront) for integrating a PWA using their magento extension.
+
+## Requirements
+- Magento >= 2.3.5 (may work in earlier version but it has not been tested)
+- Adyen Magento2 extension version >= 6.5.0
+- Vue Storefront >= 1.10.0
+- Have latest version of [magento2-rest-client](magento2-rest-client). At least you need [this PR](https://github.com/DivanteLtd/magento2-rest-client/pull/35)
+
+## Before you begin
+
+Before starting to integrate this module in your VueStorefront project, you will have to set-up the following:
+- [Create a Adyen test account if you do not have one.](https://www.adyen.com/)
+- [Set up the Adyen Customer Area.](https://docs.adyen.com/plugins/magento-2/set-up-adyen-customer-area)
+- [Set up the plugin in Magento.](https://docs.adyen.com/plugins/magento-2/set-up-the-plugin-in-magento)
+- [Set up the payment methods in Magento.](https://docs.adyen.com/plugins/magento-2/set-up-the-payment-methods-in-magento)
#### Features:
- [x] Adyen CreditCard payment
-- [x] Adyen PayPal payment
- [x] Adyen field validation and encryption.
+- [x] 3DS2 authentification
#### To be done:
-- [ ] Add notifications depend on Adyen callbacks.
+- [ ] Retry 3DS2 Authentification after entering wrong code.
+- [ ] Adyen PayPal payment.
- [ ] Add other payments methods.
-
-If you have any questions or suggestion then please feel free to drop a line ;)
+- [ ] 3DS1 authentification.
+- [ ] Store credit carts with Adyen Vault.
## Installation:
```shell
-$ git clone git@github.com:melvin-hamilton-digital/vsf-payment-adyen.git ./vue-storefront/src/modules/adyen
+$ git clone https://github.com/jimmylion/vsf-payment-adyen.git ./vue-storefront/src/modules/adyen
```
## Configuration
`config/local.json`
Add API Key and paypal endpoint to hendle PayPal result from adyen.
```json
-"adyen": {
- "originKey": "origin_key",
- "paypalResultHandler": "https://your-backend/adyen-end-points/paypal"
-}
+ "adyen": {
+ "originKey": "origin_key",
+ "paypalResultHandler": "https://your-backend/adyen-end-points/paypal",
+ "environment": "test",
+ "saveCards": true/false,
+ "allow3DS2": true/false,
+ "originKeys": {
+ "http://localhost:3000": "your localhost origin_key",
+ "https://staging.your-vsf.com": "your staging origin_key",
+ "https://your-vsf.com": "your production origin key"
+ }
+ },
```
set Driver for adyen
@@ -40,11 +64,6 @@ set Driver for adyen
}
```
-[How to get the API key](https://docs.adyen.com/developers/user-management/how-to-get-the-api-key)
-
-`sprykerConfirm` - used in /store/actions.ts -> backConfirmation
-
-
## Register the Adyen module
@@ -52,11 +71,11 @@ In `./src/modules/index.ts`
```js
...
-import { Adyen } from './adyen'
+import { PaymentAdyen } from './payment-adyen';
export const registerModules: VueStorefrontModule[] = [
...,
- Adyen
+ PaymentAdyen
]
```
@@ -64,61 +83,32 @@ export const registerModules: VueStorefrontModule[] = [
Under your theme `components/core/blocks/Checkout/Payment.vue`.
```js
-import CardForm from 'src/modules/adyen/components/CardForm'
-import PayPal from 'src/modules/adyen/components/PayPal'
-
export default {
components: {
...
- CardForm,
- PayPal
- },
- ...
- computed: {
- ...
- isAdyenValid () {
- return this.$store.state.adyen.isAdyenValid
- }
+ AdyenPayments: () =>
+ import("src/modules/payment-adyen/components/AdyenPayments.vue")
},
```
+@todo - explain where and how to include the FinishPayment component. In our case it is in:
+src/themes/jimmylion-theme/pages/Checkout.vue
+src/themes/jimmylion-theme/components/ui/Checkout/OrderReview.vue
+
Also add form component to your template:
```html
-
-
-```
-and !isAdyenValid to "Go review the order" button, for disabling it until all card data was validate.
-```html
-
- {{ $t('Go review the order') }}
-
+
```
-Your backend should return
-`"paymentmethods_endpoint": "https://www.en.spryker-demo.melvin-hamilton.store/vsbridge/cart/payment-methods?token={{token}}&cartId={{cartId}}",`
-```json
-{
- "code": 200,
- "result": [
- {
- "code": "adyenCreditCard",
- "title": "Credit Card"
- },
- {
- "code": "adyenPayPal",
- "title": "PayPal"
- }
- ]
-}
-```
-## References
-In vue-storefront/src/modules/adyen/components/CardForm.vue find `csfSetupObj` inside you can add styles, placeholders, define rootNode etc.
+## API Installation
+[How to get the API key](https://docs.adyen.com/developers/user-management/how-to-get-the-api-key)
+
+## References
[Styling Secured Fields](https://docs.adyen.com/developers/checkout/api-integration/configure-secured-fields/styling-secured-fields)
```js
diff --git a/adyen-utils/.babelrc b/adyen-utils/.babelrc
deleted file mode 100644
index 4d83c57..0000000
--- a/adyen-utils/.babelrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "presets": [
- ["@babel/preset-env", {
- "targets": {
- "browsers": [ ">0.25%"]
- }
- }]
- ]
-}
diff --git a/adyen-utils/.gitignore b/adyen-utils/.gitignore
deleted file mode 100644
index d3f255a..0000000
--- a/adyen-utils/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-node_modules
-/coverage
-/.idea
-/*.log
-.idea
-.env
-.idea/
-
-.DS_Store
-stats.json
diff --git a/adyen-utils/LICENSE b/adyen-utils/LICENSE
deleted file mode 100644
index 9df8200..0000000
--- a/adyen-utils/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2019 Adyen bv
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/adyen-utils/README.md b/adyen-utils/README.md
deleted file mode 100644
index 48ce5b4..0000000
--- a/adyen-utils/README.md
+++ /dev/null
@@ -1,173 +0,0 @@
-# 3DS 2.0 JavaScript utilities
-
-These utilities are helper functions to get 3DS 2.0 integrated on to your webpage.
-
-## Requirements
-3DS 2.0 Back-end integration with Adyen: https://docs.adyen.com/classic-integration/3d-secure-2-classic-integration/browser-based-integration/
-
-## Installation
-
-#### Option A: Clone the repo and import functions directly through UMD / ES2015
-```javascript
-import collectBrowserInfo from "./browser";
-import base64Url from "./base64url";
-import createIframe from "./iframe";
-import createForm from "./form";
-import config from "./config.js";
-```
-
-#### Option B: Build the file, link to it and use ThreeDS2Utils on the global scope
-
-Install the development dependencies:
-```terminal
-npm install
-```
-Build the file:
-```terminal
-npm run build
-```
-
-Embed it on your page:
-```
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/components/FinishPayment.vue b/components/FinishPayment.vue
index e38140f..716503f 100644
--- a/components/FinishPayment.vue
+++ b/components/FinishPayment.vue
@@ -14,10 +14,13 @@
import config from 'config'
import i18n from '@vue-storefront/i18n';
import { currentStoreView } from '@vue-storefront/core/lib/multistore';
+import Shared from './Shared'
export default {
name: 'FinishPayment',
+ mixins: [Shared],
+
props: {
callback: {
type: Function,
@@ -40,43 +43,9 @@ export default {
}
},
- async mounted() {
- if (!document.getElementById('adyen-secured-fields')) {
- if (typeof window !== 'undefined') {
- try {
- await this.loadScript(
- 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/3.3.0/adyen.js'
- );
-
- this.createForm()
-
- } catch (err) {
- console.info(err, "Couldnt fetch adyen's library");
- }
- }
- } else {
- this.createForm();
- }
- },
-
methods: {
- /**
- * @description - Dynamicly fetches AdyenCheckout class
- */
- loadScript(src) {
- return new Promise((resolve, reject) => {
- let script = document.createElement('script');
- script.setAttribute('id', 'adyen-secured-fields');
- script.src = src;
- script.onload = () => resolve(script);
- script.onerror = () => reject(new Error('Script load error: ' + src));
- document.head.append(script);
- });
- },
-
- createForm () {
- const originKeys = this.$store.state.config.adyen.originKeys;
- const environment = this.$store.state.config.adyen.environment;
+ async createForm () {
+ const { originKeys, environment } = this.$store.state.config.adyen;
const origin = window.location.origin;
if (!originKeys[origin]) {
console.error('[Adyen] Set origin key in the config!');
@@ -93,9 +62,7 @@ export default {
method => method.type === 'scheme'
),
...(
- this.$store.getters['user/isLoggedIn']
- && this.$store.getters['payment-adyen/cards']
- && !!this.$store.getters['payment-adyen/cards'].length
+ this.hasStoredCards()
? { storedPaymentMethods: this.$store.getters['payment-adyen/cards'] }
: {}
)
@@ -107,10 +74,7 @@ export default {
async initPayment () {
try {
- let result = await this.$store.dispatch(
- 'payment-adyen/initPayment',
- this.$store.state['payment-adyen'].adyenCard
- );
+ const result = this.$store.state['payment-adyen'].three3ds2Details
// If it requires 3DS Auth
if (result.type) {
@@ -123,17 +87,17 @@ export default {
case 'ChallengeShopper':
this.renderThreeDS2Challenge(result.token);
break;
- case 'RedirectShopper':
- const self = this
- const { storeCode } = currentStoreView()
- const testsmth = this.adyenCheckoutInstance.createFromAction({
- ...result.action,
- data: {
- ...result.action.data,
- 'TermUrl': `${config.server.baseUrl.endsWith('/') ? config.server.baseUrl : (config.server.baseUrl + '/')}${storeCode}/finalize-3ds1`
- }
- }).mount('#redirectTo3ds1')
- break;
+ // case 'RedirectShopper':
+ // const self = this
+ // const { storeCode } = currentStoreView()
+ // const testsmth = this.adyenCheckoutInstance.createFromAction({
+ // ...result.action,
+ // data: {
+ // ...result.action.data,
+ // 'TermUrl': `${config.server.baseUrl.endsWith('/') ? config.server.baseUrl : (config.server.baseUrl + '/')}${storeCode}/finalize-3ds1`
+ // }
+ // }).mount('#redirectTo3ds1')
+ // break;
default:
this.$store.dispatch('notification/spawnNotification', {
type: 'error',
@@ -150,10 +114,6 @@ export default {
message: result.errorMessage,
action1: { label: i18n.t('OK') }
});
- } else {
- // 3DS Auth not needed, go further...
- this.callback()
- // self.$emit('payed', this.adyenCard);
}
} catch (err) {
console.error(err, 'Adyen');
@@ -169,7 +129,7 @@ export default {
fingerprintToken: token,
async onComplete({ data }) {
// It sends request to /adyen/threeDS2Process
- if (!data && data.details && data.details['threeds2.fingerprint']) {
+ if (!data || !data.details || !data.details['threeds2.fingerprint']) {
self.$store.dispatch('notification/spawnNotification', {
type: 'error',
message: i18n.t('Could not verify card data, sorry...'),
@@ -180,8 +140,8 @@ export default {
let response = await self.$store.dispatch(
'payment-adyen/fingerprint3ds',
{
- fingerprint:
- data && data.details && data.details['threeds2.fingerprint']
+ fingerprint: data && data.details && data.details['threeds2.fingerprint'],
+ orderId: self.$store.state['payment-adyen'].three3ds2Details.orderId
}
);
@@ -230,15 +190,15 @@ export default {
'payment-adyen/fingerprint3ds',
{
fingerprint: data.details['threeds2.challengeResult'],
+ orderId: self.$store.state['payment-adyen'].three3ds2Details.orderId,
challenge: true,
noPaymentData: true
}
);
self.threedsChallenge = false;
- // Finish the hardest way
- // self.$emit('payed', self.payloadToSend);
self.callback()
+ self.$store.dispatch('payment-adyen/setShowFinishPayment', false)
} else {
self.$store.dispatch('notification/spawnNotification', {
type: 'error',
@@ -249,6 +209,7 @@ export default {
},
onError(error) {
console.log('error', error);
+ self.$store.dispatch('payment-adyen/setShowFinishPayment', false)
}
}
);
diff --git a/components/Shared.ts b/components/Shared.ts
new file mode 100644
index 0000000..0aa14d0
--- /dev/null
+++ b/components/Shared.ts
@@ -0,0 +1,43 @@
+export default {
+ async mounted() {
+ if (!document.getElementById('adyen-secured-fields')) {
+ if (typeof window !== 'undefined') {
+ try {
+ await this.loadScript(
+ 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/3.3.0/adyen.js'
+ );
+
+ this.createForm()
+
+ } catch (err) {
+ console.info(err, "Couldnt fetch adyen's library");
+ }
+ }
+ } else {
+ this.createForm();
+ }
+ },
+
+ methods: {
+ /**
+ * @description - Dynamicly fetches AdyenCheckout SDK
+ */
+ loadScript(src) {
+ return new Promise((resolve, reject) => {
+ let script = document.createElement("script");
+ script.setAttribute("id", "adyen-secured-fields");
+ script.src = src;
+ script.onload = () => resolve(script);
+ script.onerror = () => reject(new Error("Script load error: " + src));
+ document.head.append(script);
+ });
+ },
+
+ hasStoredCards() {
+ const storedPaymentMethods = this.$store.getters["payment-adyen/cards"];
+ return this.$store.getters["user/isLoggedIn"] &&
+ storedPaymentMethods &&
+ !!storedPaymentMethods.length
+ }
+ }
+}
\ No newline at end of file
diff --git a/store/actions.ts b/store/actions.ts
index 10925b8..c56c21a 100644
--- a/store/actions.ts
+++ b/store/actions.ts
@@ -1,18 +1,14 @@
-import { AdyenState } from '../types/AdyenState';
-import rootStore from '@vue-storefront/core/store'
+import { AdyenState, AuthDetails } from '../types/AdyenState';
import { ActionTree } from 'vuex';
import * as types from './mutation-types';
import Vue from 'vue';
-// import axios from 'axios'
import { Logger } from '@vue-storefront/core/lib/logger'
import fetch from 'isomorphic-fetch'
import config from 'config'
import { currentStoreView, adjustMultistoreApiUrl } from '@vue-storefront/core/lib/multistore';
import SideRequest from '@vue-storefront/core/lib/side-request';
-// it's a good practice for all actions to return Promises with effect of their execution
export const actions: ActionTree = {
- // if you are using cache in your module it's a good practice to allow develoeprs to choose either to use it or not
saveCardData ({ commit }, { cardData }) {
return new Promise ((resolve, reject) => {
commit(types.ADD_CARD_DATA, cardData)
@@ -63,7 +59,7 @@ export const actions: ActionTree = {
if (rootGetters['user/getUserToken']) {
token = `?token=${rootGetters['user/getUserToken']}`
}
-
+
let response = await fetch(adjustMultistoreApiUrl(`${baseUrl}vault${token}`), {
method: 'POST'
})
@@ -96,7 +92,7 @@ export const actions: ActionTree = {
if (rootGetters['user/getUserToken']) {
token = `?token=${rootGetters['user/getUserToken']}`
}
-
+
let response = await fetch(`${baseUrl}methods/${storeCode}/${cartId}${token}`, {
method: 'POST',
body: JSON.stringify({
@@ -113,65 +109,86 @@ export const actions: ActionTree = {
}
},
- async initPayment ({ commit, rootGetters, rootState }, { method, additional_data, browserInfo, storePaymentMethod = false }) {
+ // async initPayment ({ commit, rootGetters, rootState }, { method, additional_data, browserInfo, storePaymentMethod = false }) {
+ // const cartId = rootGetters['cart/getCartToken']
+ // if (!cartId) {
+ // console.error('[Adyen] CartId does not exist')
+ // return
+ // }
+ // let token = ''
+ // if (rootGetters['user/getUserToken']) {
+ // token = `?token=${rootGetters['user/getUserToken']}`
+ // }
+
+ // // let customer_id = null
+ // // if (rootState.user.current && rootState.user.current.id) {
+ // // customer_id = rootState.user.current.id
+ // // }
+
+ // const baseUrl = `${SideRequest(config.api, 'url')}ext/payment-adyen/`
+
+ // try {
+ // const { storeCode } = currentStoreView()
+ // let response = await fetch(`${baseUrl}payment/start/${storeCode}/${cartId}${token}`, {
+ // method: 'POST',
+ // headers: {
+ // 'Content-Type': 'application/json'
+ // },
+ // body: JSON.stringify({
+ // method,
+ // additional_data: {
+ // number: additional_data.encryptedCardNumber,
+ // expiryMonth: additional_data.encryptedExpiryMonth,
+ // cvc: additional_data.encryptedSecurityCode,
+ // expiryYear: additional_data.encryptedExpiryYear,
+ // holderName: additional_data.holderName,
+ // ...browserInfo,
+ // allow3DS2: config.adyen.allow3DS2,
+ // channel: 'web',
+ // is_active_payment_token_enabler: !!storePaymentMethod,
+ // store_cc: !!storePaymentMethod,
+ // ...(additional_data.storedPaymentMethodId ? {
+ // storedPaymentMethodId: additional_data.storedPaymentMethodId,
+ // shopperInteraction: 'ContAuth',
+ // recurringProcessingModel: 'CardOnFile'
+ // } : {})
+ // }
+ // })
+ // })
+
+ // commit(types.SET_SAVE_CARD, !!storePaymentMethod)
+
+ // let { result } = await response.json()
+
+ // return result
+
+ // } catch (err) {
+ // console.error('[Adyen Payments]', err)
+ // }
+ // },
+
+ async checkPaymentStatus ({ rootGetters }, orderId) {
const cartId = rootGetters['cart/getCartToken']
if (!cartId) {
console.error('[Adyen] CartId does not exist')
return
}
- let token = ''
- if (rootGetters['user/getUserToken']) {
- token = `?token=${rootGetters['user/getUserToken']}`
- }
-
- // let customer_id = null
- // if (rootState.user.current && rootState.user.current.id) {
- // customer_id = rootState.user.current.id
- // }
-
const baseUrl = `${SideRequest(config.api, 'url')}ext/payment-adyen/`
+ // const baseUrl = `http://localhost:8080/api/ext/payment-adyen/`
try {
const { storeCode } = currentStoreView()
- let response = await fetch(`${baseUrl}payment/start/${storeCode}/${cartId}${token}`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({
- method,
- additional_data: {
- number: additional_data.encryptedCardNumber,
- expiryMonth: additional_data.encryptedExpiryMonth,
- cvc: additional_data.encryptedSecurityCode,
- expiryYear: additional_data.encryptedExpiryYear,
- holderName: additional_data.holderName,
- ...browserInfo,
- allow3DS2: config.adyen.allow3DS2,
- channel: 'web',
- is_active_payment_token_enabler: !!storePaymentMethod,
- store_cc: !!storePaymentMethod,
- ...(additional_data.storedPaymentMethodId ? {
- storedPaymentMethodId: additional_data.storedPaymentMethodId,
- shopperInteraction: 'ContAuth',
- recurringProcessingModel: 'CardOnFile'
- } : {})
- }
- })
- })
-
- commit(types.SET_SAVE_CARD, !!storePaymentMethod)
-
+ let response = await fetch(`${baseUrl}payment/status/${orderId}?storeCode=${storeCode}`)
let { result } = await response.json()
return result
-
+
} catch (err) {
console.error('[Adyen Payments]', err)
}
},
- async fingerprint3ds ({ commit, rootGetters, rootState }, { fingerprint, noPaymentData = false, challenge = false }) {
+ async fingerprint3ds ({ commit, rootGetters, rootState }, { orderId, fingerprint, noPaymentData = false, challenge = false }) {
const cartId = rootGetters['cart/getCartToken']
if (!cartId) {
console.error('[Adyen] CartId does not exist')
@@ -188,6 +205,7 @@ export const actions: ActionTree = {
// }
const baseUrl = `${SideRequest(config.api, 'url')}ext/payment-adyen/`
+ // const baseUrl = `http://localhost:8080/api/ext/payment-adyen/`
try {
const { storeCode } = currentStoreView()
@@ -198,6 +216,7 @@ export const actions: ActionTree = {
},
body: JSON.stringify({
fingerprint,
+ orderId,
...(noPaymentData ? {noPaymentData} : {}),
...(challenge ? {challenge} : {})
})
@@ -206,7 +225,7 @@ export const actions: ActionTree = {
let { result } = await response.json()
return result
-
+
} catch (err) {
console.error('[Adyen Payments]', err)
}
@@ -218,6 +237,14 @@ export const actions: ActionTree = {
setPublicHash ({ commit }, value) {
commit(types.SET_PUBLIC_HASH, value)
+ },
+
+ setShowFinishPayment ({ commit }, value) {
+ commit(types.SET_SHOW_FINISH_PAYMENT, value)
+ },
+
+ set3dsDetails ({ commit }, value: AuthDetails) {
+ commit(types.SET_3DS_DETAILS, value)
}
}
diff --git a/store/mutation-types.ts b/store/mutation-types.ts
index b17f93e..140dda0 100644
--- a/store/mutation-types.ts
+++ b/store/mutation-types.ts
@@ -6,3 +6,5 @@ export const SET_PAYMENT_METHODS = 'SET_PAYMENT_METHODS'
export const SET_SAVE_CARD = 'SET_SAVE_CARD'
export const SET_LOADED_CARDS = 'SET_LOADED_CARDS'
export const SET_PUBLIC_HASH = 'SET_PUBLIC_HASH'
+export const SET_SHOW_FINISH_PAYMENT = 'SET_SHOW_FINISH_PAYMENT'
+export const SET_3DS_DETAILS = 'SET_3DS_DETAILS'
diff --git a/store/mutations.ts b/store/mutations.ts
index aea9493..fe34ed3 100644
--- a/store/mutations.ts
+++ b/store/mutations.ts
@@ -1,6 +1,7 @@
import { MutationTree } from 'vuex'
import * as types from './mutation-types'
import Vue from 'vue'
+import { AuthDetails } from '../types/AdyenState'
export const mutations: MutationTree = {
[types.ADD_CARD_DATA] (state, payload) {
@@ -47,6 +48,14 @@ export const mutations: MutationTree = {
[types.SET_PUBLIC_HASH] (state, value) {
state.publicHash = value
+ },
+
+ [types.SET_SHOW_FINISH_PAYMENT] (state, value) {
+ state.showFinishPayment = value
+ },
+
+ [types.SET_3DS_DETAILS] (state, details: AuthDetails) {
+ Vue.set(state, 'three3ds2Details', details)
}
}
diff --git a/store/state.ts b/store/state.ts
index d59e694..0be19ce 100644
--- a/store/state.ts
+++ b/store/state.ts
@@ -6,5 +6,7 @@ export const state: AdyenState = {
paymentMethods: [],
saveCard: false,
loadedCards: [],
- publicHash: null
+ publicHash: null,
+ showFinishPayment: false,
+ three3ds2Details: null
}
diff --git a/types/AdyenState.ts b/types/AdyenState.ts
index 2d0a461..335351f 100644
--- a/types/AdyenState.ts
+++ b/types/AdyenState.ts
@@ -20,11 +20,18 @@ interface PaymentMethod {
brands?: Array
}
+export interface AuthDetails {
+ type: string,
+ token: string
+}
+
export interface AdyenState {
isAdyenValid: boolean | null,
adyenCard: any | null,
paymentMethods: Array,
saveCard: Boolean,
loadedCards: Array,
- publicHash: string | null
+ publicHash: string | null,
+ showFinishPayment: boolean,
+ three3ds2Details: AuthDetails
}