Rabobank omnikassa 2.0 implementeren in .NET

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

Anoniem: 1108349

Topicstarter
Ben volkomen nieuw op dit forum ben geen pro en dit is de eerste keer dat ik PHP gebruik. Ik heb een probleem met het implementeren van rabobank omnikassa 2.0 in mijn webshop. De aanroep van de omnikassa api is een HTTPS POST request met een JSON body. Mijn webshop draait op .NET, maar daar hebben ze bij de rabobank geen voorbeeldcodes voor wel voor PHP en JAVA. De PHP code draait in de test omgeving perfect, maar ik krijg dit niet voor elkaar in .NET. Allebei de codes geven de zelfde JSON string, plak ik de .NET JSON string in de PHP code dan krijg ik een fout 403 van de rabobank server, kopieer ik de JSON string uit de PHP code en plak deze daarna weer in de PHP code dan gaat alles weer goed. Mijn vraag is natuurlijk hoe is dit mogelijk zelfde string met de zelfde HEX waarden een doet het wel de andere doet het niet?

Gebruikte code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PHP code:
$aRequest['timestamp'] = "2018-08-23T17:02:36.4279066+02:00";
$aRequest['merchantOrderId'] = "order123"
$aRequest['amount'] = array();
$aRequest['amount']['currency'] = "EUR";
$aRequest['amount']['amount'] = "100";
$aRequest['description'] =  "Webshop bestelling order123";
$aRequest['merchantReturnURL'] = "https://returnurl";
$aRequest['paymentBrand'] = "IDEAL";
$aRequest['paymentBrandForce'] = 'FORCE_ONCE';
$sHashString = $aRequest['timestamp'] . ',' . $aRequest['merchantOrderId'] . ',' . $aRequest['amount']['currency'] . ',' . $aRequest['amount']['amount'] . ','. ',' . $aRequest['description'] . ',' . $aRequest['merchantReturnURL'] . ',' . $aRequest['paymentBrand'] . ',' . $aRequest['paymentBrandForce'];
$sHash = hash_hmac('sha512', $sHashString, base64_decode($this->sSigningKey));
$aRequest['signature'] = $sHash;
$sApiUrl = 'https://betalen.rabobank.nl/omnikassa-api' . ($this->bTestMode ? '-sandbox' : '') . '/order/server/api/order';
$sPostData = json_encode($aRequest,JSON_UNESCAPED_SLASHES);
$sResponse = _doHttpRequest($sApiUrl, $sPostData, true, 30, false, array('Authorization: Bearer ' . $this->sAccessToken));


Waarde van string $sPostdata in PHP code:
{"timestamp":"2018-08-23T17:02:36.4279066+02:00","merchantOrderId":"order123","amount":{"currency":"EUR","amount":"100"},"description":"Webshop bestelling order123","merchantReturnURL":"https://returnurl","paymentBrand":"IDEAL","paymentBrandForce":"FORCE_ONCE","signature":"d5fa1f40a4e4f3201928c14440e4ba3b22673cae0ef67a9fadbc6e8f06990dd0dd9b3897f774fccdecf361594c9635a23bb1fea8e58e09ac26fc304aed5cd873"}


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.NET code:
orderdata od = new orderdata();
od.timestamp = "2018-08-23T17:02:36.4279066+02:00";
od.merchantOrderId = "order123";
od.merchantReturnUrl =  "https://returnurl";
od.amount.currency = "EUR";
od.amount.amount = "100";
od.description = "Webshop bestelling order123";
od.paymentBrand = "IDEAL";
od.paymentBrandForce = "FORCE_ONCE";
byte[] signingkeydata = Convert.FromBase64String(sleutels.signingkey);
HMACSHA512 hmac = new HMACSHA512(signingkeydata);
string sig = od.timestamp + "," + od.merchantOrderId + "," + od.amount.currency + "," + od.amount.amount + "," + "," + od.description + "," + od.merchantReturnUrl + "," + od.paymentBrand + "," + od.paymentBrandForce;
byte[] sign = Encoding.UTF8.GetBytes(sig);
od.signature = BitConverter.ToString(hmac.ComputeHash(sign));
od.signature = od.signature.Replace("-", "").ToLower(); 
JavaScriptSerializer a = new JavaScriptSerializer();
string json = a.Serialize(od);


