NAV Navbar
Logo

Introduction

Briefly

Welcome to Pivo Payment API Reference!

Pivo Payment service is a Payment Gateway enabling merchants to create payment orders and receive a confirmation from consumer’s payment transaction.

In technical sense we provide two different API: Pivo Rest API with OAuth or signature authentication and Form Post API with a signature authentication.

We support mobile and web payments: mobile initiated payment order is available in Rest API and web initiated payment order is supported by both APIs.

This documentation helps You to integrate Your service to Pivo Payment.

Pivo Payment API should only be used in server to server scenarios.

Terminology

Listed terms we are using in our Payment API.

Term Explanation
You The customer who is using the API.
We Pivo Payment API.
Merchant Merchant or Brand from where User is paying
Payment Order Detailed payment order information from You.
Transaction The event of money being transferred from payer to payee.
Payer   The person who is using Your service, the person whose money will be transferred to the payee.
Payee The entity who receives payer’s money.
User The person who is using Your service and Pivo.

Examples

Please note that the presented example data is not valid (e.g iban numbers, iban owners and card tokens)

Character encoding

We use UTF-8 in all requests and responses.

Automatic Callback

Pivo calls Your web site when a successful payment transaction is done. A dedicated server to server call is done to return_url along with payment transaction details.

The call will follow redirects.

For more information regarding the request parameters see section Form Post API > Success URL

⚠ In case the Automatic callback is not as quick as You wish, You can query REST API - Payments > Get Payment Order Information which gives You fast access to Payment Order status (Additionally this also omits the need to implement callback signature calculation).

Mobile or Web Payment Order

You can provide both web urls (return_url) and app url (return_app_url) to payment orders (REST API > Create a Payment Order or Form Post API), and choose later whether to use mobile or web initialization.

Either web urls or app url is required to be present.

⚠ Please note that if return_url is present then cancel_url and reject_url are also required.

REST API

Mobile Application Initiated Payment Order

Pivo allows Third Party applications and services to launch Pivo Mobile Application with a Pivo scheme.

The following diagrams gives detailed information how Pivo handles the mobile payment process.

Restriction

Siirto payment method does not support Mobile App Switch.

Pivo creates and forwards payment orders to Siirto pipeline to notify incoming payment request for a User. return_app_url is omitted during the process.

Communication

To enable Mobile App Switch You need to create the Payment Orders with return_app_url.

Scheme url sequence

Sequence

To create a Payment Order You need access to Pivo Payment API.

Scheme url sequence

Pivo Loyalty program

When You want to provide seamless user experience with Pivo or You want to provide mobile payments without Your own mobile application for You users, You can integrate Your web service to Pivo as a Merchant Loyalty Program.

Your loyalty programs appears to Pivo and it is available for users using Pivo Mobile Application. Contact us to create a loyalty program.

Loyalty program landing page (callback landing url)

Your loyalty program provides a custom web ui for Pivo. When Pivo user chooses to see Your loyalty program, Pivo mobile application will render your web ui.

Pivo Mobile will sent pivo_user_token to Your site.

Loyalty program user identity federation and subscription

Resolve Pivo user identity:

