Tamara.SDK 1.0.3

dotnet add package Tamara.SDK --version 1.0.3
                    
NuGet\Install-Package Tamara.SDK -Version 1.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tamara.SDK" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tamara.SDK" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Tamara.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tamara.SDK --version 1.0.3
                    
#r "nuget: Tamara.SDK, 1.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tamara.SDK@1.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tamara.SDK&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Tamara.SDK&version=1.0.3
                    
Install as a Cake Tool

Enviroment

IDE Visual Studio 2019

Install netcore 3.1

DotNet SDK

Tamara .NET SDK is a wrapper for the Tamara API.

Installation

  1. Using package manager:

Install-Package Tamara.SDK -Version 1.0.2

  1. Using Manage NuGet Packages from visual studio with filter parameter: tamara.sdk

Usage

####Configure in appsettings.json

Add a "tamaraPayment" field with baseUrl is Tamara payment's Url, apiToken & notificationPrivateKey are provided in our service.

Example:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "tamaraPayment": {
    "clientVersion": "1.0.0",
    "baseUrl": "https://api-sandbox.tamara.co",
    "requestTimeout": 10,
    "apiToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhY2NvdW50SWQiOiI0NWQwMzAzOC1kM2I2LTQ1ODctYWY2Ny1hNDNlY2FlYjFiZDMiLCJ0eXBlIjoibWVyY2hhbnQiLCJzYWx0IjoiOTIwNDFjZDVlOTJlNDQ1MDg1ZTQ2NzgyZWFhYTY3NjkiLCJpYXQiOjE1OTIxMzM5NTEsImlzcyI6IlRhbWFyYSJ9.HASQ6UR1fabagwqkivmCqL4cFVDOw2cgBMRm5XPlJiNSfJ-gsgwqnPnEEn6-T7Sj4sU6Niee8pUPqP4_WsVQ6DojignLFg2cmrIS_dMIZyOXrZwMbhH6Y0fX5xt2yBVpEVjRbXVaEY4xgHNfMzLwz3mIqmJ-_xuwDDA-hGQk7xibbewDVdCDviSYRHSdzOPtIhy7dcx0CkyYWOncqpJ9YyePrrA1aqZeyWclxgAuZ6zYzsHM_o2e0zwZDqKi1spY11-s1ULSd1WmAWNwoKwy1C4jThJWlXl_E4-bPR_5CUcMHgy7Je9uN3Zfwuq7XODr7ShTnsEZ-xAQW7BxejqvIA",
    "notificationPrivateKey": "b28fbd1412c7e40ce7aa625c38763f71",
    "paths": {
      "getPaymentType": "/checkout/payment-types",
      "createCheckout": "/checkout",
      "authoriseOrder": "/orders/{orderId}/authorise",
      "cancelOrder": "/orders/{orderId}/cancel",
      "capture": "/payments/capture",
      "refund": "/merchants/orders/{orderId}/refund",
      "getOrderDetails": "/orders/{orderId}",
      "updateOrderReferenceId": "/orders/{orderId}/reference-id",
      "registerWebHook": "/webhooks",
      "retrieveWebhook": "/webhooks/{webhookId}",
      "removeWebhook": "/webhooks/{webhookId}",
      "updateWebhook": "/webhooks/{webhookId}"
    }
  }
}

There are two ways:

1. Use factory
  • Create a ApiConfiguration instance
  • Create a Logger instance
    var apiConfiguration = new ApiConfiguration();
    var builder = new ConfigurationBuilder()
        .SetBasePath(Path.Combine(AppContext.BaseDirectory))
        .AddJsonFile("appsettings.json", optional: true);
    IConfiguration configuation = builder.Build();
    configuation.GetSection("tamaraPayment").Bind(apiConfiguration);

    var loggerFactory = LoggerFactory.Create(builder =>
    {
        builder.AddLog4Net(new Log4NetProviderOptions()
        {
            Name = "TamaraApiClient",
            Log4NetConfigFileName = "App_Data/log4net.xml"
        });
    });
    var logger = loggerFactory.CreateLogger<ClientTest>();
   _apiClient = CheckoutServiceFactory.CreateClient(apiConfiguration, logger);
