Payment Gateway API

This section describes how to make standalone payments using our payment gateway.

Creating a Payment Session

For every payment you wish to make you need to create a payment session first. A payment session contains payment information such as the paid amount or merchant reference. A session represents a time window for making a payment up to 24 hours from the time of its creation.

To create a session use the newPaymentSession mutation:

Loading GraphiQL...
Payment Session Parameters

Parameter

Description

amount

The amount the customer pays in minor units. So 100,56 kr would be 10056.

currency

The currency the amount is in. If left out, it is set to the merchant’s default currency. Some payment methods are only available for certain currencies, check the corresponding payment method’s documentation.

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

merchantReference

Merchant’s own internal reference that may help the merchant in identifying this payment. These have to be globally unique but they should be reused for retrying a payment.

merchantReference2 (Optional)

An optional additonal Merchant’s own internal reference that may help the merchant in identifying this payment. No uniqueness check is enforced on these references. Can be upto 1000 characters in length.

preferredGateway (Optional)

An optional gateway value that decides which gateway to be used to process this payment. Currently the only supported value is: Kronor

message

A message to show to the customer on their payment screen. It could be an order id or a reference.

expiresAt

The latest point in time (ISO8601) that the session is usable at. Must be between 0 and 24 hours into the future.

allowExecutionDate

A boolean value, controls whether an execution date can be chosen for a payment in this session (e.g. for bank transfer payments)

additionalData (Optional)

Extra information about a customer making the payment. Fields:

  • name: Name of the customer

  • email: Email of the customer

  • ip: IP address of the customer

  • language: Language one of - SV, DA, NO, IS, EN.

  • phoneNumber (Optional): Phone number of the customer

  • shippingAddress (Optional): Shipping address of the customer. Required field for PayPal payments

    Fields:

    • title (Optional): Customer’s preferred title when addressed. One of: MISS, MR, MRS, MS

    • firstName: First name of the customer

    • lastName: Last name of the customer

    • careOf (Optional): Named intermediary

    • streetAddress: Street address first line

    • streetAddress2 (Optional): Street address second line

    • streetName (Optional): Street name. Do not combine with streetAddress

    • streetNumber (Optional): Street number. Do not combine with streetAddress

    • postalCode: Postal Code

    • city: City

    • region (Optional): State or Region

    • country: Country

    • email: Email of the customer

    • phoneNumber: Phone number of the customer

  • orderLines (Optional): A list of line items in this purchase. Sum of totalAmount of all the items should be equal to the amount field. Required field for PayPal payments

    Fields:

    • reference (Optional): Item sku or any reference that helps the merchant in identifying this item

    • itemUrl (Optional): URL to item in the merchant catalogue

    • imageUrl (Optional): URL to the image of the item in the merchant catalogue

    • pricePerItem: Price per item in minor units. Should include tax, but not discounts

    • totalAmount: Total amount of all the items in this line in minor units.

    • totalTaxAmount: Total tax amount of all the items in this line in minor units

    • totalDiscountAmount (Optional): Discount applied on all items in this line in minor units. This value should include any applicable tax

    • quantity: Number of items in this line

    • taxRate: Tax rate on the items ordered in this line

    • name: Display name of the purchased item

The token in the response can be now be used to make payments. See Authentication on how to use the token in your requests.

Avoiding Duplicate Payments

Typically, if you reuse the same payment session token across multiple attempts in combination with our payment SDKs, duplicate payments are automatically avoided. However, if you are using the payment gateway API directly or use a different payment session for each payment attempt, you need to take care of this yourself.

For this purpose, we have an additional mutation newPaymentSessionWithReferenceCheck that will check if a payment session with the same merchantReference already exists. If it does, it will return the token of the existing session. Otherwise, it will create a new one. Additionally, it will return the paymentId of any successful payment done within an existing session for the same merchantReference. This way you can avoid duplicate payments.

If the currency or amount fields are different from any existing session matching the merchantReference, it will return a new session. It is assumed that the shopping cart has changed and a different session is required.

To create a session with a merchant reference check, use the newPaymentSessionWithReferenceCheck mutation:

