diff --git a/.deployment/module/argoDeploy.json b/.deployment/module/argoDeploy.json
new file mode 100644
index 0000000..80721c6
--- /dev/null
+++ b/.deployment/module/argoDeploy.json
@@ -0,0 +1,29 @@
+{
+ "artifactKey": "VirtoCommerce.Datatrans",
+ "deployRepo": "vc-deploy-dev",
+ "cmPath": "platform-dev/resources/deployment-cm.yaml",
+ "dev": {
+ "deployAppName": "vcplatform-dev",
+ "deployBranch": "dev",
+ "environmentId": "dev",
+ "environmentName": "Development",
+ "environmentType": "staging",
+ "environmentUrl": "https://vcplatform-platform.dev.govirto.com/"
+ },
+ "qa": {
+ "deployAppName": "vcplatform-qa",
+ "deployBranch": "qa",
+ "environmentId": "qa",
+ "environmentName": "QA",
+ "environmentType": "testing",
+ "environmentUrl": "https://vcplatform-platform.qa.govirto.com/"
+ },
+ "prod": {
+ "deployAppName": "vcplatform-demo",
+ "deployBranch": "demo",
+ "environmentId": "prod",
+ "environmentName": "Demo",
+ "environmentType": "production",
+ "environmentUrl": "https://vcplatform-platform.demo.govirto.com/"
+ }
+}
\ No newline at end of file
diff --git a/.deployment/module/cloudDeploy.json b/.deployment/module/cloudDeploy.json
new file mode 100644
index 0000000..8042bad
--- /dev/null
+++ b/.deployment/module/cloudDeploy.json
@@ -0,0 +1,29 @@
+{
+ "artifactKey": "VirtoCommerce.Datatrans",
+ "deployRepo": "vc-deploy-dev",
+ "cmPath": "backend/packages.json",
+ "dev": {
+ "deployAppName": "vcptcore-dev",
+ "deployBranch": "vcptcore-dev",
+ "environmentId": "dev",
+ "environmentName": "Development",
+ "environmentType": "staging",
+ "environmentUrl": "https://vcptcore-dev.govirto.com/"
+ },
+ "qa": {
+ "deployAppName": "vcptcore-qa",
+ "deployBranch": "vcptcore-qa",
+ "environmentId": "qa",
+ "environmentName": "QA",
+ "environmentType": "testing",
+ "environmentUrl": "https://vcptcore-qa.govirto.com/"
+ },
+ "prod": {
+ "deployAppName": "vcptcore-demo",
+ "deployBranch": "vcptcore-demo",
+ "environmentId": "prod",
+ "environmentName": "Demo",
+ "environmentType": "production",
+ "environmentUrl": "https://vcptcore-demo.govirto.com/"
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..d467f1b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,169 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = crlf
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+# Project files
+[*.{csproj,props}]
+insert_final_newline = false
+
+# HTML files
+[*.{html,htm}]
+insert_final_newline = false
+
+# Code
+[*.{cs,js,ts,ps1,sh,bat,cmd}]
+indent_size = 4
+
+# Dotnet code style settings
+[*.{cs,vb}]
+
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Use explicit accessibility modifiers
+dotnet_style_require_accessibility_modifiers = true:suggestion
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_prefer_inferred_tuple_names = true:suggestion
+dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion
+
+# CSharp code style settings
+[*.cs]
+
+# Prefer curly braces even for one line of code
+csharp_prefer_braces = true:suggestion
+
+# Prefer "var" everywhere
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+csharp_style_var_elsewhere = true:suggestion
+
+# Prefer method-like constructs to have a block body
+csharp_style_expression_bodied_methods = false:none
+csharp_style_expression_bodied_constructors = false:none
+csharp_style_expression_bodied_operators = false:none
+
+# Prefer property-like constructs to have an expression-body
+csharp_style_expression_bodied_properties = true:none
+csharp_style_expression_bodied_indexers = true:none
+csharp_style_expression_bodied_accessors = true:none
+
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+
+# Newline settings
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+
+csharp_space_after_cast = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+
+csharp_preserve_single_line_statements = false
+csharp_preserve_single_line_blocks = true
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_style_namespace_declarations = file_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+
+[*.{cs,vb}]
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+dotnet_style_namespace_match_folder = true:suggestion
diff --git a/.gitattributes b/.gitattributes
index 1ff0c42..176a458 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,63 +1 @@
-###############################################################################
-# Set default behavior to automatically normalize line endings.
-###############################################################################
* text=auto
-
-###############################################################################
-# Set default behavior for command prompt diff.
-#
-# This is need for earlier builds of msysgit that does not have it on by
-# default for csharp files.
-# Note: This is only used by command line
-###############################################################################
-#*.cs diff=csharp
-
-###############################################################################
-# Set the merge driver for project and solution files
-#
-# Merging from the command prompt will add diff markers to the files if there
-# are conflicts (Merging from VS is not affected by the settings below, in VS
-# the diff markers are never inserted). Diff markers may cause the following
-# file extensions to fail to load in VS. An alternative would be to treat
-# these files as binary and thus will always conflict and require user
-# intervention with every merge. To do so, just uncomment the entries below
-###############################################################################
-#*.sln merge=binary
-#*.csproj merge=binary
-#*.vbproj merge=binary
-#*.vcxproj merge=binary
-#*.vcproj merge=binary
-#*.dbproj merge=binary
-#*.fsproj merge=binary
-#*.lsproj merge=binary
-#*.wixproj merge=binary
-#*.modelproj merge=binary
-#*.sqlproj merge=binary
-#*.wwaproj merge=binary
-
-###############################################################################
-# behavior for image files
-#
-# image files are treated as binary by default.
-###############################################################################
-#*.jpg binary
-#*.png binary
-#*.gif binary
-
-###############################################################################
-# diff behavior for common document formats
-#
-# Convert binary document formats to text before diffing them. This feature
-# is only available from the command line. Turn it on by uncommenting the
-# entries below.
-###############################################################################
-#*.doc diff=astextplain
-#*.DOC diff=astextplain
-#*.docx diff=astextplain
-#*.DOCX diff=astextplain
-#*.dot diff=astextplain
-#*.DOT diff=astextplain
-#*.pdf diff=astextplain
-#*.PDF diff=astextplain
-#*.rtf diff=astextplain
-#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
index 184789a..ea99cfe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,36 +1,72 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
+*.userosscache
*.sln.docstates
-# Build results
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+# Build results
[Dd]ebug/
+[Dd]ebugPublic/
[Rr]elease/
-bin/x64/
-bin/x86/
-build/
+[Rr]eleases/
+x64/
+x86/
+bld/
[Bb]in/
-[Bb]in/**/*
[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
-# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
-!packages/*/build/
+# Visual Studio 2017 auto generated files
+Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
*_i.c
*_p.c
+*_h.h
*.ilk
*.meta
*.obj
+*.iobj
*.pch
*.pdb
+*.ipdb
*.pgc
*.pgd
*.rsp
@@ -45,21 +81,34 @@ build/
*.vssscc
.builds
*.pidb
-*.log
+*.svclog
*.scc
+# Chutzpah Test files
+_Chutzpah*
+
# Visual C++ cache files
ipch/
*.aps
*.ncb
+*.opendb
*.opensdf
*.sdf
*.cachefile
+*.VC.db
+*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
# Guidance Automation Toolkit
*.gpState
@@ -67,6 +116,10 @@ ipch/
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
# TeamCity is a build add-in
_TeamCity*
@@ -74,9 +127,25 @@ _TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
# NCrunch
-*.ncrunch*
+_NCrunch_*
.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
# Installshield output folder
[Ee]xpress/
@@ -95,64 +164,176 @@ DocProject/Help/html
publish/
# Publish Web Output
-*.Publish.xml
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
-# NuGet Packages Directory
-## TODO: If you have NuGet Package Restore enabled, uncomment the next line
-packages/
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
-# Windows Azure Build Output
-csx
+# Microsoft Azure Build Output
+csx/
*.build.csdef
-# Windows Store app package directory
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
# Others
-sql/
-*.Cache
ClientBin/
-[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
-*.[Pp]ublish.xml
+*.dbproj.schemaview
+*.jfm
*.pfx
*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
# RIA/Silverlight projects
Generated_Code/
-# Backup & report files from converting an old project file to a newer
-# Visual Studio version. Backup files are not needed, because we have git ;-)
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
# SQL Server files
-App_Data/*.mdf
-App_Data/*.ldf
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
-# =========================
-# Windows detritus
-# =========================
+# FAKE - F# Make
+.fake/
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
+# JetBrains Rider
+.idea/
+*.sln.iml
-# Folder config file
-Desktop.ini
+# CodeRush
+.cr/
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
-# Mac crap
-.DS_Store
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Virto
*.nupkg
*.zip
-
-.vs/
+.nuke
+dist/
+**/Properties/launchSettings.json
diff --git a/CommonAssemblyInfo.cs b/CommonAssemblyInfo.cs
deleted file mode 100644
index 4168720..0000000
--- a/CommonAssemblyInfo.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-//
-// Copyright © VirtoCommerce. All rights reserved.
-//
-//
-// Virto Commerce
-//
-// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyCompany("VirtoCommerce")]
-[assembly: AssemblyProduct("Virto Commerce Datatrans Module")]
-[assembly: AssemblyCopyright("Copyright © VirtoCommerce 2020")]
-
-[assembly: AssemblyFileVersion("1.1.2.0")]
-[assembly: AssemblyVersion("1.1.2.0")]
-
-#if DEBUG
-[assembly: AssemblyConfiguration("Debug")]
-#else
-[assembly: AssemblyConfiguration("Release")]
-#endif
-
-[assembly: ComVisible(false)]
-[assembly: CLSCompliant(true)]
diff --git a/Datatrans.Checkout.Core/Datatrans.Checkout.Core.csproj b/Datatrans.Checkout.Core/Datatrans.Checkout.Core.csproj
deleted file mode 100644
index 6aae8a6..0000000
--- a/Datatrans.Checkout.Core/Datatrans.Checkout.Core.csproj
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {62A342C4-FEE9-474F-9433-43C81D9CEAC9}
- Library
- Properties
- Datatrans.Checkout.Core
- Datatrans.Checkout.Core
- v4.6.1
- 512
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
- ..\packages\VirtoCommerce.Domain.2.24.19\lib\net461\VirtoCommerce.Domain.dll
- True
-
-
- ..\packages\VirtoCommerce.Platform.Core.2.13.24\lib\net461\VirtoCommerce.Platform.Core.dll
-
-
-
-
- Properties\CommonAssemblyInfo.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Datatrans.Checkout.Core.nuspec b/Datatrans.Checkout.Core/Datatrans.Checkout.Core.nuspec
deleted file mode 100644
index fd3b3a5..0000000
--- a/Datatrans.Checkout.Core/Datatrans.Checkout.Core.nuspec
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- VirtoCommerce.DatatransModule.Core
- 1.0.4
- VirtoCommerce.DatatransModule.Core
-
-
-
- VirtoCommerce
- VirtoCommerce
- https://github.com/VirtoCommerce/vc-module-datatrans
- https://github.com/VirtoCommerce/vc-module-datatrans/raw/master/NuGet/icon.png
- false
- VirtoCommerce Datatrans payment gateway implementation
- Copyright © VirtoCommerce 2011-2017
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Model/DatatransAirlineData.cs b/Datatrans.Checkout.Core/Model/DatatransAirlineData.cs
deleted file mode 100644
index f6f0c6e..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransAirlineData.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System.Collections.Generic;
-
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransAirlineData
- {
- public DatatransAirlineData()
- {
- Tickets = new List();
- }
-
- public string CountryCode { get; set; }
-
- public string AgentCode { get; set; }
-
- public string PNR { get; set; }
-
- public string IssueDate { get; set; }
-
- public IList Tickets { get; set; }
- }
-
- public class DatatransTicket
- {
- public DatatransTicket()
- {
- Flights = new List();
- }
-
- public string Index { get; set; }
-
- public string TicketNumber { get; set; }
-
- public string PassengerName { get; set; }
-
- public string DescrCode { get; set; }
-
- public IList Flights { get; set; }
- }
-
- public class DatatransFlight
- {
- public string Index { get; set; }
-
- public string Origin { get; set; }
-
- public string Destination { get; set; }
-
- public string Carrier { get; set; }
-
- public string Class { get; set; }
-
- public string FareBasis { get; set; }
-
- public string FlightNumber { get; set; }
-
- public string FlightDate { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransCheckoutSettings.cs b/Datatrans.Checkout.Core/Model/DatatransCheckoutSettings.cs
deleted file mode 100644
index e424c46..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransCheckoutSettings.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using VirtoCommerce.Domain.Order.Model;
-using VirtoCommerce.Domain.Store.Model;
-
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransCheckoutSettings
- {
- public Store Store { get; set; }
-
- public CustomerOrder Order { get; set; }
-
- public int Amount { get; set; }
-
- public string MerchantId { get; set; }
-
- public string ReferenceNumber { get; set; }
-
- public string Sign { get; set; }
-
- ///
- /// Settlement or Sale
- ///
- public string PaymentAction { get; set; }
-
- ///
- /// VIS,ECA etc
- ///
- public string PaymentMethod { get; set; }
-
- public string PurchaseCurrency { get; set; }
-
- public string Language { get; set; }
-
- ///
- /// cart/externalpaymentcallback
- ///
- public string FormActionUrl { get; set; }
-
- ///
- /// Live or test
- ///
- public string FrontendApi { get; set; }
-
- ///
- /// Code of this payment method
- ///
- public string InternalPaymentMethodCode { get; set; }
-
- public string PaymentMethodCodeParamName { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Model/DatatransErrorCodes.cs b/Datatrans.Checkout.Core/Model/DatatransErrorCodes.cs
deleted file mode 100644
index 62d44ad..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransErrorCodes.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public static class DatatransErrorCodes
- {
- public const int DefaultErrorCode = -1000;
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransRefundRequest.cs b/Datatrans.Checkout.Core/Model/DatatransRefundRequest.cs
deleted file mode 100644
index 65e6590..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransRefundRequest.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- ///
- /// https://docs.datatrans.ch/docs/payment-process-refund
- ///
- public class DatatransRefundRequest : DatatransRequest
- {
- public DatatransRefundRequest()
- {
- TransType = "06"; // 06 Indicate a refund request
- ServiceVersion = "1";
- }
-
- public string ReferenceNumber { get; set; }
-
- public int Amount { get; set; }
-
- public string Currency { get; set; }
-
- public string TransType { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransRefundResponse.cs b/Datatrans.Checkout.Core/Model/DatatransRefundResponse.cs
deleted file mode 100644
index 09e76e8..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransRefundResponse.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransRefundResponse
- {
- public string TransactionId { get; set; }
-
- public string ErrorCode { get; set; }
-
- public string ErrorMessage { get; set; }
-
- public string ErrorDetail { get; set; }
-
- public string ResponseData { get; set; }
-
- public string ResponseCode { get; set; }
-
- public string ResponseMessage { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransRequest.cs b/Datatrans.Checkout.Core/Model/DatatransRequest.cs
deleted file mode 100644
index 6992204..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransRequest.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public abstract class DatatransRequest
- {
- public string MerchantId { get; set; }
-
- public string TransactionId { get; set; }
-
- public string ServiceVersion { get; set; }
-
- public string Sign { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransResponse.cs b/Datatrans.Checkout.Core/Model/DatatransResponse.cs
deleted file mode 100644
index 5e95efe..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransResponse.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransResponse
- {
- public string TransactionId { get; set; }
-
- public string ResponseContent { get; set; }
-
- public string Status { get; set; }
-
- public string ErrorMessage { get; set; }
-
- public string ErrorCode { get; set; }
-
- public string ErrorDetail { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransSettlementRequest.cs b/Datatrans.Checkout.Core/Model/DatatransSettlementRequest.cs
deleted file mode 100644
index ca9361d..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransSettlementRequest.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransSettlementRequest : DatatransRequest
- {
- public DatatransSettlementRequest()
- {
- ServiceVersion = "1";
- }
-
- public string ReferenceNumber { get; set; }
-
- public int Amount { get; set; }
-
- public string Currency { get; set; }
-
- public DatatransAirlineData AirlineData { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransSettlementResponse.cs b/Datatrans.Checkout.Core/Model/DatatransSettlementResponse.cs
deleted file mode 100644
index 53f085a..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransSettlementResponse.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransSettlementResponse : DatatransResponse
- {
- public string ResponseCode { get; set; }
-
- public string ResponseMessage { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransTransactionRequest.cs b/Datatrans.Checkout.Core/Model/DatatransTransactionRequest.cs
deleted file mode 100644
index 6b9c1e1..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransTransactionRequest.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransTransactionRequest : DatatransRequest
- {
- public DatatransTransactionRequest()
- {
- ReqestType = "STX";
- ServiceVersion = "3";
- }
-
- public string ReqestType { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/DatatransTransactionResponse.cs b/Datatrans.Checkout.Core/Model/DatatransTransactionResponse.cs
deleted file mode 100644
index 7ccaccc..0000000
--- a/Datatrans.Checkout.Core/Model/DatatransTransactionResponse.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace Datatrans.Checkout.Core.Model
-{
- public class DatatransTransactionResponse : DatatransResponse
- {
- public string ResponseCode { get; set; }
-
- public string ResponseMessage { get; set; }
-
- public string ReferenceNumber { get; set; }
-
- public string Amount { get; set; }
-
- public string Currency { get; set; }
-
- public string AuthorizationCode { get; set; }
-
- public string PaymentMethod { get; set; }
-
- public string MaskedCC { get; set; }
-
- public string AliasCC { get; set; }
-
- public string ExpirationMonth { get; set; }
-
- public string ExpirationYear { get; set; }
-
- public string TransactionDate { get; set; }
-
- public string TransactionTime { get; set; }
-
- public string TransactionType { get; set; }
-
- public string SettledAmount { get; set; }
-
- public string ItemNumber { get; set; }
- }
-}
diff --git a/Datatrans.Checkout.Core/Model/GetAirlineDataContext.cs b/Datatrans.Checkout.Core/Model/GetAirlineDataContext.cs
deleted file mode 100644
index b6411cc..0000000
--- a/Datatrans.Checkout.Core/Model/GetAirlineDataContext.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Collections.Specialized;
-using VirtoCommerce.Domain.Order.Model;
-
-namespace Datatrans.Checkout.Core.Model
-{
- public class GetAirlineDataContext
- {
- public CustomerOrder Order { get; set; }
-
- public PaymentIn Payment { get; set; }
-
- public NameValueCollection Parameters { get; set; }
-
- public GetAirlineDataContext()
- {
- }
-
- public GetAirlineDataContext(CustomerOrder order, PaymentIn payment, NameValueCollection parameters)
- {
- Order = order;
- Payment = payment;
- Parameters = parameters;
- }
- }
-}
diff --git a/Datatrans.Checkout.Core/Properties/AssemblyInfo.cs b/Datatrans.Checkout.Core/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1ec9ef1..0000000
--- a/Datatrans.Checkout.Core/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-using System.Reflection;
-
-[assembly: AssemblyTitle("Datatrans.Checkout.Core")]
-[assembly: AssemblyDescription("")]
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Services/IDatatransCapturePaymentService.cs b/Datatrans.Checkout.Core/Services/IDatatransCapturePaymentService.cs
deleted file mode 100644
index f281cd0..0000000
--- a/Datatrans.Checkout.Core/Services/IDatatransCapturePaymentService.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.Core.Services
-{
- public interface IDatatransCapturePaymentService
- {
- DatatransAirlineData GetAirlineData(GetAirlineDataContext context);
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Services/IDatatransCheckoutService.cs b/Datatrans.Checkout.Core/Services/IDatatransCheckoutService.cs
deleted file mode 100644
index ae5578a..0000000
--- a/Datatrans.Checkout.Core/Services/IDatatransCheckoutService.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.Core.Services
-{
- public interface IDatatransCheckoutService
- {
- string GetCheckoutFormContent(DatatransCheckoutSettings context);
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/Services/IDatatransClient.cs b/Datatrans.Checkout.Core/Services/IDatatransClient.cs
deleted file mode 100644
index 2e7729e..0000000
--- a/Datatrans.Checkout.Core/Services/IDatatransClient.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.Core.Services
-{
- public interface IDatatransClient
- {
- string ServiceEndpoint { get; set; }
-
- DatatransSettlementResponse SettleTransaction(DatatransSettlementRequest request);
-
- DatatransTransactionResponse GetTransactionStatus(DatatransTransactionRequest request);
-
- DatatransRefundResponse Refund(DatatransRefundRequest request);
- }
-}
diff --git a/Datatrans.Checkout.Core/app.config b/Datatrans.Checkout.Core/app.config
deleted file mode 100644
index 2bbe771..0000000
--- a/Datatrans.Checkout.Core/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Core/packages.config b/Datatrans.Checkout.Core/packages.config
deleted file mode 100644
index 0321c3e..0000000
--- a/Datatrans.Checkout.Core/packages.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/Datatrans.Checkout.Tests.csproj b/Datatrans.Checkout.Tests/Datatrans.Checkout.Tests.csproj
deleted file mode 100644
index 97e4c4b..0000000
--- a/Datatrans.Checkout.Tests/Datatrans.Checkout.Tests.csproj
+++ /dev/null
@@ -1,140 +0,0 @@
-
-
-
-
-
-
- Debug
- AnyCPU
- {9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}
- Library
- Properties
- Datatrans.Checkout.Tests
- Datatrans.Checkout.Tests
- v4.6.1
- 512
-
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll
- True
-
-
- ..\packages\FluentValidation.7.3.1\lib\net45\FluentValidation.dll
- True
-
-
- ..\packages\Moq.4.7.145\lib\net45\Moq.dll
- True
-
-
- ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
-
- ..\packages\VirtoCommerce.Domain.2.24.19\lib\net461\VirtoCommerce.Domain.dll
- True
-
-
- ..\packages\VirtoCommerce.Platform.Core.2.13.24\lib\net461\VirtoCommerce.Platform.Core.dll
-
-
- ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll
- True
-
-
- ..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll
- True
-
-
- ..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll
- True
-
-
- ..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll
- True
-
-
-
-
- Properties\CommonAssemblyInfo.cs
-
-
-
-
-
-
-
-
-
- {62a342c4-fee9-474f-9433-43c81d9ceac9}
- Datatrans.Checkout.Core
-
-
- {c602c6c1-f419-466f-904d-d73d06b50af3}
- Datatrans.Checkout
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/DatatransTests.cs b/Datatrans.Checkout.Tests/DatatransTests.cs
deleted file mode 100644
index 7f74af5..0000000
--- a/Datatrans.Checkout.Tests/DatatransTests.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using Datatrans.Checkout.Core.Services;
-using Datatrans.Checkout.Managers;
-using Datatrans.Checkout.Services;
-using Moq;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using VirtoCommerce.Domain.Order.Model;
-using VirtoCommerce.Domain.Payment.Model;
-using VirtoCommerce.Platform.Core.Settings;
-using Xunit;
-
-namespace Datatrans.Checkout.Tests
-{
- public class DatatransTests
- {
- [Fact]
- public void TestRefund()
- {
- var context = new RefundProcessPaymentEvaluationContext
- {
- Order = new CustomerOrder
- {
- Number = "",
- Currency = "USD"
- },
- Payment = new PaymentIn
- {
- OuterId = "",
- Sum = 0M,
- Transactions = new List()
- },
- Parameters = new NameValueCollection
- {
- {"RefundAmount", (-5.33M).ToString(CultureInfo.InvariantCulture)}
- }
- };
-
- var endpoint = "https://api.sandbox.datatrans.com";
- var username = "";
- var password = "";
- var hmacKey = "";
-
- var datatransClient = CreateDatatransClient(endpoint, username, password);
-
- var datatransClientFactory = CreateDatatransClientFactory(datatransClient);
-
- var datatransCheckoutService = CreateDatatransCheckoutService();
- var datatransCapturePaymentService = CreateDatatransCapturePaymentService();
-
- var datatransCheckoutPaymentMethod = CreateDatatransCheckoutPaymentMethod(
- datatransCheckoutService.Object,
- datatransClientFactory,
- datatransCapturePaymentService.Object,
- CreateSignProvider(hmacKey));
-
- datatransCheckoutPaymentMethod.Settings = new List
- {
- new SettingEntry
- {
- Name = "Datatrans.Checkout.MerchantId",
- Value = ""
- }
- };
-
- var result = datatransCheckoutPaymentMethod.RefundProcessPayment(context);
- }
-
- private Mock CreateDatatransCheckoutService()
- {
- return new Mock();
- }
-
- private IDatatransClient CreateDatatransClient(string serviceEndpoint, string username, string password)
- {
- return new DatatransClient.DatatransClient(serviceEndpoint, username, password);
- }
-
- private Mock CreateDatatransCapturePaymentService()
- {
- return new Mock();
- }
-
- private Func CreateDatatransClientFactory(IDatatransClient datatransClient)
- {
- return (s, s1, s2) => datatransClient;
- }
-
- private Func CreateSignProvider(string hmacKey)
- {
- return s => new SignProvider(hmacKey);
- }
-
- private DatatransCheckoutPaymentMethod CreateDatatransCheckoutPaymentMethod(
- IDatatransCheckoutService datatransCheckoutService,
- Func datatransClientFactory,
- IDatatransCapturePaymentService datatransCapturePaymentService,
- Func signProviderFactory)
- {
- return new DatatransCheckoutPaymentMethod(
- datatransCheckoutService,
- datatransClientFactory,
- datatransCapturePaymentService,
- signProviderFactory);
- }
- }
-}
diff --git a/Datatrans.Checkout.Tests/DatatranscheckoutPaymentMethodTests.cs b/Datatrans.Checkout.Tests/DatatranscheckoutPaymentMethodTests.cs
deleted file mode 100644
index e2443c4..0000000
--- a/Datatrans.Checkout.Tests/DatatranscheckoutPaymentMethodTests.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-using Datatrans.Checkout.Core.Services;
-using Datatrans.Checkout.Managers;
-using Datatrans.Checkout.Services;
-using Moq;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using VirtoCommerce.Platform.Core.Settings;
-using Xunit;
-
-namespace Datatrans.Checkout.Tests
-{
- public class DatatransCheckoutPaymentMethodTests
- {
- [Fact]
- public void ValidatePostProcessRequestWithHmacAndSign2Test()
- {
- var signProviderFactory = CreateMockSignProviderFactory(CreateSignProvider());
-
- var paymentMethod = CreateDatatransCheckoutPaymentMethod(
- CreateMockDatatransCheckoutService().Object,
- CreateMockDatatransFactory().Object,
- CreateMockDatatransCapturePaymentService().Object,
- signProviderFactory.Object);
-
- paymentMethod.Settings = new List
- {
- new SettingEntry
- {
- Name = "Datatrans.Checkout.HMACHex",
- Value = "testHMACHex"
- },
- };
-
- var queryParams = new NameValueCollection
- {
- {"paymentMethodCode", "DatatransCheckout"},
- {"sign2", "testSign2"},
- {"uppTransactionId", "testUppTransactionId"},
- {"amount", "123"},
- {"currency", "RU-ru"},
- {"merchantId", "testMerchantId"},
- {"status", "success"},
- };
-
- var result = paymentMethod.ValidatePostProcessRequest(queryParams);
-
- signProviderFactory.Verify(x => x("testHMACHex"), Times.Once);
- Assert.True(result.IsSuccess);
- }
-
- [Fact]
- public void ValidatePostProcessRequestWithHmacWithoutSign2Test()
- {
- var signProviderFactory = CreateMockSignProviderFactory(CreateSignProvider());
-
- var paymentMethod = CreateDatatransCheckoutPaymentMethod(
- CreateMockDatatransCheckoutService().Object,
- CreateMockDatatransFactory().Object,
- CreateMockDatatransCapturePaymentService().Object,
- signProviderFactory.Object);
-
- paymentMethod.Settings = new List
- {
- new SettingEntry
- {
- Name = "Datatrans.Checkout.HMACHex",
- Value = "test"
- },
- };
-
- var queryParams = new NameValueCollection
- {
- {"paymentMethodCode", "DatatransCheckout"},
- {"uppTransactionId", "testUppTransactionId"},
- {"amount", "123"},
- {"currency", "RU-ru"},
- {"merchantId", "testMerchantId"},
- };
-
- var result = paymentMethod.ValidatePostProcessRequest(queryParams);
-
- signProviderFactory.Verify(x => x("test"), Times.Never);
- Assert.False(result.IsSuccess);
- }
-
- [Fact]
- public void ValidatePorstProcessRequestWitHmac2WithSign2Test()
- {
- var signProviderFactory = CreateMockSignProviderFactory(CreateSignProvider());
-
- var paymentMethod = CreateDatatransCheckoutPaymentMethod(
- CreateMockDatatransCheckoutService().Object,
- CreateMockDatatransFactory().Object,
- CreateMockDatatransCapturePaymentService().Object,
- signProviderFactory.Object);
-
- paymentMethod.Settings = new List
- {
- new SettingEntry
- {
- Name = "Datatrans.Checkout.HMACHEXSign2",
- Value = "testHMACHEXSign2"
- },
- new SettingEntry
- {
- Name = "Datatrans.Checkout.HMACHex",
- Value = "testHMACHEX"
- },
- };
-
- var queryParams = new NameValueCollection
- {
- {"paymentMethodCode", "DatatransCheckout"},
- {"sign2", "testSign2"},
- {"uppTransactionId", "testUppTransactionId"},
- {"amount", "123"},
- {"currency", "RU-ru"},
- {"merchantId", "testMerchantId"},
- {"status", "success"},
- };
-
- var result = paymentMethod.ValidatePostProcessRequest(queryParams);
-
- signProviderFactory.Verify(x => x("testHMACHEXSign2"), Times.Once);
- Assert.True(result.IsSuccess);
- }
-
- [Fact]
- public void No_Validation_Test()
- {
- var signProviderFactory = CreateMockSignProviderFactory(CreateSignProvider());
-
- var paymentMethod = CreateDatatransCheckoutPaymentMethod(
- CreateMockDatatransCheckoutService().Object,
- CreateMockDatatransFactory().Object,
- CreateMockDatatransCapturePaymentService().Object,
- signProviderFactory.Object);
-
- paymentMethod.Settings = new List
- {
- new SettingEntry
- {
- Name = "Datatrans.Checkout.HMACHex",
- Value = null
- },
- };
-
- var queryParams = new NameValueCollection
- {
- {"paymentMethodCode", "DatatransCheckout"},
- {"uppTransactionId", "testUppTransactionId"},
- {"amount", "123"},
- {"currency", "RU-ru"},
- {"merchantId", "testMerchantId"},
- {"status", "success"},
- };
-
- var result = paymentMethod.ValidatePostProcessRequest(queryParams);
-
- signProviderFactory.Verify(x => x(It.IsAny()), Times.Never);
- Assert.True(result.IsSuccess);
- }
-
-
- private ISignProvider CreateSignProvider()
- {
- var signProvider = new Mock();
-
- signProvider
- .Setup(x =>
- x.ValidateSignature(
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny()
- )
- )
- .Returns(true);
-
- return signProvider.Object;
- }
-
- private Mock> CreateMockSignProviderFactory(ISignProvider signProvider)
- {
- var providerFactory = new Mock>();
-
- providerFactory.Setup(x => x(It.IsAny())).Returns(signProvider);
-
- return providerFactory;
- }
-
- private Mock CreateMockDatatransCapturePaymentService()
- {
- return new Mock();
- }
-
- private Mock> CreateMockDatatransFactory()
- {
- return new Mock>();
- }
-
- private Mock CreateMockDatatransCheckoutService()
- {
- return new Mock();
- }
-
- private DatatransCheckoutPaymentMethod CreateDatatransCheckoutPaymentMethod(
- IDatatransCheckoutService datatransCheckoutService,
- Func datatransClientFactory,
- IDatatransCapturePaymentService datatransCapturePaymentService,
- Func signProviderFactory)
- {
- return new DatatransCheckoutPaymentMethod(datatransCheckoutService, datatransClientFactory, datatransCapturePaymentService, signProviderFactory);
- }
- }
-}
diff --git a/Datatrans.Checkout.Tests/Properties/AssemblyInfo.cs b/Datatrans.Checkout.Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index f90919c..0000000
--- a/Datatrans.Checkout.Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-using System.Reflection;
-
-[assembly: AssemblyTitle("Datatrans.Checkout.Tests")]
-[assembly: AssemblyDescription("")]
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/ServiceResponseCovertionTests.cs b/Datatrans.Checkout.Tests/ServiceResponseCovertionTests.cs
deleted file mode 100644
index e080cfc..0000000
--- a/Datatrans.Checkout.Tests/ServiceResponseCovertionTests.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using Datatrans.Checkout.DatatransClient.Converters;
-using Datatrans.Checkout.DatatransClient.Models;
-using System.IO;
-using VirtoCommerce.Platform.Core.Common;
-using Xunit;
-
-namespace Datatrans.Checkout.Tests
-{
- public class ServiceResponseTests
- {
- [Fact]
- public void ReadSettleResponse_SuccessfulReponse_ResponseRead()
- {
- //arrange
- var response = File.ReadAllText(@"../../data/settleResponseSuccess.xml");
-
- //act
- var deserializeXml = response.DeserializeXml();
- var target = deserializeXml.ToCoreModel();
-
- //assert
- Assert.Equal("01", target.ResponseCode);
- Assert.Equal("settlement succeeded", target.ResponseMessage);
- }
-
- [Fact]
- public void ReadSettleResponse_FailedReponse_ResponseRead()
- {
- var response = File.ReadAllText(@"../../data/settleResponseError.xml");
-
- var deserializeXml = response.DeserializeXml();
- var target = deserializeXml.ToCoreModel();
-
- //assert
- Assert.Equal("-80", target.ErrorCode);
- Assert.Equal("UPP record not found", target.ErrorMessage);
- }
-
- [Fact]
- public void StatuesResponse_SuccessfulReponse_ResponseRead()
- {
- var response = File.ReadAllText(@"../../data/statusResponseSuccess.xml");
-
- var deserializeXml = response.DeserializeXml();
- var target = deserializeXml.ToCoreModel();
-
- //assert
- Assert.Equal("2", target.ResponseCode);
- Assert.Equal("Trx debit waiting for daily settlement process", target.ResponseMessage);
- Assert.Equal("00400", target.ReferenceNumber);
- Assert.Equal("24720", target.Amount);
- Assert.Equal("USD", target.Currency);
- Assert.Equal("9213", target.AuthorizationCode);
- Assert.Equal("VIS", target.PaymentMethod);
- Assert.Equal("111111111111111", target.TransactionId);
- Assert.Equal("424242xxxxxx4242", target.MaskedCC);
- Assert.Equal("12", target.ExpirationMonth);
- Assert.Equal("18", target.ExpirationYear);
- Assert.Equal("20171212", target.TransactionDate);
- Assert.Equal("222638", target.TransactionTime);
- Assert.Equal("05", target.TransactionType);
- Assert.Equal("24720", target.SettledAmount);
- }
-
- [Fact]
- public void StatusSettleResponse_FailedReponse_ResponseRead()
- {
- var response = File.ReadAllText(@"../../data/statusResponseError.xml");
-
- var deserializeXml = response.DeserializeXml();
- var target = deserializeXml.ToCoreModel();
-
- //assert
- Assert.Equal("2022", target.ErrorCode);
- Assert.Equal("invalid value", target.ErrorMessage);
- Assert.Equal("merchantId", target.ErrorDetail);
- }
-
- [Fact]
- public void TestRefundResponseSuccessDeserializing()
- {
- var response = File.ReadAllText(@"../../data/refundResponseSuccess.xml");
-
- var deserializedXml = response.DeserializeXml();
-
- var refundResponse = deserializedXml.ToCoreModel();
-
- Assert.NotEmpty(refundResponse.ResponseCode);
- Assert.NotEmpty(refundResponse.ResponseMessage);
- Assert.NotEmpty(refundResponse.TransactionId);
-
- Assert.Null(refundResponse.ResponseData);
- Assert.Null(refundResponse.ErrorMessage);
- Assert.Null(refundResponse.ErrorCode);
- Assert.Null(refundResponse.ErrorDetail);
- }
-
- [Fact]
- public void TestRefundResponseErrorDeserializing()
- {
- var response = File.ReadAllText(@"../../data/refundResponseError.xml");
-
- var deserializedXml = response.DeserializeXml();
-
- var refundResponse = deserializedXml.ToCoreModel();
-
- Assert.NotEmpty(refundResponse.ErrorMessage);
- Assert.NotEmpty(refundResponse.ErrorCode);
- Assert.NotEmpty(refundResponse.ErrorDetail);
-
- Assert.Null(refundResponse.ResponseData);
- Assert.Null(refundResponse.ResponseCode);
- Assert.Null(refundResponse.ResponseMessage);
- Assert.Null(refundResponse.TransactionId);
- }
- }
-}
diff --git a/Datatrans.Checkout.Tests/SignProviderTests.cs b/Datatrans.Checkout.Tests/SignProviderTests.cs
deleted file mode 100644
index 800a980..0000000
--- a/Datatrans.Checkout.Tests/SignProviderTests.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using Datatrans.Checkout.Services;
-using System;
-using System.Security.Cryptography;
-using System.Text;
-using Xunit;
-
-namespace Datatrans.Checkout.Tests
-{
- public class SignProviderTests
- {
- [Fact]
- public void TestSignature()
- {
- var testSignatureKey = "testSignature";
-
- var signProvider = CreateSignProvider(GetHexadecimalString(testSignatureKey));
-
- var merchantId = "testMerchant";
- var amount = 123;
- var currency = "USD";
- var refno = "testRefno";
-
- var sign = signProvider.Sign(merchantId, amount, currency, refno);
- var expectedSign = CreateSignature(GetStringBytesArray(testSignatureKey), $"{merchantId}{amount.ToString()}{currency}{refno}");
-
- Assert.Equal(expectedSign, sign);
- }
-
- [Fact]
- public void TestValidation()
- {
- var testSignatureKey = "testSignatureKey";
-
- var signProvider = CreateSignProvider(GetHexadecimalString(testSignatureKey));
-
- var merchantId = "testMerchant";
- var amount = 123;
- var currency = "USD";
- var transactionId = "testTransactionId";
-
- var sourceSign = CreateSignature(GetStringBytesArray(testSignatureKey),$"{merchantId}{amount.ToString()}{currency}{transactionId}");
-
- var result = signProvider.ValidateSignature(sourceSign, merchantId, amount, currency, transactionId);
-
- Assert.True(result);
- }
-
- private SignProvider CreateSignProvider(string hex)
- {
- return new SignProvider(hex);
- }
-
- private string GetHexadecimalString(string key)
- {
- var bytes = GetStringBytesArray(key);
-
- return ConvertBytesArrayToHexadecimalString(bytes);
- }
-
- private byte[] GetStringBytesArray(string source)
- {
- return Encoding.ASCII.GetBytes(source);
- }
-
- private string CreateSignature(byte[] bytes, string strToSign)
- {
- var toSign = GetStringBytesArray(strToSign);
-
- using (var hmac = new HMACSHA256(bytes))
- {
- var hash = hmac.ComputeHash(toSign);
- return ConvertBytesArrayToHexadecimalString(hash);
- }
- }
-
- private static string ConvertBytesArrayToHexadecimalString(byte[] source)
- {
- return BitConverter.ToString(source).Replace("-", string.Empty).ToLower();
- }
- }
-}
diff --git a/Datatrans.Checkout.Tests/app.config b/Datatrans.Checkout.Tests/app.config
deleted file mode 100644
index 2bbe771..0000000
--- a/Datatrans.Checkout.Tests/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/refundResponseError.xml b/Datatrans.Checkout.Tests/data/refundResponseError.xml
deleted file mode 100644
index ddb7514..0000000
--- a/Datatrans.Checkout.Tests/data/refundResponseError.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- 11999
- USD
- 3333333333333333333333
- 06
- COA
-
-
- -72
- cannot be credited
- amount not valid
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/refundResponseSuccess.xml b/Datatrans.Checkout.Tests/data/refundResponseSuccess.xml
deleted file mode 100644
index d7eca5e..0000000
--- a/Datatrans.Checkout.Tests/data/refundResponseSuccess.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
- 11999
- USD
- 3333333333
- 06
- COA
-
-
- 01
- credit succeeded
- 444444444444444444
- 555555555555
- 6666666666
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/settleResponseError.xml b/Datatrans.Checkout.Tests/data/settleResponseError.xml
deleted file mode 100644
index 01d9745..0000000
--- a/Datatrans.Checkout.Tests/data/settleResponseError.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- 101
- USD
- 111111111111111
- COA
- 05
-
-
- -80
- UPP record not found
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/settleResponseSuccess.xml b/Datatrans.Checkout.Tests/data/settleResponseSuccess.xml
deleted file mode 100644
index c2edf07..0000000
--- a/Datatrans.Checkout.Tests/data/settleResponseSuccess.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- 101
- USD
- 111111111111111
- COA
- 05
-
-
- 01
- settlement succeeded
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/statusResponseError.xml b/Datatrans.Checkout.Tests/data/statusResponseError.xml
deleted file mode 100644
index 979d44b..0000000
--- a/Datatrans.Checkout.Tests/data/statusResponseError.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- 111111111111111
- STX
-
-
-
- 2022
- invalid value
- merchantId
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/data/statusResponseSuccess.xml b/Datatrans.Checkout.Tests/data/statusResponseSuccess.xml
deleted file mode 100644
index 0001508..0000000
--- a/Datatrans.Checkout.Tests/data/statusResponseSuccess.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
- 111111111111111
- STX
-
-
- 2
- Trx debit waiting for daily settlement process
- 00400
- 24720
- USD
- 9213
- VIS
- 111111111111111
- 424242xxxxxx4242
-
- 12
- 18
- 20171212
- 222638
- 05
- 24720
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.Tests/packages.config b/Datatrans.Checkout.Tests/packages.config
deleted file mode 100644
index 319bbb5..0000000
--- a/Datatrans.Checkout.Tests/packages.config
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout.sln b/Datatrans.Checkout.sln
deleted file mode 100644
index 6f8f7a6..0000000
--- a/Datatrans.Checkout.sln
+++ /dev/null
@@ -1,34 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Datatrans.Checkout", "Datatrans.Checkout\Datatrans.Checkout.csproj", "{C602C6C1-F419-466F-904D-D73D06B50AF3}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Datatrans.Checkout.Core", "Datatrans.Checkout.Core\Datatrans.Checkout.Core.csproj", "{62A342C4-FEE9-474F-9433-43C81D9CEAC9}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Datatrans.Checkout.Tests", "Datatrans.Checkout.Tests\Datatrans.Checkout.Tests.csproj", "{9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C602C6C1-F419-466F-904D-D73D06B50AF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C602C6C1-F419-466F-904D-D73D06B50AF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C602C6C1-F419-466F-904D-D73D06B50AF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C602C6C1-F419-466F-904D-D73D06B50AF3}.Release|Any CPU.Build.0 = Release|Any CPU
- {62A342C4-FEE9-474F-9433-43C81D9CEAC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {62A342C4-FEE9-474F-9433-43C81D9CEAC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {62A342C4-FEE9-474F-9433-43C81D9CEAC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {62A342C4-FEE9-474F-9433-43C81D9CEAC9}.Release|Any CPU.Build.0 = Release|Any CPU
- {9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9D8B50C5-9DF1-461C-8BBD-FFE82FB1E400}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Datatrans.Checkout/Content/logo.png b/Datatrans.Checkout/Content/logo.png
deleted file mode 100644
index 78794dd..0000000
Binary files a/Datatrans.Checkout/Content/logo.png and /dev/null differ
diff --git a/Datatrans.Checkout/Content/paymentForm.liquid b/Datatrans.Checkout/Content/paymentForm.liquid
deleted file mode 100644
index c654217..0000000
--- a/Datatrans.Checkout/Content/paymentForm.liquid
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/Datatrans.Checkout/Datatrans.Checkout.csproj b/Datatrans.Checkout/Datatrans.Checkout.csproj
deleted file mode 100644
index 4caafea..0000000
--- a/Datatrans.Checkout/Datatrans.Checkout.csproj
+++ /dev/null
@@ -1,191 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
-
-
- 2.0
- {C602C6C1-F419-466F-904D-D73D06B50AF3}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
- Datatrans.Checkout
- Datatrans.Checkout
- v4.6.1
- true
-
-
-
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
- true
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
- true
-
-
-
- ..\packages\DotLiquid.1.8.0\lib\NET45\DotLiquid.dll
- True
-
-
-
- ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll
- True
-
-
- ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.dll
- True
-
-
- ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.Configuration.dll
- True
-
-
- ..\packages\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll
- True
-
-
- ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
- True
-
-
- ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
-
-
-
- ..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll
-
-
-
-
-
-
-
-
-
-
- ..\packages\Microsoft.AspNet.WebApi.Core.5.2.4\lib\net45\System.Web.Http.dll
-
-
-
-
-
-
-
- ..\packages\VirtoCommerce.Domain.2.24.19\lib\net461\VirtoCommerce.Domain.dll
- True
-
-
- ..\packages\VirtoCommerce.Platform.Core.2.13.24\lib\net461\VirtoCommerce.Platform.Core.dll
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
- Properties\CommonAssemblyInfo.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {62a342c4-fee9-474f-9433-43c81d9ceac9}
- Datatrans.Checkout.Core
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
-
-
-
-
-
- True
- True
- 26902
- /
- http://localhost:26902/
- False
- False
-
-
- False
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Converters/RefundConverter.cs b/Datatrans.Checkout/DatatransClient/Converters/RefundConverter.cs
deleted file mode 100644
index 03e9de4..0000000
--- a/Datatrans.Checkout/DatatransClient/Converters/RefundConverter.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-using Datatrans.Checkout.DatatransClient.Models;
-using System.Linq;
-using System.Xml.Linq;
-
-namespace Datatrans.Checkout.DatatransClient.Converters
-{
- public static class RefundConverter
- {
- public static string ToDatatransRequest(this DatatransRefundRequest request)
- {
- var requestXml =
- new XElement("paymentService", new XAttribute("version", request.ServiceVersion),
- new XElement("body", new XAttribute("merchantId", request.MerchantId),
- new XElement("transaction", new XAttribute("refno", request.ReferenceNumber),
- new XElement("request",
- new XElement("amount", request.Amount),
- new XElement("currency", request.Currency),
- new XElement("uppTransactionId", request.TransactionId),
- new XElement("transtype", request.TransType),
- new XElement("sign", request.Sign)
- )
- )
- )
- );
-
- return requestXml.ToString();
- }
-
- public static DatatransRefundResponse ToCoreModel(this RefundResponse.paymentService response)
- {
- var coreModel = new DatatransRefundResponse();
-
- var refundResponseBody = response.body.FirstOrDefault();
- if (refundResponseBody == null)
- {
- return coreModel;
- }
-
- var transaction = refundResponseBody.transaction?.FirstOrDefault();
- var actualResponse = transaction?.response?.FirstOrDefault();
- var transactionError = transaction?.error?.FirstOrDefault();
- var generalError = refundResponseBody.error?.FirstOrDefault();
-
- if (transactionError != null)
- {
- coreModel.ErrorMessage = transactionError.errorMessage;
- coreModel.ErrorCode = transactionError.errorCode;
- coreModel.ErrorDetail = transactionError.errorDetail;
- }
-
- if (generalError != null)
- {
- coreModel.ErrorMessage = generalError.errorMessage;
- coreModel.ErrorCode = generalError.errorCode;
- coreModel.ErrorDetail = generalError.errorDetail;
- }
-
- if (actualResponse != null)
- {
- coreModel.ResponseCode = actualResponse.responseCode;
- coreModel.ResponseMessage = actualResponse.responseMessage;
- coreModel.TransactionId = actualResponse.uppTransactionId;
- }
-
- return coreModel;
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceRequestConverter.cs b/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceRequestConverter.cs
deleted file mode 100644
index 8972512..0000000
--- a/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceRequestConverter.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System.Linq;
-using System.Xml.Linq;
-using coreModel = Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.DatatransClient.Converters
-{
- public static class SettlementServiceRequestConverter
- {
- public static string ToDatatransRequest(this coreModel.DatatransSettlementRequest coreModel)
- {
- var requestXml =
- new XElement("paymentService", new XAttribute("version", coreModel.ServiceVersion),
- new XElement("body", new XAttribute("merchantId", coreModel.MerchantId),
- new XElement("transaction", new XAttribute("refno", coreModel.ReferenceNumber),
- new XElement("request",
- new XElement("amount", coreModel.Amount),
- new XElement("currency", coreModel.Currency),
- new XElement("uppTransactionId", coreModel.TransactionId),
- new XElement("sign", coreModel.Sign)
- )
- )
- )
- );
-
- if (coreModel.AirlineData != null)
- {
- var ticketIndex = 1;
- foreach (var datatransTicket in coreModel.AirlineData.Tickets)
- {
- var flighIndex = 1;
- datatransTicket.Index = (ticketIndex++).ToString();
- foreach (var datatransFlight in datatransTicket.Flights)
- {
- datatransFlight.Index = (flighIndex++).ToString();
- }
- }
-
- var airlineDataXml = new XElement("AIRLINEDATA",
- new XElement("CountryCode", coreModel.AirlineData.CountryCode),
- new XElement("AgentCode", coreModel.AirlineData.AgentCode),
- new XElement("PNR", coreModel.AirlineData.PNR),
- new XElement("IssueDate", coreModel.AirlineData.IssueDate),
-
- from ticket in coreModel.AirlineData.Tickets
- select new XElement("Ticket", new XAttribute("nr", ticket.Index),
- new XElement("TicketNumber", ticket.TicketNumber),
- new XElement("PassengerName", ticket.PassengerName),
- new XElement("DescrCode", ticket.DescrCode),
-
- from flight in ticket.Flights
- select new XElement("Flight", new XAttribute("nr", flight.Index),
- new XElement("Origin", flight.Origin),
- new XElement("Destination", flight.Destination),
- new XElement("Carrier", flight.Carrier),
- new XElement("Class", flight.Class),
- new XElement("FareBasis", flight.FareBasis),
- new XElement("FlightNumber", flight.FlightNumber),
- new XElement("FlightDate", flight.FlightDate)))
- );
-
- var requestElement = requestXml.Descendants().FirstOrDefault(x => x.Name == "request");
- requestElement?.Add(airlineDataXml);
- }
-
- return requestXml.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceResponseConverter.cs b/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceResponseConverter.cs
deleted file mode 100644
index b1ae62a..0000000
--- a/Datatrans.Checkout/DatatransClient/Converters/SettlementServiceResponseConverter.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Linq;
-using Datatrans.Checkout.DatatransClient.Models;
-using VirtoCommerce.Platform.Core.Common;
-using coreModel = Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.DatatransClient.Converters
-{
- public static class SettlementServiceResponseConverter
- {
- public static coreModel.DatatransSettlementResponse ToCoreModel(this paymentService dataModel)
- {
- var coreModel = new coreModel.DatatransSettlementResponse();
-
- var statusServiceBody = dataModel.body.FirstOrDefault();
- if (statusServiceBody == null) return coreModel;
-
- var transaction = statusServiceBody.transaction.FirstOrDefault();
- if (transaction == null) return coreModel;
-
- if (!transaction.response.IsNullOrEmpty())
- {
- var response = transaction.response.FirstOrDefault();
- coreModel.ResponseCode = response.responseCode;
- coreModel.ResponseMessage = response.responseMessage;
- }
-
- if (!transaction.error.IsNullOrEmpty())
- {
- var error = transaction.error.FirstOrDefault();
- coreModel.ErrorCode = error.errorCode;
- coreModel.ErrorDetail = error.errorDetail;
- coreModel.ErrorMessage = error.errorMessage;
- }
-
- return coreModel;
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Converters/StatusServiceRequestConverter.cs b/Datatrans.Checkout/DatatransClient/Converters/StatusServiceRequestConverter.cs
deleted file mode 100644
index 41dacce..0000000
--- a/Datatrans.Checkout/DatatransClient/Converters/StatusServiceRequestConverter.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Xml.Linq;
-using coreModel = Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.DatatransClient.Converters
-{
- public static class StatusServiceRequestConverter
- {
- public static string ToDatatransRequest(this coreModel.DatatransTransactionRequest coreModel)
- {
- XElement requestXml =
- new XElement("statusService", new XAttribute("version", coreModel.ServiceVersion),
- new XElement("body", new XAttribute("merchantId", coreModel.MerchantId),
- new XElement("transaction",
- new XElement("request",
- new XElement("uppTransactionId", coreModel.TransactionId),
- new XElement("reqtype", coreModel.ReqestType)
- )
- )
- )
- );
-
- return requestXml.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Converters/StatusServiceResponseConverter.cs b/Datatrans.Checkout/DatatransClient/Converters/StatusServiceResponseConverter.cs
deleted file mode 100644
index 46c6c20..0000000
--- a/Datatrans.Checkout/DatatransClient/Converters/StatusServiceResponseConverter.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Linq;
-using Datatrans.Checkout.DatatransClient.Models;
-using VirtoCommerce.Platform.Core.Common;
-using coreModel = Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.DatatransClient.Converters
-{
- public static class StatusServiceResponseConverter
- {
- public static coreModel.DatatransTransactionResponse ToCoreModel(this statusService dataModel)
- {
- var coreModel = new coreModel.DatatransTransactionResponse();
-
- var statusServiceBody = dataModel.body.FirstOrDefault();
- if (statusServiceBody == null) return coreModel;
-
- if (!statusServiceBody.transaction.IsNullOrEmpty())
- {
- var transaction = statusServiceBody.transaction.FirstOrDefault();
- if (transaction?.response != null)
- {
- var actualResponse = transaction.response.FirstOrDefault();
- coreModel.ResponseCode = actualResponse.responseCode;
- coreModel.ResponseMessage = actualResponse.responseMessage;
- coreModel.ReferenceNumber = actualResponse.refno;
- coreModel.Amount = actualResponse.amount;
- coreModel.Currency = actualResponse.currency;
- coreModel.AuthorizationCode = actualResponse.authorizationCode;
- coreModel.PaymentMethod = actualResponse.pmethod;
- coreModel.TransactionId = actualResponse.uppTransactionId;
- coreModel.MaskedCC = actualResponse.maskedCC;
- coreModel.AliasCC = actualResponse.aliasCC;
- coreModel.ExpirationMonth = actualResponse.expm;
- coreModel.ExpirationYear = actualResponse.expy;
- coreModel.TransactionDate = actualResponse.trxDate;
- coreModel.TransactionTime = actualResponse.trxTime;
- coreModel.TransactionType = actualResponse.trtype;
- coreModel.SettledAmount = actualResponse.settledAmount;
- coreModel.ItemNumber = actualResponse.itemNr;
- }
- }
-
- if (!statusServiceBody.error.IsNullOrEmpty())
- {
- var error = statusServiceBody.error.FirstOrDefault();
- coreModel.ErrorCode = error.errorCode;
- coreModel.ErrorDetail = error.errorDetail;
- coreModel.ErrorMessage = error.errorMessage;
- }
-
- return coreModel;
- }
- }
-}
diff --git a/Datatrans.Checkout/DatatransClient/DatatransClient.cs b/Datatrans.Checkout/DatatransClient/DatatransClient.cs
deleted file mode 100644
index cbe30af..0000000
--- a/Datatrans.Checkout/DatatransClient/DatatransClient.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-using Datatrans.Checkout.Core.Services;
-using Datatrans.Checkout.DatatransClient.Converters;
-using Datatrans.Checkout.DatatransClient.Models;
-using System;
-using System.IO;
-using System.Net;
-using System.Text;
-using System.Xml;
-using VirtoCommerce.Platform.Core.Common;
-using coreModel = Datatrans.Checkout.Core.Model;
-
-namespace Datatrans.Checkout.DatatransClient
-{
- public class DatatransClient : IDatatransClient
- {
- public string ServiceEndpoint { get; set; }
-
- protected string AuthorizationEndpoint => ServiceEndpoint + "/upp/jsp/XML_authorize.jsp";
-
- protected string StatusEndpoint => ServiceEndpoint + "/upp/jsp/XML_status.jsp";
-
- protected string ProcessEndpoint => ServiceEndpoint + "/upp/jsp/XML_processor.jsp";
-
- private readonly string _username;
- private readonly string _password;
-
- #region Implementation of IDatatransClient
-
- public DatatransClient(string serviceEndpoint, string username, string password)
- {
- ServiceEndpoint = serviceEndpoint;
- _username = username;
- _password = password;
- }
-
- public coreModel.DatatransSettlementResponse SettleTransaction(DatatransSettlementRequest request)
- {
- var requestXml = request.ToDatatransRequest();
- var response = MakeDatatransCall(ProcessEndpoint, requestXml);
-
- if (!response.ErrorMessage.IsNullOrEmpty())
- {
- return new coreModel.DatatransSettlementResponse
- {
- ErrorMessage = response.ErrorMessage
- };
- }
-
- var paymentServiceResponse = response.ResponseContent.DeserializeXml();
- var result = paymentServiceResponse.ToCoreModel();
- result.ResponseContent = response.ResponseContent;
- return result;
- }
-
- public coreModel.DatatransTransactionResponse GetTransactionStatus(DatatransTransactionRequest request)
- {
- var requestXml = request.ToDatatransRequest();
- var response = MakeDatatransCall(StatusEndpoint, requestXml);
-
- if (!response.ErrorMessage.IsNullOrEmpty())
- {
- return new coreModel.DatatransTransactionResponse
- {
- ErrorMessage = response.ErrorMessage
- };
- }
-
- var statusServiceResponse = response.ResponseContent.DeserializeXml();
- var result = statusServiceResponse.ToCoreModel();
- result.ResponseContent = response.ResponseContent;
- return result;
- }
-
- public coreModel.DatatransRefundResponse Refund(DatatransRefundRequest request)
- {
- var requestXml = request.ToDatatransRequest();
- var response = MakeDatatransCall(ProcessEndpoint, requestXml);
-
- if (!response.ErrorMessage.IsNullOrEmpty())
- {
- return new DatatransRefundResponse
- {
- ErrorMessage = response.ErrorMessage
- };
- }
-
- var datatransRefundResponse = response.ResponseContent.DeserializeXml();
-
- var result = datatransRefundResponse.ToCoreModel();
-
- result.ResponseData = response.ResponseContent;
-
- return result;
- }
-
- private ServiceResponse MakeDatatransCall(string endpoint, string sXml)
- {
- var result = new ServiceResponse();
- var endpointUri = new Uri(endpoint);
- try
- {
- var req = (HttpWebRequest) WebRequest.Create(endpointUri);
- req.Method = "POST";
- req.ContentType = "text/xml; charset=utf-8";
-
- var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_username}:{_password}"));
-
- req.Headers.Add("Authorization", $"Basic {credentials}");
-
- req.ContentLength = sXml.Length;
- using (var sw = new StreamWriter(req.GetRequestStream()))
- {
- sw.Write(sXml);
- sw.Close();
- }
-
- var res = (HttpWebResponse)req.GetResponse();
-
- var responseStream = res.GetResponseStream();
- using (var streamReader = new StreamReader(responseStream))
- {
- var xml = new XmlDocument();
- xml.LoadXml(streamReader.ReadToEnd());
- result.ResponseContent = xml.InnerXml;
- }
- }
- catch (Exception ex)
- {
- result.ErrorMessage = ex.Message;
- }
- return result;
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Models/RefundResponse.cs b/Datatrans.Checkout/DatatransClient/Models/RefundResponse.cs
deleted file mode 100644
index 0286460..0000000
--- a/Datatrans.Checkout/DatatransClient/Models/RefundResponse.cs
+++ /dev/null
@@ -1,477 +0,0 @@
-namespace Datatrans.Checkout.DatatransClient.Models
-{
- public class RefundResponse
- {
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
- public partial class paymentService
- {
-
- private paymentServiceBody[] bodyField;
-
- private string versionField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("body", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBody[] body
- {
- get
- {
- return this.bodyField;
- }
- set
- {
- this.bodyField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string version
- {
- get
- {
- return this.versionField;
- }
- set
- {
- this.versionField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBody
- {
-
- private paymentServiceBodyTransaction[] transactionField;
-
- private paymentServiceBodyTransactionError[] errorField;
-
- private string merchantIdField;
-
- private string statusField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("transaction", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransaction[] transaction
- {
- get
- {
- return this.transactionField;
- }
- set
- {
- this.transactionField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("error", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionError[] error
- {
- get
- {
- return this.errorField;
- }
- set
- {
- this.errorField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string merchantId
- {
- get
- {
- return this.merchantIdField;
- }
- set
- {
- this.merchantIdField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string status
- {
- get
- {
- return this.statusField;
- }
- set
- {
- this.statusField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransaction
- {
-
- private paymentServiceBodyTransactionRequest[] requestField;
-
- private paymentServiceBodyTransactionResponse[] responseField;
-
- private paymentServiceBodyTransactionError[] errorField;
-
- private string refnoField;
-
- private string trxStatusField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("request", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionRequest[] request
- {
- get
- {
- return this.requestField;
- }
- set
- {
- this.requestField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("response", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionResponse[] response
- {
- get
- {
- return this.responseField;
- }
- set
- {
- this.responseField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("error", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionError[] error
- {
- get
- {
- return this.errorField;
- }
- set
- {
- this.errorField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string refno
- {
- get
- {
- return this.refnoField;
- }
- set
- {
- this.refnoField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string trxStatus
- {
- get
- {
- return this.trxStatusField;
- }
- set
- {
- this.trxStatusField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionRequest
- {
-
- private string amountField;
-
- private string currencyField;
-
- private string uppTransactionIdField;
-
- private string transtypeField;
-
- private string reqtypeField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string amount
- {
- get
- {
- return this.amountField;
- }
- set
- {
- this.amountField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string currency
- {
- get
- {
- return this.currencyField;
- }
- set
- {
- this.currencyField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string uppTransactionId
- {
- get
- {
- return this.uppTransactionIdField;
- }
- set
- {
- this.uppTransactionIdField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string transtype
- {
- get
- {
- return this.transtypeField;
- }
- set
- {
- this.transtypeField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string reqtype
- {
- get
- {
- return this.reqtypeField;
- }
- set
- {
- this.reqtypeField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionResponse
- {
-
- private string responseCodeField;
-
- private string responseMessageField;
-
- private string uppTransactionIdField;
-
- private string authorizationCodeField;
-
- private string acqAuthorizationCodeField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseCode
- {
- get
- {
- return this.responseCodeField;
- }
- set
- {
- this.responseCodeField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseMessage
- {
- get
- {
- return this.responseMessageField;
- }
- set
- {
- this.responseMessageField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string uppTransactionId
- {
- get
- {
- return this.uppTransactionIdField;
- }
- set
- {
- this.uppTransactionIdField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string authorizationCode
- {
- get
- {
- return this.authorizationCodeField;
- }
- set
- {
- this.authorizationCodeField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string acqAuthorizationCode
- {
- get
- {
- return this.acqAuthorizationCodeField;
- }
- set
- {
- this.acqAuthorizationCodeField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionError
- {
-
- private string errorCodeField;
-
- private string errorMessageField;
-
- private string errorDetailField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorCode
- {
- get
- {
- return this.errorCodeField;
- }
- set
- {
- this.errorCodeField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorMessage
- {
- get
- {
- return this.errorMessageField;
- }
- set
- {
- this.errorMessageField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorDetail
- {
- get
- {
- return this.errorDetailField;
- }
- set
- {
- this.errorDetailField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
- public partial class NewDataSet
- {
-
- private paymentService[] itemsField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("paymentService")]
- public paymentService[] Items
- {
- get
- {
- return this.itemsField;
- }
- set
- {
- this.itemsField = value;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Models/ServiceResponse.cs b/Datatrans.Checkout/DatatransClient/Models/ServiceResponse.cs
deleted file mode 100644
index ca4378f..0000000
--- a/Datatrans.Checkout/DatatransClient/Models/ServiceResponse.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Datatrans.Checkout.DatatransClient.Models
-{
- public class ServiceResponse
- {
- public string ResponseContent { get; set; }
-
- public string ErrorMessage { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Models/SettlementServiceReference.cs b/Datatrans.Checkout/DatatransClient/Models/SettlementServiceReference.cs
deleted file mode 100644
index b12b811..0000000
--- a/Datatrans.Checkout/DatatransClient/Models/SettlementServiceReference.cs
+++ /dev/null
@@ -1,303 +0,0 @@
-
-namespace Datatrans.Checkout.DatatransClient.Models
-{
- //------------------------------------------------------------------------------
- //
- // This code was generated by a tool.
- // Runtime Version:2.0.50727.8825
- //
- // Changes to this file may cause incorrect behavior and will be lost if
- // the code is regenerated.
- //
- //------------------------------------------------------------------------------
-
- using System.Xml.Serialization;
-
-//
-// This source code was auto-generated by xsd, Version=2.0.50727.3038.
-//
-
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
- public partial class paymentService
- {
-
- private paymentServiceBody[] bodyField;
-
- private string versionField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("body", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBody[] body
- {
- get { return this.bodyField; }
- set { this.bodyField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string version
- {
- get { return this.versionField; }
- set { this.versionField = value; }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBody
- {
-
- private paymentServiceBodyTransaction[] transactionField;
-
- private string merchantIdField;
-
- private string statusField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("transaction", Form =
- System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransaction[] transaction
- {
- get { return this.transactionField; }
- set { this.transactionField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string merchantId
- {
- get { return this.merchantIdField; }
- set { this.merchantIdField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string status
- {
- get { return this.statusField; }
- set { this.statusField = value; }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransaction
- {
-
- private paymentServiceBodyTransactionRequest[] requestField;
-
- private paymentServiceBodyTransactionResponse[] responseField;
-
- private paymentServiceBodyTransactionError[] errorField;
-
- private string refnoField;
-
- private string trxStatusField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("request", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionRequest[] request
- {
- get { return this.requestField; }
- set { this.requestField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("response", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionResponse[] response
- {
- get { return this.responseField; }
- set { this.responseField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string refno
- {
- get { return this.refnoField; }
- set { this.refnoField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlAttributeAttribute()]
- public string trxStatus
- {
- get { return this.trxStatusField; }
- set { this.trxStatusField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("error", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public paymentServiceBodyTransactionError[] error
- {
- get { return this.errorField; }
- set { this.errorField = value; }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionRequest
- {
-
- private string amountField;
-
- private string currencyField;
-
- private string uppTransactionIdField;
-
- private string reqtypeField;
-
- private string transtypeField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string amount
- {
- get { return this.amountField; }
- set { this.amountField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string currency
- {
- get { return this.currencyField; }
- set { this.currencyField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string uppTransactionId
- {
- get { return this.uppTransactionIdField; }
- set { this.uppTransactionIdField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string reqtype
- {
- get { return this.reqtypeField; }
- set { this.reqtypeField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string transtype
- {
- get { return this.transtypeField; }
- set { this.transtypeField = value; }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionResponse
- {
-
- private string responseCodeField;
-
- private string responseMessageField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseCode
- {
- get { return this.responseCodeField; }
- set { this.responseCodeField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseMessage
- {
- get { return this.responseMessageField; }
- set { this.responseMessageField = value; }
- }
- }
-
- /////
- //[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- //[System.SerializableAttribute()]
- //[System.Diagnostics.DebuggerStepThroughAttribute()]
- //[System.ComponentModel.DesignerCategoryAttribute("code")]
- //[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- //[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
- //public partial class NewDataSet
- //{
-
- // private paymentService[] itemsField;
-
- // ///
- // [System.Xml.Serialization.XmlElementAttribute("paymentService")]
- // public paymentService[] Items
- // {
- // get { return this.itemsField; }
- // set { this.itemsField = value; }
- // }
- //}
-
-
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class paymentServiceBodyTransactionError
- {
-
- private string errorCodeField;
-
- private string errorMessageField;
-
- private string errorDetailField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorCode
- {
- get { return this.errorCodeField; }
- set { this.errorCodeField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorMessage
- {
- get { return this.errorMessageField; }
- set { this.errorMessageField = value; }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorDetail
- {
- get { return this.errorDetailField; }
- set { this.errorDetailField = value; }
- }
- }
-
-
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/DatatransClient/Models/StatusServiceReference.cs b/Datatrans.Checkout/DatatransClient/Models/StatusServiceReference.cs
deleted file mode 100644
index 8f894c7..0000000
--- a/Datatrans.Checkout/DatatransClient/Models/StatusServiceReference.cs
+++ /dev/null
@@ -1,606 +0,0 @@
-using System;
-using System.Xml.Serialization;
-
-namespace Datatrans.Checkout.DatatransClient.Models
-{
- //------------------------------------------------------------------------------
- //
- // This code was generated by a tool.
- // Runtime Version:2.0.50727.8825
- //
- // Changes to this file may cause incorrect behavior and will be lost if
- // the code is regenerated.
- //
- //------------------------------------------------------------------------------
- //
- // This source code was auto-generated by xsd, Version=2.0.50727.3038.
- //
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- [XmlRoot(Namespace = "", IsNullable = false)]
- public partial class statusService
- {
-
- private statusServiceBody[] bodyField;
-
- private string versionField;
-
- ///
- [XmlElement("body", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public statusServiceBody[] body
- {
- get
- {
- return this.bodyField;
- }
- set
- {
- this.bodyField = value;
- }
- }
-
- ///
- [XmlAttribute()]
- public string version
- {
- get
- {
- return this.versionField;
- }
- set
- {
- this.versionField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- public partial class statusServiceBody
- {
-
- private statusServiceBodyTransaction[] transactionField;
-
- private statusServiceBodyError[] errorField;
-
- private string merchantIdField;
-
- private string statusField;
-
- ///
- [XmlElement("transaction", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public statusServiceBodyTransaction[] transaction
- {
- get
- {
- return this.transactionField;
- }
- set
- {
- this.transactionField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute("error", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public statusServiceBodyError[] error
- {
- get
- {
- return this.errorField;
- }
- set
- {
- this.errorField = value;
- }
- }
-
- ///
- [XmlAttribute()]
- public string merchantId
- {
- get
- {
- return this.merchantIdField;
- }
- set
- {
- this.merchantIdField = value;
- }
- }
-
- ///
- [XmlAttribute()]
- public string status
- {
- get
- {
- return this.statusField;
- }
- set
- {
- this.statusField = value;
- }
- }
- }
-
-
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- public partial class statusServiceBodyTransaction
- {
-
- private statusServiceBodyTransactionRequest[] requestField;
-
- private statusServiceBodyTransactionResponse[] responseField;
-
- private string trxStatusField;
-
- ///
- [XmlElement("request", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public statusServiceBodyTransactionRequest[] request
- {
- get
- {
- return this.requestField;
- }
- set
- {
- this.requestField = value;
- }
- }
-
- ///
- [XmlElement("response", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public statusServiceBodyTransactionResponse[] response
- {
- get
- {
- return this.responseField;
- }
- set
- {
- this.responseField = value;
- }
- }
-
- ///
- [XmlAttribute()]
- public string trxStatus
- {
- get
- {
- return this.trxStatusField;
- }
- set
- {
- this.trxStatusField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- public partial class statusServiceBodyTransactionRequest
- {
-
- private string uppTransactionIdField;
-
- private string reqtypeField;
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string uppTransactionId
- {
- get
- {
- return this.uppTransactionIdField;
- }
- set
- {
- this.uppTransactionIdField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string reqtype
- {
- get
- {
- return this.reqtypeField;
- }
- set
- {
- this.reqtypeField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- public partial class statusServiceBodyTransactionResponse
- {
-
- private string responseCodeField;
-
- private string responseMessageField;
-
- private string refnoField;
-
- private string amountField;
-
- private string currencyField;
-
- private string authorizationCodeField;
-
- private string pmethodField;
-
- private string uppTransactionIdField;
-
- private string maskedCCField;
-
- private string aliasCCField;
-
- private string expmField;
-
- private string expyField;
-
- private string trxDateField;
-
- private string trxTimeField;
-
- private string trtypeField;
-
- private string settledAmountField;
-
- private string itemNrField;
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseCode
- {
- get
- {
- return this.responseCodeField;
- }
- set
- {
- this.responseCodeField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string responseMessage
- {
- get
- {
- return this.responseMessageField;
- }
- set
- {
- this.responseMessageField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string refno
- {
- get
- {
- return this.refnoField;
- }
- set
- {
- this.refnoField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string amount
- {
- get
- {
- return this.amountField;
- }
- set
- {
- this.amountField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string currency
- {
- get
- {
- return this.currencyField;
- }
- set
- {
- this.currencyField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string authorizationCode
- {
- get
- {
- return this.authorizationCodeField;
- }
- set
- {
- this.authorizationCodeField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string pmethod
- {
- get
- {
- return this.pmethodField;
- }
- set
- {
- this.pmethodField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string uppTransactionId
- {
- get
- {
- return this.uppTransactionIdField;
- }
- set
- {
- this.uppTransactionIdField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string maskedCC
- {
- get
- {
- return this.maskedCCField;
- }
- set
- {
- this.maskedCCField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string aliasCC
- {
- get
- {
- return this.aliasCCField;
- }
- set
- {
- this.aliasCCField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string expm
- {
- get
- {
- return this.expmField;
- }
- set
- {
- this.expmField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string expy
- {
- get
- {
- return this.expyField;
- }
- set
- {
- this.expyField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string trxDate
- {
- get
- {
- return this.trxDateField;
- }
- set
- {
- this.trxDateField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string trxTime
- {
- get
- {
- return this.trxTimeField;
- }
- set
- {
- this.trxTimeField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string trtype
- {
- get
- {
- return this.trtypeField;
- }
- set
- {
- this.trtypeField = value;
- }
- }
-
- ///
- [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string settledAmount
- {
- get
- {
- return this.settledAmountField;
- }
- set
- {
- this.settledAmountField = value;
- }
- }
-
- ///
- [XmlAttribute()]
- public string itemNr
- {
- get
- {
- return this.itemNrField;
- }
- set
- {
- this.itemNrField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [Serializable()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [XmlType(AnonymousType = true)]
- [XmlRoot(Namespace = "", IsNullable = false)]
- public partial class NewDataSet
- {
-
- private statusService[] itemsField;
-
- ///
- [XmlElement("statusService")]
- public statusService[] Items
- {
- get
- {
- return this.itemsField;
- }
- set
- {
- this.itemsField = value;
- }
- }
- }
-
- ///
- [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
- [System.SerializableAttribute()]
- [System.Diagnostics.DebuggerStepThroughAttribute()]
- [System.ComponentModel.DesignerCategoryAttribute("code")]
- [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
- public partial class statusServiceBodyError
- {
- private string errorCodeField;
-
- private string errorMessageField;
-
- private string errorDetailField;
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorCode
- {
- get
- {
- return this.errorCodeField;
- }
- set
- {
- this.errorCodeField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorMessage
- {
- get
- {
- return this.errorMessageField;
- }
- set
- {
- this.errorMessageField = value;
- }
- }
-
- ///
- [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
- public string errorDetail
- {
- get
- {
- return this.errorDetailField;
- }
- set
- {
- this.errorDetailField = value;
- }
- }
- }
-
-}
-
-
diff --git a/Datatrans.Checkout/Extensions/DecimalExtensions.cs b/Datatrans.Checkout/Extensions/DecimalExtensions.cs
deleted file mode 100644
index 553c47d..0000000
--- a/Datatrans.Checkout/Extensions/DecimalExtensions.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Datatrans.Checkout.Extensions
-{
- public static class DecimalExtensions
- {
- public static decimal NormalizeDecimal(this decimal source)
- {
- return Math.Abs(source);
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Helpers/RoundingHelper.cs b/Datatrans.Checkout/Helpers/RoundingHelper.cs
deleted file mode 100644
index 9eaf7a3..0000000
--- a/Datatrans.Checkout/Helpers/RoundingHelper.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace Datatrans.Checkout.Helpers
-{
- public static class RoundingHelper
- {
- public static int Round(this decimal value)
- {
- return (int)Math.Round(value, MidpointRounding.AwayFromZero);
- }
-
- public static int ToInt(this decimal value)
- {
- return (value * 100).Round();
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Managers/DatatransCheckoutPaymentMethod.cs b/Datatrans.Checkout/Managers/DatatransCheckoutPaymentMethod.cs
deleted file mode 100644
index 7332b6b..0000000
--- a/Datatrans.Checkout/Managers/DatatransCheckoutPaymentMethod.cs
+++ /dev/null
@@ -1,480 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-using Datatrans.Checkout.Core.Services;
-using Datatrans.Checkout.Extensions;
-using Datatrans.Checkout.Helpers;
-using Datatrans.Checkout.Services;
-using Newtonsoft.Json;
-using System;
-using System.Collections.Specialized;
-using VirtoCommerce.Domain.Order.Model;
-using VirtoCommerce.Domain.Payment.Model;
-using VirtoCommerce.Platform.Core.Common;
-
-namespace Datatrans.Checkout.Managers
-{
- public class DatatransCheckoutPaymentMethod : PaymentMethod
- {
- private const string _merchantIdSetting = "Datatrans.Checkout.MerchantId";
- private const string _HMACSetting = "Datatrans.Checkout.HMACHex";
- private const string _HMAC2Setting = "Datatrans.Checkout.HMACHEXSign2";
-
- private const string _datatransModeStoreSetting = "Datatrans.Checkout.Mode";
- private const string _paymentActionTypeSetting = "Datatrans.Checkout.PaymentActionType";
- private const string _paymentMethodSetting = "Datatrans.Checkout.PaymentMethod";
- private const string _formActionUrlSetting = "Datatrans.Checkout.FormAction";
- private const string _languageSetting = "Datatrans.Checkout.Language";
-
- private const string _transactionParamName = "uppTransactionId";
- private const string _paymentMethodCodeParamName = "paymentMethodCode";
-
- private const string _serverToServerUsername = "Datatrans.Checkout.ServerToServer.Username";
-#pragma warning disable S2068
- private const string _serverToServerPassword = "Datatrans.Checkout.ServerToServer.Password";
-#pragma warning restore S2068
- private const string _apiEndpoint = "Datatrans.Checkout.APIEndpoint";
- private const string _browserEnpoint = "Datatrans.Checkout.BrowserEndpoint";
- private const string _successfulStatus = "success";
- private const string _errorStatus = "error";
-
- #region Settings
-
- private string ApiMode => GetSetting(_datatransModeStoreSetting);
-
- private string MerchantId => GetSetting(_merchantIdSetting);
-
- private string HMACHex => GetSetting(_HMACSetting);
-
- private string HMACHex2
- {
- get
- {
- var setting = GetSetting(_HMAC2Setting);
-
- return string.IsNullOrEmpty(setting) ? null : setting;
- }
- }
-
- private string PaymentAction => GetSetting(_paymentActionTypeSetting);
-
- private string PaymentMethod => GetSetting(_paymentMethodSetting);
-
- private string FormActionUrl => GetSetting(_formActionUrlSetting);
-
- private string Language => GetSetting(_languageSetting);
-
- private string Username => GetSetting(_serverToServerUsername);
-
- private string Password => GetSetting(_serverToServerPassword);
-
- public bool IsSale => PaymentAction.EqualsInvariant("Sale");
-
- public bool IsTest => ApiMode.EqualsInvariant("test");
-
- public string ServerToServerApi => GetSetting(_apiEndpoint);
-
- public string FrontendApi => GetSetting(_browserEnpoint);
-
- #endregion
-
- public override PaymentMethodType PaymentMethodType => PaymentMethodType.PreparedForm;
-
- public override PaymentMethodGroupType PaymentMethodGroupType => PaymentMethodGroupType.Alternative;
-
- private readonly IDatatransCheckoutService _datatransCheckoutService;
- private readonly Func _datatransClientFactory;
- private readonly IDatatransCapturePaymentService _capturePaymentService;
- private readonly Func _signProviderFactory;
-
- public DatatransCheckoutPaymentMethod(
- IDatatransCheckoutService datatransCheckoutService,
- Func datatransClientFactory,
- IDatatransCapturePaymentService capturePaymentService,
- Func signProviderFactory)
- :base("DatatransCheckout")
- {
- _datatransCheckoutService = datatransCheckoutService;
- _datatransClientFactory = datatransClientFactory;
- _capturePaymentService = capturePaymentService;
- _signProviderFactory = signProviderFactory;
- }
-
- public override ProcessPaymentResult ProcessPayment(ProcessPaymentEvaluationContext context)
- {
- var result = new ProcessPaymentResult();
- if (context.Order != null && context.Store != null)
- {
- result = PrepareFormContent(context);
- }
- return result;
- }
-
- private ProcessPaymentResult PrepareFormContent(ProcessPaymentEvaluationContext context)
- {
- var formContent = _datatransCheckoutService.GetCheckoutFormContent(new DatatransCheckoutSettings
- {
- Order = context.Order,
- Store = context.Store,
- MerchantId = MerchantId,
- FormActionUrl = FormActionUrl,
- PaymentAction = PaymentAction,
- PaymentMethod = PaymentMethod,
- ReferenceNumber = context.Order.Number,
- Sign = GetSignProvider(HMACHex).Sign(MerchantId, context.Order.Sum.ToInt(), context.Order.Currency, context.Order.Number),
- Amount = context.Order.Sum.ToInt(),
- PurchaseCurrency = context.Order.Currency,
- FrontendApi = FrontendApi,
- Language = Language,
- InternalPaymentMethodCode = Code,
- PaymentMethodCodeParamName = _paymentMethodCodeParamName
- });
-
- var result = new ProcessPaymentResult
- {
- IsSuccess = true,
- NewPaymentStatus = context.Payment.PaymentStatus = PaymentStatus.Pending,
- HtmlForm = formContent,
- OuterId = null
- };
-
- return result;
- }
-
- public override PostProcessPaymentResult PostProcessPayment(PostProcessPaymentEvaluationContext context)
- {
- var result = new PostProcessPaymentResult();
-
- var status = GetParamValue(context.Parameters, "status"); //possible values: error, success
- var transactionId = GetParamValue(context.Parameters, _transactionParamName);
-
- bool.TryParse(GetSetting("Datatrans.Checkout.ErrorTesting"), out var errorTestingMode);
-
- if (errorTestingMode && IsTest)
- {
- status = _errorStatus;
-
- var errorCode = int.TryParse(GetSetting("Datatrans.Checkout.ErrorCode"), out var parsedErrorCode) ? parsedErrorCode : DatatransErrorCodes.DefaultErrorCode;
-
- context.Parameters["errorCode"] = errorCode.ToString();
- context.Parameters["errorMessage"] = "Error testing mode";
- }
-
- context.Payment.OuterId = context.OuterId;
- if (status.EqualsInvariant(_successfulStatus) && IsSale)
- {
- var captureResult = CaptureProcessPayment(new CaptureProcessPaymentEvaluationContext
- {
- Payment = context.Payment,
- Order = context.Order,
- Parameters = context.Parameters
- });
-
- if (captureResult.IsSuccess)
- {
- context.OuterId = transactionId;
- result.NewPaymentStatus = context.Payment.PaymentStatus = PaymentStatus.Paid;
- context.Payment.IsApproved = true;
- context.Payment.CapturedDate = DateTime.UtcNow;
- result.IsSuccess = true;
- }
- }
- else if (status.EqualsInvariant(_successfulStatus))
- {
- var transactionInfo = GetTransactionStatus(context.Payment.OuterId);
- context.Payment.Transactions.Add(new PaymentGatewayTransaction()
- {
- Note = "Transaction Info",
- ResponseData = transactionInfo.ResponseContent,
- Status = transactionInfo.ResponseMessage,
- ResponseCode = transactionInfo.ResponseCode,
- ProcessError = transactionInfo.ErrorMessage,
- CurrencyCode = context.Order.Currency,
- Amount = context.Order.Sum,
- IsProcessed = true,
- ProcessedDate = DateTime.UtcNow
- });
-
- result.NewPaymentStatus = context.Payment.PaymentStatus = PaymentStatus.Authorized;
- context.Payment.OuterId = result.OuterId = context.OuterId;
- context.Payment.AuthorizedDate = DateTime.UtcNow;
- result.IsSuccess = true;
- }
- else
- {
- var errorMessage = GetParamValue(context.Parameters, "errorMessage");
- var errorCode = int.TryParse(GetParamValue(context.Parameters, "errorCode"), out var parsedErrorCode) ? parsedErrorCode : DatatransErrorCodes.DefaultErrorCode;
- result.ErrorMessage = GetErrorMessage(errorCode, errorMessage);
- }
-
- result.OrderId = context.Order.Id;
- return result;
- }
-
- public override CaptureProcessPaymentResult CaptureProcessPayment(CaptureProcessPaymentEvaluationContext context)
- {
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- if (context.Payment == null)
- {
- throw new InvalidOperationException(nameof(context.Payment));
- }
-
- if (context.Order == null)
- {
- throw new InvalidOperationException(nameof(context.Order));
- }
-
- var getAirlineContext = new GetAirlineDataContext(context.Order, context.Payment, context.Parameters);
- var airlineData = _capturePaymentService.GetAirlineData(getAirlineContext);
-
- var request = new DatatransSettlementRequest
- {
- MerchantId = MerchantId,
- TransactionId = context.Payment.OuterId,
- ReferenceNumber = context.Order.Number,
- Amount = context.Payment.Sum.ToInt(),
- Currency = context.Order.Currency,
- AirlineData = airlineData,
- Sign = GetSignProvider(HMACHex).Sign(MerchantId, context.Payment.Sum.ToInt(), context.Order.Currency, context.Order.Number)
- };
-
- var paymentTransaction = new PaymentGatewayTransaction
- {
- Note = "Settle Transaction",
- CurrencyCode = context.Order.Currency,
- Amount = context.Payment.Sum
- };
- context.Payment.Transactions.Add(paymentTransaction);
-
- var result = new CaptureProcessPaymentResult();
- var datatransClient = CreateDatatransClient(ServerToServerApi);
- var settleResult = datatransClient.SettleTransaction(request);
- if (!settleResult.ErrorMessage.IsNullOrEmpty())
- {
- result.ErrorMessage = GetErrorMessage(settleResult.ResponseCode, settleResult.ResponseMessage);
- paymentTransaction.ResponseData = settleResult.ResponseContent;
- return result;
- }
-
- var transactionInfo = GetTransactionStatus(context.Payment.OuterId);
- paymentTransaction.Note = "Transaction Info after Settle Transaction";
- paymentTransaction.Status = transactionInfo.ResponseMessage;
- paymentTransaction.ResponseData = transactionInfo.ResponseContent;
- paymentTransaction.ResponseCode = transactionInfo.ResponseCode;
- paymentTransaction.ProcessError = transactionInfo.ErrorMessage;
- paymentTransaction.IsProcessed = true;
- paymentTransaction.ProcessedDate = DateTime.UtcNow;
-
- result.NewPaymentStatus = context.Payment.PaymentStatus = PaymentStatus.Paid;
- context.Payment.CapturedDate = DateTime.UtcNow;
- context.Payment.IsApproved = true;
- result.IsSuccess = true;
- result.OuterId = context.Payment.OuterId;
-
- return result;
- }
-
- protected virtual DatatransTransactionResponse GetTransactionStatus(string transactionId)
- {
- var datatransClient = CreateDatatransClient(ServerToServerApi);
- return datatransClient.GetTransactionStatus(new DatatransTransactionRequest()
- {
- MerchantId = MerchantId,
- TransactionId = transactionId
- });
- }
-
- public override RefundProcessPaymentResult RefundProcessPayment(RefundProcessPaymentEvaluationContext context)
- {
- if (context == null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- if (context.Payment == null)
- {
- throw new InvalidOperationException(nameof(context.Payment));
- }
-
- if (context.Order == null)
- {
- throw new InvalidOperationException(nameof(context.Order));
- }
-
- if (string.IsNullOrEmpty(context.Payment.OuterId))
- {
- throw new InvalidOperationException(nameof(context.Payment.OuterId));
- }
-
- if (string.IsNullOrEmpty(context.Order.Currency))
- {
- throw new InvalidOperationException(nameof(context.Order.Currency));
- }
-
- if (string.IsNullOrEmpty(context.Order.Number))
- {
- throw new InvalidOperationException(nameof(context.Payment.OuterId));
- }
-
- var result = new RefundProcessPaymentResult();
-
- var payment = context.Payment;
-
- var request = new DatatransRefundRequest
- {
- TransactionId = payment.OuterId,
- Amount = GetNormalizedAmountForRefund(context, payment),
- Currency = context.Order.Currency,
- MerchantId = MerchantId,
- ReferenceNumber = context.Order.Number,
- Sign = GetSignProvider(HMACHex).Sign(MerchantId, GetNormalizedAmountForRefund(context, payment), context.Order.Currency, context.Order.Number)
- };
-
- var datatransClient = CreateDatatransClient(ServerToServerApi);
-
- var response = datatransClient.Refund(request);
-
- var transaction = new PaymentGatewayTransaction();
-
- payment.Transactions.Add(transaction);
-
- transaction.ResponseData = response.ResponseData;
-
- if (!response.ErrorMessage.IsNullOrEmpty())
- {
- transaction.ProcessError = response.ErrorMessage;
-
- result.ErrorMessage = GetErrorMessage(response.ErrorCode, response.ErrorMessage);
- result.IsSuccess = false;
- return result;
- }
-
- transaction.Amount = GetAmountForRefund(context, payment);
- transaction.CurrencyCode = payment.Currency;
- transaction.IsProcessed = true;
- transaction.Note = "Datatrans refund";
- transaction.ResponseCode = response.ResponseCode;
- transaction.Status = response.ResponseMessage;
- transaction.ProcessedDate = DateTime.Now;
-
- result.NewPaymentStatus = IsPartialRefund(context.Parameters) ? PaymentStatus.PartiallyRefunded : PaymentStatus.Refunded;
- result.IsSuccess = true;
-
- return result;
- }
-
- private decimal GetAmountForRefund(RefundProcessPaymentEvaluationContext context, PaymentIn payment)
- {
- return IsPartialRefund(context.Parameters)
- ? GetPartialRefundAmount(context.Parameters)
- : payment.Sum;
- }
-
- private int GetNormalizedAmountForRefund(RefundProcessPaymentEvaluationContext context, PaymentIn payment)
- {
- return GetAmountForRefund(context, payment).NormalizeDecimal().ToInt();
- }
-
- private decimal GetPartialRefundAmount(NameValueCollection parameters)
- {
- if (!IsPartialRefund(parameters))
- {
- throw new ArgumentException("Parameters doesn't have a RefundAmount parameter");
- }
-
- return decimal.Parse(parameters["RefundAmount"]);
- }
-
- private bool IsPartialRefund(NameValueCollection parameters)
- {
- return parameters?["RefundAmount"] != null;
- }
-
- private IDatatransClient CreateDatatransClient(string endpoint)
- {
- return _datatransClientFactory(endpoint, Username, Password);
- }
-
- public override VoidProcessPaymentResult VoidProcessPayment(VoidProcessPaymentEvaluationContext context)
- {
- return new VoidProcessPaymentResult { IsSuccess = false, NewPaymentStatus = PaymentStatus.Voided };
- }
-
- ///
- /// Check for transaction Id and payment method code in returned params collection
- /// This method is repsonsible for selecting this particular payment method among all active store payment methods
- ///
- ///
- ///
- public override ValidatePostProcessRequestResult ValidatePostProcessRequest(NameValueCollection queryString)
- {
- var transactionId = GetParamValue(queryString, _transactionParamName);
- var paymentMethodName = GetParamValue(queryString, _paymentMethodCodeParamName);
- var sign2 = GetParamValue(queryString, "sign2");
- var sign = GetParamValue(queryString, "sign");
- var refNo = GetParamValue(queryString, "refNo");
- var merchantId = GetParamValue(queryString, "merchantId");
- var amount = GetParamValue(queryString, "amount");
- var currency = GetParamValue(queryString, "currency");
- var status = GetParamValue(queryString, "status");
-
- bool validSignature;
-
- // Sign2 returns only for successful payments
- // So we need to check status additionally
- if (!string.IsNullOrEmpty(sign2) && !string.IsNullOrEmpty(HMACHex) && status.EqualsInvariant(_successfulStatus))
- {
- validSignature = GetSignProvider(HMACHex2 ?? HMACHex).ValidateSignature(sign2, merchantId, int.Parse(amount), currency, transactionId);
- }
- // Even if sign2 not received, it doesn't means that payment is scam
- // It still could be a valid payment, with status "error" if it contains "sign" parameter
- // We don't need additioonal check for a status, cause we know that sign2 passing with only successful payments
- // https://docs.datatrans.ch/docs/security-sign
- else if (!string.IsNullOrEmpty(sign) && !string.IsNullOrEmpty(HMACHex))
- {
- validSignature = GetSignProvider(HMACHex).ValidateSignature(sign, merchantId, int.Parse(amount), currency, refNo);
- }
- // Sign parameter is required if HMACHex setting is not null
- // And payment can't be valid without "sign"
- else if (string.IsNullOrEmpty(sign) && !string.IsNullOrEmpty(HMACHex))
- {
- validSignature = false;
- }
- // Case when sign and sign2 parameters is missing, and if HMACHex and HMACHex2 settings is not filled
- // We do not need to do anything with validation
- else
- {
- validSignature = true;
- }
-
- return new ValidatePostProcessRequestResult
- {
- IsSuccess = validSignature && !string.IsNullOrEmpty(transactionId) && paymentMethodName.EqualsInvariant(Code),
- OuterId = transactionId
- };
- }
-
-
- private string GetParamValue(NameValueCollection queryString, string paramName)
- {
- if (queryString == null || !queryString.HasKeys())
- {
- return null;
- }
-
- return queryString.Get(paramName);
- }
-
- private ISignProvider GetSignProvider(string hmacKey)
- {
- return _signProviderFactory(hmacKey);
- }
-
- private string GetErrorMessage(object code, string errorMessage)
- {
- return JsonConvert.SerializeObject(new {Code = code, Message = errorMessage});
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Module.cs b/Datatrans.Checkout/Module.cs
deleted file mode 100644
index 86e4d75..0000000
--- a/Datatrans.Checkout/Module.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using Datatrans.Checkout.Core.Services;
-using Datatrans.Checkout.Managers;
-using Datatrans.Checkout.Services;
-using Microsoft.Practices.ServiceLocation;
-using Microsoft.Practices.Unity;
-using System;
-using VirtoCommerce.Domain.Payment.Services;
-using VirtoCommerce.Platform.Core.Modularity;
-using VirtoCommerce.Platform.Core.Settings;
-
-namespace Datatrans.Checkout
-{
- public class Module : ModuleBase
- {
- private readonly IUnityContainer _container;
-
- public Module(IUnityContainer container)
- {
- _container = container;
- }
-
- public override void Initialize()
- {
- _container.RegisterType();
- _container.RegisterType();
-
- IDatatransClient DatatransClientFactory(string endpoint, string username, string password) => new DatatransClient.DatatransClient(endpoint, username, password);
- _container.RegisterInstance((Func) DatatransClientFactory);
-
- ISignProvider SignProviderFactory(string hmacKey) => new SignProvider(hmacKey);
- _container.RegisterInstance((Func) SignProviderFactory);
-
- var settingsManager = ServiceLocator.Current.GetInstance();
-
- Func datatransPaymentMethod = () =>
- {
- var paymentMethod = new DatatransCheckoutPaymentMethod(
- _container.Resolve(),
- _container.Resolve>(),
- _container.Resolve(),
- _container.Resolve>());
- paymentMethod.Name = "Datatrans Checkout Gateway";
- paymentMethod.Description = "Datatrans Checkout payment gateway integration";
- paymentMethod.LogoUrl = "https://raw.githubusercontent.com/VirtoCommerce/vc-module-datatrans/master/Datatrans.Checkout/Content/logo.png";
- paymentMethod.Settings = settingsManager.GetModuleSettings("Datatrans.Checkout");
- return paymentMethod;
- };
-
- var paymentMethodsService = _container.Resolve();
- paymentMethodsService.RegisterPaymentMethod(datatransPaymentMethod);
- }
- }
-}
diff --git a/Datatrans.Checkout/Properties/AssemblyInfo.cs b/Datatrans.Checkout/Properties/AssemblyInfo.cs
deleted file mode 100644
index 66392c1..0000000
--- a/Datatrans.Checkout/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-using System.Reflection;
-
-[assembly: AssemblyTitle("Datatrans.Checkout")]
-[assembly: AssemblyDescription("")]
diff --git a/Datatrans.Checkout/Services/DatatransCapturePaymentServiceEmptyImp.cs b/Datatrans.Checkout/Services/DatatransCapturePaymentServiceEmptyImp.cs
deleted file mode 100644
index d012e64..0000000
--- a/Datatrans.Checkout/Services/DatatransCapturePaymentServiceEmptyImp.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Datatrans.Checkout.Core.Model;
-using Datatrans.Checkout.Core.Services;
-
-namespace Datatrans.Checkout.Services
-{
- ///
- /// Mock implementation, should be overridden in custom implementations
- ///
- public class DatatransCapturePaymentServiceEmptyImp : IDatatransCapturePaymentService
- {
- #region Implementation of IDatatransCapturePaymentService
-
- public DatatransAirlineData GetAirlineData(GetAirlineDataContext context)
- {
- return null;
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Services/DatatransCheckoutService.cs b/Datatrans.Checkout/Services/DatatransCheckoutService.cs
deleted file mode 100644
index c432099..0000000
--- a/Datatrans.Checkout/Services/DatatransCheckoutService.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using System.IO;
-using System.Reflection;
-using Datatrans.Checkout.Core.Model;
-using Datatrans.Checkout.Core.Services;
-using DotLiquid;
-using VirtoCommerce.Domain.Store.Model;
-
-namespace Datatrans.Checkout.Services
-{
- public class DatatransCheckoutService : IDatatransCheckoutService
- {
- ///
- /// NOA = authorization only
- /// CAA = authorization with immediate settlement in case of successful authorization
- ///
- public const string DefaultPaymentActionCode = "NOA";
-
- ///
- /// Returns Datatrans Checkout Card Payment Form built with Datatrans Lighbox
- ///
- public string GetCheckoutFormContent(DatatransCheckoutSettings context)
- {
- var assembly = Assembly.GetExecutingAssembly();
- Stream stream = assembly.GetManifestResourceStream("Datatrans.Checkout.Content.paymentForm.liquid");
- if (stream == null)
- {
- return string.Empty;
- }
-
- StreamReader sr = new StreamReader(stream);
- var formContent = sr.ReadToEnd();
-
- Template template = Template.Parse(formContent);
- var content = template.Render(Hash.FromAnonymousObject(new
- {
- storeUrl = GetStoreUrl(context.Store),
- orderId = context.Order.Number,
- amount = context.Amount,
- merchantId = context.MerchantId,
- referenceNumber = context.ReferenceNumber,
- sign = context.Sign,
- paymentAction = DefaultPaymentActionCode,
- paymentMethod = context.PaymentMethod,
- purchaseCurrency = context.PurchaseCurrency,
- language = context.Language,
- formActionUrl = context.FormActionUrl,
- frontendApi = context.FrontendApi,
- paymentMethodCode = context.InternalPaymentMethodCode,
- paymentMethodCodeParamName = context.PaymentMethodCodeParamName
- }));
-
- return content;
- }
-
- private string GetStoreUrl(Store store)
- {
- if (!string.IsNullOrEmpty(store.SecureUrl))
- {
- return store.SecureUrl;
- }
-
- if (!string.IsNullOrEmpty(store.Url))
- {
- return store.Url;
- }
-
- return "";
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Services/ISignProvider.cs b/Datatrans.Checkout/Services/ISignProvider.cs
deleted file mode 100644
index 6edb66e..0000000
--- a/Datatrans.Checkout/Services/ISignProvider.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Datatrans.Checkout.Services
-{
- public interface ISignProvider
- {
- string Sign(string merchantId, int amount, string currency, string refno, string aliasCC = null);
-
- bool ValidateSignature(string signature, string merchantId, int amount, string currency, string transactionId);
- }
-}
diff --git a/Datatrans.Checkout/Services/SignProvider.cs b/Datatrans.Checkout/Services/SignProvider.cs
deleted file mode 100644
index c4edf84..0000000
--- a/Datatrans.Checkout/Services/SignProvider.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Security.Cryptography;
-using System.Text;
-
-[assembly: InternalsVisibleTo("Datatrans.Checkout.Tests")]
-namespace Datatrans.Checkout.Services
-{
- internal class SignProvider : ISignProvider
- {
- private readonly string _hmacHex;
-
- private byte[] Hmac => _hmac ?? (_hmac = HexDecode(_hmacHex));
- private byte[] _hmac;
-
- public SignProvider(string hmacKey)
- {
- if (string.IsNullOrEmpty(hmacKey))
- {
- throw new ArgumentNullException(nameof(hmacKey));
- }
-
- _hmacHex = hmacKey;
- }
-
- public string Sign(string merchantId, int amount, string currency, string refno, string aliasCC = null)
- {
- if (merchantId == null)
- {
- throw new ArgumentNullException(nameof(merchantId));
- }
-
- if (currency == null)
- {
- throw new ArgumentNullException(nameof(currency));
- }
-
- if (refno == null)
- {
- throw new ArgumentNullException(nameof(refno));
- }
-
- var targetData = string.Join(string.Empty, aliasCC, merchantId, amount.ToString(), currency, refno);
-
- return GenerateSignature(targetData);
- }
-
- public bool ValidateSignature(string signature, string merchantId, int amount, string currency, string transactionId)
- {
- var targetData = string.Join(string.Empty, merchantId, amount.ToString(), currency, transactionId);
-
- var expectedSignature = GenerateSignature(targetData);
-
- return expectedSignature == signature;
- }
-
- private string GenerateSignature(string source)
- {
- var toSign = Encoding.ASCII.GetBytes(source);
-
- using (var hmac = new HMACSHA256(Hmac))
- {
- var hash = hmac.ComputeHash(toSign);
- return BitConverter.ToString(hash).Replace("-", string.Empty).ToLower();
- }
- }
-
- ///
- /// https://stackoverflow.com/a/12187656
- ///
- private byte[] HexDecode(string hex)
- {
- // In these case, key is not a string, it is byte array in hexadecimal string representation
- var bytes = new byte[hex.Length / 2];
- for (var i = 0; i < bytes.Length; i++)
- {
- bytes[i] = byte.Parse(hex.Substring(i * 2, 2), NumberStyles.HexNumber);
- }
- return bytes;
- }
- }
-}
\ No newline at end of file
diff --git a/Datatrans.Checkout/Web.Debug.config b/Datatrans.Checkout/Web.Debug.config
deleted file mode 100644
index 2e302f9..0000000
--- a/Datatrans.Checkout/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout/Web.Release.config b/Datatrans.Checkout/Web.Release.config
deleted file mode 100644
index c358444..0000000
--- a/Datatrans.Checkout/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Datatrans.Checkout/Web.config b/Datatrans.Checkout/Web.config
deleted file mode 100644
index c42c0b0..0000000
--- a/Datatrans.Checkout/Web.config
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Datatrans.Checkout/app.config b/Datatrans.Checkout/app.config
deleted file mode 100644
index a11b43d..0000000
--- a/Datatrans.Checkout/app.config
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Datatrans.Checkout/module.ignore b/Datatrans.Checkout/module.ignore
deleted file mode 100644
index 03996c7..0000000
--- a/Datatrans.Checkout/module.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-VirtoCommerce.Domain.dll
-DotLiquid.dll
-it\DotLiquid.resources.dll
\ No newline at end of file
diff --git a/Datatrans.Checkout/module.manifest b/Datatrans.Checkout/module.manifest
deleted file mode 100644
index e215165..0000000
--- a/Datatrans.Checkout/module.manifest
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
- Datatrans.Checkout
- 1.1.2
- 2.13.24
-
-
-
-
- Datatrans Payment Gateway
- APIs and UI for Datatrans payment gateway (using Datatrans Lightbox mode)
-
- Virto Commerce
- Konstantin Savosteev
-
- First version.
- Modules/$(Datatrans.Checkout)/Content/logo.png
-
- Datatrans.Checkout.dll
- Datatrans.Checkout.Module, Datatrans.Checkout
-
-
-
-
- Datatrans.Checkout.MerchantId
- string
- Merchant Id
- Merchant Id
-
-
- Datatrans.Checkout.HMACHex
- string
- HMAC key
- Your HMAC key in hexadecimal format
-
-
- Datatrans.Checkout.HMACHEXSign2
- string
- HMAC key for sign2 (optional)
- Your HMAC key in hexadecimal format
-
-
- Datatrans.Checkout.ServerToServer.Username
- string
- Cross server authorization username
- Server to server requests protection
-
-
- Datatrans.Checkout.ServerToServer.Password
- password
- Cross server authorization password
- Server to server requests protection
-
-
-
-
- Datatrans.Checkout.Mode
- string
- test
-
- test
- live
-
- Working mode
- Payment gateway mode
-
-
- Datatrans.Checkout.PaymentActionType
- string
-
- Settlement
- Sale
-
- Sale
- Payment action type
- Payment action type
-
-
- Datatrans.Checkout.PaymentMethod
- string
- VIS,ECA,AMX
- Visa, Mastercard, Amex, Diners, UATP, Paypal and Masterpass
- Payment Method
-
- VIS - Visa, ECA - MasterCard, AMX - American Express, DIN - Diners, MPW - Masterpass, UATP - UATP.
-
-
-
- Datatrans.Checkout.Language
- string
-
- en
-
- en
- Language
- Purchase locale code used for creating payment.
-
-
- Datatrans.Checkout.FormAction
- string
- http://localhost/cart/externalpaymentcallback
- Process Payment action
- If datatrans api call is successful executes redirect to this URL to process payment. Only absolute urls are allowed.
-
-
- Datatrans.Checkout.APIEndpoint
- string
- https://api.sandbox.datatrans.com
- URL for server to server requests
-
-
- Datatrans.Checkout.BrowserEndpoint
- string
- https://pay.sandbox.datatrans.com
- URL for payment page
-
-
-
-
- Datatrans.Checkout.ErrorTesting
- boolean
- false
- Enable error testing mode
- If this switch ON Datatrans module will always send error on transaction post processing. Not available on "live" mode.
-
-
- Datatrans.Checkout.ErrorCode
- string
- -1000
- Error code
- This error code will be send on transaction post processing.
-
-
-
-
diff --git a/Datatrans.Checkout/packages.config b/Datatrans.Checkout/packages.config
deleted file mode 100644
index f9825a0..0000000
--- a/Datatrans.Checkout/packages.config
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..4834e4f
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,12 @@
+
+
+
+
+ 3.800.0
+
+ $(VersionSuffix)-$(BuildNumber)
+
+
+ true
+
+
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index 56ab4cc..0000000
--- a/Jenkinsfile
+++ /dev/null
@@ -1,2 +0,0 @@
-#!groovy
-virtoModule {}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3caa727
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,12 @@
+Copyright (c) Virto Solutions LTD. All rights reserved.
+
+Licensed under the Virto Commerce Open Software License (the "License"); you
+may not use this file except in compliance with the License. You may
+obtain a copy of the License at
+
+https://virtocommerce.com/open-source-license
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied.
diff --git a/NuGet/build.bat b/NuGet/build.bat
deleted file mode 100644
index e864f66..0000000
--- a/NuGet/build.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-SET "SOURCE_DIR=%~dp0%.."
-SET "TARGET_DIR=%SOURCE_DIR%\NuGet"
-
-IF NOT DEFINED ProgramFiles(x86) SET ProgramFiles(x86)=%ProgramFiles%
-IF NOT DEFINED MSBUILD_PATH IF EXIST "%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe" SET MSBUILD_PATH=%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe
-IF NOT DEFINED MSBUILD_PATH IF EXIST "%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" SET MSBUILD_PATH=%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe
-IF NOT DEFINED MSBUILD_PATH SET MSBUILD_PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe
-
-"%MSBUILD_PATH%" "%SOURCE_DIR%\Datatrans.Checkout.sln" /nologo /verbosity:m /t:Build /p:Configuration=Release;Platform="Any CPU"
-
-
-nuget pack "%SOURCE_DIR%\Datatrans.Checkout.Core\Datatrans.Checkout.Core.csproj" -IncludeReferencedProjects -Symbols -Properties Configuration=Release -o "%TARGET_DIR%"
-
-@pause
diff --git a/NuGet/publish.bat b/NuGet/publish.bat
deleted file mode 100644
index 37a35af..0000000
--- a/NuGet/publish.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-@echo off
-setlocal enabledelayedexpansion
-
-if "%1" equ "" (
- echo Pass NuGet API key as first parameter
- pause
- exit /b 1
-)
-
-for %%f in (*.nupkg) do (
- set fileName=%%~nf
- if "!fileName!" equ "!fileName:.symbols=!" (
- nuget push %%f -Source nuget.org -ApiKey %1
- )
-)
-
-pause
diff --git a/README.md b/README.md
index b160aa0..49c6525 100644
--- a/README.md
+++ b/README.md
@@ -31,3 +31,8 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
+
+
+MerchantId & Secret
+
+https://admin.sandbox.datatrans.com/MenuDispatch.jsp?main=3&sub=4
\ No newline at end of file
diff --git a/VirtoCommerce.Datatrans.sln b/VirtoCommerce.Datatrans.sln
new file mode 100644
index 0000000..98a028b
--- /dev/null
+++ b/VirtoCommerce.Datatrans.sln
@@ -0,0 +1,64 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32630.192
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A3C4C5C8-97F9-41EB-95B7-257CF03A7E75}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtoCommerce.Datatrans.Web", "src\VirtoCommerce.Datatrans.Web\VirtoCommerce.Datatrans.Web.csproj", "{F464AF2F-03EA-409A-954F-15967078E45F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtoCommerce.Datatrans.Data", "src\VirtoCommerce.Datatrans.Data\VirtoCommerce.Datatrans.Data.csproj", "{FD525333-5E56-4DCF-89E5-FA397A8E29A4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtoCommerce.Datatrans.Core", "src\VirtoCommerce.Datatrans.Core\VirtoCommerce.Datatrans.Core.csproj", "{EADFE715-1C75-4BDC-B137-323FBF4F22DE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A9ACD1D0-6240-45AF-A81B-613C374CE836}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtoCommerce.Datatrans.Tests", "tests\VirtoCommerce.Datatrans.Tests\VirtoCommerce.Datatrans.Tests.csproj", "{003B1BF7-B0F8-41C1-ADC3-0F398178DDC5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7125869A-CBFE-41AE-911A-68238F65D326}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ .gitignore = .gitignore
+ copilot.md = copilot.md
+ Directory.Build.props = Directory.Build.props
+ LICENSE = LICENSE
+ module.ignore = module.ignore
+ README.md = README.md
+ VirtoCommerce.Datatrans.sln.DotSettings = VirtoCommerce.Datatrans.sln.DotSettings
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F464AF2F-03EA-409A-954F-15967078E45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F464AF2F-03EA-409A-954F-15967078E45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F464AF2F-03EA-409A-954F-15967078E45F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F464AF2F-03EA-409A-954F-15967078E45F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD525333-5E56-4DCF-89E5-FA397A8E29A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD525333-5E56-4DCF-89E5-FA397A8E29A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD525333-5E56-4DCF-89E5-FA397A8E29A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD525333-5E56-4DCF-89E5-FA397A8E29A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EADFE715-1C75-4BDC-B137-323FBF4F22DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EADFE715-1C75-4BDC-B137-323FBF4F22DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EADFE715-1C75-4BDC-B137-323FBF4F22DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EADFE715-1C75-4BDC-B137-323FBF4F22DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {003B1BF7-B0F8-41C1-ADC3-0F398178DDC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {003B1BF7-B0F8-41C1-ADC3-0F398178DDC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {003B1BF7-B0F8-41C1-ADC3-0F398178DDC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {003B1BF7-B0F8-41C1-ADC3-0F398178DDC5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {F464AF2F-03EA-409A-954F-15967078E45F} = {A3C4C5C8-97F9-41EB-95B7-257CF03A7E75}
+ {FD525333-5E56-4DCF-89E5-FA397A8E29A4} = {A3C4C5C8-97F9-41EB-95B7-257CF03A7E75}
+ {EADFE715-1C75-4BDC-B137-323FBF4F22DE} = {A3C4C5C8-97F9-41EB-95B7-257CF03A7E75}
+ {003B1BF7-B0F8-41C1-ADC3-0F398178DDC5} = {A9ACD1D0-6240-45AF-A81B-613C374CE836}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {910B8326-55DD-48B2-BFA6-A63D7D9ED579}
+ EndGlobalSection
+EndGlobal
diff --git a/VirtoCommerce.Datatrans.sln.DotSettings b/VirtoCommerce.Datatrans.sln.DotSettings
new file mode 100644
index 0000000..6f30e24
--- /dev/null
+++ b/VirtoCommerce.Datatrans.sln.DotSettings
@@ -0,0 +1,8 @@
+
+ <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="aaBb" /></Policy>
+ True
+ True
+ True
+ True
+ True
+
diff --git a/docs/media/diagram-db-model.drawio b/docs/media/diagram-db-model.drawio
new file mode 100644
index 0000000..7d64fff
--- /dev/null
+++ b/docs/media/diagram-db-model.drawio
@@ -0,0 +1 @@
+7Vtdc5s4FP01zOw+NMOHsZ3HmNrtTO1tJkl3H3cUkEFTjBghf/XXr4QkMJadQLeO1dgzngQuF4HuOTqSThzLCxabTwTkyQxHMLVcO9pY3kfLdR3bG7JfPLIVkb49EIGYoEgm1YFH9AOqO2V0iSJYNBIpxilFeTMY4iyDIW3EACF43Uyb47T51BzEUAs8hiDVo/+giCYiOvTtOv4ZojhRT3ZseWUBVLIMFAmI8LoRghs6wRmVr3gPyQJkMKPsygyQ75BY/jihlPf0znIn7DPn2TcxxnEKQY6KmxAvWDgsWMpkDhYo5WXeaWgkG2KP88aWFxCMqThabAKYcqwUDOKdJkeuVnUgvN0WNwQfVtvpd5tmn9fe33Q2i+8Hzx9kKyuQLmV9ZW3oVhUcRqz+8pQ9CtHtA0wBRTgb11dGMIvuOLosafzwAxL8hGcgY50fFRQQWl/DmUyfIPZ63kdHpchzm53rXZPvWeAlCeEL/XF7kpKAxJC+kNiXgEcNtsnKfYJ4ASnZsoR1zbGKSckuv1SQlEVZNVkKJJPiqsHqGfcYlcSSA9PryXbksBwoSqomRNflXbsw7zXU22uov9+QKI3WEDvY6XgdKlnUhVHuO6OU15JRzsAwSvXsJhOc4c9Sqt9syLX9N6WUzqivJIKk0HjFFD3nhxQ8lwwqSSCnMI+zgE1KFKCM6a9gSYjTFOQFKtNFJEFpNAVbvKSqIXU2mqMNjB7EDMZzGf+mrLFCUozPBYrV/DJIUZyx45BRjj9xRGDB3mUKCiozjpJyBQmFmxdZpLDx90BWw32HZa5/iGWefZxQDQS7wuW9LgAKKNZ1ikD6wBYKIItLzJqQ8LpGBOdPavTxQM6JBsl4BcVUXRafDfUAp5gjmwlBKNPKzvkj9mHdDewb3/LZCwTs3KnP2YenExrgrKAEoBIOyIBaQw7WiOJcPieFc/UaRBaTHz9jStnMfwzWF2n9OtYSW68ltCdDtqche/+lC7aY9XWelqqdoCiCmRiSfJ0IarwPQHmw/lXN98HYH4gt8fBa47EDgPeW9fe1+mMuhP+ymwLXurOFav/19Yn//DadWtVS1yR4lC6K3FGRgxBl8VTc2d/Dzz8Ffhvr6Hhy3xLP/iUr5eFV2a9Ryv65lXKgITv54nQB943GYksA+q0BOJc0DrWCh8uC9Vmoo3tAGo3D4lVd/OVgmaKDt1cdPI0O3p5bB5Vr+JPQmqWCt63Lfy4VdHQ/T6wQI0Ahi8tfFyGD7dEyRQYdfef8mKB8UYrW1evQvA532FLeTud1OPqW+IKmrg6ba6f97swUt8PRt9vvye6oqGvwdKZvkAspiFfPoyuIxsxy+t74giSzw3Kzu2Se3fZw9G34b+17VFw1WCP1zXNlCl+U7dEBK1Ok0P1/u+OrFBrsfLj6VtzAwdey/hVRzdVBVd5Da8ULdD86IGaMGur2RyA9/Kv9Ye18taPzVz3sk0F2tT9aDsffz/5w37f94Zpvf7i6/fHaHzUvyfvogKAxU9zV+ziVXp7d+3B178PAwdi2/uYbH65ufFTqmIEFX+mHCSB/+PafF7PoN8kCYaf1P7eIr4LX/5Hkjf8D
\ No newline at end of file
diff --git a/docs/media/diagram-db-model.png b/docs/media/diagram-db-model.png
new file mode 100644
index 0000000..8346629
Binary files /dev/null and b/docs/media/diagram-db-model.png differ
diff --git a/module.ignore b/module.ignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/DatatransApiRoutes.cs b/src/VirtoCommerce.Datatrans.Core/Models/DatatransApiRoutes.cs
new file mode 100644
index 0000000..1c5439e
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/DatatransApiRoutes.cs
@@ -0,0 +1,22 @@
+namespace VirtoCommerce.Datatrans.Core.Models;
+
+public class DatatransApiRoutes
+{
+ // POST
+ public string GetSecureFieldsPath() => "/v1/transactions/secureFields";
+
+ // GET
+ public string GetTransactionPath(string transactionId) => $"/v1/transactions/{transactionId}";
+
+ // POST
+ public string GetAuthorizeAuthenticatedPath(string transactionId) => $"/v1/transactions/{transactionId}/authorize";
+
+ // POST
+ public string GetCapturePath(string transactionId) => $"/v1/transactions/{transactionId}/capture";
+
+ // POST
+ public string GetVoidPath(string transactionId) => $"/v1/transactions/{transactionId}/cancel";
+
+ // POST
+ public string GetRefundPath(string transactionId) => $"/v1/transactions/{transactionId}/credit";
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/DatatransOptions.cs b/src/VirtoCommerce.Datatrans.Core/Models/DatatransOptions.cs
new file mode 100644
index 0000000..6bb397d
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/DatatransOptions.cs
@@ -0,0 +1,20 @@
+namespace VirtoCommerce.Datatrans.Core.Models;
+
+public class DatatransOptions
+{
+ public string SandboxBaseUrl { get; set; } = "https://api.sandbox.datatrans.com";
+ public string ProductionBaseUrl { get; set; } = "https://api.datatrans.com";
+
+ public string SandboxSecureFieldsScriptUrl { get; set; } = "https://pay.sandbox.datatrans.com/upp/payment/js/secure-fields-2.0.0.min.js";
+ public string ProductionSecureFieldsScriptUrl { get; set; } = "https://pay.datatrans.com/upp/payment/js/secure-fields-2.0.0.min.js";
+
+ public string SandboxStartUrlBase { get; set; } = "https://pay.sandbox.datatrans.com/v1/start/";
+ public string ProductionStartUrlBase { get; set; } = "https://pay.datatrans.com/v1/start/";
+
+ public bool UseSandbox { get; set; } = true;
+
+ public string MerchantId { get; set; }
+ public string Secret { get; set; }
+
+ public DatatransApiRoutes Routes { get; set; } = new();
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeAuthenticatedRequest.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeAuthenticatedRequest.cs
new file mode 100644
index 0000000..236d755
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeAuthenticatedRequest.cs
@@ -0,0 +1,7 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransAuthorizeAuthenticatedRequest
+{
+ public string Refno { get; set; }
+ public long Amount { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeResponse.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeResponse.cs
new file mode 100644
index 0000000..c1920fa
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransAuthorizeResponse.cs
@@ -0,0 +1,6 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransAuthorizeResponse : DatatransResponseBase
+{
+ public string AcquirerAuthorizationCode { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureRequest.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureRequest.cs
new file mode 100644
index 0000000..a1bdd9c
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureRequest.cs
@@ -0,0 +1,8 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransCaptureRequest
+{
+ public long Amount { get; set; }
+ public string Currency { get; set; }
+ public string Refno { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureResponse.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureResponse.cs
new file mode 100644
index 0000000..066cf6d
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransCaptureResponse.cs
@@ -0,0 +1,3 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransCaptureResponse : DatatransResponseBase;
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransError.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransError.cs
new file mode 100644
index 0000000..039c9a3
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransError.cs
@@ -0,0 +1,8 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransError
+{
+ public string Code { get; set; }
+ public string Message { get; set; }
+ public object Raw { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitRequest.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitRequest.cs
new file mode 100644
index 0000000..830e645
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitRequest.cs
@@ -0,0 +1,9 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransInitRequest
+{
+ public long Amount { get; set; }
+ public string Currency { get; set; }
+ public string ReturnUrl { get; set; }
+ public string ReturnMethod { get; set; } = "GET";
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitResponse.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitResponse.cs
new file mode 100644
index 0000000..5224121
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransInitResponse.cs
@@ -0,0 +1,6 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransInitResponse : DatatransResponseBase
+{
+ public string TransactionId { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundRequest.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundRequest.cs
new file mode 100644
index 0000000..972cfad
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundRequest.cs
@@ -0,0 +1,8 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransRefundRequest
+{
+ public long Amount { get; set; }
+ public string Currency { get; set; }
+ public string Refno { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundResponse.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundResponse.cs
new file mode 100644
index 0000000..3ae4f3e
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransRefundResponse.cs
@@ -0,0 +1,7 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransRefundResponse : DatatransResponseBase
+{
+ public string TransactionId { get; set; }
+ public string AcquirerAuthorizationCode { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransResponseBase.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransResponseBase.cs
new file mode 100644
index 0000000..9c7164a
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransResponseBase.cs
@@ -0,0 +1,6 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransResponseBase
+{
+ public DatatransError Error { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransTransaction.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransTransaction.cs
new file mode 100644
index 0000000..edb3038
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransTransaction.cs
@@ -0,0 +1,58 @@
+using Newtonsoft.Json;
+
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransTransaction : DatatransResponseBase
+{
+ public string TransactionId { get; set; }
+ public string MerchantId { get; set; }
+ public string Type { get; set; }
+ public string Status { get; set; }
+ public string Currency { get; set; }
+ public string Refno { get; set; }
+ public string PaymentMethod { get; set; }
+ public string AcquirerAuthorizationCode { get; set; }
+ public DatatransTransactionDetail Detail { get; set; }
+ public DatatransTransactionCard Card { get; set; }
+}
+
+public class DatatransTransactionDetail
+{
+ public DatatransTransactionAmount Authorize { get; set; }
+}
+
+public class DatatransTransactionAmount
+{
+ public long Amount { get; set; }
+}
+
+public class DatatransTransactionCard
+{
+ public string Alias { get; set; }
+ public string Fingerprint { get; set; }
+ public string Masked { get; set; }
+ public string ExpiryMonth { get; set; }
+ public string ExpiryYear { get; set; }
+ public DatatransTransactionCardInfo Info { get; set; }
+
+ [JsonProperty("3D")]
+ public DatatransTransactionCard3D ThreeD
+ {
+ get; set;
+ }
+}
+
+public class DatatransTransactionCardInfo
+{
+ public string Brand { get; set; }
+ public string Type { get; set; }
+ public string Usage { get; set; }
+ public string Country { get; set; }
+ public string Issuer { get; set; }
+}
+
+public class DatatransTransactionCard3D
+{
+ public string AuthenticationResponse { get; set; }
+ public string TransStatusReason { get; set; }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransVoidResponse.cs b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransVoidResponse.cs
new file mode 100644
index 0000000..d70f6c2
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Models/External/DatatransVoidResponse.cs
@@ -0,0 +1,3 @@
+namespace VirtoCommerce.Datatrans.Core.Models.External;
+
+public class DatatransVoidResponse : DatatransResponseBase;
diff --git a/src/VirtoCommerce.Datatrans.Core/ModuleConstants.cs b/src/VirtoCommerce.Datatrans.Core/ModuleConstants.cs
new file mode 100644
index 0000000..61ac728
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/ModuleConstants.cs
@@ -0,0 +1,46 @@
+using System.Collections.Generic;
+using VirtoCommerce.Platform.Core.Settings;
+
+namespace VirtoCommerce.Datatrans.Core;
+
+public static class ModuleConstants
+{
+ public static class Settings
+ {
+ public static class General
+ {
+ public static SettingDescriptor Sandbox { get; } = new()
+ {
+ Name = "VirtoCommerce.Payment.Datatrans.Sandbox",
+ GroupName = "Payment|Datatrans",
+ ValueType = SettingValueType.Boolean,
+ DefaultValue = true,
+ };
+
+ public static SettingDescriptor ReturnUrl { get; } = new()
+ {
+ Name = "VirtoCommerce.Payment.Datatrans.ReturnUrl",
+ GroupName = "Payment|Datatrans",
+ ValueType = SettingValueType.ShortText,
+ DefaultValue = "/account/orders/{orderId}/payment",
+ };
+
+ public static IEnumerable AllGeneralSettings
+ {
+ get
+ {
+ yield return Sandbox;
+ yield return ReturnUrl;
+ }
+ }
+ }
+
+ public static IEnumerable AllSettings
+ {
+ get
+ {
+ return General.AllGeneralSettings;
+ }
+ }
+ }
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/Services/IDatatransClient.cs b/src/VirtoCommerce.Datatrans.Core/Services/IDatatransClient.cs
new file mode 100644
index 0000000..a07867c
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/Services/IDatatransClient.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using VirtoCommerce.Datatrans.Core.Models.External;
+
+namespace VirtoCommerce.Datatrans.Core.Services;
+
+public interface IDatatransClient
+{
+ Task InitTransactionAsync(DatatransInitRequest request, CancellationToken cancellationToken = default);
+
+ Task GetTransactionAsync(string transactionId, CancellationToken cancellationToken = default);
+
+ Task AuthorizeAuthenticatedAsync(string transactionId, DatatransAuthorizeAuthenticatedRequest request, CancellationToken cancellationToken = default);
+
+ Task CaptureAsync(string transactionId, DatatransCaptureRequest request, CancellationToken cancellationToken = default);
+
+ Task VoidAsync(string transactionId, CancellationToken cancellationToken = default);
+
+ Task RefundAsync(string transactionId, DatatransRefundRequest request, CancellationToken cancellationToken = default);
+
+ Uri BuildStartPaymentUri(string transactionId);
+
+ string GetSecureFieldsScriptUrl();
+}
diff --git a/src/VirtoCommerce.Datatrans.Core/VirtoCommerce.Datatrans.Core.csproj b/src/VirtoCommerce.Datatrans.Core/VirtoCommerce.Datatrans.Core.csproj
new file mode 100644
index 0000000..a3c0217
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Core/VirtoCommerce.Datatrans.Core.csproj
@@ -0,0 +1,16 @@
+
+
+ net8.0
+
+
+
+ false
+
+
+
+
+
+
+
+
+
diff --git a/src/VirtoCommerce.Datatrans.Data/Providers/DatatransPaymentMethod.cs b/src/VirtoCommerce.Datatrans.Data/Providers/DatatransPaymentMethod.cs
new file mode 100644
index 0000000..e791a51
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Data/Providers/DatatransPaymentMethod.cs
@@ -0,0 +1,495 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using VirtoCommerce.CoreModule.Core.Currency;
+using VirtoCommerce.Datatrans.Core;
+using VirtoCommerce.Datatrans.Core.Models.External;
+using VirtoCommerce.Datatrans.Core.Services;
+using VirtoCommerce.OrdersModule.Core.Model;
+using VirtoCommerce.PaymentModule.Core.Model;
+using VirtoCommerce.PaymentModule.Model.Requests;
+using VirtoCommerce.Platform.Core.Common;
+using VirtoCommerce.Platform.Core.Settings;
+using VirtoCommerce.StoreModule.Core.Model;
+
+namespace VirtoCommerce.Datatrans.Data.Providers;
+
+public class DatatransPaymentMethod(IDatatransClient datatransClient, ICurrencyService currencyService) : PaymentMethod(nameof(DatatransPaymentMethod)), ISupportCaptureFlow, ISupportRefundFlow
+{
+ public override PaymentMethodType PaymentMethodType => PaymentMethodType.Standard;
+ public override PaymentMethodGroupType PaymentMethodGroupType => PaymentMethodGroupType.BankCard;
+
+ #region Overrides
+
+ public override ProcessPaymentRequestResult ProcessPayment(ProcessPaymentRequest request)
+ {
+ return ProcessPaymentAsync(request).GetAwaiter().GetResult();
+ }
+
+ public override PostProcessPaymentRequestResult PostProcessPayment(PostProcessPaymentRequest request)
+ {
+ return PostProcessPaymentAsync(request).GetAwaiter().GetResult();
+ }
+
+ public override VoidPaymentRequestResult VoidProcessPayment(VoidPaymentRequest request)
+ {
+ return VoidProcessPaymentAsync(request).GetAwaiter().GetResult();
+ }
+
+ public override CapturePaymentRequestResult CaptureProcessPayment(CapturePaymentRequest context)
+ {
+ return CaptureProcessPaymentAsync(context).GetAwaiter().GetResult();
+ }
+
+ public override RefundPaymentRequestResult RefundProcessPayment(RefundPaymentRequest context)
+ {
+ return RefundProcessPaymentAsync(context).GetAwaiter().GetResult();
+ }
+
+ public override ValidatePostProcessRequestResult ValidatePostProcessRequest(NameValueCollection queryString)
+ {
+ var transactionId = queryString["transactionId"];
+
+ var result = new ValidatePostProcessRequestResult
+ {
+ IsSuccess = !transactionId.IsNullOrEmpty(),
+ OuterId = transactionId,
+ };
+
+ return result;
+ }
+
+ #endregion
+
+ #region Protected async methods
+
+ protected virtual async Task ProcessPaymentAsync(ProcessPaymentRequest request)
+ {
+ var payment = (PaymentIn)request.Payment;
+
+ var initRequest = await CreateInitRequest(request);
+ var initResponse = await datatransClient.InitTransactionAsync(initRequest);
+
+ var success = initResponse.Error is null && !initResponse.TransactionId.IsNullOrEmpty();
+
+ payment.OuterId = initResponse.TransactionId;
+ payment.PaymentStatus = success ? PaymentStatus.Pending : PaymentStatus.Voided;
+ payment.Status = payment.PaymentStatus.ToString();
+
+ return await CreateInitRequestResult(initResponse, request);
+ }
+
+ protected virtual async Task PostProcessPaymentAsync(PostProcessPaymentRequest request, CancellationToken cancellationToken = default)
+ {
+ var transactionId = request.Parameters?.Get("transactionId");
+
+ if (transactionId.IsNullOrEmpty())
+ {
+ return new PostProcessPaymentRequestResult
+ {
+ IsSuccess = false,
+ ErrorMessage = "transactionId not found",
+ };
+ }
+
+ var transaction = await datatransClient.GetTransactionAsync(transactionId, cancellationToken);
+
+ if (transaction.Status is "authenticated")
+ {
+ transaction.Refno = Guid.NewGuid().ToString("N").ToLower();
+ var authorizeRequest = await CreateAuthorizeRequest(transaction, request);
+ await datatransClient.AuthorizeAuthenticatedAsync(transactionId, authorizeRequest, cancellationToken);
+
+ transaction = await datatransClient.GetTransactionAsync(transactionId, cancellationToken);
+ }
+
+ var order = (CustomerOrder)request.Order;
+ var payment = (PaymentIn)request.Payment;
+ var result = GetDatatransPostResult(transaction, order, payment);
+
+ return result;
+ }
+
+ protected virtual async Task VoidProcessPaymentAsync(VoidPaymentRequest request)
+ {
+ var payment = (PaymentIn)request.Payment;
+
+ if (payment.PaymentStatus == PaymentStatus.Voided)
+ {
+ return new VoidPaymentRequestResult
+ {
+ IsSuccess = true,
+ NewPaymentStatus = PaymentStatus.Voided,
+ };
+ }
+
+ if (payment.PaymentStatus == PaymentStatus.Paid || payment.CapturedDate.HasValue)
+ {
+ return new VoidPaymentRequestResult
+ {
+ IsSuccess = false,
+ ErrorMessage = "Cannot void a captured payment. Use refund instead.",
+ };
+ }
+
+ var transactionId = GetTransactionId(request);
+ var response = await datatransClient.VoidAsync(transactionId);
+
+ if (response.Error != null)
+ {
+ var transaction = await datatransClient.GetTransactionAsync(transactionId);
+ payment.OuterId = transactionId;
+ payment.PaymentStatus = ConvertStatus(transaction.Status);
+ }
+
+ payment.Status = payment.PaymentStatus.ToString();
+
+ return new VoidPaymentRequestResult
+ {
+ IsSuccess = response.Error == null,
+ NewPaymentStatus = payment.PaymentStatus,
+ ErrorMessage = response.Error?.Message,
+ };
+ }
+
+ protected virtual async Task CaptureProcessPaymentAsync(CapturePaymentRequest context)
+ {
+ var payment = (PaymentIn)context.Payment;
+ var transactionId = GetTransactionId(context);
+
+ var alreadyCaptured = payment.Captures.Sum(x => x.Amount);
+ var total = payment.Sum;
+
+ var amountToCapture = context.CaptureAmount ?? total - alreadyCaptured;
+
+ if (amountToCapture <= 0m)
+ {
+ return new CapturePaymentRequestResult
+ {
+ IsSuccess = true,
+ NewPaymentStatus = payment.PaymentStatus,
+ ErrorMessage = null,
+ };
+ }
+
+ var transaction = await datatransClient.GetTransactionAsync(transactionId);
+ var amountMinor = await ToMinorUnits(payment.Currency, amountToCapture);
+
+ var captureRequest = new DatatransCaptureRequest
+ {
+ Amount = amountMinor,
+ Currency = payment.Currency,
+ Refno = transaction.Refno,
+ };
+
+ var response = await datatransClient.CaptureAsync(transactionId, captureRequest);
+
+ payment.OuterId = transactionId;
+
+ if (response.Error == null)
+ {
+ transaction = await datatransClient.GetTransactionAsync(transactionId);
+ payment.PaymentStatus = ConvertStatus(transaction.Status);
+ payment.CapturedDate ??= DateTime.UtcNow;
+ }
+ else
+ {
+ payment.PaymentStatus = PaymentStatus.Error;
+ }
+
+ payment.Status = payment.PaymentStatus.ToString();
+
+ return new CapturePaymentRequestResult
+ {
+ IsSuccess = response.Error == null,
+ NewPaymentStatus = payment.PaymentStatus,
+ ErrorMessage = response.Error?.Message,
+ };
+ }
+
+ protected virtual async Task RefundProcessPaymentAsync(RefundPaymentRequest context)
+ {
+ var payment = (PaymentIn)context.Payment;
+ var transactionId = GetTransactionId(context);
+
+ if (!payment.CapturedDate.HasValue)
+ {
+ return new RefundPaymentRequestResult
+ {
+ IsSuccess = false,
+ ErrorMessage = "No captured amount to refund.",
+ };
+ }
+
+ if (payment.PaymentStatus == PaymentStatus.Refunded)
+ {
+ return new RefundPaymentRequestResult
+ {
+ IsSuccess = false,
+ ErrorMessage = "Refund amount exceeds captured amount.",
+ };
+ }
+
+ var amountToRefund = context.AmountToRefund;
+
+ if (amountToRefund <= 0m)
+ {
+ return new RefundPaymentRequestResult
+ {
+ IsSuccess = false,
+ ErrorMessage = "Refund amount must be greater than zero.",
+ };
+ }
+
+ var transaction = await datatransClient.GetTransactionAsync(transactionId);
+ var amountMinor = await ToMinorUnits(payment.Currency, amountToRefund);
+
+ var request = new DatatransRefundRequest
+ {
+ Amount = amountMinor,
+ Currency = payment.Currency,
+ Refno = transaction.Refno,
+ };
+
+ var response = await datatransClient.RefundAsync(transactionId, request);
+
+ if (response.Error == null)
+ {
+ transaction = await datatransClient.GetTransactionAsync(transactionId);
+ payment.PaymentStatus = ConvertStatus(transaction.Status);
+ }
+
+ payment.Status = payment.PaymentStatus.ToString();
+
+ return new RefundPaymentRequestResult
+ {
+ IsSuccess = response.Error == null,
+ NewPaymentStatus = payment.PaymentStatus,
+ ErrorMessage = response.Error?.Message,
+ };
+ }
+
+ #endregion
+
+ #region Extension points
+
+ protected virtual async Task CreateInitRequest(ProcessPaymentRequest request)
+ {
+ var store = (Store)request.Store;
+ var order = (CustomerOrder)request.Order;
+ var payment = (PaymentIn)request.Payment;
+
+ var url = (store.SecureUrl.IsNullOrEmpty() ? store.Url : store.SecureUrl)?.TrimEnd('/');
+
+ var result = AbstractTypeFactory.TryCreateInstance();
+
+ var currency = payment.Currency.EmptyToNull() ?? order.Currency;
+
+ result.Amount = await ToMinorUnits(currency, payment.Sum);
+ result.Currency = currency;
+
+ var returnUrl = Settings.GetValue(ModuleConstants.Settings.General.ReturnUrl)
+ .Replace("{orderId}", order.Id)
+ .TrimStart('/');
+
+ result.ReturnUrl = $"{url}/{returnUrl}";
+
+ return result;
+ }
+
+ protected virtual Task CreateInitRequestResult(DatatransInitResponse initResponse, ProcessPaymentRequest request)
+ {
+ var payment = (PaymentIn)request.Payment;
+
+ var result = new ProcessPaymentRequestResult
+ {
+ IsSuccess = initResponse.Error == null,
+ NewPaymentStatus = payment.PaymentStatus,
+ ErrorMessage = initResponse.Error?.Message,
+ };
+
+ if (result.IsSuccess)
+ {
+ result.PublicParameters = new()
+ {
+ ["transactionId"] = initResponse.TransactionId,
+ ["clientScript"] = datatransClient.GetSecureFieldsScriptUrl(),
+ ["startUrl"] = datatransClient.BuildStartPaymentUri(initResponse.TransactionId).ToString(),
+ };
+ }
+
+ return Task.FromResult(result);
+ }
+
+ protected virtual Task CreateAuthorizeRequest(DatatransTransaction transaction, PostProcessPaymentRequest request)
+ {
+ var result = AbstractTypeFactory.TryCreateInstance();
+
+ result.Amount = transaction.Detail.Authorize.Amount;
+ result.Refno = transaction.Refno;
+
+ return Task.FromResult(result);
+ }
+
+ #endregion
+
+ #region Helpers
+
+ private static string GetTransactionId(PaymentRequestBase context)
+ {
+ var payment = (PaymentIn)context.Payment;
+
+ var transactionId =
+ payment?.OuterId
+ ?? context.Parameters?.Get("transactionId")
+ ?? context.OuterId;
+
+ return transactionId;
+ }
+
+ private async Task ToMinorUnits(string currencyCode, decimal amount)
+ {
+ const int @base = 10;
+ var currency = (await currencyService.GetAllCurrenciesAsync()).FirstOrDefault(x => x.Code.EqualsIgnoreCase(currencyCode));
+ var multiplier = currency != null
+ ? (decimal)Math.Pow(@base, currency.DecimalDigits) // 1, 100, or 1000
+ : 100m;
+
+ return (long)Math.Round(amount * multiplier, MidpointRounding.AwayFromZero);
+ }
+
+ #endregion
+
+ #region Post process status mappers
+
+ private static PostProcessPaymentRequestResult GetDatatransPostResult(DatatransTransaction transaction, CustomerOrder order, PaymentIn payment)
+ {
+ var newStatus = ConvertStatus(transaction.Status);
+
+ return newStatus switch
+ {
+ PaymentStatus.Authorized or PaymentStatus.Paid => PaymentApproved(transaction, order, payment, newStatus),
+ PaymentStatus.Declined => PaymentDeclined(transaction, payment),
+ PaymentStatus.Pending => PaymentPending(transaction, payment),
+ _ => PaymentInvalid(transaction, payment),
+ };
+ }
+
+ private static PostProcessPaymentRequestResult PaymentApproved(DatatransTransaction transaction, CustomerOrder order, PaymentIn payment, PaymentStatus newStatus)
+ {
+ var result = new PostProcessPaymentRequestResult
+ {
+ NewPaymentStatus = newStatus,
+ OrderId = order.Id,
+ OuterId = transaction.TransactionId,
+ IsSuccess = true,
+ };
+
+ payment.PaymentStatus = newStatus;
+ payment.Status = newStatus.ToString();
+ payment.IsApproved = true;
+ payment.OuterId = transaction.TransactionId;
+ payment.AuthorizedDate ??= DateTime.UtcNow;
+
+ payment.CapturedDate ??= DateTime.UtcNow;
+ payment.Captures ??= new List();
+ payment.Captures.Add(new Capture
+ {
+ TransactionId = transaction.TransactionId,
+ Amount = payment.Sum,
+ Currency = payment.Currency,
+ CreatedDate = DateTime.UtcNow,
+ OuterId = transaction.TransactionId,
+ });
+
+ var note = $"Transaction ID: {transaction.TransactionId}";
+ if (!string.IsNullOrEmpty(transaction.MerchantId))
+ {
+ note += $", Merchant ID: {transaction.MerchantId}";
+ }
+
+ payment.Comment = $"Paid successfully via Datatrans. {note}{Environment.NewLine}";
+ order.Status = "Processing";
+
+ var paymentGatewayTransaction = new PaymentGatewayTransaction
+ {
+ IsProcessed = true,
+ ProcessedDate = DateTime.UtcNow,
+ CurrencyCode = payment.Currency,
+ Amount = payment.Sum,
+ Note = note,
+ ResponseData = JsonConvert.SerializeObject(transaction),
+ };
+
+ payment.Transactions ??= new List();
+ payment.Transactions.Add(paymentGatewayTransaction);
+
+ return result;
+ }
+
+ private static PostProcessPaymentRequestResult PaymentDeclined(DatatransTransaction transaction, PaymentIn payment)
+ {
+ var error = transaction.Error != null ? JsonConvert.SerializeObject(transaction.Error) : "Invalid Datatrans response";
+ var errorMessage = $"Your transaction was declined: {error}";
+
+ payment.Status = nameof(PaymentStatus.Declined);
+ payment.ProcessPaymentResult = new ProcessPaymentRequestResult { ErrorMessage = errorMessage };
+ payment.Comment = $"{errorMessage}{Environment.NewLine}";
+
+ return new PostProcessPaymentRequestResult
+ {
+ NewPaymentStatus = PaymentStatus.Declined,
+ ErrorMessage = errorMessage,
+ };
+ }
+
+ private static PostProcessPaymentRequestResult PaymentPending(DatatransTransaction transaction, PaymentIn payment)
+ {
+ var error = transaction.Error != null ? JsonConvert.SerializeObject(transaction.Error) : "Invalid Datatrans response";
+ var errorMessage = $"Your transaction is pending: {error}";
+
+ payment.ProcessPaymentResult = new ProcessPaymentRequestResult { ErrorMessage = errorMessage };
+ payment.Comment = $"{errorMessage}{Environment.NewLine}";
+ payment.OuterId ??= transaction.TransactionId;
+
+ return new PostProcessPaymentRequestResult
+ {
+ ErrorMessage = errorMessage,
+ IsSuccess = true,
+ OuterId = transaction.TransactionId,
+ };
+ }
+
+ private static PostProcessPaymentRequestResult PaymentInvalid(DatatransTransaction transaction, PaymentIn payment)
+ {
+ var error = transaction.Error != null ? JsonConvert.SerializeObject(transaction.Error) : "Invalid Datatrans response";
+ var errorMessage = $"There was an error processing your transaction: {error}";
+
+ payment.Status = nameof(PaymentStatus.Error);
+ payment.ProcessPaymentResult = new ProcessPaymentRequestResult { ErrorMessage = errorMessage };
+ payment.Comment = $"{errorMessage}{Environment.NewLine}";
+
+ return new PostProcessPaymentRequestResult { ErrorMessage = errorMessage };
+ }
+
+ private static PaymentStatus ConvertStatus(string status)
+ {
+ return status switch
+ {
+ "initialized" => PaymentStatus.Pending,
+ "authenticated" => PaymentStatus.Pending,
+ "authorized" => PaymentStatus.Authorized,
+ "settled" => PaymentStatus.Paid,
+ "canceled" => PaymentStatus.Voided,
+ "transmitted" => PaymentStatus.Pending,
+ "failed" => PaymentStatus.Declined,
+ _ => PaymentStatus.Error,
+ };
+ }
+
+ #endregion
+}
diff --git a/src/VirtoCommerce.Datatrans.Data/Services/DatatransClient.cs b/src/VirtoCommerce.Datatrans.Data/Services/DatatransClient.cs
new file mode 100644
index 0000000..61e0233
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Data/Services/DatatransClient.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using VirtoCommerce.Datatrans.Core.Models;
+using VirtoCommerce.Datatrans.Core.Models.External;
+using VirtoCommerce.Datatrans.Core.Services;
+using VirtoCommerce.Platform.Core.Common;
+
+namespace VirtoCommerce.Datatrans.Data.Services;
+
+public class DatatransClient(IHttpClientFactory httpClientFactory, IOptions options) : IDatatransClient
+{
+ private static readonly JsonSerializerSettings _serializerSettings = new()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver(),
+ NullValueHandling = NullValueHandling.Ignore
+ };
+
+ private readonly DatatransOptions _options = options.Value;
+
+ private string BaseStartUrl => _options.UseSandbox ? _options.SandboxStartUrlBase : _options.ProductionStartUrlBase;
+ private string SecureScriptUrl => _options.UseSandbox ? _options.SandboxSecureFieldsScriptUrl : _options.ProductionSecureFieldsScriptUrl;
+
+ public Uri BuildStartPaymentUri(string transactionId)
+ {
+ if (transactionId.IsNullOrEmpty())
+ {
+ throw new ArgumentException("Value cannot be null or empty.", nameof(transactionId));
+ }
+
+ return new Uri($"{BaseStartUrl}{Uri.EscapeDataString(transactionId)}");
+ }
+
+ public string GetSecureFieldsScriptUrl() => SecureScriptUrl;
+
+ public async Task InitTransactionAsync(DatatransInitRequest request, CancellationToken cancellationToken = default)
+ {
+ var resp = await SendAsync(HttpMethod.Post, _options.Routes.GetSecureFieldsPath(), request, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ public async Task GetTransactionAsync(string transactionId, CancellationToken cancellationToken = default)
+ {
+ var path = _options.Routes.GetTransactionPath(transactionId);
+ var resp = await SendAsync(HttpMethod.Get, path, null, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ public async Task AuthorizeAuthenticatedAsync(string transactionId, DatatransAuthorizeAuthenticatedRequest request, CancellationToken cancellationToken = default)
+ {
+ var path = _options.Routes.GetAuthorizeAuthenticatedPath(transactionId);
+ var resp = await SendAsync(HttpMethod.Post, path, request, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ public async Task CaptureAsync(string transactionId, DatatransCaptureRequest request, CancellationToken cancellationToken = default)
+ {
+ var path = _options.Routes.GetCapturePath(transactionId);
+ var resp = await SendAsync(HttpMethod.Post, path, request, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ public async Task VoidAsync(string transactionId, CancellationToken cancellationToken = default)
+ {
+ var path = _options.Routes.GetVoidPath(transactionId);
+ var resp = await SendAsync(HttpMethod.Post, path, new { }, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ public async Task RefundAsync(string transactionId, DatatransRefundRequest request, CancellationToken cancellationToken = default)
+ {
+ var path = _options.Routes.GetRefundPath(transactionId);
+ var resp = await SendAsync(HttpMethod.Post, path, request, cancellationToken);
+ return ParseResponse(resp);
+ }
+
+ private async Task SendAsync(HttpMethod method, string path, object body, CancellationToken ct)
+ {
+ using var msg = new HttpRequestMessage(method, path);
+
+ if (body is not null)
+ {
+ var json = JsonConvert.SerializeObject(body, _serializerSettings);
+ msg.Content = new StringContent(json, Encoding.UTF8, "application/json");
+ }
+
+ var httpClient = httpClientFactory.CreateClient("Datatrans");
+
+ using var resp = await httpClient.SendAsync(msg, ct);
+ var content = await resp.Content.ReadAsStringAsync(ct);
+
+ return content;
+ }
+
+ private static T ParseResponse(string json) where T : DatatransResponseBase, new()
+ {
+ try
+ {
+ if (json.IsNullOrEmpty())
+ {
+ return new T();
+ }
+
+ return JsonConvert.DeserializeObject(json);
+ }
+ catch (Exception exception)
+ {
+ return new T
+ {
+ Error = new DatatransError
+ {
+ Message = exception.Message,
+ Raw = json,
+ },
+ };
+ }
+ }
+}
diff --git a/src/VirtoCommerce.Datatrans.Data/VirtoCommerce.Datatrans.Data.csproj b/src/VirtoCommerce.Datatrans.Data/VirtoCommerce.Datatrans.Data.csproj
new file mode 100644
index 0000000..b844f65
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Data/VirtoCommerce.Datatrans.Data.csproj
@@ -0,0 +1,16 @@
+
+
+ net8.0
+
+
+
+ false
+
+
+
+
+
+
+
+
+
diff --git a/NuGet/icon.png b/src/VirtoCommerce.Datatrans.Web/Content/logo.png
similarity index 100%
rename from NuGet/icon.png
rename to src/VirtoCommerce.Datatrans.Web/Content/logo.png
diff --git a/src/VirtoCommerce.Datatrans.Web/Localizations/en.VirtoCommerce.Datatrans.json b/src/VirtoCommerce.Datatrans.Web/Localizations/en.VirtoCommerce.Datatrans.json
new file mode 100644
index 0000000..7f23ce4
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Web/Localizations/en.VirtoCommerce.Datatrans.json
@@ -0,0 +1,18 @@
+{
+ "payment": {
+ "labels": {
+ "DatatransPaymentMethod": {
+ "name": "Datatrans",
+ "description": "Datatrans integration"
+ }
+ }
+ },
+ "settings": {
+ "VirtoCommerce.Payment.Datatrans": {
+ "Sandbox": {
+ "title": "Sandbox",
+ "description": "Mode of Datatrans payment gateway (test or real)"
+ }
+ }
+ }
+}
diff --git a/src/VirtoCommerce.Datatrans.Web/Module.cs b/src/VirtoCommerce.Datatrans.Web/Module.cs
new file mode 100644
index 0000000..34bebf9
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Web/Module.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Net.Http.Headers;
+using System.Text;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using VirtoCommerce.Datatrans.Core;
+using VirtoCommerce.Datatrans.Core.Models;
+using VirtoCommerce.Datatrans.Core.Services;
+using VirtoCommerce.Datatrans.Data.Providers;
+using VirtoCommerce.Datatrans.Data.Services;
+using VirtoCommerce.PaymentModule.Core.Services;
+using VirtoCommerce.Platform.Core.Common;
+using VirtoCommerce.Platform.Core.Modularity;
+using VirtoCommerce.Platform.Core.Settings;
+
+namespace VirtoCommerce.Datatrans.Web;
+
+public class Module : IModule, IHasConfiguration
+{
+ public ManifestModuleInfo ModuleInfo { get; set; }
+ public IConfiguration Configuration { get; set; }
+
+ public void Initialize(IServiceCollection serviceCollection)
+ {
+ serviceCollection.AddOptions().Bind(Configuration.GetSection("Payments:Datatrans")).ValidateDataAnnotations();
+
+ serviceCollection.AddTransient();
+ serviceCollection.AddTransient();
+
+ serviceCollection.AddHttpClient("Datatrans", (sp, http) =>
+ {
+ var options = sp.GetRequiredService>().Value;
+ http.BaseAddress = new Uri(options.UseSandbox ? options.SandboxBaseUrl : options.ProductionBaseUrl);
+ http.Timeout = TimeSpan.FromSeconds(30);
+
+ if (!options.MerchantId.IsNullOrEmpty())
+ {
+ var bytes = Encoding.UTF8.GetBytes($"{options.MerchantId}:{options.Secret}");
+ http.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Basic", Convert.ToBase64String(bytes));
+ }
+ });
+ }
+
+ public void PostInitialize(IApplicationBuilder appBuilder)
+ {
+ var settingsRegistrar = appBuilder.ApplicationServices.GetRequiredService();
+ settingsRegistrar.RegisterSettings(ModuleConstants.Settings.AllSettings, ModuleInfo.Id);
+
+ var paymentMethodsRegistrar = appBuilder.ApplicationServices.GetRequiredService();
+ paymentMethodsRegistrar.RegisterPaymentMethod(() => appBuilder.ApplicationServices.GetService());
+
+ settingsRegistrar.RegisterSettingsForType(ModuleConstants.Settings.General.AllGeneralSettings, nameof(DatatransPaymentMethod));
+
+ }
+
+ public void Uninstall()
+ {
+ // Nothing to do here
+ }
+}
diff --git a/src/VirtoCommerce.Datatrans.Web/VirtoCommerce.Datatrans.Web.csproj b/src/VirtoCommerce.Datatrans.Web/VirtoCommerce.Datatrans.Web.csproj
new file mode 100644
index 0000000..553714d
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Web/VirtoCommerce.Datatrans.Web.csproj
@@ -0,0 +1,23 @@
+
+
+ net8.0
+ Library
+ false
+ true
+ 1591
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/VirtoCommerce.Datatrans.Web/module.manifest b/src/VirtoCommerce.Datatrans.Web/module.manifest
new file mode 100644
index 0000000..9b4719f
--- /dev/null
+++ b/src/VirtoCommerce.Datatrans.Web/module.manifest
@@ -0,0 +1,35 @@
+
+
+ VirtoCommerce.Datatrans
+ 3.800.0
+
+
+ 3.904.0
+
+
+
+
+
+
+ VirtoCommerce Datatrans
+ VirtoCommerce Datatrans
+
+
+ Basil Kotov
+
+
+ VirtoCommerce
+
+
+ https://github.com/VirtoCommerce/vc-module-datatrans
+ Modules/$(VirtoCommerce.Datatrans)/Content/logo.png
+ false
+
+ VirtoCommerce.Datatrans.Web.dll
+ VirtoCommerce.Datatrans.Web.Module, VirtoCommerce.Datatrans.Web
+
+ First version.
+ Copyright © 2025 VirtoCommerce. All rights reserved
+ extension module
+ false
+
diff --git a/tests/VirtoCommerce.Datatrans.Tests/Test.cs b/tests/VirtoCommerce.Datatrans.Tests/Test.cs
new file mode 100644
index 0000000..be4d654
--- /dev/null
+++ b/tests/VirtoCommerce.Datatrans.Tests/Test.cs
@@ -0,0 +1,13 @@
+using Xunit;
+
+namespace VirtoCommerce.Datatrans.Tests;
+
+[Trait("Category", "Unit")]
+public class Test
+{
+ [Fact]
+ public void Run_Test()
+ {
+ Assert.Equal(0, 0);
+ }
+}
diff --git a/tests/VirtoCommerce.Datatrans.Tests/VirtoCommerce.Datatrans.Tests.csproj b/tests/VirtoCommerce.Datatrans.Tests/VirtoCommerce.Datatrans.Tests.csproj
new file mode 100644
index 0000000..458e70d
--- /dev/null
+++ b/tests/VirtoCommerce.Datatrans.Tests/VirtoCommerce.Datatrans.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+ net8.0
+ false
+
+
+
+ true
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
+