@riskdefy/chargebacks 1.0.6 → 1.0.8

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.
@@ -0,0 +1,621 @@
1
+ <template>
2
+ <div class="row g-5 g-xl-10">
3
+ <!--begin::Col-->
4
+
5
+ <div class="col-xl-8">
6
+ <Details
7
+ :reason_explained="reason_explained"
8
+ :reason="reason"
9
+ :merchant="merchant"
10
+ :incoming="incoming"
11
+ ></Details>
12
+ </div>
13
+
14
+ <div class="col-xl-4 mb-10">
15
+ <div class="card">
16
+ <!--begin::Header-->
17
+ <div class="card">
18
+ <Summary
19
+ :reason="reason"
20
+ :processor="processor"
21
+ :merchant="merchant"
22
+ :incoming="incoming"
23
+ ></Summary>
24
+ </div>
25
+ <!--end::Header-->
26
+ <!--begin::Body-->
27
+ <!--end::Body-->
28
+ </div>
29
+ <div class="card card-body d-flex align-items-start mt-5 pt-5">
30
+ <!--begin::Chart-->
31
+ <div class="mb-auto">
32
+ <!--begin::Header-->
33
+ <div class="align-items-center border-0">
34
+ <h3 class="align-items-start flex-column">
35
+ <span class="fw-normal fs-7 text-dark ps-5"
36
+ >Response Timeline</span
37
+ >
38
+ </h3>
39
+ </div>
40
+ <!--end::Header-->
41
+ <!--begin::Body-->
42
+ <div class="card-body pt-5">
43
+ <!--begin::Timeline-->
44
+ <div class="timeline-label">
45
+ <!--begin::Item-->
46
+ <div
47
+ v-if="incoming.found_date != '0000-00-00 00:00:00'"
48
+ class="timeline-item"
49
+ >
50
+ <!--begin::Label-->
51
+ <div class="timeline-label text-gray-800 fs-8">
52
+ {{ getFoundTime }}
53
+ </div>
54
+ <!--end::Label-->
55
+ <!--begin::Badge-->
56
+ <div class="timeline-badge">
57
+ <i class="fa fa-genderless text-success fs-1"></i>
58
+ </div>
59
+ <!--end::Badge-->
60
+ <!--begin::Text-->
61
+ <div class="text-gray-800 ps-3 fs-8">
62
+ Transaction Found ({{ getFoundDate }})
63
+ </div>
64
+ <!--end::Text-->
65
+ </div>
66
+ <div v-else class="timeline-item">
67
+ <!--begin::Label-->
68
+ <div class="timeline-label text-gray-400 fs-8">00:00</div>
69
+ <!--end::Label-->
70
+ <!--begin::Badge-->
71
+ <div class="timeline-badge">
72
+ <i class="fa fa-genderless text-gray-400 fs-1"></i>
73
+ </div>
74
+ <!--end::Badge-->
75
+ <!--begin::Text-->
76
+ <div class="text-gray-400 ps-3 fs-8">Transaction Not Found</div>
77
+ <!--end::Text-->
78
+ </div>
79
+ <div
80
+ v-if="incoming.found_date != '0000-00-00 00:00:00'"
81
+ class="timeline-item"
82
+ >
83
+ <!--begin::Label-->
84
+ <div class="timeline-label text-gray-800 fs-8">
85
+ {{ getPopulatedTime }}
86
+ </div>
87
+ <!--end::Label-->
88
+ <!--begin::Badge-->
89
+ <div class="timeline-badge">
90
+ <i class="fa fa-genderless text-success fs-1"></i>
91
+ </div>
92
+ <!--end::Badge-->
93
+ <!--begin::Text-->
94
+ <div class="text-gray-800 ps-3 fs-8">
95
+ Details Populated ({{ getPopulatedDate }})
96
+ </div>
97
+ <!--end::Text-->
98
+ </div>
99
+ <div v-else class="timeline-item">
100
+ <!--begin::Label-->
101
+ <div class="timeline-label text-gray-400 fs-8">00:00</div>
102
+ <!--end::Label-->
103
+ <!--begin::Badge-->
104
+ <div class="timeline-badge">
105
+ <i class="fa fa-genderless text-gray-400 fs-1"></i>
106
+ </div>
107
+ <!--end::Badge-->
108
+ <!--begin::Text-->
109
+ <div class="text-gray-400 ps-3 fs-8">Details Not Populated</div>
110
+ <!--end::Text-->
111
+ </div>
112
+ <!--end::Item-->
113
+ <!--begin::Item-->
114
+ <div
115
+ v-if="incoming.sent_date != '0000-00-00 00:00:00'"
116
+ class="timeline-item"
117
+ >
118
+ <!--begin::Label-->
119
+ <div class="timeline-label text-gray-800 fs-8">
120
+ {{ getSentTime }}
121
+ </div>
122
+ <!--end::Label-->
123
+ <!--begin::Badge-->
124
+ <div class="timeline-badge">
125
+ <i class="fa fa-genderless text-success fs-1"></i>
126
+ </div>
127
+ <!--end::Badge-->
128
+ <!--begin::Content-->
129
+ <div class="timeline-content d-flex">
130
+ <span class="text-gray-800 ps-3 fs-8"
131
+ >Response Sent ({{ getSentDate }})</span
132
+ >
133
+ </div>
134
+ <!--end::Content-->
135
+ </div>
136
+ <div v-else class="timeline-item">
137
+ <!--begin::Label-->
138
+ <div class="timeline-label text-gray-400 fs-8">00:00</div>
139
+ <!--end::Label-->
140
+ <!--begin::Badge-->
141
+ <div class="timeline-badge">
142
+ <i class="fa fa-genderless text-gray-400 fs-1"></i>
143
+ </div>
144
+ <!--end::Badge-->
145
+ <!--begin::Content-->
146
+ <div class="timeline-content d-flex">
147
+ <span class="text-gray-400 ps-3 fs-8">Response Not Sent</span>
148
+ </div>
149
+ <!--end::Content-->
150
+ </div>
151
+ <!--end::Item-->
152
+ </div>
153
+ <!--end::Timeline-->
154
+ </div>
155
+ <!--end: Card Body-->
156
+ </div>
157
+ <!--end::Chart-->
158
+ </div>
159
+ <!--end::Chart widget 31-->
160
+ </div>
161
+ <!--end::Col-->
162
+ <!--begin::Col-->
163
+ <!--end::Col-->
164
+ </div>
165
+ </template>
166
+
167
+ <script lang="ts">
168
+ import { defineComponent, onMounted, computed, ref } from "vue";
169
+ import { Modal } from "bootstrap";
170
+
171
+ import Details from "./Details.vue";
172
+ import Summary from "./Summary.vue";
173
+ import ApiService from "../service/api";
174
+
175
+ interface Incoming {
176
+ id: string;
177
+ transaction_found: string;
178
+ details_populated: string;
179
+ dispute_url: string;
180
+ is_responded: string;
181
+ // eslint-disable-next-line
182
+ card_holder: any;
183
+ // eslint-disable-next-line
184
+ card: any;
185
+ // eslint-disable-next-line
186
+ transaction: any;
187
+ // eslint-disable-next-line
188
+ order_details: any;
189
+ // eslint-disable-next-line
190
+ order2_details: any;
191
+ order3_details: any;
192
+ crm2_details: any;
193
+ crm3_details: any;
194
+ product_details: any;
195
+ merchant_id: string;
196
+ reason: string;
197
+ // eslint-disable-next-line
198
+ dispute_cycle: any;
199
+ connection_id: string;
200
+ found_date: string;
201
+ populated_date: string;
202
+ sent_date: string;
203
+ reason_condition: string;
204
+ }
205
+
206
+ interface Merchant {
207
+ dba_name: string;
208
+ processor_id: string;
209
+ // eslint-disable-next-line
210
+ merchantDetails: any;
211
+ }
212
+
213
+ interface Connection {
214
+ id: string;
215
+ conn_name: string;
216
+ scheme: string;
217
+ host: string;
218
+ domain: string;
219
+ auth_type: string;
220
+ payload_type: string;
221
+ response_type: string;
222
+ enabled: string;
223
+ conn_status: string;
224
+ category: string;
225
+ created: string;
226
+ modified: string;
227
+ logo_url: string;
228
+ }
229
+
230
+ export default defineComponent({
231
+ name: "incoming-details",
232
+ components: {
233
+ Details,
234
+ Summary,
235
+ },
236
+ props: {
237
+ apiKey: {
238
+ type: String,
239
+ required: true,
240
+ },
241
+ incomingId: {
242
+ type: String,
243
+ required: true,
244
+ },
245
+ },
246
+ setup(props: any) {
247
+ const getIncomingId = computed(() => {
248
+ return props.incomingId;
249
+ });
250
+ const incoming = ref<Incoming>({
251
+ id: "",
252
+ transaction_found: "0",
253
+ details_populated: "0",
254
+ dispute_url: "",
255
+ is_responded: "",
256
+ card_holder: {},
257
+ card: {},
258
+ transaction: {
259
+ action: {},
260
+ },
261
+ order_details: {
262
+ items: [],
263
+ },
264
+ order2_details: {
265
+ items: [],
266
+ },
267
+ order3_details: {
268
+ items: [],
269
+ },
270
+ crm2_details: {},
271
+ crm3_details: {},
272
+ product_details: {},
273
+ merchant_id: "",
274
+ reason: "",
275
+ dispute_cycle: {},
276
+ connection_id: "",
277
+ found_date: "0000-00-00 00:00:00",
278
+ populated_date: "0000-00-00 00:00:00",
279
+ sent_date: "0000-00-00 00:00:00",
280
+ reason_condition: "",
281
+ });
282
+ const merchant = ref<Merchant>({
283
+ dba_name: "",
284
+ processor_id: "",
285
+ merchantDetails: {},
286
+ });
287
+ const reason = ref({});
288
+ const reason_explained = ref({
289
+ message: {},
290
+ instructions: {},
291
+ });
292
+ const processor = ref({});
293
+ const templates = ref({});
294
+ const templateImages = ref([]);
295
+
296
+ onMounted(async () => {
297
+ ApiService.setApiKey(props.apiKey);
298
+
299
+ setTimeout(async () => {
300
+ await getIncoming();
301
+ await getConnections();
302
+ }, 500);
303
+ });
304
+
305
+ const connections = ref<Connection[]>([]);
306
+ const getConnections = async () => {
307
+ const response = await ApiService.get("apis/connections?limit=100");
308
+ if (response?.data?.success) {
309
+ connections.value = [...(response?.data ?? [])];
310
+ }
311
+ };
312
+ const isTransactionAvailable = computed(() => {
313
+ const transaction = incoming.value.transaction;
314
+ return (
315
+ transaction &&
316
+ Object.keys(transaction).length > 0 &&
317
+ transaction.transaction_id && // Assuming transaction_id is a key indicator
318
+ transaction.transaction_id !== ""
319
+ );
320
+ });
321
+ const getFoundTime = computed(() => {
322
+ const time = incoming.value.found_date.split(" ")[1];
323
+ const partTime = time.split(":");
324
+ return `${partTime[0]}:${partTime[1]}`;
325
+ });
326
+ const getFoundDate = computed(() => {
327
+ const date = incoming.value.found_date.split(" ")[0];
328
+ const partDate = date.split("-");
329
+ return `${partDate[1]}-${partDate[2]}`;
330
+ });
331
+ const getPopulatedTime = computed(() => {
332
+ const time = incoming.value.populated_date.split(" ")[1];
333
+ const partTime = time.split(":");
334
+ return `${partTime[0]}:${partTime[1]}`;
335
+ });
336
+ const getPopulatedDate = computed(() => {
337
+ const date = incoming.value.populated_date.split(" ")[0];
338
+ const partDate = date.split("-");
339
+ return `${partDate[1]}-${partDate[2]}`;
340
+ });
341
+ const getSentTime = computed(() => {
342
+ const time = incoming.value.sent_date.split(" ")[1];
343
+ const partTime = time.split(":");
344
+ return `${partTime[0]}:${partTime[1]}`;
345
+ });
346
+ const getSentDate = computed(() => {
347
+ const date = incoming.value.sent_date.split(" ")[0];
348
+ const partDate = date.split("-");
349
+ return `${partDate[1]}-${partDate[2]}`;
350
+ });
351
+ const apiSyncItems = ref([]);
352
+
353
+ const getIncoming = async () => {
354
+ try {
355
+ const { data } = await ApiService.get(
356
+ `chargebacks/incoming?id=${getIncomingId.value}`
357
+ );
358
+ incoming.value = data[0];
359
+ console.log("here", incoming.value);
360
+ try {
361
+ incoming.value.card_holder = JSON.parse(incoming.value.card_holder);
362
+ } catch (e) {
363
+ incoming.value.card_holder = {};
364
+ }
365
+
366
+ try {
367
+ incoming.value.card = JSON.parse(incoming.value.card);
368
+ } catch (e) {
369
+ incoming.value.card = {};
370
+ }
371
+
372
+ try {
373
+ incoming.value.transaction = JSON.parse(incoming.value.transaction);
374
+ } catch (e) {
375
+ incoming.value.transaction = { action: {} };
376
+ }
377
+
378
+ try {
379
+ incoming.value.dispute_cycle = JSON.parse(
380
+ incoming.value.dispute_cycle
381
+ );
382
+ } catch (e) {
383
+ incoming.value.dispute_cycle = {};
384
+ }
385
+
386
+ try {
387
+ incoming.value.order_details = JSON.parse(
388
+ incoming.value.order_details
389
+ );
390
+ } catch (e) {
391
+ incoming.value.order_details = { items: [] };
392
+ }
393
+
394
+ try {
395
+ incoming.value.order2_details = JSON.parse(
396
+ incoming.value.order2_details
397
+ );
398
+ } catch (e) {
399
+ incoming.value.order2_details = { items: [] };
400
+ }
401
+
402
+ try {
403
+ incoming.value.product_details = JSON.parse(
404
+ incoming.value.product_details
405
+ );
406
+ } catch (e) {
407
+ incoming.value.product_details = {};
408
+ }
409
+ } catch (err) {
410
+ console.log(err);
411
+ incoming.value = {
412
+ id: "",
413
+ transaction_found: "0",
414
+ details_populated: "0",
415
+ dispute_url: "",
416
+ is_responded: "",
417
+ card_holder: {},
418
+ card: {},
419
+ transaction: {
420
+ action: {},
421
+ },
422
+ order_details: {
423
+ items: [],
424
+ },
425
+ order2_details: {
426
+ items: [],
427
+ },
428
+ order3_details: {
429
+ items: [],
430
+ },
431
+ crm2_details: {},
432
+ crm3_details: {},
433
+ product_details: {},
434
+ merchant_id: "",
435
+ reason: "",
436
+ dispute_cycle: {},
437
+ connection_id: "",
438
+ found_date: "0000-00-00 00:00:00",
439
+ populated_date: "0000-00-00 00:00:00",
440
+ sent_date: "0000-00-00 00:00:00",
441
+ reason_condition: "",
442
+ };
443
+ }
444
+
445
+ try {
446
+ const { data } = await ApiService.get(
447
+ `merchants/accounts?merchant_id=${incoming.value.merchant_id}`
448
+ );
449
+ merchant.value = data[0];
450
+ try {
451
+ merchant.value.merchantDetails = JSON.parse(
452
+ merchant.value.merchantDetails
453
+ );
454
+ } catch (e) {
455
+ merchant.value.merchantDetails = {};
456
+ }
457
+ } catch (err) {
458
+ merchant.value = {
459
+ dba_name: "",
460
+ processor_id: "",
461
+ merchantDetails: {},
462
+ };
463
+ }
464
+
465
+ try {
466
+ const { data } = await ApiService.get(
467
+ `chargebacks/reasons?code=${incoming.value.reason}`
468
+ );
469
+ reason.value = data[0];
470
+ } catch (err) {
471
+ reason.value = {};
472
+ }
473
+
474
+ try {
475
+ const { data } = await ApiService.get(
476
+ `chargebacks/reasons_explained?code=${incoming.value.reason}`
477
+ );
478
+ reason_explained.value = data[0];
479
+ reason_explained.value.message = JSON.parse(data[0].message);
480
+ reason_explained.value.instructions = JSON.parse(data[0].instructions);
481
+ } catch (err) {
482
+ reason_explained.value = { message: {}, instructions: {} };
483
+ }
484
+
485
+ try {
486
+ const { data } = await ApiService.get(
487
+ `processors/isos/${merchant.value.processor_id}`
488
+ );
489
+ processor.value = data[0];
490
+ } catch (err) {
491
+ processor.value = {};
492
+ }
493
+
494
+ try {
495
+ const { data } = await ApiService.get(
496
+ `apis/merchants?fields=id,alias_name,connection_id,endpoint_name&category=Gateway&merchant_id=${incoming.value.merchant_id}`
497
+ );
498
+ apiSyncItems.value = data;
499
+ } catch (e) {
500
+ apiSyncItems.value = [];
501
+ }
502
+ };
503
+
504
+ const resetIncoming = () => {
505
+ getIncoming();
506
+ };
507
+
508
+ const onOpenResponseDrawer = async () => {
509
+ try {
510
+ let res = await ApiService.get(
511
+ `chargebacks/incoming/${incoming.value.id}?action=evidence_images`
512
+ );
513
+ if (res.success) {
514
+ if (res.data[0] === null) {
515
+ templateImages.value = [];
516
+ } else {
517
+ templateImages.value = res.data[0];
518
+ }
519
+ }
520
+
521
+ res = await ApiService.get(
522
+ `chargebacks/incoming/${incoming.value.id}?action=response_packet`
523
+ );
524
+ if (res.success) {
525
+ if (res.data[0] === null) {
526
+ templates.value = {};
527
+ } else {
528
+ templates.value = res.data[0];
529
+ }
530
+ }
531
+ } catch (e) {
532
+ templates.value = {};
533
+ templateImages.value = [];
534
+ }
535
+ };
536
+
537
+ const submitTemplate = async () => {
538
+ try {
539
+ let res = await ApiService.get(
540
+ `chargebacks/incoming/${incoming.value.id}?action=evidence_images`
541
+ );
542
+ if (res.data.success) {
543
+ if (res.data[0] === null) {
544
+ templateImages.value = [];
545
+ } else {
546
+ templateImages.value = res.data[0];
547
+ }
548
+ }
549
+
550
+ res = await ApiService.get(
551
+ `chargebacks/incoming/${incoming.value.id}?action=response_packet`
552
+ );
553
+ if (res.success) {
554
+ if (res.data[0] === null) {
555
+ templates.value = {};
556
+ } else {
557
+ templates.value = res.data[0];
558
+ }
559
+ }
560
+ } catch (e) {
561
+ templates.value = {};
562
+ templateImages.value = [];
563
+ }
564
+ };
565
+
566
+ const onViewDispute = () => {
567
+ const modal = new Modal(document.getElementById("modal_pdf_view"));
568
+ modal.show();
569
+ };
570
+ const incomingWithoutTransaction = computed(() => {
571
+ const { transaction, card_holder, ...rest } = incoming.value;
572
+ return rest;
573
+ });
574
+ return {
575
+ incoming,
576
+ isTransactionAvailable,
577
+ incomingWithoutTransaction,
578
+ merchant,
579
+ reason,
580
+ reason_explained,
581
+ processor,
582
+ getFoundTime,
583
+ getPopulatedTime,
584
+ resetIncoming,
585
+ getSentTime,
586
+ getSentDate,
587
+ getFoundDate,
588
+ getPopulatedDate,
589
+ connections,
590
+
591
+ onOpenResponseDrawer,
592
+ submitTemplate,
593
+ templates,
594
+ templateImages,
595
+ onViewDispute,
596
+ apiSyncItems,
597
+ };
598
+ },
599
+ });
600
+ </script>
601
+ <style>
602
+ .el-step__title {
603
+ font-size: 12px;
604
+ line-height: 38px;
605
+ font-weight: 500;
606
+ font-family: inherit;
607
+ }
608
+ .el-step__title.is-process {
609
+ font-weight: 500;
610
+ }
611
+
612
+ .el-step__icon-inner {
613
+ font-size: 12px;
614
+ }
615
+ .el-message__content {
616
+ padding: 2px;
617
+ font-size: 12px;
618
+ line-height: 1;
619
+ }
620
+ </style>
621
+