@goweekdays/layer-common 0.0.12 → 0.1.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/CHANGELOG.md +12 -0
- package/components/AddPaymentMethod.vue +554 -140
- package/components/Input/Number.vue +1 -1
- package/components/Layout/Header.vue +8 -5
- package/components/Layout/NavigationDrawer.vue +6 -3
- package/components/LocalPagination.vue +26 -16
- package/components/NavigationItem.vue +7 -0
- package/components/Std/Pagination.vue +52 -0
- package/components/SwitchOrg.vue +43 -5
- package/components/TableList.vue +3 -1
- package/composables/useAddress.ts +37 -0
- package/composables/useChartOfAccount.ts +62 -0
- package/composables/useInvoice.ts +4 -0
- package/composables/useLocal.ts +19 -11
- package/composables/useLocalAuth.ts +62 -6
- package/composables/useOrg.ts +1 -1
- package/composables/usePaymentMethod.ts +180 -12
- package/composables/useSubscription.ts +95 -0
- package/composables/useUtils.ts +14 -2
- package/middleware/01.auth.ts +0 -9
- package/middleware/org.ts +1 -1
- package/nuxt.config.ts +2 -0
- package/package.json +1 -1
- package/pages/payment-method-cancel-link.vue +31 -0
- package/pages/payment-method-failed-link.vue +31 -0
- package/plugins/API.ts +1 -3
- package/types/invoice.d.ts +28 -0
- package/types/local.d.ts +1 -0
- package/types/payment-method.d.ts +11 -0
- package/types/subscription.d.ts +6 -0
- package/types/xendit.d.ts +3 -0
|
@@ -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,13 @@ 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
|
-
|
|
78
|
-
|
|
77
|
+
`/api/payment-methods/id/${id}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getByCustomerId(id = "") {
|
|
82
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
83
|
+
`/api/payment-methods/customer/${id}`
|
|
79
84
|
);
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -84,16 +89,10 @@ export default function usePaymentMethod() {
|
|
|
84
89
|
const cardExpiration = useState("cardExpiration", () => "");
|
|
85
90
|
const cardSecurityCode = useState("cardSecurityCode", () => "");
|
|
86
91
|
const cardholderName = useState("cardholderName", () => "");
|
|
92
|
+
const cardholderMobileNumber = useState("cardholderMobileNumber", () => "");
|
|
93
|
+
const cardholderEmail = useState("cardholderEmail", () => "");
|
|
87
94
|
const selectedPaymentMethod = useState("selectedPaymentMethod", () => "");
|
|
88
95
|
|
|
89
|
-
function reset() {
|
|
90
|
-
eWalletNumber.value = "";
|
|
91
|
-
cardNumber.value = "";
|
|
92
|
-
cardExpiration.value = "";
|
|
93
|
-
cardSecurityCode.value = "";
|
|
94
|
-
cardholderName.value = "";
|
|
95
|
-
}
|
|
96
|
-
|
|
97
96
|
function linkOnly(value: Record<string, any>) {
|
|
98
97
|
return useNuxtApp().$api<Record<string, any>>(
|
|
99
98
|
"/api/payment-methods/link-only",
|
|
@@ -109,21 +108,25 @@ export default function usePaymentMethod() {
|
|
|
109
108
|
channel: "GCASH",
|
|
110
109
|
logo: "/gcash-logo.svg",
|
|
111
110
|
type: "EWALLET",
|
|
111
|
+
text: "GCash",
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
channel: "PAYMAYA",
|
|
115
115
|
logo: "/paymaya-logo.svg",
|
|
116
116
|
type: "EWALLET",
|
|
117
|
+
text: "PayMaya",
|
|
117
118
|
},
|
|
118
119
|
{
|
|
119
120
|
channel: "GRABPAY",
|
|
120
121
|
logo: "/grabpay-logo.svg",
|
|
121
122
|
type: "EWALLET",
|
|
123
|
+
text: "GrabPay",
|
|
122
124
|
},
|
|
123
125
|
{
|
|
124
126
|
channel: "SHOPEEPAY",
|
|
125
127
|
logo: "/shopeepay-logo.svg",
|
|
126
128
|
type: "EWALLET",
|
|
129
|
+
text: "ShopeePay",
|
|
127
130
|
},
|
|
128
131
|
];
|
|
129
132
|
|
|
@@ -132,26 +135,31 @@ export default function usePaymentMethod() {
|
|
|
132
135
|
channel: "UBP",
|
|
133
136
|
logo: "/ubp-logo.svg",
|
|
134
137
|
type: "DIRECT_DEBIT",
|
|
138
|
+
text: "BA_UBP",
|
|
135
139
|
},
|
|
136
140
|
{
|
|
137
141
|
channel: "BDO",
|
|
138
142
|
logo: "/bdo-logo.svg",
|
|
139
143
|
type: "DIRECT_DEBIT",
|
|
144
|
+
text: "BDO",
|
|
140
145
|
},
|
|
141
146
|
{
|
|
142
147
|
channel: "BPI",
|
|
143
148
|
logo: "/bpi-logo.svg",
|
|
144
149
|
type: "DIRECT_DEBIT",
|
|
150
|
+
text: "BA_BPI",
|
|
145
151
|
},
|
|
146
152
|
{
|
|
147
153
|
channel: "RCBC",
|
|
148
154
|
logo: "/rcbc-logo.svg",
|
|
149
155
|
type: "DIRECT_DEBIT",
|
|
156
|
+
text: "RCBC",
|
|
150
157
|
},
|
|
151
158
|
{
|
|
152
159
|
channel: "Chinabank",
|
|
153
160
|
logo: "/chinabank-logo.svg",
|
|
154
161
|
type: "DIRECT_DEBIT",
|
|
162
|
+
text: "Chinabank",
|
|
155
163
|
},
|
|
156
164
|
];
|
|
157
165
|
|
|
@@ -160,6 +168,155 @@ export default function usePaymentMethod() {
|
|
|
160
168
|
...supportedDirectDebit,
|
|
161
169
|
];
|
|
162
170
|
|
|
171
|
+
const { updatePaymentMethodById } = useSubscription();
|
|
172
|
+
|
|
173
|
+
const linkingOverlay = useState("linkingOverlay", () => false);
|
|
174
|
+
const updatingPaymentMethod = useState("updatingPaymentMethod", () => false);
|
|
175
|
+
const linkingMessage = useState("linkingMessage", () => "");
|
|
176
|
+
const paymentMethod = useState(
|
|
177
|
+
"paymentMethod",
|
|
178
|
+
(): Record<string, any> | null => null
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
function reset() {
|
|
182
|
+
eWalletNumber.value = "";
|
|
183
|
+
cardNumber.value = "";
|
|
184
|
+
cardExpiration.value = "";
|
|
185
|
+
cardSecurityCode.value = "";
|
|
186
|
+
cardholderName.value = "";
|
|
187
|
+
paymentMethod.value = null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function initLink(value: TLinkParams, callback?: Function) {
|
|
191
|
+
const validation = z.object({
|
|
192
|
+
subscriptionId: z.string().min(1).optional(),
|
|
193
|
+
paymentMethodType: z.enum(["EWALLET", "DIRECT_DEBIT", "CREDIT_CARD"]),
|
|
194
|
+
paymentMethodChannel: z.string().min(1),
|
|
195
|
+
customerId: z.string().min(1),
|
|
196
|
+
card_number: z.string().optional(),
|
|
197
|
+
expiry_month: z.string().optional(),
|
|
198
|
+
expiry_year: z.string().optional(),
|
|
199
|
+
card_security_code: z.string().optional(),
|
|
200
|
+
cardholder_name: z.string().optional(),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const parsed = validation.safeParse(value);
|
|
204
|
+
|
|
205
|
+
if (!parsed.success) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Validation failed: ${parsed.error.issues
|
|
208
|
+
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
|
|
209
|
+
.join(", ")}`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
linkingOverlay.value = true;
|
|
214
|
+
const success_return_url = `${window.origin}/payment-method-linked`;
|
|
215
|
+
const failure_return_url = `${window.origin}/payment-method-failed-link`;
|
|
216
|
+
const cancel_return_url = `${window.origin}/payment-method-cancel-link`;
|
|
217
|
+
|
|
218
|
+
const payload: Record<string, any> = {
|
|
219
|
+
type: value.paymentMethodType,
|
|
220
|
+
reusability: "MULTIPLE_USE",
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
if (payload.type === "EWALLET") {
|
|
224
|
+
payload.country = "PH";
|
|
225
|
+
payload.ewallet = {
|
|
226
|
+
channel_code: value.paymentMethodChannel,
|
|
227
|
+
channel_properties: {
|
|
228
|
+
success_return_url,
|
|
229
|
+
failure_return_url,
|
|
230
|
+
cancel_return_url,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
payload.customer_id = value.customerId;
|
|
235
|
+
} else if (payload.type === "DIRECT_DEBIT") {
|
|
236
|
+
payload.direct_debit = {
|
|
237
|
+
channel_code: value.paymentMethodChannel,
|
|
238
|
+
channel_properties: {
|
|
239
|
+
success_return_url,
|
|
240
|
+
failure_return_url,
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
payload.customer_id = value.customerId;
|
|
244
|
+
} else if (payload.type === "CARD") {
|
|
245
|
+
payload.card = {
|
|
246
|
+
currency: "PHP",
|
|
247
|
+
channel_properties: {
|
|
248
|
+
success_return_url,
|
|
249
|
+
failure_return_url,
|
|
250
|
+
skip_three_d_secure: true,
|
|
251
|
+
},
|
|
252
|
+
card_information: {
|
|
253
|
+
card_number: value.card_number,
|
|
254
|
+
expiry_month: value.expiry_month,
|
|
255
|
+
expiry_year: value.expiry_year,
|
|
256
|
+
cvv: value.card_security_code,
|
|
257
|
+
cardholder_name: value.cardholder_name,
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const _paymentMethod = await linkOnly(payload);
|
|
264
|
+
|
|
265
|
+
// Open a small popup window
|
|
266
|
+
const popupWidth = 500;
|
|
267
|
+
const popupHeight = 600;
|
|
268
|
+
const left = (screen.width - popupWidth) / 2;
|
|
269
|
+
const top = (screen.height - popupHeight) / 2;
|
|
270
|
+
|
|
271
|
+
const popup = window.open(
|
|
272
|
+
_paymentMethod.actions[0].url,
|
|
273
|
+
"eWalletPopup",
|
|
274
|
+
`width=${popupWidth},height=${popupHeight},top=${top},left=${left},resizable=yes,scrollbars=yes`
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
// Check every 500ms if the popup is closed
|
|
278
|
+
const checkPopupClosed = setInterval(async () => {
|
|
279
|
+
if (!popup || popup.closed) {
|
|
280
|
+
clearInterval(checkPopupClosed);
|
|
281
|
+
console.log(
|
|
282
|
+
"Popup closed. Proceeding with subscription automation..."
|
|
283
|
+
);
|
|
284
|
+
// Call your function to handle subscription
|
|
285
|
+
|
|
286
|
+
const temp = await getById(_paymentMethod.id);
|
|
287
|
+
|
|
288
|
+
if (temp.status === "ACTIVE" && value.subscriptionId) {
|
|
289
|
+
await updatePaymentMethodById(
|
|
290
|
+
value.subscriptionId,
|
|
291
|
+
_paymentMethod.id as string
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
paymentMethod.value = await getById(_paymentMethod.id);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (callback) {
|
|
298
|
+
callback();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
updatingPaymentMethod.value = false;
|
|
302
|
+
linkingOverlay.value = false;
|
|
303
|
+
}
|
|
304
|
+
}, 500);
|
|
305
|
+
} catch (error: any) {
|
|
306
|
+
linkingMessage.value = error.response._data.message;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function updateStatusById(id: string, status: string) {
|
|
311
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
312
|
+
`/api/payment-methods/status/${id}`,
|
|
313
|
+
{
|
|
314
|
+
method: "PATCH",
|
|
315
|
+
body: { status },
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
163
320
|
return {
|
|
164
321
|
linkEWallet,
|
|
165
322
|
linkCard,
|
|
@@ -170,10 +327,21 @@ export default function usePaymentMethod() {
|
|
|
170
327
|
cardExpiration,
|
|
171
328
|
cardSecurityCode,
|
|
172
329
|
cardholderName,
|
|
330
|
+
cardholderMobileNumber,
|
|
331
|
+
cardholderEmail,
|
|
173
332
|
selectedPaymentMethod,
|
|
174
333
|
reset,
|
|
175
334
|
linkOnly,
|
|
176
335
|
getById,
|
|
177
336
|
supportedPaymentMethods,
|
|
337
|
+
supportedDirectDebit,
|
|
338
|
+
supportedEwallets,
|
|
339
|
+
initLink,
|
|
340
|
+
linkingOverlay,
|
|
341
|
+
updatingPaymentMethod,
|
|
342
|
+
linkingMessage,
|
|
343
|
+
paymentMethod,
|
|
344
|
+
getByCustomerId,
|
|
345
|
+
updateStatusById,
|
|
178
346
|
};
|
|
179
347
|
}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
export default function useSubscription() {
|
|
2
|
+
function createSubscriptionPlan(
|
|
3
|
+
seats: number,
|
|
4
|
+
trialDays: number,
|
|
5
|
+
productId: string
|
|
6
|
+
) {
|
|
7
|
+
return useNuxtApp().$api("/api/subscriptions/plan", {
|
|
8
|
+
method: "POST",
|
|
9
|
+
body: {
|
|
10
|
+
seats,
|
|
11
|
+
trialDays,
|
|
12
|
+
productId,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
2
17
|
function add(subscriptionId: string, user: string) {
|
|
3
18
|
return useNuxtApp().$api("/api/subscriptions", {
|
|
4
19
|
method: "POST",
|
|
@@ -9,6 +24,40 @@ export default function useSubscription() {
|
|
|
9
24
|
});
|
|
10
25
|
}
|
|
11
26
|
|
|
27
|
+
function addBillingContactById(id: string, email: string) {
|
|
28
|
+
return useNuxtApp().$api(`/api/subscriptions/billing-contact/${id}`, {
|
|
29
|
+
method: "PUT",
|
|
30
|
+
body: {
|
|
31
|
+
email,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function updateBillingContactByAddedAt(
|
|
37
|
+
id: string,
|
|
38
|
+
addedAt: string,
|
|
39
|
+
email: string
|
|
40
|
+
) {
|
|
41
|
+
return useNuxtApp().$api(
|
|
42
|
+
`/api/subscriptions/billing-contact/${id}/added-at/${addedAt}`,
|
|
43
|
+
{
|
|
44
|
+
method: "PUT",
|
|
45
|
+
body: {
|
|
46
|
+
email,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function deleteBillingContactByAddedAt(id: string, addedAt: string) {
|
|
53
|
+
return useNuxtApp().$api(
|
|
54
|
+
`/api/subscriptions/billing-contact/${id}/added-at/${addedAt}`,
|
|
55
|
+
{
|
|
56
|
+
method: "DELETE",
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
12
61
|
function getById(id: string) {
|
|
13
62
|
return useNuxtApp().$api<TSubscription>(`/api/subscriptions/id/${id}`);
|
|
14
63
|
}
|
|
@@ -62,6 +111,15 @@ export default function useSubscription() {
|
|
|
62
111
|
});
|
|
63
112
|
}
|
|
64
113
|
|
|
114
|
+
function updatePaymentMethodById(id: string, paymentMethodId: string) {
|
|
115
|
+
return useNuxtApp().$api(`/api/subscriptions/payment-method/${id}`, {
|
|
116
|
+
method: "PUT",
|
|
117
|
+
body: {
|
|
118
|
+
paymentMethodId,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
65
123
|
async function affSubscriptionStatus() {
|
|
66
124
|
const { currentUser } = useLocalAuth();
|
|
67
125
|
|
|
@@ -144,6 +202,36 @@ export default function useSubscription() {
|
|
|
144
202
|
);
|
|
145
203
|
}
|
|
146
204
|
|
|
205
|
+
function processSubscriptionPayment(id: string, invoice: string) {
|
|
206
|
+
return useNuxtApp().$api(`/api/subscriptions/payment/id/${id}`, {
|
|
207
|
+
method: "PUT",
|
|
208
|
+
body: {
|
|
209
|
+
invoice,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function addOrgSubscription(value: {
|
|
215
|
+
user: string;
|
|
216
|
+
transactionId: string;
|
|
217
|
+
promoCode?: string;
|
|
218
|
+
seats: number;
|
|
219
|
+
perSeatPrice: number;
|
|
220
|
+
currency: string;
|
|
221
|
+
org: {
|
|
222
|
+
name: string;
|
|
223
|
+
email: string;
|
|
224
|
+
contact: string;
|
|
225
|
+
busInst: string;
|
|
226
|
+
type: string;
|
|
227
|
+
};
|
|
228
|
+
}) {
|
|
229
|
+
return useNuxtApp().$api("/api/subscriptions/subscribe", {
|
|
230
|
+
method: "POST",
|
|
231
|
+
body: value,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
147
235
|
return {
|
|
148
236
|
add,
|
|
149
237
|
getById,
|
|
@@ -161,5 +249,12 @@ export default function useSubscription() {
|
|
|
161
249
|
updateSeatsById,
|
|
162
250
|
updatePromoCodeById,
|
|
163
251
|
updateStatusById,
|
|
252
|
+
updatePaymentMethodById,
|
|
253
|
+
addBillingContactById,
|
|
254
|
+
updateBillingContactByAddedAt,
|
|
255
|
+
deleteBillingContactByAddedAt,
|
|
256
|
+
processSubscriptionPayment,
|
|
257
|
+
createSubscriptionPlan,
|
|
258
|
+
addOrgSubscription,
|
|
164
259
|
};
|
|
165
260
|
}
|
package/composables/useUtils.ts
CHANGED
|
@@ -133,11 +133,14 @@ export default function useUtils() {
|
|
|
133
133
|
async function getCountries() {
|
|
134
134
|
try {
|
|
135
135
|
const countries = await useNuxtApp().$api<Array<Record<string, any>>>(
|
|
136
|
-
"https://restcountries.com/v3.1/all",
|
|
136
|
+
"https://restcountries.com/v3.1/all?fields=name,currencies,idd",
|
|
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] || "";
|
|
@@ -221,6 +224,14 @@ export default function useUtils() {
|
|
|
221
224
|
);
|
|
222
225
|
}
|
|
223
226
|
|
|
227
|
+
function extractMonthYear(expiry: string) {
|
|
228
|
+
const [month, year] = expiry.split("/");
|
|
229
|
+
return {
|
|
230
|
+
month: month.padStart(2, "0"),
|
|
231
|
+
year: 2000 + parseInt(year, 10),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
224
235
|
return {
|
|
225
236
|
requiredRule,
|
|
226
237
|
emailRule,
|
|
@@ -242,5 +253,6 @@ export default function useUtils() {
|
|
|
242
253
|
computeTieredCost,
|
|
243
254
|
requireListRule,
|
|
244
255
|
convertPermissionsToArray,
|
|
256
|
+
extractMonthYear,
|
|
245
257
|
};
|
|
246
258
|
}
|
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/middleware/org.ts
CHANGED
|
@@ -5,7 +5,7 @@ const hexSchema = z
|
|
|
5
5
|
.regex(/^[0-9a-fA-F]{24}$/, "Invalid organization ID");
|
|
6
6
|
|
|
7
7
|
export default defineNuxtRouteMiddleware((to) => {
|
|
8
|
-
const
|
|
8
|
+
const organization = (to.params.organization as string) ?? "";
|
|
9
9
|
|
|
10
10
|
if (organization && !hexSchema.safeParse(organization).success) {
|
|
11
11
|
return navigateTo(
|
package/nuxt.config.ts
CHANGED
|
@@ -8,6 +8,7 @@ export default defineNuxtConfig({
|
|
|
8
8
|
|
|
9
9
|
runtimeConfig: {
|
|
10
10
|
public: {
|
|
11
|
+
XENDIT_PUBLIC_KEY: (process.env.XENDIT_PUBLIC_KEY as string) ?? "",
|
|
11
12
|
BASE_URL: process.env.BASE_URL ?? "/",
|
|
12
13
|
cookieConfig: {
|
|
13
14
|
domain: (process.env.DOMAIN as string) ?? "localhost",
|
|
@@ -24,6 +25,7 @@ export default defineNuxtConfig({
|
|
|
24
25
|
APP_AFFILIATE: (process.env.APP_AFFILIATE as string) ?? "",
|
|
25
26
|
APP_INVENTORY: (process.env.APP_INVENTORY as string) ?? "",
|
|
26
27
|
APP_ASSET: (process.env.APP_ASSET as string) ?? "",
|
|
28
|
+
APP_ACCOUNTING: (process.env.APP_ACCOUNTING as string) ?? "",
|
|
27
29
|
APP_BOOK_KEEPING: (process.env.APP_BOOK_KEEPING as string) ?? "",
|
|
28
30
|
},
|
|
29
31
|
},
|
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>
|
package/plugins/API.ts
CHANGED
|
@@ -11,9 +11,7 @@ export default defineNuxtPlugin(() => {
|
|
|
11
11
|
retryDelay: 500,
|
|
12
12
|
onRequest({ options }) {
|
|
13
13
|
const accessToken = useCookie("accessToken", cookieConfig).value;
|
|
14
|
-
options.headers
|
|
15
|
-
? { Authorization: `Bearer ${accessToken}` }
|
|
16
|
-
: {};
|
|
14
|
+
options.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
17
15
|
},
|
|
18
16
|
|
|
19
17
|
async onResponseError({ response }) {
|
|
@@ -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
|
+
};
|
package/types/local.d.ts
CHANGED
|
@@ -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;
|