Skip to content

Commit

Permalink
[feature] identity verification (#244)
Browse files Browse the repository at this point in the history
* added support for creating and fetching IdentityVerifications

* support fetching identity verification checks and added missing event types

---------

Co-authored-by: Iulian Masar <[email protected]>
  • Loading branch information
iulian03 and Iulian Masar authored Feb 26, 2025
1 parent 0e59176 commit 753206d
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 6 deletions.
65 changes: 65 additions & 0 deletions MangoPay.SDK.Tests/ApiIdentityVerificationsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Threading.Tasks;
using MangoPay.SDK.Entities.GET;
using MangoPay.SDK.Entities.POST;
using NUnit.Framework;

namespace MangoPay.SDK.Tests
{
[TestFixture]
[Explicit]
public class ApiIdentityVerifications : BaseTest
{
private static IdentityVerificationDTO _identityVerification;

[Test]
public async Task Test_CreateIdentityVerification()
{
await GetNewIdentityVerification();

Assert.IsNotNull(_identityVerification);
Assert.IsNotNull(_identityVerification.ReturnUrl);
Assert.IsNotNull(_identityVerification.HostedUrl);
Assert.IsNotNull(_identityVerification.Status);
}

[Test]
public async Task Test_GetIdentityVerification()
{
await GetNewIdentityVerification();
IdentityVerificationDTO fetched = await Api.IdentityVerifications.GetAsync(_identityVerification.Id);

Assert.IsNotNull(fetched);
Assert.AreEqual(_identityVerification.HostedUrl, fetched.HostedUrl);
Assert.AreEqual(_identityVerification.ReturnUrl, fetched.ReturnUrl);
Assert.AreEqual(_identityVerification.Status, fetched.Status);
}

[Test]
public async Task Test_GetIdentityVerificationChecks()
{
await GetNewIdentityVerification();
IdentityVerificationCheckDTO check =
await Api.IdentityVerifications.GetChecksAsync(_identityVerification.Id);

Assert.IsNotNull(check);
Assert.IsNotNull(check.SessionId);
Assert.IsNotNull(check.Status);
Assert.IsNotNull(check.LastUpdate);
Assert.IsNotNull(check.CreationDate);
Assert.IsNotNull(check.Checks);
}

private async Task GetNewIdentityVerification()
{
if (_identityVerification == null)
{
UserNaturalDTO john = await GetJohn();
IdentityVerificationPostDto postDto = new IdentityVerificationPostDto();
postDto.ReturnUrl = "https://example.com";
postDto.Tag = "Created by the .NET SDK";

_identityVerification = await Api.IdentityVerifications.CreateAsync(postDto, john.Id);
}
}
}
}
6 changes: 5 additions & 1 deletion MangoPay.SDK/Core/APIs/ApiBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,11 @@ public abstract class ApiBase
{ MethodKey.VirtualAccountDeactivate, new ApiEndPoint("/wallets/{0}/virtual-accounts/{1}", RequestType.PUT) },
{ MethodKey.VirtualAccountGet, new ApiEndPoint("/wallets/{0}/virtual-accounts/{1}", RequestType.GET) },
{ MethodKey.VirtualAccountGetAll, new ApiEndPoint("/wallets/{0}/virtual-accounts", RequestType.GET) },
{ MethodKey.VirtualAccountGetAvailabilities, new ApiEndPoint("/virtual-accounts/availability", RequestType.GET) }
{ MethodKey.VirtualAccountGetAvailabilities, new ApiEndPoint("/virtual-accounts/availability", RequestType.GET) },

{ MethodKey.IdentityVerificationCreate, new ApiEndPoint("/users/{0}/identity-verifications", RequestType.POST) },
{ MethodKey.IdentityVerificationGet, new ApiEndPoint("/identity-verifications/{0}", RequestType.GET) },
{ MethodKey.IdentityVerificationGetChecks, new ApiEndPoint("/identity-verifications/{0}/checks", RequestType.GET) }
};

/// <summary>Creates new API instance.</summary>
Expand Down
48 changes: 48 additions & 0 deletions MangoPay.SDK/Core/APIs/ApiIdentityVerifications.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Threading.Tasks;
using MangoPay.SDK.Core.Enumerations;
using MangoPay.SDK.Entities.GET;
using MangoPay.SDK.Entities.POST;