Waarde van string json in .NET code:
{"timestamp":"2018-08-23T17:02:36.4279066+02:00","merchantOrderId":"order123","amount":{"currency":"EUR","amount":"100"},"description":"Webshop bestelling order123","merchantReturnUrl":"https://returnurl","paymentBrand":"IDEAL","paymentBrandForce":"FORCE_ONCE","signature":"d5fa1f40a4e4f3201928c14440e4ba3b22673cae0ef67a9fadbc6e8f06990dd0dd9b3897f774fccdecf361594c9635a23bb1fea8e58e09ac26fc304aed5cd873"}

Beste antwoord (via Anoniem: 1108349 op 25-08-2018 13:21)


  • Gropah
  • Registratie: December 2007
  • Niet online

Gropah

Admin Softe Goederen

Oompa-Loompa 💩

Ik weet het natuurlijk niet zeker, maar de kans is groot dat de API hoofdletter gevoelig is, dus bijvoorbeeld merchantReturnUrl is niet hetzelfde als merchantReturnURL

Het zou overigens handig zijn als je de json ook in een code block zou zetten, das makkelijker vergelijken

[ Voor 24% gewijzigd door Gropah op 25-08-2018 13:13 ]

Alle reacties


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Gropah
  • Registratie: December 2007
  • Niet online

Gropah

Admin Softe Goederen

Oompa-Loompa 💩

Ik weet het natuurlijk niet zeker, maar de kans is groot dat de API hoofdletter gevoelig is, dus bijvoorbeeld merchantReturnUrl is niet hetzelfde als merchantReturnURL

Het zou overigens handig zijn als je de json ook in een code block zou zetten, das makkelijker vergelijken

[ Voor 24% gewijzigd door Gropah op 25-08-2018 13:13 ]


Acties:
  • 0 Henk 'm!

Anoniem: 1108349

Topicstarter
Dat is inderdaad de oplossing helemaal overheen gekeken wat stom!

Acties:
  • 0 Henk 'm!

Anoniem: 1108349

Topicstarter
Gropah heel erg bedankt voor de snelle reactie werkt nu ook goed in .net, heb ik dus al dagen overheen gekeken.

Acties:
  • 0 Henk 'm!

  • 62696e617279
  • Registratie: November 2017
  • Laatst online: 09-12-2024
Altijd fijn, die hoofdletter gevoeligheid in software. 8)7

Acties:
  • 0 Henk 'm!

  • ElCondor
  • Registratie: Juni 2001
  • Laatst online: 14:48

ElCondor

Geluk is Onmisbaar

@Anoniem: 1108349 , zodat anderen dit ook begrijpen, wellicht toch fijn om de .NET code nog even in een code block te zetten. ;)

Hay 365 dias en un año y 366 occasiones para festejar (Boliviaans spreekwoord)


Acties:
  • +1 Henk 'm!

Anoniem: 1108349

