Skip to content

Repository files navigation

Payment Highway JavaScript API Library

node

This is an example implementation of the communication with the Payment Highway API using JavaScript/TypeScript. The Form API and Payment API implement the basic functionality of the Payment Highway.

This code is provided as-is, use it as inspiration, reference or drop it directly into your own project and use it.

For full documentation on the PaymentHighway API visit our developer website: https://paymenthighway.fi/dev/

Installation

npm install paymenthighway

Overview

Start with building the HTTP form parameters by using the FormParameterBuilder.

FormBuilder

Create an instance of the builder, then use the generate methods to receive a list of parameters for each API call.

Initializing the builder

varpaymentHighway=require('paymenthighway');varmethod='POST';vartestKey='testKey';vartestSecret='testSecret';varaccount='test';varmerchant='test_merchantId';varserviceUrl='https://v1-hub-staging.sph-test-solinor.com';varformBuilder=newpaymentHighway.FormBuilder(method,testKey,testSecret,account,merchant,serviceUrl);

Example common parameters for the following form generation functions

varsuccessUrl='https://example.com/success';varfailureUrl='https://example.com/failure';varcancelUrl='https://example.com/cancel';varlanguage='EN';

Each method returns a FormContainer (TS)/(JS) object, which provides required hidden fields for the HTML form to make a successful transaction to Form API. The builder will generate a request id, timestamp, and secure signature for the transactions, which are included in the FormContainer fields.

In order to charge a card given in the Form API, the corresponding transaction id must be committed by using Payment API.

classFormContainer{constructor(publicmethod: Method,publicbaseUrl: string,publicactionUrl: string,publicnameValuePairs: Pair<string,string>[],publicrequestId: string){}publicgetAction(): string{returnthis.baseUrl+this.actionUrl;}}

GenerateAddCardParameters

varformContainer=formBuilder.generateAddCardParameters(successUrl,failureUrl,cancelUrl,language);// form parametersvaraction=formContainer.getAction();varmethod=formContainer.method;// 'GET'|'POST'varfields=formContainer.nameValuePairs;// Pair<string, string> []fields.forEach((pair)=>{pair.first;pair.second;});

GeneratePaymentParameters

varamount=1950;varcurrency='EUR';varorderId='1000123A';vardescription='10 balloons 19,50€';varformContainer=formBuilder.generatePaymentParameters(successUrl,failureUrl,cancelUrl,language,amount,currency,orderId,description);

GenerateGetAddCardAndPaymentParameters

varamount=1990;varcurrency='EUR';varorderId='1000123A';vardescription='A Box of Dreams. 19,90€';varformContainer=formBuilder.generateAddCardAndPaymentParameters(successUrl,failureUrl,cancelUrl,language,amount,currency,orderId,description);

Simple MobilePay form payment

varamount=1990;varcurrency='EUR';varorderId='1000123A';vardescription='A Box of Dreams. 19,90€';varformContainer=formBuilder.generatePayWithMobilePayParameters(successUrl,failureUrl,cancelUrl,language,amount,currency,orderId,description);

MobilePay payment is to be committed as any other Form Payment

MobilePay form payment with optional parameters

varamount=1990;varcurrency='EUR';varorderId='1000123A';vardescription='A Box of Dreams. 19,90€';varexitIframeOnResult=undefined;varlogoUrl='https://foo.bar/biz.png';varphoneNumber='+358401234567';varshopName='Jaskan kenkä';varformContainer=formBuilder.generatePayWithMobilePayParameters(successUrl,failureUrl,cancelUrl,language,amount,currency,orderId,description,exitIframeOnResult,logoUrl,phoneNumber,shopName);
About shop logo in MobilePay
  • The logo must be 250x250 pixel in .png format.
  • MPO will show a default logo in the app if this is empty or the image location doesn’t exist.
  • Once a ShopLogoURL has been sent to MPOnline the .png-file on that URL must never be changed. If the shop wants a new (or more than one) logo, a new ShopLogoURL must be used.
  • The logo must be hosted on a HTTPS (secure) server.

Example validateFormRedirect

// Initialize secure signervarsecureSigner=newpaymentHighway.SecureSigner(testKey,testSecret);// success routeapp.get('/success',function(req,res){varvalidRedirect=secureSigner.validateFormRedirect(req.query);// Boolean});

PaymentApi

In order to do safe transactions, an execution model is used where the first call to /transaction acquires a financial transaction handle, later referred as “ID”, which ensures the transaction is executed exactly once. Afterwards it is possible to execute a debit transaction by using the received id handle. If the execution fails, the command can be repeated in order to confirm the transaction with the particular id has been processed. After executing the command, the status of the transaction can be checked by executing the PaymentAPI.transactionStatus("id") request.

In order to be sure that a tokenized card is valid and is able to process payment transactions the corresponding tokenization id must be used to get the actual card token.

Initializing the Payment API

varserviceUrl="https://v1-hub-staging.sph-test-solinor.com";vartestKey='testKey';vartestSecret='testSecret';varaccount='test';varmerchant='test_merchantId';varpaymentAPI=newPaymentAPI(serviceUrl,testKey,testSecret,account,merchant);

Init transaction

returnpaymentAPI.initTransaction();

Commit Form Transaction

varamount=1990;varcurrency='EUR';varrequest=newpaymentHighway.CommitTransactionRequest(amount,currency);returnpaymentAPI.commitTransaction(transactionId,request);// Returns PromiseLike

