Implementacija CorvusPay kartičnog plaćanja koristeći Node.js, Express.js i Angular

U ovom blog postu možete saznati kako implementirati CorvusPay kartično plaćanje koristeći Node.js tj. Express.js i Angular Framework.

Kartično plaćanje provodi se kroz Corvus Form Service što znači da korisnik nakon odabira artikala bude preusmjeren na URL za autorizaciju kreditne kartice. Na tom URL-u ispunjava se obrazac s potrebnim podacima o kreditnoj kartici nakon čega korisnik ponovno bude preusmjeren na web shop gdje se najčešće prikazuje poruka o ne/uspješnoj kupovini.

Tijek transakcije kroz CorvusPay sustav odvija se na sljedeći način:

  • Kupac u web trgovini odabire proizvod ili uslugu koju želi platiti karticom.
  • Kupac se preusmjerava sa stranice trgovca na CorvusPay platnu formu (stranicu) gdje unosi podatke potrebne za realizaciju kartične transakcije.
  • CorvusPay šalje banci zahtjev za autorizacijom.
  • Banka šalje odgovor na zahtjev za autorizacijom na CorvusPay.
  • CorvusPay preusmjerava kupca na cancel ili success url kojeg definira trgovac ovisno o ishodu transakcije.

Moguća je i integracija tog obrasca unutar web shopa, ali u tom slučaju trgovac mora imati PCI DSS certifikat.

Tijek implementacije

Proces se istovremeno odvija u dva smjera. Prvi se tiče administrativnih poslova u kojima Corvus od trgovca prikuplja potrebnu dokumentaciju za pokretanje procesa aktivacije kartičnog plaćanje koju prosljeđuje prema bankama/kartičnim kućama.

Paralelno trgovac (web shop) postavlja obavezan sadržaj na web trgovinu (uvjeti korištenja i plaćanja, logo CorvusPaya,…), vrši implementaciju prema dostupnim uputama i testira sustav pomoću razvojnog certifikata. Nakon obavljenih testova postavlja se produkcijski certifikat čime se proces implementacije završava.

Uvod

Komunikacija između trgovca i usluge CorvusPay vrši se putem HTTPS POST web zahtjeva.

Svaki web zahtjev prema Corvusu treba obavezno sadržavati tri parametra, a to su:

Store ID
Secret Key
Client Certificate (.p12).

Dobiju se dva seta ovih podataka. Jedan set za testiranje, a drugi za produkciju.

Obavezni CorvusPay parametri

Obavezni parametri su: version, store_id, order_number, language, currency, amount, cart, signature i require_complete.

U slučaju greške pri kreiranju parametara prikazat će se sljedeći ekran:

CorvusPay greška
Vaš zahtjev ne može biti obrađen – CorvusPay

order_number mora biti jedinstven jer sustav će provjeriti i odbiti svaki upit na Corvus API ako narudžba s istim brojem narudžbe već postoji.

signature se kreira koristeći HMAC-SHA256. On se sastoji od svih obaveznih i opcionalnih vrijednosti (key-value field pairs), poredanih abecedno i spojenih bez razmaka.

To onda izgleda ovako:

na osnovu čega se dobije signature

signature = HMAC-256(key, key-value field pairs)

~ ključ: UNV3-i2otJw0rUWzA2lpcNRqTOYRWdAeTw
~ parametri:
– version : 1.3
– store_id : 2029
– order_number : 1537270065109
– amount : 10.00
– currency : HRK
– cart : kindle paperwhite
– require_complete : false
– language : hr

CorvusPay HTTPS POST
CorvusPay Integration Manual v5.1.0

Neobavezni CorvusPay parametri

Osim obaveznih parametara moguće je koristiti i neobavezne. U ovom slučaju to će biti parametri vezani uz plaćanje na rate.

Tri su načina pokretanja transakcije na rate:
• Fiksni broj rata
• Fleksibilan broj rata
• Samostalan odabir rata za određenu karticu

