paytrail / api-documentation

Paytrail Payment API documentation
MIT License
6 stars 11 forks source link

Add C# example #45

Closed tommi-martin closed 2 years ago

tommi-martin commented 2 years ago

Branch contains example code for a HMAC calculation using C#

marspox commented 2 years ago

Hi @tommi-martin . I have tried to use your code from your PR. Unfortunately after sending http request I'm getting 401 unauthorized.. Is there something what I have missed?


static async Task Main(string[] args)
    {
        string secret = "SAIPPUAKAUPPIAS";
        var headers = new Dictionary<string, string>();
        headers.Add("checkout-account", "375917");
        headers.Add("checkout-algorithm", "sha256");
        headers.Add("checkout-method", "POST");
        headers.Add("checkout-nonce", "564635208570151");
        headers.Add("checkout-timestamp", "2018-07-06T10:01:31.904Z");
        var b = new Body();
        b.stamp = "unique-identifier-for-merchant";
        b.reference = "3759170";
        b.amount = 1525;
        b.currency = "EUR";
        b.language = "FI";
        var item = new Item();
        item.unitPrice = 1525;
        item.units = 1;
        item.vatPercentage = 24;
        item.productCode = "#1234";
        item.deliveryDate = "2018-09-01";
        b.items = new Item[] { item };
        b.customer = new Customer("test.customer@example.com");
        b.redirectUrls = new RedirectUrls("https://ecom.example.com/cart/success", "https://ecom.example.com/cart/cancel");
        var body = JsonSerializer.Serialize(b);
        var encData = Crypto.CalculateHmac(secret, headers, body);
        Console.WriteLine("Encrypted data: " + encData);
        var client = new HttpClient();
        var httpRequestMessage = new HttpRequestMessage()
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri("https://services.paytrail.com/payments"),
            Content = new StringContent(body),
            Headers = {
                { "checkout-account", "375917" },
                { "checkout-algorithm", "sha256" },
                { "checkout-method", "POST" },
                { "checkout-nonce", "564635208570151" },
                { "checkout-timestamp", "2018-07-06T10:01:31.904Z" },
                { "signature", encData },
            }
        };
        var response = await client.SendAsync(httpRequestMessage);
    }
tommi-martin commented 2 years ago

Pull request closed. There are issues to be resolved inside the code example. After issues are addressed a new pull request will be made. @marspox I'll return to your comment as soon as I have more information for you.

RalitsaBatistaSolteq commented 2 years ago

@marspox, your code implementation looks good to me, however the request data in the C# example is the same as in the paytrail js/php examples and using it is only for testing encoded data result. If you'd like to make a real request you have to use your account data.

image

Also I suggest you to use variables from the headers dictionary instead manually type them like: var httpRequestMessage = new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri("https://services.paytrail.com/payments"), Content = new StringContent(body), Headers = { { "checkout-account", headers["checkout-account"] }, { "checkout-algorithm", headers["checkout-algorithm"] }, { "checkout-method", headers["checkout-method"] }, { "checkout-nonce", headers["checkout-nonce"] }, { "checkout-timestamp", headers["checkout-timestamp"] }, { "signature", encData }, } };

marspox commented 2 years ago

Hi @RalitsaBatistaSolteq Thank you for your answer. I know that code is ugly it was just sample created in few minutes just to find out If I will have same issue for c# sample code which I had when I used postman and example of nodejs code attached in documentation for generating a signature. I thought that checkout-account (375917) is some kind of test account which can be used for testing API, as it is used in many places in doc. as example...

BR

RalitsaBatistaSolteq commented 2 years ago

@marspox ,

  1. please set the Content-type for the HttpRequestMessage object as follows: Content = new StringContent(body,System.Text.Encoding.UTF8, "application/json"), instead of Content = new StringContent(body)

  2. b.stamp needs to be different for every new call, so you can use Random generated number like this: add method to the Crypto class public static string RandomDigits(int length) { var random = new Random(); string s = string.Empty; for (int i = 0; i < length; i++) s = String.Concat(s, random.Next(10).ToString()); return s; }

    use it in Program.cs 
     b.stamp = Crypto.RandomDigits(11);
  3. also you can debug at the end with : Console.WriteLine("StatCode: " + response.StatusCode); Console.WriteLine("Result: " + await response.Content.ReadAsStringAsync());

Let me know if you have any other questions.