From 53a79b23bdc610ad7fa3e3da44b8bbf343d48b5c Mon Sep 17 00:00:00 2001 From: Sourav Sarkar Date: Tue, 15 Oct 2024 09:20:38 +0530 Subject: [PATCH] feat: migrate to dotnet server sdk --- .../dotnet/PayPalAdvancedIntegration.csproj | 1 + .../v2/server/dotnet/Server.cs | 159 +++++++---------- .../dotnet/PayPalStandardIntegration.csproj | 1 + standard-integration/server/dotnet/Server.cs | 161 +++++++----------- 4 files changed, 129 insertions(+), 193 deletions(-) diff --git a/advanced-integration/v2/server/dotnet/PayPalAdvancedIntegration.csproj b/advanced-integration/v2/server/dotnet/PayPalAdvancedIntegration.csproj index 1c9d4604..838e3aa4 100644 --- a/advanced-integration/v2/server/dotnet/PayPalAdvancedIntegration.csproj +++ b/advanced-integration/v2/server/dotnet/PayPalAdvancedIntegration.csproj @@ -7,5 +7,6 @@ + diff --git a/advanced-integration/v2/server/dotnet/Server.cs b/advanced-integration/v2/server/dotnet/Server.cs index dcd334fb..5132e726 100644 --- a/advanced-integration/v2/server/dotnet/Server.cs +++ b/advanced-integration/v2/server/dotnet/Server.cs @@ -1,16 +1,18 @@ using System; -using System.IO; -using System.Net.Http; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; +using Microsoft.Extensions.Logging; +using PaypalServerSDK.Standard; +using PaypalServerSDK.Standard.Authentication; +using PaypalServerSDK.Standard.Controllers; +using PaypalServerSDK.Standard.Http.Response; +using PaypalServerSDK.Standard.Models; +using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration; namespace PayPalAdvancedIntegration; @@ -56,22 +58,42 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) [ApiController] public class CheckoutController : Controller { - private readonly IHttpClientFactory _httpClientFactory; + private readonly OrdersController _ordersController; + private readonly PaymentsController _paymentsController; + private IConfiguration _configuration { get; } private string _paypalClientId { - get { return Environment.GetEnvironmentVariable("PAYPAL_CLIENT_ID"); } + get { return System.Environment.GetEnvironmentVariable("PAYPAL_CLIENT_ID"); } } private string _paypalClientSecret { - get { return Environment.GetEnvironmentVariable("PAYPAL_CLIENT_SECRET"); } + get { return System.Environment.GetEnvironmentVariable("PAYPAL_CLIENT_SECRET"); } } - private readonly string _base = "https://api-m.sandbox.paypal.com"; - public CheckoutController(IHttpClientFactory httpClientFactory, IConfiguration configuration) + private readonly ILogger _logger; + + public CheckoutController(IConfiguration configuration, ILogger logger) { - _httpClientFactory = httpClientFactory; _configuration = configuration; + _logger = logger; + + // Initialize the PayPal SDK client + PaypalServerSDKClient client = new PaypalServerSDKClient.Builder() + .Environment(PaypalServerSDK.Standard.Environment.Sandbox) + .ClientCredentialsAuth( + new ClientCredentialsAuthModel.Builder(_paypalClientId, _paypalClientSecret).Build() + ) + .LoggingConfig(config => + config + .LogLevel(LogLevel.Information) + .RequestConfig(reqConfig => reqConfig.Body(true)) + .ResponseConfig(respConfig => respConfig.Headers(true)) + ) + .Build(); + + _ordersController = client.OrdersController; + _paymentsController = client.PaymentsController; } [HttpPost("api/orders")] @@ -80,7 +102,7 @@ public async Task CreateOrder([FromBody] dynamic cart) try { var result = await _CreateOrder(cart); - return StatusCode((int)result.httpStatusCode, result.jsonResponse); + return StatusCode((int)result.StatusCode, result.Data); } catch (Exception ex) { @@ -89,13 +111,37 @@ public async Task CreateOrder([FromBody] dynamic cart) } } + private async Task _CreateOrder(dynamic cart) + { + CheckoutPaymentIntent intent = (CheckoutPaymentIntent) + Enum.Parse(typeof(CheckoutPaymentIntent), "CAPTURE", true); + + OrdersCreateInput ordersCreateInput = new OrdersCreateInput + { + Body = new OrderRequest + { + Intent = intent, + PurchaseUnits = new List + { + new PurchaseUnitRequest + { + Amount = new AmountWithBreakdown { CurrencyCode = "USD", MValue = "100", }, + }, + }, + }, + }; + + ApiResponse result = await _ordersController.OrdersCreateAsync(ordersCreateInput); + return result; + } + [HttpPost("api/orders/{orderID}/capture")] public async Task CaptureOrder(string orderID) { try { var result = await _CaptureOrder(orderID); - return StatusCode((int)result.httpStatusCode, result.jsonResponse); + return StatusCode((int)result.StatusCode, result.Data); } catch (Exception ex) { @@ -104,91 +150,12 @@ public async Task CaptureOrder(string orderID) } } - private async Task GenerateAccessToken() - { - if (string.IsNullOrEmpty(_paypalClientId) || string.IsNullOrEmpty(_paypalClientSecret)) - { - throw new Exception("MISSING_API_CREDENTIALS"); - } - - var auth = Convert.ToBase64String( - Encoding.UTF8.GetBytes($"{_paypalClientId}:{_paypalClientSecret}") - ); - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, $"{_base}/v1/oauth2/token") - { - Content = new StringContent( - "grant_type=client_credentials", - Encoding.UTF8, - "application/x-www-form-urlencoded" - ) - }; - request.Headers.Add("Authorization", $"Basic {auth}"); - - var response = await client.SendAsync(request); - var data = JsonConvert.DeserializeObject( - await response.Content.ReadAsStringAsync() - ); - return data.access_token; - } - - private async Task _CreateOrder(dynamic cart) - { - var accessToken = await GenerateAccessToken(); - var url = $"{_base}/v2/checkout/orders"; - var payload = new - { - intent = "CAPTURE", - purchase_units = new[] - { - new { amount = new { currency_code = "USD", value = "100.00" } } - } - }; - - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, url) - { - Content = new StringContent( - JsonConvert.SerializeObject(payload), - Encoding.UTF8, - "application/json" - ) - }; - request.Headers.Add("Authorization", $"Bearer {accessToken}"); - - var response = await client.SendAsync(request); - return await HandleResponse(response); - } - private async Task _CaptureOrder(string orderID) { - var accessToken = await GenerateAccessToken(); - var url = $"{_base}/v2/checkout/orders/{orderID}/capture"; - - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, url) - { - Content = new StringContent("", Encoding.UTF8, "application/json") - }; - request.Headers.Add("Authorization", $"Bearer {accessToken}"); + OrdersCaptureInput ordersCaptureInput = new OrdersCaptureInput { Id = orderID, }; - var response = await client.SendAsync(request); - return await HandleResponse(response); - } + ApiResponse result = await _ordersController.OrdersCaptureAsync(ordersCaptureInput); - private async Task HandleResponse(HttpResponseMessage response) - { - try - { - var jsonResponse = JsonConvert.DeserializeObject( - await response.Content.ReadAsStringAsync() - ); - return new { jsonResponse, httpStatusCode = response.StatusCode }; - } - catch (Exception) - { - var errorMessage = await response.Content.ReadAsStringAsync(); - throw new Exception(errorMessage); - } + return result; } } diff --git a/standard-integration/server/dotnet/PayPalStandardIntegration.csproj b/standard-integration/server/dotnet/PayPalStandardIntegration.csproj index 6b5a7d0e..a506c6d8 100644 --- a/standard-integration/server/dotnet/PayPalStandardIntegration.csproj +++ b/standard-integration/server/dotnet/PayPalStandardIntegration.csproj @@ -7,5 +7,6 @@ + diff --git a/standard-integration/server/dotnet/Server.cs b/standard-integration/server/dotnet/Server.cs index 9be4f5e5..5132e726 100644 --- a/standard-integration/server/dotnet/Server.cs +++ b/standard-integration/server/dotnet/Server.cs @@ -1,18 +1,20 @@ using System; -using System.IO; -using System.Net.Http; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Newtonsoft.Json; +using Microsoft.Extensions.Logging; +using PaypalServerSDK.Standard; +using PaypalServerSDK.Standard.Authentication; +using PaypalServerSDK.Standard.Controllers; +using PaypalServerSDK.Standard.Http.Response; +using PaypalServerSDK.Standard.Models; +using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration; -namespace PayPalStandardIntegration; +namespace PayPalAdvancedIntegration; public class Program { @@ -56,22 +58,42 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) [ApiController] public class CheckoutController : Controller { - private readonly IHttpClientFactory _httpClientFactory; + private readonly OrdersController _ordersController; + private readonly PaymentsController _paymentsController; + private IConfiguration _configuration { get; } private string _paypalClientId { - get { return Environment.GetEnvironmentVariable("PAYPAL_CLIENT_ID"); } + get { return System.Environment.GetEnvironmentVariable("PAYPAL_CLIENT_ID"); } } private string _paypalClientSecret { - get { return Environment.GetEnvironmentVariable("PAYPAL_CLIENT_SECRET"); } + get { return System.Environment.GetEnvironmentVariable("PAYPAL_CLIENT_SECRET"); } } - private readonly string _base = "https://api-m.sandbox.paypal.com"; - public CheckoutController(IHttpClientFactory httpClientFactory, IConfiguration configuration) + private readonly ILogger _logger; + + public CheckoutController(IConfiguration configuration, ILogger logger) { - _httpClientFactory = httpClientFactory; _configuration = configuration; + _logger = logger; + + // Initialize the PayPal SDK client + PaypalServerSDKClient client = new PaypalServerSDKClient.Builder() + .Environment(PaypalServerSDK.Standard.Environment.Sandbox) + .ClientCredentialsAuth( + new ClientCredentialsAuthModel.Builder(_paypalClientId, _paypalClientSecret).Build() + ) + .LoggingConfig(config => + config + .LogLevel(LogLevel.Information) + .RequestConfig(reqConfig => reqConfig.Body(true)) + .ResponseConfig(respConfig => respConfig.Headers(true)) + ) + .Build(); + + _ordersController = client.OrdersController; + _paymentsController = client.PaymentsController; } [HttpPost("api/orders")] @@ -80,7 +102,7 @@ public async Task CreateOrder([FromBody] dynamic cart) try { var result = await _CreateOrder(cart); - return StatusCode((int)result.httpStatusCode, result.jsonResponse); + return StatusCode((int)result.StatusCode, result.Data); } catch (Exception ex) { @@ -89,13 +111,37 @@ public async Task CreateOrder([FromBody] dynamic cart) } } + private async Task _CreateOrder(dynamic cart) + { + CheckoutPaymentIntent intent = (CheckoutPaymentIntent) + Enum.Parse(typeof(CheckoutPaymentIntent), "CAPTURE", true); + + OrdersCreateInput ordersCreateInput = new OrdersCreateInput + { + Body = new OrderRequest + { + Intent = intent, + PurchaseUnits = new List + { + new PurchaseUnitRequest + { + Amount = new AmountWithBreakdown { CurrencyCode = "USD", MValue = "100", }, + }, + }, + }, + }; + + ApiResponse result = await _ordersController.OrdersCreateAsync(ordersCreateInput); + return result; + } + [HttpPost("api/orders/{orderID}/capture")] public async Task CaptureOrder(string orderID) { try { var result = await _CaptureOrder(orderID); - return StatusCode((int)result.httpStatusCode, result.jsonResponse); + return StatusCode((int)result.StatusCode, result.Data); } catch (Exception ex) { @@ -104,91 +150,12 @@ public async Task CaptureOrder(string orderID) } } - private async Task GenerateAccessToken() - { - if (string.IsNullOrEmpty(_paypalClientId) || string.IsNullOrEmpty(_paypalClientSecret)) - { - throw new Exception("MISSING_API_CREDENTIALS"); - } - - var auth = Convert.ToBase64String( - Encoding.UTF8.GetBytes($"{_paypalClientId}:{_paypalClientSecret}") - ); - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, $"{_base}/v1/oauth2/token") - { - Content = new StringContent( - "grant_type=client_credentials", - Encoding.UTF8, - "application/x-www-form-urlencoded" - ) - }; - request.Headers.Add("Authorization", $"Basic {auth}"); - - var response = await client.SendAsync(request); - var data = JsonConvert.DeserializeObject( - await response.Content.ReadAsStringAsync() - ); - return data.access_token; - } - - private async Task _CreateOrder(dynamic cart) - { - var accessToken = await GenerateAccessToken(); - var url = $"{_base}/v2/checkout/orders"; - var payload = new - { - intent = "CAPTURE", - purchase_units = new[] - { - new { amount = new { currency_code = "USD", value = "100.00" } } - } - }; - - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, url) - { - Content = new StringContent( - JsonConvert.SerializeObject(payload), - Encoding.UTF8, - "application/json" - ) - }; - request.Headers.Add("Authorization", $"Bearer {accessToken}"); - - var response = await client.SendAsync(request); - return await HandleResponse(response); - } - private async Task _CaptureOrder(string orderID) { - var accessToken = await GenerateAccessToken(); - var url = $"{_base}/v2/checkout/orders/{orderID}/capture"; - - var client = _httpClientFactory.CreateClient(); - var request = new HttpRequestMessage(HttpMethod.Post, url) - { - Content = new StringContent("", Encoding.UTF8, "application/json") - }; - request.Headers.Add("Authorization", $"Bearer {accessToken}"); + OrdersCaptureInput ordersCaptureInput = new OrdersCaptureInput { Id = orderID, }; - var response = await client.SendAsync(request); - return await HandleResponse(response); - } + ApiResponse result = await _ordersController.OrdersCaptureAsync(ordersCaptureInput); - private async Task HandleResponse(HttpResponseMessage response) - { - try - { - var jsonResponse = JsonConvert.DeserializeObject( - await response.Content.ReadAsStringAsync() - ); - return new { jsonResponse, httpStatusCode = response.StatusCode }; - } - catch (Exception) - { - var errorMessage = await response.Content.ReadAsStringAsync(); - throw new Exception(errorMessage); - } + return result; } }