Browse Source

Merge branch 'main' into tracks-and-sessions

pull/79/head
Berkan Sasmaz 5 years ago
parent
commit
207e417638
  1. 2
      .github/workflows/dotnet.yml
  2. 37
      delete-bin-obj-folders.js
  3. 10
      etc/azure/deploy-to-k8s.yml
  4. 7
      etc/k8s/README.md
  5. 2
      etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql.yaml
  6. 2
      global.json
  7. 1
      modules/payment/.gitattributes
  8. 259
      modules/payment/.gitignore
  9. 5
      modules/payment/.prettierrc
  10. 6
      modules/payment/NuGet.Config
  11. 176
      modules/payment/Payment.sln
  12. 23
      modules/payment/Payment.sln.DotSettings
  13. 97
      modules/payment/README.md
  14. 15
      modules/payment/common.props
  15. 9
      modules/payment/configureawait.props
  16. 6
      modules/payment/global.json
  17. 3
      modules/payment/src/Payment.Admin.Application.Contracts/FodyWeavers.xml
  18. 30
      modules/payment/src/Payment.Admin.Application.Contracts/FodyWeavers.xsd
  19. 17
      modules/payment/src/Payment.Admin.Application.Contracts/Payment.Admin.Application.Contracts.csproj
  20. 17
      modules/payment/src/Payment.Admin.Application.Contracts/PaymentAdminApplicationContractsModule.cs
  21. 7
      modules/payment/src/Payment.Admin.Application.Contracts/PaymentAdminRemoteServiceConsts.cs
  22. 11
      modules/payment/src/Payment.Admin.Application.Contracts/Payments/IPaymentRequestAdminAppService.cs
  23. 17
      modules/payment/src/Payment.Admin.Application.Contracts/Payments/PaymentRequestGetListInput.cs
  24. 24
      modules/payment/src/Payment.Admin.Application.Contracts/Payments/PaymentRequestWithDetailsDto.cs
  25. 20
      modules/payment/src/Payment.Admin.Application.Contracts/Permissions/PaymentAdminPermissionDefinitionProvider.cs
  26. 12
      modules/payment/src/Payment.Admin.Application.Contracts/Permissions/PaymentAdminPermissions.cs
  27. 3
      modules/payment/src/Payment.Admin.Application/FodyWeavers.xml
  28. 30
      modules/payment/src/Payment.Admin.Application/FodyWeavers.xsd
  29. 17
      modules/payment/src/Payment.Admin.Application/Payment.Admin.Application.csproj
  30. 14
      modules/payment/src/Payment.Admin.Application/PaymentAdminApplicationAutoMapperProfile.cs
  31. 25
      modules/payment/src/Payment.Admin.Application/PaymentAdminApplicationModule.cs
  32. 46
      modules/payment/src/Payment.Admin.Application/Payments/PaymentRequestAdminAppService.cs
  33. 3
      modules/payment/src/Payment.Admin.Blazor/FodyWeavers.xml
  34. 30
      modules/payment/src/Payment.Admin.Blazor/FodyWeavers.xsd
  35. 43
      modules/payment/src/Payment.Admin.Blazor/Navigation/PaymentAdminBlazorMenuContributor.cs
  36. 7
      modules/payment/src/Payment.Admin.Blazor/Navigation/PaymentAdminMenuNames.cs
  37. 89
      modules/payment/src/Payment.Admin.Blazor/Pages/Payment/Requests/Index.razor
  38. 82
      modules/payment/src/Payment.Admin.Blazor/Pages/Payment/Requests/Index.razor.cs
  39. 16
      modules/payment/src/Payment.Admin.Blazor/Payment.Admin.Blazor.csproj
  40. 28
      modules/payment/src/Payment.Admin.Blazor/PaymentAdminBlazorModule.cs
  41. 14
      modules/payment/src/Payment.Admin.Blazor/PaymentAdminComponentBase.cs
  42. 6
      modules/payment/src/Payment.Admin.Blazor/_Imports.razor
  43. 26
      modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/PaymentRequestAdminClientProxy.Generated.cs
  44. 8
      modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/PaymentRequestAdminClientProxy.cs
  45. 132
      modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/paymentAdmin-generate-proxy.json
  46. 3
      modules/payment/src/Payment.Admin.HttpApi.Client/FodyWeavers.xml
  47. 30
      modules/payment/src/Payment.Admin.HttpApi.Client/FodyWeavers.xsd
  48. 21
      modules/payment/src/Payment.Admin.HttpApi.Client/Payment.Admin.HttpApi.Client.csproj
  49. 27
      modules/payment/src/Payment.Admin.HttpApi.Client/PaymentAdminHttpApiClientModule.cs
  50. 3
      modules/payment/src/Payment.Admin.HttpApi/FodyWeavers.xml
  51. 30
      modules/payment/src/Payment.Admin.HttpApi/FodyWeavers.xsd
  52. 16
      modules/payment/src/Payment.Admin.HttpApi/Payment.Admin.HttpApi.csproj
  53. 13
      modules/payment/src/Payment.Admin.HttpApi/PaymentAdminController.cs
  54. 34
      modules/payment/src/Payment.Admin.HttpApi/PaymentAdminHttpApiModule.cs
  55. 26
      modules/payment/src/Payment.Admin.HttpApi/Payments/PaymentRequestAdminController.cs
  56. 3
      modules/payment/src/Payment.Application.Contracts/FodyWeavers.xml
  57. 30
      modules/payment/src/Payment.Application.Contracts/FodyWeavers.xsd
  58. 17
      modules/payment/src/Payment.Application.Contracts/Payment.Application.Contracts.csproj
  59. 16
      modules/payment/src/Payment.Application.Contracts/PaymentApplicationContractsModule.cs
  60. 7
      modules/payment/src/Payment.Application.Contracts/PaymentRemoteServiceConsts.cs
  61. 19
      modules/payment/src/Payment.Application.Contracts/PaymentRequests/IPaymentRequestAppService.cs
  62. 32
      modules/payment/src/Payment.Application.Contracts/PaymentRequests/PaymentRequestCreationDto.cs
  63. 29
      modules/payment/src/Payment.Application.Contracts/PaymentRequests/PaymentRequestDto.cs
  64. 18
      modules/payment/src/Payment.Application.Contracts/PaymentRequests/StartPaymentDto.cs
  65. 10
      modules/payment/src/Payment.Application.Contracts/PaymentRequests/StartPaymentResultDto.cs
  66. 19
      modules/payment/src/Payment.Application.Contracts/Permissions/PaymentPermissionDefinitionProvider.cs
  67. 14
      modules/payment/src/Payment.Application.Contracts/Permissions/PaymentPermissions.cs
  68. 12
      modules/payment/src/Payment.Application.Contracts/Samples/ISampleAppService.cs
  69. 7
      modules/payment/src/Payment.Application.Contracts/Samples/SampleDto.cs
  70. 3
      modules/payment/src/Payment.Application/FodyWeavers.xml
  71. 30
      modules/payment/src/Payment.Application/FodyWeavers.xsd
  72. 21
      modules/payment/src/Payment.Application/Payment.Application.csproj
  73. 14
      modules/payment/src/Payment.Application/PaymentAppService.cs
  74. 13
      modules/payment/src/Payment.Application/PaymentApplicationAutoMapperProfile.cs
  75. 41
      modules/payment/src/Payment.Application/PaymentApplicationModule.cs
  76. 173
      modules/payment/src/Payment.Application/PaymentRequests/PaymentRequestAppService.cs
  77. 29
      modules/payment/src/Payment.Application/Samples/SampleAppService.cs
  78. 3
      modules/payment/src/Payment.BackgroundServices/FodyWeavers.xml
  79. 30
      modules/payment/src/Payment.BackgroundServices/FodyWeavers.xsd
  80. 15
      modules/payment/src/Payment.BackgroundServices/Payment.BackgroundServices.csproj
  81. 15
      modules/payment/src/Payment.BackgroundServices/PaymentBackgroundServicesModule.cs
  82. 3
      modules/payment/src/Payment.Domain.Shared/FodyWeavers.xml
  83. 30
      modules/payment/src/Payment.Domain.Shared/FodyWeavers.xsd
  84. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/ar.json
  85. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/cs.json
  86. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/de-DE.json
  87. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/en-GB.json
  88. 36
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/en.json
  89. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/es.json
  90. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/fi.json
  91. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/fr.json
  92. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/hi.json
  93. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/hu.json
  94. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/it.json
  95. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/nl.json
  96. 6
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/pl-PL.json
  97. 6
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/pt-BR.json
  98. 7
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/ro-RO.json
  99. 6
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/sk.json
  100. 6
      modules/payment/src/Payment.Domain.Shared/Localization/Payment/sl.json