Steps to follow:

  1. Let user to choose ‘identify’ or ‘subscribe’
  2. Generate unique stamp (e.g. a78dbd25-844b-49b4-b883-a544df95f8bf)
  3. Generate callback landing url to Your site with the unique stamp for Pivo mobile application (e.g. ‘https://yourwebsite.com/orders/a78dbd25-844b-49b4-b883-a544df95f8bf’)
  4. Generate return app url with urls api (by default set platform: pivo and url: generated callback landing url)
  5. Create Payment Order with stamp and set generated return app url as return_app_url define payment order as identification (type: identification, REST API - User identication)
  6. Let Pivo mobile application to receive http redirect (302 Found) with location set as payment_order.pivo_app_url (e.g. pivo://api/v1/payment_button?payment_id=50d295f3400db23b8f9b7b906ac2997ed30112bc3393e1a284cf84940e90798f)
  7. Pivo mobile application opens and user sees Authorize Your loyalty program view.
  8. After a successful authorization Your web site receives Automatic callback confirmation (see section Introduction > Automatic Callback)
  9. User’s Pivo mobile application returns to the return_app_url

After successful authorization and callback confirmation you can request user identity from the REST API - Users

After You have received user identity, Your web ui can assign a pivo_user_token cookie for Pivo application, which is used to identify user in subsequent calls.

⚠ In case Pivo mobile application is not following the schema redirects, please disable turbolinks or other navigation optimization solutions which modify the page structure.

Mobile Payments Without Your Own Application

To let Pivo Mobile Application to handle Your loyalty program payments, You need to create the Payment Order with a special ‘return_app_url’ and return http redirect for Pivo client.

Steps to follow:

  1. Let user to choose the product
  2. Generate unique stamp (e.g. a78dbd25-844b-49b4-b883-a544df95f8bf)
  3. Generate callback landing url to Your site with the unique stamp for Pivo mobile application (e.g. ‘https://yourwebsite.com/orders/a78dbd25-844b-49b4-b883-a544df95f8bf’)
  4. Generate return app url with urls api (by default set platform: pivo and url: generated callback landing url)
  5. Create Payment Order with your ‘stamp’ and set generated return app url as ‘return_app_url’
  6. Let Pivo mobile application to receive http redirect (302 Found) with location set as payment_order.pivo_app_url (e.g. ‘pivo://api/v1/payment_button?payment_id=50d295f3400db23b8f9b7b906ac2997ed30112bc3393e1a284cf84940e90798f’)
  7. Pivo mobile application opens and user sees Accept payment view.
  8. After a successful payment a payment receipt view is shown in Pivo mobile application and Your web site receives Automatic callback confirmation (see section Introduction > Automatic Callback)
  9. User clicks the close button and Pivo mobile application returns to the ‘return_app_url’

⚠ In case Pivo mobile application is not following the schema redirects, please disable turbolinks or other navigation optimization solutions which modify the page structure.

Closing view

When loyalty program needs to provide a close view for User a specific url scheme can be used. The Pivo Application closes the current loyalty program view and guides user back to Pivo Application main view.

Either http redirect

or a link click event can be used to fire the wanted behaviour.

Web Browser Initiated Payment Order

Pivo provides a dedicated landing page with user instructions to pay Your payment order.

After a successful payment order creation redirect User’s web browser to location_url. In case of a mobile browser, the Pivo mobile application is tried to open automatically. For desktop browser’s we enquire user to fill a phone number, which will notify Pivo mobile application with a push notification.

After a successful payment transaction, the browser returns to Your web site with payment transaction details (additionally see Automatic Callback for server callback).

REST API - Authorization

Pivo Payment API relies on OAuth2 Client Credentials Grant Authorization.

Subsequent resource API calls require an access token, which can be established with provisioned client credentials.

To use resources You need to request specific access request scope when creating access token (e.g. payments)

Don’t leak Your OAuth client secret to users nor mobile applications.

Getting an Access Token

POST https://qa-maksu-api.pivo.fi/oauth/token

Getting an Access Token with Your credentials.

A successful response contains the access token.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/oauth/token" -d '{"client_id":"payment_api_user","client_secret":"30713f017cf49f1cde8c058446273d02ef040548178a89c050c7aff357729178","scope":"payments acquirings","grant_type":"client_credentials"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json

Request body:

{
  "client_id": "payment_api_user",
  "client_secret": "30713f017cf49f1cde8c058446273d02ef040548178a89c050c7aff357729178",
  "scope": "payments acquirings",
  "grant_type": "client_credentials"
}

Response with status 200:

{
  "access_token": "da7142545da034dfa0b8a5111e43314c61564fbbc8f83cbd6b3932bd453dc82e",
  "token_type": "bearer",
  "expires_in": 7200,
  "scope": "payments acquirings",
  "created_at": 1533793540
}

Query Parameters

Name Required Type Description
client_id true String The client id
client_secret true String The client secret
scope true String The scope of the access request. E.g. ‘payments’
grant_type true String Type of the scope. Use ‘client_credentials’

Response Fields

Name Type Description
access_token String The access token
token_type String Type of the token
expires_in Integer Expire time of access token in seconds
scope String OAuth scope of the session
created_at Integer Unix timestamp of creation time

REST API - Acquirings

Used to create Merchant acquiring data.

Acquiring defines merchant’s financial contact information as a Payment method (aka. payment type) for Pivo user.

Currently we support bank_account, payment card and siirto payment methods.

To support bank account, You need a bank account number from bank contract. To support card payments, You need credit card merchant agreement details from payment card contract. To support siirto, You need a siirto id from Pivo.

Based on Your business needs you can create a single acquiring defining all payment methods or separate acquirings for each payment method.

When creating acquiring, You can provide

If iban is provided then iban_owner_name field is mandatory.

When creating new card information (merchant token) all card_provider* fields are required.

Pivo uses Payment Highway (PH) Client Credentials Share for card payments. This feature enables sharing Pivo tokenized payment cards with third party Payment Highway merchants.

When siirto_id is provided then siirto_business_id is mandatory.

Access scope: acquirings

To use this resource You need to request specific access scope when getting access token.

Create Acquiring with bank account information

POST https://qa-maksu-api.pivo.fi/api/acquirings

A successful response contains information about the created acquiring data.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/acquirings" -d '{"iban":"FI2112345600000785","iban_owner_name":"Pivo Wallet Oy"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 0aebc7a98163b624214c1b08f7b5fcbee7071fbd14223781dac0e521abd195d7

Request body:

{
  "iban": "FI2112345600000785",
  "iban_owner_name": "Pivo Wallet Oy"
}

Response with status 200:

{
  "acquiring_id": "3eb3e55ba46867e51ec71084c0471838214cbb2cec68c20ac01b3fb46c879849",
  "payment_methods": {
    "account": {
      "iban": "FI2112345600000785",
      "iban_owner_name": "Pivo Wallet Oy"
    }
  }
}

Query Parameters

Name Required Type Description
iban true String IBAN number
iban_owner_name true String IBAN owner name

Response Fields

Name Type Description
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing methods of payment
account JSON Object Object containing information about bank account
iban String Payee IBAN number
iban_owner_name String Payee name

Create Acquiring with new payment card data

POST https://qa-maksu-api.pivo.fi/api/acquirings

A successful response contains information about the created acquiring data.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/acquirings" -d '{"card_provider_account":"your_account","card_provider_merchant":"Your Merchant Name","card_provider_key":"your_account_1","card_provider_secret":"your_very_secret_key"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 1e0a5a48eb918023f48dccb3d4a6282bd0da5ee57ba035b5d92bcd054a008564

Request body:

{
  "card_provider_account": "your_account",
  "card_provider_merchant": "Your Merchant Name",
  "card_provider_key": "your_account_1",
  "card_provider_secret": "your_very_secret_key"
}

Response with status 200:

{
  "acquiring_id": "a18a0ad0e17d8177c6dfb0390598a48507132ba72a0cef35a616e8a09a86f25c",
  "payment_methods": {
    "card": {
      "merchant_token": "72ee1044424661e47919d6c51f4b4ee5b346c18a9561904087967b1752c4bde4"
    }
  }
}

Query Parameters

Name Required Type Description
card_provider_account true String Your PH provider account
card_provider_merchant true String Your PH provider merchant name
card_provider_key true String Your PH technical account specific key
card_provider_secret true String Your PH technical account specific secret

Response Fields

Name Type Description
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing methods od payment
card JSON Object Card information
merchant_token String Merchant credit card token

Create Acquiring Data with previously created card merchant token

POST https://qa-maksu-api.pivo.fi/api/acquirings

A successful response contains information about the created acquiring data.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/acquirings" -d '{"card_merchant_token":"b8a11e6de4e73a704456255423b192dd847adc0277ddee26a454921cdbbe0bd1"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 20396f1b9e2def0278a4981fb9587b7ff6f0f3d4f042f12a24ddbe88e64618b0

Request body:

{
  "card_merchant_token": "b8a11e6de4e73a704456255423b192dd847adc0277ddee26a454921cdbbe0bd1"
}

Response with status 200:

{
  "acquiring_id": "644085cc4e628f2904937aea0cb10ddf794989763bdd8c1907b7c23a7e1b7c75",
  "payment_methods": {
    "card": {
      "merchant_token": "b8a11e6de4e73a704456255423b192dd847adc0277ddee26a454921cdbbe0bd1"
    }
  }
}

Query Parameters

Name Required Type Description
card_merchant_token true String Your previously created card merchant token

Response Fields

Name Type Description
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing methods od payment
card JSON Object Card information
merchant_token String Merchant credit card token

Create Acquiring with bank account information, payment card data and siirto_id

POST https://qa-maksu-api.pivo.fi/api/acquirings

A successful response contains information about the created acquiring data.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/acquirings" -d '{"iban":"FI2112345600000785","iban_owner_name":"Pivo Wallet Oy","card_provider_account":"your_account","card_provider_merchant":"Your Merchant Name","card_provider_key":"your_account_1","card_provider_secret":"your_very_secret_key","siirto_id":"your Siirto id","siirto_business_id":"FI22410078"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 3e7eb4e027d69ce5499296bdbb3088c1706716715fdbd361e2ab1195356284c6

Request body:

{
  "iban": "FI2112345600000785",
  "iban_owner_name": "Pivo Wallet Oy",
  "card_provider_account": "your_account",
  "card_provider_merchant": "Your Merchant Name",
  "card_provider_key": "your_account_1",
  "card_provider_secret": "your_very_secret_key",
  "siirto_id": "your Siirto id",
  "siirto_business_id": "FI22410078"
}

Response with status 200:

{
  "acquiring_id": "3220cc19f88392e01ddb2303dda4cba3086d1d1b0af654e509401123d60d4c48",
  "payment_methods": {
    "account": {
      "iban": "FI2112345600000785",
      "iban_owner_name": "Pivo Wallet Oy"
    },
    "card": {
      "merchant_token": "87bf46f528b19cfbcae0c97839f49d5c6040becabaacd6c5d91bc8de120d04a8"
    },
    "siirto": {
      "siirto_id": "your Siirto id",
      "siirto_business_id": "FI22410078"
    }
  }
}

Query Parameters

Name Required Type Description
iban true String IBAN number
iban_owner_name true String IBAN owner name
card_provider_account true String Your PH provider account
card_provider_merchant true String Your PH provider merchant name
card_provider_key true String Your PH technical account specific key
card_provider_secret true String Your PH technical account specific secret
siirto_id true String Your Siirto id
siirto_business_id true String Your business id in international format (e.g. FI22410078)

Response Fields

Name Type Description
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing methods od payment
account JSON Object Object containing information about bank account
iban String Payee IBAN number
iban_owner_name String Payee name
card JSON Object Card information
merchant_token String Merchant credit card token
siirto JSON Object Siirto information
siirto_id String Your Siirto id
siirto_business_id String Your business id in international format (e.g. FI22410078)

Get acquiring info

GET https://qa-maksu-api.pivo.fi/api/acquirings/:acquiring_id

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/acquirings/5d7114a7d240b3fd6b19fa0c001cc068ff29a6799d0ef9b3d62698f8ecd01b20" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 43199753acc6caada0d11e9fa1d519f08d81124ce54ad6041566644ca0fb72e5

Response with status 200:

{
  "acquiring_id": "5d7114a7d240b3fd6b19fa0c001cc068ff29a6799d0ef9b3d62698f8ecd01b20",
  "payment_methods": {
    "account": {
      "iban": "FI2112345600000785",
      "iban_owner_name": "Test Iban owner"
    },
    "card": {
      "merchant_token": "Test Merchant token"
    }
  }
}

Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing payment methods
account JSON Object Object containing information about bank account
iban String Payee IBAN number
iban_owner_name String Payee name
card JSON Object Card information
merchant_token String Merchant credit card token
siirto JSON Object Siirto information
siirto_id String Your Siirto id
siirto_business_id String Your business id in international format (e.g. FI22410078)

List Acquirings

GET https://qa-maksu-api.pivo.fi/api/acquirings

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/acquirings" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer dd80ed15d4a457ff756b204916acd3806ed671831e2d46e76d1a26f7e8dd3049

Response with status 200:

{
  "acquirings": [
    {
      "acquiring_id": "9d15bdbe1cc967824b17a599f8aa3859531c145411a9ac05f09d5f73582dd7f9",
      "payment_methods": {
        "account": {
          "iban": "FI2112345600000785",
          "iban_owner_name": "Test Iban owner"
        },
        "card": {
          "merchant_token": "Test Merchant token"
        }
      }
    }
  ]
}

Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description
acquirings JSON list Created acruiring object
acquiring_id String Unique Acquiring identifier
payment_methods JSON object Object containing methods od payment
account JSON Object Object containing information about bank account
iban String Payee IBAN number
iban_owner_name String Payee name
card JSON Object Card information
merchant_token String Merchant credit card token
siirto JSON Object Siirto information
siirto_id String Your Siirto id
siirto_business_id String Your business id in international format (e.g. FI22410078)

REST API - Payments

Create, view and cancel payment orders.

An Acquiring is required before payment order can be created.

Please see section Mobile or Web Payment Order whether to provide return_url and/or return_app_url parameters.

Access scope: payments

To use this resource You need to request a specific access scope when getting access token.

Typical Error Codes

Error codes 4xx are client errors. On an error, please check Your parameters and access token.

Error Code Message Meaning
400 Bad Request Parameters are invalid or malformed
401 Unauthorized No access token provided or the access token is invalid. Signature is not correct.
403 Forbidden The access token does not have proper scope
404 Not Found The payment does not exist

Parameter maximum length

When maximum size of the parameters (merchant_name, message) are met, parameters will be truncated (shortened to maximum size).

Create a Payment Order

POST https://qa-maksu-api.pivo.fi/api/payments

A successful response contains information about the created payment order.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments" -d '{"stamp":"b33dba71-9b73-4605-9e4d-f42e87d42aee","reference":"14932116599460307792","acquiring_id":"a44d0a7ea234f50cb271b333b218a6466cf101e37297cdade246ad9e11977194","amount":350,"merchant_name":"Pivo Wallet Oy","merchant_business_id":"2241007-8","merchant_webstore_url":"https://pivolompakko.fi/","message":"It be a message.","phone":"+358402017501","return_url":"https://yourwebsite.com/callback/return","cancel_url":"https://yourwebsite.com/callback/cancel","reject_url":"https://yourwebsite.com/callback/reject","return_app_url":"yourscheme://api/return"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer 5e7c4715c0028e125c3415f458e721ff1fa1b5c8ecb4d83924d4710f02721c1b

Request body:

{
  "stamp": "b33dba71-9b73-4605-9e4d-f42e87d42aee",
  "reference": "14932116599460307792",
  "acquiring_id": "a44d0a7ea234f50cb271b333b218a6466cf101e37297cdade246ad9e11977194",
  "amount": 350,
  "merchant_name": "Pivo Wallet Oy",
  "merchant_business_id": "2241007-8",
  "merchant_webstore_url": "https://pivolompakko.fi/",
  "message": "It be a message.",
  "phone": "+358402017501",
  "return_url": "https://yourwebsite.com/callback/return",
  "cancel_url": "https://yourwebsite.com/callback/cancel",
  "reject_url": "https://yourwebsite.com/callback/reject",
  "return_app_url": "yourscheme://api/return"
}

Response with status 200:

{
  "payment_id": "9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "stamp": "b33dba71-9b73-4605-9e4d-f42e87d42aee",
  "merchant_name": "Pivo Wallet Oy",
  "merchant_webstore_url": "https://pivolompakko.fi/",
  "merchant_business_id": "2241007-8",
  "reference": "14932116599460307792",
  "message": "It be a message.",
  "amount": 350,
  "return_app_url": "yourscheme://api/return?payment_id=9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "pivo_app_url": "pivo://api/v1/payment_button?payment_id=9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "expires_at": 1533795340,
  "expired": false,
  "type": "payment_order",
  "created_at": "2018-08-09T05:45:40Z",
  "updated_at": "2018-08-09T05:45:40Z",
  "acquiring": {
    "acquiring_id": "a44d0a7ea234f50cb271b333b218a6466cf101e37297cdade246ad9e11977194"
  },
  "phone": "+358402017501",
  "phone_status": "received",
  "status": "pending",
  "url": "",
  "location_url": "http://localhost:4000/api/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "return_url": "https://yourwebsite.com/callback/return",
  "cancel_url": "https://yourwebsite.com/callback/cancel",
  "reject_url": "https://yourwebsite.com/callback/reject"
}

Query Parameters

Name Required Type Description
stamp true String Your unique identifier for the payment order
reference false String Payment’s reference number in standard format (viite). If not present ‘message’ is used.
acquiring_id true String Unique identifier for the acquiring data
amount true Integer Amount in euro cents
merchant_name false String Merchant name. Maximum length is 100 characters. Displayed in Pivo ‘approve payment’ view. If not given iban_owner_name is used from Your acquiring data.
merchant_business_id false String Merchant business id (Y-tunnus)
merchant_webstore_url false String Merchant’s web store address
message false String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
phone false String User’s phone number. Will be suggested (pre-filled) for User on desktop browser payments. The phone number needs to be in international format (e.g. +358401234567) or local format (e.g. 0401234567).
return_url false String Success url. Called automatically by Us to confirm payment transaction. On web payments consumer’s browser is redirected to the url along with payment transaction details. If not provided, web payment is not supported (location_url is defined as blank) and no confirmation is sent.
cancel_url false String Used on web payments when consumer cancels the payment order. User’s browser is redirected to the url along with cancellation details.
reject_url false String Used on web payments when we cannot help consumer to pay. User’s browser is redirected to the url along with rejection details.
return_app_url false String Used to get back to Your application.

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
merchant_name String Name of the merchant
merchant_webstore_url String Merchant’s web store address
merchant_business_id String Merchant business id (Y-tunnus)
reference String Payment’s reference number in standard format (viite)
message String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
amount Integer Amount in euro cents
return_app_url String Used to get back to Your application.
pivo_app_url String Url that You will use to open the Pivo mobile app
expires_at Integer UNIX time stamp of expiration time (seconds)
expired Boolean Tells whether the payment order is expired
type String Payment order type, ‘payment_order’
created_at String Creation time, ISO-8601 format
updated_at String Update time, ISO-8601 format
phone String User’s phone number
phone_status phone status
status String Status of the payment order (‘pending’, ‘paid’, ‘cancelled’, ‘rejected’ or ‘refunded’)
url String Generated with call back urls when final state is given
location_url String web UI location for the payment order
return_url String Return url
cancel_url String Cancel url
reject_url String Reject url
acquiring JSON object Acquiring data
acquiring_id String Unique Acquiring identifier

Get all payments

GET https://qa-maksu-api.pivo.fi/api/payments

Get list of payment orders

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/payments" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer b913dd8f5efe8e3f8d4b95a4085f9af7f4aaef204ed6152fe4ccc3df8df72dd3

Response with status 200:

{
  "payments": [
    {
      "payment_id": "fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
      "stamp": "dbfed8b0-f52c-4949-9fed-8ebed5b8fdf3",
      "merchant_name": "Pivo Wallet Oy",
      "amount": 121,
      "status": "refunded"
    },
    {
      "payment_id": "9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
      "stamp": "2606c59e-7648-4def-85ca-bec3a953d141",
      "merchant_name": "Pivo Wallet Oy",
      "amount": 350,
      "status": "pending"
    }
  ],
  "meta": {
    "current_page": 1,
    "total_pages": 1,
    "total_count": 2
  }
}

Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description
payments JSON List List containing information in payment orders
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
merchant_name String Name of the merchant
amount Integer Amount in euro cents
status String Status of the payment order (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)
meta JSON Object Contains information on paging of paymebts
current_page Integer Which page of the list is
total_pages Integer Total amount of pages
total_count Integer Total amount of payment orders

Get Payment Order Information

GET https://qa-maksu-api.pivo.fi/api/payments/:payment_id

Get payment order information with payment_id or Your stamp. Parameter :payment_id can be either Your stamp or payment_id generated by Us.

The phone_status statuses are explaned in the section Add phone number to existing payment

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/payments/fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer 9747cc806cb2efa5f0c98aeab59d0290833821ffea30b1a8ce056b10f570ace9

Response with status 200:

{
  "payment_id": "fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
  "stamp": "8c04fb01-2096-46f6-8099-71173bd737a5",
  "merchant_name": "Pivo Wallet Oy",
  "merchant_webstore_url": "https://pivolompakko.fi/",
  "merchant_business_id": "2241007-8",
  "reference": "14932116599460307792",
  "message": "Another message",
  "amount": 121,
  "return_app_url": "yourscheme://api/return?payment_id=fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
  "pivo_app_url": "pivo://api/v1/payment_button?payment_id=fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
  "expires_at": 1533795340,
  "expired": false,
  "type": "payment_order",
  "created_at": "2018-08-09T05:45:40Z",
  "updated_at": "2018-08-09T05:45:40Z",
  "acquiring": {
    "acquiring_id": "00b5ca45b4ac3cea47d532e5e1ceb7b4ad465dde63dd67e75837810f88f19cd0"
  },
  "phone": "+358500000000",
  "phone_status": "received",
  "current_amount": 111,
  "status": "refunded",
  "url": "https://yourwebsite.com/callback/return?archive_id=d0dfa88fbcc3a97ed0c8&payment_id=fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e&payment_type=account&signature=account_id+27efbd50f6720c4777d5d43c4327fc74f3ce9edc0aefb3350641d99477f99133&stamp=8c04fb01-2096-46f6-8099-71173bd737a5&status=paid",
  "location_url": "http://localhost:4000/api/payments/fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
  "payment_type": "account",
  "archive_id": "d0dfa88fbcc3a97ed0c8",
  "return_url": "https://yourwebsite.com/callback/return",
  "cancel_url": "https://yourwebsite.com/callback/cancel",
  "reject_url": "https://yourwebsite.com/callback/reject",
  "refunds": [
    {
      "stamp": "6a05c255-e043-4904-8622-b7334f0944a3",
      "reference": "5a3fdda0-bfb7-42b7-8b6e-f4997994b286",
      "amount": 10,
      "archive_id": "ba30f21a-5e44-42eb-9212-36b3760c3135",
      "payment_type": "account",
      "created_at": "2018-08-09T05:45:40Z"
    }
  ]
}

Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
merchant_name String Name of the merchant
merchant_webstore_url String Merchant’s web store address
merchant_business_id String Merchant business id (Y-tunnus)
reference String Payment’s reference number in standard format (viite)
message String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
amount Integer Amount in euro cents
return_app_url String Used to get back to Your application.
pivo_app_url String Url that you will use to open the Pivo mobile app
expires_at Integer UNIX time stamp of expiration time (seconds)
expired Boolean Tells whether the payment order is expired
type String Payment order type, “payment order”
created_at String Creation time, ISO-8601 format
updated_at String Update time, ISO-8601 format
phone String User’s phone number
phone_status phone status
current_amount Integer Current amount tells the current real value of the payment order (in euro cents), calculates refunds.
status String Status of the payment order (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)
url String Generated with call back urls when final state is given
location_url String web UI location for the payment order
payment_type String Payment method of the payment transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment, ‘siirto’ Payment order paid as siirto payment.
archive_id String Payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code)
return_url String Return url
cancel_url String Cancel url
reject_url String Reject url
acquiring JSON object Acquiring data
acquiring_id String Unique Acquiring identifier
refunds JSON object Refund data
stamp String Refund unique identifier
reference String Refund reference number in standard format (viite)
amount String Refunded amount in euro cents.
payment_type String Payment method of the refund transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment
archive_id String Refund payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code)
created_at String Refund creation time, ISO-8601 format

Canceling a Payment Order

DELETE https://qa-maksu-api.pivo.fi/api/payments/:payment_id

Cancels the the payment order. No data is returned on successful response.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843" -d '' -X DELETE \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer 7f5f3e8fc58474537c402ddc782a54549d884ac6115f3dec23558fdab6fcf7d0

Response with status 200:


Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description

None

Refunding a Payment Order

POST https://qa-maksu-api.pivo.fi/api/payments/:payment_id/refund

Refunds the paid payment. Supports full and partial refunds.

⚠ Please note that this API is restricted! For more information please contact us. (access right refund)

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments/fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e/refund" -d '{"reference":"14932116599460307792","amount":21,"nonce":"ff4ed2386d8e44ecec6beff31ed006bbc309c4ccf6f1abc156b3f97f5b69043e","stamp":"5cdef572-bb90-4ab2-b6ee-d51567975815"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer ff4ed2386d8e44ecec6beff31ed006bbc309c4ccf6f1abc156b3f97f5b69043e

Request body:

{
  "reference": "14932116599460307792",
  "amount": 21,
  "nonce": "ff4ed2386d8e44ecec6beff31ed006bbc309c4ccf6f1abc156b3f97f5b69043e",
  "stamp": "5cdef572-bb90-4ab2-b6ee-d51567975815"
}

Response with status 200:

{
  "payment_id": "fd8bcb800ae79bf1f7b9afb137d9972f8f885dfa2256e9fa9505c3e73da4643e",
  "stamp": "90c602ea-ac24-4052-af8f-ff68b4157238",
  "refund": {
    "stamp": "5cdef572-bb90-4ab2-b6ee-d51567975815",
    "reference": "14932116599460307792",
    "amount": 21,
    "archive_id": "d0dfa88fbcc3a97ed0c8",
    "payment_type": "account",
    "created_at": "2018-08-09T05:45:41Z"
  }
}

Query Parameters

Name Required Type Description
reference false String Refund’s reference number in standard format (viite).
amount false Integer Refund amount in euro cents. If omitted the payment is fully refunded.
nonce true String Parameter ‘nonce’ or request header ‘Request-Id’ is required for security. Must be unique.
stamp true String Your unique identifier for the refund

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
refund JSON object Created refund information
stamp String Unique identifier for the refund
reference String Refund reference number in standard format (viite)
amount Integer Refunded amount in euro cents.
payment_type String Payment method of the refund transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment
archive_id String Refund payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code)
created_at String Refund creation time, ISO-8601 format

Add phone number to existing payment

PUT https://qa-maksu-api.pivo.fi/api/payments/:payment_id/phone_number/:phone_number

Used to add phone number to an existing payment order. When You add a phone number to an existing payment order the Payer will receive a push notification referencing to the payment order.

The phone number needs to be in international format (e.g. +358401234567) or local format (e.g. 0401234567).

⚠ Please note that this API is restricted! For more information please contact us. (access right payments_phone_number)

Phone statuses

phone_status Explanation
received Phone number is received along with other payment order creation data
prosessing in process (set phone number has called and a Payment notification is sent)
ok Pivo user did not receive push notification
push Pivo user received a push notification
siirto Payment notification was sent to Siirto.
accepted Pivo user was not found, Nor registered device in Siirto, but the created payment order is waiting for user to register with the given phone number.
error Processing failed (Recreating the initiated call might help)

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843/phone_number/%2B358401234567" -d '' -X PUT \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer 014d50f602f47064deab429fde3a34cec05b2348f6bcf71491a495db00f2f1ba

Response with status 200:

{
  "phone_status": "ok"
}

Query Parameters

Name Required Type Description

None

Response Fields

Name Type Description
phone_status phone status

Charge payment order with charge token

POST https://qa-maksu-api.pivo.fi/api/payments/:payment_id/charge

Used to create a charge with Pivo charge token.

⚠ Please note that this API is restricted! For more information please contact us. (access right payments_charge)

Typical Error Codes

Error Code Message Meaning
400 Bad request With body {“payment_method”:“not_supported” } when Pivo user has chosen a Payment Method which is not supported by the Merchant
409 Conflict It is possible to call charge only once with the defined charge token. Following requests will end up with conflick http response code.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843/charge" -d '{"charge_token":"532de5c164b34b05f077"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Api-Version: 2"

Request Header:

Accept: application/json
Content-Type: application/json
Api-Version: 2
Authorization: Bearer 182ab83b7d26933a267dca35cfaa9c8d03aee04f3ee5090d07d43c92ad13941c

Request body:

{
  "charge_token": "532de5c164b34b05f077"
}

Response with status 200:

{
  "archive_id": "20170105593497XH0002",
  "payment_type": "siirto"
}

Query Parameters

Name Required Type Description
charge_token true String Charge token

Response Fields

Name Type Description
payment_type String Payment method of the payment transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment, ‘siirto’ Payment order paid as siirto payment.
archive_id String Payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code)

