Skip to content

Commit

Permalink
Add support for new PaymentLink update and delete methods (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
Viincenttt committed Jul 7, 2024
1 parent 529e802 commit 9f39442
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/Mollie.Api/Client/Abstract/IPaymentLinkClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,31 @@ public interface IPaymentLinkClient : IBaseMollieClient {
/// <returns></returns>
Task<PaymentLinkResponse> CreatePaymentLinkAsync(PaymentLinkRequest paymentLinkRequest);

/// <summary>
/// Update a payment link
/// </summary>
/// <param name="paymentLinkId">Provide the ID of the item you want to perform this operation on.</param>
/// <param name="paymentLinkUpdateRequest">The request body</param>
/// <param name="testmode">Most API credentials are specifically created for either live mode or test mode.
/// In those cases the testmode query parameter can be omitted. For organization-level credentials such as
/// OAuth access tokens, you can enable test mode by setting the testmode query parameter to true.</param>
/// <returns>The updated payment link response</returns>
Task<PaymentLinkResponse> UpdatePaymentLinkAsync(
string paymentLinkId,
PaymentLinkUpdateRequest paymentLinkUpdateRequest,
bool testmode = false);

/// <summary>
/// Payment links for which no payments have been made yet can be deleted entirely. This can be useful for
/// removing payment links that have been incorrectly configured or that are no longer relevant.
/// </summary>
/// <param name="paymentLinkId">Provide the ID of the item you want to perform this operation on.</param>
/// <param name="testmode">Most API credentials are specifically created for either live mode or test mode.
/// In those cases the testmode query parameter can be omitted. For organization-level credentials such as
/// OAuth access tokens, you can enable test mode by setting the testmode query parameter to true.</param>
/// <returns></returns>
Task DeletePaymentLinkAsync(string paymentLinkId, bool testmode = false);

/// <summary>
/// Retrieve a single payment link object by its token.
/// </summary>
Expand Down
25 changes: 24 additions & 1 deletion src/Mollie.Api/Client/PaymentLinkClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ public async Task<PaymentLinkResponse> CreatePaymentLinkAsync(PaymentLinkRequest
return await PostAsync<PaymentLinkResponse>($"payment-links", paymentLinkRequest).ConfigureAwait(false);
}

public async Task<PaymentLinkResponse> UpdatePaymentLinkAsync(
string paymentLinkId,
PaymentLinkUpdateRequest paymentLinkUpdateRequest,
bool testmode = false) {

ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);
var queryParameters = BuildQueryParameters(testmode);
string relativeUri = $"payment-links/{paymentLinkId}{queryParameters.ToQueryString()}";
return await PatchAsync<PaymentLinkResponse>(relativeUri, paymentLinkUpdateRequest).ConfigureAwait(false);
}

public async Task DeletePaymentLinkAsync(string paymentLinkId, bool testmode = false) {
ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);
var queryParameters = BuildQueryParameters(testmode);
string relativeUri = $"payment-links/{paymentLinkId}{queryParameters.ToQueryString()}";
await DeleteAsync(relativeUri).ConfigureAwait(false);
}

public async Task<PaymentLinkResponse> GetPaymentLinkAsync(string paymentLinkId, bool testmode = false)
{
ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);
Expand All @@ -42,7 +60,6 @@ public async Task<PaymentLinkResponse> GetPaymentLinkAsync(UrlObjectLink<Payment
return await GetAsync(url).ConfigureAwait(false);
}