namespace MangoPay.SDK.Core.APIs
{
/// <summary>API for identity verification.</summary>
public class ApiIdentityVerifications : ApiBase
{
/// <summary>Instantiates new ApiIdentityVerification object.</summary>
/// <param name="root">Root/parent instance that holds the OAuthToken and Configuration instance.</param>
public ApiIdentityVerifications(MangoPayApi root) : base(root)
{
}

/// <summary>Creates new identity verification.</summary>
/// <param name="idempotentKey">Idempotent key for this request.</param>
/// <param name="identityVerification">Object instance to be created.</param>
/// <param name="userId">The user identifier.</param>
/// <returns>Object instance returned from API.</returns>
public async Task<IdentityVerificationDTO> CreateAsync(IdentityVerificationPostDto identityVerification,
string userId, string idempotentKey = null)
{
return await CreateObjectAsync<IdentityVerificationDTO, IdentityVerificationPostDto>(
MethodKey.IdentityVerificationCreate, identityVerification,
idempotentKey, userId);
}

/// <summary>See the status and basic details of an identity verification session</summary>
/// <param name="id">Identity verification identitifer.</param>
/// <returns>Object instance returned from API.</returns>
public async Task<IdentityVerificationDTO> GetAsync(string id)
{
return await this.GetObjectAsync<IdentityVerificationDTO>(MethodKey.IdentityVerificationGet,
entitiesId: id);
}

/// <summary>Obtain verified user data and results of each check performed</summary>
/// <param name="id">Identity verification identitifer.</param>
/// <returns>Object instance returned from API.</returns>
public async Task<IdentityVerificationCheckDTO> GetChecksAsync(string id)
{
return await this.GetObjectAsync<IdentityVerificationCheckDTO>(MethodKey.IdentityVerificationGetChecks,
entitiesId: id);
}
}
}
10 changes: 7 additions & 3 deletions MangoPay.SDK/Core/Enumerations/EventType.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

using System;

namespace MangoPay.SDK.Core.Enumerations
{
/// <summary>Event types enumeration.</summary>
Expand Down Expand Up @@ -105,6 +103,12 @@ public enum EventType
VIRTUAL_ACCOUNT_ACTIVE,
VIRTUAL_ACCOUNT_BLOCKED,
VIRTUAL_ACCOUNT_CLOSED,
VIRTUAL_ACCOUNT_FAILED
VIRTUAL_ACCOUNT_FAILED,

IDENTITY_VERIFICATION_VALIDATED,
IDENTITY_VERIFICATION_FAILED,
IDENTITY_VERIFICATION_INCONCLUSIVE,
IDENTITY_VERIFICATION_OUTDATED,
IDENTITY_VERIFICATION_TIMEOUT
}
}
4 changes: 4 additions & 0 deletions MangoPay.SDK/Core/Enumerations/MethodKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,5 +205,9 @@ public enum MethodKey
VirtualAccountGetAll,
VirtualAccountDeactivate,
VirtualAccountGetAvailabilities,

IdentityVerificationCreate,
IdentityVerificationGet,
IdentityVerificationGetChecks
}
}
37 changes: 37 additions & 0 deletions MangoPay.SDK/Entities/GET/CheckDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using MangoPay.SDK.Core;
using Newtonsoft.Json;

namespace MangoPay.SDK.Entities.GET
{
public class CheckDTO
{
/// <summary>The unique identifier of the verification check.</summary>
public string CheckId { get; set; }

/// <summary>
/// Type of verification check performed:
/// <para>BUSINESS_VERIFICATION - Verification of the business entity of a Legal User.</para>
/// <para>IDENTITY_DOCUMENT_VERIFICATION - Verification of the identity document of a Natural User or the legal representative of a Legal User.</para>
/// <para>PERSONS_SIGNIFICANT_CONTROL - Verification of a person of significant control of a Legal User.</para>
/// </summary>
public string Type { get; set; }

/// <summary>Returned values: VALIDATED, REFUSED, REVIEW</summary>
public string CheckStatus { get; set; }

/// <summary>The date and time at which the check was created.</summary>
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime CreationDate { get; set; }

/// <summary>The date and time at which the check was last updated.</summary>
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime LastUpdate { get; set; }

/// <summary>
/// The data points collected and verified during the check.
/// </summary>
public List<CheckDataDTO> Data { get; set; }
}
}
11 changes: 11 additions & 0 deletions MangoPay.SDK/Entities/GET/CheckDataDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace MangoPay.SDK.Entities.GET
{
public class CheckDataDTO
{
/// <summary>The type of the data point.</summary>
public string Type { get; set; }

/// <summary>The value of the data point.</summary>
public string Value { get; set; }
}
}
34 changes: 34 additions & 0 deletions MangoPay.SDK/Entities/GET/IdentityVerificationCheckDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using MangoPay.SDK.Core;
using Newtonsoft.Json;