Loading GraphiQL...
Payment Session Parameters

Parameter

Description

amount

The amount the customer pays in minor units. So 100,56 kr would be 10056.

currency

The currency the amount is in. Some payment methods are only available for certain currencies, check the corresponding payment method’s documentation.

country

The country the money is being received.

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

merchantReference

Merchant’s own internal reference that may help the merchant in identifying this payment. This is the field that will be used for finding existing sessions.

merchantReference2 (Optional)

An optional additonal Merchant’s own internal reference that may help the merchant in identifying this payment. No uniqueness check is enforced on these references. Can be upto 1000 characters in length.

preferredGateway (Optional)

An optional gateway value that decides which gateway to be used to process this payment. Currently the only supported value is: Kronor

message

A message to show to the customer on their payment screen. It could be an order id or a reference.

expiresAt

The latest point in time (ISO8601) that the session is usable at. Must be between 0 and 24 hours into the future.

allowExecutionDate

A boolean value, controls whether an execution date can be chosen for a payment in this session (e.g. for bank transfer payments)

additionalData (Optional)

Extra information about a customer making the payment. Fields:

  • name: Name of the customer

  • email: Email of the customer

  • ip: IP address of the customer

  • language: Language one of - SV, DA, NO, IS, EN.

  • phoneNumber (Optional): Phone number of the customer

The token in the response can be now be used to make payments. See Authentication on how to use the token in your requests.

Swish

Loading GraphiQL...
Swish Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

flow

Set to "mcom" for standalone payments.

returnUrl

The url to redirect to after the payment is done.

Credit Card

Loading GraphiQL...
Credit Card Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect to after the payment is done.

MobilePay

Mobilepay is currently only supported for sessions in Danish Krone. Set the currency to "DKK" in newPaymentSession to get a token that can be used for Mobilepay.

Loading GraphiQL...
MobilePay Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect to after the payment is done.

Vipps

Vipps is only supported for sessions in Norwegian Krone. Set the currency to "NOK" in newPaymentSession to get a token that can be used for Vipps.

Loading GraphiQL...
Vipps Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect to after the payment is done.

Przelewy24

Przelewy24(P24) is currently only supported for sessions in Polish Zloty. Set the currency to PLN and country to PL when creating a payment session to get a token that can be used for P24. Note that for processing Przelewy24 payments, it is mandatory to pass additionalData.name in the newPaymentSession or newPaymentSessionWithReferenceCheck mutation when you start a payment.

Loading GraphiQL...
P24 Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect to after the payment is done.

Bank Transfer

Loading GraphiQL...
Bank Transfer Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect from the bank after the payment is done.

merchantReturnUrl

Merchant’s url to redirect to when using the payment component

aspspId

Id of the bank customer chose

requestRedirectState

State string passed in the query param of returnUrl

PayPal

PayPal is currently supported via onboarding merchants on our platform with your PayPal accounts. Note that for processing PayPal payments, it is mandatory to pass additionalData.shippingAddress and additionalData.orderLines in the newPaymentSession or newPaymentSessionWithReferenceCheck mutation when you start a payment.

Loading GraphiQL...
PayPal Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

returnUrl

The url to redirect to after the payment is done.

Once the payment is approved using the PayPal SDK or PayPal payment URL, you can capture the funds. This is handled automatically in our payment SDKs and in the backend. The mutation is provided as a way for instant payment completions if you are using the payment gateway API directly.

Loading GraphiQL...
PayPal Payment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

paymentId

The paymentId as received in the response from newPayPalPayment mutation.

Things to keep in mind

Within a payment session, when there’s already a paid or authorized payment, initiating a new payment with a different payment method will result in the waitToken of the paid or authorized payment. This way users don’t end up paying twice in the same session.

Likewise, if there’s an existing payment P1 for a payment method PM1 and there’s an attempt to create another payment P2 using the same payment method PM1 using the same parameters as P1, it will result in the waitToken of already created pending payment P1. To create a new payment, cancel the existing payment first and create another one.

Getting Payment Request Status