2
.github/workflows/dotnet.yml

@ -24,7 +24,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build

37
delete-bin-obj-folders.js

@ -0,0 +1,37 @@
const { resolve } = require("path");
const { readdir, rmdir } = require("fs").promises;
async function* removeFolder(dir) {
await rmdir(dir, { recursive: true });
yield dir;
}
async function* getBinObj(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
if (!dirent.isDirectory()) continue;
const name = dirent.name;
if (name === "node_modules") continue;
const res = resolve(dir, dirent.name);
if (name === "bin" || name === "obj") {
yield* removeFolder(res);
continue;
}
yield* getBinObj(res);
}
}
(async () => {
console.log("\x1b[36m%s\x1b[0m", "Deleting all BIN and OBJ folders...");
for await (const dir of getBinObj(".")) {
console.log("\x1b[33m%s\x1b[0m", `Removed: ${dir}`);
}
console.log("\x1b[36m%s\x1b[0m", "All BIN and OBJ folders are deleted.");
})();

10
etc/azure/deploy-to-k8s.yml

@ -7,6 +7,14 @@ pool:
vmImage: 'ubuntu-latest'
steps:
- task: UseDotNet@2
displayName: 'Use .NET sdk'
inputs:
packageType: sdk
version: 6.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet
includePreviewVersions: true
- task: PowerShell@2
displayName: Build docker images
inputs:
@ -53,4 +61,4 @@ steps:
chartName: 'etc/k8s/helm-chart/eventhub'
releaseName: 'eh-az'
valueFile: 'etc/k8s/helm-chart/eventhub/values.azure.yaml'
arguments: '--namespace eventhub --create-namespace --set global.eventHubImageVersion=$(version)'
arguments: '--timeout 20m --namespace eventhub --create-namespace --set global.eventHubImageVersion=$(version)'

7
etc/k8s/README.md