namespace MangoPay.SDK.Entities.GET
{
public class IdentityVerificationCheckDTO : EntityBase
{
/// <summary>Unique identifier for the entire verification session.</summary>
public string SessionId { get; set; }

/// <summary>
/// The status of the identity verification session:
/// <para>PENDING – The session is available on the HostedUrl, to which the user must be redirected to complete it.</para>
/// <para>VALIDATED – The session was successful.</para>
/// <para>REFUSED – The session was refused.</para>
/// <para>REVIEW – The session is under manual review by Mangopay.</para>
/// <para>OUTDATED – The session is no longer valid (likely due to expired documents used during the session).</para>
/// <para>TIMEOUT – The session timed out due to inactivity.</para>
/// <para>ERROR – The session was not completed because an error occurred.</para>
/// </summary>
public string Status { get; set; }

/// <summary>The date and time at which the session was last updated.</summary>
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime LastUpdate { get; set; }

/// <summary>
/// The details of the individual verification checks performed during the session.
/// </summary>
public List<CheckDTO> Checks { get; set; }
}
}
23 changes: 23 additions & 0 deletions MangoPay.SDK/Entities/GET/IdentityVerificationDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace MangoPay.SDK.Entities.GET
{
public class IdentityVerificationDTO : EntityBase
{
/// <summary>The URL to which the user is returned after the hosted identity verification session, regardless of the outcome.</summary>
public string ReturnUrl { get; set; }

/// <summary>The URL to redirect the user to for the hosted identity verification session.</summary>
public string HostedUrl { get; set; }

/// <summary>
/// The status of the identity verification session:
/// <para>PENDING – The session is available on the HostedUrl, to which the user must be redirected to complete it.</para>
/// <para>VALIDATED – The session was successful.</para>
/// <para>REFUSED – The session was refused.</para>
/// <para>REVIEW – The session is under manual review by Mangopay.</para>
/// <para>OUTDATED – The session is no longer valid (likely due to expired documents used during the session).</para>
/// <para>TIMEOUT – The session timed out due to inactivity.</para>
/// <para>ERROR – The session was not completed because an error occurred.</para>
/// </summary>
public string Status { get; set; }
}
}
8 changes: 8 additions & 0 deletions MangoPay.SDK/Entities/POST/IdentityVerificationPostDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MangoPay.SDK.Entities.POST
{
public class IdentityVerificationPostDto : EntityPostBase
{
/// <summary>The URL to which the user is returned after the hosted identity verification session, regardless of the outcome.</summary>
public string ReturnUrl { get; set; }
}
}
7 changes: 5 additions & 2 deletions MangoPay.SDK/MangoPayApi.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using MangoPay.SDK.Core;
using System;
using MangoPay.SDK.Core;
using MangoPay.SDK.Core.APIs;
using System;

namespace MangoPay.SDK
{
Expand Down Expand Up @@ -44,6 +44,7 @@ public MangoPayApi()
Deposits = new ApiDeposits(this);
Conversions = new ApiConversions(this);
VirtualAccounts = new ApiVirtualAccounts(this);
IdentityVerifications = new ApiIdentityVerifications(this);
}

/// <summary>Provides authorization token methods.</summary>
Expand Down Expand Up @@ -130,6 +131,8 @@ public MangoPayApi()

public ApiVirtualAccounts VirtualAccounts;

public ApiIdentityVerifications IdentityVerifications;

#endregion

#region Internal and private
Expand Down

0 comments on commit 753206d

Please sign in to comment.