REST API - Urls

Used to create urls for payment order and share when Pivo mobile application is used.

When generating return_app_url to payment order the target platform is pivo.

when generating share able link the target platform is http.

Access scope: urls

To use this resource You need to request a specific access scope when getting access token.

Create Loyalty program url for pivo platform

POST https://qa-maksu-api.pivo.fi/api/urls/loyalty_program_site

Response contains the generated url and used platform

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/urls/loyalty_program_site" -d '{"platform":"pivo","url":"https://yourwebsite.com/orders/a78dbd25-844b-49b4-b883-a544df95f8bf"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer c18cd974374b5bf920d07172e1576adb313d2da3dc08d217d51f8d7c0197e4c5

Request body:

{
  "platform": "pivo",
  "url": "https://yourwebsite.com/orders/a78dbd25-844b-49b4-b883-a544df95f8bf"
}

Response with status 200:

{
  "platform": "pivo",
  "url": "pivo://api/v1/open/loyalty_program_site?url=https://yourwebsite.com/orders/a78dbd25-844b-49b4-b883-a544df95f8bf&pivo_loyalty_program=example_pivo_loyalty_program_name"
}

Query Parameters

Name Required Type Description
platform true String Target platform. (“pivo” or “http”)
url true String Loyalty program landing url. Fully qualified url with protocol, host and path.

Response Fields

Name Type Description
platform String Target platform to which the generated url was created
url String Generated url

REST API - User identification

Create a Pivo user identification request

Please read Pivo Loyalty program for more information regarding Pivo integration.

Access scope: payments

To use this resource You need to request a specific access scope when getting access token.

Additionally We need to grant Your account a specific payments_type permission.

Create an identification request