Napomene:
• Ako se za određenu platnu karticu ne pošalje parametar payment_brandName kartica neće biti dostupna za odabir
• Prvi znak parametra payment_ trebao bi biti jednak N ili Y jer to označava je li dozvoljeno jednokratno plaćanje ili ne
• Posljednja četiri znaka određuju raspon broja rata. Kupac može odabrati broj rata u rasponu između prvog dvoznamenkastog broja i drugog dvoznamenkastog broja

CorvusPay plaćanje na rate
CorvusPay Integration Manual v5.1.0

Web aplikacija (Angular)

Unutar forme pomoću POST metode poziva se API za pokretanje kartičnog plaćanja.

Sve navedene vrijednosti su promjenjive tako da ih prilikom svake promjene unutar .ts datoteke treba osvježiti i unutar forme </form>.

Parametri signature i payment_ mogu se kreirati na frontendu i backendu. U ovom slučaju oni će se kreirati na frontendu i prosljeđivati kroz formu na API.

Za potrebu kreiranja HmacSHA256 potpisa koristi se crypto-js. Uz to, unutar environment varijable nalaze se razvojni i produkcijski parametri secretKey i storeId.

Glavna razlika u ovom dijelu tiče se ukupne cijene tj. ovisno o tome prelazi li iznos od 500kn plaćanje na rate biti će odobreno ili onemogućeno. U oba slučaja kreira se različit signature.

Za ukupan iznos veći ili jednak 500kn koristi se sljedeće:

CorvusPay - plaćanje na rate

Dok se za iznose manje od 500kn koristi:

CorvusPay - jednokratno plaćanje

Backend API (Express.js)

Backend logika nalazit će se u server.js datoteci. Kako ju kreirati možete se vidjeti u blog postu “Izrada RESTful API-ja koristeći Node.js i Express.js“. Razlika između primjera iz tog blog posta i ovoga sada je što više nije potrebno koristiti body-parser.

Ova će se datoteka sastojati od tri krajnje točke (API endpoints).

Prva krajnja točka, '/corvusPay', preusmjerit će korisnika na formu za plaćanje.

Nakon unosa i obrade podataka o kartici

CorvusPay - obrada u tijeku
CorvusPay – obrada u tijeku

korisnik je preusmjeren na dodatnu sigurnosnu autentifikaciju kartice.

CorvusPay - sigurnosna autentifikacija kartice
CorvusPay – sigurnosna autentifikacija kartice

Ako je sve prošlo uspješno korisniku će se prikazati obavijest

CorvusPay - transakcija-uspjela
CorvusPay – transakcija uspjela

i na e-mail će dobiti obavijest o uspješnoj narudžbi.

CorvusPay - obavijest o uspješnoj narudžbi
CorvusPay – obavijest o uspješnoj narudžbi

Druga krajnja točka, '/corvusPaySuccess' , prihvaća odgovor od Corvusa kada je plaćanje uspješno provedeno.

CorvusPay - uspješno plaćanje

Treća krajnja točka, '/corvusPayCancel' , prihvaća odgovor od Corvusa kada je plaćanje neuspješno ili otkazano.

CorvusPay - neuspjelo plaćanje

HelmetJS – zaštita HTTP headera Express.js aplikacija

Sigurnost, jedna od stvari s kojoj svi prilikom razvoja aplikacije govore, ali ju malo njih smatra ozbiljnom ili odgađa za kasnije.

S druge strane, HTTP headeri su nešto što korisnici Express.js aplikacije ne vide i onda je developerima lako zapostaviti ih i gledati na njih kao na nešto nebitno. S obzirom da headeri daju razne informacije koje osobe s lošim namjerama mogu iskoristiti jasno je zašto ipak treba voditi brigu o njima tj. informacijama koje pružaju.

Jedna od tih informacije je X-Powered-By: Express što web pregledniku govori što pokreće aplikaciju tj. na čemu se temelji. Helmet.js će, između ostalog, sakriti ovu informaciju.

Zato je cilj ovog blog posta pokazati kako na brz i jednostavan način zaštititi Express.js aplikaciju koristeći Helmet.js koji neće riješiti sve sigurnosne probleme, ali je ipak odličan početak.

