diff --git a/src/CheckoutSdk/CheckoutApi.cs b/src/CheckoutSdk/CheckoutApi.cs
index b310977d..979ba5e4 100644
--- a/src/CheckoutSdk/CheckoutApi.cs
+++ b/src/CheckoutSdk/CheckoutApi.cs
@@ -8,6 +8,7 @@
using Checkout.Forward;
using Checkout.Instruments;
using Checkout.Metadata;
+using Checkout.NetworkTokens;
using Checkout.Payments;
using Checkout.Payments.Contexts;
using Checkout.Payments.Hosted;
@@ -45,6 +46,7 @@ public class CheckoutApi : ICheckoutApi
private readonly IPaymentContextsClient _paymentContextsClient;
private readonly IPaymentSessionsClient _paymentSessionsClient;
private readonly IForwardClient _forwardClient;
+ private readonly INetworkTokensClient _networkTokensClient;
public CheckoutApi(CheckoutConfiguration configuration)
{
@@ -75,6 +77,7 @@ public CheckoutApi(CheckoutConfiguration configuration)
_paymentContextsClient = new PaymentContextsClient(baseApiClient, configuration);
_paymentSessionsClient = new PaymentSessionsClient(baseApiClient, configuration);
_forwardClient = new ForwardClient(baseApiClient, configuration);
+ _networkTokensClient = new NetworkTokensClient(baseApiClient, configuration);
}
private static ApiClient BaseApiClient(CheckoutConfiguration configuration)
@@ -212,5 +215,11 @@ public IForwardClient ForwardClient()
{
return _forwardClient;
}
+
+ public INetworkTokensClient NetworkTokensClient()
+ {
+ return _networkTokensClient;
+ }
+
}
-}
\ No newline at end of file
+}
diff --git a/src/CheckoutSdk/Common/Resource.cs b/src/CheckoutSdk/Common/Resource.cs
index d824460d..e986936a 100644
--- a/src/CheckoutSdk/Common/Resource.cs
+++ b/src/CheckoutSdk/Common/Resource.cs
@@ -23,6 +23,11 @@ public Link GetUploadLink()
return GetLink("upload");
}
+ public Link GetCryptogramLink()
+ {
+ return GetLink("cryptogram");
+ }
+
public bool HasLink(string relation)
{
return Links.ContainsKey(relation);
diff --git a/src/CheckoutSdk/Forward/ForwardClient.cs b/src/CheckoutSdk/Forward/ForwardClient.cs
index a460282e..4ffca6c1 100644
--- a/src/CheckoutSdk/Forward/ForwardClient.cs
+++ b/src/CheckoutSdk/Forward/ForwardClient.cs
@@ -1,11 +1,13 @@
using Checkout.Forward.Requests;
using Checkout.Forward.Responses;
-using System;
using System.Threading;
using System.Threading.Tasks;
namespace Checkout.Forward
{
+ ///
+ /// Forward
+ ///
public class ForwardClient : AbstractClient, IForwardClient
{
private const string Forward = "forward";
@@ -15,6 +17,12 @@ public ForwardClient(IApiClient apiClient, CheckoutConfiguration configuration)
{
}
+ ///
+ /// Forward an API request
+ /// [BETA]
+ /// Forwards an API request to a third-party endpoint.
+ /// For example, you can forward payment credentials you've stored in our Vault to a third-party payment processor.
+ ///
public Task ForwardAnApiRequest(ForwardRequest forwardRequest,
CancellationToken cancellationToken = default)
{
@@ -27,6 +35,11 @@ public Task ForwardAnApiRequest(ForwardRequest forwardRequ
);
}
+ ///
+ /// Get forward request
+ /// Retrieve the details of a successfully forwarded API request.
+ /// The details can be retrieved for up to 14 days after the request was initiated.
+ ///
public Task GetForwardRequest(string forwardId,
CancellationToken cancellationToken = default)
{
diff --git a/src/CheckoutSdk/Forward/IForwardClient.cs b/src/CheckoutSdk/Forward/IForwardClient.cs
index bfe4bc05..8d192a9a 100644
--- a/src/CheckoutSdk/Forward/IForwardClient.cs
+++ b/src/CheckoutSdk/Forward/IForwardClient.cs
@@ -5,21 +5,24 @@
namespace Checkout.Forward
{
+ ///
+ /// Forward
+ ///
public interface IForwardClient
{
///
- /// Forward an API request
- /// Beta
- /// Forwards an API request to a third-party endpoint.
- /// For example, you can forward payment credentials you've stored in our Vault to a third-party payment processor.
+ /// Forward an API request
+ /// [BETA]
+ /// Forwards an API request to a third-party endpoint.
+ /// For example, you can forward payment credentials you've stored in our Vault to a third-party payment processor.
///
Task ForwardAnApiRequest(ForwardRequest forwardRequest,
CancellationToken cancellationToken = default);
///
- /// Get forward request
- /// Retrieve the details of a successfully forwarded API request.
- /// The details can be retrieved for up to 14 days after the request was initiated.
+ /// Get forward request
+ /// Retrieve the details of a successfully forwarded API request.
+ /// The details can be retrieved for up to 14 days after the request was initiated.
///
Task GetForwardRequest(string forwardId, CancellationToken cancellationToken = default);
}
diff --git a/src/CheckoutSdk/ICheckoutApi.cs b/src/CheckoutSdk/ICheckoutApi.cs
index ac042857..9d924002 100644
--- a/src/CheckoutSdk/ICheckoutApi.cs
+++ b/src/CheckoutSdk/ICheckoutApi.cs
@@ -8,6 +8,7 @@
using Checkout.Forward;
using Checkout.Instruments;
using Checkout.Metadata;
+using Checkout.NetworkTokens;
using Checkout.Payments;
using Checkout.Payments.Contexts;
using Checkout.Payments.Hosted;
@@ -65,5 +66,7 @@ public interface ICheckoutApi : ICheckoutApiClient
IPaymentSessionsClient PaymentSessionsClient();
IForwardClient ForwardClient();
+
+ INetworkTokensClient NetworkTokensClient();
}
-}
\ No newline at end of file
+}
diff --git a/src/CheckoutSdk/NetworkTokens/Common/Responses/Card.cs b/src/CheckoutSdk/NetworkTokens/Common/Responses/Card.cs
new file mode 100644
index 00000000..bf3b68df
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/Common/Responses/Card.cs
@@ -0,0 +1,14 @@
+namespace Checkout.NetworkTokens.Common.Responses
+{
+ public class Card
+ {
+ /// The last four digits of the card number (Required, constraints: ^[0-9]{4}$)
+ public string Last4 { get; set; }
+
+ /// The card's expiration month (Required, constraints: [ 1 .. 12 ], ^[0-9]{1,2}$)
+ public string ExpiryMonth { get; set; }
+
+ /// The card's expiration year (Required, constraints: ^[0-9]{4}$)
+ public string ExpiryYear { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkToken.cs b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkToken.cs
new file mode 100644
index 00000000..fbeebc9c
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkToken.cs
@@ -0,0 +1,45 @@
+namespace Checkout.NetworkTokens.Common.Responses
+{
+ public class NetworkToken
+ {
+ /// Unique token ID assigned by Checkout.com for each token (Required)
+ public string Id { get; set; }
+
+ /// Token status (Required)
+ public StateType State { get; set; }
+
+ ///
+ /// The network token number. This field is only returned when the network token status is one of the
+ /// following: active, suspended, inactive (Constraints: ^[0-9]+$)
+ ///
+ public string Number { get; set; }
+
+ ///
+ /// The network token's expiration month. This field is only returned when the network token status is
+ /// one of the following: active, suspended, inactive (Constraints: ^[0-9]{1,2}$)
+ ///
+ public string ExpiryMonth { get; set; }
+
+ ///
+ /// The network token's expiration year. This field is only returned when the network token status is
+ /// one of the following: active, suspended, inactive (Constraints: ^[0-9]{4}$)
+ ///
+ public string ExpiryYear { get; set; }
+
+ /// The type of token (Required)
+ public NetworkTokenType Type { get; set; }
+
+ /// When the network token was created (Required)
+ public string CreatedOn { get; set; }
+
+ /// When the network token was modified (Required)
+ public string ModifiedOn { get; set; }
+
+ ///
+ /// Unique Payment account reference value assigned to payment account. All affiliated payment tokens,
+ /// as well as the underlying PAN, have the same payment_account_reference (Optional)
+ ///
+ public string PaymentAccountReference { get; set; }
+
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenResponse.cs b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenResponse.cs
new file mode 100644
index 00000000..3d937a49
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenResponse.cs
@@ -0,0 +1,16 @@
+using Checkout.Common;
+
+namespace Checkout.NetworkTokens.Common.Responses
+{
+ public class NetworkTokenResponse : Resource
+ {
+ /// The card details (Required)
+ public Card Card { get; set; }
+
+ /// Network token details (Required)
+ public NetworkToken NetworkToken { get; set; }
+
+ /// Token requestor ID (Optional)
+ public string TokenRequestorId { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenType.cs b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenType.cs
new file mode 100644
index 00000000..b36635e0
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/Common/Responses/NetworkTokenType.cs
@@ -0,0 +1,12 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.Common.Responses
+{
+ public enum NetworkTokenType
+ {
+ [EnumMember(Value = "vts")] Vts,
+
+ [EnumMember(Value = "mdes")] Mdes,
+
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/Common/Responses/StateType.cs b/src/CheckoutSdk/NetworkTokens/Common/Responses/StateType.cs
new file mode 100644
index 00000000..0ad54446
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/Common/Responses/StateType.cs
@@ -0,0 +1,22 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.Common.Responses
+{
+ public enum StateType
+ {
+ [EnumMember(Value = "active")]
+ Active,
+
+ [EnumMember(Value = "suspended")]
+ Suspended,
+
+ [EnumMember(Value = "inactive")]
+ Inactive,
+
+ [EnumMember(Value = "declined")]
+ Declined,
+
+ [EnumMember(Value = "requested")]
+ Requested
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/GetNetworkTokens/Responses/NetworkTokenByIdResponse.cs b/src/CheckoutSdk/NetworkTokens/GetNetworkTokens/Responses/NetworkTokenByIdResponse.cs
new file mode 100644
index 00000000..4d5cfe0d
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/GetNetworkTokens/Responses/NetworkTokenByIdResponse.cs
@@ -0,0 +1,9 @@
+using Checkout.NetworkTokens.Common.Responses;
+
+namespace Checkout.NetworkTokens.GetNetworkTokens.Responses
+{
+ public class NetworkTokenByIdResponse : NetworkTokenResponse
+ {
+
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/INetworkTokensClient.cs b/src/CheckoutSdk/NetworkTokens/INetworkTokensClient.cs
new file mode 100644
index 00000000..174f3a28
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/INetworkTokensClient.cs
@@ -0,0 +1,59 @@
+using Checkout.NetworkTokens.GetNetworkTokens.Responses;
+using Checkout.NetworkTokens.PatchDelete.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Responses;
+using Checkout.NetworkTokens.PostNetworkTokens.Requests;
+using Checkout.NetworkTokens.PostNetworkTokens.Responses;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Checkout.NetworkTokens
+{
+ ///
+ /// Network Tokens
+ ///
+ public interface INetworkTokensClient
+ {
+ ///
+ /// Provision a Network Token
+ /// [BETA]
+ /// Provisions a network token synchronously. If the merchant stores their cards with Checkout.com, then
+ /// source ID can be used to request a network token for the given card. If the merchant does not store their
+ /// cards with Checkout.com, then card details have to be provided.
+ ///
+ Task ProvisionANetworkToken(
+ ProvisionANetworkTokenRequest provisionANetworkTokenRequest,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// Get Network Token
+ /// [BETA]
+ /// Given network token ID, this endpoint returns network token details: DPAN, expiry date, state, TRID and also
+ /// card details like last four and expiry date.
+ ///
+ Task GetNetworkToken(
+ string networkTokenId,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// Request a cryptogram
+ /// [BETA]
+ /// Using network token ID as an input, this endpoint returns token cryptogram.
+ ///
+ Task RequestACryptogram(
+ string networkTokenId,
+ NetworkTokenCryptogramRequest networkTokenCryptogramRequest,
+ CancellationToken cancellationToken = default);
+
+ ///
+ /// Permanently deletes a network token
+ /// [BETA]
+ /// This endpoint is for permanently deleting a network token. A network token should be deleted when a payment
+ /// instrument it is associated with is removed from file or if the security of the token has been compromised.
+ ///
+ Task PermanentlyDeletesANetworkToken(
+ string networkTokenId,
+ PermanentlyDeleteANetworkTokenRequest permanentlyDeleteANetworkTokenRequest,
+ CancellationToken cancellationToken = default);
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/NetworkTokensClient.cs b/src/CheckoutSdk/NetworkTokens/NetworkTokensClient.cs
new file mode 100644
index 00000000..20ddde27
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/NetworkTokensClient.cs
@@ -0,0 +1,108 @@
+using Checkout.NetworkTokens.GetNetworkTokens.Responses;
+using Checkout.NetworkTokens.PatchDelete.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Responses;
+using Checkout.NetworkTokens.PostNetworkTokens.Requests;
+using Checkout.NetworkTokens.PostNetworkTokens.Responses;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Checkout.NetworkTokens
+{
+ ///
+ /// Network Tokens
+ ///
+ public class NetworkTokensClient : AbstractClient, INetworkTokensClient
+ {
+ private const string NetworkTokensPath = "network-tokens";
+ private const string CryptogramsPath = "cryptograms";
+ private const string DeletePath = "delete";
+
+ public NetworkTokensClient(IApiClient apiClient,
+ CheckoutConfiguration configuration) :
+ base(apiClient, configuration, SdkAuthorizationType.OAuth)
+ {
+ }
+
+ ///
+ /// Provision a Network Token
+ /// [BETA]
+ /// Provisions a network token synchronously. If the merchant stores their cards with Checkout.com, then
+ /// source ID can be used to request a network token for the given card. If the merchant does not store their
+ /// cards with Checkout.com, then card details have to be provided.
+ ///
+ public Task ProvisionANetworkToken(
+ ProvisionANetworkTokenRequest provisionANetworkTokenRequest,
+ CancellationToken cancellationToken = default)
+ {
+ CheckoutUtils.ValidateParams("provisionANetworkTokenRequest", provisionANetworkTokenRequest);
+ return ApiClient.Post(
+ NetworkTokensPath,
+ SdkAuthorization(),
+ provisionANetworkTokenRequest,
+ cancellationToken);
+ }
+
+ ///
+ /// Get Network Token
+ /// [BETA]
+ /// Given network token ID, this endpoint returns network token details: DPAN, expiry date, state, TRID and also
+ /// card details like last four and expiry date.
+ ///
+ public Task GetNetworkToken(string networkTokenId,
+ CancellationToken cancellationToken = default)
+ {
+ CheckoutUtils.ValidateParams("networkTokenId", networkTokenId);
+ return ApiClient.Get(
+ BuildPath(NetworkTokensPath,
+ networkTokenId),
+ SdkAuthorization(),
+ cancellationToken);
+ }
+
+ ///
+ /// Request a cryptogram
+ /// [BETA]
+ /// Using network token ID as an input, this endpoint returns token cryptogram.
+ ///
+ public Task RequestACryptogram(string networkTokenId,
+ NetworkTokenCryptogramRequest networkTokenCryptogramRequest,
+ CancellationToken cancellationToken = default)
+ {
+ CheckoutUtils.ValidateParams("networkTokenId",
+ networkTokenId,
+ "networkTokenCryptogramRequest",
+ networkTokenCryptogramRequest);
+ return ApiClient.Post(
+ BuildPath(NetworkTokensPath,
+ networkTokenId,
+ CryptogramsPath),
+ SdkAuthorization(),
+ networkTokenCryptogramRequest,
+ cancellationToken);
+ }
+
+ ///
+ /// Permanently deletes a network token
+ /// [BETA]
+ /// This endpoint is for permanently deleting a network token. A network token should be deleted when a payment
+ /// instrument it is associated with is removed from file or if the security of the token has been compromised.
+ ///
+ public Task PermanentlyDeletesANetworkToken(string networkTokenId,
+ PermanentlyDeleteANetworkTokenRequest permanentlyDeleteANetworkTokenRequest,
+ CancellationToken cancellationToken = default)
+ {
+ CheckoutUtils.ValidateParams("networkTokenId",
+ networkTokenId,
+ "permanentlyDeleteANetworkTokenRequest",
+ permanentlyDeleteANetworkTokenRequest);
+ return ApiClient.Patch(
+ BuildPath(NetworkTokensPath,
+ networkTokenId,
+ DeletePath),
+ SdkAuthorization(),
+ permanentlyDeleteANetworkTokenRequest,
+ cancellationToken);
+ }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/InitiatedByType.cs b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/InitiatedByType.cs
new file mode 100644
index 00000000..ecdc5b77
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/InitiatedByType.cs
@@ -0,0 +1,14 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.PatchDelete.Requests
+{
+ public enum InitiatedByType
+ {
+ [EnumMember(Value = "cardholder")]
+ Cardholder,
+
+ [EnumMember(Value = "token_requestor")]
+ TokenRequestor,
+
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/PermanentlyDeleteANetworkTokenRequest.cs b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/PermanentlyDeleteANetworkTokenRequest.cs
new file mode 100644
index 00000000..cb490d57
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/PermanentlyDeleteANetworkTokenRequest.cs
@@ -0,0 +1,11 @@
+namespace Checkout.NetworkTokens.PatchDelete.Requests
+{
+ public class PermanentlyDeleteANetworkTokenRequest
+ {
+ /// Who initiated/requested the deletion of the token.
+ public InitiatedByType InitiatedBy { get; set; }
+
+ /// The reason for deletion the token.
+ public ReasonType Reason { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/ReasonType.cs b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/ReasonType.cs
new file mode 100644
index 00000000..9b7b077f
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PatchDelete/Requests/ReasonType.cs
@@ -0,0 +1,13 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.PatchDelete.Requests
+{
+ public enum ReasonType
+ {
+ [EnumMember(Value = "fraud")]
+ Fraud,
+
+ [EnumMember(Value = "other")]
+ Other,
+ }
+}
\ No newline at end of file
diff --git a/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/NetworkTokenCryptogramRequest.cs b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/NetworkTokenCryptogramRequest.cs
new file mode 100644
index 00000000..81ba2d44
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/NetworkTokenCryptogramRequest.cs
@@ -0,0 +1,8 @@
+namespace Checkout.NetworkTokens.PostCryptograms.Requests
+{
+ public class NetworkTokenCryptogramRequest
+ {
+ /// Transaction type the cryptogram is requested for. ยบ
+ public TransactionType TransactionType { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/TransactionType.cs b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/TransactionType.cs
new file mode 100644
index 00000000..0d577f69
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Requests/TransactionType.cs
@@ -0,0 +1,19 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.PostCryptograms.Requests
+{
+ public enum TransactionType
+ {
+ [EnumMember(Value = "ecom")]
+ Ecom,
+
+ [EnumMember(Value = "recurring")]
+ Recurring,
+
+ [EnumMember(Value = "pos")]
+ Pos,
+
+ [EnumMember(Value = "aft")]
+ Aft,
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostCryptograms/Responses/NetworkTokenCryptogramResponse.cs b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Responses/NetworkTokenCryptogramResponse.cs
new file mode 100644
index 00000000..876ff894
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostCryptograms/Responses/NetworkTokenCryptogramResponse.cs
@@ -0,0 +1,16 @@
+using Checkout.Common;
+
+namespace Checkout.NetworkTokens.PostCryptograms.Responses
+{
+ public class NetworkTokenCryptogramResponse : Resource
+ {
+ ///
+ /// The cryptogram from the network token. Will only be refreshed for active network tokens and returned when
+ /// the network token isn't declined or pending
+ ///
+ public string Cryptogram { get; set; }
+
+ /// Electronic Commerce Indicator (ECI) from the issuer.
+ public string Eci { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/ProvisionANetworkTokenRequest.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/ProvisionANetworkTokenRequest.cs
new file mode 100644
index 00000000..6a7a1604
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/ProvisionANetworkTokenRequest.cs
@@ -0,0 +1,10 @@
+using Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources;
+
+namespace Checkout.NetworkTokens.PostNetworkTokens.Requests
+{
+ public class ProvisionANetworkTokenRequest
+ {
+ /// The source object (Required)
+ public AbstractSource Source { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/AbstractSource.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/AbstractSource.cs
new file mode 100644
index 00000000..d866393d
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/AbstractSource.cs
@@ -0,0 +1,9 @@
+namespace Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources
+{
+ public abstract class AbstractSource
+ {
+ /// The source type
+ public SourceType? Type { get; set; }
+ protected AbstractSource(SourceType type) { Type = type; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/CardSource.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/CardSource.cs
new file mode 100644
index 00000000..9462df18
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/CardSource.cs
@@ -0,0 +1,20 @@
+namespace Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources
+{
+ public class CardSource : AbstractSource
+ {
+ /// Initializes a new instance of the CardSource class.
+ public CardSource() : base(SourceType.Card) { }
+
+ /// The card number (Required, constraints: [ 12 .. 19 ] characters, ^[0-9]+$, [ 12 .. 19 ])
+ public string Number { get; set; }
+
+ /// The expiry month of the card (Required, constraints: [ 1 .. 12 ], ^[0-9]{1,2}$)
+ public string ExpiryMonth { get; set; }
+
+ /// The four-digit expiry year of the card (Required, constraints: ^[0-9]{4}$)
+ public string ExpiryYear { get; set; }
+
+ /// The CVV number for the card (Optional, constraints: [ 1 .. 9999 ])
+ public string Cvv { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/IdSource.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/IdSource.cs
new file mode 100644
index 00000000..e81b7c0d
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/IdSource.cs
@@ -0,0 +1,11 @@
+namespace Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources
+{
+ public class IdSource : AbstractSource
+ {
+ /// Initializes a new instance of the IdSource class.
+ public IdSource() : base(SourceType.Id) { }
+
+ /// The card instrument (Required, constraints: ^(src)_(\w{26})$)
+ public string Id { get; set; }
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/SourceType.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/SourceType.cs
new file mode 100644
index 00000000..00ab8e96
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Requests/Sources/SourceType.cs
@@ -0,0 +1,14 @@
+using System.Runtime.Serialization;
+
+namespace Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources
+{
+ public enum SourceType
+ {
+ [EnumMember(Value = "id")]
+ Id,
+
+ [EnumMember(Value = "card")]
+ Card,
+
+ }
+}
diff --git a/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Responses/ProvisionANetworkTokenResponse.cs b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Responses/ProvisionANetworkTokenResponse.cs
new file mode 100644
index 00000000..25d92efa
--- /dev/null
+++ b/src/CheckoutSdk/NetworkTokens/PostNetworkTokens/Responses/ProvisionANetworkTokenResponse.cs
@@ -0,0 +1,9 @@
+using Checkout.NetworkTokens.Common.Responses;
+
+namespace Checkout.NetworkTokens.PostNetworkTokens.Responses
+{
+ public class ProvisionANetworkTokenResponse : NetworkTokenResponse
+ {
+
+ }
+}
diff --git a/src/CheckoutSdk/OAuthScope.cs b/src/CheckoutSdk/OAuthScope.cs
index 29c41196..315baf5e 100644
--- a/src/CheckoutSdk/OAuthScope.cs
+++ b/src/CheckoutSdk/OAuthScope.cs
@@ -51,5 +51,6 @@ public enum OAuthScope
[OAuthScope("issuing:transactions-read")] IssuingTransactionsRead,
[OAuthScope("Payment Context")] PaymentContext,
[OAuthScope("forward")] Forward,
+ [OAuthScope("vault:network-tokens")] VaultNetworkTokens,
}
}
diff --git a/test/CheckoutSdkTest/NetworkTokens/NetworkTokenIntegrationTest.cs b/test/CheckoutSdkTest/NetworkTokens/NetworkTokenIntegrationTest.cs
new file mode 100644
index 00000000..087476a9
--- /dev/null
+++ b/test/CheckoutSdkTest/NetworkTokens/NetworkTokenIntegrationTest.cs
@@ -0,0 +1,75 @@
+using Checkout.NetworkTokens.PatchDelete.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Requests;
+using Checkout.NetworkTokens.PostNetworkTokens.Requests;
+using Checkout.NetworkTokens.PostNetworkTokens.Requests.Sources;
+using Shouldly;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Checkout.NetworkTokens
+{
+ public class NetworkTokenIntegrationTest : SandboxTestFixture
+ {
+ public NetworkTokenIntegrationTest() : base(PlatformType.DefaultOAuth)
+ {
+ }
+
+ [Fact(Skip = "use on demand")]
+ private async Task ShouldProvisionANetworkToken()
+ {
+ var request = new ProvisionANetworkTokenRequest
+ {
+ Source = new IdSource()
+ {
+ Id = "src_wmlfc3zyhqzehihu7giusaaawu"
+ },
+ };
+
+ var response = await DefaultApi.NetworkTokensClient().ProvisionANetworkToken(request);
+
+ response.ShouldNotBeNull();
+ response.Card.ShouldNotBeNull();
+ response.NetworkToken.ShouldNotBeNull();
+ }
+
+ [Fact(Skip = "use on demand")]
+ private async Task ShouldGetNetworkToken()
+ {
+ var networkTokenId = "nt_xgu3isllqfyu7ktpk5z2yxbwna";
+ var response = await DefaultApi.NetworkTokensClient().GetNetworkToken(networkTokenId);
+
+ response.ShouldNotBeNull();
+ response.Card.ShouldNotBeNull();
+ response.NetworkToken.ShouldNotBeNull();
+ }
+
+ [Fact(Skip = "use on demand")]
+ private async Task ShouldGetNetworkTokens()
+ {
+ var networkTokenId = "nt_xgu3isllqfyu7ktpk5z2yxbwna";
+
+ var request = new NetworkTokenCryptogramRequest() { TransactionType = TransactionType.Ecom };
+
+ var response = await DefaultApi.NetworkTokensClient().RequestACryptogram(networkTokenId, request);
+
+ response.ShouldNotBeNull();
+ response.Cryptogram.ShouldNotBeEmpty();
+ }
+
+ [Fact(Skip = "use on demand")]
+ private async Task ShouldPatchNetworkToken()
+ {
+ var networkTokenId = "nt_xgu3isllqfyu7ktpk5z2yxbwna";
+
+ var request = new PermanentlyDeleteANetworkTokenRequest
+ {
+ InitiatedBy = InitiatedByType.TokenRequestor, Reason = ReasonType.Other
+ };
+
+ var response = await DefaultApi.NetworkTokensClient()
+ .PermanentlyDeletesANetworkToken(networkTokenId, request);
+
+ response.HttpStatusCode.ShouldBe(204);
+ }
+ }
+}
diff --git a/test/CheckoutSdkTest/NetworkTokens/NetworkTokensClientTest.cs b/test/CheckoutSdkTest/NetworkTokens/NetworkTokensClientTest.cs
new file mode 100644
index 00000000..a5f22710
--- /dev/null
+++ b/test/CheckoutSdkTest/NetworkTokens/NetworkTokensClientTest.cs
@@ -0,0 +1,125 @@
+using Checkout.NetworkTokens.GetNetworkTokens.Responses;
+using Checkout.NetworkTokens.PatchDelete.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Requests;
+using Checkout.NetworkTokens.PostCryptograms.Responses;
+using Checkout.NetworkTokens.PostNetworkTokens.Requests;
+using Checkout.NetworkTokens.PostNetworkTokens.Responses;
+using Moq;
+using Shouldly;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace Checkout.NetworkTokens
+{
+ public class NetworkTokensClientTest : UnitTestFixture
+ {
+ private readonly SdkAuthorization _authorization = new SdkAuthorization(PlatformType.DefaultOAuth, ValidDefaultSk);
+ private readonly Mock _apiClient = new Mock();
+ private readonly Mock _sdkCredentials = new Mock(PlatformType.DefaultOAuth);
+ private readonly Mock _httpClientFactory = new Mock();
+ private readonly Mock _configuration;
+
+ public NetworkTokensClientTest()
+ {
+ _sdkCredentials.Setup(credentials => credentials.GetSdkAuthorization(SdkAuthorizationType.OAuth))
+ .Returns(_authorization);
+
+ _configuration = new Mock(_sdkCredentials.Object,
+ Environment.Sandbox, _httpClientFactory.Object);
+ }
+
+ [Fact]
+ private async Task ShouldProvisionANetworkToken()
+ {
+ ProvisionANetworkTokenRequest provisionANetworkTokenRequest = new ProvisionANetworkTokenRequest();
+ ProvisionANetworkTokenResponse provisionANetworkTokenResponse = new ProvisionANetworkTokenResponse();
+
+ _apiClient.Setup(apiClient =>
+ apiClient.Post(
+ "network-tokens",
+ _authorization,
+ provisionANetworkTokenRequest,
+ CancellationToken.None, null))
+ .ReturnsAsync(() => provisionANetworkTokenResponse);
+
+ INetworkTokensClient client =
+ new NetworkTokensClient(_apiClient.Object, _configuration.Object);
+
+ ProvisionANetworkTokenResponse response = await client.ProvisionANetworkToken(provisionANetworkTokenRequest);
+
+ response.ShouldNotBeNull();
+ response.ShouldBeSameAs(provisionANetworkTokenResponse);
+ }
+
+ [Fact]
+ private async Task ShouldGetNetworkToken()
+ {
+ string networkTokenId = "network_token_id";
+ NetworkTokenByIdResponse networkTokenByIdResponse = new NetworkTokenByIdResponse();
+
+ _apiClient.Setup(apiClient =>
+ apiClient.Get(
+ "network-tokens/" + networkTokenId,
+ _authorization,
+ CancellationToken.None))
+ .ReturnsAsync(() => networkTokenByIdResponse);
+
+ INetworkTokensClient client =
+ new NetworkTokensClient(_apiClient.Object, _configuration.Object);
+
+ NetworkTokenByIdResponse response = await client.GetNetworkToken(networkTokenId);
+
+ response.ShouldNotBeNull();
+ response.ShouldBeSameAs(networkTokenByIdResponse);
+ }
+
+ [Fact]
+ private async Task ShouldRequestACryptogram()
+ {
+ string networkTokenId = "network_token_id";
+ NetworkTokenCryptogramRequest networkTokenCryptogramRequest = new NetworkTokenCryptogramRequest();
+ NetworkTokenCryptogramResponse networkTokenCryptogramResponse = new NetworkTokenCryptogramResponse();
+
+ _apiClient.Setup(apiClient =>
+ apiClient.Post(
+ "network-tokens/" + networkTokenId + "/cryptograms",
+ _authorization,
+ networkTokenCryptogramRequest,
+ CancellationToken.None, null))
+ .ReturnsAsync(() => networkTokenCryptogramResponse);
+
+ INetworkTokensClient client =
+ new NetworkTokensClient(_apiClient.Object, _configuration.Object);
+
+ NetworkTokenCryptogramResponse response = await client.RequestACryptogram(networkTokenId, networkTokenCryptogramRequest);
+
+ response.ShouldNotBeNull();
+ response.ShouldBeSameAs(networkTokenCryptogramResponse);
+ }
+
+ [Fact]
+ private async Task ShouldPermanentlyDeleteANetworkToken()
+ {
+ string networkTokenId = "network_token_id";
+ PermanentlyDeleteANetworkTokenRequest permanentlyDeleteANetworkTokenRequest = new PermanentlyDeleteANetworkTokenRequest();
+ EmptyResponse emptyResponse = new EmptyResponse();
+
+ _apiClient.Setup(apiClient =>
+ apiClient.Patch(
+ "network-tokens/" + networkTokenId + "/delete",
+ _authorization,
+ permanentlyDeleteANetworkTokenRequest,
+ CancellationToken.None, null))
+ .ReturnsAsync(() => emptyResponse);
+
+ INetworkTokensClient client =
+ new NetworkTokensClient(_apiClient.Object, _configuration.Object);
+
+ EmptyResponse response = await client.PermanentlyDeletesANetworkToken(networkTokenId, permanentlyDeleteANetworkTokenRequest);
+
+ response.ShouldNotBeNull();
+ response.ShouldBeSameAs(emptyResponse);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/CheckoutSdkTest/TestCardSource.cs b/test/CheckoutSdkTest/TestCardSource.cs
index 3f5fd4d9..ffd2bd0f 100644
--- a/test/CheckoutSdkTest/TestCardSource.cs
+++ b/test/CheckoutSdkTest/TestCardSource.cs
@@ -13,7 +13,7 @@ static TestCardSource()
Visa.Name = "Mr. Test";
Visa.Number = "4242424242424242";
Visa.ExpiryMonth = 6;
- Visa.ExpiryYear = 2025;
+ Visa.ExpiryYear = 2030;
Visa.Cvv = "100";
}