POST https://qa-maksu-api.pivo.fi/api/payments

A successful response contains information about the created payment order.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/api/payments" -d '{"stamp":"5189bb87-df26-4783-9010-46be98af3c77","type":"identification","merchant_name":"Pivo Wallet Oy","message":"It be a message.","return_url":"https://yourwebsite.com/callback/return","cancel_url":"https://yourwebsite.com/callback/cancel","reject_url":"https://yourwebsite.com/callback/reject","return_app_url":"yourscheme://api/return"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer c11350fdef69f689c7448863db6511bc9ebc0d2385508e860def581be61639dd

Request body:

{
  "stamp": "5189bb87-df26-4783-9010-46be98af3c77",
  "type": "identification",
  "merchant_name": "Pivo Wallet Oy",
  "message": "It be a message.",
  "return_url": "https://yourwebsite.com/callback/return",
  "cancel_url": "https://yourwebsite.com/callback/cancel",
  "reject_url": "https://yourwebsite.com/callback/reject",
  "return_app_url": "yourscheme://api/return"
}

Response with status 200:

{
  "payment_id": "2e1b5dbc5687fe0502c7b4834305ef61e8b1a3a7e7b2febc887bb510895230a7",
  "stamp": "5189bb87-df26-4783-9010-46be98af3c77",
  "merchant_name": "Pivo Wallet Oy",
  "merchant_webstore_url": "",
  "merchant_business_id": "",
  "reference": "",
  "message": "It be a message.",
  "return_app_url": "yourscheme://api/return?payment_id=2e1b5dbc5687fe0502c7b4834305ef61e8b1a3a7e7b2febc887bb510895230a7",
  "pivo_app_url": "pivo://api/v1/payment_button?payment_id=2e1b5dbc5687fe0502c7b4834305ef61e8b1a3a7e7b2febc887bb510895230a7",
  "expires_at": 1533795341,
  "expired": false,
  "type": "identification",
  "created_at": "2018-08-09T05:45:41Z",
  "updated_at": "2018-08-09T05:45:41Z",
  "phone": "",
  "phone_status": "received",
  "status": "pending",
  "url": "",
  "location_url": "http://localhost:4000/api/payments/2e1b5dbc5687fe0502c7b4834305ef61e8b1a3a7e7b2febc887bb510895230a7",
  "return_url": "https://yourwebsite.com/callback/return",
  "cancel_url": "https://yourwebsite.com/callback/cancel",
  "reject_url": "https://yourwebsite.com/callback/reject"
}

Query Parameters

Name Required Type Description
stamp true String Your unique identifier for the payment order
type true String payment order type: identification
merchant_name true String Merchant name. Maximum length is 100 characters. Displayed in Pivo ‘approve authorization’ view. If not given iban_owner_name is used from Your acquiring data.
message false String Identification related message for the user. Maximum length is 140 characters.
return_url false String Success url. Called automatically by Us to confirm payment transaction. On web payments consumer’s browser is redirected to the url along with payment transaction details. If not provided, web payment is not supported (location_url is defined as blank) and no confirmation is sent.
cancel_url false String Used on web payments when consumer cancels the payment order. User’s browser is redirected to the url along with cancellation details.
reject_url false String Used on web payments when we cannot help consumer to pay. User’s browser is redirected to the url along with rejection details.
return_app_url false String Used to get back to Your application.

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
merchant_name String Name of the merchant
merchant_webstore_url String Merchant’s web store address
merchant_business_id String Merchant business id (Y-tunnus)
reference String Payment’s reference number in standard format (viite)
message String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
return_app_url String Used to get back to Your application.
pivo_app_url String Url that You will use to open the Pivo mobile app
expires_at Integer UNIX time stamp of expiration time (seconds)
expired Boolean Tells whether the payment order is expired
type String Payment order type, “payment order”
created_at String Creation time, ISO-8601 format
updated_at String Update time, ISO-8601 format
phone String User’s phone number
phone_status phone status
status String Status of the payment order (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)
url String Generated with call back urls when final state is given
location_url String web UI location for the payment order
return_url String Return url
cancel_url String Cancel url
reject_url String Reject url

REST API - Users

Used to fetch User identity information for authorized identification requests.

Access scope: users

To use this resource You need to request a specific access scope when getting access token.

Fetch user identify

GET https://qa-maksu-api.pivo.fi/api/users

Response contains the requested user information

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/users?payment_id=c5b66378ea63b52d39aa64b6ca81f5f97a17b19c9a729f91c22e66fa199124c7" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 51a2aed6ed41960b3481d2e8c23004f2dbe2954952ddf671490cc581f8c997a1

Response with status 200:

{
  "user": {
    "id": "1f7155fcf6dec738e3a93448697cb7023086b929239645a53a4d895c239be763",
    "ssn": "081181-9984",
    "birthday": "08.11.1981",
    "sex": "0",
    "first_names": "Anna",
    "full_name": "Pivo Anna",
    "last_name": "Pivo",
    "phone_number": "+358442365198"
  }
}

Query Parameters

Name Required Type Description
payment_id true String Payment Id of the authorized identification request

Response Fields

Name Type Description
user JSON object User identity information
id String Unique application and merchant specific user id
ssn String Social security number
birthday String Birthday in dd.MM.yyyy format
sex String User gender (0 = female, 1 = male)
first_names String First names
full_name String Full name
last_name String Last name
phone_number String Phone number in internation format
email String Email
image_url String Image url
address JSON object Address
street String Street address
post_code String Postal code
city String Postal office
country String Country

REST API - PSP Payments

Retrieves Pivo form parameters from psp and creates a payment order.

Supports setting return_app_url for payment order even if payment service provider does not support it.

Access scope: psp_payments

To use this resource You need to request a specific access scope when getting access token.

Create a Payment Order with PSP account

POST https://qa-maksu-api.pivo.fi/psp/payments

A successful response contains information about the created payment order. Merchant specific data is received from the PSP.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/psp/payments" -d '{"stamp":"8d2a297b09a867370a35","psp_account_id":"052c21810f3fc2312621c18aa78bf50809a1bbed661daf3bc4a0ba34b282be54","amount":350,"message":"It be a message.","return_app_url":"yourscheme://api/return","callback_url":"https://yourwebsite.com/callback","merchant_id":"585858","vat":"24"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 917d274ddc687d975783dbe230e7673de7969969297cfa95e8c052a7b1570088

Request body:

{
  "stamp": "8d2a297b09a867370a35",
  "psp_account_id": "052c21810f3fc2312621c18aa78bf50809a1bbed661daf3bc4a0ba34b282be54",
  "amount": 350,
  "message": "It be a message.",
  "return_app_url": "yourscheme://api/return",
  "callback_url": "https://yourwebsite.com/callback",
  "merchant_id": "585858",
  "vat": "24"
}

Response with status 200:

{
  "payment_id": "9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "stamp": "8d2a297b09a867370a35",
  "merchant_name": "Test merchant",
  "merchant_webstore_url": "https://example.com/",
  "merchant_business_id": "1234567-8",
  "message": "Test payment!",
  "amount": 100,
  "status": "pending",
  "pivo_app_url": "pivo://api/v1/payment_button?payment_id=9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "location_url": "http://localhost:4000/api/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "return_app_url": "yourscheme://api/return",
  "callback_url": "https://yourwebsite.com/callback"
}

Query Parameters

Name Required Type Description
stamp true String Your unique identifier for the psp payment order, max length depends on psp implementation (checkout max length 20)
psp_account_id true String Unique identifier for your psp account data
amount true Integer Amount in euro cents
message false String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
return_app_url false String Used to get back to Your application.
callback_url false String Automatic callback url for merchant.
merchant_id false String Optional psp merchant_id for psp payment initiation. Merchant id of the shop selling the item (SiS-shop).
vat false String Optional vat value for payment. If not provided then 24 is used
commission_amount false String Optional commission, requires commission_merchant_id field
commission_merchant_id false String Optional commission merchant_id, requires commission_amount field. Merchant ID, that will receive the commission from the payment (usually same as merchant_id)
commission_message false String Optional commission message

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
stamp String Your unique identifier for the payment order
merchant_name String Name of the merchant
merchant_webstore_url String Merchant’s web store address
merchant_business_id String Merchant business id (Y-tunnus)
message String Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
amount Integer Amount in euro cents
status String Status of the created payment order (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)
pivo_app_url String Url that You will use to open the Pivo mobile app
location_url String web UI location for the payment order
return_app_url String Used to get back to Your application.
callback_url String Automatic callback url for merchant.

Retrieve a Payment Order for PSP account

POST https://qa-maksu-api.pivo.fi/psp/payments/:payment_id

A successful response contains information about the payment order.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/psp/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843" -d '{"psp_account_id":"5a86534f240e40fdabf356cfbe22d74a7d82c6b11b8af9e01b652a54fdfd678c"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 70390caa2b5d78ec0efb9ba5c6def54ca938f37f1c3c75b53fe6836bb1f52158

Request body:

{
  "psp_account_id": "5a86534f240e40fdabf356cfbe22d74a7d82c6b11b8af9e01b652a54fdfd678c"
}

Response with status 200:

{
  "payment_id": "9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
  "status": "paid"
}

Query Parameters

Name Required Type Description
psp_account_id true String Unique identifier for the psp account data

Response Fields

Name Type Description
payment_id String Pivo unique identifier for the payment order.
status String Status of the payment order (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)

Charge PSP Payment Order with charge token

POST https://qa-maksu-api.pivo.fi/psp/payments/:payment_id/charge

A successful response contains payment transaction details.

⚠ Please note that this API is restricted! For more information please contact us. (access right psp_payments_charge)

Typical Error Codes

Error Code Message Meaning
400 Bad request With body {“payment_method”:“not_supported” } when Pivo user has chosen a Payment Method which is not supported by the Merchant
409 Conflict It is possible to call charge only once with the defined charge token. Following requests will end up with conflick http response code.

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/psp/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843/charge" -d '{"psp_account_id":"0deb47320d5c68adfb4a4cac8a6cf00a35a20aff4c292df3dd077d4e1b217cee","charge_token":"847c772471d390797606046767215847453106ebc80cc34ce14d11d45c53e553"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer ceccca00c0820779dc282d14ce6447896c1e2d3f9cc143a41f56632b8a060ecc

Request body:

{
  "psp_account_id": "0deb47320d5c68adfb4a4cac8a6cf00a35a20aff4c292df3dd077d4e1b217cee",
  "charge_token": "847c772471d390797606046767215847453106ebc80cc34ce14d11d45c53e553"
}

Response with status 200:

{
  "archive_id": "94f3ec67896f615a49a4",
  "payment_type": "account"
}

Query Parameters

Name Required Type Description
psp_account_id true String Unique identifier for the psp account data
charge_token true String Charge token

Response Fields

Name Type Description
payment_type String Payment method of the payment transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment, ‘siirto’ Payment order paid as siirto payment.
archive_id String Payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code)

Refund PSP Payment Order with original stamp

POST https://qa-maksu-api.pivo.fi/psp/payments/:payment_id/refund

A successful response contains refund payment status.

⚠ Please note that this API is restricted! For more information please contact us. (access right psp_payments_refund)

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/psp/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843/refund" -d '{"psp_account_id":"f5f3b2efd4fa01564c2c9569b3ab7f48b7e172ad147aedd5304df5dcd087c9f5","original_stamp":"525657c491c9fd19c9a2","stamp":"6777b0018e15d9e39e07"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer b92e2c3d0cd503de5d6179b1ddb701736a7755105fd27955958b52f37f196a98

