555 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.SymbolStore;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gehGassi.Domain.Common;
using gehGassi.Domain.Payment;
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json.Converters;
namespace gehGassi.Core.Interfaces
{
/// <summary>
/// Schnittstellenbeschreibung für einen Service der die Kommunikation mit MangoPay ermöglicht
/// </summary>
public interface IMangoPayService
{
/// <summary>
/// ruft eine Test-Funktion auf
/// </summary>
/// <returns>Task</returns>
Task TestAsync();
/// <summary>
/// Erstellen eines Mangopay-Benutzers für einen App-User.
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="suppressCommit">Soll das Commit unterdrückt werden?</param>
/// <returns>MangoPayResult mit der ID des Mangopay-Users</returns>
Task<MangoPayResult<string>> CreateOwnerAsync(string appUserId, bool suppressCommit);
/// <summary>
/// Aktualisieren eines Mangopay-Benutzers für einen App-User
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> UpdateOwnerAsync(string appUserId);
/// <summary>
/// Prüfen ob ein MangoPay-Benutzer existiert
/// </summary>
/// <param name="mangoPayUserId">Id des Mangopay-Benutzers</param>
/// <returns>true wenn existent, false sonst</returns>
Task<MangoPayResult<bool>> OwnerExistsAsync(string mangoPayUserId);
/// <summary>
/// Erstellt ein Wallet für einen AppUser mit einem bestimmten Typ.
/// Wenn das Wallet schon existiert, wird es zurückgegeben.
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="walletType">Typ des Wallets</param>
/// <returns>Wallet</returns>
Task<MangoPayResult<Wallet>> CreateWalletAsync(string appUserId, WalletType walletType);
/// <summary>
/// Aktualisiert den Kontostand eines Wallets und gibt diesen zurück
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="walletType">Typ des Wallets</param>
/// <returns>Wallet mit neuem Kontostand</returns>
Task<MangoPayResult<Wallet>> GetWalletBalanceAsync(string appUserId, WalletType walletType);
/// <summary>
/// Aktualisiert den Kontostand eines Wallets und gibt diesen zurück
/// </summary>
/// <param name="walletId">Id des Wallets bei MangoPay</param>
/// <returns>Kontostand</returns>
Task<MangoPayResult<long>> GetWalletBalanceAsync(string walletId);
/// <summary>
/// Prüfen ob ein MangoPay-Wallet existiert
/// </summary>
/// <param name="walletId">Id des Mangopay-Wallets</param>
/// <returns>true wenn existent, false sonst</returns>
Task<MangoPayResult<bool>> WalletExistsAsync(string walletId);
/// <summary>
/// Erstellt ein Bankkonto für einen AppUser
/// </summary>
/// <param name="mangoPayUserId">Id des Benutzers bei MangoPay</param>
/// <param name="ownerName">Name des Inhabers des Bankkontos</param>
/// <param name="address">Adresse des Inhabers des Bankkontos</param>
/// <param name="iban">Iban des Bankkontos</param>
/// <param name="bic">BIC des Bankkontos</param>
/// <returns>MangoPayResult mit der ID des Bankkontos</returns>
Task<MangoPayResult<string>> CreateBankAccountAsync(string mangoPayUserId, string ownerName, Address address, string iban, string bic);
/// <summary>
/// Gibt ein Bankkonto für einen App-User zurück
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="mangoPayUserId">Id des Benutzers bei MangoPay</param>
/// <param name="bankAccountId">Id des Bankkontos bei MangoPay</param>
/// <returns>MangoPayResult mit Bankkonto oder null, wenn keines gefunden</returns>
Task<MangoPayResult<BankAccount>> GetBankAccountAsync(string appUserId, string mangoPayUserId, string bankAccountId);
/// <summary>
/// Deaktiveren eines Bankkontos für einen App-User
/// </summary>
/// <param name="mangoPayUserId">Id des Benutzers bei MangoPay</param>
/// <param name="bankAccountId">Id des Bankkontos bei MangoPay</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> DeactivateBankAccountAsync(string mangoPayUserId, string bankAccountId);
/// <summary>
/// Transferieren von Geld vom Guthaben-Konto zum Transaktions-Konto
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="ammount">Betrag der transferiert werden soll</param>
/// <param name="tag">Tag der zum Transfer abgelegt werden soll</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> TransferMoneyFromCreditToFeeAccountAsync(string appUserId, long ammount, string tag);
/// <summary>
/// Transferieren von Geld vom Transaktions-Konto zum Guthaben-Konto
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="ammount">Betrag der transferiert werden soll</param>
/// <param name="tag">Tag der zum Transfer abgelegt werden soll</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> TransferMoneyFromFeeToCreditAccountAsync(string appUserId, long ammount, string tag);
/// <summary>
/// Transferieren von Geld von einem Wallet zu einem anderen
/// </summary>
/// <param name="sourceAppUserId">Quell-App-UserId</param>
/// <param name="targetAppUserId">Ziel-App-UserId</param>
/// <param name="walkId">Id des Walks</param>
/// <param name="ammount">Betrag der transferiert werden soll</param>
/// <param name="fees">Gebühren an gehGassi</param>
/// <param name="tag">Tag der zum Transfer abgelegt werden soll</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> TransferMoneyAsync(string sourceAppUserId, string targetAppUserId, string walkId, long ammount, long fees, string tag);
/// <summary>
/// Transferiert Geld von einem Wallet zu einem anderen
/// </summary>
/// <param name="sourceMangopayUserId">Id des Mangopayusers der zahlt</param>
/// <param name="sourceWalletId">Quellwallet Id</param>
/// <param name="targetMangopayUserId">Id des Mangopayusers der die Zahlung erhält</param>
/// <param name="targetWalletId">Zielwallet Id</param>
/// <param name="walkId">Id des Walks - oder leer</param>
/// <param name="ammount">Betrag</param>
/// <param name="fees">Optinal: Gebühren an gehGassi</param>
/// <param name="tag">Tag der zum Transfer abgelegt werden soll</param>
/// <param name="sourceAppUserId">Optional: Quell-App-UserId</param>
/// <param name="targetAppUserId">Optional: Ziel-App-UserId</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> TransferMoneyAsync(string sourceMangopayUserId, string sourceWalletId, string targetMangopayUserId, string targetWalletId, string walkId, long ammount, long fees, string tag, string sourceAppUserId = "", string targetAppUserId = "");
/// <summary>
/// Erstellen einer Kreditkarten-Einzahlung
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="walkId">Id des Walks</param>
/// <param name="ammount">Betrag der eingezahlt werden soll</param>
/// <param name="fees">Gebühren die an gehgassi abgeführt werden</param>
/// <param name="fromCredit">Betrag der zusätzlich vom Guthabenkonto genommen werden muss</param>
/// <param name="tag">Tag der zur Einzahlung abgelegt werden soll</param>
/// <param name="returnUrl">Return-Url für MangoPay</param>
/// <returns>MangopayResult mit einem string der eine ReturnUrl beinhaltet die die App öffnen muss</returns>
Task<MangoPayResult<string>> CreatePayInCardAsync(string appUserId, string walkId, long ammount, long fees, long fromCredit, string tag, string returnUrl);
/// <summary>
/// Erstellen einer Maestro-Einzahlung
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="walkId">Id des Walks</param>
/// <param name="ammount">Betrag der eingezahlt werden soll</param>
/// <param name="fees">Gebühren die an gehgassi abgeführt werden</param>
/// <param name="fromCredit">Betrag der zusätzlich vom Guthabenkonto genommen werden muss</param>
/// <param name="tag">Tag der zur Einzahlung abgelegt werden soll</param>
/// <param name="returnUrl">Return-Url für MangoPay</param>
/// <returns>MangopayResult mit einem string der eine ReturnUrl beinhaltet die die App öffnen muss</returns>
Task<MangoPayResult<string>> CreatePayInMaestroAsync(string appUserId, string walkId, long ammount, long fees, long fromCredit, string tag, string returnUrl);
/// <summary>
/// Erstellen einer Klarna-Einzahlung
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="walkId">Id des Walks</param>
/// <param name="ammount">Betrag der eingezahlt werden soll</param>
/// <param name="fees">Gebühren die an gehgassi abgeführt werden</param>
/// <param name="fromCredit">Betrag der zusätzlich vom Guthabenkonto genommen werden muss</param>
/// <param name="tag">Tag der zur Einzahlung abgelegt werden soll</param>
/// <param name="returnUrl">Return-Url für MangoPay</param>
/// <returns>MangopayResult mit einem string der eine ReturnUrl beinhaltet die die App öffnen muss</returns>
Task<MangoPayResult<string>> CreatePayInKlarnaAsync(string appUserId, string walkId, long ammount, long fees, long fromCredit, string tag, string returnUrl);
/// <summary>
/// Erstellen einer PayPal-Einzahlung
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="walkId">Id des Walks</param>
/// <param name="ammount">Betrag der eingezahlt werden soll</param>
/// <param name="fees">Gebühren die an gehgassi abgeführt werden</param>
/// <param name="fromCredit">Betrag der zusätzlich vom Guthabenkonto genommen werden muss</param>
/// <param name="tag">Tag der zur Einzahlung abgelegt werden soll</param>
/// <param name="returnUrl">Return-Url für MangoPay</param>
/// <returns>MangopayResult mit einem string der eine ReturnUrl beinhaltet die die App öffnen muss</returns>
Task<MangoPayResult<string>> CreatePayInPayPalAsync(string appUserId, string walkId, long ammount, long fees, long fromCredit, string tag, string returnUrl);
/// <summary>
/// Gibt eine Transaktion bei Mangopay zurück.
/// Kann zum Prüfen des Status einer Transaktion verwendet werden.
/// </summary>
/// <param name="mangoPayTransactionId">Id der Transaktion bei MangoPay</param>
/// <returns>MangoPayResult mit Transaktion</returns>
Task<MangoPayResult<MangoPayTransaction>> GetTransactionAsync(string mangoPayTransactionId);
/// <summary>
/// Erstellen eines Kyc-Dokuments
/// </summary>
/// <param name="mangoPayUserId">Id des Users bei MangoPay</param>
/// <param name="type">Typ des Dokumentes</param>
/// <param name="files">Liste von Dateien als byte-Array</param>
/// <returns>MangoPayResult mit der ID des Dokumentes</returns>
Task<MangoPayResult<string>> CreateKycDocumentAsync(string mangoPayUserId, IdentityDocumentType type, List<byte[]> files);
/// <summary>
/// Gibt ein Kyc-Dokument zurück
/// </summary>
/// <param name="documentId">Id des Dokumentes bei MangoPay</param>
/// <returns>Kyc-Dokument</returns>
Task<MangoPayResult<MangoPayKycDocument>> GetKycDocumentAsync(string documentId);
/// <summary>
/// Gibt eine Auszahlung zurück
/// </summary>
/// <param name="payoutId">Id der Auszalhung</param>
/// <returns>MangoPayResult mit Auszahlung oder null, wenn nicht vorhanden</returns>
Task<MangoPayResult<MangoPayPayout>> GetPayoutAsync(string payoutId);
/// <summary>
/// Erstellen einer Auszahlung
/// </summary>
/// <param name="mangoPayUserId">Id des Users bei Mangopay</param>
/// <param name="mangoPayWalletId">Id des Wallets bei MangoPay</param>
/// <param name="mangoPayBankId">Id der Bankverbindung bei MangoPay</param>
/// <param name="ammount">Summe die Ausgezahlt werden soll in der kleinsten Einheit</param>
/// <param name="tag">TAG mit Referenz auf gehgassi</param>
/// <returns>MangoPayResult mit erstellter Auszahlung</returns>
Task<MangoPayResult<MangoPayPayout>> CreatePayoutAsync(string mangoPayUserId, string mangoPayWalletId, string mangoPayBankId, long ammount, string tag);
/// <summary>
/// Gibt Infos zu einer Rückzahlung zurück
/// </summary>
/// <param name="refundId">Id der Rückzahlung</param>
/// <returns>MangoPayResult</returns>
Task<MangoPayResult<MangoPayRefund>> GetRefundAsync(string refundId);
/// <summary>
/// Erstellen eines Legal-Mangopay-Benutzers für einen Kunden
/// </summary>
/// <param name="customerId">Id des Kunden</param>
/// <param name="suppressCommit">Soll das Commit unterdrückt werden?</param>
/// <returns>MangoPayResult mit der ID des Mangopay-Users</returns>
Task<MangoPayResult<string>> CreateLegalOwnerAsync(long customerId, bool suppressCommit);
/// <summary>
/// Aktualisieren eines Mangopay-Benutzers für einen Kunden
/// </summary>
/// <param name="customerId">Id des Kunden</param>
/// <returns>true wenn erfolgreich, false sonst</returns>
Task<MangoPayResult<bool>> UpdateLegalOwnerAsync(long customerId);
/// <summary>
/// Prüfen ob ein MangoPay-Benutzer für einen Kunden existiert
/// </summary>
/// <param name="mangoPayUserId">Id des Mangopay-Benutzers des Kunden</param>
/// <returns>true wenn existent, false sonst</returns>
Task<MangoPayResult<bool>> LegalOwnerExistsAsync(string mangoPayUserId);
/// <summary>
/// Erstellt ein Wallet für einen Kunden mit einem bestimmten Typ.
/// </summary>
/// <param name="customerUniqueId">Unique Id des Kunden</param>
/// <param name="walletType">Typ des Wallets</param>
/// <param name="description">Beschreibung</param>
/// <returns>Wallet</returns>
Task<MangoPayResult<Wallet>> CreateWalletForCustomerAsync(string customerUniqueId, WalletType walletType, string description);
}
/// <summary>
/// Ergebnis einer MangoPay-Operation
/// </summary>
public class MangoPayResult<T>
{
/// <summary>
/// Anfrage erfolgreich
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Wenn nicht erfolgreich, Fehlermeldung
/// </summary>
public string ErrorMessage { get; set; }
/// <summary>
/// Wenn nicht erfolgreich, Fehlertyp
/// </summary>
public string ErrorType { get; set; }
/// <summary>
/// Wenn nicht erfolgreich, Fehlermeldungen
/// </summary>
public Dictionary<string,string> ErrorMessages { get; set; }
/// <summary>
/// Rückgabe-Wert
/// </summary>
public T Value { get; set; }
/// <summary>
/// Erstellt eine Instanz
/// </summary>
public MangoPayResult()
{
Success = false;
ErrorMessage = string.Empty;
ErrorType = MangoPayErrorCodes.Err_None;
ErrorMessages = new Dictionary<string, string>();
Value = default(T);
}
}
/// <summary>
/// Fehlercodes bei MangoPay Operationen
/// </summary>
public static class MangoPayErrorCodes
{
public const string Err_None = "Err_None";
public const string Err_Unknown = "Err_Unknown";
public const string Err_AppUser_NotFound = "Err_AppUser_NotFound";
public const string Err_User_NotFound = "Err_User_NotFound";
public const string Err_User_Create_Exists = "Err_User_Create_Exists";
public const string Err_User_BirthDate = "Err_User_BirthDate";
public const string Err_User_Nationality = "Err_User_Nationality";
public const string Err_User_MainResidence = "Err_User_MainResidence";
public const string Err_User_Update_NotExists = "Err_User_Update_NotExists";
public const string Err_Wallet_NotExists = "Err_Wallet_NotExists";
public const string Err_Transfer_NotEnoughMoney = "Err_Transfer_NotEnoughMoney";
public const string Err_PayIn_Failed = "Err_PayIn_Failed";
public const string Err_Kyc_PageFailed = "Err_Kyc_PageFailed";
public const string Err_Kyc_DocumentFailed = "Err_Kyc_DocumentFailed";
public const string Err_PayOut_Failed = "Err_PayOut_Failed";
public const string Err_Refund_Failed = "Err_Refund_Failed";
public const string Err_Customer_DataMissing = "Err_Customer_DataMissing";
public const string Err_Customer_NotFound = "Err_Customer_NotFound";
}
/// <summary>
/// Repräsentiert eine Transaktion bei Mangopay
/// </summary>
public class MangoPayTransaction
{
/// <summary>
/// Transaktions-ID
/// </summary>
public string TransactionId { get; set; }
/// <summary>
/// Id des Benutzers bei MangoPay der die Transaktion veranlasst hat
/// </summary>
public string AuthorId { get; set; }
/// <summary>
/// Id des Benutzers bei MangoPay der die Transaktion erhalten hat
/// </summary>
public string CreditedUserId { get; set; }
/// <summary>
/// Betrag der dem Benutzer abgezogen wurde, der die Transaktion veranlasst hat
/// </summary>
public long AmmountDebited { get; set; }
/// <summary>
/// Betrag der dem Benutzer gutgeschrieben wurde, der die Transaktion erhalten hat
/// </summary>
public long AmmountCredited { get; set; }
/// <summary>
/// Betrag der als Gebühr abgezogen wurde
/// </summary>
public long Fees { get; set; }
/// <summary>
/// Status der Transaktion
/// </summary>
public PaymentTransactionStatus Status { get; set; }
/// <summary>
/// Ergebniscode der Transaktion
/// </summary>
public string ResultCode { get; set; }
/// <summary>
/// Ergebnismeldung der Transaktion
/// </summary>
public string ResultMessage { get; set; }
/// <summary>
/// Datum der Ausführung
/// </summary>
public DateTimeOffset? ExecutionDate { get; set; }
/// <summary>
/// Transaktions-Typ
/// </summary>
public MangoPayTransactionType TransactionType { get; set; }
/// <summary>
/// Id des Wallets bei Mangopay das die Gutschrift erhalten hat
/// </summary>
public string CreditedWalletId { get; set; }
/// <summary>
/// Id des Wallets bei Mangopay das die Belastung erhalten hat
/// </summary>
public string DebitedWalletId { get; set; }
/// <summary>
/// Typ der Einzahlung
/// </summary>
public PayInType PayInType { get; set; }
}
/// <summary>
/// Repräsentiert ein KYC-Dokument bei MangoPay
/// </summary>
public class MangoPayKycDocument
{
/// <summary>
/// Id des Dokumentes
/// </summary>
public string DocumentId { get; set; }
/// <summary>
/// ID des MangoPay-Users
/// </summary>
public string UserId { get; set; }
/// <summary>
/// ID des Kyc-Dokuments
/// </summary>
public IdentityDocumentType Type { get; set; }
/// <summary>
/// Status des Kyc-Dokuments
/// </summary>
public IdentityDocumentStatus Status { get; set; }
/// <summary>
/// Typ der Ablehnung
/// </summary>
public string RefusedReasonType { get; set; }
/// <summary>
/// Meldung der Ablehnung
/// </summary>
public string RefusedReasonMessage { get; set; }
/// <summary>
/// Liste von Detail-Codes wenn ein Dokument abgelehnt wurde
/// </summary>
public List<string> Flags { get; set; }
/// <summary>
/// Datum der Bearbeitung
/// </summary>
public DateTimeOffset? ProcessedDate { get; set; }
}
/// <summary>
/// Repräsentiert eine Auszahlung bei Mangopay
/// </summary>
public class MangoPayPayout
{
/// <summary>
/// Id der Auszahlung
/// </summary>
public string PayoutId { get; set; }
/// <summary>
/// ID des MangoPay-Users
/// </summary>
public string UserId { get; set; }
/// <summary>
/// Datum der Auführung
/// </summary>
public DateTimeOffset? ExecutionDate { get; set; }
/// <summary>
/// Result code.
/// </summary>
public string ResultCode { get; set; }
/// <summary>
/// The pre-authorization result message explaining the result code.
/// </summary>
public string ResultMessage { get; set; }
/// <summary>
/// Status der Transaktion
/// </summary>
public PaymentTransactionStatus Status { get; set; }
}
/// <summary>
/// Repräsentiert eine Rückzahlung bei Mangopay
/// </summary>
public class MangoPayRefund
{
/// <summary>
/// ID der Rücküberweisung
/// </summary>
public string RefundId { get; set; }
/// <summary>
/// ID der originalen Transaktion (Id der Auszahlungs-Transaktion)
/// </summary>
public string OriginalTransactionId { get; set; }
/// <summary>
/// Typ Grund für Rückzahlung
/// </summary>
[MaxLength(255)]
public string RefundReasonType { get; set; }
/// <summary>
/// Beschreibung Grund Rückzahlung
/// </summary>
[MaxLength(255)]
public string RefundReasonMessage { get; set; }
/// <summary>
/// Status der Transaktion
/// </summary>
public PaymentTransactionStatus Status { get; set; }
}
}