Topicstarter
ElCondor ik denk dat je bedoelt dat ik de werkende code nog even vermeld voor hen die ook hiermee bezig zijn dus hierbij de correct werkende code in .NET met de aanroep naar de omnikassa api, dit is een afgeslankte vorm zonder klant gegevens en product gegevens (zijn alleen nodig voor de paymentbrand AFTERPAY) en die bied ik niet aan.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
namespace omnikassatest
{
    public class Class1
    {
        public static class urls
        {
           public static string refreshurl = "https://betalen.rabobank.nl/omnikassa-api-sandbox/gatekeeper/refresh";
           public static string merchantreturnurl = "de return url";
           public static string orderurl = "https://betalen.rabobank.nl/omnikassa-api-sandbox/order/server/api/order";
        }
        public static class sleutels
        {
            public static string refreshtoken = "ophalen bij rabobank dashboard";
            public static string signingkey = "ophalen bij rabobank dashboard";
        }
        public class tokendata
        {
            public string token;
            public string validUntil;
            public string durationInMillis;
        }
        public class Amount
        {
            public string currency;
            public string amount;
        }
        public class orderdata
        {
            public string timestamp;
            public string merchantOrderId;
            public Amount amount = new Amount();
            public string description;
            public string merchantReturnURL; //hier zat de fout Url i.p.v. URL
            public string paymentBrand;
            public string paymentBrandForce;
            public string signature;
        }
        public class redirecturl
        {
            public string redirectUrl;
            public string signature;
        }
        public void adtokentocache()
        {
            ObjectCache cache = MemoryCache.Default;
            tokendata t = new tokendata();
            t = get_token();
            cache.Add("token", t.token, DateTime.Now.AddMilliseconds(Convert.ToDouble(t.durationInMillis)));
        }
        public tokendata get_token()
        {
            string html = string.Empty;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urls.refreshurl);
            request.Headers.Add("Authorization", "Bearer "+ sleutels.refreshtoken);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                html = reader.ReadToEnd();
            }
            JavaScriptSerializer a = new JavaScriptSerializer();
            tokendata data = (tokendata)a.Deserialize(html, typeof(tokendata));
            return data;
        }
        public string omni(decimal totaal, string betaalwijze, string orderid)
        {
            ObjectCache cache = MemoryCache.Default;
            if (cache["token"] == null)
            {
                adtokentocache();
            }
            string url = "";
            orderdata od = new orderdata();
            od.timestamp = DateTime.Now.ToString("o");
            od.timestamp = od.timestamp.Replace(" ", "");
            od.merchantOrderId = orderid;
            od.merchantReturnURL = urls.merchantreturnurl;
            od.amount.currency = "EUR";
            Int32 pr = Convert.ToInt32(totaal * 100);
            od.amount.amount = pr.ToString();
            od.description = "Webshop bestelling " + od.merchantOrderId;
            od.paymentBrand = betaalwijze;
            od.paymentBrandForce = "FORCE_ONCE";
            byte[] signingkeydata = Convert.FromBase64String(sleutels.signingkey);
            HMACSHA512 hmac = new HMACSHA512(signingkeydata);
            string sig = od.timestamp + "," + od.merchantOrderId + "," + od.amount.currency + "," + od.amount.amount + "," + "," + od.description + "," + od.merchantReturnURL + "," + od.paymentBrand + "," + od.paymentBrandForce;
            byte[] sign = Encoding.UTF8.GetBytes(sig);
            od.signature = BitConverter.ToString(hmac.ComputeHash(sign));
            od.signature = od.signature.Replace("-", "").ToLower(); 
            JavaScriptSerializer a = new JavaScriptSerializer();
            string json = a.Serialize(od);
            using (var httpClient = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Post, urls.orderurl);
                request.Headers.Add("Authorization", "Bearer " + cache["token"]);
                request.Content = new StringContent(json);
                request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                var response = httpClient.SendAsync(request).Result;
                var responseString = response.Content.ReadAsStringAsync().Result;
                redirecturl r = new redirecturl();
                r = a.Deserialize<redirecturl>(responseString);
                url = r.redirectUrl;
            }
            return url;
        }
    }
}

Acties:
  • +1 Henk 'm!

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 14:58
Oef.. Fijn dat het werkt natuurlijk, maar ik wil je als tip meegeven om wat meer op je styling te letten. Voor .Net en specifiek C# heeft Microsoft daar zelf fijne guidelines voor geschreven. Nu zal ik de laatste zijn die zegt dat je die guidelines ook tot de letter moet volgen, maar wees op z'n minst (voor jezelf) consequent. Hier krijg ik de bibbers van:
-Diverse soorten casings door elkaar (pascal / camel / geen)
-Nederlands en Engels door elkaar

Roomba E5 te koop


Acties:
  • 0 Henk 'm!

Anoniem: 1108349

Topicstarter
sig 69 sorry dat je de bibbers van mijn programmeer stijl krijg, ben inderdaad niet erg consequent nooit geweest trouwens, ik heb echter nooit de noodzaak ingezien om dit wel te zijn. Dit is dan ook de eerste keer dat iemand anders dan ikzelf mijn code leest. Mijn code gebruik ik alleen voor mijn eigen bedrijf (webshop en p.o.s systeem), dus als het werkt zoals ik wil dat het werkt vind ik het wel goed. Maar ik zal in het vervolg als ik wat op dit forum plaats proberen om wat consequenter te zijn.

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 14:58
Het is maar een tip hè doe er mee wat je wil.

Roomba E5 te koop


  • vincentkoevoets
  • Registratie: Augustus 2018
  • Laatst online: 23-04 16:47
Ik durf het bijna niet te vragen, maar heb je misschien ook de volledige PHP-versie nog ergens, en zou je die ook kunnen posten? Ik probeer in PHP hetzelfde te bereiken.
Alvast bedankt!

  • KirovAir
  • Registratie: September 2009
  • Laatst online: 16:04