Request body:

{
  "psp_account_id": "f5f3b2efd4fa01564c2c9569b3ab7f48b7e172ad147aedd5304df5dcd087c9f5",
  "original_stamp": "525657c491c9fd19c9a2",
  "stamp": "6777b0018e15d9e39e07"
}

Response with status 200:

{
  "result": "REFUNDED"
}

Query Parameters

Name Required Type Description
psp_account_id true String Unique identifier for the psp account data
amount false Integer Refund amount in euro cents. If omitted the payment is fully refunded.
original_stamp true String Your unique identifier for the original psp payment order, max length depends on psp implementation (checkout max length 20)
stamp true String Your unique identifier for the psp refund, max length depends on psp implementation (checkout max length 20)

Response Fields

Name Type Description
result String Status of the refund (“pending”, “paid”, “cancelled”, “rejected” or “refunded”)

Add phone number to existing payment

PUT https://qa-maksu-api.pivo.fi/psp/payments/:payment_id/phone_number/:phone_number

Used to add phone number to an existing payment order. When You add a phone number to an existing payment order the Payer will receive a push notification referencing to the payment order.

The phone number needs to be in international format (e.g. +358401234567) or local format (e.g. 0401234567).

⚠ Please note that this API is restricted! For more information please contact us. (access right psp_payments_phone_number)

Phone statuses

phone_status Explanation
received Phone number is received along with other payment order creation data
prosessing in process (set phone number has called and a Payment notification is sent)
ok Pivo user did not receive push notification
push Pivo user received a push notification
siirto Payment notification was sent to Siirto.
accepted Pivo user was not found, Nor registered device in Siirto, but the created payment order is waiting for user to register with the given phone number.
error Processing failed (Recreating the initiated call might help)

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/psp/payments/9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843/phone_number/%2B358401234567" -d '{"psp_account_id":"8359261a268c5d72d5b4209a03036fdab440b64f211289f022681e2945fef227"}' -X PUT \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer d922d8d9c569d885100497c158f3bbd5cf2a03bebceb3c3b265ed135df8771d9

Request body:

{
  "psp_account_id": "8359261a268c5d72d5b4209a03036fdab440b64f211289f022681e2945fef227"
}

Response with status 200:

{
  "phone_status": "ok"
}

Query Parameters

Name Required Type Description
psp_account_id true String Unique identifier for the psp account data

Response Fields

Name Type Description
phone_status phone status

REST API - OP Yrityssiirto

For creating OP Yrityssiirto payments

Please see the section for detailed information when implementing signature calculation.

Dedicated documentation

Dedicated API documentation which only contains Authorization and this section.

Access scope: other_payments

To use this resource You need to request a specific access scope when getting access token.

Typical Error Codes

Error codes 4xx are client errors. On an error, please check Your parameters and access token.

Error Code Message Meaning
400 Bad request Check Your parameters
401 Unauthorized No access token provided or the access token is invalid. Signature is not correct.
403 Forbidden The access token does not have proper scope OR we are missing Your account number in provision data
412 Precondition Failed Check Your parameters again (e.g. format or business_id)

Create OP Yrityssiirto payment

POST https://qa-maksu-api.pivo.fi/other/payments

Response contains archive_number

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/other/payments" -d '{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"message":"Message for receiver","reference":"14932116599460307792"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer b8bad20769fb53e89d2c646fcd68f0549a92ffc095a7da9609b083065db07a71

Request body:

{
  "amount": 100,
  "originator": {
    "iban": "FI5558498520024222",
    "name": "Iban owner name",
    "business_id": "FI66554436",
    "industry_class_code": "4752"
  },
  "beneficiary": {
    "iban": "FI2159986920069366",
    "name": "Virtanen",
    "first_names": "Oskari Olavi"
  },
  "message": "Message for receiver",
  "reference": "14932116599460307792"
}

Response with status 200:

{
  "archive_number": "20180119593064010085",
  "status": "paid"
}

Query Parameters

Name Required Type Description
amount true Integer Amount in euro cents
originator true JSON object Originator object presenting the payer company
originator.iban true String The account number in IBAN format
originator.name true String The account owner name
originator.business_id true String The business id of the payer company. International format (ALV number).
originator.industry_class_code true String The industry class code of the payer company
beneficiary true JSON object Beneficiary object presenting the receiver(payee)
beneficiary.iban true String The account number in IBAN format
beneficiary.name true String The account owner name (person last name or company name)
beneficiary.first_names false String The account owner first names (for person, not required for company)
message false String message
reference true String Payment’s reference number in standard format (viite). If not present ‘message’ is used.

Response Fields

Name Type Description
archive_number String Archive number of the created payment
status String paid

Create OP Yrityssiirto payment with ultimate originator

POST https://qa-maksu-api.pivo.fi/other/payments

Response contains archive_number

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/other/payments" -d '{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer 130284d873da761f5e8357167af93f79d6490464c514a7d2eccc5e8780d9c75f

Request body:

{
  "amount": 100,
  "originator": {
    "iban": "FI5558498520024222",
    "name": "Iban owner name",
    "business_id": "FI66554436",
    "industry_class_code": "4752"
  },
  "beneficiary": {
    "iban": "FI2159986920069366",
    "name": "Virtanen",
    "first_names": "Oskari Olavi"
  },
  "ultimate_originator": {
    "name": "Korhonen Pekka Tuomas",
    "ssn": "240811-1234",
    "business_id": "24",
    "industrial_class_code": "08"
  },
  "message": "Message for receiver",
  "reference": "14932116599460307792"
}

Response with status 200:

{
  "archive_number": "20180119593064010085",
  "status": "paid"
}

Query Parameters

Name Required Type Description
amount true Integer Amount in euro cents
originator true JSON object Originator object presenting the payer company
originator.iban true String The account number in IBAN format
originator.name true String The account owner name
originator.business_id true String The business id of the payer company. International format (ALV number).
originator.industry_class_code true String The industry class code of the payer company
beneficiary true JSON object Beneficiary object presenting the receiver(payee)
beneficiary.iban true String The account number in IBAN format
beneficiary.name true String The account owner name (person last name or company name)
beneficiary.first_names false String The account owner first names (for person, not required for company)
ultimate_originator false JSON object Ultimate originator object presenting the party on whose behalf the originator is paying
ultimate_originator.name true String The name of the ultimate receiver (for person lastname and firstnames or company name)
ultimate_originator.ssn false String The ssn of the person (required for person)
ultimate_originator.business_id false String The business_id of the company (required for company). International format (ALV number).
ultimate_originator.industrial_class_code false String The industrial_class_code of the company (required for company)
message false String message
reference true String Payment’s reference number in standard format (viite). If not present ‘message’ is used.

Response Fields

Name Type Description
archive_number String Archive number of the created payment
status String paid

Create OP Yrityssiirto payment with shared secret parameter signature

POST https://qa-maksu-api.pivo.fi/other/payments

Response contains archive_number

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/other/payments" -d '{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792","signature":"payment_api_user 312fe4d8055b2e8e1a5cded6d4d53d0d667dc2f1b495c9902a536a6198dbfbf4"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: 

Request body:

{
  "amount": 100,
  "originator": {
    "iban": "FI5558498520024222",
    "name": "Iban owner name",
    "business_id": "FI66554436",
    "industry_class_code": "4752"
  },
  "beneficiary": {
    "iban": "FI2159986920069366",
    "name": "Virtanen",
    "first_names": "Oskari Olavi"
  },
  "ultimate_originator": {
    "name": "Korhonen Pekka Tuomas",
    "ssn": "240811-1234",
    "business_id": "24",
    "industrial_class_code": "08"
  },
  "message": "Message for receiver",
  "reference": "14932116599460307792",
  "signature": "payment_api_user 312fe4d8055b2e8e1a5cded6d4d53d0d667dc2f1b495c9902a536a6198dbfbf4"
}

Response with status 200:

{
  "archive_number": "20180119593064010085",
  "status": "paid"
}

Query Parameters

Name Required Type Description
amount true Integer Amount in euro cents
originator true JSON object Originator object presenting the payer company
originator.iban true String The account number in IBAN format
originator.name true String The account owner name
originator.business_id true String The business id of the payer company. International format (ALV number).
originator.industry_class_code true String The industry class code of the payer company
beneficiary true JSON object Beneficiary object presenting the receiver(payee)
beneficiary.iban true String The account number in IBAN format
beneficiary.name true String The account owner name (person last name or company name)
beneficiary.first_names false String The account owner first names (for person, not required for company)
ultimate_originator false JSON object Ultimate originator object presenting the party on whose behalf the originator is paying
ultimate_originator.name true String The name of the ultimate receiver (for person lastname and firstnames or company name)
ultimate_originator.ssn false String The ssn of the person (required for person)
ultimate_originator.business_id false String The business_id of the company (required for company). International format (ALV number).
ultimate_originator.industrial_class_code false String The industrial_class_code of the company (required for company)
message false String message
reference true String Payment’s reference number in standard format (viite). If not present ‘message’ is used.
signature true String Calculated signature from other fields. Use dot-notation for nested elements, order alphabetically and calculate hmac as presented in Signature section

Response Fields

Name Type Description
archive_number String Archive number of the created payment
status String paid

Create OP Yrityssiirto payment with public key parameter signature

POST https://qa-maksu-api.pivo.fi/other/payments

Response contains archive_number

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/other/payments" -d '{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792","signature":"pk:payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 jOhd62LYpHLGaunHprdeloEIQutUBVqPjUa3ndZr7Fr1/R2Atwxf6Iow7J6BCHVcj4ZLYPNm91Pp/z85FXEpnze+pTcdfP2yThdVrqniAllDZTvWGArsBZVUVJdxM/NUkxkWvYGTrSoOVhAnZ8Q9VbnvJsK+rEymRK7CCThULRQd9BK1gLWfjfpsKIdliOdT3xr/XUDciJGtnimTJtfvlyt24CwzyQ055UGXTL52eciJYNMYlgBPUZictee8QjGp40epF3AFm6OpYch/G7FEc4aMT8D7DB/zTGsttUGvUSBCrUADyde4WrXnSM4ds9siMoDgdOkKV8/90C61MPs9mQ=="}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: 

Request body:

{
  "amount": 100,
  "originator": {
    "iban": "FI5558498520024222",
    "name": "Iban owner name",
    "business_id": "FI66554436",
    "industry_class_code": "4752"
  },
  "beneficiary": {
    "iban": "FI2159986920069366",
    "name": "Virtanen",
    "first_names": "Oskari Olavi"
  },
  "ultimate_originator": {
    "name": "Korhonen Pekka Tuomas",
    "ssn": "240811-1234",
    "business_id": "24",
    "industrial_class_code": "08"
  },
  "message": "Message for receiver",
  "reference": "14932116599460307792",
  "signature": "pk:payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 jOhd62LYpHLGaunHprdeloEIQutUBVqPjUa3ndZr7Fr1/R2Atwxf6Iow7J6BCHVcj4ZLYPNm91Pp/z85FXEpnze+pTcdfP2yThdVrqniAllDZTvWGArsBZVUVJdxM/NUkxkWvYGTrSoOVhAnZ8Q9VbnvJsK+rEymRK7CCThULRQd9BK1gLWfjfpsKIdliOdT3xr/XUDciJGtnimTJtfvlyt24CwzyQ055UGXTL52eciJYNMYlgBPUZictee8QjGp40epF3AFm6OpYch/G7FEc4aMT8D7DB/zTGsttUGvUSBCrUADyde4WrXnSM4ds9siMoDgdOkKV8/90C61MPs9mQ=="
}

