Tokenization
To save a customer's card info, you can tokenize the card and store it for future use. To enable tokenization for your account, contact your account manager.
Supported providers
This document uses Payex as a working example. Please reference the api-specification to see all supported payment product types, and the operations that they support.
Token types
Swedbank Pay supports two types of tokens:
- payment token
- recurrence token
Bambora supports only payment token:
- payment token
Payment token
A payment token can be used to create payment where the card details will be
prefilled in the checkout. The payer still has to enter the CVC
to complete
the purchase.
The payment token can also be used to perform unscheduled purchase without involving the payer, also known as an merchant initiated transaction (MIT)
Performing MIT transactions require approval. Contact your account manager.
Recurrence token
A recurrence token can be used to create recurring payment where you can charge a card without payer interaction. When an initial payment token is generated, subsequent payments are made through server-to-server request
Creating a token
There are two ways of creating a card token, either in advance, without withdrawing any money, or during a purchase process.
Creating token in advance
To store a token without performing a payment, do the following:
Authentication
To authenticate, you create a Checkout API client and use the credentials to Create an access token. The same client can be used for Sandbox mode and production.
For all requests to the API set the following header:
Authorization: Bearer {access_token}
Create token session
With the access token, call Payment token session with this body:
- payex.creditcard
- bambora.creditcard
{
"session": {
"order": {
"currency": "NOK",
"merchant_reference": "order-number"
},
"url": {
"return_url": "https://example.com/accept",
"callback_url": "https://example.com/callback?method=GET",
"merchant_terms_url": "https://example.com/terms.html"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999"
}
},
"token_provider": {
"payment_product_type": "payex.creditcard",
"token_types": ["payment_token", "recurrence_token"]
}
}
{
"session": {
"order": {
"currency": "NOK",
"merchant_reference": "order-number"
},
"url": {
"return_url": "https://example.com/accept",
"callback_url": "https://example.com/callback?method=GET",
"merchant_terms_url": "https://example.com/terms.html"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999"
}
},
"token_provider": {
"payment_product_type": "bambora.creditcard",
"token_types": ["payment_token"]
}
}
The response will look like this:
{
"id": "T11223445.5cyWnV68vzJ1kYjZPrKWWm",
"url": "https://checkout.test.dintero.com/v1/view/T11223445.5cyWnV68vzJ1kYjZPrKWWm"
}
Redirect the customer to the url for them to confirm their card.
Creating token while performing a purchase
To store card information for a customer using Swedbank Pay during the payment process, do the following:
When creating the session set:
For payex.creditcard:
configuration.payex.creditcard.generate_payment_token=true
configuration.payex.creditcard.generate_recurrence_token=true
For bambora.creditcard:
configuration.bambora.creditcard.generate_payment_token=true
See create session for more information. It's also possible to disable CVC for returning payments if you have a dedicated agreement with Swedbank Pay.
Fetching and storing token
When the customer has completed filling in their card info, the return_url
and callback_url
will receive a request.
When you get this request, the payment token will be stored on the transaction.
Use get transaction details to retrieve the transaction, with the query-param includes
to include the cards tokens
example:
?includes=card.payment_token
?includes=card.recurrence_token
The token will then be included in the card details, e.g. card.payment_token
.
Store the token internally in a secure manner.
Using the token
To use the token in a new session for the same customer, put the token value in
the session under customer.tokens.payex.creditcard
or customer.tokens.bambora.creditcard
. See create session.
- payex.creditcard
- bambora.creditcard
{
"url": {
"return_url": "https://example.com/thankyou",
"callback_url": "https://example.com/callback"
},
"order": {
"amount": 29990,
"currency": "NOK",
"merchant_reference": "merchants_order_number"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999",
"tokens": {
"payex.creditcard": {
"payment_token": "<token previously acquired>"
}
}
},
"profile_id": "default"
}
{
"url": {
"return_url": "https://example.com/thankyou",
"callback_url": "https://example.com/callback"
},
"order": {
"amount": 29990,
"currency": "NOK",
"merchant_reference": "merchants_order_number"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999",
"tokens": {
"bambora.creditcard": {
"payment_token": "<token previously acquired>"
}
}
},
"profile_id": "default"
}
The response will look like this:
{
"id": "T11223445.5cyWnV68vzJ1kYjZPrKWWm",
"url": "https://checkout.test.dintero.com/v1/view/T11223445.5cyWnV68vzJ1kYjZPrKWWm"
}
Redirect the customer to the url for them to confirm the payment with CVC
.
Recurrence transactions
To perform transactions without involving the customer, using a recurrence token,
use recurring_purchase
operation when calling the pay endpoint.
With the access token, call Create and pay merchant initiated session with the following body:
{
"session": {
"url": {
"callback_url": "https://example.com/callback?method=GET"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999",
"tokens": {
"payex.creditcard": {
"recurrence_token": "<token previously acquired>"
}
}
},
"order": {
"amount": 29990,
"currency": "NOK",
"vat_amount": 6000,
"items": [
{
"line_id": "1",
"description": "Stablestol",
"quantity": 1,
"amount": 29990,
"vat_amount": 6000,
"vat": 25
}
],
"merchant_reference": "order-1"
},
"configuration": {
"auto_capture": false
}
},
"payment": {
"payment_product_type": "payex.creditcard",
"operation": "recurring_purchase"
}
}
Unscheduled transactions
To perform transactions without involving the customer, MIT (merchant initiated)
transactions use unscheduled_purchase
operation when calling the pay endpoint.
With the access token, call Create and pay merchant initiated session with the following body:
{
"session": {
"url": {
"callback_url": "https://example.com/callback?method=GET"
},
"customer": {
"email": "john.doe@example.com",
"phone_number": "+4799999999",
"tokens": {
"payex.creditcard": {
"payment_token": "<token previously acquired>"
}
}
},
"order": {
"amount": 29990,
"currency": "NOK",
"vat_amount": 6000,
"items": [
{
"line_id": "1",
"description": "Stablestol",
"quantity": 1,
"amount": 29990,
"vat_amount": 6000,
"vat": 25
}
],
"merchant_reference": "order-1"
},
"configuration": {
"auto_capture": false
}
},
"payment": {
"payment_product_type": "payex.creditcard",
"operation": "unscheduled_purchase"
}
}
Do Not Try Again & Excessive Reattempts
In accordance with directives from Visa and Mastercard there are
2 different types of limitations in the amount of successive reattempts
of previously failed transaction using unscheduled_purchase
or recurring_purchase
One such limitation will be limiting the amount of successive reattempts of a previously failed transaction that can be done using creditcard based payment method within a specified period The limitation in question varies based on the card brand:
- MasterCard - 10 failed payment attempts allowed during a period of 24 hours.
- Visa - 15 failed payment attempts allowed during a period of 30 days.
Note that all of the attempts has to get a failed response to be added to the limit quota - if a transaction goes through successfully, the quota will reset.
The other limitation is in the case that Visa or Mastercard gives such a response that is flagged as “Do Not Retry” in accordance to Visa and MasterCard regulations. This response is given in the cases that they deem the transaction to never be possible to be valid - as an example, if the card no longer exists, and thus there is no point in retrying.
In these cases, the card will be blocked immediately and no further attempts are allowed.
Both of these limitations are based on the combination of the acquiring agreement that the transaction was initiated from, and the PAN of the card that was used. That is, a card might be blocked because of "Excessive Reattempts" at a particular merchant, while being allowed more reattempts at another. Please note that in the case a new card is issued in place of an old expired one, the new card usually keeps the same PAN - meaning that if the old card was blocked, the new one will be as well (until the period resets). This marks the importance of having such a logic in place that limits reattempts before the block actually takes place - this is where the new, clearer response messages will help.
Merchant is resposible for managing their retry policy for payments that
fails, and not retry when payment fails with DO_NOT_RETRY
error.
Insufficient error handling will cause cards to be blocked
payex.creditcard
authorization error example
A 200 response will be returned if the pay request fail because of authorization error. The transaction will have status FAILED and more information about the cause can be found in the AUTHORIZE event
{
"id": "...",
"status": "FAILED",
"events": [
{
"event": "INITIALIZE",
"success": true
},
{
"event": "AUTHORIZE",
"success": false,
"error": {
"type": "REJECTED_BY_ACQUIRER_POSSIBLE_FRAUD",
"code": "payex:errorCode:REJECTED_BY_ACQUIRER_POSSIBLE_FRAUD",
"message": "payex:errorDescription:Wrong card-no check digit response-code: 34",
"result_code": "34"
}
}
]
}
Prevent duplicate transactions
Use the Dintero-Feature-Toggles
header to prevent creating duplicate
transactions.
Including strict-merchant-reference
value in the header will prevent creating
duplicate transaction as it will require the merchant_reference
to be unique
within 24 hours
headers
Dintero-Feature-Toggles: strict-merchant-reference
Content-Type: application/json
body
{
"session": {
"url": {
"callback_url": "https://example.com/callback?method=GET"
},
"customer": {
"tokens": {
"payex.creditcard": {
"payment_token": "<token previously acquired>"
}
}
},
"order": {
"amount": 29990,
"currency": "NOK",
"vat_amount": 6000,
"merchant_reference": "order-1"
},
"configuration": {}
},
"payment": {
"payment_product_type": "payex.creditcard",
"operation": "unscheduled_purchase"
}
}
A 400 response will be returned if merchant_reference
was duplicated
{
"session_id": "T11223445.5cyWnV68vzJ1kYjZPrKWWm",
"error": {
"message": "session.order.merchant_reference",
"code": "DUPLICATE"
}
}