Što je Helmet.js?

Helmet.js je kolekcija od 14 modula koje se brinu za sigurnost HTTP zaglavlja (headers) točnije response headera.

HelmetJS moduli

7 od 14 modula aktiviraju se jednom linijom koda

Osim toga, svaki od tih zadanih modula moguće je individualno aktivirati

ili deaktivirati

Helmet.js moduli

Trenutno postoji 14 modula (defaultni označeni sa (✓)), a to su sljedeći:

1.) contentSecurityPolicy

Sets the Content-Security-Policy header which can help protect against malicious injection of JavaScript, CSS, plugins, and more.

2.) crossdomain

Prevents Adobe Flash and Adobe Acrobat from loading content on your site.

3.) dnsPrefetchControl (✓)

This middleware lets you disable browsers’ DNS prefetching by setting the X-DNS-Prefetch-Control header.

4.) expectCt

Tells browsers to expect Certificate Transparency. For more about Certificate Transparency and this header, see this blog post and the in-progress spec.

5.) featurePolicy

Lets you restrict which browser features can be used. For example, you can disable fullscreen or vibration APIs.

6.) frameguard (✓)

Frameguard mitigates clickjacking attacks by setting the X-Frame-Options header.

7.) hidePoweredBy (✓)

Removes the X-Powered-By header to make it slightly harder for attackers to see what potentially-vulnerable technology powers your site.

8.) hpkp

Helps you set the Public-Key-Pins header to prevent person-in-the-middle attacks. Usage of this header (and therefore this middleware) is not recommended. Be very careful when deploying this—you can easily misuse this header and cause problems. Chrome dropped support for HPKP citing risks of misuse.

9.) hsts (✓)

This module sets the Strict-Transport-Security header to keep your users on HTTPS.

10.) ieNoOpen (✓)

This middleware sets the X-Download-Options to prevent Internet Explorer from executing downloads in your site’s context.

11.) noCache

Aims to disable browser caching by setting several headers.

12.) noSniff (✓)

Helps prevent browsers from trying to guess (“sniff”) the MIME type, which can have security implications. It does this by setting the X-Content-Type-Options header to nosniff.

13.) referrerPolicy

Can control the behavior of the Referer header by setting the Referrer-Policy header.

14.) xssFilter (✓)

Sets the X-XSS-Protection header to prevent reflected XSS attacks.

Kreiranje projekta

Kreiram mapu projekta ExpressHelmet i unutar nje datoteku server.js

HelmetJS i Express.js

sa sljedećim sadržajem:

Detalje o tome kako kreirati osnovni Express.js API moguće je pronaći u blog postu pod naslovom Izrada RESTful API-ja koristeći Node.js i Express.js

Ako sada pokrenem API na adresi http://localhost:8080/api unutar Google Chrome Developer alata pod tabom Network dobit ću sljedeće:

HelmetJS i Express.js Headers

Postavljanje Helmet.js-a

Sljedećom naredbom untuar mape projekta instaliram Hellmet.js

Također, unutar server.js datoteke dodajem sljedeće:

Ako sada pokrenem API na adresi http://localhost:8080/api unutar Google Chrome Developer alata pod tabom Network dobit ću sljedeće:

HelmetJS i Express.js Headers

Na slici iznad mogu se vidjeti headeri kojih ranije nije bilo, a to su:

Također, headere mogu vidjeti i pokretanjem sljedeće naredbe:

Command line curl

Zaključak

Helmet.js nije “all in one” rješenje niti se njegovim postavljenjem unutar projekta može reći da je sigurnosna zaštita aplikacije gotova, ali je svakako dobar početak procesa razmišljanja o sigurnosti.

Node.js Cron Job – automatsko izvršavanje zakazanih zadataka

Do sada sam objavio nekoliko članaka korištenju NodeJS API-ja i svaki od njih ima istu poveznicu, a to je činjenica da se izvršavaju isključivo kada ih pozovem. U većini slučajeva to tako treba biti, ali postoje i slučajevi u kojima želim da se određeni zadatak izvrši bez da ga ručno moram pokrenuti pozivajući neki API endpoint. U tome će mi pomoći Cron Job.