Response with status 200:

{
  "archive_number": "20180119593064010085",
  "status": "paid"
}

Query Parameters

Name Required Type Description
amount true Integer Amount in euro cents
originator true JSON object Originator object presenting the payer company
originator.iban true String The account number in IBAN format
originator.name true String The account owner name
originator.business_id true String The business id of the payer company. International format (ALV number).
originator.industry_class_code true String The industry class code of the payer company
beneficiary true JSON object Beneficiary object presenting the receiver(payee)
beneficiary.iban true String The account number in IBAN format
beneficiary.name true String The account owner name (person last name or company name)
beneficiary.first_names false String The account owner first names (for person, not required for company)
ultimate_originator false JSON object Ultimate originator object presenting the party on whose behalf the originator is paying
ultimate_originator.name true String The name of the ultimate receiver (for person lastname and firstnames or company name)
ultimate_originator.ssn false String The ssn of the person (required for person)
ultimate_originator.business_id false String The business_id of the company (required for company). International format (ALV number).
ultimate_originator.industrial_class_code false String The industrial_class_code of the company (required for company)
message false String message
reference true String Payment’s reference number in standard format (viite). If not present ‘message’ is used.
signature true String Private key calculated signature from other fields. Use dot-notation for nested elements, order alphabetically and calculate private key signature as presented in Signature section

Response Fields

Name Type Description
archive_number String Archive number of the created payment
status String paid

Create OP Yrityssiirto payment with public key header signature

POST https://qa-maksu-api.pivo.fi/other/payments

Request contains Request-Id and Signature headers.

Signature is calculated from the payload (body).

⚠ Note the curl example uses wrongly Request please use Request-Id as defined!

Response contains archive_number and the status of the payment

cUrl Example:

$ curl "https://qa-maksu-api.pivo.fi/other/payments" -d '{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792"}' -X POST \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -H "Request: 8eb15bc6-b6fa-497d-adf4-97f067ea052f" \
    -H "Signature: payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 eUotQ2nhZRok8UNH34z8VSeLpfCWoFIwddxHvwjvttZErQk33rM5rii+nkB7ZRrpwkC/lRXymSHWAzhBThhdYwVB6Hzk77ljmFObebla8hXuaKFcqBMrG0LkkBx83BNiLVDr31VxgYqMYnyd7jluJTjKcfzCsfNssrOHb9BfhZfzD4x1Gysn8nIkkXfm9eeIgASFtHNA+jBQddon9c+D3BrwpOe3zlqz+15tzkhJ1zScrlLVKU7m0fwvmzh9RQrFVeeFKbmrxg/3BZ3j6ybeG0s+vxYFXwXCFjKZiuTfgLyGlffAfgWn5NSze3mexXsRlQw4OX970yfTCfawqyziyQ=="

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: 
Request-Id: 8eb15bc6-b6fa-497d-adf4-97f067ea052f
Signature: payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 eUotQ2nhZRok8UNH34z8VSeLpfCWoFIwddxHvwjvttZErQk33rM5rii+nkB7ZRrpwkC/lRXymSHWAzhBThhdYwVB6Hzk77ljmFObebla8hXuaKFcqBMrG0LkkBx83BNiLVDr31VxgYqMYnyd7jluJTjKcfzCsfNssrOHb9BfhZfzD4x1Gysn8nIkkXfm9eeIgASFtHNA+jBQddon9c+D3BrwpOe3zlqz+15tzkhJ1zScrlLVKU7m0fwvmzh9RQrFVeeFKbmrxg/3BZ3j6ybeG0s+vxYFXwXCFjKZiuTfgLyGlffAfgWn5NSze3mexXsRlQw4OX970yfTCfawqyziyQ==

Request body:

{
  "amount": 100,
  "originator": {
    "iban": "FI5558498520024222",
    "name": "Iban owner name",
    "business_id": "FI66554436",
    "industry_class_code": "4752"
  },
  "beneficiary": {
    "iban": "FI2159986920069366",
    "name": "Virtanen",
    "first_names": "Oskari Olavi"
  },
  "ultimate_originator": {
    "name": "Korhonen Pekka Tuomas",
    "ssn": "240811-1234",
    "business_id": "24",
    "industrial_class_code": "08"
  },
  "message": "Message for receiver",
  "reference": "14932116599460307792"
}

Response with status 200:

{
  "archive_number": "20180119593064010085",
  "status": "paid"
}

Query Parameters

Name Required Type Description
amount true Integer Amount in euro cents
originator true JSON object Originator object presenting the payer company
originator.iban true String The account number in IBAN format
originator.name true String The account owner name
originator.business_id true String The business id of the payer company. International format (ALV number).
originator.industry_class_code true String The industry class code of the payer company
beneficiary true JSON object Beneficiary object presenting the receiver(payee)
beneficiary.iban true String The account number in IBAN format
beneficiary.name true String The account owner name (person last name or company name)
beneficiary.first_names false String The account owner first names (for person, not required for company)
ultimate_originator false JSON object Ultimate originator object presenting the party on whose behalf the originator is paying
ultimate_originator.name true String The name of the ultimate receiver (for person lastname and firstnames or company name)
ultimate_originator.ssn false String The ssn of the person (required for person)
ultimate_originator.business_id false String The business_id of the company (required for company). International format (ALV number).
ultimate_originator.industrial_class_code false String The industrial_class_code of the company (required for company)
message false String message
reference true String Payment’s reference number in standard format (viite). If not present ‘message’ is used.

Response Fields

Name Type Description
archive_number String Archive number of the created payment
status String paid

REST API - Tupas

Used to fetch Tupas report.

Access scope: tupas

To use this resource You need to request a specific access scope when getting access token.

Fetch tupas count

GET https://qa-maksu-api.pivo.fi/api/tupas/count

Response contains the requested tupas report

cUrl Example:

$ curl -g "https://qa-maksu-api.pivo.fi/api/tupas/count?startdate=2018-03-01&enddate=2018-04-01&status=confirmed" -X GET \
    -H "Accept: application/json" \
    -H "Content-Type: application/json"

Request Header:

Accept: application/json
Content-Type: application/json
Authorization: Bearer fa561a7cb5da03db141ca99d2157017ce0208179242e95f8834eefb9f6cdbc2d

Response with status 200:

{
  "tupas_authentications": 0
}

Query Parameters

Name Required Type Description
startdate true String The start date (inclusive) in ISO8601 format (YYYY-MM-DD)
enddate true String The end date (exclusive) in ISO8601 format (YYYY-MM-DD)
status false String The status of requested Tupas authentication requests. Default is :confirmed

Response Fields

Name Type Description
tupas_authentications string The number of tupas authentications between requested time interval

Form Post API

Form Post API can be used when there is a need to let User’s browser to create the payment order.

Form Parameters

The following example and table lists the create payment order form fields which are sent to Pivo landing page.

An example HTML form

 <form action="https://maksu.pivo.fi/api/payments" method="post">
      <input type='hidden' name='signature' value='payment_api_user 2533ebbee2bf2b3408106c1572af2cfc9b3d59c15b85a786c6a796cb24ec1419'>
      <input type='hidden' name='acquiring_id' value='[Your acquiring id]'>
      <input type='hidden' name='merchant_name' value='Pivo Wallet Oy'>
      <input type='hidden' name='merchant_business_id' value='2241007-8'>
      <input type='hidden' name='merchant_webstore_url' value='https://pivo.fi/'>
      <input type='hidden' name='stamp' value='b5091240-079b-44c4-bb06-9ccbadb81121'>
      <input type='hidden' name='reference' value='14932116599460307792'>
      <input type='hidden' name='amount' value='350'>
      <input type='hidden' name='message' value='A Message to Your customer'>
      <input type='hidden' name='phone' value=''>
      <input type='hidden' name='return_url' value="https://yourwebsite.com/callback/return">
      <input type='hidden' name='cancel_url' value="https://yourwebsite.com/callback/cancel">
      <input type='hidden' name='reject_url' value="https://yourwebsite.com/callback/reject">
      <input type='hidden' name='return_app_url' value="yourscheme://api/return">
    </form>

The following table lists the create payment order form fields which are sent to Pivo landing page.

Please see section Mobile or Web Payment Order whether to provide return_url and/or return_app_url parameters.

Parameter Required Explanation
signature true Calculated signature in supported format
acquiring_id true Reference to Your acquiring data
merchant_name false Merchant name. Maximum length is 80 characters. Displayed in Pivo ‘approve payment’ view. If not given iban_owner_name is used from your acquiring data.
merchant_business_id false Merchant business id (Y-tunnus)
merchant_webstore_url false Merchant’s web store address
stamp true Your unique identifier for the payment order.
reference false Payment’s reference number in standard format (viite). If not present ‘message’ or default message is used.
amount true Amount in euro cents
message false Payment related message for the user. e.g. Product summary. Maximum length is 140 characters.
phone false User’s phone number
return_url false Success url. Called automatically by Us to confirm payment transaction. On web payments consumer’s browser is redirected to the url along with payment transaction details. If not provided, web payment is not supported and no confirmation is sent.
cancel_url false Used on web payments when consumer cancels the payment order. User’s browser is redirected to the url along with cancellation details.
reject_url false Used on web payments when we cannot help consumer to pay. User’s browser is redirected to the url along with rejection details.
return_app_url false Used to get back to your application.

Calculating the Signature

See section Shared secret signature

Inline base64 coder

You can define a form post parameter with base64 encoded value. This is handy as browser or merchant shopping carts tend to mesh the form parameter values after signature calculation.

We decode the base64 encoded values after signature verification and before storing the payment order.

See the example regarding the correct format.

An example using the inline base64 coder

  # e.g.
  "merchant_name" => "base64 VGVzdGnDpCBPeQ==" 
  # is decoded to 
  "merchant_name" => "Testiä Oy"

Automatic Callback URLs

When the callback are defined for created payment order and the final state for payment order is received (paid, cancelled, rejected), Your callbacks are called by Us and possible by the consumer’s browser.

Pivo verifies the payment transaction with a callback and forwards the browser to Your site. Payment transaction details are appended as parameters.

Success URL

A.k.a return url.

The following table lists the parameters for the return_url HTTP GET call:

Parameter Explanation
payment_id Pivo unique identifier for the payment order.
stamp Your unique identifier for the payment order.
status Status of the payment order (“pending”, “paid”, “cancelled”, “rejected”, or “refunded”)
payment_type Payment method of the payment transaction. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment, ‘siirto’ Payment order paid as siirto payment..
archive_id Payment transaction identification in payment system, ‘arkistointitunnus’. E.g. Bank transfer ‘20170105593497XH0002’ (arkistointitunnus), card payment ‘170125211023’ (filing_code).
signature Calculated signature in supported format

Cancel URL

When consumer cancels the payment order.

The following table lists the parameters for the cancel_url HTTP GET call:

Parameter Explanation
payment_id Pivo unique identifier for the payment order.
stamp Your unique identifier for the payment order.
status Status of the payment order (“pending”, “paid”, “cancelled”, “rejected”, or “refunded”)
signature Calculated signature in supported format

Reject URL

When payment order is rejected by Us.

The following table lists the parameters for the reject_url HTTP GET call:

Parameter Explanation
payment_id Pivo unique identifier for the payment order.
stamp Your unique identifier for the payment order.
status Status of the payment order (“paid”)
signature Calculated signature in supported format

