mirror of https://github.com/abpframework/eventhub
475 changed files with 88743 additions and 51008 deletions
@ -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."); |
|||
})(); |
|||
@ -1,6 +1,6 @@ |
|||
{ |
|||
"sdk": { |
|||
"version": "5.0.201", |
|||
"version": "6.0.100-rc.1.21458.32", |
|||
"rollForward": "latestFeature" |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1 @@ |
|||
**/wwwroot/libs/** linguist-vendored |
|||
@ -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 |
|||
@ -0,0 +1,5 @@ |
|||
{ |
|||
"singleQuote": true, |
|||
"useTabs": false, |
|||
"tabWidth": 4 |
|||
} |
|||
@ -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> |
|||
@ -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 |
|||
@ -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> |
|||
@ -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 |
|||
 |
|||
|
|||
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` |
|||
@ -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> |
|||
@ -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> |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"sdk": { |
|||
"version": "6.0", |
|||
"rollForward": "latestFeature" |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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 |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Payment.Admin |
|||
{ |
|||
public class PaymentAdminRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "PaymentAdmin"; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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>(); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Payment.Admin.Navigation |
|||
{ |
|||
public static class PaymentAdminMenuNames |
|||
{ |
|||
public const string GroupName = "Payment"; |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
@ -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 } |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
{ |
|||
} |
|||
} |
|||
@ -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": {} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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)); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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 |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Payment |
|||
{ |
|||
public class PaymentRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "Payment"; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
|
|||
namespace Payment.PaymentRequests |
|||
{ |
|||
[Serializable] |
|||
public class StartPaymentResultDto |
|||
{ |
|||
public string CheckoutLink { get; set; } |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace Payment.Samples |
|||
{ |
|||
public class SampleDto |
|||
{ |
|||
public int Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using AutoMapper; |
|||
using Payment.PaymentRequests; |
|||
|
|||
namespace Payment |
|||
{ |
|||
public class PaymentApplicationAutoMapperProfile : Profile |
|||
{ |
|||
public PaymentApplicationAutoMapperProfile() |
|||
{ |
|||
CreateMap<PaymentRequest, PaymentRequestDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -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)); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
} |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -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> |
|||
@ -0,0 +1,15 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Payment |
|||
{ |
|||
[DependsOn( |
|||
typeof(PaymentDomainModule) |
|||
)] |
|||
public class PaymentBackgroundServicesModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -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> |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"MyAccount": "إدارة ملفى", |
|||
"SamplePageMessage": "صفحة نموذجية للوحدة النمطية Payment" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"MyAccount": "Spravovat profil", |
|||
"SamplePageMessage": "Ukázková stránka pro modul Payment" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"MyAccount": "Mein Konto", |
|||
"SamplePageMessage": "Eine Beispielseite für das Modul PaymentModul" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "en-GB", |
|||
"texts": { |
|||
"MyAccount": "My account", |
|||
"SamplePageMessage": "A sample page for the Payment module" |
|||
} |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"MyAccount": "Mi cuenta", |
|||
"SamplePageMessage": "Una página de ejemplo para el módulo Payment " |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "fi", |
|||
"texts": { |
|||
"MyAccount": "Tilini", |
|||
"SamplePageMessage": "Esimerkkisivu Payment-moduulille" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "fr", |
|||
"texts": { |
|||
"MyAccount": "Mon compte", |
|||
"SamplePageMessage": "Exemple de page pour le module Payment" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "hi", |
|||
"texts": { |
|||
"MyAccount": "मेरा खाता", |
|||
"SamplePageMessage": "Payment मॉड्यूल के लिए एक नमूना पृष्ठ" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "hu", |
|||
"texts": { |
|||
"MyAccount": "A fiókom", |
|||
"SamplePageMessage": "Mintaoldal a Payment modulhoz" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "it", |
|||
"texts": { |
|||
"MyAccount": "Il mio conto", |
|||
"SamplePageMessage": "Una pagina di esempio per il modulo Payment" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "nl", |
|||
"texts": { |
|||
"MyAccount": "Mijn rekening", |
|||
"SamplePageMessage": "Een voorbeeldpagina voor de Payment module" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ro-RO", |
|||
"texts": { |
|||
"MyAccount": "Contul meu", |
|||
"SamplePageMessage": "Un exemplu de pagină pentru modululul Payment" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "sk", |
|||
"texts": { |
|||
"SamplePageMessage": "Ukážka stránky pre modul Payment" |
|||
} |
|||
} |
|||
@ -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…
Reference in new issue