@viur/shop-components 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/ShopOrderStepper.vue
CHANGED
|
@@ -1,213 +1,264 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
2
|
+
<div class="loading-wrapper" v-if="state.loading">
|
|
3
|
+
<sl-spinner class="loading"></sl-spinner>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<div class="loading-wrapper" v-if="PaymentCheckIsActive">
|
|
7
|
+
<sl-spinner class="loading"></sl-spinner>
|
|
8
|
+
{{ $t('messages.wait_for_payment') }}
|
|
9
|
+
</div>
|
|
10
|
+
<div class="form-wrapper">
|
|
11
|
+
<sl-alert :open="state.hasError" variant="danger">{{ state.errorMessage }}</sl-alert>
|
|
12
|
+
<form class="unzerUI form" novalidate>
|
|
13
|
+
<template v-if="shopStore.state.order?.['payment_provider'] === 'unzer-card'">
|
|
14
|
+
<div class="field">
|
|
15
|
+
<div id="card-element-id-number" class="unzerInput">
|
|
16
|
+
<!-- Card number UI Element is inserted here. -->
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="two fields">
|
|
20
|
+
<div class="field ten wide">
|
|
21
|
+
<div id="card-element-id-expiry" class="unzerInput">
|
|
22
|
+
<!-- Card expiry date UI Element is inserted here. -->
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field six wide">
|
|
26
|
+
<div id="card-element-id-cvc" class="unzerInput">
|
|
27
|
+
<!-- Card CVC UI Element is inserted here. -->
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<template v-else-if="shopStore.state.order?.['payment_provider'] === 'unzer-paypal'">
|
|
34
|
+
<sl-alert open variant="danger">{{ $t('viur.shop.paypal_client_popup_info') }}</sl-alert>
|
|
35
|
+
<div id="paypal-element" class="field"></div>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<template v-else-if="shopStore.state.order?.['payment_provider'] === 'unzer-ideal'">
|
|
39
|
+
<div id="ideal-element" class="field"></div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<template v-else-if="shopStore.state.order?.['payment_provider'] === 'unzer-googlepay'">
|
|
43
|
+
<div id="googlepay-element" class="field"></div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<template v-else-if="shopStore.state.order?.['payment_provider'] === 'unzer-paylater_invoice'">
|
|
47
|
+
<p v-html="$t('viur.shop.missing_birthdate', shopStore.state.order.billing_address.dest)"/>
|
|
48
|
+
<sl-input
|
|
49
|
+
slot="left"
|
|
50
|
+
type="date"
|
|
51
|
+
min="1900-01-01"
|
|
52
|
+
:max="new Date().toISOString().slice(0, 10)"
|
|
53
|
+
:placeholder="$t('viur.shop.birthdate')"
|
|
54
|
+
:label="$t('viur.shop.birthdate')"
|
|
55
|
+
:value="state.birthdate"
|
|
56
|
+
@sl-change="birthdateChange"
|
|
57
|
+
:disabled="state.loading"
|
|
58
|
+
></sl-input>
|
|
59
|
+
<div id="paylater-invoice-element" class="field"></div>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<p
|
|
63
|
+
v-if="!!shopStore.state?.paymentProviderData?.redirectUrl"
|
|
64
|
+
v-html="$t('viur.shop.payment_link', {url: shopStore.state.paymentProviderData.redirectUrl})"
|
|
65
|
+
/>
|
|
66
|
+
</form>
|
|
67
|
+
|
|
68
|
+
<button
|
|
69
|
+
v-if="shopStore.state.order?.['payment_provider'] !== 'unzer-googlepay'"
|
|
70
|
+
:disabled="state.loading || state.birthdateIsInvalid"
|
|
71
|
+
class="unzerUI primary button fluid"
|
|
72
|
+
@click="submitFormToUnzer"
|
|
73
|
+
>{{ $t('viur.shop.pay') }}
|
|
74
|
+
</button>
|
|
75
|
+
<sl-button :disabled="state.loading" variant="danger" @click="cancelPayment">
|
|
76
|
+
{{ $t('actions.cancel') }}
|
|
77
|
+
</sl-button>
|
|
78
|
+
</div>
|
|
62
79
|
</template>
|
|
63
80
|
|
|
64
81
|
<script setup>
|
|
65
82
|
import {Request} from '@viur/vue-utils';
|
|
83
|
+
import {HTTPError} from '@viur/vue-utils/utils/request.js';
|
|
66
84
|
import {useIntervalFn} from '@vueuse/core';
|
|
67
85
|
import {computed, onBeforeMount, reactive} from 'vue';
|
|
86
|
+
import {useAddress} from '../composables/address.js';
|
|
68
87
|
import {useOrder} from '../composables/order';
|
|
69
88
|
import {useViurShopStore} from '../shop';
|
|
70
89
|
|
|
71
90
|
const shopStore = useViurShopStore();
|
|
72
91
|
const {fetchOrder} = useOrder();
|
|
92
|
+
const {saveBirthdate} = useAddress();
|
|
73
93
|
|
|
74
94
|
const emits = defineEmits(['cancel']);
|
|
75
95
|
|
|
76
96
|
const {pause: PaymentCheckPause, resume: PaymentCheckResume, isActive: PaymentCheckIsActive} = useIntervalFn(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
console.debug('checking ...');
|
|
98
|
+
|
|
99
|
+
fetchOrder(shopStore.state.orderKey).then(() => {
|
|
100
|
+
if (shopStore.state.order?.['is_paid']) {
|
|
101
|
+
console.debug('Order is paid');
|
|
102
|
+
shopStore.navigateToTab('complete');
|
|
103
|
+
PaymentCheckPause();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
86
106
|
|
|
87
107
|
}, 2000, {immediate: false});
|
|
88
108
|
|
|
89
109
|
|
|
90
110
|
const state = reactive({
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
unzer: computed(() => {
|
|
112
|
+
if (!shopStore.state.paymentProviderData) return null;
|
|
113
|
+
return new unzer(shopStore.state.paymentProviderData['public_key'], {locale: shopStore.state.locale});
|
|
114
|
+
}),
|
|
115
|
+
paymentHandler: {},
|
|
116
|
+
loading: false,
|
|
117
|
+
hasError: false,
|
|
118
|
+
errorMessage: null,
|
|
119
|
+
waitPayment: false,
|
|
120
|
+
birthdate: null,
|
|
121
|
+
birthdateIsInvalid: false,
|
|
100
122
|
});
|
|
101
123
|
|
|
102
124
|
/**
|
|
103
125
|
* Initialize the payment type creation with Unzer-UI components
|
|
104
126
|
*/
|
|
105
127
|
function initUnzerForm() {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
128
|
+
//Unzer field definition
|
|
129
|
+
if (shopStore.state.order?.['payment_provider'] === 'unzer-card') {
|
|
130
|
+
const card = state.unzer.Card();
|
|
131
|
+
// Rendering input field card number
|
|
132
|
+
card.create('number', {
|
|
133
|
+
containerId: 'card-element-id-number',
|
|
134
|
+
onlyIframe: false,
|
|
135
|
+
});
|
|
136
|
+
// Rendering input field card expiry
|
|
137
|
+
card.create('expiry', {
|
|
138
|
+
containerId: 'card-element-id-expiry',
|
|
139
|
+
onlyIframe: false,
|
|
140
|
+
});
|
|
141
|
+
// Rendering input field card cvc
|
|
142
|
+
card.create('cvc', {
|
|
143
|
+
containerId: 'card-element-id-cvc',
|
|
144
|
+
onlyIframe: false,
|
|
145
|
+
});
|
|
146
|
+
state.paymentHandler['unzer-card'] = card;
|
|
147
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-paypal') {
|
|
148
|
+
// Creating a PayPal instance
|
|
149
|
+
const paypal = state.unzer.Paypal();
|
|
150
|
+
// Rendering input field
|
|
151
|
+
//paypal.create('email', {
|
|
152
|
+
// containerId: 'paypal-element',
|
|
153
|
+
//});
|
|
154
|
+
state.paymentHandler['unzer-paypal'] = paypal;
|
|
155
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-sofort') {
|
|
156
|
+
const sofort = state.unzer.Sofort();
|
|
157
|
+
state.paymentHandler['unzer-sofort'] = sofort;
|
|
158
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-ideal') {
|
|
159
|
+
const ideal = state.unzer.Ideal();
|
|
160
|
+
ideal.create('ideal', {
|
|
161
|
+
containerId: 'ideal-element',
|
|
162
|
+
});
|
|
163
|
+
state.paymentHandler['unzer-ideal'] = ideal;
|
|
164
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-bancontact') {
|
|
165
|
+
const bancontact = state.unzer.Bancontact();
|
|
166
|
+
state.paymentHandler['unzer-bancontact'] = bancontact;
|
|
167
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-googlepay') {
|
|
168
|
+
const googlepayScriptPromise = new Promise((resolve, reject) => {
|
|
169
|
+
const googlepayScript = document.createElement('script');
|
|
170
|
+
googlepayScript.setAttribute('src', 'https://pay.google.com/gp/p/js/pay.js');
|
|
171
|
+
googlepayScript.onload = () => {
|
|
172
|
+
resolve(googlepayScript);
|
|
173
|
+
};
|
|
174
|
+
googlepayScript.onerror = reject;
|
|
175
|
+
document.head.appendChild(googlepayScript);
|
|
176
|
+
});
|
|
177
|
+
const googlepay = state.unzer.Googlepay();
|
|
178
|
+
state.paymentHandler['unzer-googlepay'] = googlepay;
|
|
179
|
+
const paymentDataRequestObject = googlepay.initPaymentDataRequestObject({
|
|
180
|
+
gatewayMerchantId: shopStore.state.paymentProviderData.channel,
|
|
181
|
+
merchantInfo: {
|
|
182
|
+
merchantId: shopStore.state.paymentProviderData.merchant_id,
|
|
183
|
+
merchantName: shopStore.state.paymentProviderData.merchant_name,
|
|
184
|
+
},
|
|
185
|
+
transactionInfo: {
|
|
186
|
+
countryCode: shopStore.state.order.billing_address.dest['country'].toUpperCase(),
|
|
187
|
+
currencyCode: 'EUR',
|
|
188
|
+
totalPrice: shopStore.state.order.total.toString(),
|
|
189
|
+
totalPriceStatus: 'ESTIMATED', // backend should have the last words
|
|
190
|
+
// totalPriceStatus: 'FINAL',
|
|
191
|
+
// checkoutOption: 'COMPLETE_IMMEDIATE_PURCHASE',
|
|
192
|
+
},
|
|
193
|
+
// buttonColor: 'white',
|
|
194
|
+
allowedCardNetworks: shopStore.state.paymentProviderData.brands,
|
|
195
|
+
allowCreditCards: shopStore.state.paymentProviderData.allow_credit_cards,
|
|
196
|
+
allowPrepaidCards: shopStore.state.paymentProviderData.allow_prepaid_cards,
|
|
197
|
+
|
|
198
|
+
onPaymentAuthorizedCallback: (paymentData) => {
|
|
199
|
+
PaymentCheckPause();
|
|
200
|
+
state.loading = true;
|
|
201
|
+
state.hasError = false;
|
|
202
|
+
|
|
203
|
+
return googlepay.createResource(paymentData)
|
|
204
|
+
.then(result => {
|
|
205
|
+
console.debug(result);
|
|
206
|
+
saveType(result.id);
|
|
207
|
+
return {status: 'success'}; // Tell Google Pay we could handle it
|
|
208
|
+
})
|
|
209
|
+
.catch(function (error) {
|
|
210
|
+
paymentError(error);
|
|
211
|
+
return { // Tell Google Pay we could NOT handle it
|
|
212
|
+
status: 'error',
|
|
213
|
+
message: error.customerMessage || error.message || error || 'Unexpected error',
|
|
151
214
|
};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
onPaymentAuthorizedCallback: (paymentData) => {
|
|
177
|
-
PaymentCheckPause();
|
|
178
|
-
state.loading = true;
|
|
179
|
-
state.hasError = false;
|
|
180
|
-
|
|
181
|
-
return googlepay.createResource(paymentData)
|
|
182
|
-
.then(result => {
|
|
183
|
-
console.debug(result);
|
|
184
|
-
saveType(result.id);
|
|
185
|
-
return {status: 'success'}; // Tell Google Pay we could handle it
|
|
186
|
-
})
|
|
187
|
-
.catch(function (error) {
|
|
188
|
-
paymentError(error);
|
|
189
|
-
return { // Tell Google Pay we could NOT handle it
|
|
190
|
-
status: 'error',
|
|
191
|
-
message: error.customerMessage || error.message || error || 'Unexpected error',
|
|
192
|
-
};
|
|
193
|
-
});
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
console.debug('unzer-googlepay', googlepay, paymentDataRequestObject);
|
|
197
|
-
// TODO: How can we catch >Uncaught (in promise) AbortError: User closed the Payment Request UI.< ?
|
|
198
|
-
googlepayScriptPromise.then(() => {
|
|
199
|
-
// gpay script has been loaded, we can start the payment
|
|
200
|
-
googlepay.create(
|
|
201
|
-
{containerId: 'googlepay-element'},
|
|
202
|
-
paymentDataRequestObject,
|
|
203
|
-
);
|
|
204
|
-
});
|
|
205
|
-
} else {
|
|
206
|
-
console.warn(`Unknown payment provider: ${shopStore.state.order?.['payment_provider']}`);
|
|
207
|
-
}
|
|
208
|
-
state.loading = false;
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
console.debug('unzer-googlepay', googlepay, paymentDataRequestObject);
|
|
219
|
+
// TODO: How can we catch >Uncaught (in promise) AbortError: User closed the Payment Request UI.< ?
|
|
220
|
+
googlepayScriptPromise.then(() => {
|
|
221
|
+
// gpay script has been loaded, we can start the payment
|
|
222
|
+
googlepay.create(
|
|
223
|
+
{containerId: 'googlepay-element'},
|
|
224
|
+
paymentDataRequestObject,
|
|
225
|
+
);
|
|
226
|
+
});
|
|
227
|
+
} else if (shopStore.state.order?.['payment_provider'] === 'unzer-paylater_invoice') {
|
|
228
|
+
state.birthdateIsInvalid = true; // no value --> invalid
|
|
229
|
+
const paylaterInvoice = state.unzer.PaylaterInvoice();
|
|
230
|
+
paylaterInvoice.create({
|
|
231
|
+
containerId: 'paylater-invoice-element',
|
|
232
|
+
customerType: 'B2C', // or B2B
|
|
233
|
+
});
|
|
234
|
+
state.paymentHandler['unzer-paylater_invoice'] = paylaterInvoice;
|
|
235
|
+
} else {
|
|
236
|
+
console.warn(`Unknown payment provider: ${shopStore.state.order?.['payment_provider']}`);
|
|
237
|
+
}
|
|
238
|
+
state.loading = false;
|
|
209
239
|
}
|
|
210
240
|
|
|
241
|
+
function birthdateChange(event) {
|
|
242
|
+
console.debug('birthdateChange', arguments);
|
|
243
|
+
if (!event.target.value || !event.target.checkValidity()) {
|
|
244
|
+
// state.birthdate = null;
|
|
245
|
+
state.birthdateIsInvalid = true;
|
|
246
|
+
} else {
|
|
247
|
+
state.birthdate = event.target.value;
|
|
248
|
+
state.birthdateIsInvalid = false;
|
|
249
|
+
state.loading = true;
|
|
250
|
+
saveBirthdate(shopStore.state.order.billing_address.dest['key'], event.target.value)
|
|
251
|
+
.then(result => {
|
|
252
|
+
console.debug(result);
|
|
253
|
+
})
|
|
254
|
+
.catch(paymentError)
|
|
255
|
+
.finally(() => {
|
|
256
|
+
state.loading = false;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
|
|
211
262
|
/**
|
|
212
263
|
* Handle an error
|
|
213
264
|
*
|
|
@@ -215,10 +266,17 @@ function initUnzerForm() {
|
|
|
215
266
|
* with a translated (and detailed) description for the customer
|
|
216
267
|
*/
|
|
217
268
|
function paymentError(error) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
269
|
+
console.error(error);
|
|
270
|
+
state.loading = false;
|
|
271
|
+
state.hasError = true;
|
|
272
|
+
if (error && error.constructor.name === HTTPError.name && error.response.headers.get('x-viur-shop-error')) {
|
|
273
|
+
error.response.json().then(res => {
|
|
274
|
+
console.error(res.errors);
|
|
275
|
+
state.errorMessage = res.errors.map(err => err.customer_message || err.message).join(', ');
|
|
276
|
+
});
|
|
277
|
+
} else {
|
|
221
278
|
state.errorMessage = error.customerMessage || error.message || error || 'Error';
|
|
279
|
+
}
|
|
222
280
|
}
|
|
223
281
|
|
|
224
282
|
/**
|
|
@@ -227,13 +285,15 @@ function paymentError(error) {
|
|
|
227
285
|
* This function is used by all unzer pyment types, except Google Pay.
|
|
228
286
|
*/
|
|
229
287
|
function submitFormToUnzer() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
288
|
+
PaymentCheckPause();
|
|
289
|
+
state.loading = true;
|
|
290
|
+
state.hasError = false;
|
|
291
|
+
state.paymentHandler[shopStore.state.order?.['payment_provider']].createResource()
|
|
292
|
+
.then((result) => {
|
|
293
|
+
saveType(result.id);
|
|
294
|
+
})
|
|
295
|
+
.catch((error) => {
|
|
296
|
+
paymentError(error);
|
|
237
297
|
});
|
|
238
298
|
}
|
|
239
299
|
|
|
@@ -245,73 +305,74 @@ function submitFormToUnzer() {
|
|
|
245
305
|
* @param typeId The type-id of the created Type, e.g. ``s-crd-abc123def456``
|
|
246
306
|
*/
|
|
247
307
|
function saveType(typeId) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
}).catch(error => {
|
|
269
|
-
paymentError(error);
|
|
308
|
+
const paymenttarget = shopStore.state.order?.['payment_provider'].split('-').slice(1).join('-');
|
|
309
|
+
Request.post(`${shopStore.state.shopUrl}/pp_unzer_${paymenttarget}/save_type`, {
|
|
310
|
+
dataObj: {
|
|
311
|
+
order_key: shopStore.state.orderKey,
|
|
312
|
+
type_id: typeId,
|
|
313
|
+
},
|
|
314
|
+
}).then(async (resp) => {
|
|
315
|
+
shopStore.state.order = await resp.json();
|
|
316
|
+
shopStore.checkoutOrder().then((resp) => {
|
|
317
|
+
state.loading = false;
|
|
318
|
+
state.hasError = false;
|
|
319
|
+
if (shopStore.state.paymentProviderData?.redirectUrl) {
|
|
320
|
+
state.waitPayment = true;
|
|
321
|
+
window.open(shopStore.state.paymentProviderData.redirectUrl, '_blank', 'popup');
|
|
322
|
+
PaymentCheckResume();
|
|
323
|
+
}
|
|
324
|
+
}).catch(async (error) => {
|
|
325
|
+
paymentError(error);
|
|
270
326
|
});
|
|
327
|
+
|
|
328
|
+
}).catch(error => {
|
|
329
|
+
paymentError(error);
|
|
330
|
+
});
|
|
271
331
|
}
|
|
272
332
|
|
|
273
333
|
|
|
274
334
|
function cancelPayment() {
|
|
275
|
-
|
|
276
|
-
|
|
335
|
+
PaymentCheckPause();
|
|
336
|
+
emits('cancel');
|
|
277
337
|
}
|
|
278
338
|
|
|
279
339
|
onBeforeMount(() => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
|
|
340
|
+
state.loading = true;
|
|
341
|
+
if (!shopStore.state.paymentProviderData) {
|
|
342
|
+
shopStore.checkout().then(() => {
|
|
343
|
+
initUnzerForm();
|
|
344
|
+
fetchOrder(shopStore.state.orderKey); // refresh order after checkout_start freeze
|
|
345
|
+
}).catch((error) => {
|
|
346
|
+
console.log(error);
|
|
347
|
+
});
|
|
348
|
+
} else {
|
|
349
|
+
initUnzerForm();
|
|
350
|
+
}
|
|
290
351
|
});
|
|
291
352
|
|
|
292
353
|
</script>
|
|
293
354
|
|
|
294
355
|
<style scoped>
|
|
295
356
|
.loading-wrapper {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
357
|
+
display: flex;
|
|
358
|
+
flex-direction: column;
|
|
359
|
+
align-items: center;
|
|
299
360
|
}
|
|
300
361
|
|
|
301
362
|
.form-wrapper {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
363
|
+
display: flex;
|
|
364
|
+
flex-direction: column;
|
|
365
|
+
gap: 20px;
|
|
305
366
|
}
|
|
306
367
|
|
|
307
368
|
.loading {
|
|
308
|
-
|
|
369
|
+
font-size: 3rem;
|
|
309
370
|
}
|
|
310
371
|
</style>
|
|
311
372
|
|
|
312
373
|
<style>
|
|
313
374
|
/* global style to overwrite UnzerCSS */
|
|
314
375
|
.unzerUI.primary.button, .unzerUI.primary.buttons .button {
|
|
315
|
-
|
|
376
|
+
background-color: var(--ignt-color-primary) !important;
|
|
316
377
|
}
|
|
317
378
|
</style>
|
|
@@ -4,6 +4,7 @@ import {useCart} from '../composables/cart';
|
|
|
4
4
|
import {useOrder} from '../composables/order';
|
|
5
5
|
import {useViurShopStore} from '../shop';
|
|
6
6
|
import {useShipping} from './shipping.js';
|
|
7
|
+
import {Request} from '@viur/vue-utils';
|
|
7
8
|
|
|
8
9
|
export const useAddress = defineStore('useAddressStore', () => {
|
|
9
10
|
const shopStore = useViurShopStore();
|
|
@@ -110,10 +111,34 @@ export const useAddress = defineStore('useAddressStore', () => {
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
function saveBirthdate(addressKey, birthdate) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
Request.securePost(
|
|
117
|
+
`/json/${shopStore.state.moduleName}/address/edit/${addressKey}`, {
|
|
118
|
+
dataObj: {
|
|
119
|
+
'@order': shopStore.state.orderKey,
|
|
120
|
+
birthdate,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
)
|
|
124
|
+
.then(async (res) => {
|
|
125
|
+
const data = await res.json();
|
|
126
|
+
if (data['action'] === 'editSuccess') {
|
|
127
|
+
resolve(data);
|
|
128
|
+
} else {
|
|
129
|
+
reject(`Update failed`);
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
.catch(reject);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
113
137
|
return {
|
|
114
138
|
state,
|
|
115
139
|
saveForm,
|
|
116
140
|
updateAddresses,
|
|
117
141
|
saveAddresses,
|
|
142
|
+
saveBirthdate,
|
|
118
143
|
};
|
|
119
144
|
});
|
package/src/translations/de.js
CHANGED
|
@@ -59,6 +59,8 @@ export default {
|
|
|
59
59
|
'order_step_complete': 'Bestellung Abgeschlossen',
|
|
60
60
|
'paypal_client_popup_info': 'Bitte prüfen Sie, ob Ihr Browser das PayPal-Popup zulässt.',
|
|
61
61
|
'payment_link': 'Ihr Browser öffnet kein Popup? Dann klicken Sie bitte <a href="{url}" target="_blank">hier</a>.',
|
|
62
|
+
'birthdate': 'Geburtsdatum',
|
|
63
|
+
'missing_birthdate': 'Bei der ausgewählten Bezahlmethode benötigen wir zur Rechnungsadresse noch das Geburtsdatum von <i>{firstname} {lastname}</i>.',
|
|
62
64
|
},
|
|
63
65
|
},
|
|
64
66
|
messages: {
|
package/src/translations/en.js
CHANGED
|
@@ -58,6 +58,8 @@ export default {
|
|
|
58
58
|
'order_step_complete': 'Order complete',
|
|
59
59
|
'paypal_client_popup_info': 'Please make sure your browser allows the PayPal popup.',
|
|
60
60
|
'payment_link': 'Your browser does not open a popup? Then please click <a href="{url}" target="_blank">here</a>.',
|
|
61
|
+
'birthdate': 'date of birth',
|
|
62
|
+
'missing_birthdate': 'For the selected payment method, we require the date of birth of <i>{firstname} {lastname}</i> in addition to the billing address.',
|
|
61
63
|
},
|
|
62
64
|
},
|
|
63
65
|
messages: {
|
package/src/translations/fr.js
CHANGED
|
@@ -59,6 +59,8 @@ export default {
|
|
|
59
59
|
'order_step_complete': 'Valider la commande',
|
|
60
60
|
'paypal_client_popup_info':"Assurez-vous que votre navigateur autorise la fenêtre contextuelle PayPal.",
|
|
61
61
|
'payment_link': 'Votre navigateur n\'ouvre pas de popup ? Alors cliquez <a href="{url}" target="_blank">ici</a>.',
|
|
62
|
+
'birthdate': 'date de naissance',
|
|
63
|
+
'missing_birthdate': 'Pour le mode de paiement sélectionné, nous avons besoin, en plus de l\'adresse de facturation, de la date de naissance de <i>{firstname} {lastname}</i>.',
|
|
62
64
|
},
|
|
63
65
|
},
|
|
64
66
|
messages: {
|