In case Your signature calculation is incorrect the signature is omitted from the reject url parameters.

Signature

Pivo Payment API supports three authentication methods.

You can choose any of the method You like. Use only one method for a single request.

For signature based authentications it is possible to use shared secret or public key signing. You can find further information below for implementing your own signature routines.

In Header signature the signature is calculated over the payload (body) as the Parameter signature uses ordered dot notation. Header signature requires Request-Id header field.

In case of shared secret you receive the secret from us, however when using public key please create Your own keys and send the public for Us.

Please consider which level of authentication You need. There exists weakness for OAuth client credentials authentication “Threat: Accidental Exposure of Passwords at Client Site of RFC6819”

Signature Format

Calculated signature format depends whether shared secret or public key is used

Name Format
shared secret <your-merchant-identification> <shared-secret-calculated-signature>
public key pk:<your-merchant-identification>/<your-public-key-id> <private-key-calculated-signature>

Shared secret signature

An example of a method that calculates shared secret signature in Ruby

module SignatureTools
  def self.sign_signature(account_id, secret, method, path, request_id: nil, params: {}, body: nil)
    fail AuthenticationFailed, 'no account_id given' unless account_id
    fail AuthenticationFailed, "no secret given for account: #{account_id}" unless secret

    message_fields = message_fields(method,
                                    path,
                                    request_id: request_id,
                                    params:     params,
                                    body:       body)

    signature = OpenSSL::HMAC.hexdigest OpenSSL::Digest.new('sha256'),
                                        secret,
                                        message_fields

    "#{account_id} #{signature}"
  end

  def self.message_fields(method, path, request_id: nil, params: {}, body: nil)
    message_fields = [method.to_s.upcase, path]
    message_fields << request_id if request_id
    message_fields += params.except(:signature).sort_by { |k, _| k }
                        .map { |k, v| "#{k.to_s.downcase}:#{v}" }
    message_fields << (body.nil? ? '' : body.is_a?(String) ? body : body.to_json)
    message_fields = message_fields.join("\n")
  end
end

# example values
account_id = 'test_account'

account_secret = 'secret'
method = 'POST'
path   = '/api/payments'
params = { "acquiring_id"          => "[Your acquiring id]",
           "amount"                => "350",
           "cancel_url"            => "https://yourwebsite.com/callback/cancel",
           "merchant_business_id"  => "2241007-8",
           "merchant_name"         => "Pivo Wallet Oy",
           "merchant_webstore_url" => "https://pivo.fi/",
           "message"               => "A Message to Your customer",
           "phone"                 => "",
           "reference"             => "14932116599460307792",
           "reject_url"            => "https://yourwebsite.com/callback/reject",
           "return_url"            => "https://yourwebsite.com/callback/return",
           "stamp"                 => "b5091240-079b-44c4-bb06-9ccbadb81121",
           "return_app_url"        => "yourscheme://api/return"
            }

signature = SignatureTools.sign_signature account_id, account_secret, method, path, params: params

# > signature
# => payment_api_user 2533ebbee2bf2b3408106c1572af2cfc9b3d59c15b85a786c6a796cb24ec1419"

# message fields as reference
# > message_fields
# => "POST\n/api/payments\nacquiring_id:[Your acquiring id]\namount:350\ncancel_url:https://yourwebsite.com/callback/cancel\nmerchant_business_id:2241007-8\nmerchant_name:Pivo Wallet Oy\nmerchant_webstore_url:https://pivo.fi/\nmessage:A Message to Your customer\nphone:\nreference:14932116599460307792\nreject_url:https://yourwebsite.com/callback/reject\nreturn_url:https://yourwebsite.com/callback/return\nstamp:b5091240-079b-44c4-bb06-9ccbadb81121\n"

Steps to calculate the signature

  1. HTTP method (e.g. ‘POST’) written in capital letters
  2. HTTP URI path: Plain path, no host (e.g. ‘/api/payments’)
  3. Request-id is added
  4. POST parameters sorted in alphabetical order by key. The keys must be written in small letters. The key and the value are joined using a colon (“:”).
  5. The HTTP body (if any) is added to the string as is.
  6. The information are combined to one row using the LF character (‘\n’)

⚠ Please note that even an empty value should be added.

⚠ Please note that if your request does not contain an optional parameter it should be omitted from the signature calculation.

Shared secret signature for Form Post API

See section Shared secret signature

Shared secret signature for OP Yrityssiirto

The following lines gives You a starting point when implementing parameter signature for OP Yrityssiirto.

Use the SignatureTools.sign_signature from previous section and data from below.

Please see the example data. The calculated signature is shown at the end and parameter message_fields for the SignatureTools.sign_signature method is highlighted to help implementation.

  # dotted hash example mixed to hash implementation
  module DottedHash
    def to_dotted_hash(recursive_key = '')
      self.each_with_object({}) do |(k, v), ret|
        key = recursive_key + k.to_s

        if v.is_a?(Hash)
          ret.merge!(v.to_dotted_hash(key + '.'))
        else
          ret[key] = v
        end
      end
    end
  end

  ::Hash.prepend DottedHash
  # ---

  account_id = "payment_api_user",
  account_secret = "30713f017cf49f1cde8c058446273d02ef040548178a89c050c7aff357729178"
  payload_params  = {
                      "amount"=>100,
                      "originator"=>{:iban=>"FI5558498520024222", :name=>"Iban owner name", :business_id=>"FI66554436", :industry_class_code=>"4752"},
                      "beneficiary"=>{:iban=>"FI2159986920069366", :name=>"Virtanen", :first_names=>"Oskari Olavi"},
                      "ultimate_originator"=>{:name=>"Korhonen Pekka Tuomas", :ssn=>"240811-1234", :business_id=>"24", :industrial_class_code=>"08"},
                      "message"=>"Message for receiver",
                      "reference"=>"14932116599460307792"
                    }

  payload_dotted_hash = payload_params.to_dotted_hash
  # payload_dotted_hash values
  # => {"amount"=>100,
  # "originator.iban"=>"FI5558498520024222",
  # "originator.name"=>"Iban owner name",
  # "originator.business_id"=>"FI66554436",
  # "originator.industry_class_code"=>"4752",
  # "beneficiary.iban"=>"FI2159986920069366",
  # "beneficiary.name"=>"Virtanen",
  # "beneficiary.first_names"=>"Oskari Olavi",
  # "ultimate_originator.name"=>"Korhonen Pekka Tuomas",
  # "ultimate_originator.ssn"=>"240811-1234",
  # "ultimate_originator.business_id"=>"24",
  # "ultimate_originator.industrial_class_code"=>"08",
  # "message"=>"Message for receiver",
  # "reference"=>"14932116599460307792"}  

  signature                   = SignatureTools.sign_signature account_id,
                                                              account_secret,
                                                              'POST',
                                                              '/other/payments',
                                                              params: payload_dotted_hash
  payload_params['signature'] = signature
  # signature value
  # => "payment_api_user 312fe4d8055b2e8e1a5cded6d4d53d0d667dc2f1b495c9902a536a6198dbfbf4"

  # message_fields in SignatureTools.sign_signature
  # => "POST\n/other/payments\namount:100\nbeneficiary.first_names:Oskari Olavi\nbeneficiary.iban:FI2159986920069366\nbeneficiary.name:Virtanen\nmessage:Message for receiver\noriginator.business_id:FI66554436\noriginator.iban:FI5558498520024222\noriginator.industry_class_code:4752\noriginator.name:Iban owner name\nreference:14932116599460307792\nultimate_originator.business_id:24\nultimate_originator.industrial_class_code:08\nultimate_originator.name:Korhonen Pekka Tuomas\nultimate_originator.ssn:240811-1234\n"

Public key signature

Generate a set of private and public keys.

Filename Explanation
pivo_payment_api_private.key private key which You use to sign the request
pivo_payment_api_public.key public key which You send to Us. With the public key we can verify that the request is signed correctly with the private key.

See the examples for creating keys and sending public key to Us.

$ cat cert_info
[ req ]
 default_bits           = 2048
 distinguished_name     = req_distinguished_name
 prompt                 = no

 [ req_distinguished_name ]
 C                      = FI
 O                      = Pivo Payment API


$ openssl req -pubkey -outform PEM -nodes -newkey rsa:2048 -sha1 -x509 -keyout pivo_payment_api_private.key -out pivo_payment_api_public.cert -config cert_info

$ openssl x509 -pubkey -noout -in pivo_payment_api_public.cert  > pivo_payment_api_public.key
$ cat pivo_payment_api_public.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqffh1Fga+zO1CXOSKJTi
ePww/SeAIEDrezztRYpX8NFCVdUvQ+zlezbJNPiGlxVjz/Eyi2nNfAhtOi4UXZse
ivPg95cgKCv9DTB0737Mpw/oPKDmYqmD7W/T/3TZeZWPFNjyK7OAfFvbVMbPD3Ku
0X1iPvczuYm3oU9msDj9SWdN3rUrC+JV6lzsWDvEBLqQykLenNbcuDPyihsPSr60
jE5f3CoT6Tx3egTfBhj7CjO2VtEfrsivn9qaypFOu4dzf5XWUMDrrrOveUCD4BOH
ZDOG9PWlQhVkTvWgtm7OhmqWWsVKCKDOCTHsWmAymMfYLG/6iRzNJ5oGEMZimYTI
jQIDAQAB
-----END PUBLIC KEY-----

# send public key with email to Us
cat public.key | mail -s "<Your company name> public key for pivo payment api" "jari.takalo@op.fi"

We are using the private key pivo_payment_api_public.key in examples


$ cat pivo_payment_api_private.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqffh1Fga+zO1CXOSKJTiePww/SeAIEDrezztRYpX8NFCVdUv
Q+zlezbJNPiGlxVjz/Eyi2nNfAhtOi4UXZseivPg95cgKCv9DTB0737Mpw/oPKDm
YqmD7W/T/3TZeZWPFNjyK7OAfFvbVMbPD3Ku0X1iPvczuYm3oU9msDj9SWdN3rUr
C+JV6lzsWDvEBLqQykLenNbcuDPyihsPSr60jE5f3CoT6Tx3egTfBhj7CjO2VtEf
rsivn9qaypFOu4dzf5XWUMDrrrOveUCD4BOHZDOG9PWlQhVkTvWgtm7OhmqWWsVK
CKDOCTHsWmAymMfYLG/6iRzNJ5oGEMZimYTIjQIDAQABAoIBAQCn5L1FxRY553S/
9lJ9Fby0Z+F4X+l3cslpfeCfHa4KqpqNML20qjBwyshsM8a3PSDQSmB0SDn7eFN0
8gmaAV1lQsyJpdXU+MbJnYEVBjrgF51/Li0Fbo9sHlfacrFUIcEphbeKJZEYxp/c
mVn114IKW4GN0yBb+UbT6Bv2nQTN2Mn578+uu105a++yMSvNvVVjHk7vaq88yQmI
i79tCUl/sZmIChiH52QIvrJ9UAN/yjvkgxi61RJpuxcIFsBuRAAZvpofY8T4MErU
zuwLSg+HMedIia9TvxVY25vgT6WrcQrd8QqqN2u7qaVKfAmh2F8J7LvxF7YP53A2
KnHs9GpBAoGBANtZ7rlfrfKWhJdI88jfZ9AvGPaWo3x3ohN3yp/jR6D+GQNEpc3v
Oa5w+ws0oS8QHrYjhPDEuF6aUd/QvEPZNGJO3ImYPKXub0DVVfzYmT2eRvD/0iza
1JQ3aFNZp1KzaxxJ2IPlIMG0hLbN+dmzFPmLZ0BiFMlE3FVvz+GdvRRdAoGBAMZd
vtdS7LCYN5EtylX/+g2kJT5rHrwtAIYcEpx5WS202Nunc2CsVW0Gu+dggLgC9v3b
PFg9HLd6glEygiam+WX1jOlQRADNHEE5EEb/awdUSn6TuXaucptpMCPcVA2Szmqi
yBkQDkZId7mqn1iuI3UkgUmQz4Je5bFdqMlULUHxAoGADHX4bMl1rUFFuP5o8vFW
CWqThXabRPfa2jZE6X5U1F16+EePD7rWUQWUDVfpDC5jQD+WTsMuIhmsKwXFnCkb
o7YNKzfdwiNgaJN19g4r7mcuaoRt4SRxTRY0s/901OriW9IKHbwHd1mU7HmZBvf4
ahC0ReEMgz6JMcVPTubSFfUCgYEAmJklZp/0VSXEGXsQXHg+9J+BxzLAwiIcdQ7D
gnwXjoHBEbkPmR752JWFl8k1PFmLiF5PXdIldUBZX/1rAjERSs5LSHDm33bqdYJg
cz2qKEk/xX/+/L3WjJeu4OduAcMd6AqxxBYF5St6bupDCwVrYYJjsyQjfjdim79h
SP/okQECgYBXAqtou1Y0IPCsO7OZVxm0v1bdQXwaRmmSnzMFaJMGGO4xnpfOAcjL
1nC2XJG26recgoX7wajeeJT0ByukWdf2DCjMR1waLGhJw9IJSwXUbKe4A2hHNx10
7mo94Tf+lu3zoc+UX3YqvL7YPa/8Rtv8b/FP31V1Zve1n4lHHlxkwQ==
-----END RSA PRIVATE KEY-----