public async Task<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(UrlObjectLink<ListResponse<PaymentLinkResponse>> url)
{
return await GetAsync(url).ConfigureAwait(false);
Expand All @@ -62,6 +79,12 @@ public async Task<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(str
return await GetListAsync<ListResponse<PaymentLinkResponse>>("payment-links", from, limit, queryParameters).ConfigureAwait(false);
}

private Dictionary<string, string> BuildQueryParameters(bool testmode = false) {
var result = new Dictionary<string, string>();
result.AddValueIfTrue("testmode", testmode);
return result;
}

private Dictionary<string, string> BuildQueryParameters(string? profileId = null, bool testmode = false)
{
var result = new Dictionary<string, string>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Mollie.Api.Models.PaymentLink.Request;

public record PaymentLinkUpdateRequest {
/// <summary>
/// A short description of the payment link. The description is visible in the Dashboard and will be shown on the
/// customer's bank or card statement when possible.
///
/// Updating the description does not affect any previously existing payments created for this payment link.
/// </summary>
public required string Description { get; init; }

/// <summary>
/// Whether the payment link is archived. Customers will not be able to complete payments on archived payment links.
/// </summary>
public required bool Archived { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public record PaymentLinkResponse
/// </summary>
public required Amount Amount { get; set; }

/// <summary>
/// Whether the payment link is archived. Customers will not be able to complete payments on archived payment links.
/// </summary>
public required bool Archived { get; set; }

/// <summary>
/// The URL your customer will be redirected to after completing the payment process.
/// </summary>
Expand Down
50 changes: 50 additions & 0 deletions tests/Mollie.Tests.Integration/Api/PaymentLinkTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Mollie.Api.Models.PaymentLink.Request;
using Mollie.Api.Models.PaymentLink.Response;
using Mollie.Tests.Integration.Framework;
using Xunit;

namespace Mollie.Tests.Integration.Api;

Expand Down Expand Up @@ -52,6 +53,7 @@ public async Task CanCreatePaymentLinkAndRetrieveIt() {
response.ExpiresAt.Should().Be(expiresAtWithoutMs);
response.Description.Should().Be(paymentLinkRequest.Description);
response.RedirectUrl.Should().Be(paymentLinkRequest.RedirectUrl);
response.Archived.Should().BeFalse();
});

verifyPaymentLinkResponse(createdPaymentLinkResponse);
Expand Down Expand Up @@ -87,6 +89,54 @@ public async Task CanCreatePaymentLinkWithNullAmount() {
verifyPaymentLinkResponse(retrievePaymentLinkResponse);
}

[Fact]
public async Task CanUpdatePaymentLink() {
// Given: We create a new payment link
PaymentLinkRequest paymentLinkRequest = new() {
Description = "Test",
Amount = new Amount(Currency.EUR, 50),
WebhookUrl = DefaultWebhookUrl,
RedirectUrl = DefaultRedirectUrl,
ExpiresAt = DateTime.Now.AddDays(1)
};
var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);

// When: We update the payment link
PaymentLinkUpdateRequest paymentLinkUpdateRequest = new() {
Description = "Updated description",
Archived = true
};
var updatedPaymentLinkResponse = await _paymentLinkClient.UpdatePaymentLinkAsync(
createdPaymentLinkResponse.Id,
paymentLinkUpdateRequest);

// Then: We expect the payment link to be updated
updatedPaymentLinkResponse.Description.Should().Be(paymentLinkUpdateRequest.Description);
updatedPaymentLinkResponse.Archived.Should().Be(paymentLinkUpdateRequest.Archived);
}

[Fact]
public async Task CanDeletePaymentLink() {
// Given: We create a new payment link
PaymentLinkRequest paymentLinkRequest = new() {
Description = "Test",
Amount = new Amount(Currency.EUR, 50),
WebhookUrl = DefaultWebhookUrl,
RedirectUrl = DefaultRedirectUrl,
ExpiresAt = DateTime.Now.AddDays(1)
};
var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);

// When: We delete the payment link
await _paymentLinkClient.DeletePaymentLinkAsync(createdPaymentLinkResponse.Id);

// Then: We expect the payment link to be updated
MollieApiException exception = await Assert.ThrowsAsync<MollieApiException>(() =>
_paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id));
exception.Details.Status.Should().Be(404);
exception.Details.Detail.Should().Be("Payment link does not exists.");
}

public void Dispose()
{
_paymentLinkClient?.Dispose();
Expand Down

0 comments on commit 9f39442

Please sign in to comment.