Tokenize (get the actual card token by using token id)

returnpaymentAPI.tokenization(tokenizationId);

Example Debit with Token

NOTE: The debitTransaction method will be deprecated starting from Sep 14th 2019 in favor of the new chargeCustomerInitiatedTransaction and chargeMerchantInitiatedTransaction in order to comply with the EU's PSD2 directive.

vartoken=newpaymentHighway.Token('tokenId');varamount=1990;varcurrency='EUR';varrequest=newpaymentHighway.TransactionRequest(token,amount,currency);returnpaymentAPI.initTransaction().then(function(init){returnpaymentAPI.debitTransaction(init.id,request);});

Charging a card token

After the introduction of the European PSD2 directive, the electronic payment transactions are categorised in so called customer initiated transactions (CIT) and merchant initiated transactions (MIT).

Customer initiated transactions are scenarios, where the customer actively takes part in the payment process. This also includes token, or "one-click" purchases, where the transaction uses a previously saved payment method.

Merchant initiated transactions are payments triggered without the customer's participation. This kind of transactions can be used for example in scenarios where the final price is not known at the time of the purchase or the customer is not present when the charge is made. A prior agreement, or "mandate" between the customer and the merchant is required.

Charging a customer initiated transaction (CIT)

When charging a token using customer initiated transaction, applicable exemptions are attempted in order to avoid the need for strong customer authentication, 3D Secure. These exemptions may include but are not limited to: low-value (under 30 EUR) or transaction risk analysis.

Regardless, there is always a possibility the card issuer requires strong customer authentication by requesting a step-up. In this case, the response will contain "soft decline" result code 400 and an URL, where the customer needs to be redirected to, in order to perform the authentication. The merchant's URLs where the customer will be redirected back to - after completing the authentication - need to be defined in the returnUrls (ReturnUrls) parameter in StrongCustomerAuthentication.

When the customer is redirected back to the success URL, after completing the payment using strong customer authentication, the payment needs to be committed exactly as in the normal FormAPI payment flow. Please note, a new transaction ID is created for this payment and the original transaction ID from the CIT request is considered as failed. The merchant supplied "order", the request ID, or custom merchant parameters specified in the return URLs, can be used to connect the returning customer to the specific payment.

In addition to the return urls, the StrongCustomerAuthentication object contains many optional fields for information about the customer and the transaction. This information is used in transaction risk analysis (TRA) and may increase the likelihood of transaction being considered as low-risk, thus avoiding the need for strong authentication.

consttoken=newpaymentHighway.Token('tokenId');constamount=1990;constcurrency='EUR';constreturnUrls=ReturnUrls.Builder("https://example.com/success",// URL the user is redirected after succesful 3D-Secure authentication if strong customer authentication is required"https://example.com/cancel",// URL the user is redirected after cancelled 3D-Secure authentication if strong customer authentication is required"https://example.com/failure"// URL the user is redirected after failed 3D-Secure authentication if strong customer authentication is required).setWebhookSuccessUrl("https://example.com/success/12345/?webhook=1").setWebhookCancelUrl("https://example.com/failure/12345/?webhook=1").setWebhookFailureUrl("https://example.com/webhook/failure/?webhook=1").build();constcustomerDetails=CustomerDetails.Builder().setShippingAddressMatchesBillingAddress(true).setName('Eric Example').setEmail('eric.example@example.com')// ....build();constsca=StrongCustomerAuthentication.Builder(returnUrls).setCustomerDetails(customerDetails)// Optionally other information about the customer and purchase to help in transaction risk analysis (TRA).build();returnpaymentAPI.chargeCustomerInitiatedTransaction(transactionId,newChargeCitRequest(token,amount,currency,sca));

Charging a merchant initiated transaction (MIT)

When charging the customer's card in context where the customer is not actively participating in the transaction you should use the chargeMerchantInitiatedTransaction method. The MIT transactions are exempt from the strong customer authentication requirements of PSD2 so the request cannot be answered with "soft-decline" response (code 400) unlike customer initated transactions.

vartoken=newpaymentHighway.Token('tokenId');varamount=1990;varcurrency='EUR';returnpaymentAPI.chargeMerchantInitiatedTransaction(transactionId,newChargeMitRequest(token,amount,currency));

Partial Revert

returnpaymentAPI.revertTransaction(transactionId,newRevertTransactionRequest(amount));

Revert whole transaction

returnpaymentAPI.revertTransaction(transactionId,newRevertTransactionRequest());

Transaction Status

returnpaymentAPI.transactionStatus(transactionId);

Order status

returnpaymentAPI.searchOrders("order");

Daily batch report

returnpaymentAPI.fetchDailyReport("yyyyMMdd");

Form status

returnpaymentAPI.formSessionStatus("sessionId");

Errors

Payment Highway authenticates each request and if there is invalid parameters or a signature mismatch, it returns an error. PaymentHighwayAPI returns PromiseLike from each requests.

It is recommended to gracefully handle errors from the API.

PaymentHighwayAPI.initTransaction().then(function(initResponse){// handle response
...
}).catch(function(error){// handle errors
...
});

Help us make it better

Please tell us how we can make the API better. If you have a specific feature request or if you found a bug, please use GitHub issues. Fork these docs and send a pull request with improvements.

About

Payment Highway JavaScript API library

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages