860 lines
49 KiB
C#
860 lines
49 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using gehGassi.Core.Interfaces;
|
|
using gehGassi.Core.Services;
|
|
using gehGassi.Domain.Common;
|
|
using gehGassi.Domain.Payment;
|
|
using gehGassi.Domain.Walks;
|
|
using gehGassi.Dto.Messages;
|
|
using gehGassi.External.Services;
|
|
using gehGassi.Persistence.Migrations;
|
|
using gehGassi.Web.Hubs;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace gehGassi.Web.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Controller für die Kommunikation mit MangoPay
|
|
/// </summary>
|
|
[Authorize]
|
|
public class MangoPayController : BaseController
|
|
{
|
|
private readonly IMangoPayService _mangoPayService;
|
|
private readonly IPaymentTransactionService _paymentTransactionService;
|
|
private readonly IWalkService _walkService;
|
|
private readonly ISystemMessageService _systemMessageService;
|
|
private readonly IAppHubSender _appHubSender;
|
|
private readonly IServiceScopeFactory _resolver;
|
|
private readonly IPushNotificationService _pushNotificationService;
|
|
private readonly ILogger<MangoPayController> _logger;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="mangoPayService">Instanz eines IMangoPayService</param>
|
|
/// <param name="paymentTransactionService">Instanz eines IPaymentTransactionService</param>
|
|
/// <param name="walkService">Instanz eines IWalkService</param>
|
|
/// <param name="systemMessageService">Instanz eines ISystemMessageService</param>
|
|
/// <param name="appHubSender">Instanz eines IAppHubSender</param>
|
|
/// <param name="resolver">Instanz einer IServiceScopeFactory</param>
|
|
/// <param name="logger">Instanz eines ILogger</param>
|
|
/// <param name="pushNotificationService">Instanz eines IPushNotificationService</param>
|
|
public MangoPayController(IMangoPayService mangoPayService, IPaymentTransactionService paymentTransactionService, IWalkService walkService, ISystemMessageService systemMessageService, IAppHubSender appHubSender,
|
|
IServiceScopeFactory resolver, ILogger<MangoPayController> logger, IPushNotificationService pushNotificationService)
|
|
{
|
|
_mangoPayService = mangoPayService;
|
|
_paymentTransactionService = paymentTransactionService;
|
|
_walkService = walkService;
|
|
_systemMessageService = systemMessageService;
|
|
_appHubSender = appHubSender;
|
|
_resolver = resolver;
|
|
_pushNotificationService = pushNotificationService;
|
|
//_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Nimmt das Ergebnis einer Einzahlungsatkion bei MangoPay entgegen
|
|
/// </summary>
|
|
/// <param name="transactionId">TransaktionsId bei Mangopay</param>
|
|
/// <returns>200 ok</returns>
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> PayInReturn(string transactionId)
|
|
{
|
|
//Zuerst prüfen ob die Tranksation bei MangoPay erfolgreich war...
|
|
var transactionResponse = await _mangoPayService.GetTransactionAsync(transactionId);
|
|
//_logger.LogWarning($"PayInReturn: TransactionId {transactionId}");
|
|
if (transactionResponse.Success)
|
|
{
|
|
var mangoPayTransaction = transactionResponse.Value;
|
|
if (mangoPayTransaction.Status == PaymentTransactionStatus.SUCCEEDED)
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: Transaction SUCCEDED");
|
|
//nun die Transaktion lokal holen und sehen ob eine mit dem Status CREATED existiert...
|
|
var paymentTransaction = await _paymentTransactionService.GetAsync(mangoPayTransaction.TransactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.CREATED);
|
|
if (paymentTransaction != null)
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: PaymentTansaction with status CREATED exists");
|
|
var paymentTransactionSuccess = await _paymentTransactionService.GetAsync(mangoPayTransaction.TransactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.SUCCEEDED);
|
|
|
|
if (paymentTransactionSuccess != null) return BadRequest();
|
|
//_logger.LogWarning($"PayInReturn: PaymentTansaction with status SUCCEEDED does not exist --> OK");
|
|
|
|
|
|
paymentTransactionSuccess = _paymentTransactionService.Create(mangoPayTransaction.TransactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.SUCCEEDED, paymentTransaction.WalkId,
|
|
paymentTransaction.TargetAppUserId, paymentTransaction.TargetWalletId, string.Empty, string.Empty, paymentTransaction.Ammount, paymentTransaction.FromCredit, "EUR", paymentTransaction.PayInType);
|
|
_paymentTransactionService.Add(paymentTransactionSuccess);
|
|
await _paymentTransactionService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: PaymentTansaction with status SUCCEEDED created");
|
|
|
|
//Die Zahlung war erfolgreich. Also dies nun beim Walk ablegen und die Benutzer benachrichtigen
|
|
var walk = await _walkService.GetAsync(paymentTransactionSuccess.WalkId);
|
|
if (walk != null)
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: Walk exists");
|
|
//Wenn noch ein Teil vom Guthabenkonto genommen werden muss
|
|
if (paymentTransactionSuccess.FromCredit > 0)
|
|
{
|
|
var tag = $"Walk_Authorize_{walk.Id}";
|
|
await _mangoPayService.TransferMoneyFromCreditToFeeAccountAsync(walk.DogOwnerId, paymentTransactionSuccess.FromCredit, tag);
|
|
//_logger.LogWarning($"PayInReturn: TransferMoneyFromCreditToFeeAccountAsync done");
|
|
}
|
|
|
|
walk.PaymentStatus = PaymentStatus.Authorized;
|
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await _walkService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: Paymentstatus set to Authorized");
|
|
|
|
//Wallets aktualisieren
|
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Credits);
|
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Fees);
|
|
|
|
//_logger.LogWarning($"PayInReturn: Wallets updated");
|
|
|
|
//Überlappende Walks die im Status "Request" sind, stornieren
|
|
await _walkService.CancelWalkRequestsAsync(walk.DogWalkerId, walk.Start, walk.End);
|
|
await _walkService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: CancelWalkRequestsAsync done");
|
|
|
|
//Walker informieren. TODO: pushnotification?
|
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkAdded, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync("System");
|
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
|
await _pushNotificationService.SendNewWalkAsync(walk.DogWalkerId, walk.Id);
|
|
|
|
//_logger.LogWarning($"PayInReturn: Systemmessage sent");
|
|
|
|
var returnUrl = Url.Action("PayInSuccess", "MangoPay", new{walkId = walk.Id}, protocol: HttpContext.Request.Scheme);
|
|
|
|
//_logger.LogWarning($"PayInReturn: redirecting to: {returnUrl}");
|
|
#if DEBUG
|
|
returnUrl = $"http://10.0.0.31:54763/de/mangopay/payinsuccess?walkId={HttpUtility.UrlEncode(walk.Id)}";// Url.Action("PayInReturn", "MangoPay", , protocol: "http");
|
|
#endif
|
|
|
|
return Redirect(returnUrl);
|
|
}
|
|
else
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: Walk does not exist");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Gescheitert. Kann diverse Gründe haben. z.B. nicht genügend Geld auf dem Wallet
|
|
//nun die Transaktion lokal holen und sehen ob eine mit dem Status CREATED existiert...
|
|
var paymentTransaction = await _paymentTransactionService.GetAsync(mangoPayTransaction.TransactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.CREATED);
|
|
if (paymentTransaction != null)
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: Transaction FAILED");
|
|
|
|
var paymentTransactionFailed = _paymentTransactionService.Create(mangoPayTransaction.TransactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.FAILED, paymentTransaction.WalkId, paymentTransaction.TargetAppUserId, paymentTransaction.TargetWalletId, string.Empty, string.Empty, paymentTransaction.Ammount, paymentTransaction.FromCredit, "EUR", transactionResponse.Value.ResultMessage, transactionResponse.Value.ResultCode, new Dictionary<string, string>(), paymentTransaction.PayInType);
|
|
_paymentTransactionService.Add(paymentTransactionFailed);
|
|
await _paymentTransactionService.CommitAsync("System");
|
|
|
|
var returnUrl = Url.Action("PayInFailed", "MangoPay", new { walkId = paymentTransaction.WalkId }, protocol: HttpContext.Request.Scheme);
|
|
|
|
//_logger.LogWarning($"PayInReturn: redirecting to: {returnUrl}");
|
|
|
|
#if DEBUG
|
|
returnUrl = $"http://10.0.0.31:54763/de/mangopay/payinfailed?walkId={HttpUtility.UrlEncode(paymentTransaction.WalkId)}";// Url.Action("PayInReturn", "MangoPay", , protocol: "http");
|
|
#endif
|
|
|
|
return Redirect(returnUrl);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var paymentTransaction = await _paymentTransactionService.GetAsync(transactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.CREATED);
|
|
if (paymentTransaction != null)
|
|
{
|
|
var paymentTransactionFailed = _paymentTransactionService.Create(transactionId, PaymentTransactionType.PayIn, PaymentTransactionStatus.FAILED, paymentTransaction.WalkId, paymentTransaction.TargetAppUserId, paymentTransaction.TargetWalletId, string.Empty, string.Empty, paymentTransaction.Ammount, paymentTransaction.FromCredit, "EUR", transactionResponse.ErrorMessage, transactionResponse.ErrorType, transactionResponse.ErrorMessages, paymentTransaction.PayInType);
|
|
_paymentTransactionService.Add(paymentTransactionFailed);
|
|
await _paymentTransactionService.CommitAsync("System");
|
|
|
|
var returnUrl = Url.Action("PayInFailed", "MangoPay", new { walkId = paymentTransaction.WalkId }, protocol: HttpContext.Request.Scheme);
|
|
#if DEBUG
|
|
returnUrl = $"http://10.0.0.31:54763/de/mangopay/payinfailed?walkId={HttpUtility.UrlEncode(paymentTransaction.WalkId)}";// Url.Action("PayInReturn", "MangoPay", , protocol: "http");
|
|
#endif
|
|
|
|
return Redirect(returnUrl);
|
|
}
|
|
}
|
|
|
|
return BadRequest();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Signal, dass eine Zahlung erfolgreich war für einen Walk
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <returns>200 OK</returns>
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> PayInSuccess(string walkId)
|
|
{
|
|
//_logger.LogWarning($"PayInSuccess: called for walkid {walkId}");
|
|
await Task.Delay(1);
|
|
ViewBag.DarkMode = false;
|
|
return View();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Signal, dass eine Zahlung nicht erfolgreich war für einen Walk
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <returns>200 OK</returns>
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> PayInFailed(string walkId)
|
|
{
|
|
//_logger.LogWarning($"PayInFailed: called for walkid {walkId}");
|
|
await Task.Delay(1);
|
|
ViewBag.DarkMode = false;
|
|
return View();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Webhook für MangoPay
|
|
/// </summary>
|
|
/// <param name="eventType">Event-Typ</param>
|
|
/// <param name="ressourceId">Id der Ressource</param>
|
|
/// <returns>200 OK</returns>
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> WebHook(string eventType, string ressourceId)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(eventType) && !string.IsNullOrWhiteSpace(ressourceId))
|
|
{
|
|
var serviceProvider = HttpContext.RequestServices;
|
|
if (eventType == "KYC_SUCCEEDED")
|
|
{
|
|
var documentId = ressourceId;
|
|
_ = Task.Run(() => HandleKycSucceded(documentId, _resolver));
|
|
}
|
|
else if (eventType == "KYC_FAILED")
|
|
{
|
|
var documentId = ressourceId;
|
|
_ = Task.Run(() => HandleKycFailed(documentId, _resolver));
|
|
}
|
|
else if (eventType == "KYC_OUTDATED")
|
|
{
|
|
var documentId = ressourceId;
|
|
_ = Task.Run(() => HandleKycOutdated(documentId, _resolver));
|
|
}
|
|
else if (eventType == "PAYOUT_NORMAL_SUCCEEDED")
|
|
{
|
|
var payoutId = ressourceId;
|
|
_ = Task.Run(() => HandlePayOutSucceeded(payoutId, _resolver));
|
|
}
|
|
|
|
else if (eventType == "PAYOUT_NORMAL_FAILED")
|
|
{
|
|
var payoutId = ressourceId;
|
|
_ = Task.Run(() => HandlePayOutFailed(payoutId, _resolver));
|
|
}
|
|
|
|
else if (eventType == "PAYOUT_REFUND_SUCCEEDED")
|
|
{
|
|
var payoutId = ressourceId;
|
|
_ = Task.Run(() => HandlePayOutRefunded(payoutId, _resolver));
|
|
}
|
|
|
|
else if (eventType == "PAYIN_NORMAL_SUCCEEDED")
|
|
{
|
|
var payinId = ressourceId;
|
|
_ = Task.Run(() => HandlePayInSucceeded(payinId, _resolver));
|
|
}
|
|
|
|
else if (eventType == "PAYIN_NORMAL_FAILED")
|
|
{
|
|
var payinId = ressourceId;
|
|
_ = Task.Run(() => HandlePayInFailed(payinId, _resolver));
|
|
}
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
|
|
#region Private
|
|
|
|
/// <summary>
|
|
/// Eine KYC-Überprüfung war erfolgreich
|
|
/// </summary>
|
|
/// <param name="documentId">Id des Kyc-Dokumentes bei MangoPay</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandleKycSucceded(string documentId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var identityDocumentService = (IIdentityDocumentService)svcProvider.GetService(typeof(IIdentityDocumentService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (identityDocumentService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var identityDocument = await identityDocumentService.GetByMangoPayIdAsync(documentId);
|
|
if (identityDocument != null)
|
|
{
|
|
var documentResult = await _mangoPayService.GetKycDocumentAsync(documentId);
|
|
if (documentResult != null && documentResult.Success)
|
|
{
|
|
identityDocument.Status = documentResult.Value.Status;
|
|
identityDocument.Processed = documentResult.Value.ProcessedDate;
|
|
identityDocument.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await identityDocumentService.CommitAsync("System");
|
|
|
|
var appUser = await appUserService.GetAsync(identityDocument.AppUserId);
|
|
if (appUser != null)
|
|
{
|
|
appUser.KycPassed = true;
|
|
appUser.KycPassedDate = DateTimeOffset.UtcNow;
|
|
appUser.UpdatedAt = DateTimeOffset.UtcNow;
|
|
if (!appUser.Verified)
|
|
{
|
|
appUser.Verified = true;
|
|
appUser.VerifiedDate = DateTimeOffset.UtcNow;
|
|
}
|
|
|
|
await appUserService.CommitAsync("System");
|
|
}
|
|
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine KYC-Überprüfung ist gescheitert
|
|
/// </summary>
|
|
/// <param name="documentId">Id des Kyc-Dokumentes bei MangoPay</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandleKycFailed(string documentId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var identityDocumentService = (IIdentityDocumentService)svcProvider.GetService(typeof(IIdentityDocumentService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (identityDocumentService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var identityDocument = await identityDocumentService.GetByMangoPayIdAsync(documentId);
|
|
if (identityDocument != null)
|
|
{
|
|
var documentResult = await _mangoPayService.GetKycDocumentAsync(documentId);
|
|
if (documentResult != null && documentResult.Success)
|
|
{
|
|
identityDocument.Status = documentResult.Value.Status;
|
|
identityDocument.Processed = documentResult.Value.ProcessedDate;
|
|
identityDocument.RefusedReasonType = documentResult.Value.RefusedReasonType;
|
|
identityDocument.RefusedReasonMessage = documentResult.Value.RefusedReasonMessage;
|
|
if (documentResult.Value.Flags != null && documentResult.Value.Flags.Any())
|
|
identityDocument.FlagsValue = string.Join(";", documentResult.Value.Flags);
|
|
else
|
|
identityDocument.FlagsValue = string.Empty;
|
|
identityDocument.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await identityDocumentService.CommitAsync("System");
|
|
|
|
var appUser = await appUserService.GetAsync(identityDocument.AppUserId);
|
|
if (appUser != null)
|
|
{
|
|
appUser.KycPassed = false;
|
|
appUser.KycPassedDate = null;
|
|
appUser.UpdatedAt = DateTimeOffset.UtcNow;
|
|
|
|
await appUserService.CommitAsync("System");
|
|
}
|
|
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine KYC-Überprüfung ist gescheitert
|
|
/// </summary>
|
|
/// <param name="documentId">Id des Kyc-Dokumentes bei MangoPay</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandleKycOutdated(string documentId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var identityDocumentService = (IIdentityDocumentService)svcProvider.GetService(typeof(IIdentityDocumentService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (identityDocumentService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var identityDocument = await identityDocumentService.GetByMangoPayIdAsync(documentId);
|
|
if (identityDocument != null)
|
|
{
|
|
var documentResult = await _mangoPayService.GetKycDocumentAsync(documentId);
|
|
if (documentResult != null && documentResult.Success)
|
|
{
|
|
identityDocument.Status = documentResult.Value.Status;
|
|
identityDocument.Processed = documentResult.Value.ProcessedDate;
|
|
identityDocument.RefusedReasonType = documentResult.Value.RefusedReasonType;
|
|
identityDocument.RefusedReasonMessage = documentResult.Value.RefusedReasonMessage;
|
|
if (documentResult.Value.Flags != null && documentResult.Value.Flags.Any())
|
|
identityDocument.FlagsValue = string.Join(";", documentResult.Value.Flags);
|
|
else
|
|
identityDocument.FlagsValue = string.Empty;
|
|
identityDocument.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await identityDocumentService.CommitAsync("System");
|
|
|
|
|
|
var appUser = await appUserService.GetAsync(identityDocument.AppUserId);
|
|
var latestIdentityDocument = await identityDocumentService.GetLatestAsync(identityDocument.AppUserId);
|
|
if (latestIdentityDocument != null && latestIdentityDocument.Id == identityDocument.Id)
|
|
{
|
|
//Wenn das das aktuell gültige KYC-Dokument ist, dann KYC vom App-User wieder entfernen
|
|
if (appUser != null)
|
|
{
|
|
appUser.KycPassed = false;
|
|
appUser.KycPassedDate = null;
|
|
appUser.UpdatedAt = DateTimeOffset.UtcNow;
|
|
|
|
await appUserService.CommitAsync("System");
|
|
}
|
|
}
|
|
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, identityDocument.Id, SystemMessageTables.IdentityDocument, SystemMessageType.IdentityDocumentUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendIdentityDocumentUpdateAsync(appUser.Id, identityDocument.Id);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine Auszahlung war erfolgreich
|
|
/// </summary>
|
|
/// <param name="payoutId">Id der Auszahlung</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandlePayOutSucceeded(string payoutId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var payoutService = (IPayoutService)svcProvider.GetService(typeof(IPayoutService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (payoutService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var payout = await payoutService.GetByMangoPayIdAsync(payoutId);
|
|
if (payout != null)
|
|
{
|
|
var payoutResult = await _mangoPayService.GetPayoutAsync(payoutId);
|
|
if (payoutResult != null && payoutResult.Success)
|
|
{
|
|
payout.Status = payoutResult.Value.Status;
|
|
payout.ExecutionDate = payoutResult.Value.ExecutionDate;
|
|
payout.ResultCode = payoutResult.Value.ResultCode;
|
|
payout.ResultMessage = payoutResult.Value.ResultMessage;
|
|
payout.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await payoutService.CommitAsync("System");
|
|
|
|
var appUser = await appUserService.GetAsync(payout.AppUserId);
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine Auszahlung ist gescheitert
|
|
/// </summary>
|
|
/// <param name="payoutId">Id der Auszahlung</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandlePayOutFailed(string payoutId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var payoutService = (IPayoutService)svcProvider.GetService(typeof(IPayoutService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (payoutService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var payout = await payoutService.GetByMangoPayIdAsync(payoutId);
|
|
if (payout != null)
|
|
{
|
|
var payoutResult = await _mangoPayService.GetPayoutAsync(payoutId);
|
|
if (payoutResult != null && payoutResult.Success)
|
|
{
|
|
payout.Status = payoutResult.Value.Status;
|
|
payout.ExecutionDate = payoutResult.Value.ExecutionDate;
|
|
payout.ResultCode = payoutResult.Value.ResultCode;
|
|
payout.ResultMessage = payoutResult.Value.ResultMessage;
|
|
payout.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await payoutService.CommitAsync("System");
|
|
|
|
var appUser = await appUserService.GetAsync(payout.AppUserId);
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine Auszahlung ist gescheitert und wurde zurücküberwiesen
|
|
/// </summary>
|
|
/// <param name="refundId">Id der Rückzahlung</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandlePayOutRefunded(string refundId, IServiceScopeFactory resolver)
|
|
{
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var payoutService = (IPayoutService)svcProvider.GetService(typeof(IPayoutService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (payoutService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var refundResult = await _mangoPayService.GetRefundAsync(refundId);
|
|
if (refundResult.Success && refundResult.Value.Status == PaymentTransactionStatus.SUCCEEDED)
|
|
{
|
|
var payout = await payoutService.GetByMangoPayIdAsync(refundResult.Value.OriginalTransactionId);
|
|
if (payout != null)
|
|
{
|
|
payout.Status = PaymentTransactionStatus.FAILED;
|
|
payout.Refunded = true;
|
|
payout.RefundReasonType = refundResult.Value.RefundReasonType;
|
|
payout.RefundReasonMessage = refundResult.Value.RefundReasonMessage;
|
|
payout.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await payoutService.CommitAsync("System");
|
|
|
|
var appUser = await appUserService.GetAsync(payout.AppUserId);
|
|
//Benachrichtigung
|
|
if (appUser != null)
|
|
{
|
|
if (appUser.Type == AppUserType.DogOwner || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogOwner, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
else if (appUser.Type == AppUserType.DogWalker || appUser.Type == AppUserType.Both)
|
|
{
|
|
systemMessageService.Add(appUser.Id, AppUserType.DogWalker, payout.Id, SystemMessageTables.Payout, SystemMessageType.PayoutUpdate, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync(User.Identity.Name);
|
|
await _appHubSender.SystemMessageAddedAsync(appUser.Id);
|
|
await _pushNotificationService.SendPayoutUpdateAsync(appUser.Id, payout.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine Einzahlung war erfolgreich
|
|
/// </summary>
|
|
/// <param name="payinId">Id der Einzahlung</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandlePayInSucceeded(string payinId, IServiceScopeFactory resolver)
|
|
{
|
|
//30 Sekunden warten, falls der Event schneller kommen sollte als in der App
|
|
await Task.Delay(30000);
|
|
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var paymentTransactionService = (IPaymentTransactionService)svcProvider.GetService(typeof(IPaymentTransactionService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (paymentTransactionService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var paymentTransaction = await paymentTransactionService.GetAsync(payinId, PaymentTransactionType.PayIn);
|
|
if (paymentTransaction != null)
|
|
{
|
|
//Es muss zumindest eine Transaktion geben die den Status CREATED hat
|
|
if (paymentTransaction.Status == PaymentTransactionStatus.CREATED)
|
|
{
|
|
var paymentTransactionSuccess = _paymentTransactionService.Create(payinId, PaymentTransactionType.PayIn, PaymentTransactionStatus.SUCCEEDED, paymentTransaction.WalkId, paymentTransaction.TargetAppUserId, paymentTransaction.TargetWalletId, string.Empty, string.Empty, paymentTransaction.Ammount, paymentTransaction.FromCredit, "EUR", paymentTransaction.PayInType);
|
|
_paymentTransactionService.Add(paymentTransactionSuccess);
|
|
await _paymentTransactionService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: PaymentTansaction with status SUCCEEDED created");
|
|
|
|
//Die Zahlung war erfolgreich. Also dies nun beim Walk ablegen und die Benutzer benachrichtigen
|
|
var walk = await _walkService.GetAsync(paymentTransactionSuccess.WalkId);
|
|
if (walk != null)
|
|
{
|
|
//_logger.LogWarning($"PayInReturn: Walk exists");
|
|
//Wenn noch ein Teil vom Guthabenkonto genommen werden muss
|
|
if (paymentTransactionSuccess.FromCredit > 0)
|
|
{
|
|
var tag = $"Walk_Authorize_{walk.Id}";
|
|
await _mangoPayService.TransferMoneyFromCreditToFeeAccountAsync(walk.DogOwnerId, paymentTransactionSuccess.FromCredit, tag);
|
|
//_logger.LogWarning($"PayInReturn: TransferMoneyFromCreditToFeeAccountAsync done");
|
|
}
|
|
|
|
walk.PaymentStatus = PaymentStatus.Authorized;
|
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await _walkService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: Paymentstatus set to Authorized");
|
|
|
|
//Wallets aktualisieren
|
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Credits);
|
|
await _mangoPayService.GetWalletBalanceAsync(walk.DogOwnerId, WalletType.Fees);
|
|
|
|
//_logger.LogWarning($"PayInReturn: Wallets updated");
|
|
|
|
//Überlappende Walks die im Status "Request" sind, stornieren
|
|
await _walkService.CancelWalkRequestsAsync(walk.DogWalkerId, walk.Start, walk.End);
|
|
await _walkService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: CancelWalkRequestsAsync done");
|
|
|
|
//Walker informieren. TODO: pushnotification?
|
|
_systemMessageService.Add(walk.DogWalkerId, AppUserType.DogWalker, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkAdded, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync("System");
|
|
await _appHubSender.SystemMessageAddedAsync(walk.DogWalkerId);
|
|
await _pushNotificationService.SendNewWalkAsync(walk.DogWalkerId, walk.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eine Einzahlung war nicht erfolgreich
|
|
/// </summary>
|
|
/// <param name="payinId">Id der Einzahlung</param>
|
|
/// <param name="resolver">IServiceScopeFactory</param>
|
|
/// <returns>Task</returns>
|
|
private async Task HandlePayInFailed(string payinId, IServiceScopeFactory resolver)
|
|
{
|
|
//30 Sekunden warten, falls der Event schneller kommen sollte als in der App
|
|
await Task.Delay(30000);
|
|
|
|
try
|
|
{
|
|
using var scope = resolver.CreateScope();
|
|
var svcProvider = scope.ServiceProvider;
|
|
|
|
var paymentTransactionService = (IPaymentTransactionService)svcProvider.GetService(typeof(IPaymentTransactionService));
|
|
var appUserService = (IAppUserService)svcProvider.GetService(typeof(IAppUserService));
|
|
var systemMessageService = (ISystemMessageService)svcProvider.GetService(typeof(ISystemMessageService));
|
|
var appHubSender = (IAppHubSender)svcProvider.GetService(typeof(IAppHubSender));
|
|
|
|
if (paymentTransactionService != null && appUserService != null && systemMessageService != null && appHubSender != null)
|
|
{
|
|
var paymentTransaction = await paymentTransactionService.GetAsync(payinId, PaymentTransactionType.PayIn);
|
|
if (paymentTransaction != null)
|
|
{
|
|
//Es muss zumindest eine Transaktion geben die den Status CREATED hat
|
|
if (paymentTransaction.Status == PaymentTransactionStatus.CREATED)
|
|
{
|
|
var paymentTransactionFailed = _paymentTransactionService.Create(payinId, PaymentTransactionType.PayIn, PaymentTransactionStatus.FAILED, paymentTransaction.WalkId, paymentTransaction.TargetAppUserId, paymentTransaction.TargetWalletId, string.Empty, string.Empty, paymentTransaction.Ammount, paymentTransaction.FromCredit, "EUR", paymentTransaction.PayInType);
|
|
_paymentTransactionService.Add(paymentTransactionFailed);
|
|
await _paymentTransactionService.CommitAsync("System");
|
|
|
|
//_logger.LogWarning($"PayInReturn: PaymentTansaction with status SUCCEEDED created");
|
|
|
|
//Die Zahlung war erfolgreich. Also dies nun beim Walk ablegen und die Benutzer benachrichtigen
|
|
var walk = await _walkService.GetAsync(paymentTransactionFailed.WalkId);
|
|
if (walk != null)
|
|
{
|
|
walk.PaymentStatus = PaymentStatus.Pending;
|
|
walk.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await _walkService.CommitAsync("System");
|
|
|
|
//Owner informieren.
|
|
_systemMessageService.Add(walk.DogOwnerId, AppUserType.DogOwner, walk.Id, SystemMessageTables.Walk, SystemMessageType.WalkChanged, DateTimeOffset.UtcNow.AddDays(14));
|
|
await _systemMessageService.CommitAsync("System");
|
|
await _appHubSender.SystemMessageAddedAsync(walk.DogOwnerId);
|
|
await _pushNotificationService.SendWalkPaymentFailedAsync(walk.DogOwnerId, walk.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
await Task.Delay(1);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|