2. Use dependency injection

ApiConfiguration & Logger were created as the same way above.

services.AddScoped<ITamaraApiClient, TamaraApiClient>(provider => new TamaraApiClient(apiConfiguration, logger));
Notification Service
1. Register notification service
services.AddScoped<ITammaraNotificationService, TamaraNotificationService>(provider => new TamaraNotificationService(apiConfiguration.NotificationPrivateKey, logger));
2. Create a controller to receive notification from Tamara
        [HttpPost]
        public async Task<IActionResult> ReceiveAuthoriseNotification()
        {
            var request = HttpContext.Request;
            var result =  await _tammaraNotificationService.ProcessAuthoriseNotification(request);

            return Json(result);
        }
        [HttpPost]
        public async Task<IActionResult> ReceiveWebhookNotification()
        {
            var request = HttpContext.Request;
            var result = await _tammaraNotificationService.ProcessWebhook(request);

            return Json(result);
        }
3. Test:

POST: https://localhost:2600/Notification/ReceiveNotification

Header:

Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDEzMDYwOTcsImlhdCI6MTYwMTMwNDI5NywiaXNzIjoiVGFtYXJhIn0.JuoMMVuStl5RLKxfNDRH7nxjFaQBp4YQr-FH9DDR9zk

Body:

{
  "order_id": "16280ad8-cde0-4d27-b06d-e6658fe53382",
  "order_reference_id": "50548981",
  "order_status": "approved",
  "data": []
}

API Support:

  1. GetPaymentTypes --- /checkout/payment-types
  2. CreateCheckout --- /checkout
  3. AuthoriseOrder --- /orders/{orderId}/authorise
  4. CancelOrder --- /orders/{orderId}/cancel
  5. Capture --- /payments/capture
  6. Refund --- /merchants/orders/{orderId}/refund
  7. GetOrderDetails --- /orders/{orderId}
  8. UpdateOrderReferenceId --- /orders/{orderId}/reference-id
  9. RegisterWebhook --- /webhooks
  10. RetrieveWebhook --- /webhooks/{webhookId}
  11. RemoveWebhook --- /webhooks/{webhookId}
  12. UpdateWebhook --- /webhooks/{webhookId}
  13. GetOrderDetailsByReference --- /merchants/orders/reference-id/{orderReferenceId}

Release notes:

1.0.2: updated simple refund flow

DotNet SDK

Tamara .NET SDK is a wrapper for the Tamara API.

Usage

Create a checkout session

Class Order modify field

public object RiskAssessment { get; set; }  

public object AdditionalData { get; set; } 

With type object, allows passing any values, request order

example: Order.json path: Tamara.Net.ClientSDK.Test.ConsoleApp\App_Data\Mock\Order.json

Service.cs

public async Task<ApiResponse<CheckoutResponse>> CreateCheckout(Order order)  
{
    ApiRequest apiRequestModel = new ApiRequest()
    {
        Method = HttpMethod.Post,
        Path = _apiConfiguration.Paths.CreateCheckout,
        Data = order
    };

    var response = await Execute<CheckoutResponse>(apiRequestModel);
    return response;
}

Calling function

await _tamaraApiClient.CreateCheckout(order);

Check Payment Options Availability

Service.cs 
public async Task<ApiResponse<CheckoutResponse>> CreateCheckout(Order order)
{
    ApiRequest apiRequestModel = new ApiRequest()
    {
        Method = HttpMethod.Post,
        Path = _apiConfiguration.Paths.CreateCheckout,
        Data = order
    };

    var response = await Execute<CheckoutResponse>(apiRequestModel);
    return response;
}

Calling function

await _tamaraApiClient.CreateCheckout(order);

Example

Open source dotnet-sdk: double click Tamara.Net.ClientSDK.sln

Run project Tamara.Net.ClientSDK.Sample.WebApp:

  • Right click choose "Set as startup project",

  • Click icon run

URL: https://localhost:2600

Create a checkout session

Select tab Check Payment Options

