Skip to content

Commit

Permalink
Merge branch 'main' into feat/authorisation-adjustment
Browse files Browse the repository at this point in the history
  • Loading branch information
Kwok-he-Chu authored Aug 1, 2023
2 parents c144ce5 + 18e42fa commit 24f8e71
Show file tree
Hide file tree
Showing 22 changed files with 109 additions and 140 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ on:

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Setup .NET
Expand Down
13 changes: 1 addition & 12 deletions checkout-example-advanced/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,14 @@
}
},
"profiles": {
"adyen_dotnet_checkout_example_advanced": {
"Checkout Example Advanced": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080"
},
"adyen_dotnet_checkout_example_advanced_port_tunneling": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080",
// The following two properties enable dev tunnels in visual studio 17.4+. This is used to proxy your localhost and receive webhooks.
"devTunnelEnabled": true,
"devTunnelAccess": "public"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<ItemGroup>
<PackageReference Include="Adyen" Version="10.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.19" />
</ItemGroup>
</Project>
8 changes: 3 additions & 5 deletions checkout-example-advanced/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,8 @@ To expose this endpoint locally, we have highlighted two options in step 4 or 5.


4. Expose your localhost with Visual Studio using dev tunnels.
- Add `https://*.devtunnels.ms` to your allowed origins
- Login to Visual Studio
- Under `Options``Environment``Preview Features` → Check `Enable dev tunnels for Web Application`
- Select `adyen_dotnet_checkout_example_port_tunneling` as your launch settings profile
- Add `https://*.devtunnels.ms` to your allowed origins
- Create your public (temporary/persistent) dev tunnel by following [this guide](https://learn.microsoft.com/en-us/aspnet/core/test/dev-tunnels?view=aspnetcore-7.0)

If you use Visual Studio 17.4 or higher, the webhook URL will be the generated URL (i.e. `https://xd1r2txt-5001.euw.devtunnels.ms`).

Expand Down Expand Up @@ -134,7 +132,7 @@ set ADYEN_HMAC_KEY=yourAdyenHmacKey


```shell
dotnet run --project checkout-example
dotnet run --project checkout-example-advanced
```

10. Update your webhook in your Customer Area with the public url that is generated.
Expand Down
13 changes: 1 addition & 12 deletions checkout-example/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,14 @@
}
},
"profiles": {
"adyen_dotnet_checkout_example": {
"Checkout Example": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080"
},
"adyen_dotnet_checkout_example_port_tunneling": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080",
// The following two properties enable dev tunnels in visual studio 17.4+. This is used to proxy your localhost and receive webhooks.
"devTunnelEnabled": true,
"devTunnelAccess": "public"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
Expand Down
2 changes: 1 addition & 1 deletion checkout-example/adyen-dotnet-checkout-example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<ItemGroup>
<PackageReference Include="Adyen" Version="10.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.19" />
</ItemGroup>
</Project>
7 changes: 2 additions & 5 deletions checkout-example/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,9 @@ git clone https://github.com/adyen-examples/adyen-dotnet-online-payments.git
This demo provides a simple webhook integration at `/api/webhooks/notifications`. For it to work, you need to provide a way for Adyen's servers to reach your running application and add a standard webhook in the Customer Area.
To expose this endpoint locally, we have highlighted two options in step 4 or 5. Choose one or consider alternative tunneling software.


4. Expose your localhost with Visual Studio using dev tunnels.
- Add `https://*.devtunnels.ms` to your allowed origins
- Login to Visual Studio
- Under `Options``Environment``Preview Features` → Check `Enable dev tunnels for Web Application`
- Select `adyen_dotnet_checkout_example_port_tunneling` as your launch settings profile
- Add `https://*.devtunnels.ms` to your allowed origins
- Create your public (temporary/persistent) dev tunnel by following [this guide](https://learn.microsoft.com/en-us/aspnet/core/test/dev-tunnels?view=aspnetcore-7.0)

If you use Visual Studio 17.4 or higher, the webhook URL will be the generated URL (i.e. `https://xd1r2txt-5001.euw.devtunnels.ms`).

Expand Down
13 changes: 1 addition & 12 deletions giftcard-example/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,14 @@
}
},
"profiles": {
"adyen_dotnet_giftcard_example": {
"Gift Card Example": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080"
},
"adyen_dotnet_giftcard_example_port_tunneling": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080",
// The following two properties enable dev tunnels in visual studio 17.4+. This is used to proxy your localhost and receive webhooks.
"devTunnelEnabled": true,
"devTunnelAccess": "public"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
Expand Down
2 changes: 1 addition & 1 deletion giftcard-example/adyen-dotnet-giftcard-example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<ItemGroup>
<PackageReference Include="Adyen" Version="10.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.19" />
</ItemGroup>
</Project>
7 changes: 2 additions & 5 deletions giftcard-example/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,9 @@ git clone https://github.com/adyen-examples/adyen-dotnet-online-payments.git
This demo provides a simple webhook integration at `/api/webhooks/notifications`. For it to work, you need to provide a way for Adyen's servers to reach your running application and add a standard webhook in the Customer Area.
To expose this endpoint locally, we have highlighted two options in step 4 or 5. Choose one or consider alternative tunneling software.


4. Expose your localhost with Visual Studio using dev tunnels.
- Add `https://*.devtunnels.ms` to your allowed origins
- Login to Visual Studio
- Under `Options``Environment``Preview Features` → Check `Enable dev tunnels for Web Application`
- Select `adyen_dotnet_giftcard_example_port_tunneling` as your launch settings profile
- Add `https://*.devtunnels.ms` to your allowed origins
- Create your public (temporary/persistent) dev tunnel by following [this guide](https://learn.microsoft.com/en-us/aspnet/core/test/dev-tunnels?view=aspnetcore-7.0)

If you use Visual Studio 17.4 or higher, the webhook URL will be the generated URL (i.e. `https://xd1r2txt-5001.euw.devtunnels.ms`).

Expand Down
13 changes: 1 addition & 12 deletions paybylink-example/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,14 @@
}
},
"profiles": {
"adyen_dotnet_paybylink_example": {
"Pay By Link Example": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080"
},
"adyen_dotnet_paybylink_example_port_tunneling": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:8080",
// The following two properties enable dev tunnels in visual studio 17.4+. This is used to proxy your localhost and receive webhooks.
"devTunnelEnabled": true,
"devTunnelAccess": "public"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
Expand Down
2 changes: 1 addition & 1 deletion paybylink-example/adyen-dotnet-paybylink-example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<ItemGroup>
<PackageReference Include="Adyen" Version="10.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.19" />
</ItemGroup>
</Project>
6 changes: 2 additions & 4 deletions paybylink-example/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ To expose this endpoint locally, we have highlighted two options in step 4 or 5.


4. Expose your localhost with Visual Studio using dev tunnels.
- Add `https://*.devtunnels.ms` to your allowed origins
- Login to Visual Studio
- Under `Options``Environment``Preview Features` → Check `Enable dev tunnels for Web Application`
- Select `adyen_dotnet_paybylink_example_port_tunneling` as your launch settings profile
- Add `https://*.devtunnels.ms` to your allowed origins
- Create your public (temporary/persistent) dev tunnel by following [this guide](https://learn.microsoft.com/en-us/aspnet/core/test/dev-tunnels?view=aspnetcore-7.0)

If you use Visual Studio 17.4 or higher, the webhook URL will be the generated URL (i.e. `https://xd1r2txt-5001.euw.devtunnels.ms`).

Expand Down
21 changes: 13 additions & 8 deletions subscription-example/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using Adyen.HttpClient;
using Adyen.Model.Checkout;
using Adyen.Model.Recurring;
using adyen_dotnet_subscription_example.Clients;
using adyen_dotnet_subscription_example.Models;
using adyen_dotnet_subscription_example.Repositories;
using adyen_dotnet_subscription_example.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -13,15 +14,17 @@ namespace adyen_dotnet_subscription_example.Controllers
{
public class AdminController : Controller
{
private readonly IRecurringClient _recurringClient;
private readonly ICheckoutClient _checkoutClient;
private readonly ISubscriptionService _subscriptionService;
private readonly ICheckoutService _checkoutClient;
private readonly ISubscriptionRepository _repository;
private readonly ILogger<AdminController> _logger;

public AdminController(IRecurringClient recurringClient, ICheckoutClient checkoutClient, ISubscriptionRepository repository)
public AdminController(ISubscriptionService subscriptionService, ICheckoutService checkoutClient, ISubscriptionRepository repository, ILogger<AdminController> logger)
{
_recurringClient = recurringClient;
_subscriptionService = subscriptionService;
_checkoutClient = checkoutClient;
_repository = repository;
_logger = logger;
}

[Route("admin")]
Expand Down Expand Up @@ -58,10 +61,11 @@ public async Task<IActionResult> MakePayment(string recurringDetailReference, Ca
break;
}
}
catch (HttpClientException)
catch (HttpClientException e)
{
ViewBag.Message = $"Payment failed for RecurringDetailReference {recurringDetailReference}. See error logs for the exception.";
ViewBag.Img = "failed";
_logger.LogError($"Payment failed for RecurringDetailReference {recurringDetailReference}: \n{e.ResponseBody}\n");
}
return View();
}
Expand All @@ -71,7 +75,7 @@ public async Task<IActionResult> Disable(string recurringDetailReference, Cancel
{
try
{
DisableResult result = await _recurringClient.DisableRecurringDetailAsync(ShopperReference.Value, recurringDetailReference, cancellationToken);
DisableResult result = await _subscriptionService.DisableRecurringDetailAsync(ShopperReference.Value, recurringDetailReference, cancellationToken);

switch (result.Response)
{
Expand All @@ -85,10 +89,11 @@ public async Task<IActionResult> Disable(string recurringDetailReference, Cancel
break;
}
}
catch (HttpClientException)
catch (HttpClientException e)
{
ViewBag.Message = $"Disable failed for RecurringDetailReference {recurringDetailReference}. See error logs for the exception.";
ViewBag.Img = "failed";
_logger.LogError($"Disable failed for RecurringDetailReference {recurringDetailReference}: \n{e.ResponseBody}\n");
}
return View();
}
Expand Down
8 changes: 4 additions & 4 deletions subscription-example/Controllers/TokenizationController.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using adyen_dotnet_subscription_example.Clients;
using Adyen.Model.Checkout;
using Adyen.Model.Checkout;
using Microsoft.AspNetCore.Mvc;
using System.Threading;
using System.Threading.Tasks;
using adyen_dotnet_subscription_example.Services;

namespace adyen_dotnet_subscription_example.Controllers
{
[ApiController]
public class TokenizationController : ControllerBase
{
private readonly ICheckoutClient _checkoutService;
private readonly ICheckoutService _checkoutService;

public TokenizationController(ICheckoutClient checkoutService)
public TokenizationController(ICheckoutService checkoutService)
{
_checkoutService = checkoutService;
}
Expand Down
56 changes: 42 additions & 14 deletions subscription-example/Controllers/WebhookController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ public async Task<ActionResult<string>> Webhooks(NotificationRequest notificatio
return BadRequest("[not accepted invalid hmac key]");
}

// Process notification asynchronously.
await ProcessNotificationAsync(container.NotificationItem);
// Process notifications asynchronously.
await ProcessAuthorisationNotificationAsync(container.NotificationItem);

await ProcessRecurringContractNotificationAsync(container.NotificationItem);

return Ok("[accepted]");
}
Expand All @@ -63,18 +65,42 @@ public async Task<ActionResult<string>> Webhooks(NotificationRequest notificatio
}
}

private Task ProcessNotificationAsync(NotificationRequestItem notification)
private Task ProcessAuthorisationNotificationAsync(NotificationRequestItem notification)
{
// (1) For the synchronous flow (enabled by default), check the "Authorisation" eventCode:
// Read more: https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens?tab=subscriptions_2#authorised-result-code-1

// (2) For the asynchronous flow, (enabled by contacting our support team), you need to check the "RECURRING_CONTRACT" eventCode instead of the "AUTHORISATION" eventCode.
// Read more: https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens?tab=subscriptions_2#pending-and-refusal-result-codes-1
// Read more here: https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens?tab=subscriptions_2#pending-and-refusal-result-codes-1
if (notification.EventCode != "AUTHORISATION")
{
return Task.CompletedTask;
}

// Perform your business logic here for the success:false scenario.
if (!notification.Success)
{
// We just log it for now. You would probably want to update your backend or send this the message to a queue.
_logger.LogInformation($"Webhook unsuccessful: {notification.Reason} \n" +
$"EventCode: {notification.EventCode} \n" +
$"Merchant Reference ::{notification.MerchantReference} \n" +
$"PSP Reference ::{notification.PspReference} \n");

return Task.CompletedTask;
}

_logger.LogInformation($"Received webhook with event: \n" +
$"EventCode: {notification.EventCode} \n" +
$"Merchant Reference: {notification.MerchantReference} \n" +
$"PSP Reference: {notification.PspReference} \n");
return Task.CompletedTask;
}


private Task ProcessRecurringContractNotificationAsync(NotificationRequestItem notification)
{
// Read more about EventCode "RECURRING_CONTRACT" here: https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens?tab=subscriptions_2#pending-and-refusal-result-codes-1.
if (notification.EventCode != "RECURRING_CONTRACT")
{
return Task.CompletedTask;
}

// Perform your business logic here for the success:false scenario.
if (!notification.Success)
{
Expand All @@ -101,17 +127,19 @@ private Task ProcessNotificationAsync(NotificationRequestItem notification)
}

// Get and log the recurringProcessingModel below.
notification.AdditionalData.TryGetValue("recurringProcessingModel", out string recurringProcessingModel);

_logger.LogInformation($"Received recurringDetailReference: {recurringDetailReference} for {shopperReference}" +
$"RecurringProcessingModel: {recurringProcessingModel}");
if (notification.AdditionalData.TryGetValue("recurringProcessingModel", out string recurringProcessingModel))
{
_logger.LogInformation($"EventCode: {notification.EventCode} \nReceived recurringDetailReference: {recurringDetailReference} for {shopperReference} \n" +
$"RecurringProcessingModel: {recurringProcessingModel}");
}

// Save the paymentMethod, shopperReference and recurringDetailReference in our in-memory cache.
_repository.Upsert(notification.PaymentMethod, shopperReference, recurringDetailReference);

_logger.LogInformation($"Received webhook with event: \n" +
$"Merchant Reference: {notification.MerchantReference} \n" +
$"PSP Reference: {notification.PspReference} \n");
$"EventCode: {notification.EventCode} \n" +
$"Merchant Reference: {notification.MerchantReference} \n" +
$"PSP Reference: {notification.PspReference} \n");
return Task.CompletedTask;
}
}
Expand Down
Loading

0 comments on commit 24f8e71

Please sign in to comment.