Public key parameter signature signing example with ruby

  def SignatureTools.sign_pki_signature(account_id, key_id, private_key, method, path, request_id: nil, params: {}, body: nil)
    fail AuthenticationFailed, 'no account_id given' unless account_id
    fail AuthenticationFailed, "no private_key given for account: #{account_id}" unless private_key

    message_fields = message_fields(method,
                                    path,
                                    request_id: request_id,
                                    params:     params,
                                    body:       body)

    signature = private_key.sign(OpenSSL::Digest::SHA256.new,
                                 message_fields)
    signature = Base64.strict_encode64(signature)
    signature = "pk:#{account_id}/#{key_id} #{signature}"

    Rails.logger.debug { "Message: \n#{message_fields}" }
    Rails.logger.debug { "Calculated pki signature: #{signature} for\n account_id: #{account_id}\n with key id: #{key_id} \n method: #{method}\n path: #{path}\n params: #{params.to_json}\n body: #{body}\n." }

    signature
  end

    test_private_key =
      <<-END
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEAqffh1Fga+zO1CXOSKJTiePww/SeAIEDrezztRYpX8NFCVdUv
  Q+zlezbJNPiGlxVjz/Eyi2nNfAhtOi4UXZseivPg95cgKCv9DTB0737Mpw/oPKDm
  YqmD7W/T/3TZeZWPFNjyK7OAfFvbVMbPD3Ku0X1iPvczuYm3oU9msDj9SWdN3rUr
  C+JV6lzsWDvEBLqQykLenNbcuDPyihsPSr60jE5f3CoT6Tx3egTfBhj7CjO2VtEf
  rsivn9qaypFOu4dzf5XWUMDrrrOveUCD4BOHZDOG9PWlQhVkTvWgtm7OhmqWWsVK
  CKDOCTHsWmAymMfYLG/6iRzNJ5oGEMZimYTIjQIDAQABAoIBAQCn5L1FxRY553S/
  9lJ9Fby0Z+F4X+l3cslpfeCfHa4KqpqNML20qjBwyshsM8a3PSDQSmB0SDn7eFN0
  8gmaAV1lQsyJpdXU+MbJnYEVBjrgF51/Li0Fbo9sHlfacrFUIcEphbeKJZEYxp/c
  mVn114IKW4GN0yBb+UbT6Bv2nQTN2Mn578+uu105a++yMSvNvVVjHk7vaq88yQmI
  i79tCUl/sZmIChiH52QIvrJ9UAN/yjvkgxi61RJpuxcIFsBuRAAZvpofY8T4MErU
  zuwLSg+HMedIia9TvxVY25vgT6WrcQrd8QqqN2u7qaVKfAmh2F8J7LvxF7YP53A2
  KnHs9GpBAoGBANtZ7rlfrfKWhJdI88jfZ9AvGPaWo3x3ohN3yp/jR6D+GQNEpc3v
  Oa5w+ws0oS8QHrYjhPDEuF6aUd/QvEPZNGJO3ImYPKXub0DVVfzYmT2eRvD/0iza
  1JQ3aFNZp1KzaxxJ2IPlIMG0hLbN+dmzFPmLZ0BiFMlE3FVvz+GdvRRdAoGBAMZd
  vtdS7LCYN5EtylX/+g2kJT5rHrwtAIYcEpx5WS202Nunc2CsVW0Gu+dggLgC9v3b
  PFg9HLd6glEygiam+WX1jOlQRADNHEE5EEb/awdUSn6TuXaucptpMCPcVA2Szmqi
  yBkQDkZId7mqn1iuI3UkgUmQz4Je5bFdqMlULUHxAoGADHX4bMl1rUFFuP5o8vFW
  CWqThXabRPfa2jZE6X5U1F16+EePD7rWUQWUDVfpDC5jQD+WTsMuIhmsKwXFnCkb
  o7YNKzfdwiNgaJN19g4r7mcuaoRt4SRxTRY0s/901OriW9IKHbwHd1mU7HmZBvf4
  ahC0ReEMgz6JMcVPTubSFfUCgYEAmJklZp/0VSXEGXsQXHg+9J+BxzLAwiIcdQ7D
  gnwXjoHBEbkPmR752JWFl8k1PFmLiF5PXdIldUBZX/1rAjERSs5LSHDm33bqdYJg
  cz2qKEk/xX/+/L3WjJeu4OduAcMd6AqxxBYF5St6bupDCwVrYYJjsyQjfjdim79h
  SP/okQECgYBXAqtou1Y0IPCsO7OZVxm0v1bdQXwaRmmSnzMFaJMGGO4xnpfOAcjL
  1nC2XJG26recgoX7wajeeJT0ByukWdf2DCjMR1waLGhJw9IJSwXUbKe4A2hHNx10
  7mo94Tf+lu3zoc+UX3YqvL7YPa/8Rtv8b/FP31V1Zve1n4lHHlxkwQ==
  -----END RSA PRIVATE KEY-----
    END

  account_id = 'payment_api_user'
  key_id = 'ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731'
  private_key = OpenSSL::PKey::RSA.new(test_private_key)
  params = 
    {"amount"=>100,
    "reference"=>"1232",
    "message"=>"testi viesti",
    "originator.iban"=>"FI5558498520024222",
    "originator.name"=>"Ahtelaisen ahkiot ja alariippulukot",
    "originator.business_id"=>"FI66554436",
    "originator.industry_class_code"=>"4752",
    "ultimate_originator.name"=>"Virtanen Oskari Olavi",
    "ultimate_originator.ssn"=>"240811-1234",
    "ultimate_originator.business_id"=>"24",
    "ultimate_originator.industrial_class_code"=>"08",
    "beneficiary.iban"=>"FI2159986920069366",
    "beneficiary.name"=>"Virtanen",
    "beneficiary.first_names"=>"Oskari Olavi"}

    signature                  = SignatureTools.sign_pki_signature account_id,
                                                                   key_id,
                                                                   private_key,
                                                                   'POST',
                                                                   '/other/payments',
                                                                   params: params

   #  signature
   # => "pk:payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 k0CsOV/U0rxPxefEhuxyTuyvmBZCCqbDip6eN4l+UchqesCi+86XtdTirV04KEEE2B0GLVYx+SI9Ryue9sOt3xGjfAQz4ZpH5PE9xx/YKwVQ3B6Bu1bZwTVLOf5EPiAkMKgNjVSqbndIH4iBHPYjvXLmKytTs6kryJ4IOZ4DXd0vohy/paZe/TBqjDvdLcBZVNOix86RmE7rJ62y4S+FKUxNYavb0OVDEH+9LFrsMuFpQ9TQYcAQuT6St7q5qbGKcJ8PyFgJHABt8mAJMrKO45MrNUBylx7UauAW+6TB/rDQhfBnNZ2EmJc7LbjINoFah9rwwEZnZiTac0Q7IE2CKw=="

Public key header signature signing example with ruby

See the example request

    account_id = 'payment_api_user'
    key_id = 'ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731'
    private_key = OpenSSL::PKey::RSA.new(test_private_key)
    request_id = '8eb15bc6-b6fa-497d-adf4-97f067ea052f'
    payload_params  = {
                      "amount"=>100,
                      "originator"=>{:iban=>"FI5558498520024222", :name=>"Iban owner name", :business_id=>"FI66554436", :industry_class_code=>"4752"},
                      "beneficiary"=>{:iban=>"FI2159986920069366", :name=>"Virtanen", :first_names=>"Oskari Olavi"},
                      "ultimate_originator"=>{:name=>"Korhonen Pekka Tuomas", :ssn=>"240811-1234", :business_id=>"24", :industrial_class_code=>"08"},
                      "message"=>"Message for receiver",
                      "reference"=>"14932116599460307792"
                    }

    signature  = SignatureTools.sign_pki_signature account_id,
                                                 key_id,
                                                 private_key,
                                                 'POST',
                                                 '/other/payments',
                                                 request_id: request_id,
                                                 body:       payload_params.to_json

  # message_fields
  # => "POST\n/other/payments\n8eb15bc6-b6fa-497d-adf4-97f067ea052f\n{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792"}"
  # puts "#{message_fields}"
  #POST
  #/other/payments
  #8eb15bc6-b6fa-497d-adf4-97f067ea052f
  #{"amount":100,"originator":{"iban":"FI5558498520024222","name":"Iban owner name","business_id":"FI66554436","industry_class_code":"4752"},"beneficiary":{"iban":"FI2159986920069366","name":"Virtanen","first_names":"Oskari Olavi"},"ultimate_originator":{"name":"Korhonen Pekka Tuomas","ssn":"240811-1234","business_id":"24","industrial_class_code":"08"},"message":"Message for receiver","reference":"14932116599460307792"}
  #
  # signature
  # => "pk:payment_api_user/ae4c6330abae2d13d646895bc397b0030ed378d0dada0a29907c1e5ae83e0731 eUotQ2nhZRok8UNH34z8VSeLpfCWoFIwddxHvwjvttZErQk33rM5rii+nkB7ZRrpwkC/lRXymSHWAzhBThhdYwVB6Hzk77ljmFObebla8hXuaKFcqBMrG0LkkBx83BNiLVDr31VxgYqMYnyd7jluJTjKcfzCsfNssrOHb9BfhZfzD4x1Gysn8nIkkXfm9eeIgASFtHNA+jBQddon9c+D3BrwpOe3zlqz+15tzkhJ1zScrlLVKU7m0fwvmzh9RQrFVeeFKbmrxg/3BZ3j6ybeG0s+vxYFXwXCFjKZiuTfgLyGlffAfgWn5NSze3mexXsRlQw4OX970yfTCfawqyziyQ=="