sig69 schreef op dinsdag 28 augustus 2018 @ 22:33:
Oef.. Fijn dat het werkt natuurlijk, maar ik wil je als tip meegeven om wat meer op je styling te letten. Voor .Net en specifiek C# heeft Microsoft daar zelf fijne guidelines voor geschreven. Nu zal ik de laatste zijn die zegt dat je die guidelines ook tot de letter moet volgen, maar wees op z'n minst (voor jezelf) consequent. Hier krijg ik de bibbers van:
-Diverse soorten casings door elkaar (pascal / camel / geen)
-Nederlands en Engels door elkaar
Schrikbarende code om in productie te zien. :o

"The only thing more dangerous than a hardware guru with a code patch is a programmer with a soldering iron."


  • robertpNL
  • Registratie: Augustus 2003
  • Niet online
vincentkoevoets schreef op donderdag 30 augustus 2018 @ 10:02:
Ik durf het bijna niet te vragen, maar heb je misschien ook de volledige PHP-versie nog ergens, en zou je die ook kunnen posten? Ik probeer in PHP hetzelfde te bereiken.
Alvast bedankt!
Zie Rabobank support site. Verderop de pagina bij SDK vind je dan een link "Download de Software Development Kit voor Rabo OmniKassa o.b.v. PHP (inclusief documentatie / English documentation included)". Daar zit voorbeeld code in.

  • vincentkoevoets
  • Registratie: Augustus 2018
  • Laatst online: 23-04 16:47
robertpNL schreef op donderdag 30 augustus 2018 @ 10:06:
[...]


Zie Rabobank support site. Verderop de pagina bij SDK vind je dan een link "Download de Software Development Kit voor Rabo OmniKassa o.b.v. PHP (inclusief documentatie / English documentation included)". Daar zit voorbeeld code in.
Nou ja zeg, ik heb weer met mijn neus gekeken! Daar was ik naar op zoek, bedankt voor je reactie.

Acties:
  • 0 Henk 'm!

  • pekeltje
  • Registratie: December 2009
  • Laatst online: 04-01 14:34
robertpNL schreef op donderdag 30 augustus 2018 @ 10:06:
[...]


Zie Rabobank support site. Verderop de pagina bij SDK vind je dan een link "Download de Software Development Kit voor Rabo OmniKassa o.b.v. PHP (inclusief documentatie / English documentation included)". Daar zit voorbeeld code in.
Weet je toevallig ook of er een volledig werkend voorbeeld is in PHP ?
Heb de SDK, maar weet nog dat ik bij de andere een report.php en return.php had, en een ideal.php waarin de betaling werd geregeld.
Of moeten we nu alles zelf uitzoeken van de Rabobank met behulp van de API ?

Acties:
  • +1 Henk 'm!

Anoniem: 1108349

Topicstarter
pekeltje schreef op vrijdag 31 augustus 2018 @ 16:42:
[...]


Weet je toevallig ook of er een volledig werkend voorbeeld is in PHP ?
Heb de SDK, maar weet nog dat ik bij de andere een report.php en return.php had, en een ideal.php waarin de betaling werd geregeld.
Of moeten we nu alles zelf uitzoeken van de Rabobank met behulp van de API ?
Ik heb een voorbeeldcode in PHP gekregen via de rabobank support afdeling van de firma Ideal Checkout, deze code is niet dezelfde die je kan downloaden van de rabobank site. Deze code bestaat uit een Report.php, Return php, Settings php, Omnikassa.cls.php en een Start.php. Helemaal kant en klaar is deze code volgens mij niet maar er staan wel goede aanwijzingen in wat je er zelf nog aan moet toevoegen. Ik weet niet of dat het op prijs wordt gesteld als ik deze code hier op het forum plaats, maar ik kan hem eventueel wel mailen.

Acties:
  • 0 Henk 'm!

  • pekeltje
  • Registratie: December 2009
  • Laatst online: 04-01 14:34
Dat zijn inderdaad de bestanden zoals we die nu ook gebruiken.

Ik heb je een PM gestuurd.

Acties:
  • +1 Henk 'm!

Anoniem: 396143

alle .Netters, check deze library:
github Omnikassa 2.0 Lib
met dank aan Dirk Lemstra

[ Voor 6% gewijzigd door Anoniem: 396143 op 26-10-2018 10:21 ]


Acties:
  • 0 Henk 'm!

Anoniem: 1108349

Topicstarter
Dit is niet versie 2.0 maar 1.0

Acties:
  • 0 Henk 'm!

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 25-04 17:58

robjanssen

Software Developer

Pagina: 1