diff --git a/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyBackgroundSyncs.Codeunit.al b/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyBackgroundSyncs.Codeunit.al
index de7e4eebdc..5691e2e289 100644
--- a/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyBackgroundSyncs.Codeunit.al
+++ b/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyBackgroundSyncs.Codeunit.al
@@ -337,6 +337,37 @@ codeunit 30101 "Shpfy Background Syncs"
end;
end;
+ internal procedure DisputesSync(ShopCode: Code[20])
+ var
+ Shop: Record "Shpfy Shop";
+ begin
+ if Shop.Get(ShopCode) then begin
+ Shop.SetRecFilter();
+ DisputesSync(Shop);
+ end;
+ end;
+
+ ///
+ /// Payment Dispute Sync.
+ ///
+ /// Parameter of type Record "Shopify Shop".
+ internal procedure DisputesSync(var Shop: Record "Shpfy Shop")
+ var
+ Parameters: text;
+ PaymentParametersTxt: Label '%1', Comment = '%1 = Shop Record View', Locked = true;
+ begin
+ Shop.SetRange("Allow Background Syncs", true);
+ if not Shop.IsEmpty then begin
+ Parameters := StrSubstNo(PaymentParametersTxt, Shop.GetView());
+ EnqueueJobEntry(Report::"Shpfy Sync Disputes", Parameters, StrSubstNo(SyncDescriptionTxt, PayoutsSyncTypeTxt, Shop.GetFilter(Code)), true, true);
+ end;
+ Shop.SetRange("Allow Background Syncs", false);
+ if not Shop.IsEmpty then begin
+ Parameters := StrSubstNo(PaymentParametersTxt, Shop.GetView());
+ EnqueueJobEntry(Report::"Shpfy Sync Disputes", Parameters, StrSubstNo(SyncDescriptionTxt, PayoutsSyncTypeTxt, Shop.GetFilter(Code)), false, true);
+ end;
+ end;
+
///
/// Product Images Sync.
///
diff --git a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al
index 29b64ce181..f740afdf0d 100644
--- a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al
+++ b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al
@@ -999,6 +999,23 @@ page 30101 "Shpfy Shop Card"
Report.Run(Report::"Shpfy Sync Shipm. to Shopify");
end;
}
+ action(SyncDisputes)
+ {
+ ApplicationArea = All;
+ Caption = 'Sync Disputes';
+ Image = ErrorLog;
+ Promoted = true;
+ PromotedCategory = Category5;
+ PromotedOnly = true;
+ ToolTip = 'Synchronize dispute information with related payment transactions.';
+
+ trigger OnAction()
+ var
+ BackgroundSyncs: Codeunit "Shpfy Background Syncs";
+ begin
+ BackgroundSyncs.DisputesSync(Rec.Code);
+ end;
+ }
action(SyncAll)
{
ApplicationArea = All;
diff --git a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al
index 53c8e4934e..99fdff807f 100644
--- a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al
+++ b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al
@@ -899,6 +899,21 @@ page 30113 "Shpfy Order"
Page.Run(Page::"Shpfy Data Capture List", DataCapture);
end;
}
+ action(Disputes)
+ {
+ ApplicationArea = All;
+ Caption = 'Show Related Disputes';
+ Image = Entry;
+ ToolTip = 'View the disputes related to order of the selected transaction.';
+
+ trigger OnAction();
+ var
+ Dispute: Record "Shpfy Dispute";
+ begin
+ Dispute.SetRange("Source Order Id", Rec."Shopify Order Id");
+ Page.Run(Page::"Shpfy Disputes", Dispute);
+ end;
+ }
}
}
diff --git a/Apps/W1/Shopify/app/src/Payments/Codeunits/ShpfyPayments.Codeunit.al b/Apps/W1/Shopify/app/src/Payments/Codeunits/ShpfyPayments.Codeunit.al
index 86a45c6f7c..79c6802c47 100644
--- a/Apps/W1/Shopify/app/src/Payments/Codeunits/ShpfyPayments.Codeunit.al
+++ b/Apps/W1/Shopify/app/src/Payments/Codeunits/ShpfyPayments.Codeunit.al
@@ -203,4 +203,108 @@ codeunit 30169 "Shpfy Payments"
end;
end;
end;
+
+ internal procedure ImportNewDisputes()
+ var
+ Dispute: Record "Shpfy Dispute";
+ SinceId: BigInteger;
+ JDisputes: JsonArray;
+ JItem: JsonToken;
+ JResponse: JsonToken;
+ Url: Text;
+ UrlTxt: Label 'shopify_payments/disputes.json?since_id=%1', Locked = true;
+ begin
+ if Dispute.FindLast() then
+ SinceId := Dispute.Id;
+
+ Url := CommunicationMgt.CreateWebRequestURL(StrSubstNo(UrlTxt, SinceId));
+
+ repeat
+ JResponse := CommunicationMgt.ExecuteWebRequest(Url, 'GET', JResponse, Url);
+
+ if JsonHelper.GetJsonArray(JResponse, JDisputes, 'disputes') then
+ foreach JItem in JDisputes do
+ ImportDisputeData(JItem);
+ until Url = '';
+ end;
+
+ internal procedure UpdateUnfinishedDisputes()
+ var
+ Dispute: Record "Shpfy Dispute";
+ DisputeToken: JsonToken;
+ JResponse: JsonToken;
+ Url: Text;
+ UrlTxt: Label 'shopify_payments/disputes/%1.json', Locked = true;
+ begin
+ Dispute.SetFilter("Status", '<>%1&<>%2', Dispute."Status"::Won, Dispute."Status"::Lost);
+
+ if Dispute.FindSet() then
+ repeat
+ Url := CommunicationMgt.CreateWebRequestURL(StrSubstNo(UrlTxt, Dispute.Id));
+ JResponse := CommunicationMgt.ExecuteWebRequest(Url, 'GET', JResponse);
+ DisputeToken := JsonHelper.GetJsonToken(JResponse, 'dispute');
+ ImportDisputeData(DisputeToken);
+ until Dispute.Next() = 0;
+ end;
+
+ internal procedure ImportDisputeData(DisputeToken: JsonToken)
+ var
+ Dispute: Record "Shpfy Dispute";
+ RecordRef: RecordRef;
+ Id: BigInteger;
+ begin
+ Id := JsonHelper.GetValueAsBigInteger(DisputeToken, 'id');
+
+ Clear(Dispute);
+ if not Dispute.Get(Id) then begin
+ RecordRef.Open(Database::"Shpfy Dispute");
+ RecordRef.Init();
+ JsonHelper.GetValueIntoField(DisputeToken, 'order_id', RecordRef, Dispute.FieldNo("Source Order Id"));
+ JsonHelper.GetValueIntoField(DisputeToken, 'currency', RecordRef, Dispute.FieldNo(Currency));
+ JsonHelper.GetValueIntoField(DisputeToken, 'amount', RecordRef, Dispute.FieldNo(Amount));
+ JsonHelper.GetValueIntoField(DisputeToken, 'network_reason_code', RecordRef, Dispute.FieldNo("Network Reason Code"));
+ JsonHelper.GetValueIntoField(DisputeToken, 'evidence_due_by', RecordRef, Dispute.FieldNo("Evidence Due By"));
+ JsonHelper.GetValueIntoField(DisputeToken, 'evidence_sent_on', RecordRef, Dispute.FieldNo("Evidence Sent On"));
+ JsonHelper.GetValueIntoField(DisputeToken, 'finalized_on', RecordRef, Dispute.FieldNo("Finalized On"));
+ RecordRef.SetTable(Dispute);
+ RecordRef.Close();
+ Dispute.Id := Id;
+ Dispute.Status := ConvertToDisputeStatus(JsonHelper.GetValueAsText(DisputeToken, 'status'));
+ Dispute.Type := ConvertToDisputeType(JsonHelper.GetValueAsText(DisputeToken, 'type'));
+ Dispute.Reason := ConvertToDisputeReason(JsonHelper.GetValueAsText(DisputeToken, 'reason'));
+ Dispute.Insert();
+ end else begin
+ Dispute.Status := ConvertToDisputeStatus(JsonHelper.GetValueAsText(DisputeToken, 'status'));
+ Dispute."Evidence Sent On" := JsonHelper.GetValueAsDateTime(DisputeToken, 'evidence_due_by');
+ Dispute."Finalized On" := JsonHelper.GetValueAsDateTime(DisputeToken, 'finalized_on');
+ Dispute.Modify();
+ end;
+ end;
+
+ local procedure ConvertToDisputeStatus(Value: Text): Enum "Shpfy Dispute Status"
+ begin
+ Value := CommunicationMgt.ConvertToCleanOptionValue(Value);
+ if Enum::"Shpfy Dispute Status".Names().Contains(Value) then
+ exit(Enum::"Shpfy Dispute Status".FromInteger(Enum::"Shpfy Dispute Status".Ordinals().Get(Enum::"Shpfy Dispute Status".Names().IndexOf(Value))))
+ else
+ exit(Enum::"Shpfy Dispute Status"::Unknown);
+ end;
+
+ local procedure ConvertToDisputeType(Value: Text): Enum "Shpfy Dispute Type"
+ begin
+ Value := CommunicationMgt.ConvertToCleanOptionValue(Value);
+ if Enum::"Shpfy Dispute Type".Names().Contains(Value) then
+ exit(Enum::"Shpfy Dispute Type".FromInteger(Enum::"Shpfy Dispute Type".Ordinals().Get(Enum::"Shpfy Dispute Type".Names().IndexOf(Value))))
+ else
+ exit(Enum::"Shpfy Dispute Type"::Unknown);
+ end;
+
+ local procedure ConvertToDisputeReason(Value: Text): Enum "Shpfy Dispute Reason"
+ begin
+ Value := CommunicationMgt.ConvertToCleanOptionValue(Value);
+ if Enum::"Shpfy Dispute Status".Names().Contains(Value) then
+ exit(Enum::"Shpfy Dispute Reason".FromInteger(Enum::"Shpfy Dispute Reason".Ordinals().Get(Enum::"Shpfy Dispute Reason".Names().IndexOf(Value))))
+ else
+ exit(Enum::"Shpfy Dispute Reason"::Unknown);
+ end;
}
\ No newline at end of file
diff --git a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeReason.Enum.al b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeReason.Enum.al
new file mode 100644
index 0000000000..0f06632d25
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeReason.Enum.al
@@ -0,0 +1,64 @@
+namespace Microsoft.Integration.Shopify;
+
+enum 30153 "Shpfy Dispute Reason"
+{
+ Caption = 'Shopify Dispute Reason';
+ Extensible = false;
+
+ value(0; Unknown)
+ {
+ Caption = 'Unknown';
+ }
+ value(1; "Bank Not Process")
+ {
+ Caption = 'Bank Not Process';
+ }
+ value(2; "Credit Not Processed")
+ {
+ Caption = 'Credit Not Processed';
+ }
+ value(3; "Customer Initiated")
+ {
+ Caption = 'Customer Initiated';
+ }
+ value(4; "Debit Not Authorized")
+ {
+ Caption = 'Debit Not Authorized';
+ }
+ value(5; Duplicate)
+ {
+ Caption = 'Duplicate';
+ }
+ value(6; Fraudulent)
+ {
+ Caption = 'Fraudulent';
+ }
+ value(7; General)
+ {
+ Caption = 'General';
+ }
+ value(8; "Incorrect Account Details")
+ {
+ Caption = 'Incorrect Account Details';
+ }
+ value(9; "Insufficient Funds")
+ {
+ Caption = 'Insufficient Funds';
+ }
+ value(10; "Product Not Received")
+ {
+ Caption = 'Product Not Received';
+ }
+ value(11; "Product Unacceptable")
+ {
+ Caption = 'Product Unacceptable';
+ }
+ value(12; "Subscription Canceled")
+ {
+ Caption = 'Subscription Canceled';
+ }
+ value(13; Unrecognized)
+ {
+ Caption = 'Unrecognized';
+ }
+}
\ No newline at end of file
diff --git a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeStatus.Enum.al b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeStatus.Enum.al
new file mode 100644
index 0000000000..62a0a82a42
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeStatus.Enum.al
@@ -0,0 +1,37 @@
+namespace Microsoft.Integration.Shopify;
+
+enum 30154 "Shpfy Dispute Status"
+{
+
+ Caption = 'Shopify Dispute Status';
+ Extensible = false;
+
+ value(0; Unknown)
+ {
+ Caption = ' ';
+ }
+ value(1; "Needs Response")
+ {
+ Caption = 'Needs Response';
+ }
+ value(2; "Under Review")
+ {
+ Caption = 'Under Review';
+ }
+ value(3; "Charge Refunded")
+ {
+ Caption = 'Charge Refunded';
+ }
+ value(4; "Accepted")
+ {
+ Caption = 'Accepted';
+ }
+ value(5; "Won")
+ {
+ Caption = 'Won';
+ }
+ value(6; "Lost")
+ {
+ Caption = 'Lost';
+ }
+}
\ No newline at end of file
diff --git a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeType.Enum.al b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeType.Enum.al
new file mode 100644
index 0000000000..03964346a4
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyDisputeType.Enum.al
@@ -0,0 +1,20 @@
+namespace Microsoft.Integration.Shopify;
+
+enum 30155 "Shpfy Dispute Type"
+{
+ Caption = 'Shopify Dispute Type';
+ Extensible = false;
+
+ value(0; Unknown)
+ {
+ Caption = ' ';
+ }
+ value(1; Inquiry)
+ {
+ Caption = 'Inquiry';
+ }
+ value(2; Chargeback)
+ {
+ Caption = 'Chargeback';
+ }
+}
\ No newline at end of file
diff --git a/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyDisputes.Page.al b/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyDisputes.Page.al
new file mode 100644
index 0000000000..8e8487174e
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyDisputes.Page.al
@@ -0,0 +1,76 @@
+namespace Microsoft.Integration.Shopify;
+
+page 30161 "Shpfy Disputes"
+{
+ Editable = false;
+ PageType = List;
+ UsageCategory = None;
+ SourceTable = "Shpfy Dispute";
+ Caption = 'Disputes';
+
+ layout
+ {
+ area(Content)
+ {
+ repeater(control01)
+ {
+
+ field(Id; Rec.Id)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Id field.';
+ }
+ field("Source Order Id"; Rec."Source Order Id")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Source Order Id field.';
+ }
+ field("Type"; Rec."Type")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Type field.';
+ }
+ field(Currency; Rec.Currency)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Currency field.';
+ }
+ field(Amount; Rec.Amount)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Amount field.';
+ }
+ field(Reason; Rec.Reason)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Shpfy Dispute Reason field.';
+ }
+ field("Network Reason Code"; Rec."Network Reason Code")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Network Reason Code field.';
+ }
+ field(Status; Rec.Status)
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Status field.';
+ }
+ field("Evidence Due By"; Rec."Evidence Due By")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Evidence Due By field.';
+ }
+ field("Evidence Sent On"; Rec."Evidence Sent On")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Evidence Sent On field.';
+ }
+ field("Finalized On"; Rec."Finalized On")
+ {
+ ApplicationArea = All;
+ ToolTip = 'Specifies the value of the Finalized On field.';
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyPaymentTransactions.Page.al b/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyPaymentTransactions.Page.al
index 7d87bdf43a..c3f0870834 100644
--- a/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyPaymentTransactions.Page.al
+++ b/Apps/W1/Shopify/app/src/Payments/Pages/ShpfyPaymentTransactions.Page.al
@@ -102,6 +102,21 @@ page 30124 "Shpfy Payment Transactions"
Page.Run(Page::"Shpfy Data Capture List", DataCapture);
end;
}
+ action(Disputes)
+ {
+ ApplicationArea = All;
+ Caption = 'Show Related Disputes';
+ Image = Entry;
+ ToolTip = 'View the disputes related to order of the selected transaction.';
+
+ trigger OnAction();
+ var
+ Dispute: Record "Shpfy Dispute";
+ begin
+ Dispute.SetRange("Source Order Id", Rec."Source Order Id");
+ Page.Run(Page::"Shpfy Disputes", Dispute);
+ end;
+ }
}
}
}
diff --git a/Apps/W1/Shopify/app/src/Payments/Reports/ShpfySyncDisputes.Report.al b/Apps/W1/Shopify/app/src/Payments/Reports/ShpfySyncDisputes.Report.al
new file mode 100644
index 0000000000..0190bdc155
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Reports/ShpfySyncDisputes.Report.al
@@ -0,0 +1,25 @@
+namespace Microsoft.Integration.Shopify;
+
+report 30120 "Shpfy Sync Disputes"
+{
+ ApplicationArea = All;
+ Caption = 'Shopify Sync Disputes';
+ ProcessingOnly = true;
+ UsageCategory = Tasks;
+
+ dataset
+ {
+ dataitem(Shop; "Shpfy Shop")
+ {
+ RequestFilterFields = Code;
+ trigger OnAfterGetRecord()
+ var
+ Sync: Codeunit "Shpfy Payments";
+ begin
+ Sync.SetShop(Shop);
+ Sync.UpdateUnfinishedDisputes();
+ Sync.ImportNewDisputes();
+ end;
+ }
+ }
+}
diff --git a/Apps/W1/Shopify/app/src/Payments/Tables/ShpfyDispute.Table.al b/Apps/W1/Shopify/app/src/Payments/Tables/ShpfyDispute.Table.al
new file mode 100644
index 0000000000..9673d0e9d2
--- /dev/null
+++ b/Apps/W1/Shopify/app/src/Payments/Tables/ShpfyDispute.Table.al
@@ -0,0 +1,79 @@
+namespace Microsoft.Integration.Shopify;
+
+///
+/// Table Shopify Payout (ID 30125).
+///
+table 30155 "Shpfy Dispute"
+{
+ Access = Internal;
+ Caption = 'Shopify Dispute';
+ DataClassification = CustomerContent;
+
+ fields
+ {
+ field(1; Id; BigInteger)
+ {
+ Caption = 'Id';
+ DataClassification = SystemMetadata;
+ }
+ field(2; "Source Order Id"; BigInteger)
+ {
+ BlankZero = true;
+ Caption = 'Source Order Id';
+ DataClassification = SystemMetadata;
+ TableRelation = "Shpfy Order Header";
+ }
+ field(3; Type; Enum "Shpfy Dispute Type")
+ {
+ Caption = 'Type';
+ DataClassification = CustomerContent;
+ }
+ field(4; Currency; Code[10])
+ {
+ Caption = 'Currency';
+ DataClassification = CustomerContent;
+ }
+ field(5; Amount; Decimal)
+ {
+ Caption = 'Amount';
+ DataClassification = CustomerContent;
+ }
+ field(6; "Reason"; enum "Shpfy Dispute Reason")
+ {
+ Caption = 'Shpfy Dispute Reason';
+ DataClassification = CustomerContent;
+ }
+ field(7; "Network Reason Code"; Text[100])
+ {
+ Caption = 'Network Reason Code';
+ DataClassification = CustomerContent;
+ }
+ field(8; "Status"; Enum "Shpfy Dispute Status")
+ {
+ Caption = 'Status';
+ DataClassification = CustomerContent;
+ }
+ field(9; "Evidence Due By"; DateTime)
+ {
+ Caption = 'Evidence Due By';
+ DataClassification = CustomerContent;
+ }
+ field(10; "Evidence Sent On"; DateTime)
+ {
+ Caption = 'Evidence Sent On';
+ DataClassification = CustomerContent;
+ }
+ field(11; "Finalized On"; DateTime)
+ {
+ Caption = 'Finalized On';
+ DataClassification = CustomerContent;
+ }
+ }
+ keys
+ {
+ key(PK; Id)
+ {
+ Clustered = true;
+ }
+ }
+}
diff --git a/Apps/W1/Shopify/test/Payments/ShpfyPaymentsTest.Codeunit.al b/Apps/W1/Shopify/test/Payments/ShpfyPaymentsTest.Codeunit.al
index 049b2e060a..74d20809fd 100644
--- a/Apps/W1/Shopify/test/Payments/ShpfyPaymentsTest.Codeunit.al
+++ b/Apps/W1/Shopify/test/Payments/ShpfyPaymentsTest.Codeunit.al
@@ -53,4 +53,51 @@ codeunit 139566 "Shpfy Payments Test"
JPayment.Add('processed_at', Format(CurrentDateTime - 1, 0, 9));
exit(JPayment.AsToken());
end;
+
+ [Test]
+ procedure UnitTestImportDispute()
+ var
+ Dispute: Record "Shpfy Dispute";
+ Payments: Codeunit "Shpfy Payments";
+ DisputeToken: JsonToken;
+ DisputeStatus: Enum "Shpfy Dispute Status";
+ FinalizedOn: DateTime;
+ Id: BigInteger;
+ begin
+ // [SCENARIO] Extract the data out json token that contains a Dispute info into the "Shpfy Dispute" record.
+ // [GIVEN] A random Generated Dispute
+ Id := Any.IntegerInRange(10000, 99999);
+ DisputeToken := GetRandomDisputeAsJsonToken(Id, DisputeStatus, FinalizedOn);
+
+ // [WHEN] Invoke the function ImportDisputeData(JToken)
+ Payments.ImportDisputeData(DisputeToken);
+
+ // // [THEN] A dispute record is created and the dispute status and finalized on should match the generated one
+ Dispute.Get(Id);
+ LibraryAssert.AreEqual(DisputeStatus, Dispute.Status, 'Dispute status should match the generated one');
+ LibraryAssert.AreEqual(FinalizedOn, Dispute."Finalized On", 'Dispute finalized on should match the generated one');
+ end;
+
+ local procedure GetRandomDisputeAsJsonToken(Id: BigInteger; var DisputeStatus: Enum "Shpfy Dispute Status"; var FinalizedOn: DateTime): JsonToken
+ var
+ DisputeObject: JsonObject;
+ begin
+ DisputeStatus := Enum::"Shpfy Dispute Status".FromInteger(Any.IntegerInRange(0, 6));
+ FinalizedOn := CurrentDateTime - 1;
+
+ DisputeObject.Add('id', Id);
+ DisputeObject.Add('order_id', Any.IntegerInRange(10000, 99999));
+ DisputeObject.Add('type', 'chargeback');
+ DisputeObject.Add('amount', Any.DecimalInRange(100, 2));
+ DisputeObject.Add('currency', Any.IntegerInRange(10000, 99999));
+ DisputeObject.Add('reason', 'fraudulent');
+ DisputeObject.Add('network_reason_code', Any.IntegerInRange(10000, 99999));
+ DisputeObject.Add('status', Format(DisputeStatus));
+ DisputeObject.Add('evidence_due_by', Format(CurrentDateTime - 1, 0, 9));
+ DisputeObject.Add('evidence_sent_on', Format(CurrentDateTime - 1, 0, 9));
+ DisputeObject.Add('finalized_on', Format(FinalizedOn, 0, 9));
+ DisputeObject.Add('initiated_at', Format(CurrentDateTime - 1, 0, 9));
+
+ exit(DisputeObject.AsToken());
+ end;
}
\ No newline at end of file