Postavljanje projekta

Kreiram mapu naziva ExpressNodeCron i unutar nje pokrećem naredbu:

Odmah nakon toga instaliram Express.js i Node Cron pakete:

Sada u mapi projekta mogu vidjeti datoteku package.json koja je osnova ovog projekta.

Kreiranje API-ja

Unutar datoteke index.js koju sam upravo kreirao kopiram sljedeći sadržaj:

API odmah testiram na putanji http://localhost:8080/api/

ExpressJS API

Cron Job funkcionalnost

Sada pratim dostupnu dokumentaciju na adresi https://www.npmjs.com/package/node-cron

Na sljedećem primjeru nalazi se osnova cron job funkcionalnosti.

Na liniji 1 nalazi se "* * * * *" što označava odabrani interval u kojemu će se određeni zadatak izvršiti.

Na liniji 2 nalazi se zadatak koji će se izvršiti u zadanom intervalu.

Node.js Cron Job – automatsko izvršavanje zakazanih zadataka

Osim ranije spomenutog intervala moguće su i sljedeće kombinacije:

– više vrijednosti odvojenih zarezom

– korištenje raspona vrijednosti

– izvršavanje u koracima

– korištenje naziva mjeseca i dana umjesto brojeva (moraju biti na engleskom jeziku)

Svi ranije navedeni zadaci pokreću se prilikom startanja NodeJS servera, ali postoje još i dodatne metode pomoću kojih je moguće u određenom trenutku pokrenuti neki Cron Job, stopirati ga ili skroz ugasiti.

Start task.start();

Stop task.stop();

Jednom stopirati zadatak moguće je ponovno pokrenuti.

Primjer:

Pozivanjem putanje http://localhost:8080/api/stopiraj zaustavljam Cron Job.

Destroy task.destroy();

Jednom prekinuti zadatak nije moguće ponovno pokrenuti.

ExpressJS middleware za ograničavanje ponovljenih zahtjeva na API-je

Jedna od najvažnijih komponenti svakog API-ja, osim mogućnosti upravljanja podacima, je sigurnost. A jedna od osnovnih komponenti te sigurnosti je mogućnost blokiranja prekomjernih upita koji se šalju na pojedini API endpoint.

U ovom ću slučaju za tu svrhu koristiti Express Rate Limit modul.

Postavljanje projekta

Kreiram mapu naziva ExpressRateLimit i unutar nje pokrećem naredbu:

Odmah nakon toga instaliram Express.js i Express Rate Limit pakete:

Sada u mapi projekta mogu vidjeti datoteku package.json koja je osnova ovog projekta.

Sada imam sve potrebno za kreiranje API-ja.

Kreiranje API-ja

Kreiram index.js datoteku unutar koje kopiram sljedeći sadržaj:

API mogu testirati na putanji http://localhost:8080/api/

ExpressJS Rate Limit – zaštita API-ja

Sada, nakon što sam se uvjerio da API ispravno radi, mogu implementirati Express Rate Limit modul.

Express Rate Limit modul

Kreiram dvije krajnje točke (endpoint):

Njima pristupam putem URL-ova:

http://localhost:8080/api/putanja1 i http://localhost:8080/api/putanja2

ExpressJS Rate Limit – zaštita API-ja

Prije nego ubacim sigurnosnu zaštitu URL-ovima je moguće pristupiti neograničeno mnogo puta. Ovo nije problem kada, kao u ovom konkretnom slučaju, šaljem mali json objekt, ali kada je u pitanju API koji dohvaća više podataka iz npr. SQL baze onda to već postaje problem jer može doći do zagušenja ili potpunog blokiranja servera.

Sada ću dodati apiLimiter objekt s nekoliko parametara.

Ako želim da se ta pravila primjene na sve krajnje točke (endpoint) dodajem sljedeće:

Mogu vidjeti da je svaki sljedeći upit sporiji od prethodnog i da se nakon 5 poslanih upita prikazuje poruka iz apiLimiter objekta.