@ -2,10 +2,11 @@
* Docker Desktop with Kubernetes enabled
* Install [NGINX ingress](https://kubernetes.github.io/ingress-nginx/deploy/) for k8s
* Install [Helm](https://helm.sh/docs/intro/install/) for running helm charts
### How to run?
* Add entries to the hosts file (in Windows: `C:\Windows\System32\drivers\etc\hosts`):
* Add entries to the hosts file (in Windows: `C:\Windows\System32\drivers\etc\hosts`, in MacOs: `/etc/hosts`):
````
127.0.0.1 eh-st-account
@ -16,6 +17,8 @@
````
* Run `build-images.ps1` in the `scripts` directory.
* Run `helm install eh-st eventhub` in the `helm-chart` directory.
* Run `minikube-load-images.ps1` in the `scripts` directory(only for `minikube`).
* Run `deploy-staging.ps1` in the `helm-chart` directory. It is deployed with the `eventhub` namespace.
* *You may wait ~30 seconds on first run for preparing the database*.
* Browse https://eh-st-www and https://eh-st-admin
* Username: `admin`, password: `1q2w3E*`.

2
etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql.yaml

@ -14,7 +14,7 @@ spec:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: postgres
- image: postgres:13-bullseye
name: {{ .Release.Name }}-{{ .Chart.Name }}
{{- if eq .Release.Name "eh-az" }}
volumeMounts:

2
global.json

@ -1,6 +1,6 @@
{
"sdk": {
"version": "5.0.201",
"version": "6.0.100-rc.1.21458.32",
"rollForward": "latestFeature"
}
}

1
modules/payment/.gitattributes

@ -0,0 +1 @@
**/wwwroot/libs/** linguist-vendored

259
modules/payment/.gitignore

@ -0,0 +1,259 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# 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
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.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
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# 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*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: 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
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# 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 ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# 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/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# Payment
host/Payment.IdentityServer/Logs/logs.txt
host/Payment.HttpApi.Host/Logs/logs.txt
host/Payment.Web.Host/Logs/logs.txt
host/Payment.Web.Unified/Logs/logs.txt
host/Payment.Blazor.Server.Host/Logs/logs.txt

5
modules/payment/.prettierrc

@ -0,0 +1,5 @@
{
"singleQuote": true,
"useTabs": false,
"tabWidth": 4
}

6
modules/payment/NuGet.Config

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="BlazoriseMyGet" value="https://www.myget.org/F/blazorise/api/v3/index.json" />
</packageSources>
</configuration>

176
modules/payment/Payment.sln

@ -0,0 +1,176 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31808.319
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Domain.Shared", "src\Payment.Domain.Shared\Payment.Domain.Shared.csproj", "{D64C1577-4929-4B60-939E-96DE1534891A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Domain", "src\Payment.Domain\Payment.Domain.csproj", "{F2840BC7-0188-4606-9126-DADD0F5ABF7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Application.Contracts", "src\Payment.Application.Contracts\Payment.Application.Contracts.csproj", "{BD65D04F-08D5-40C1-8C24-77CA0BACB877}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Application", "src\Payment.Application\Payment.Application.csproj", "{78040F9E-3501-4A40-82DF-00A597710F35}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{649A3FFA-182F-4E56-9717-E6A9A2BEC545}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.EntityFrameworkCore", "src\Payment.EntityFrameworkCore\Payment.EntityFrameworkCore.csproj", "{0CE86223-D31D-4315-A1F5-87BA3EE1B844}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.HttpApi", "src\Payment.HttpApi\Payment.HttpApi.csproj", "{077AA5F8-8B61-420C-A6B5-0150A66FDB34}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.TestBase", "test\Payment.TestBase\Payment.TestBase.csproj", "{C5BB573D-3030-4BCB-88B7-F6A85C32766C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.EntityFrameworkCore.Tests", "test\Payment.EntityFrameworkCore.Tests\Payment.EntityFrameworkCore.Tests.csproj", "{527F645C-C1FC-406E-8479-81386C8ECF13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Domain.Tests", "test\Payment.Domain.Tests\Payment.Domain.Tests.csproj", "{E60895E5-79C4-447D-88B7-85CB5BA336A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Application.Tests", "test\Payment.Application.Tests\Payment.Application.Tests.csproj", "{90CB5DC4-C040-45C7-8900-9688B26405BC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.Web", "src\Payment.Web\Payment.Web.csproj", "{3B7B6317-1B85-4164-8E11-75574F80AE17}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{E46CF089-D16A-4761-BE24-1B1B1D49225A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "www", "www", "{4EF8B98A-E7A3-48A6-9C1F-10DE32001213}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin", "admin", "{5B39D229-146D-423E-9E50-91471851824E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{EFBC83DB-A546-471E-99E4-4948C3ADCAA1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "www", "www", "{D3FD0217-A8C7-4BAF-BF77-962F1B055515}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin", "admin", "{FC718EF0-43EB-4767-9578-95FA0B3727A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.HttpApi.Client", "src\Payment.HttpApi.Client\Payment.HttpApi.Client.csproj", "{3FF65447-69D5-4115-8398-8156FB381215}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Payment.BackgroundServices", "src\Payment.BackgroundServices\Payment.BackgroundServices.csproj", "{98CAA357-46A3-48EC-B5D9-27C706862351}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.Application.Contracts", "src\Payment.Admin.Application.Contracts\Payment.Admin.Application.Contracts.csproj", "{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.Application", "src\Payment.Admin.Application\Payment.Admin.Application.csproj", "{267E26D0-3401-4945-AD58-30FE482566DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.HttpApi", "src\Payment.Admin.HttpApi\Payment.Admin.HttpApi.csproj", "{046100DA-71ED-43C5-8C33-D424D678DBEA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.HttpApi.Client", "src\Payment.Admin.HttpApi.Client\Payment.Admin.HttpApi.Client.csproj", "{A791943D-3F0B-41E3-AE73-15A60180B4A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.Blazor", "src\Payment.Admin.Blazor\Payment.Admin.Blazor.csproj", "{7C6D6C96-0816-43F3-81C8-44CBC18434DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.Admin.Application.Tests", "test\Payment.Admin.Application.Tests\Payment.Admin.Application.Tests.csproj", "{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.Build.0 = Release|Any CPU
{F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.Build.0 = Release|Any CPU
{BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.Build.0 = Release|Any CPU
{78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.Build.0 = Release|Any CPU
{0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.Build.0 = Release|Any CPU
{077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.Build.0 = Release|Any CPU
{C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.Build.0 = Release|Any CPU
{527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.Build.0 = Release|Any CPU
{E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.Build.0 = Release|Any CPU
{90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.Build.0 = Release|Any CPU
{3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.Build.0 = Release|Any CPU
{3FF65447-69D5-4115-8398-8156FB381215}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3FF65447-69D5-4115-8398-8156FB381215}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3FF65447-69D5-4115-8398-8156FB381215}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3FF65447-69D5-4115-8398-8156FB381215}.Release|Any CPU.Build.0 = Release|Any CPU
{98CAA357-46A3-48EC-B5D9-27C706862351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98CAA357-46A3-48EC-B5D9-27C706862351}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98CAA357-46A3-48EC-B5D9-27C706862351}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98CAA357-46A3-48EC-B5D9-27C706862351}.Release|Any CPU.Build.0 = Release|Any CPU
{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75}.Release|Any CPU.Build.0 = Release|Any CPU
{267E26D0-3401-4945-AD58-30FE482566DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{267E26D0-3401-4945-AD58-30FE482566DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{267E26D0-3401-4945-AD58-30FE482566DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{267E26D0-3401-4945-AD58-30FE482566DD}.Release|Any CPU.Build.0 = Release|Any CPU
{046100DA-71ED-43C5-8C33-D424D678DBEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{046100DA-71ED-43C5-8C33-D424D678DBEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{046100DA-71ED-43C5-8C33-D424D678DBEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{046100DA-71ED-43C5-8C33-D424D678DBEA}.Release|Any CPU.Build.0 = Release|Any CPU
{A791943D-3F0B-41E3-AE73-15A60180B4A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A791943D-3F0B-41E3-AE73-15A60180B4A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A791943D-3F0B-41E3-AE73-15A60180B4A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A791943D-3F0B-41E3-AE73-15A60180B4A5}.Release|Any CPU.Build.0 = Release|Any CPU
{7C6D6C96-0816-43F3-81C8-44CBC18434DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C6D6C96-0816-43F3-81C8-44CBC18434DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C6D6C96-0816-43F3-81C8-44CBC18434DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C6D6C96-0816-43F3-81C8-44CBC18434DE}.Release|Any CPU.Build.0 = Release|Any CPU
{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D64C1577-4929-4B60-939E-96DE1534891A} = {E46CF089-D16A-4761-BE24-1B1B1D49225A}
{F2840BC7-0188-4606-9126-DADD0F5ABF7A} = {E46CF089-D16A-4761-BE24-1B1B1D49225A}
{BD65D04F-08D5-40C1-8C24-77CA0BACB877} = {4EF8B98A-E7A3-48A6-9C1F-10DE32001213}
{78040F9E-3501-4A40-82DF-00A597710F35} = {4EF8B98A-E7A3-48A6-9C1F-10DE32001213}
{0CE86223-D31D-4315-A1F5-87BA3EE1B844} = {E46CF089-D16A-4761-BE24-1B1B1D49225A}
{077AA5F8-8B61-420C-A6B5-0150A66FDB34} = {4EF8B98A-E7A3-48A6-9C1F-10DE32001213}
{C5BB573D-3030-4BCB-88B7-F6A85C32766C} = {EFBC83DB-A546-471E-99E4-4948C3ADCAA1}
{527F645C-C1FC-406E-8479-81386C8ECF13} = {EFBC83DB-A546-471E-99E4-4948C3ADCAA1}
{E60895E5-79C4-447D-88B7-85CB5BA336A4} = {EFBC83DB-A546-471E-99E4-4948C3ADCAA1}
{90CB5DC4-C040-45C7-8900-9688B26405BC} = {D3FD0217-A8C7-4BAF-BF77-962F1B055515}
{3B7B6317-1B85-4164-8E11-75574F80AE17} = {4EF8B98A-E7A3-48A6-9C1F-10DE32001213}
{E46CF089-D16A-4761-BE24-1B1B1D49225A} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{4EF8B98A-E7A3-48A6-9C1F-10DE32001213} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{5B39D229-146D-423E-9E50-91471851824E} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{EFBC83DB-A546-471E-99E4-4948C3ADCAA1} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}
{D3FD0217-A8C7-4BAF-BF77-962F1B055515} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}
{FC718EF0-43EB-4767-9578-95FA0B3727A5} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}
{3FF65447-69D5-4115-8398-8156FB381215} = {4EF8B98A-E7A3-48A6-9C1F-10DE32001213}
{98CAA357-46A3-48EC-B5D9-27C706862351} = {E46CF089-D16A-4761-BE24-1B1B1D49225A}
{B4D6C73B-2848-4B0C-BFA5-7EBEA59F6A75} = {5B39D229-146D-423E-9E50-91471851824E}
{267E26D0-3401-4945-AD58-30FE482566DD} = {5B39D229-146D-423E-9E50-91471851824E}
{046100DA-71ED-43C5-8C33-D424D678DBEA} = {5B39D229-146D-423E-9E50-91471851824E}
{A791943D-3F0B-41E3-AE73-15A60180B4A5} = {5B39D229-146D-423E-9E50-91471851824E}
{7C6D6C96-0816-43F3-81C8-44CBC18434DE} = {5B39D229-146D-423E-9E50-91471851824E}
{E31DBDFE-1CC7-4E1B-B65C-C3810BF85981} = {FC718EF0-43EB-4767-9578-95FA0B3727A5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6AAFA1C6-603E-13FA-45E5-7910AA9F661D}
EndGlobalSection
EndGlobal

23
modules/payment/Payment.sln.DotSettings

@ -0,0 +1,23 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/UpgradedFromVSSettings/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceDoWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceFixedStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForeachStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceForStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceLockStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Mutable/@EntryIndexedValue">False</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String>
</wpf:ResourceDictionary>

97
modules/payment/README.md

@ -0,0 +1,97 @@
# Payment Module
Payment module provides an API to make payments via using PayPal easily.
## Installation
TODO
## Usage
1. Create a Payment Request via using `IPaymentRequestAppService`
2. Build an URL to redirect to checkout page via using `IPaymentUrlBuilder`
```csharp
public class MyPageModel : AbpPageModel
{
protected IPaymentRequestAppService PaymentRequestAppService { get; }
protected IPaymentUrlBuilder PaymentUrlBuilder { get; }
public MyPageModel(
IPaymentRequestAppService paymentRequestAppService,
IPaymentUrlBuilder paymentUrlBuilder)
{
PaymentRequestAppService = paymentRequestAppService;
PaymentUrlBuilder = paymentUrlBuilder;
}
public async Task OnPostAsync()
{
var paymentRequest = await PaymentRequestAppService.CreateAsync(new PaymentRequestCreationDto
{
Amount = 9.90m,
CustomerId = CurrentUser.Id.ToString(),
ProductId = "UniqueProductId",
ProductName = "Awesome Product"
});
var checkoutUrl = PaymentUrlBuilder.BuildCheckoutUrl(paymentRequest.Id).AbsoluteUri;
Response.Redirect(checkoutUrl);
}
}
```
---
## Distributed Events
- `Payment.Completed` (**PaymentRequestCompletedEto**): Published when a payment is completed. Completion can be triggered via webhook or callback. Source doesn't affect to the event. Event will be triggered once.
- `PaymentRequestId`: Represents PaymentRequest entity Id.
- `ExtraProperties`: Represents ExtraProperties of PaymentRequest entity. You can use this properties to find your related objects to that payment.
- `Payment.Failed`(**PaymentRequestFailedEto**): Published when a payment is failed.
- `PaymentRequestId`: Represents PaymentRequest entity Id.
- `FailReason`: Reason of failure from payment provider (PayPal)
- `ExtraProperties`: Represents ExtraProperties of PaymentRequest entity.
## Webhook Handling
You have to make some configuration for webhooks on PayPal Dashboard.
_If you test it locally, you can use [ngrok](https://ngrok.com/) to open your localhost to world_
0. Deploy eventhub or open your ip:port to public. Your HttpApi.Host must be accessible from all over the world.
1. Go to [Application List](https://developer.paypal.com/developer/applications). Find your app and go details. _(You can use my account below)_
<details>
<summary>PayPal Account Credentials</summary>
> `info@enisnecipoglu.com`
> `1q2w3E**`
> Use following temp number for two factor authentication verification:
> https://receive-smss.com/sms/48722717428/
> _(Yes the star (*) is doubled. min password length requirement was 8)_
</details>
2. At the bottom of page you'll see the Webhooks section
![image](https://user-images.githubusercontent.com/23705418/138262017-b2c3a689-f929-4dbb-8927-04ab9a2c5292.png)
3. Click to **Add Webhook** button and use following values:
- **Webhook URL**: `https://yourhttpapihosturl.com/api/payment/requests/webhook` _(replace hostname with your API public url)_
- **Event types**: `Checkout order approved`, `Checkout order completed`

15
modules/payment/common.props

@ -0,0 +1,15 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>0.1.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AbpProjectType>module</AbpProjectType>
</PropertyGroup>
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target>
</Project>

9
modules/payment/configureawait.props

@ -0,0 +1,9 @@
<Project>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.5.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

6
modules/payment/global.json

@ -0,0 +1,6 @@
{
"sdk": {
"version": "6.0",
"rollForward": "latestFeature"
}
}

3
modules/payment/src/Payment.Admin.Application.Contracts/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Admin.Application.Contracts/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

17
modules/payment/src/Payment.Admin.Application.Contracts/Payment.Admin.Application.Contracts.csproj

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment.Admin</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="5.0.0-beta.1" />
<PackageReference Include="Volo.Abp.Authorization" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Domain.Shared\Payment.Domain.Shared.csproj" />
</ItemGroup>
</Project>

17
modules/payment/src/Payment.Admin.Application.Contracts/PaymentAdminApplicationContractsModule.cs

@ -0,0 +1,17 @@
using System;
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
namespace Payment.Admin
{
[DependsOn(
typeof(PaymentDomainSharedModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]
public class PaymentAdminApplicationContractsModule : AbpModule
{
}
}

7
modules/payment/src/Payment.Admin.Application.Contracts/PaymentAdminRemoteServiceConsts.cs

@ -0,0 +1,7 @@
namespace Payment.Admin
{
public class PaymentAdminRemoteServiceConsts
{
public const string RemoteServiceName = "PaymentAdmin";
}
}

11
modules/payment/src/Payment.Admin.Application.Contracts/Payments/IPaymentRequestAdminAppService.cs

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Payment.Admin.Payments
{
public interface IPaymentRequestAdminAppService : IApplicationService
{
Task<PagedResultDto<PaymentRequestWithDetailsDto>> GetListAsync(PaymentRequestGetListInput input);
}
}

17
modules/payment/src/Payment.Admin.Application.Contracts/Payments/PaymentRequestGetListInput.cs

@ -0,0 +1,17 @@
using System;
using Payment.PaymentRequests;
using Volo.Abp.Application.Dtos;
namespace Payment.Admin.Payments
{
public class PaymentRequestGetListInput : PagedAndSortedResultRequestDto
{
public string ProductName { get; set; }
public DateTime? MaxCreationTime { get; set; }
public DateTime? MinCreationTime { get; set; }
public PaymentRequestState? Status { get; set; }
}
}

24
modules/payment/src/Payment.Admin.Application.Contracts/Payments/PaymentRequestWithDetailsDto.cs

@ -0,0 +1,24 @@
using System;
using Payment.PaymentRequests;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
namespace Payment.Admin.Payments
{
public class PaymentRequestWithDetailsDto : ExtensibleEntityDto<Guid>, IHasCreationTime
{
public string CustomerId { get; set; }
public string ProductName { get; set; }
public float Price { get; set; }
public string Currency { get; set; }
public PaymentRequestState State { get; set; }
public string FailReason { get; set; }
public DateTime CreationTime { get; }
}
}

20
modules/payment/src/Payment.Admin.Application.Contracts/Permissions/PaymentAdminPermissionDefinitionProvider.cs

@ -0,0 +1,20 @@
using Payment.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace Payment.Admin.Permissions
{
public class PaymentAdminPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var paymentGroup = context.AddGroup(PaymentAdminPermissions.GroupName, L("Permission:PaymentManagement"));
paymentGroup.AddPermission(PaymentAdminPermissions.Request.Default, L("Permission:PaymentRequest"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<PaymentResource>(name);
}
}
}

12
modules/payment/src/Payment.Admin.Application.Contracts/Permissions/PaymentAdminPermissions.cs

@ -0,0 +1,12 @@
namespace Payment.Admin.Permissions
{
public class PaymentAdminPermissions
{
public const string GroupName = "PaymentAdmin";
public static class Request
{
public const string Default = GroupName + ".Request";
}
}
}

3
modules/payment/src/Payment.Admin.Application/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Admin.Application/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

17
modules/payment/src/Payment.Admin.Application/Payment.Admin.Application.csproj

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment.Admin</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="5.0.0-beta.1" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Admin.Application.Contracts\Payment.Admin.Application.Contracts.csproj" />
<ProjectReference Include="..\Payment.Domain\Payment.Domain.csproj" />
</ItemGroup>
</Project>

14
modules/payment/src/Payment.Admin.Application/PaymentAdminApplicationAutoMapperProfile.cs

@ -0,0 +1,14 @@
using AutoMapper;
using Payment.Admin.Payments;
using Payment.PaymentRequests;
namespace Payment.Admin
{
public class PaymentAdminApplicationAutoMapperProfile : Profile
{
public PaymentAdminApplicationAutoMapperProfile()
{
CreateMap<PaymentRequest, PaymentRequestWithDetailsDto>();
}
}
}

25
modules/payment/src/Payment.Admin.Application/PaymentAdminApplicationModule.cs

@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Payment.Admin
{
[DependsOn(
typeof(PaymentDomainModule),
typeof(PaymentAdminApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
public class PaymentAdminApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<PaymentAdminApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<PaymentAdminApplicationAutoMapperProfile>(validate: true);
});
}
}
}

46
modules/payment/src/Payment.Admin.Application/Payments/PaymentRequestAdminAppService.cs

@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Payment.Admin.Permissions;
using Payment.PaymentRequests;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Payment.Admin.Payments
{
[Authorize(PaymentAdminPermissions.Request.Default)]
public class PaymentRequestAdminAppService : ApplicationService, IPaymentRequestAdminAppService
{
protected IPaymentRequestRepository PaymentRequestRepository { get; }
public PaymentRequestAdminAppService(IPaymentRequestRepository paymentRequestRepository)
{
PaymentRequestRepository = paymentRequestRepository;
}
public async Task<PagedResultDto<PaymentRequestWithDetailsDto>> GetListAsync(PaymentRequestGetListInput input)
{
var paymentRequests = await PaymentRequestRepository.GetListAsync(
input.SkipCount,
input.MaxResultCount,
input.Sorting,
input.ProductName,
input.MaxCreationTime,
input.MinCreationTime,
input.Status
);
var totalCount = await PaymentRequestRepository.GetCountAsync(
input.ProductName,
input.MaxCreationTime,
input.MinCreationTime,
input.Status
);
return new PagedResultDto<PaymentRequestWithDetailsDto>(
totalCount,
ObjectMapper.Map<List<PaymentRequest>, List<PaymentRequestWithDetailsDto>>(paymentRequests)
);
}
}
}

3
modules/payment/src/Payment.Admin.Blazor/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Admin.Blazor/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

43
modules/payment/src/Payment.Admin.Blazor/Navigation/PaymentAdminBlazorMenuContributor.cs

@ -0,0 +1,43 @@
using System.Threading.Tasks;
using Payment.Admin.Permissions;
using Payment.Localization;
using Volo.Abp.UI.Navigation;
namespace Payment.Admin.Navigation
{
public class PaymentAdminBlazorMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
await AddPaymentMenuAsync(context);
}
private Task AddPaymentMenuAsync(MenuConfigurationContext context)
{
var l = context.GetLocalizer<PaymentResource>();
var paymentMenu = context.Menu.FindMenuItem(PaymentAdminMenuNames.GroupName);
if (paymentMenu == null)
{
paymentMenu = new ApplicationMenuItem(
PaymentAdminMenuNames.GroupName,
l["Menu:PaymentManagement"],
icon: "fa fa-money-check",
url: "/payment/requests",
requiredPermissionName: PaymentAdminPermissions.Request.Default
);
}
context.Menu.AddItem(paymentMenu);
return Task.CompletedTask;
}
}
}

7
modules/payment/src/Payment.Admin.Blazor/Navigation/PaymentAdminMenuNames.cs

@ -0,0 +1,7 @@
namespace Payment.Admin.Navigation
{
public static class PaymentAdminMenuNames
{
public const string GroupName = "Payment";
}
}

89
modules/payment/src/Payment.Admin.Blazor/Pages/Payment/Requests/Index.razor

@ -0,0 +1,89 @@
@page "/Payment/Requests"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(PaymentAdminPermissions.Request.Default)]
@using global::Payment.Admin.Payments
@using global::Payment.PaymentRequests
@using global::Payment.Admin.Permissions
@using Volo.Abp.BlazoriseUI.Components.ObjectExtending
@inherits PaymentAdminComponentBase
<Card>
<CardHeader>
<h2>@L["PaymentRequests"]</h2>
</CardHeader>
<CardBody>
<Form>
<div id="FilterSection" class="row mt-3">
<Field ColumnSize="ColumnSize.Is3">
<FieldLabel>@L["ProductName"]</FieldLabel>
<TextEdit Placeholder="@L["ProductName"]" @bind-Text="@GetListInput.ProductName"/>
</Field>
<Field ColumnSize="ColumnSize.Is3">
<FieldLabel>@L["Status"]</FieldLabel>
<Select Placeholder="@L["Status"]" TValue="PaymentRequestState?" SelectedValue="@GetListInput.Status" SelectedValueChanged="OnPaymentRequestStateChanged">
<option value="@((PaymentRequestState?) null)">-</option>
@foreach (var item in PaymentRequestStates)
{
<SelectItem Value="@item">@L["Enum:PaymentRequestState:" + item]</SelectItem>
}
</Select>
</Field>
<Field ColumnSize="ColumnSize.Is3">
<FieldLabel>@L["MinCreationTime"]</FieldLabel>
<DateEdit Placeholder="@L["MinCreationTime"]" @bind-Date="@GetListInput.MinCreationTime"/>
</Field>
<Field ColumnSize="ColumnSize.Is3">
<FieldLabel>@L["MaxCreationTime"]</FieldLabel>
<DateEdit Placeholder="@L["MaxCreationTime"]" @bind-Date="@GetListInput.MaxCreationTime"/>
</Field>
<Field ColumnSize="ColumnSize.Is12">
<Row>
<Column ColumnSize="ColumnSize.Is9"></Column>
<Column ColumnSize="ColumnSize.Is3">
<SubmitButton Block="true"
Clicked="@GetPaymentRequestsAsync">
<Icon Name="IconName.Search" />
</SubmitButton>
</Column>
</Row>
</Field>
</div>
</Form>
<DataGrid TItem="PaymentRequestWithDetailsDto"
Data="PaymentRequests"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize"
Responsive="true">
<DataGridColumns>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="ProductName"
Caption="@L["ProductName"]">
</DataGridColumn>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="Currency"
Caption="@L["Currency"]">
</DataGridColumn>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="Price"
Caption="@L["Price"]">
</DataGridColumn>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="State"
Caption="@L["State"]">
</DataGridColumn>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="FailReason"
Caption="@L["FailReason"]">
</DataGridColumn>
<DataGridColumn TItem="PaymentRequestWithDetailsDto"
Field="CreationTime"
Caption="@L["CreationTime"]">
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>

82
modules/payment/src/Payment.Admin.Blazor/Pages/Payment/Requests/Index.razor.cs

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blazorise;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
using Payment.Admin.Payments;
using Volo.Abp.Application.Dtos;
using Payment.PaymentRequests;
namespace Payment.Admin.Pages.Payment.Requests
{
public partial class Index
{
[Inject]
protected IPaymentRequestAdminAppService PaymentRequestAdminAppService { get; set; }
protected IReadOnlyList<PaymentRequestWithDetailsDto> PaymentRequests { get; set; }
protected IReadOnlyList<PaymentRequestState> PaymentRequestStates => Enum.GetValues<PaymentRequestState>();
protected PaymentRequestGetListInput GetListInput { get; set; }
protected virtual int PageSize { get; } = LimitedResultRequestDto.DefaultMaxResultCount;
protected int CurrentPage { get; set; } = 1;
protected string CurrentSorting { get; set; }
protected int? TotalCount { get; set; }
public Index()
{
GetListInput = new();
}
protected override async Task OnInitializedAsync()
{
await GetPaymentRequestsAsync();
await InvokeAsync(StateHasChanged);
}
protected virtual async Task GetPaymentRequestsAsync()
{
try
{
GetListInput.Sorting = CurrentSorting;
GetListInput.SkipCount = (CurrentPage - 1) * PageSize;
GetListInput.MaxResultCount = PageSize;
var result = await PaymentRequestAdminAppService.GetListAsync(GetListInput);
PaymentRequests = result.Items.As<IReadOnlyList<PaymentRequestWithDetailsDto>>();
TotalCount = (int?) result.TotalCount;
await InvokeAsync(StateHasChanged);
}
catch (Exception ex)
{
await HandleErrorAsync(ex);
}
}
protected virtual async Task OnDataGridReadAsync(DataGridReadDataEventArgs<PaymentRequestWithDetailsDto> e)
{
CurrentSorting = e.Columns
.Where(c => c.SortDirection != SortDirection.None)
.Select(c => c.Field + (c.SortDirection == SortDirection.Descending ? " DESC" : ""))
.JoinAsString(",");
CurrentPage = e.Page;
await GetPaymentRequestsAsync();
await InvokeAsync(StateHasChanged);
}
private async Task OnPaymentRequestStateChanged(PaymentRequestState? status)
{
GetListInput.Status = status;
await GetPaymentRequestsAsync();
}
}
}

16
modules/payment/src/Payment.Admin.Blazor/Payment.Admin.Blazor.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Payment.Admin</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly.Theming" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Admin.HttpApi.Client\Payment.Admin.HttpApi.Client.csproj" />
</ItemGroup>
</Project>

28
modules/payment/src/Payment.Admin.Blazor/PaymentAdminBlazorModule.cs

@ -0,0 +1,28 @@
using Payment.Admin.Navigation;
using Volo.Abp.AspNetCore.Components.Web.Theming.Routing;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
namespace Payment.Admin
{
[DependsOn(
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule),
typeof(PaymentAdminHttpApiClientModule)
)]
public class PaymentAdminBlazorModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new PaymentAdminBlazorMenuContributor());
});
Configure<AbpRouterOptions>(options =>
{
options.AdditionalAssemblies.Add(typeof(PaymentAdminBlazorModule).Assembly);
});
}
}
}

14
modules/payment/src/Payment.Admin.Blazor/PaymentAdminComponentBase.cs

@ -0,0 +1,14 @@
using Payment.Localization;
using Volo.Abp.AspNetCore.Components;
namespace Payment.Admin
{
public abstract class PaymentAdminComponentBase : AbpComponentBase
{
protected PaymentAdminComponentBase()
{
LocalizationResource = typeof(PaymentResource);
ObjectMapperContext = typeof(PaymentAdminBlazorModule);
}
}
}

6
modules/payment/src/Payment.Admin.Blazor/_Imports.razor

@ -0,0 +1,6 @@
@using Microsoft.AspNetCore.Components.Web
@using Volo.Abp.AspNetCore.Components.Web
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.BlazoriseUI.Components
@using Blazorise
@using Blazorise.DataGrid

26
modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/PaymentRequestAdminClientProxy.Generated.cs

@ -0,0 +1,26 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying;
using Payment.Admin.Payments;
// ReSharper disable once CheckNamespace
namespace Payment.Admin.Payments.ClientProxies
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IPaymentRequestAdminAppService), typeof(PaymentRequestAdminClientProxy))]
public partial class PaymentRequestAdminClientProxy : ClientProxyBase<IPaymentRequestAdminAppService>, IPaymentRequestAdminAppService
{
public virtual async Task<PagedResultDto<PaymentRequestWithDetailsDto>> GetListAsync(PaymentRequestGetListInput input)
{
return await RequestAsync<PagedResultDto<PaymentRequestWithDetailsDto>>(nameof(GetListAsync), new ClientProxyRequestTypeValue
{
{ typeof(PaymentRequestGetListInput), input }
});
}
}
}

8
modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/PaymentRequestAdminClientProxy.cs

@ -0,0 +1,8 @@
// This file is part of PaymentRequestAdminClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Payment.Admin.Payments.ClientProxies
{
public partial class PaymentRequestAdminClientProxy
{
}
}

132
modules/payment/src/Payment.Admin.HttpApi.Client/ClientProxies/paymentAdmin-generate-proxy.json

@ -0,0 +1,132 @@
{
"modules": {
"paymentAdmin": {
"rootPath": "paymentAdmin",
"remoteServiceName": "PaymentAdmin",
"controllers": {
"Payment.Admin.Payments.PaymentRequestAdminController": {
"controllerName": "PaymentRequestAdmin",
"controllerGroupName": "PaymentRequestAdmin",
"type": "Payment.Admin.Payments.PaymentRequestAdminController",
"interfaces": [
{
"type": "Payment.Admin.Payments.IPaymentRequestAdminAppService"
}
],
"actions": {
"GetListAsyncByInput": {
"uniqueName": "GetListAsyncByInput",
"name": "GetListAsync",
"httpMethod": "GET",
"url": "api/payment/requests",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Payment.Admin.Payments.PaymentRequestGetListInput, Payment.Admin.Application.Contracts",
"type": "Payment.Admin.Payments.PaymentRequestGetListInput",
"typeSimple": "Payment.Admin.Payments.PaymentRequestGetListInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProductName",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "MaxCreationTime",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "MinCreationTime",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Status",
"jsonName": null,
"type": "Payment.PaymentRequests.PaymentRequestState?",
"typeSimple": "Payment.PaymentRequests.PaymentRequestState?",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Sorting",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "SkipCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "MaxResultCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.PagedResultDto<Payment.Admin.Payments.PaymentRequestWithDetailsDto>",
"typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto<Payment.Admin.Payments.PaymentRequestWithDetailsDto>"
},
"allowAnonymous": null,
"implementFrom": "Payment.Admin.Payments.IPaymentRequestAdminAppService"
}
}
}
}
}
},
"types": {}
}

3
modules/payment/src/Payment.Admin.HttpApi.Client/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Admin.HttpApi.Client/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
modules/payment/src/Payment.Admin.HttpApi.Client/Payment.Admin.HttpApi.Client.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment.Admin</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Http.Client" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Admin.Application.Contracts\Payment.Admin.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="**\*generate-proxy.json" />
<Content Remove="**\*generate-proxy.json" />
</ItemGroup>
</Project>

27
modules/payment/src/Payment.Admin.HttpApi.Client/PaymentAdminHttpApiClientModule.cs

@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Payment.Admin
{
[DependsOn(
typeof(PaymentAdminApplicationContractsModule),
typeof(AbpHttpClientModule)
)]
public class PaymentAdminHttpApiClientModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddStaticHttpClientProxies(
typeof(PaymentAdminApplicationContractsModule).Assembly,
PaymentAdminRemoteServiceConsts.RemoteServiceName
);
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<PaymentAdminHttpApiClientModule>();
});
}
}
}

3
modules/payment/src/Payment.Admin.HttpApi/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Admin.HttpApi/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

16
modules/payment/src/Payment.Admin.HttpApi/Payment.Admin.HttpApi.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Payment.Admin</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Admin.Application.Contracts\Payment.Admin.Application.Contracts.csproj" />
</ItemGroup>
</Project>

13
modules/payment/src/Payment.Admin.HttpApi/PaymentAdminController.cs

@ -0,0 +1,13 @@
using Payment.Localization;
using Volo.Abp.AspNetCore.Mvc;
namespace Payment.Admin
{
public abstract class PaymentAdminController : AbpControllerBase
{
protected PaymentAdminController()
{
LocalizationResource = typeof(PaymentResource);
}
}
}

34
modules/payment/src/Payment.Admin.HttpApi/PaymentAdminHttpApiModule.cs

@ -0,0 +1,34 @@
using Localization.Resources.AbpUi;
using Microsoft.Extensions.DependencyInjection;
using Payment.Localization;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace Payment.Admin
{
[DependsOn(
typeof(PaymentAdminApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule)
)]
public class PaymentAdminHttpApiModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(PaymentAdminHttpApiModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<PaymentResource>()
.AddBaseTypes(typeof(AbpUiResource));
});
}
}
}

26
modules/payment/src/Payment.Admin.HttpApi/Payments/PaymentRequestAdminController.cs

@ -0,0 +1,26 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace Payment.Admin.Payments
{
[RemoteService(Name = PaymentAdminRemoteServiceConsts.RemoteServiceName)]
[Area("paymentAdmin")]
[Route("api/payment/requests")]
public class PaymentRequestAdminController : PaymentAdminController, IPaymentRequestAdminAppService
{
protected IPaymentRequestAdminAppService PaymentRequestAdminAppService { get; }
public PaymentRequestAdminController(IPaymentRequestAdminAppService paymentRequestAdminAppService)
{
PaymentRequestAdminAppService = paymentRequestAdminAppService;
}
[HttpGet]
public Task<PagedResultDto<PaymentRequestWithDetailsDto>> GetListAsync(PaymentRequestGetListInput input)
{
return PaymentRequestAdminAppService.GetListAsync(input);
}
}
}

3
modules/payment/src/Payment.Application.Contracts/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Application.Contracts/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

17
modules/payment/src/Payment.Application.Contracts/Payment.Application.Contracts.csproj

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="5.0.0-beta.1" />
<PackageReference Include="Volo.Abp.Authorization" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Domain.Shared\Payment.Domain.Shared.csproj" />
</ItemGroup>
</Project>

16
modules/payment/src/Payment.Application.Contracts/PaymentApplicationContractsModule.cs

@ -0,0 +1,16 @@
using Volo.Abp.Application;
using Volo.Abp.Modularity;
using Volo.Abp.Authorization;
namespace Payment
{
[DependsOn(
typeof(PaymentDomainSharedModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]
public class PaymentApplicationContractsModule : AbpModule
{
}
}

7
modules/payment/src/Payment.Application.Contracts/PaymentRemoteServiceConsts.cs

@ -0,0 +1,7 @@
namespace Payment
{
public class PaymentRemoteServiceConsts
{
public const string RemoteServiceName = "Payment";
}
}

19
modules/payment/src/Payment.Application.Contracts/PaymentRequests/IPaymentRequestAppService.cs

@ -0,0 +1,19 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace Payment.PaymentRequests
{
public interface IPaymentRequestAppService : IApplicationService
{
Task<PaymentRequestDto> GetAsync(Guid id);
Task<PaymentRequestDto> CreateAsync(PaymentRequestCreationDto input);
Task<StartPaymentResultDto> StartPaymentAsync(StartPaymentDto input);
Task<PaymentRequestDto> CompleteAsync(string token);
Task<bool> HandleWebhookAsync(string payload);
}
}

32
modules/payment/src/Payment.Application.Contracts/PaymentRequests/PaymentRequestCreationDto.cs

@ -0,0 +1,32 @@
using JetBrains.Annotations;
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Validation;
namespace Payment.PaymentRequests
{
[Serializable]
public class PaymentRequestCreationDto : ExtensibleObject
{
[DynamicMaxLength(typeof(PaymentRequestConsts), nameof(PaymentRequestConsts.MaxCustomerIdLength))]
public string CustomerId { get; set; }
[DynamicMaxLength(typeof(PaymentRequestConsts), nameof(PaymentRequestConsts.MaxProductIdLength))]
public string ProductId { get; set; }
[Required]
[DynamicMaxLength(typeof(PaymentRequestConsts), nameof(PaymentRequestConsts.MaxProductNameLength))]
public string ProductName { get; set; }
public decimal Price { get; set; }
/// <summary>
/// 3 Letter Language Code in ISO 4217 Standards.
/// For example: USD, EUR.
/// </summary>
[StringLength(PaymentRequestConsts.MaxCurrencyLength)]
[CanBeNull]
public string Currency { get; set; }
}
}

29
modules/payment/src/Payment.Application.Contracts/PaymentRequests/PaymentRequestDto.cs

@ -0,0 +1,29 @@
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
namespace Payment.PaymentRequests
{
[Serializable]
public class PaymentRequestDto : CreationAuditedEntityDto<Guid>, IHasExtraProperties
{
public string CustomerId { get; set; }
public string ProductId { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public string Currency { get; set; }
public PaymentRequestState State { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public PaymentRequestDto()
{
ExtraProperties = new ExtraPropertyDictionary();
}
}
}

18
modules/payment/src/Payment.Application.Contracts/PaymentRequests/StartPaymentDto.cs

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using System;
using System.ComponentModel.DataAnnotations;
namespace Payment.PaymentRequests
{
[Serializable]
public class StartPaymentDto
{
public Guid PaymentRequestId { get; set; }
[NotNull]
[Required]
public string ReturnUrl { get; set; }
public string CancelUrl { get; set; }
}
}

10
modules/payment/src/Payment.Application.Contracts/PaymentRequests/StartPaymentResultDto.cs

@ -0,0 +1,10 @@
using System;
namespace Payment.PaymentRequests
{
[Serializable]
public class StartPaymentResultDto
{
public string CheckoutLink { get; set; }
}
}

19
modules/payment/src/Payment.Application.Contracts/Permissions/PaymentPermissionDefinitionProvider.cs

@ -0,0 +1,19 @@
using Payment.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace Payment.Permissions
{
public class PaymentPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup(PaymentPermissions.GroupName, L("Permission:Payment"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<PaymentResource>(name);
}
}
}

14
modules/payment/src/Payment.Application.Contracts/Permissions/PaymentPermissions.cs

@ -0,0 +1,14 @@
using Volo.Abp.Reflection;
namespace Payment.Permissions
{
public class PaymentPermissions
{
public const string GroupName = "Payment";
public static string[] GetAll()
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(PaymentPermissions));
}
}
}

12
modules/payment/src/Payment.Application.Contracts/Samples/ISampleAppService.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace Payment.Samples
{
public interface ISampleAppService : IApplicationService
{
Task<SampleDto> GetAsync();
Task<SampleDto> GetAuthorizedAsync();
}
}

7
modules/payment/src/Payment.Application.Contracts/Samples/SampleDto.cs

@ -0,0 +1,7 @@
namespace Payment.Samples
{
public class SampleDto
{
public int Value { get; set; }
}
}

3
modules/payment/src/Payment.Application/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Application/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
modules/payment/src/Payment.Application/Payment.Application.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="5.0.0-beta.1" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="5.0.0-beta.1" />
<ProjectReference Include="..\Payment.Application.Contracts\Payment.Application.Contracts.csproj" />
<ProjectReference Include="..\Payment.Domain\Payment.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="PayPalCheckoutSdk" Version="1.0.4" />
</ItemGroup>
</Project>

14
modules/payment/src/Payment.Application/PaymentAppService.cs

@ -0,0 +1,14 @@
using Payment.Localization;
using Volo.Abp.Application.Services;
namespace Payment
{
public abstract class PaymentAppService : ApplicationService
{
protected PaymentAppService()
{
LocalizationResource = typeof(PaymentResource);
ObjectMapperContext = typeof(PaymentApplicationModule);
}
}
}

13
modules/payment/src/Payment.Application/PaymentApplicationAutoMapperProfile.cs

@ -0,0 +1,13 @@
using AutoMapper;
using Payment.PaymentRequests;
namespace Payment
{
public class PaymentApplicationAutoMapperProfile : Profile
{
public PaymentApplicationAutoMapperProfile()
{
CreateMap<PaymentRequest, PaymentRequestDto>();
}
}
}

41
modules/payment/src/Payment.Application/PaymentApplicationModule.cs

@ -0,0 +1,41 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.Application;
using Microsoft.Extensions.Options;
using Payment.PayPal;
using System;
using PayPalCheckoutSdk.Core;
namespace Payment
{
[DependsOn(
typeof(PaymentDomainModule),
typeof(PaymentApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
public class PaymentApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<PaymentApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<PaymentApplicationModule>(validate: true);
});
context.Services.AddTransient(provider =>
{
var options = provider.GetService<IOptions<PayPalOptions>>().Value;
if (options.Environment.IsNullOrWhiteSpace() || options.Environment == PayPalConsts.Environment.Sandbox)
{
return new PayPalHttpClient(new SandboxEnvironment(options.ClientId, options.Secret));
}
return new PayPalHttpClient(new LiveEnvironment(options.ClientId, options.Secret));
});
}
}
}

173
modules/payment/src/Payment.Application/PaymentRequests/PaymentRequestAppService.cs

@ -0,0 +1,173 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Payment.PayPal;
using PayPalCheckoutSdk.Core;
using PayPalCheckoutSdk.Orders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Payment.PaymentRequests
{
public class PaymentRequestAppService : PaymentAppService, IPaymentRequestAppService
{
protected readonly IPaymentRequestRepository _paymentRequestRepository;
protected readonly PaymentOptions _paymentOptions;
protected readonly PayPalHttpClient _payPalHttpClient;
public PaymentRequestAppService(
IPaymentRequestRepository paymentRequestRepository,
IOptions<PaymentOptions> paymentOptions,
PayPalHttpClient payPalHttpClient)
{
_paymentRequestRepository = paymentRequestRepository;
_paymentOptions = paymentOptions.Value;
_payPalHttpClient = payPalHttpClient;
}
public async Task<PaymentRequestDto> GetAsync(Guid id)
{
var paymentRequest = await _paymentRequestRepository.GetAsync(id);
return ObjectMapper.Map<PaymentRequest, PaymentRequestDto>(paymentRequest);
}
public async Task<PaymentRequestDto> CreateAsync(PaymentRequestCreationDto input)
{
var paymentRequest = new PaymentRequest(
GuidGenerator.Create(),
input.CustomerId,
input.ProductId,
input.ProductName,
input.Price,
input.Currency ?? _paymentOptions.DefaultCurrency
);
foreach (var extraProperty in input.ExtraProperties)
{
paymentRequest.SetProperty(extraProperty.Key, extraProperty.Value);
}
await _paymentRequestRepository.InsertAsync(paymentRequest);
return ObjectMapper.Map<PaymentRequest, PaymentRequestDto>(paymentRequest);
}
public async Task<StartPaymentResultDto> StartPaymentAsync(StartPaymentDto input)
{
var paymentRequest = await _paymentRequestRepository.GetAsync(input.PaymentRequestId);
var order = new OrderRequest
{
CheckoutPaymentIntent = "CAPTURE",
ApplicationContext = new ApplicationContext
{
ReturnUrl = input.ReturnUrl,
CancelUrl = input.CancelUrl,
},
PurchaseUnits = new List<PurchaseUnitRequest>
{
new PurchaseUnitRequest
{
AmountWithBreakdown = new AmountWithBreakdown
{
AmountBreakdown = new AmountBreakdown
{
ItemTotal = new Money
{
CurrencyCode = paymentRequest.Currency,
Value = paymentRequest.Price.ToString(".00")
}
},
CurrencyCode = paymentRequest.Currency,
Value = paymentRequest.Price.ToString(".00"),
},
Items = new List<Item>
{
new Item
{
Quantity = 1.ToString(),
Name = paymentRequest.ProductName,
UnitAmount = new Money
{
CurrencyCode = paymentRequest.Currency,
Value = paymentRequest.Price.ToString(".00")
}
}
},
ReferenceId = paymentRequest.Id.ToString()
}
}
};
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
var result = (await _payPalHttpClient.Execute(request)).Result<Order>();
return new StartPaymentResultDto
{
CheckoutLink = result.Links.First(x => x.Rel == "approve").Href
};
}
public async Task<PaymentRequestDto> CompleteAsync(string token)
{
var request = new OrdersCaptureRequest(token);
request.RequestBody(new OrderActionRequest());
var order = (await _payPalHttpClient.Execute(request)).Result<Order>();
var paymentRequest = await UpdatePaymentRequestStateAsync(order);
return ObjectMapper.Map<PaymentRequest, PaymentRequestDto>(paymentRequest);
}
public async Task<bool> HandleWebhookAsync(string payload)
{
var jObject = JObject.Parse(payload);
//// TODO: Find way to parse with System.Text.Json instead of Newtonsoft
var order = jObject["resource"].ToObject<Order>();
var request = new OrdersGetRequest(order.Id);
// Ensure order object comes from PayPal
var response = await _payPalHttpClient.Execute(request);
order = response.Result<Order>();
await UpdatePaymentRequestStateAsync(order);
// PayPal doesn't accept Http 204 (NoContent) result and tries to execute webhook again.
// So with following value, API returns Http 200 (OK) result.
return true;
}
private async Task<PaymentRequest> UpdatePaymentRequestStateAsync(Order order)
{
var paymentRequestId = Guid.Parse(order.PurchaseUnits.First().ReferenceId);
var paymentRequest = await _paymentRequestRepository.GetAsync(paymentRequestId);
if (order.Status is PayPalConsts.OrderStatus.Completed or PayPalConsts.OrderStatus.Approved)
{
paymentRequest.SetAsCompleted();
}
else
{
paymentRequest.SetAsFailed(order.Status);
}
paymentRequest.ExtraProperties[PayPalConsts.OrderIdPropertyName] = order.Id;
paymentRequest.ExtraProperties[nameof(order.Status)] = order.Status;
await _paymentRequestRepository.UpdateAsync(paymentRequest);
return paymentRequest;
}
}
}

29
modules/payment/src/Payment.Application/Samples/SampleAppService.cs

@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
namespace Payment.Samples
{
public class SampleAppService : PaymentAppService, ISampleAppService
{
public Task<SampleDto> GetAsync()
{
return Task.FromResult(
new SampleDto
{
Value = 42
}
);
}
[Authorize]
public Task<SampleDto> GetAuthorizedAsync()
{
return Task.FromResult(
new SampleDto
{
Value = 42
}
);
}
}
}

3
modules/payment/src/Payment.BackgroundServices/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

30
modules/payment/src/Payment.BackgroundServices/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

15
modules/payment/src/Payment.BackgroundServices/Payment.BackgroundServices.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<Import Project="..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Payment</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Payment.Domain\Payment.Domain.csproj" />
</ItemGroup>
</Project>

15
modules/payment/src/Payment.BackgroundServices/PaymentBackgroundServicesModule.cs

@ -0,0 +1,15 @@
using Volo.Abp.Modularity;
namespace Payment
{
[DependsOn(
typeof(PaymentDomainModule)
)]
public class PaymentBackgroundServicesModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
}
}
}

3
modules/payment/src/Payment.Domain.Shared/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
modules/payment/src/Payment.Domain.Shared/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/ar.json

@ -0,0 +1,7 @@
{
"culture": "ar",
"texts": {
"MyAccount": "إدارة ملفى",
"SamplePageMessage": "صفحة نموذجية للوحدة النمطية Payment"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/cs.json

@ -0,0 +1,7 @@
{
"culture": "cs",
"texts": {
"MyAccount": "Spravovat profil",
"SamplePageMessage": "Ukázková stránka pro modul Payment"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/de-DE.json

@ -0,0 +1,7 @@
{
"culture": "de-DE",
"texts": {
"MyAccount": "Mein Konto",
"SamplePageMessage": "Eine Beispielseite für das Modul PaymentModul"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/en-GB.json

@ -0,0 +1,7 @@
{
"culture": "en-GB",
"texts": {
"MyAccount": "My account",
"SamplePageMessage": "A sample page for the Payment module"
}
}

36
modules/payment/src/Payment.Domain.Shared/Localization/Payment/en.json

@ -0,0 +1,36 @@
{
"culture": "en",
"texts": {
"CompletePayment": "Complete the Payment",
"Enum:PaymentRequestState:Completed": "Completed",
"Enum:PaymentRequestState:Failed": "Failed",
"Enum:PaymentRequestState:Waiting": "Waiting",
"GoBack": "Go Back",
"MyAccount": "My account",
"PaymentRequestIsNotWaiting": "The state isn't 'Waiting', so you can't pay this Payment Request at this time.",
"PaymentResult": "Payment Result",
"Price": "Price",
"ProductInformation": "Product Information",
"ProductName": "Product Name",
"SamplePageMessage": "A sample page for the Payment module",
"Status": "State",
"YourPaymentCompletedSuccessfully": "Your payment has been completed successfully!",
"YourPaymentFailed": "Your payment has been failed unfortunetely!",
"Permission:Payment": "Payment",
"Menu:PaymentManagement": "Payment",
"PaymentRequests": "Payment Requests",
"PaymentRequestState:0": "Waiting",
"PaymentRequestState:1": "Completed",
"PaymentRequestState:2": "Failed",
"MinCreationTime": "Min Creation Time",
"MaxCreationTime": "Max Creation Time",
"CustomerId": "Customer Id",
"Currency": "Currency",
"State": "State",
"FailReason": "Fail Reason",
"CreationTime": "Creation Time",
"Permission:PaymentManagement": "Payment Management",
"Permission:PaymentRequest": "Payment Requests"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/es.json

@ -0,0 +1,7 @@
{
"culture": "es",
"texts": {
"MyAccount": "Mi cuenta",
"SamplePageMessage": "Una página de ejemplo para el módulo Payment "
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/fi.json

@ -0,0 +1,7 @@
{
"culture": "fi",
"texts": {
"MyAccount": "Tilini",
"SamplePageMessage": "Esimerkkisivu Payment-moduulille"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/fr.json

@ -0,0 +1,7 @@
{
"culture": "fr",
"texts": {
"MyAccount": "Mon compte",
"SamplePageMessage": "Exemple de page pour le module Payment"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/hi.json

@ -0,0 +1,7 @@
{
"culture": "hi",
"texts": {
"MyAccount": "मेरा खाता",
"SamplePageMessage": "Payment मॉड्यूल के लिए एक नमूना पृष्ठ"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/hu.json

@ -0,0 +1,7 @@
{
"culture": "hu",
"texts": {
"MyAccount": "A fiókom",
"SamplePageMessage": "Mintaoldal a Payment modulhoz"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/it.json

@ -0,0 +1,7 @@
{
"culture": "it",
"texts": {
"MyAccount": "Il mio conto",
"SamplePageMessage": "Una pagina di esempio per il modulo Payment"
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/nl.json

@ -0,0 +1,7 @@
{
"culture": "nl",
"texts": {
"MyAccount": "Mijn rekening",
"SamplePageMessage": "Een voorbeeldpagina voor de Payment module"
}
}

6
modules/payment/src/Payment.Domain.Shared/Localization/Payment/pl-PL.json

@ -0,0 +1,6 @@
{
"culture": "pl-PL",
"texts": {
}
}

6
modules/payment/src/Payment.Domain.Shared/Localization/Payment/pt-BR.json

@ -0,0 +1,6 @@
{
"culture": "pt-BR",
"texts": {
}
}

7
modules/payment/src/Payment.Domain.Shared/Localization/Payment/ro-RO.json

@ -0,0 +1,7 @@
{
"culture": "ro-RO",
"texts": {
"MyAccount": "Contul meu",
"SamplePageMessage": "Un exemplu de pagină pentru modululul Payment"
}
}

6
modules/payment/src/Payment.Domain.Shared/Localization/Payment/sk.json

@ -0,0 +1,6 @@
{
"culture": "sk",
"texts": {
"SamplePageMessage": "Ukážka stránky pre modul Payment"
}
}

6
modules/payment/src/Payment.Domain.Shared/Localization/Payment/sl.json

@ -0,0 +1,6 @@
{
"culture": "sl",
"texts": {
"MyAccount": "Moj račun"
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save