diff --git a/MangoPay.SDK.Tests/ApiConversionsTest.cs b/MangoPay.SDK.Tests/ApiConversionsTest.cs new file mode 100644 index 0000000..b364949 --- /dev/null +++ b/MangoPay.SDK.Tests/ApiConversionsTest.cs @@ -0,0 +1,134 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using MangoPay.SDK.Core.Enumerations; +using MangoPay.SDK.Entities; +using MangoPay.SDK.Entities.GET; +using MangoPay.SDK.Entities.POST; +using NUnit.Framework; + +namespace MangoPay.SDK.Tests +{ + [TestFixture] + public class ApiConversionsTest : BaseTest + { + [Test] + public async Task Test_GetConversionRate() + { + var conversionRate = await Api.Conversions.GetConversionRate("EUR", "GBP"); + + Assert.IsNotNull(conversionRate); + Assert.IsNotNull(conversionRate.ClientRate); + Assert.IsNotNull(conversionRate.MarketRate); + } + + [Test] + public async Task Test_CreateInstantConversion() + { + var createdInstantConversion = await CreateInstantConversion(); + + Assert.IsNotNull(createdInstantConversion); + Assert.IsNotNull(createdInstantConversion.CreditedFunds.Amount); + Assert.IsNotNull(createdInstantConversion.DebitedFunds.Amount); + Assert.AreEqual(createdInstantConversion.Status, TransactionStatus.SUCCEEDED); + Assert.AreEqual(createdInstantConversion.Type, TransactionType.CONVERSION); + } + + [Test] + public async Task Test_GetInstantConversion() + { + var createdInstantConversion = await CreateInstantConversion(); + var returnedInstantConversion = await Api.Conversions.GetInstantConversion(createdInstantConversion.Id); + + Assert.IsNotNull(returnedInstantConversion); + Assert.IsNotNull(returnedInstantConversion.CreditedFunds.Amount); + Assert.IsNotNull(returnedInstantConversion.DebitedFunds.Amount); + Assert.AreEqual(returnedInstantConversion.Status, TransactionStatus.SUCCEEDED); + Assert.AreEqual(returnedInstantConversion.Type, TransactionType.CONVERSION); + } + + [Test] + public async Task Test_CreateConversionQuote() + { + var createdConversionQuote = await CreateConversionQuote(); + + Assert.IsNotNull(createdConversionQuote); + Assert.IsNotNull(createdConversionQuote.CreditedFunds); + Assert.IsNotNull(createdConversionQuote.DebitedFunds); + Assert.IsNotNull(createdConversionQuote.ConversionRateResponse); + Assert.AreEqual("ACTIVE", createdConversionQuote.Status); + } + + [Test] + public async Task Test_GetConversionQuote() + { + var createdConversionQuote = await CreateConversionQuote(); + var returnedConversionQuote = await Api.Conversions.GetConversionQuote(createdConversionQuote.Id); + + Assert.IsNotNull(returnedConversionQuote); + Assert.IsNotNull(returnedConversionQuote.CreditedFunds); + Assert.IsNotNull(returnedConversionQuote.DebitedFunds); + Assert.IsNotNull(returnedConversionQuote.ConversionRateResponse); + Assert.AreEqual("ACTIVE", returnedConversionQuote.Status); + } + + [Test] + public async Task Test_CreateQuotedConversion() + { + var john = await GetJohn(); + var wallet = + new WalletPostDTO(new List { john.Id }, "WALLET IN GBP WITH MONEY", CurrencyIso.GBP); + var creditedWallet = await Api.Wallets.CreateAsync(wallet); + + var debitedWallet = await GetJohnsWalletWithMoney(); + + var quote = await CreateConversionQuote(); + var quotedConversionPostDTO = new QuotedConversionPostDTO( + quoteId: quote.Id, + authorId: debitedWallet.Owners[0], + debitedWalletId: debitedWallet.Id, + creditedWalletId: creditedWallet.Id, + tag: "Created using the Mangopay .NET SDK" + ); + + var quotedConversion = await this.Api.Conversions.CreateQuotedConversion(quotedConversionPostDTO); + + Assert.IsNotNull(quotedConversion); + Assert.AreEqual(TransactionStatus.SUCCEEDED, quotedConversion.Status); + Assert.AreEqual(TransactionNature.REGULAR, quotedConversion.Nature); + } + + private async Task CreateInstantConversion() + { + var john = await GetJohn(); + var wallet = + new WalletPostDTO(new List { john.Id }, "WALLET IN GBP WITH MONEY", CurrencyIso.GBP); + var creditedWallet = await Api.Wallets.CreateAsync(wallet); + + var debitedWallet = await GetJohnsWalletWithMoney(); + + var instantConversion = new ConversionPostDTO( + john.Id, + debitedWallet.Id, + creditedWallet.Id, + new Money { Amount = 30, Currency = CurrencyIso.EUR }, + new Money { Currency = CurrencyIso.GBP }, + new Money { Amount = 10, Currency = CurrencyIso.GBP }, + "create instant conversion" + ); + + return await Api.Conversions.CreateInstantConversion(instantConversion); + } + + private async Task CreateConversionQuote() + { + var conversionQuote = new ConversionQuotePostDTO( + new Money { Amount = 30, Currency = CurrencyIso.EUR }, + new Money { Currency = CurrencyIso.GBP }, + 90, + "Created using the Mangopay .NET SDK" + ); + + return await Api.Conversions.CreateConversionQuote(conversionQuote); + } + } +} \ No newline at end of file diff --git a/MangoPay.SDK.Tests/ApiInstantConversionTest.cs b/MangoPay.SDK.Tests/ApiInstantConversionTest.cs deleted file mode 100644 index 3c8e149..0000000 --- a/MangoPay.SDK.Tests/ApiInstantConversionTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using MangoPay.SDK.Core.Enumerations; -using MangoPay.SDK.Entities; -using MangoPay.SDK.Entities.GET; -using MangoPay.SDK.Entities.POST; -using NUnit.Framework; - -namespace MangoPay.SDK.Tests -{ - [TestFixture] - public class ApiInstantConversionTest: BaseTest - { - [Test] - public async Task Test_GetConversionRate() - { - var conversionRate = await Api.InstantConversion.GetConversionRate("EUR", "GBP"); - - Assert.IsNotNull(conversionRate); - Assert.IsNotNull(conversionRate.ClientRate); - Assert.IsNotNull(conversionRate.MarketRate); - } - - [Test] - public async Task Test_CreateInstantConversion() - { - var createdInstantConversion = await CreateInstantConversion(); - - Assert.IsNotNull(createdInstantConversion); - Assert.IsNotNull(createdInstantConversion.CreditedFunds.Amount); - Assert.IsNotNull(createdInstantConversion.DebitedFunds.Amount); - Assert.IsNotNull(createdInstantConversion.Fees); - Assert.AreEqual(createdInstantConversion.Status, TransactionStatus.SUCCEEDED); - Assert.AreEqual(createdInstantConversion.Type, TransactionType.CONVERSION); - } - - [Test] - public async Task Test_GetInstantConversion() - { - var createdInstantConversion = await CreateInstantConversion(); - var returnedInstantConversion = await Api.InstantConversion.GetInstantConversion(createdInstantConversion.Id); - - Assert.IsNotNull(returnedInstantConversion); - Assert.IsNotNull(returnedInstantConversion.CreditedFunds.Amount); - Assert.IsNotNull(returnedInstantConversion.DebitedFunds.Amount); - Assert.IsNotNull(returnedInstantConversion.Fees); - Assert.AreEqual(returnedInstantConversion.Status, TransactionStatus.SUCCEEDED); - Assert.AreEqual(returnedInstantConversion.Type, TransactionType.CONVERSION); - } - - private async Task CreateInstantConversion() - { - var john = await GetJohn(); - var wallet = - new WalletPostDTO(new List {john.Id}, "WALLET IN GBP WITH MONEY", CurrencyIso.GBP); - var creditedWallet = await Api.Wallets.CreateAsync(wallet); - - var debitedWallet = await GetJohnsWalletWithMoney(); - - var instantConversion = new InstantConversionPostDTO( - john.Id, - debitedWallet.Id, - creditedWallet.Id, - new Money { Amount = 30, Currency = CurrencyIso.EUR }, - new Money { Currency = CurrencyIso.GBP }, - new Money { Amount = 9, Currency = CurrencyIso.EUR}, - "create instant conversion" - ); - - return await Api.InstantConversion.CreateInstantConversion(instantConversion); - } - } -} \ No newline at end of file diff --git a/MangoPay.SDK/Core/APIs/ApiBase.cs b/MangoPay.SDK/Core/APIs/ApiBase.cs index 6172054..f0fedf3 100644 --- a/MangoPay.SDK/Core/APIs/ApiBase.cs +++ b/MangoPay.SDK/Core/APIs/ApiBase.cs @@ -234,7 +234,11 @@ public abstract class ApiBase { MethodKey.GetConversionRate,new ApiEndPoint("/conversions/rate/{0}/{1}",RequestType.GET)}, { MethodKey.CreateInstantConversion,new ApiEndPoint("/conversions/instant-conversion",RequestType.POST)}, - { MethodKey.GetInstantConversion,new ApiEndPoint("/conversions/{0}",RequestType.GET)} + { MethodKey.GetInstantConversion,new ApiEndPoint("/conversions/{0}",RequestType.GET)}, + { MethodKey.CreateConversionQuote,new ApiEndPoint("/conversions/quote",RequestType.POST)}, + { MethodKey.GetConversionQuote, new ApiEndPoint("/conversions/quote/{0}", RequestType.GET)}, + { MethodKey.CreateQuotedConversion, new ApiEndPoint("/conversions/quoted-conversion", RequestType.POST)}, + }; /// Creates new API instance. diff --git a/MangoPay.SDK/Core/APIs/ApiConversions.cs b/MangoPay.SDK/Core/APIs/ApiConversions.cs new file mode 100644 index 0000000..1359030 --- /dev/null +++ b/MangoPay.SDK/Core/APIs/ApiConversions.cs @@ -0,0 +1,58 @@ +using System.Threading.Tasks; +using MangoPay.SDK.Core.Enumerations; +using MangoPay.SDK.Entities.GET; +using MangoPay.SDK.Entities.POST; + +namespace MangoPay.SDK.Core.APIs +{ + public class ApiConversions : ApiBase + { + public ApiConversions(MangoPayApi root) : base(root) + { + } + + public async Task GetConversionRate(string debitedCurrency, string creditedCurrency) + { + return await this.GetObjectAsync(MethodKey.GetConversionRate, + entitiesId: new[] { debitedCurrency, creditedCurrency }); + } + + public async Task CreateInstantConversion(ConversionPostDTO conversion, + string idempotentKey = null) + { + return await + this.CreateObjectAsync(MethodKey.CreateInstantConversion, + conversion, idempotentKey); + } + + public async Task GetInstantConversion(string id) + { + return await this.GetObjectAsync(MethodKey.GetInstantConversion, + entitiesId: id); + } + + public async Task CreateConversionQuote(ConversionQuotePostDTO conversionQuote, + string idempotentKey = null) + { + return await this.CreateObjectAsync( + MethodKey.CreateConversionQuote, + conversionQuote, + idempotentKey); + } + + public async Task GetConversionQuote(string id) + { + return await this.GetObjectAsync(MethodKey.GetConversionQuote, entitiesId: id); + } + + public async Task CreateQuotedConversion( + QuotedConversionPostDTO quotedConversionPostDto, + string idempotentKey = null) + { + return await this.CreateObjectAsync( + MethodKey.CreateQuotedConversion, + quotedConversionPostDto, + idempotentKey); + } + } +} \ No newline at end of file diff --git a/MangoPay.SDK/Core/APIs/ApiInstantConversion.cs b/MangoPay.SDK/Core/APIs/ApiInstantConversion.cs deleted file mode 100644 index f237315..0000000 --- a/MangoPay.SDK/Core/APIs/ApiInstantConversion.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Threading.Tasks; -using MangoPay.SDK.Core.Enumerations; -using MangoPay.SDK.Entities.GET; -using MangoPay.SDK.Entities.POST; - -namespace MangoPay.SDK.Core.APIs -{ - public class ApiInstantConversion : ApiBase - { - public ApiInstantConversion(MangoPayApi root) : base(root) - { - } - - public async Task GetConversionRate(string debitedCurrency, string creditedCurrency) - { - return await this.GetObjectAsync(MethodKey.GetConversionRate, - entitiesId: new[] { debitedCurrency, creditedCurrency }); - } - - public async Task CreateInstantConversion(InstantConversionPostDTO instantConversion, - string idempotentKey = null) - { - return await - this.CreateObjectAsync(MethodKey.CreateInstantConversion, - instantConversion, idempotentKey); - } - - public async Task GetInstantConversion(string id) - { - return await this.GetObjectAsync(MethodKey.GetInstantConversion, - entitiesId: id); - } - } -} \ No newline at end of file diff --git a/MangoPay.SDK/Core/APIs/ApiOAuth.cs b/MangoPay.SDK/Core/APIs/ApiOAuth.cs index 3b66b94..39082fe 100644 --- a/MangoPay.SDK/Core/APIs/ApiOAuth.cs +++ b/MangoPay.SDK/Core/APIs/ApiOAuth.cs @@ -29,6 +29,6 @@ public async Task CreateTokenAsync(CreateOAuthTokenPostDTO entity restTool.AddRequestHttpHeader(Constants.CONTENT_TYPE, Constants.APPLICATION_X_WWW_FORM_URLENCODED); return await restTool.RequestAsync(endPoint, null, entity); - } + } } } diff --git a/MangoPay.SDK/Core/Enumerations/MethodKey.cs b/MangoPay.SDK/Core/Enumerations/MethodKey.cs index dee1495..76158d1 100644 --- a/MangoPay.SDK/Core/Enumerations/MethodKey.cs +++ b/MangoPay.SDK/Core/Enumerations/MethodKey.cs @@ -192,6 +192,9 @@ public enum MethodKey GetConversionRate, CreateInstantConversion, - GetInstantConversion + GetInstantConversion, + CreateConversionQuote, + GetConversionQuote, + CreateQuotedConversion, } } diff --git a/MangoPay.SDK/Entities/GET/InstantConversionDTO.cs b/MangoPay.SDK/Entities/GET/ConversionDTO.cs similarity index 98% rename from MangoPay.SDK/Entities/GET/InstantConversionDTO.cs rename to MangoPay.SDK/Entities/GET/ConversionDTO.cs index cd492fa..59d318f 100644 --- a/MangoPay.SDK/Entities/GET/InstantConversionDTO.cs +++ b/MangoPay.SDK/Entities/GET/ConversionDTO.cs @@ -5,7 +5,7 @@ namespace MangoPay.SDK.Entities.GET { - public class InstantConversionDTO: EntityBase + public class ConversionDTO: EntityBase { /// The unique identifier of the user at the source of the transaction. public string AuthorId { get; set; } diff --git a/MangoPay.SDK/Entities/GET/ConversionQuoteDTO.cs b/MangoPay.SDK/Entities/GET/ConversionQuoteDTO.cs new file mode 100644 index 0000000..43af40c --- /dev/null +++ b/MangoPay.SDK/Entities/GET/ConversionQuoteDTO.cs @@ -0,0 +1,26 @@ +using System; +using MangoPay.SDK.Core.Enumerations; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace MangoPay.SDK.Entities.GET +{ + public class ConversionQuoteDTO : EntityBase + { + /// The date and time at which the quote expires + [JsonConverter(typeof(Core.UnixDateTimeConverter))] + public DateTime ExpirationDate { get; set; } + + /// The status of the transaction. + public string Status { get; set; } + + /// The sell funds + public Money DebitedFunds { get; set; } + + /// The buy funds + public Money CreditedFunds { get; set; } + + /// Real time indicative market rate of a specific currency pair + public ConversionRateDTO ConversionRateResponse { get; set; } + } +} \ No newline at end of file diff --git a/MangoPay.SDK/Entities/GET/QuotedConversionDTO.cs b/MangoPay.SDK/Entities/GET/QuotedConversionDTO.cs new file mode 100644 index 0000000..827f534 --- /dev/null +++ b/MangoPay.SDK/Entities/GET/QuotedConversionDTO.cs @@ -0,0 +1,11 @@ +namespace MangoPay.SDK.Entities.GET +{ + public class QuotedConversionDTO : TransactionDTO + { + /// The unique identifier of the active quote which guaranteed the rate for the conversion. + public string QuoteId { get; set; } + + /// Information about the conversion rate used during the transaction. + public ConversionRateDTO ConversionRateResponse { get; set; } + } +} \ No newline at end of file diff --git a/MangoPay.SDK/Entities/POST/InstantConversionPostDTO.cs b/MangoPay.SDK/Entities/POST/ConversionPostDTO.cs similarity index 88% rename from MangoPay.SDK/Entities/POST/InstantConversionPostDTO.cs rename to MangoPay.SDK/Entities/POST/ConversionPostDTO.cs index 6ddfb97..59d38d0 100644 --- a/MangoPay.SDK/Entities/POST/InstantConversionPostDTO.cs +++ b/MangoPay.SDK/Entities/POST/ConversionPostDTO.cs @@ -1,9 +1,9 @@ namespace MangoPay.SDK.Entities.POST { - public class InstantConversionPostDTO: EntityPostBase + public class ConversionPostDTO: EntityPostBase { - public InstantConversionPostDTO(string authorId, string debitedWalletId, string creditedWalletId, + public ConversionPostDTO(string authorId, string debitedWalletId, string creditedWalletId, Money debitedFunds, Money creditedFunds, Money fees, string tag = null) { diff --git a/MangoPay.SDK/Entities/POST/ConversionQuotePostDTO.cs b/MangoPay.SDK/Entities/POST/ConversionQuotePostDTO.cs new file mode 100644 index 0000000..5a6444a --- /dev/null +++ b/MangoPay.SDK/Entities/POST/ConversionQuotePostDTO.cs @@ -0,0 +1,27 @@ +namespace MangoPay.SDK.Entities.POST +{ + public class ConversionQuotePostDTO : EntityPostBase + { + public ConversionQuotePostDTO( + Money debitedFunds, + Money creditedFunds, + int duration, + string tag + ) + { + DebitedFunds = debitedFunds; + CreditedFunds = creditedFunds; + Duration = duration; + Tag = tag; + } + + /// The sell funds + public Money DebitedFunds { get; set; } + + /// The buy funds + public Money CreditedFunds { get; set; } + + /// The time in seconds during which the quote is active and can be used for conversions. + public int Duration { get; set; } + } +} \ No newline at end of file diff --git a/MangoPay.SDK/Entities/POST/QuotedConversionPostDTO.cs b/MangoPay.SDK/Entities/POST/QuotedConversionPostDTO.cs new file mode 100644 index 0000000..f9ccc88 --- /dev/null +++ b/MangoPay.SDK/Entities/POST/QuotedConversionPostDTO.cs @@ -0,0 +1,34 @@ +namespace MangoPay.SDK.Entities.POST +{ + public class QuotedConversionPostDTO : EntityPostBase + { + public QuotedConversionPostDTO( + string quoteId, + string authorId, + string debitedWalletId, + string creditedWalletId, + string tag + ) + { + QuoteId = quoteId; + AuthorId = authorId; + DebitedWalletId = debitedWalletId; + CreditedWalletId = creditedWalletId; + Tag = tag; + } + + /// The unique identifier of the active quote which guaranteed + /// the rate for the conversion. + public string QuoteId { get; set; } + + /// The unique identifier of the user at the source of the + /// transaction. In a conversion, both the debited and credited wallets are owned by the author. + public string AuthorId { get; set; } + + /// The unique identifier of the debited wallet (in the sell currency). + public string DebitedWalletId { get; set; } + + /// The unique identifier of the credited wallet (in the buy currency). + public string CreditedWalletId { get; set; } + } +} \ No newline at end of file diff --git a/MangoPay.SDK/MangoPayApi.cs b/MangoPay.SDK/MangoPayApi.cs index 469c2b3..65855d5 100644 --- a/MangoPay.SDK/MangoPayApi.cs +++ b/MangoPay.SDK/MangoPayApi.cs @@ -42,7 +42,7 @@ public MangoPayApi() UboDeclarations = new ApiUboDeclarations(this); Regulatory = new ApiRegulatory(this); Deposits = new ApiDeposits(this); - InstantConversion = new ApiInstantConversion(this); + Conversions = new ApiConversions(this); } /// Provides authorization token methods. @@ -125,7 +125,7 @@ public MangoPayApi() public ApiDeposits Deposits; - public ApiInstantConversion InstantConversion; + public ApiConversions Conversions; #endregion