ExpressJS Rate Limit – zaštita API-ja

U slučaju da za svaku krajnju točku tj. svaki endpoint želim postaviti drugačiji uvijet to radim tako da kreiram toliki broj objekata koliko ima krajnjih čvorova. Npr.

Nodemailer & NodeJS – API za slanje emaila

Cilj ovog blog posta je pokazati kako napraviti API za slanje emaila. To ću postići koristeći NodeJS, ExpressJS, Nodemailer i naravno Gmail.

Postavljanje projekta

Kreiram mapu za projekt i unutar nje pokrećem naredbu

i odmah nakon toga instaliram potrebne NPM pakete:

Express.js: $ npm install express --save
Nodemailer: $ npm install nodemailer--save
bodyParser: $ npm install body-parser -save

Struktura projekta prema package.json sada izgleda ovako:

Sada imam sve spremno za kreiranje datoteke unutar koje će se nalaziti logika API-ja.

API sada mogu i pokrenuti te se uvjeriti da radi. Pokrećem ga naredbom u kojoj riječ “index” označava naziv .js datoteke.

Nodemailer & NodeJS – API za slanje emaila

To je mogla biti i npr. server.js datoteka. U tom bi slučaju API pokrenuo naredbom $ node server.

Na adresi http://localhost:8080/api mogu vidjeti da je API uspješno pokrenut.

Nodemailer & NodeJS – API za slanje emaila

Slanje testnog e-maila

Unutar datoteke index.js sada ću kreirati API za slanje e-maila.

S obzirom na parametar secureConnection: false vrlo je važno da omogućim dopuštanje nesigurnijim aplikacijama da pristupe računu na adresi https://myaccount.google.com/security?pli=1

“Less Secure Apps” - Google

Jer ako to ne napravim dobit ću poruku o grešci što znači da e-mail neće biti poslan/primljen. Ovaj dio mi je zadavao najviše problema prije dvije godine kada sam prvi put radio Nodemailer API. U pitanju je bila funkcionalnost vezana uz resetiranje lozinke.

Nodemailer & NodeJS – API za slanje emaila

Ako sada putem Postmana pokrenem POST zahtjev na adresu http://localhost:8080/api/posaljiEmail vrlo brzo će mi stići e-mail.

Nodemailer & NodeJS – API za slanje emaila

Zašto se u slici iznad kao adresa primatelja nalazi drugačija adresa od one navedene gore u API-ju? To je zbog postavki unutar Gmaila gdje je navedeno da je adresa k*n*a*t@tomislavstankovic.com zadana adresa pošiljatelja. S obzirom da ovdje koristim Gmail kao servis za slanje e-maila jasno je da će on uzeti te zadane postavke.

Nodemailer & NodeJS – API za slanje emaila

E-mail sa “pravim” podacima

U gornjem sam se primjeru uvjerio da moj Nodemailer API uredno radi, a sada želim imati mogućnost određivanja na koju adresu i koji sadržaj želim poslati.

API sada izgleda ovako:

Nodemailer & NodeJS – API za slanje emaila

Ovdje se može vidjeti da podatke šaljem kroz req.body i upravo je to razlog zbog kojeg koristim body-parser. U slučaju da nisam koristio body-parser dobio bi sljedeću grešku.

Ovdje se može vidjeti da podatke šaljem kroz <span class="lang:js decode:true  crayon-inline">req.body</span> i upravo je to razlog zbog kojeg koristim <strong><em><a href="https://www.npmjs.com/package/body-parser" rel="noopener" target="_blank">body-parser</a></em></strong>. U slučaju da nisam koristio <em>body-parser</em> dobio bi sljedeću grešku.

Također, ako ne unesem sve potrebne podatke body-parser neće imati s čime raditi i opet ću dobiti grešku. U ovom slučaju nisam poslao e-mail adresu primatelja.

Nodemailer & NodeJS – API za slanje emaila

Nakon što unesem sve potrebne podatke, body-parser će odraditi svoje i e-mail će biti uspješno poslan/primljen.

Nodemailer & NodeJS – API za slanje emaila