@goweekdays/layer-common 0.0.12 → 0.0.13
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/CHANGELOG.md +6 -0
- package/components/AddPaymentMethod.vue +18 -23
- package/components/Std/Pagination.vue +52 -0
- package/components/TableList.vue +3 -1
- package/composables/useAddress.ts +30 -0
- package/composables/useInvoice.ts +4 -0
- package/composables/usePaymentMethod.ts +144 -12
- package/composables/useSubscription.ts +57 -0
- package/composables/useUtils.ts +4 -1
- package/middleware/01.auth.ts +0 -9
- package/package.json +1 -1
- package/pages/payment-method-cancel-link.vue +31 -0
- package/pages/payment-method-failed-link.vue +31 -0
- package/types/invoice.d.ts +28 -0
- package/types/payment-method.d.ts +11 -0
- package/types/subscription.d.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
3
|
<v-col cols="12">
|
|
4
|
-
<
|
|
4
|
+
<v-item-group
|
|
5
|
+
v-model.number="selectedPaymentMethod"
|
|
6
|
+
selected-class="bg-cyan-accent-1"
|
|
7
|
+
mandatory
|
|
8
|
+
>
|
|
5
9
|
<v-row no-gutters>
|
|
6
|
-
<v-col cols="12"
|
|
7
|
-
|
|
10
|
+
<v-col cols="12">
|
|
11
|
+
<InputLabel title="E-Wallet" />
|
|
8
12
|
</v-col>
|
|
9
|
-
</v-row>
|
|
10
|
-
</slot>
|
|
11
|
-
</v-col>
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
<v-row no-gutters>
|
|
15
|
-
<v-col cols="12">
|
|
16
|
-
<v-item-group
|
|
17
|
-
v-model.number="selectedPaymentMethod"
|
|
18
|
-
selected-class="bg-cyan-accent-1"
|
|
19
|
-
mandatory
|
|
20
|
-
>
|
|
14
|
+
<v-col cols="12" class="mt-2">
|
|
21
15
|
<v-row>
|
|
22
|
-
<v-col cols="12">
|
|
23
|
-
<InputLabel title="E-Wallet" />
|
|
24
|
-
</v-col>
|
|
25
16
|
<template v-for="eWalletItem in props.supportedEwallets">
|
|
26
17
|
<v-col cols="12" lg="3" md="4" sm="4">
|
|
27
18
|
<v-item v-slot="{ toggle, selectedClass }">
|
|
@@ -37,11 +28,15 @@
|
|
|
37
28
|
</v-item>
|
|
38
29
|
</v-col>
|
|
39
30
|
</template>
|
|
31
|
+
</v-row>
|
|
32
|
+
</v-col>
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
<v-col cols="12" class="mt-6">
|
|
35
|
+
<InputLabel title="Direct Debit" />
|
|
36
|
+
</v-col>
|
|
44
37
|
|
|
38
|
+
<v-col cols="12" class="mt-2">
|
|
39
|
+
<v-row>
|
|
45
40
|
<template
|
|
46
41
|
v-for="supportedDirectDebitItem in props.supportedDirectDebit"
|
|
47
42
|
>
|
|
@@ -64,9 +59,9 @@
|
|
|
64
59
|
</v-col>
|
|
65
60
|
</template>
|
|
66
61
|
</v-row>
|
|
67
|
-
</v-
|
|
68
|
-
</v-
|
|
69
|
-
</v-
|
|
62
|
+
</v-col>
|
|
63
|
+
</v-row>
|
|
64
|
+
</v-item-group>
|
|
70
65
|
</v-col>
|
|
71
66
|
</v-row>
|
|
72
67
|
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters justify="end" align="center">
|
|
3
|
+
<span class="mr-2 text-caption text-fontgray">
|
|
4
|
+
{{ props.pageRange }}
|
|
5
|
+
</span>
|
|
6
|
+
<div class="arrow-navigation">
|
|
7
|
+
<v-btn
|
|
8
|
+
icon="mdi-chevron-left"
|
|
9
|
+
variant="text"
|
|
10
|
+
density="comfortable"
|
|
11
|
+
:disabled="page <= 1"
|
|
12
|
+
@click="decrement"
|
|
13
|
+
/>
|
|
14
|
+
<v-btn
|
|
15
|
+
icon="mdi-chevron-right"
|
|
16
|
+
variant="text"
|
|
17
|
+
density="comfortable"
|
|
18
|
+
:disabled="page >= props.pages"
|
|
19
|
+
@click="increment"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</v-row>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
const page = defineModel({ type: Number, default: 0 });
|
|
27
|
+
|
|
28
|
+
const props = defineProps({
|
|
29
|
+
pages: {
|
|
30
|
+
type: Number,
|
|
31
|
+
required: true,
|
|
32
|
+
default: 0,
|
|
33
|
+
},
|
|
34
|
+
pageRange: {
|
|
35
|
+
type: String,
|
|
36
|
+
required: true,
|
|
37
|
+
default: "-- - -- of --",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const emit = defineEmits(["refresh", "update:pagination"]);
|
|
42
|
+
|
|
43
|
+
function increment() {
|
|
44
|
+
page.value++;
|
|
45
|
+
emit("update:pagination", page.value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function decrement() {
|
|
49
|
+
page.value--;
|
|
50
|
+
emit("update:pagination", page.value);
|
|
51
|
+
}
|
|
52
|
+
</script>
|
package/components/TableList.vue
CHANGED
|
@@ -43,10 +43,11 @@
|
|
|
43
43
|
<slot name="extension"></slot>
|
|
44
44
|
</template>
|
|
45
45
|
</v-toolbar>
|
|
46
|
+
<v-divider></v-divider>
|
|
46
47
|
|
|
47
48
|
<v-data-table
|
|
48
49
|
v-model="selected"
|
|
49
|
-
v-bind="
|
|
50
|
+
v-bind="attrs"
|
|
50
51
|
:headers="props.headers"
|
|
51
52
|
:items="props.items"
|
|
52
53
|
item-value="_id"
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
</template>
|
|
67
68
|
|
|
68
69
|
<script setup lang="ts">
|
|
70
|
+
const attrs = useAttrs();
|
|
69
71
|
const selected = defineModel({
|
|
70
72
|
type: Array as PropType<Array<string>>,
|
|
71
73
|
default: () => [],
|
|
@@ -32,10 +32,38 @@ export default function useAddress() {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function updateById({
|
|
36
|
+
id = "",
|
|
37
|
+
country = "",
|
|
38
|
+
address = "",
|
|
39
|
+
continuedAddress = "",
|
|
40
|
+
city = "",
|
|
41
|
+
province = "",
|
|
42
|
+
postalCode = "",
|
|
43
|
+
taxId = "",
|
|
44
|
+
} = {}) {
|
|
45
|
+
return useNuxtApp().$api(`/api/addresses/details/${id}`, {
|
|
46
|
+
method: "PUT",
|
|
47
|
+
body: {
|
|
48
|
+
country,
|
|
49
|
+
address,
|
|
50
|
+
continuedAddress,
|
|
51
|
+
city,
|
|
52
|
+
province,
|
|
53
|
+
postalCode,
|
|
54
|
+
taxId,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
35
59
|
function getByUserId(user = "") {
|
|
36
60
|
return useNuxtApp().$api<TAddress>(`/api/addresses/user/${user}`);
|
|
37
61
|
}
|
|
38
62
|
|
|
63
|
+
function getByOrgId(id = "") {
|
|
64
|
+
return useNuxtApp().$api<TAddress>(`/api/addresses/org/${id}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
39
67
|
const _address = useState("address", (): TAddress => {
|
|
40
68
|
return {
|
|
41
69
|
type: "",
|
|
@@ -103,5 +131,7 @@ export default function useAddress() {
|
|
|
103
131
|
getByUserId,
|
|
104
132
|
address: _address,
|
|
105
133
|
completeAddress,
|
|
134
|
+
getByOrgId,
|
|
135
|
+
updateById,
|
|
106
136
|
};
|
|
107
137
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export default function useInvoice() {
|
|
2
2
|
function getBySubscriptionId({ search = "", id = "", page = 1 } = {}) {
|
|
3
|
+
if (!id) {
|
|
4
|
+
throw new Error("Subscription ID is required");
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
return useNuxtApp().$api<Record<string, any>>(
|
|
4
8
|
`/api/invoices/subscription/${id}`,
|
|
5
9
|
{
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
1
3
|
export default function usePaymentMethod() {
|
|
2
4
|
function linkEWallet({
|
|
3
5
|
type = "GCASH",
|
|
@@ -72,10 +74,7 @@ export default function usePaymentMethod() {
|
|
|
72
74
|
|
|
73
75
|
function getById(id = "") {
|
|
74
76
|
return useNuxtApp().$api<Record<string, any>>(
|
|
75
|
-
`/api/payment-methods/id/${id}
|
|
76
|
-
{
|
|
77
|
-
method: "GET",
|
|
78
|
-
}
|
|
77
|
+
`/api/payment-methods/id/${id}`
|
|
79
78
|
);
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -86,14 +85,6 @@ export default function usePaymentMethod() {
|
|
|
86
85
|
const cardholderName = useState("cardholderName", () => "");
|
|
87
86
|
const selectedPaymentMethod = useState("selectedPaymentMethod", () => "");
|
|
88
87
|
|
|
89
|
-
function reset() {
|
|
90
|
-
eWalletNumber.value = "";
|
|
91
|
-
cardNumber.value = "";
|
|
92
|
-
cardExpiration.value = "";
|
|
93
|
-
cardSecurityCode.value = "";
|
|
94
|
-
cardholderName.value = "";
|
|
95
|
-
}
|
|
96
|
-
|
|
97
88
|
function linkOnly(value: Record<string, any>) {
|
|
98
89
|
return useNuxtApp().$api<Record<string, any>>(
|
|
99
90
|
"/api/payment-methods/link-only",
|
|
@@ -160,6 +151,142 @@ export default function usePaymentMethod() {
|
|
|
160
151
|
...supportedDirectDebit,
|
|
161
152
|
];
|
|
162
153
|
|
|
154
|
+
const { updatePaymentMethodById } = useSubscription();
|
|
155
|
+
|
|
156
|
+
const linkingOverlay = useState("linkingOverlay", () => false);
|
|
157
|
+
const updatingPaymentMethod = useState("updatingPaymentMethod", () => false);
|
|
158
|
+
const linkingMessage = useState("linkingMessage", () => "");
|
|
159
|
+
const paymentMethod = useState(
|
|
160
|
+
"paymentMethod",
|
|
161
|
+
(): Record<string, any> | null => null
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
function reset() {
|
|
165
|
+
eWalletNumber.value = "";
|
|
166
|
+
cardNumber.value = "";
|
|
167
|
+
cardExpiration.value = "";
|
|
168
|
+
cardSecurityCode.value = "";
|
|
169
|
+
cardholderName.value = "";
|
|
170
|
+
paymentMethod.value = null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function initLink(value: TLinkParams) {
|
|
174
|
+
const validation = z.object({
|
|
175
|
+
subscriptionId: z.string().min(1),
|
|
176
|
+
paymentMethodType: z.enum(["EWALLET", "DIRECT_DEBIT", "CREDIT_CARD"]),
|
|
177
|
+
paymentMethodChannel: z.string().min(1),
|
|
178
|
+
customerId: z.string().min(1),
|
|
179
|
+
card_number: z.string().optional(),
|
|
180
|
+
expiry_month: z.string().optional(),
|
|
181
|
+
expiry_year: z.string().optional(),
|
|
182
|
+
card_security_code: z.string().optional(),
|
|
183
|
+
cardholder_name: z.string().optional(),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const parsed = validation.safeParse(value);
|
|
187
|
+
|
|
188
|
+
if (!parsed.success) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`Validation failed: ${parsed.error.issues
|
|
191
|
+
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
192
|
+
.join(", ")}`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
linkingOverlay.value = true;
|
|
197
|
+
const success_return_url = `${window.origin}/payment-method-linked`;
|
|
198
|
+
const failure_return_url = `${window.origin}/payment-method-failed-link`;
|
|
199
|
+
const cancel_return_url = `${window.origin}/payment-method-cancel-link`;
|
|
200
|
+
|
|
201
|
+
const payload: Record<string, any> = {
|
|
202
|
+
type: value.paymentMethodType,
|
|
203
|
+
reusability: "MULTIPLE_USE",
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
if (payload.type === "EWALLET") {
|
|
207
|
+
payload.country = "PH";
|
|
208
|
+
payload.ewallet = {
|
|
209
|
+
channel_code: value.paymentMethodChannel,
|
|
210
|
+
channel_properties: {
|
|
211
|
+
success_return_url,
|
|
212
|
+
failure_return_url,
|
|
213
|
+
cancel_return_url,
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
payload.customer_id = value.customerId;
|
|
218
|
+
} else if (payload.type === "DIRECT_DEBIT") {
|
|
219
|
+
payload.direct_debit = {
|
|
220
|
+
channel_code: value.paymentMethodChannel,
|
|
221
|
+
channel_properties: {
|
|
222
|
+
success_return_url,
|
|
223
|
+
failure_return_url,
|
|
224
|
+
cancel_return_url,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
payload.customer_id = value.customerId;
|
|
228
|
+
} else if (payload.type === "CREDIT_CARD") {
|
|
229
|
+
payload.card = {
|
|
230
|
+
currency: "PHP",
|
|
231
|
+
channel_properties: {
|
|
232
|
+
success_return_url,
|
|
233
|
+
failure_return_url,
|
|
234
|
+
skip_three_d_secure: true,
|
|
235
|
+
},
|
|
236
|
+
card_information: {
|
|
237
|
+
card_number: value.card_number,
|
|
238
|
+
expiry_month: value.expiry_month,
|
|
239
|
+
expiry_year: value.expiry_year,
|
|
240
|
+
cvv: value.card_security_code,
|
|
241
|
+
cardholder_name: value.cardholder_name,
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
const _paymentMethod = await linkOnly(payload);
|
|
248
|
+
|
|
249
|
+
// Open a small popup window
|
|
250
|
+
const popupWidth = 500;
|
|
251
|
+
const popupHeight = 600;
|
|
252
|
+
const left = (screen.width - popupWidth) / 2;
|
|
253
|
+
const top = (screen.height - popupHeight) / 2;
|
|
254
|
+
|
|
255
|
+
const popup = window.open(
|
|
256
|
+
_paymentMethod.actions[0].url,
|
|
257
|
+
"eWalletPopup",
|
|
258
|
+
`width=${popupWidth},height=${popupHeight},top=${top},left=${left},resizable=yes,scrollbars=yes`
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
// Check every 500ms if the popup is closed
|
|
262
|
+
const checkPopupClosed = setInterval(async () => {
|
|
263
|
+
if (!popup || popup.closed) {
|
|
264
|
+
clearInterval(checkPopupClosed);
|
|
265
|
+
console.log(
|
|
266
|
+
"Popup closed. Proceeding with subscription automation..."
|
|
267
|
+
);
|
|
268
|
+
// Call your function to handle subscription
|
|
269
|
+
|
|
270
|
+
const temp = await getById(_paymentMethod.id);
|
|
271
|
+
|
|
272
|
+
if (temp.status === "ACTIVE") {
|
|
273
|
+
await updatePaymentMethodById(
|
|
274
|
+
value.subscriptionId,
|
|
275
|
+
_paymentMethod.id as string
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
paymentMethod.value = await getById(_paymentMethod.id);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
updatingPaymentMethod.value = false;
|
|
282
|
+
linkingOverlay.value = false;
|
|
283
|
+
}
|
|
284
|
+
}, 500);
|
|
285
|
+
} catch (error: any) {
|
|
286
|
+
linkingMessage.value = error.response._data.message;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
163
290
|
return {
|
|
164
291
|
linkEWallet,
|
|
165
292
|
linkCard,
|
|
@@ -175,5 +302,10 @@ export default function usePaymentMethod() {
|
|
|
175
302
|
linkOnly,
|
|
176
303
|
getById,
|
|
177
304
|
supportedPaymentMethods,
|
|
305
|
+
initLink,
|
|
306
|
+
linkingOverlay,
|
|
307
|
+
updatingPaymentMethod,
|
|
308
|
+
linkingMessage,
|
|
309
|
+
paymentMethod,
|
|
178
310
|
};
|
|
179
311
|
}
|
|
@@ -9,6 +9,40 @@ export default function useSubscription() {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
function addBillingContactById(id: string, email: string) {
|
|
13
|
+
return useNuxtApp().$api(`/api/subscriptions/billing-contact/${id}`, {
|
|
14
|
+
method: "PUT",
|
|
15
|
+
body: {
|
|
16
|
+
email,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function updateBillingContactByAddedAt(
|
|
22
|
+
id: string,
|
|
23
|
+
addedAt: string,
|
|
24
|
+
email: string
|
|
25
|
+
) {
|
|
26
|
+
return useNuxtApp().$api(
|
|
27
|
+
`/api/subscriptions/billing-contact/${id}/added-at/${addedAt}`,
|
|
28
|
+
{
|
|
29
|
+
method: "PUT",
|
|
30
|
+
body: {
|
|
31
|
+
email,
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function deleteBillingContactByAddedAt(id: string, addedAt: string) {
|
|
38
|
+
return useNuxtApp().$api(
|
|
39
|
+
`/api/subscriptions/billing-contact/${id}/added-at/${addedAt}`,
|
|
40
|
+
{
|
|
41
|
+
method: "DELETE",
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
12
46
|
function getById(id: string) {
|
|
13
47
|
return useNuxtApp().$api<TSubscription>(`/api/subscriptions/id/${id}`);
|
|
14
48
|
}
|
|
@@ -62,6 +96,15 @@ export default function useSubscription() {
|
|
|
62
96
|
});
|
|
63
97
|
}
|
|
64
98
|
|
|
99
|
+
function updatePaymentMethodById(id: string, paymentMethodId: string) {
|
|
100
|
+
return useNuxtApp().$api(`/api/subscriptions/payment-method/${id}`, {
|
|
101
|
+
method: "PUT",
|
|
102
|
+
body: {
|
|
103
|
+
paymentMethodId,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
65
108
|
async function affSubscriptionStatus() {
|
|
66
109
|
const { currentUser } = useLocalAuth();
|
|
67
110
|
|
|
@@ -144,6 +187,15 @@ export default function useSubscription() {
|
|
|
144
187
|
);
|
|
145
188
|
}
|
|
146
189
|
|
|
190
|
+
function processSubscriptionPayment(id: string, invoice: string) {
|
|
191
|
+
return useNuxtApp().$api(`/api/subscriptions/payment/id/${id}`, {
|
|
192
|
+
method: "PUT",
|
|
193
|
+
body: {
|
|
194
|
+
invoice,
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
147
199
|
return {
|
|
148
200
|
add,
|
|
149
201
|
getById,
|
|
@@ -161,5 +213,10 @@ export default function useSubscription() {
|
|
|
161
213
|
updateSeatsById,
|
|
162
214
|
updatePromoCodeById,
|
|
163
215
|
updateStatusById,
|
|
216
|
+
updatePaymentMethodById,
|
|
217
|
+
addBillingContactById,
|
|
218
|
+
updateBillingContactByAddedAt,
|
|
219
|
+
deleteBillingContactByAddedAt,
|
|
220
|
+
processSubscriptionPayment,
|
|
164
221
|
};
|
|
165
222
|
}
|
package/composables/useUtils.ts
CHANGED
|
@@ -137,7 +137,10 @@ export default function useUtils() {
|
|
|
137
137
|
{ method: "GET" }
|
|
138
138
|
);
|
|
139
139
|
|
|
140
|
-
const uniqueCountries
|
|
140
|
+
const uniqueCountries: Map<
|
|
141
|
+
string,
|
|
142
|
+
{ index: string; name: string; code: string }
|
|
143
|
+
> = new Map();
|
|
141
144
|
|
|
142
145
|
countries.forEach((country) => {
|
|
143
146
|
let suffixes = country.idd?.suffixes?.[0] || "";
|
package/middleware/01.auth.ts
CHANGED
|
@@ -11,13 +11,4 @@ export default defineNuxtRouteMiddleware(async () => {
|
|
|
11
11
|
// Redirect to login page if no access token
|
|
12
12
|
return navigateTo({ name: "index" });
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
const { getCurrentUser } = useLocalAuth();
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
await getCurrentUser();
|
|
19
|
-
} catch (error) {
|
|
20
|
-
// Redirect to login page if user authentication fails
|
|
21
|
-
return navigateTo({ name: "index" });
|
|
22
|
-
}
|
|
23
14
|
});
|
package/package.json
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-card class="pa-4" elevation="4" color="warning lighten-1">
|
|
4
|
+
<v-card-title class="text-white d-flex align-center">
|
|
5
|
+
<v-icon class="mr-2">mdi-check-circle</v-icon>
|
|
6
|
+
Cancelled Payment Method Link
|
|
7
|
+
</v-card-title>
|
|
8
|
+
|
|
9
|
+
<v-card-actions class="d-flex justify-center">
|
|
10
|
+
<v-btn
|
|
11
|
+
color="white"
|
|
12
|
+
variant="tonal"
|
|
13
|
+
rounded="xl"
|
|
14
|
+
size="large"
|
|
15
|
+
@click="closeWindow"
|
|
16
|
+
>Close</v-btn
|
|
17
|
+
>
|
|
18
|
+
</v-card-actions>
|
|
19
|
+
</v-card>
|
|
20
|
+
</v-row>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
definePageMeta({
|
|
25
|
+
layout: "plain",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const closeWindow = () => {
|
|
29
|
+
window.close();
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-card class="pa-4" elevation="4" color="error lighten-1">
|
|
4
|
+
<v-card-title class="text-white d-flex align-center">
|
|
5
|
+
<v-icon class="mr-2">mdi-check-circle</v-icon>
|
|
6
|
+
Failed Payment Method Link
|
|
7
|
+
</v-card-title>
|
|
8
|
+
|
|
9
|
+
<v-card-actions class="d-flex justify-center">
|
|
10
|
+
<v-btn
|
|
11
|
+
color="white"
|
|
12
|
+
variant="tonal"
|
|
13
|
+
rounded="xl"
|
|
14
|
+
size="large"
|
|
15
|
+
@click="closeWindow"
|
|
16
|
+
>Close</v-btn
|
|
17
|
+
>
|
|
18
|
+
</v-card-actions>
|
|
19
|
+
</v-card>
|
|
20
|
+
</v-row>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
definePageMeta({
|
|
25
|
+
layout: "plain",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const closeWindow = () => {
|
|
29
|
+
window.close();
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
declare type TInvoiceItem = {
|
|
2
|
+
itemId: string;
|
|
3
|
+
quantity: number;
|
|
4
|
+
seats?: number;
|
|
5
|
+
total: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
declare type TInvoiceMetadata = {
|
|
9
|
+
userId?: string | ObjectId;
|
|
10
|
+
orgId?: string | ObjectId;
|
|
11
|
+
subscriptionId?: string | ObjectId;
|
|
12
|
+
currency?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
declare type TInvoice = {
|
|
17
|
+
_id?: string | ObjectId;
|
|
18
|
+
invoiceNumber: string;
|
|
19
|
+
billingCycle: string;
|
|
20
|
+
status: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
items: TInvoiceItem[];
|
|
24
|
+
metadata?: TInvoiceMetadata;
|
|
25
|
+
amount: number;
|
|
26
|
+
dueDate: string;
|
|
27
|
+
type: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare type TLinkParams = {
|
|
2
|
+
subscriptionId: string;
|
|
3
|
+
paymentMethodType: string;
|
|
4
|
+
paymentMethodChannel: string;
|
|
5
|
+
customerId: string;
|
|
6
|
+
card_number?: string;
|
|
7
|
+
expiry_month?: string;
|
|
8
|
+
expiry_year?: string;
|
|
9
|
+
card_security_code?: string;
|
|
10
|
+
cardholder_name?: string;
|
|
11
|
+
};
|
package/types/subscription.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
declare type TBillingRecipient = {
|
|
2
|
+
addedAt?: string;
|
|
3
|
+
email: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
1
6
|
declare type TSubscription = {
|
|
2
7
|
_id?: string;
|
|
3
8
|
user?: string;
|
|
@@ -14,6 +19,7 @@ declare type TSubscription = {
|
|
|
14
19
|
maxSeats?: number;
|
|
15
20
|
status?: string;
|
|
16
21
|
billingCycle: "monthly" | "yearly";
|
|
22
|
+
billingContacts?: TBillingRecipient[];
|
|
17
23
|
nextBillingDate?: string;
|
|
18
24
|
lastPaymentStatus?: string;
|
|
19
25
|
failedAttempts?: number;
|