Card API (v1)

Download OpenAPI specification:Download

This document contains a technical description for adding cards and deleting cards to and from Storebox PCI DSS Certified environment.

This only includes card operations that are out of PCI-scope. For operations like programatically adding cardholder data use the Vault API.

The intended audience for this documentation is technicians developing system integration to Storebox.

The API is organized around REST. The API is designed to have predictable, resource-oriented URLs and to use HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP authentication and HTTP verbs. JSON is the data interchange format and will be returned in responses from the API, including errors.

Cards

When users have registered their card number, Storebox will collect and maintian token values from multiple sources in order to identify users realtime based on their paymentcard. This usually requires collaboration with the terminal which provides the token sent to Storebox.

Note that Storebox stores cards in a PCI-DSS compliant environment and never exposes a users raw card number. All endpoints containing card information returns only a masked version of the card number.

Concepts:

open
Truncated/Masked card number A masked card number consists of the first 6 and last 4 digits of the card number. The middle digits have been replaced by a character, we use X, for example: 4571000000000000 -> 457100XXXXXX0000
Card types When cards are entered in Storebox, we try to identify the type of the card based on the IIN.

The identified type resolves to a cardTypeId:
1 - Dankort/VISA Dankort
2 - eDankort
3 - VISA/VISA Electron
4 - Mastercard
5 - Reserved
6 - JCB
7 - Maestro
8 - Diners Club
9 - American Express
10 - Reserved
11 - Forbrugsforeningen
16 - BankAxept
Card frame To support users in registering their payment card information, Storebox delivers a PCI-DSS certified webpage.
The page can be embedded in an iframe or webview on any page and is highly customizable.

Show card frame

When submitting a card to Storebox PCI compliant environment, Storebox will make as many validation checks as possible before accepting the request.

Checks include:

  • Valid cardnumber
  • Valid card type (setup dependent)
  • Card expiry

It is important to note that requests will also return http code 200 on validation errors.

For cardframe submits the cardframe will handle card validation responses from the backend and only send the enduser to the accepturl if a valid card has been entered.

When the backend accepts a submit request, the processing of the card will continue asynchronously. When processing has completed and only then, the PCI environment will send a notification to the provided callbackurl.

The accept URL is the URL where the enduser is redirected after they click the add payment card button. The URL is mainly an indicator to the caller that the operation is done, and the input window can be closed. The following is an example of completion detection in the iframe integration.

<iframe src="..." onload="done()"></iframe>

<script>
function done() {
  // ... remove iframe etc
}
</script>

The callback URL is where the registered data is sent. This will usually be the server that hosts the integrating website/API.

Strong Customer Authentication

To have Strong Customer Authentication (SCA) like 3D Secure activated contact Storebox.

If SCA is enabled, a declineurl must also be provided, when loading the cardframe. The SCA flow will start automatically after the card submit and will redirect the user through the relevant verification flow.

Only if the SCA flow is successful will the card be added to Storebox and the user will be redirected to the accept URL. If the flow for some reason is unsuccessfull the user will be redirected to the decline URL.

Basic example

Server-side you generate the cardframe URL with all parameters (salt must never fall in the hands of client) and provide it to the client.

A quick demo can be had via https://developer.storebox.com/frame/index.html

Example data:

Hash generation: UTF8 hmac-sha256 with salt as key of the string "userid + provider + accepturl + declineurl + callbackurl + cssurl + languageurl". hmac-sha256({salt}, userId + provider + accepturl + declineurl + callbackurl + cssurl + languageurl)

String being HMAC'd: yourcustomeridyourprovideridhttps://developer.storebox.com/frame/accepted.htmlhttps://developer.storebox.com/frame/declined.htmlhttps://storebox.comhttps://developer.storebox.com/frame/assets/card.css?v=5https://developer.storebox.com/frame/assets/lang.json?v=6