Fill the Order input values, example body:

    {
      "country": "SA",
      "order_value": {
        "amount": "100.00",
        "currency": "SAR"
      },
      "phone_number": "966503334444",
      "is_vip": true
    }

Controller

{
public async Task<IActionResult> PaymentOptions(PaymentOptionsRequest request)
{
    _logger.LogInformation("PaymentOptionsCheck");
    var paymentOptions = await _tamaraApiClient.PaymentOptions(paymentOptionsRequest);    
    if (request != null && request.Country != null && request.OrderValue != null) 
    {
        paymentOptions = await _tamaraApiClient.PaymentOptions(request);
        paymentOptionsRequest = request;
    }

    if (paymentOptions.IsSuccess())
    {
        ViewBag.Data = JsonConvert.SerializeObject(paymentOptions.Data); 
    } else
    {
        ViewBag.Data = JsonConvert.SerializeObject(paymentOptions.Meta);  
    }
    return View(paymentOptionsRequest);
    
}

ViewBag.Data response data paymentOptions

Check Payment Options Availability

Select tab Create a checkout session

Fill the Order input values, example body:

RiskAssessment

{
    "value": {
        "return_date": ",
        "class": "Economy",
        "passengers": [
            {
                "nationality": "SA",
                "name": "ALANOD key",
                "id_details": ",
                "date_of_birth": "22-06-1998"
            }
        ],
        "is_guest_user": true,
        "customer_age": 25,
        "origin_leg_0": "RUH",
        "customer_gender": "Female",
        "booking_date": "18-03-2024",
        "is_existing_customer": false,
        "origin": "RUH",
        "customer_dob": "22-06-1998",
        "customer_nationality": "SA",
        "order_count_last3months": 0,
        "destination": "JED",
        "travel_type": "Domestic",
        "trip_type": "Oneway",
        "destination_leg_0": "JED",
        "travel_date": "18-03-2024",
        "number_of_passengers": {
            "adults": 1,
            "children": 0
        },
        "coupons": [],
        "is_fraudulent_customer": false,
        "has_delivered_order": true
    },
    "key": "passenger_0"
}

AdditionalData

{
    "additional_data": {
        "delivery_method_customize": "a home delivery",
        "delivery_method": "home delivery",
        "pickup_store": "Store A",
        "store_code": "Store code A",
        "vendor_info": [
            {
                "vendor_amount": 0,
                "merchant_settlement_amount": 0,
                "vendor_reference_code": "string"
            }
        ]
    }
}

Controller

{
public async Task<IActionResult> CheckoutSession(OrderRequest request)
{
    string propertieErr = string.Empty;
    request.ExRiskAssessment = Constant.ExRiskAssessment;
    request.ExAdditionalData = Constant.ExAdditionalData;
    string rootPath = _hostingEnvironment.ContentRootPath;
    string parentRootPath = Directory.GetParent(rootPath)?.FullName;
    string orderStr = System.IO.File.ReadAllText((parentRootPath + MockDataFolder) + "Order.json");
    var order = JsonConvert.DeserializeObject<Order>(orderStr);
    try
    {
        if (!string.IsNullOrWhiteSpace(request.RiskAssessment))
        {
            propertieErr = "RiskAssessment error, ";
            order.RiskAssessment = JsonConvert.DeserializeObject<object>(request.RiskAssessment);
        }

        if (!string.IsNullOrWhiteSpace(request.AdditionalData))
        {
            propertieErr = "AdditionalData error, ";
            order.AdditionalData = JsonConvert.DeserializeObject<object>(request.AdditionalData);
        }
        var result = await _tamaraApiClient.CreateCheckout(order);
        ViewBag.Data = JsonConvert.SerializeObject(result);
    }
    
    catch(Exception ex)
    {
        ViewBag.Data = propertieErr + (ex.Message);
    }
           
    return View(request);
}
}

ViewBag.Data response data result CreateCheckout

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 13,810 6/3/2024
1.0.2 4,905 11/21/2022
1.0.1 5,593 6/25/2021
1.0.0 2,942 12/2/2020

Version 1.0.3
   - Fixed bugs
   - Enabled spit settlement