Regardless of the payment method, payment request status can be queried from the following endpoint. This query is useful if you want an overall view of all the payment requests and their respective statuses associated with a payment. A user may cancel the payment request or it could fail due to a mistake or a timeout and so they may attempt to make the payment again. These attempts are all part of the same session and can be queried as follows:

Loading GraphiQL...

If you are interested in only the latest payment request and its current status, you can use the following query:

Loading GraphiQL...

The response will contain status information for on-going payments associated with your API token. The data on this endpoint may be deleted after some time so do not rely on it to query payment status. Use the wait token obtained from creating the payment to find a specific payment request. After the payment is complete with a PAID or AUTHORIZED status, the resultingPaymentId field will contain the id of the resulting payment that can be used to query payment information and to generate refunds.

Payment Status Values

Status

Description

PRE_FLIGHT_CHECK

Payment is undergoing check

INITIALIZING

Payment is initialising

WAITING_FOR_PAYMENT

Payment is requested and waiting for confirmation

FLOW_COMPLETED

User has successfully completed the payment flow for a BANK_TRANSFER payment, wait for the payment to reach PAID state before shipping the order

ACCEPTED

Funds for a BANK_TRANSFER payment has been debited from the customer’s bank account, wait for the payment to reach PAID state before shipping the order

AUTHORIZED

Card payment is authorized, it will transition to PAID once all the money has been captured

PARTIALLY_CAPTURED

Some money from the payment has been captured and paid out, but not all of it

CAPTURE_DECLINED

The payment cannot be captured and is declined by the payment gateway. Any further attempts to capture are not allowed.

PAID

Payment is paid.

ERROR

Payment errored.

DECLINED

Payment was declined by the customer.

CANCELLED

Payment was cancelled.

PROCESSING

Payment is being processed.

CANCELLING

Attempting to cancel the payment.

Getting Payment Status

Regardless of the payment method, payment status can be queried from the following endpoint:

Loading GraphiQL...

The response will contain status information for all paid payments associated with your API token.

The refunds object contains a list of all refunds that have been made to this payment and their status.

In order to avoid having to poll for status we recommend that you use a GraphQL subscription to track the state of the payments over time. E.g.

Loading GraphiQL...

Payment status subscription example in React

Here’s an example of a how a client might subscribe to updates to paymentRequests in progress. Note that the protocol in the URI needs to be wss instead of https.

import React from 'react';
import ReactDOM from 'react-dom/client';

import { gql, useSubscription, ApolloClient, InMemoryCache } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';

// session token from the newPaymentSession mutation
const authToken = '...'

const client = new ApolloClient({
    link: new WebSocketLink({
      uri: 'wss://localhost:8080/v1/graphql',
      options: {
        reconnect: true,
        connectionParams: {
          headers: {
            Authorization: `Bearer ${authToken}`
          }
        }
      }
    }),
    cache: new InMemoryCache(),
  });

const GET_PAYMENT_STATUS = gql`
    subscription PaymentStatus {
      paymentRequests {
        waitToken
        amount
        status {
          status
        }
      }
    }
`;

