klarna-on-demand
Version:
SDK for Klarna's on-demand purchase service.
227 lines (160 loc) • 12.5 kB
Markdown
#Integration Guide
This guide includes all information necessary to receive payments from a user of your application through Klarna. In this guide, you will see how to allow the user to register with Klarna, change payment preferences and perform purchases.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
###Table of Contents
- [Including the SDK in your project](#including-the-sdk-in-your-project)
- [Supplying your API key](#supplying-your-api-key)
- [The registration view](#the-registration-view)
- [Showing the view and interacting with it](#showing-the-view-and-interacting-with-it)
- [When should you show the registration view?](#when-should-you-show-the-registration-view)
- [Performing purchases](#performing-purchases)
- [Purchase example](#purchase-example)
- [Signing requests](#signing-requests)
- [The preferences view](#the-preferences-view)
- [Showing the view and interacting with it](#showing-the-view-and-interacting-with-it-1)
- [Closing views](#closing-views)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
##Including the SDK in your project
This guide assumes you use [NPM](https://www.npmjs.com/) to manage your javascript dependencies. If you do not, refer to our [official documentation (coming soon)](http://developers.klarna.com) for an alternative setup approach.
In your project's folder, run the following command:
```
npm install klarna-on-demand
```
At which point, the SDK should be available under the same folder at `node_modules/klarna-on-demand/lib/klarna-on-demand.js` or minified at `node_modules/klarna-on-demand/lib/klarna-on-demand.min.js`.
**Note:** As stated in the project's README, this SDK is mainly aimed at hybrid phone applications. However, for the sake of simplicity, we will ignore the various way one would be able to create a native app from html source, and instead focus on a basic example of a website that can be opened directly from your machine's file system.
##Supplying your API key
In order to use the SDK, you will need an API key to identify yourself. You can get one from our [developer site (coming soon)](http://developers.klarna.com/).
You must set the API key on each page where you plan to utilize the SDK, before making any actual calls, as can be seen in the example below. If you don't have a key of your own yet the one listed below will work as well, but will not properly represent your application:
```html
<html>
<head>
<script type="text/javascript" src='node_modules/klarna-on-demand/lib/klarna-on-demand.js'></script>
<!-- additional header business -->
</head>
<body>
<script>
KlarnaOnDemand.setApiKey('test_d8324b98-97ce-4974-88de-eaab2fdf4f14');
// possibly other script things
</script>
<div>
<!-- some page content would go here -->
</div>
</body>
</html>
```
**Note:** API keys beginning with "test" always belong to the playground environment, so you may perform any action while using them without worry of subjecting users to any actual cost.
<a name="registration_view"></a>
##The registration view
Users must go through a quick one time registration process in order to pay using Klarna. To make this process as simple as possible, the SDK provides a method which opens an iframe over the entire viewport. This iframe hosts the registration view that you should present to your users. Once the registration process is complete, you will receive a token that will allow you to charge the user for purchases.
**Note:** It is important to point out that the registration view will not function properly without network access, and that it does not currently support landscape orientation.
###Showing the view and interacting with it
For the sake of this example, assume we have a button that opens the registration view (we will cover a better approach [later](#when_to_show_registration)).
Assuming the page in question has already imported the SDK and that an API key has been set, the button could work in the following manner:
```html
<!-- ... -->
<script>
function registerClicked() {
event.preventDefault();
KlarnaOnDemand.openRegistrationView(onSuccess, onError);
};
var onSuccess = function(userToken) {
// Save the user token
}
var onError = function(errorCode) {
// Inform an error happened, and ask the user to try again
}
</script>
<!-- ... -->
<button onclick="registerClicked()">Register</button>
<!-- ... -->
}
```
You can see that displaying the registration view is as simple as calling a function, which takes handlers to be called on each of the registration process's possible outcomes:
1. Registration complete - the user successfully completed the registration process, and has been assigned a token that you can use to place orders on the user's behalf. This corresponds to the `onSuccess` handler above, with the user token received by the handler as an argument.
2. Registration failed - an error of some sort has prevented the user from successfully going through the registration process. This corresponds to the `onError` handler above, with an error code supplied to the handler. This error code is mainly for debugging purposes, and should not be presented to the user.
**Note:** The SDK does not supply a specific way to store user tokens. It is up to your application to persist the token.
<a name="when_to_show_registration"></a>
###When should you show the registration view?
While we've seen how to utilize the registration view, we never talked about **when** you should display it. Our recommendation is to display the registration view when you do not have a user token stored and the user is attempting to initiate a purchase. Assuming your user has gone through the registration process successfully and received a token there is no need to have the user register again, as tokens do not expire (though they can be revoked).
##Performing purchases
The aim of this SDK is to allow users to make purchases using your application, backed by Klarna as a payment method. However, the SDK does not offer any direct methods for performing purchases as this will expose your application's private Klarna credentials. Instead, applications using the SDK are expected to work with an application backend, which will perform the actual purchase requests.
In this section, we will see how to communicate with such a backend and for that purpose we supply a sample backend that you can find [here](https://github.com/klarna/sample-ondemand-backend). Reading the sample backend's documentation will allow you to fully grasp how an application using this SDK is expected to perform purchases.
###Purchase example
To perform a purchase, you must first sign it (more about this [later](#signing_requests)).
You will most likely have a "buy" button somewhere in your application. Assuming the page in question has already imported the SDK and that an API key has been set, the code below shows how such a button might be implemented:
```html
<!-- ... -->
<script>
function buyClicked(userToken) {
var originProof = new KlarnaOnDemand.OriginProof(9900, "SEK", userToken);
var data = JSON.stringify({
'origin_proof': originProof.toString(),
'reference': "TCKT0001",
'user_token': userToken
});
var request = new XMLHttpRequest();
request.open("POST", "http://localhost:9292/pay");
request.setRequestHeader("Content-type", "application/json; charset=utf-8");
request.onreadystatechange = function() {
if(request.readyState == 4 && request.status == 204) {
// Purchase was successful!
}
else {
// The purchase failed
}
}
request.send(data);
};
</script>
<!-- ... -->
<button onclick="buyClicked()">Buy</button>
<!-- ... -->
```
All the code above does is send the following JSON to `http://localhost:9292/pay` (where a locally run sample backend would expect purchase requests):
```json
{
"origin_proof":"eyJkYXRhIjoie1wiYW1vdW50XCI6OTkwMCxcImN1cnJlbmN5",
"reference":"TCKT0001",
"user_token":"c4efa3a2-3c02-4544-9259-720285788f60"
}
```
This JSON contains the data required for the sample backend to know which purchase request to issue. The `reference` identifies the item to purchase, the `user_token` identifies the user for whom to perform the purchase and the `origin_proof` proves that the request originated from the user's device. Note how we sent a string representation of `originProof` by calling its `toString` method.
Remember that if you try this out for yourself, your origin proof and user token will obviously be different. Also note the placeholder comments in the last portion of the code sample, where you will most likely want to notify the user of the purchase attempt's outcome.
This is really all there is to performing a purchase, though as previously mentioned you will want to take a look at the [sample backend](https://github.com/klarna/sample-ondemand-backend) to get the full picture.
<a name="signing_requests"></a>
###Signing requests
While you can, and almost certainly will, communicate with your application's backend in a way that is different from the very simplistic approach we present here, one thing you will always have to do is sign your purchase requests. The SDK provides an easy way to sign requests, and this will significantly increase your user's security while buying.
Let us say a user wants to make a purchase for a total of 40.50 Euros. All that's necessary to generate the relevant signature is to construct an object as seen below:
```javascript
var originProof = new new KlarnaOnDemand.OriginProof(4050, "EUR", getUserToken());
```
Assume `getUserToken()` returns the user's token as received during registration. Note that the constructor expects the purchase amount to be supplied in cents. You can find the constructor's full documentation [here](http://klarna.github.io/klarna-on-demand-js/classes/KlarnaOnDemand.OriginProof.html).
##The preferences view
After having registered to pay using Klarna, users may wish to view or alter their payment settings (for example, users may wish to switch from using a credit card to monthly invoice payments). As was the case with registration, the SDK allows opening an iframe which hosts a view for this purpose. Using the user token acquired during the registration process, you will be able to present your users with a preferences view.
**Note:** It is important to point out that the preferences activity will not function properly without network access, and that it does not currently support landscape orientation. Also, a user's token will remain constant regardless of any preference changes.
###Showing the view and interacting with it
It is good practice to allow users to access the preferences view on demand. Let's see how to set up a button that launches the preferences view.
Assuming the page in question has already imported the SDK and that an API key has been set, the button in question could work in the following manner:
```html
<!-- ... -->
<script>
function preferencesClicked() {
event.preventDefault();
KlarnaOnDemand.openPreferencesView(getKlarnaUserToken(), preferenceError);
};
var preferenceError = function(errorCode) {
// Inform an error happened, and ask the user to try again
}
</script>
<!-- ... -->
<button onclick="preferencesClicked()">Preferences</button>
<!-- ... -->
}
```
You can see that displaying the preferences view is simply a matter of invoking a function, which takes a user token for whom to display the view and a handler to be called in case of an error.
This handler, corresponding to `preferenceError` above, will be called with an error code supplied if an error does occur. This error code is mainly for debugging purposes, and should not be presented to the user.
We strongly encourage you to notify the user in case of an error, as most errors are unrecoverable and require the preferences view to be reopened.
**Note:** The SDK provides no method for retrieving the user token, and the `getKlarnaUserToken` method above is for illustrative purposes only.
## Closing views
Seeing how both views made available by the SDK hide the current document, the SDK provides a method that can be used to hide them once they are no longer required. Simply call `KlarnaOnDemand.closeView()` to dismiss the currently displayed view.