Final URL with proper URL encoded parameters, provider and hash that is provided to client: [https://cardapi.test.storebox.com/api/v1/cards/cardframe?provider=yourproviderid&userId=yourcustomerid&accepturl=https%3A%2F%2Fdeveloper.storebox.com%2Fframe%2Faccepted.html&declineurl=https%3A%2F%2Fdeveloper.storebox.com%2Fframe%2Fdeclined.html&callbackurl=https%3A%2F%2Fstorebox.com&cssurl=https%3A%2F%2Fdeveloper.storebox.com%2Fframe%2Fassets%2Fcard.css%3Fv%3D5&languageurl=https%3A%2F%2Fdeveloper.storebox.com%2Fframe%2Fassets%2Flang.json%3Fv%3D6&hash=57f3a998962a7fc188edfa84f58bab67ba141de2416a55b92895f538467c18f5&type=card"]

Result in browser

Result

Styling

The card frame is styled via the CSS specified in the cssurlparameter in the initial call.

The stylesheet is cached and is only downloaded if the URL changes. For this reason a version parameter can be used in the cssurl, for example https://.../style.css?v=1. Please refrain from using a constantly changing parameter, like a timestamp.

This is the Card Frame HTML structure that can be styled:

<form action="" method="post">
  <div class="field field-input">
    <div class="field-label">Kortnummer</div>
    <input id="CardNumber" name="CardNumber">
  </div>
  <div class="field field-input">
    <div class="field-label">Udløbsmåned</div>
    <input id="ExpMonth" name="ExpMonth">
  </div>
  <div class="field field-input">
     <div class="field-label">Udløbsår</div>
    <input id="ExpYear"name="ExpYear">
  </div>
  <div class="field field-btn">
    <input type="submit" class="button" value="Gem nyt kort ">
  </div>
</form>

<div class="generalError">
</div>

<div class="maxCards">
</div>

Localization

A JSON file specified by languageurl configures the text displayed in the card input. The file contains of translation label and value like in the following example. The file must be provided in UTF-8.

{
  "expMonth": {
    "errorInvalid":"Skal være mellem 1 og 12",
    "label":"Udløbsmåned",
    "placeholder": "Indtast udløbsmåned"
  },
  "expYear": {
    "label":"Udløbsår",
    "placeholder":"Indtast udløbsår",
    "errorExpired":"Kortet er udløbet"
  },
  "error": {
    "generalError":"Der skete en fejl. Prøv venligst igen",
    "maxCards":"Du kan ikke tilføje flere kort"
  },
  "btn": {
    "save":"Gem kort"
  },
  "accountno": {
    "errorInvalid":"Ugyldigt kontonummer",
    "errorMinLength":"Skal minimum være 11 tegn",
    "label":"Kontonummer",
    "placeholder":"Indtast kontonummer",
    "duplicate":"Kontonumret er allerede registreret"
  },
  "card": {
    "errorInvalid":"Ugyldigt kortnummer",
    "unsupportedType":"Denne korttype kan ikke bruges",
    "unsupportedBinRange":"Dette kortnummer kan ikke bruges",
    "label":"Kortnummer",
    "placeholder":"Indtast kortnummer",
    "duplicate":"Kortet er allerede registreret"
  }
}

The text values are cached and are only downloaded if the URL changes. For this reason a version parameter should be used in the languageurl, for example http://.../en.json?v=1. Please refrain from using a constantly changing parameter, like a timestamp.

Add card callback

When a card has been fully processed a callback (GET) will happen if the callbackUrl parameter was defined on initial cardframe request. This includes important parameters such as externalCardId. Documentation is found under 'Callbacks' below.

At the time of writing, the callback is the only way to obtain those values. If the values are lost or ignored, they cannot be re-sent by Storebox. Especially externalCardId should be stored as this makes it possible to remove the card from the PCI environment at a later point.

Under some circumstances a notification may be sent more than once.

The callback does not act upon the responses sent from the callbackurl endpoint. I.e. a redirect will not be followed.

Account number frame recommendation

When handling cards that support payment via account number, it is necessary to register both account number as well as the card number. Just like how all the card numbers must be registered for any combined card that contains multiple payment methods, e.g. MasterCard with both debit and credit.

  1. Show card frame type "card"
  2. Show an interrim landing page that asks end-user whether account number payment method exists on card
  3. If account number payment method exists, show card frame type "account"

Alternatively you may consider letting the user choose what they will be adding: a card number or an account number.

query Parameters
userId
required
string

External id of the user who owns the card

provider
required
string

The identity of the caller. This is issued by Storebox

accepturl
required
string

The URL where the page is redirected after successful card submit. This happens in the frontend so app handlers can be used.

declineurl
string

Required if Strong Customer Authentication (like 3DS) is enabled. The URL where the page is redirected after unsuccessful Strong Customer Authentication. This happens in the frontend so app handlers can be used.

cssurl
string

Absolute URL for the CSS file for input styling

languageurl
string

Public URL for the translation JSON file

callbackurl
string

The URL to callback when the card has finished processing.

type
string
Enum: "card" "accountno"

What type of frame should be displayed. Default is the card frame

Possible values

  • card - only card input
  • accountno - only account number input
hash
required
string

HMAC-SHA256 hash of the parameters. hmac-sha256({salt}, userId + provider + accepturl + declineurl + callbackurl + cssurl + languageurl). The salt is provided by Storebox along with the provider value

Responses

Callbacks

Add card

NOTE It is only allowed to add non-EMV cards, for example BankAxept or customer card using this interface. For EMV card, please contact Storebox support.

The API accepts an encrypted package containing the full cardnumber and expiry month/year.

The encrypted payload is a JSON string in the form:

{
  "expiry": {
    "year": 20,
    "month": 1
  },
  "cardNumber": "...",
  "par": "..."
}

cardNumber or par may be omitted. If PAR is omitted, Storebox will try to look it up. If cardNumber is omitted, the receipts will only work with PAR-based payment methods.

The string is encrypted and Base64 encoded. The supported encryption algorithm is RSA with OAEP padding.

Test example of generating the card payload from the command line.

cat <carddata.txt> | openssl pkeyutl  -encrypt -pubin -inkey <transport.pem> -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 | base64

The resulting card payload should be added in the encryptedCard request property.

If BankAxept cards are added, they have to be in their card number for i.e. 957852<account-number><luhn-digit>.

Request Body schema: application/json
provider
required
string

The provider name

userId
required
string

The user id

encryptionProvider
required
string

The encryption provider

encryptedCard
required
string

The card encrypted with the RSA transport key using OAEP padding

callbackUrl
string

The URL to receive the callback when the card is created

Responses

Request samples

Content type
application/json
{
  • "provider": "storebox",
  • "userId": "1234",
  • "encryptionProvider": "storebox",
  • "encryptedCard": "string",
  • "callbackUrl": "string"
}

Get all cards

Return all cards registered to the caller. The result is pageable and sortable.

Authorizations:
basicAuth
query Parameters
page
integer <int32>

Pagenumber to return. The page index is zero-based. Defaults to 0 (zero)

size
integer <int32>

Elements returned per page. Defaults to 100.

sort
string^(cardNumber|cardTypeId|userId|created),(asc|...

Sort of the returned content. Defaults to 'sort=created,desc'.

Sort can have any of the values: cardNumber, cardTypeId, userId or created.

In addition to defining the field to sort in, the sort direction is also defined in this field by either asc or desc

Example: '...&sort=cardNumber,asc&...'

Responses

Response samples

Content type
application/json
{
  • "content": [
    ],
  • "totalElements": 1000,
  • "totalPages": 10,
  • "first": true,
  • "last": false,
  • "numberOfElements": 100,
  • "page": 0
}

Get user cards

Get all cards registered to a specific userId

Authorizations:
basicAuth
path Parameters
userId
required
string
Example: e75ca15c8ae1401c943ff15df437f1d8

Member id that should be looked up

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Start card verification

If existing cards are stored in Storebox, which have not yet been verified by 3DS, this endpoint can be used to start the 3DS flow.

The card owner must complete the authentication, so this endpoint will redirect and start the 3DS flow. The endpoint must therefore be used from a browser or webview like the card frame.

After a successful completion the card will be marked as verified.

query Parameters
provider
required
string

The identity of the caller. This is issued by Storebox.

externalCardId
required
string

Id of the card to verify. The card id was delivered in the callback on card creation.

accepturl
required
string

The URL where the page is redirected after successful card verification. This happens in the frontend so app handlers can be used.

declineurl
required
string

The URL where the page is redirected if the verification was unsuccessful. This happens in the frontend so app handlers can be used.

hash
required
string

HMAC-SHA256 hash of the parameters. hmac-sha256({salt}, provider + externalCardId + accepturl + declineurl). The salt is provided by Storebox along with the provider value

Responses

Delete a card

Deletes a card from the PCI DSS environment. This cannot be undone.

Authorizations:
basicAuth
path Parameters
externalCardId
required
string

Card id that was delivered in the callback on card creation

Responses

BankAxept

Operations related to BankAxept. This is only relevant in Norway.

Show account number frame

Insert account number only. Note that even though this inserts an account number it is still conceptually a card, i.e. it is deleted as a card using the externalCardId. The callback is the same as the card frame.

query Parameters
userId
required
string

External id of the user who owns the card

provider
required
string

The identity of the caller. This is issued by Storebox

accepturl
required
string

The URL where the page is redirected after successful card submit. This happens in the frontend so app handlers can be used.

cssurl
string

Absolute URL for the CSS file for input styling

languageurl
string

Public URL for the translation JSON file

callbackurl
string

The URL to callback when the card has finished processing

hash
required
string

HMAC-SHA256 hash of the parameters. hmac- sha256({salt}, userId + provider + accepturl + callbackurl + cssurl + languageurl). The salt is provided by Storebox along with the provider value

Responses

Add account no

Insert account number only by API. This endpoint verifies the format of the account defined by the accountNoType.

Request Body schema: application/json
accountNo
required
string

The accountNo that should be added.

accountNoType
required
string

The type of the submitted account no. This value is provided by Storebox.

userId
required
string

An unique identifier of the owner of the account no.

provider
required
string

The owner program of the account no. This value is provided by Storebox.

callbackUrl
string

Optional - Event url to call when the asynchronous add account no. operation has completed.

Responses

Request samples

Content type
application/json
{
  • "accountNo": "12345678901",
  • "accountNoType": "bankaxept",
  • "userId": "3sk2zjf65u97jrw4yl17",
  • "provider": "storebox",
  • "callbackUrl": "https://storebox.com"
}

Response samples

Content type
application/json
{
  • "status": 0,
  • "externalCardId": "hdwu2gbqesc49admkxnv"
}