function App() {
  const { loading, error, data } = useSubscription(GET_PAYMENT_STATUS, {
    variables: {},
    client: client
  });

  if (loading) return <p>Loading ...</p>;
  if (error) return <p>Error: {JSON.stringify(error)}</p>;
  return <h1>{JSON.stringify(data)}</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Cancelling a PaymentRequest

Sometimes you would want to cancel a payment that’s created. You can only cancel a payment when it’s in the WAITING_FOR_PAYMENT status.

Loading GraphiQL...
CancelPayment Parameters

Parameter

Description

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

paymentId

The waitToken from the response of newSwishPayment mutation.

Capturing Authorized Card Payment

In order to move a payment from the AUTHORIZED state to PAID you need to capture it. You need to use one of paymentId or paymentTransactionId to capture the payment.

Loading GraphiQL...

Capturing is an asynchronous process that takes a bit of time. In order to know when it’s done you will need to poll or subscribe to the paymentCaptures object. You can use either the captureId or captureTransactionId from the newPaymentCapture mutation to check the capture status.

Loading GraphiQL...

The capture status will begin in the CAPTURING state and hopefully progress to the CAPTURE_DONE state.

Here’s a complete list of the possible states that a paymentCapture can be in:

Possible paymentCapture statuses

Value

Description

CAPTURING

The intial state, keep polling for updates

CAPTURE_DONE

The capture is successfull

CAPTURE_COOLDOWN

The capture failed due to too many partial captures happening to the same payment within a short timeframe. This only happens with some payment providers. Please try capturing again in 24 hours.

CAPTURE_DECLINED

The capture failed due to the card being declined. In these cases, you need to contact the customer for the pending amount to pay via other means.

ERROR

Something went wrong

Release Payment

A payment that has been authorized, but not yet captured can’t be refunded. Instead it has to be released. At the moment you can only release the full amount, partial releases aren’t possible. It’s also not possible to release the remaining money after some of it has been captured.

To release a payment, use the following mutation:

Loading GraphiQL...
Refund Parameters

Parameter

Description

amount

The amount to be released in minor units. So 100,56 kr would be 10056.

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

paymentId

Id of the payment to be refunded, see resultingPaymentId in paymentRequest query.

paymentTransactionId

Transaction ID of the payment to be refunded, see transactionId in paymentRequest query. Pass one of paymentId or paymentTransactionId

createdBy

Who is creating the refund.

generatedFrom

Where is the refund being created, will default to “Portal” when creating a refund from the kronor portal.

merchantReference

An optional value that has to be unique across all releases

Getting Payment Release Status

Loading GraphiQL...
Possible Values of the currentStatus Field

Value

Description

IN_PROGRESS

The release has been registered in the Kronor system

DONE

The release has succeeded, this is the final state

ERROR

Something went wrong

The happy flow is to go from IN_PROGRESS to DONE

Refunds

A payment can be refunded in several partial refunds, until the amount refunded reaches the amount paid in a specific payment.

To issue a refund use the following mutation:

Loading GraphiQL...
Refund Parameters

Parameter

Description

amount

The amount to be refunded in minor units. So 100,56 kr would be 10056.

idempotencyKey

Idempotency key is required to prevent double processing a request. See also Idempotency keys.

paymentId

Id of the payment to be refunded, see resultingPaymentId in paymentRequest query.

paymentTransactionId

Transaction ID of the payment to be refunded, see transactionId in paymentRequest query. Pass one of paymentId or paymentTransactionId

message

A message to show to the customer for the refund.

createdBy

Who is creating the refund.

generatedFrom

Where is the refund being created, will default to “Portal” when creating a refund from the kronor portal.

merchantReference

An optional value that has to be unique across all refunds. This is intended to help prevent duplicate refunds.

Getting Refund Status

Refunds can be queried using the payment query to get a specific payment for refunds, or by using the refund status query:

Loading GraphiQL...

The response will contain status information for all refunds associated with your API token. The possible values of status are listed in the table below.

Possible Values of the Status Field

Value

Description

INITIALIZING

The refund has been registered in the Kronor system

CREATED

The refund has been registered in a third party payment system

DEBITED

A third party payment system has confirmed that the refund is debited

PAID

The refund has been paid, this is the final state

ERROR

Something went wrong

The happy flow is to go from INITIALIZING to CREATED to DEBITED to PAID. The DEBITED step is sometimes skipped.

Getting More Payment Request Details

Details related to the specific type of payment can be added to the query, e.g. transactionCreditCardDetails. If the payment wasn’t done using credit card then the fields under transactionCreditCardDetails will all be null.

These fields are not available to the payment-gateway role. Please use merchant-backend or merchant-read-only.

Loading GraphiQL...

Getting More Payment Details

Details related to the specific type of payment can be added to the query, e.g. transactionCreditCardDetails. If the payment wasn’t done using credit card then the fields under transactionCreditCardDetails will all be null.

These fields are not available to the payment-gateway role. Please use merchant-backend or merchant-read-only.

Loading GraphiQL...