Open Invoice Manual

An open invoice makes it easier for shoppers to buy products on a merchant web site:

  1. Shoppers provide some personal data, like their address and birth date.
  2. We assess whether they are eligible to receive products or services before they actually pay for them.
  3. When this scenario applies, an invoice is included with the purchased goods.
  4. Shoppers need to pay the total amount stated on the invoice by initiating a bank transfer; otherwise, they have to return the goods.
  5. If an invoice is not honored, and if the purchased goods are not duly returned, merchants can turn the invoice over to a debt collection agency.

This manual explores a number of options available in the open invoice process.

The open invoice payment method is available only in a limited number of countries.

This functionality is not enabled by default, as it requires additional configuration on Adyen's end. Contact the  Adyen Support Team to request enabling it for you.

The open invoice process offers two options to accept open invoices:

  • Adyen accepts full risk, in cooperation with an invoicing partner.
  • Adyen provides only invoice administration and communication services, in cooperation with an invoicing partner.

From now on and throughout this document, the collaboration between Adyen and an invoicing partner is referred to as Adyen.

When Adyen accepts fullrisk, the merchant receives a percentage of the transaction amount immediately after sending a capture modification.

Invoice payment processing

The invoice payment process follows this high-level workflow:

  1. The shopper provides their personal information.

  2. We verify this data against our risk check system.

  3. Goods and open invoice are delivered to the shopper.

  4. The merchant sends us a capture modification including the payment due date for the shopper.

  5. If payment is not received in time, Adyen contacts the shopper and handles the process.

  6. Even if the shopper does not honor the invoice, the funds are settled with the merchant.

The time period between capturing a payment and settling it depends on the open invoice partner the merchant chooses to work with.

Supported acquirers

Currently, we support the following open invoice partners:

 

You can implement open invoice payment method either with API or HPP integration. 

API is not currently supported for Klarna account installments and AfterPay. 

Depending on your business model our API can also be used for recurring payments (Recurring Manual) via open invoice, contact the Adyen Support Team for more information.

Audience

This manual targets developers who integrate merchants' systems with the Adyen payment platform.

Feedback

We strive to provide you with clear, concise, and complete documentation. We are committed to improving it continuously to make it accessible and easy to understand.

We appreciate your comments, and we'd love to hear your voice: drop us a line and share your thoughts with us!

  Adyen Support Team

Open invoice last update

Version

Date

Changes

4.2 2016 - 02 - 12 Added API related information in Shopper fields  and Klarna specification.

Version

Date

Changes

4.2 2016 - 02 - 12 Added API related information in Shopper fields and Klarna specification.
4.1.3 2016 - 14 - 09 Added refusal reason in Klarna specifications.
4.1.2 2012-12-09

Added new way to calculate the payment in Invoice line HPP.

4.1.1 2015-10-27

Modified a field open invoice data in Invoice line HPP.

4.1.0 2015-09-15

Introduced OpenInvoiceData.merchantData to Hold different merchant data points like product, purchase, customer and so on.

4.0 2015-05-13
  • Documentation migration from PDF to web-based online deliverable as main distributable asset.
  • Versioning: version reset and adoption of semantic versioning as per v. 4.0.0.
  • Manual redesign to improve readability, navigation, content search.

1.10

2015-03-10

Changed: modifying reference to correct external manual.

1.09

2014-12-12

  • Rectified certain field names.
  • Improved section on modifications.
  • Explanation on invoice lines separated into HPP and API integration.

1.08

2014-09-18

Changed: document layout.

1.07

2014-09-11

Added airline data.

1.06 2014-04-04
  • Added Klarna-specific requirements.
  • Added itemVATPercentage option.
  • Included and updated specific shopper details.
1.05 2014-05-13
  • Added possibility to immediately send order lines with the payment request.
  • Added signature calculation.
1.04 2010-07-28
  • Added changelog and audience sections.
  • Manual reviewed for English and layout consistency.

Provide shopper information

Submit the below-listed fields along with an API/HPP payment request.

If the optional additional data is not submitted, the shopper can enter it on the HPP. If it is submitted, it is pre-populated. The additional data to submit is:

  1. Shopper data
  2. Billing address
  3. Delivery address

 

Billing and delivery address

Name

Type

Required

Description

billingAddress

class

(tick)

A container for the billing address information.

It contains the following elements:

  • city

  • country

  • houseNumberOrName

  • postalCode

  • stateOrProvince

  • street

deliveryAddress

class

(error)

A container for the delivery address information.

Only required if the delivery address is not the same as the billing address.

It contains the following elements:

  • city

  • country

  • houseNumberOrName

  • postalCode

  • stateOrProvince

  • street

city

String

(tick)

Name of the city.

country

String

(tick)

The country identifier. 

The country value format needs to adhere to the ISO 3166-1 alpha-2 standard. 
An invalid country code results in a transaction/request rejection. 
You can look up country codes on the ISO web site.

houseNumberOrName

String

(tick)

House number, or house name, or other house identifier.

postalCode

String

(tick)

Zip/Post code.

stateOrProvince

String

(error)

Name of the state, region or province, where applicable.

street

String

(tick)

Name of the street.

Shopper Data

When you send an open invoice payment request, you always need to include the following additional shopper data fields:

Name

Type

Required

Description

selectedBrand

String

(tick)
  • For Klarna set the value to klarna.

  • For RatePay set the value to ratepay.

shopperEmail

String

(tick)

The shopper's email address.

shopperReference

String

(tick)

An ID that uniquely refers to the shopper (e.g. a customer ID in a shopping cart system).

deviceFingerprint

String

(error)

Required for RatePay only. Contact Adyen Support Team for instructions on how to generate the device fingerprint.

These fields should always be included.

Name

Type

Required

Description

shopperName

class

(tick)

A container for the shopper information.

It contains the following elements:

  • firstName

  • infix

  • lastName

  • gender

firstName

String

(tick)

The first name of the shopper.

infix

String

(tick)

The infix of the shopper name.

lastName

String

(tick)

The last name of the shopper.

gender

String

(tick)

The gender of the shopper.

Value must be MALE or FEMALE.

dateOfBirth

String

(tick)

A shopper's date of birth. Format: yyyy-MM-dd

telephoneNumber

String

(tick)

The telephone number of the shopper.

socialSecurityNumber

String

(error)

The social security number of the shopper.

Required for Sweden, Finland, Norway and Denmark.

Code example:

JSON
{
   "merchantAccount":"TestMerchant",
   "amount":{
      "currency":"SEK",
      "value":"10000"
   },
   "selectedBrand":"klarna",
   "shopperEmail":"youremail@email.com",
   "shopperReference":"14411521",
   "shopperIP":"69.89.31.226",
   "reference":"Test invoice",
   "shopperName":{
      "firstName":"Testperson-se",
      "lastName":"Approved",
      "gender":"MALE"
   },
   "dateOfBirth":"1941-03-21",
   "telephoneNumber":"0765260000",
   "socialSecurityNumber":"9202",
   "billingAddress":{
      "country":"SE",
      "city":"Ankeborg",
      "houseNumberOrName":"1",
      "street":"Stargatan",
      "postalCode":"12345"
   },
   "deliveryAddress":{
      "country":"SE",
      "city":"Ankeborg",
      "houseNumberOrName":"1",
      "street":"Stargatan",
      "postalCode":"12345"
   },
   "additionalData":{
      "openinvoicedata.numberOfLines":"2",
      "openinvoicedata.line1.currencyCode":"SEK",
      "openinvoicedata.line1.description":"item 1",
      "openinvoicedata.line1.itemAmount":"3000",
      "openinvoicedata.line1.itemVatAmount":"0",
      "openinvoicedata.line1.itemVatPercentage":"0",
      "openinvoicedata.line1.numberOfItems":"1",
      "openinvoicedata.line1.vatCategory":"None",
      "openinvoicedata.line2.currencyCode":"SEK",
      "openinvoicedata.line2.description":"item 2",
      "openinvoicedata.line2.itemAmount":"5882",
      "openinvoicedata.line2.numberOfItems":"1",
      "openinvoicedata.line2.itemVatPercentage":"1900",
      "openinvoicedata.line2.itemVatAmount":"1118",
      "openinvoicedata.line2.vatCategory":"High",
      "openinvoicedata.merchantData":"ZXh0cmEgZGF0YSBoZXJl"
   }
}

Billing and delivery address

Name Type Required Description
billingAddress class (tick) A container for the billing address information.

It contains the following elements:

  • city
  • country
  • houseNumberOrName
  • postalCode
  • stateOrProvince
  • street

billingAddressType

String (error)

Specifies whether the shopper is allowed to view and/or modify the billing address fields.

If the field is supplied, the billingAddressType field is part of the merchant signature.

It can have the following values:

  • 1: the billing address fields are visible but unmodifiable.
  • 2: the billing address fields are not visible, thus fields will be unmodifiable.
  • Not supplied: the billing address fields are visible and modifiable.
deliveryAddress class (tick) A container for the delivery address information.

It contains the following elements:

  • city
  • country
  • houseNumberOrName
  • postalCode
  • stateOrProvince
  • street
deliveryAddressType String (error)

Specifies whether the shopper is allowed to view and/or modify delivery address fields.

It can have the following values:

  • 1: the delivery address fields are visible but unmodifiable.
  • 2: the delivery address fields are not visible, thus fields will be unmodifiable.
  • Not supplied: the delivery address fields are visible and modifiable.

If the field is supplied, the deliveryAddressType field is is part of the merchant signature.

city String (tick) Name of the city.
country String (tick)

The country identifier. 

The country value format needs to adhere to the ISO 3166-1 alpha-2 standard. An invalid country code results in a transaction/request rejection. You can look up country codes on the ISO web site.

houseNumberOrName String (tick) House number, or house name,or other house identifier.
postalCode String (tick) Zip/Post code.
stateOrProvince String (tick) Name of the state, region or province, where applicable.
street String (tick) Name of the street.

Shopper data

When you send an open invoice payment request, you always need to include the following additional shopper data fields:

Name Type Required Description
shopperEmail String (tick) The shopper's email address.
shopperReference String (tick) An ID that uniquely refers to the shopper (e.g. a customer ID in a shopping cart system).

If you submit the following fields along with the open invoice payment request, they are pre-populated for the shopper.

Otherwise, the shopper needs to fill them in on the HPP:

Name Type Required Description
shopper class (tick) A container for the shopper information.

It contains the following elements:

  • firstName
  • infix
  • lastName
  • gender
  • dateOfBirthDayOfMonth
  • dateOfBirtMonth
  • dateOfBirthYear
  • telephoneNumber
  • socialSecurityNumber

firstName

String (tick)

Thefirstnameoftheshopper.

infix

String (tick)

Theinfixoftheshoppersname.

lastName

String (tick)

Thelastnameoftheshopper.

gender

String (tick)

The gender of the shopper.

ValuemustbeMALE or FEMALE.

dateOfBirthDayOfMonth

String (tick)

The day value of the date of birth of the shopper.

dateOfBirthMonth

String (tick)

The month value of the date of birth of the shopper.

dateOfBirthYear

String (tick)

The year value of the date of birth of the shopper.

telephoneNumber

String (tick)

Thetelephonenumberoftheshopper

shopperType

String (error)

Specifies whether the shopper is allowed to view and/or modify the shopper fields.

It can have the following values:

  • 1: the shopper fields are visible but unmodifiable.
  • 2: the shopper fields are not visible, thus fields will be unmodifiable.
  • Not supplied: the shopper fields are visible and modifiable.

socialSecurityNumber

String

(error)

The social security number of the shopper.

Required for Sweden, Finland, Norway and Denmark.

Provide airline data

When you send an open invoice payment request to the HPP, you can include airline data. These fields can be pre-populated together with the payment request, before sending them to the HPP. In our HPP manual, you can see an example on how you can populate airline data and calculate the signature.

Parent Child
airline  












agency_invoice_number

agency_plan_name

airline_code

customer_reference_number

boarding_fee

passenger_name

ticket_issue_address

ticket_number

travel_agency_code

travel_agency_name
flight_date
airline_designator_code

passenger

leg

airline.passenger  
 

first_name

last_name

traveller_type

date_of_birth
phone_number
airline.leg  
 

carrier_code

class_of_travel

date_of_travel

depart_airport

depart_tax

destination_code

fare_base_code

flight_number

stop_over_code

Airline fields

Parent container object for airline data fields: airline

Name Type Required Description Notes
passenger_name
String (error)

Passenger name, initials and title name.

 

  • Format: last name + first name or initials + title
    Example: EARHART/AMELIA MARY MS.
  • minLength: 1
  • maxLength: 49
customer_reference_number String (error)

Reference number; alphanumeric.

 

  • minLength: 0
  • maxLength: 20
ticket_issue_address String (error) Addres of the place/agency that issued the ticket.
  • minLength: 0
  • maxLength: 16
airline_code String (error)

IATA 3-digit accounting code (PAX); numeric.

It identifies the carrier.

  • Format: IATA 3-digit accounting code (PAX)
    Example.: KLM = 074
  • minLength: 3
  • maxLength: 3
airline_designator_code String (error)

IATA 2-letter accounting code (PAX); alphabetical.

It identifies the carrier.
  • Format: IATA 2-letter airline code
    Example.: KLM = KL
  • minLength: 2
  • maxLength: 2
ticket_number String (error) The ticket's unique identifier.
  • minLength: 1
  • maxLength: 150
travel_agency_code String (error)

IATA number, also ARC number or ARC/IATA number.

Unique identifier number for travel agencies.

  • minLength: 1
  • maxLength: 8
travel_agency_name String (error) The name of the travel agency.
  • minLength: 1
  • maxLength: 25
agency_plan_name String (error) 2-letter agency plan identifier; alphabetical.
  • minLength: 2
  • maxLength: 2
agency_invoice_number String (error) Reference number for the invoice, issued by the agency.
  • minLength: 1
  • maxLength: 6
flight_date String (error)

Flight departure date.

Local time (HH:mm) is optonal.

  • Date format: yyyy-MM-dd
  • Date and time format: yyyy-MM-dd HH:mm
  • minLength: 10
  • maxLength: 16
boarding_fee String (error)

Chargeable amount for boarding the plane.

The transaction amount needs to be represented in minor units according to the Currency codes table. Some currencies do not have decimal points, such as JPY, and some have 3 decimal points, such as BHD. For example, 10 GBP is submitted as 1000, whereas 10 JPY is submitted as 10.

  • minLength: 1
  • maxLength: 18

Airline leg fields

Parent container object for airline leg data fields: airline.leg<legNr.>

Name Type Required Description Notes
depart_airport String (error)

Alphabetical identifier of the departure airport.
This field is required/mandatory if the airline data includes leg details.

 

  • Format: IATA 3-letter airport code.
    Example: Amsterdam = AMS
  • minLength: 3
  • maxLength: 3
flight_number String (error) The flight identifier.
  • minLength: 1
  • maxLength: 5
carrier_code String (error)

IATA 2-letter accounting code (PAX); alphabetical.
It identifies the carrier.
This field is required/mandatory if the airline data includes leg details.

 

  • Format: IATA 2-letter airline code
    Example.: KLM = KL
  • minLength: 2
  • maxLength: 2
fare_base_code String (error) Fare basis code; alphanumeric.
  • minLength: 1
  • maxLength: 7
class_of_travel String (error)

1-letter travel class identifier; alphabetical.

There is no standard; however, the following codes are used rather consistently:

  • F: first class
  • J: business class
  • Y: economy class
  • W: premium economy
  • minLength: 1
  • maxLength: 1
stop_over_code String (error)

1-letter code that indicates whether the passenger is entitled to make a stopover.

Only two types of characters are allowed:

  • O: Stopover allowed
  • X: Stopover not allowed
  • minLength: 1
  • maxLength: 1
destination_code String (error)

Alphabetical identifier of the destination/arrival airport.
This field is required/mandatory if the airline data includes leg details.

 

  • Format: IATA 3-letter airport code.
    Example: Amsterdam = AMS
  • minLength: 3
  • maxLength: 3
date_of_travel

String

(error) Date and time of travel.
ISO 8601-compliant.
  • Format: yyyy-MM-dd HH:mm
  • minLength: 16
  • maxLength: 16
depart_tax

String

(error)

Departure tax. Amount charged by a country to an individual upon their leaving.

The transaction amount needs to be represented in minor units according to the Currency codes table. Some currencies do not have decimal points, such as JPY, and some have 3 decimal points, such as BHD. For example, 10 GBP is submitted as 1000, whereas 10 JPY is submitted as 10.

  • minLength: 1
  • maxLength: 12

Airline passenger fields

Parent container object for airline passenger data fields: airline.passenger<passengerNr.>

Name Type Required Description Notes
first_name String (error)

Passenger first name/given name.
This field is required/mandatory if the airline data includes passenger details.

 

This field does not have a max. character length constraint. However:
  • passenger_name cannot be longer than 49 character.
  • Most acquirers truncate this field at ~40 characters, sometimes even at ~30 characters.

Therefore, it's advisable to keep this field length within the recommended maxLength value.

  • minLength: 1
  • maxLength: ~20
last_name String (error)

Passenger last name/family name.
This field is required/mandatory if the airline data includes passenger details.

 

This field does not have a max. character length constraint. However:
  • passenger_name cannot be longer than 49 character.
  • Most acquirers truncate this field at ~40 characters, sometimes even at ~30 characters.

Therefore, it's advisable to keep this field length within the recommended maxLength value.

  • minLength: 1
  • maxLength: ~20
traveller_type String (error)

Passenger type code (PTC).

IATA PTC values are 3-letter alphabetical. Example: ADT, SRC, CNN, INS.

However, several carriers use non-standard codes that can be up to 5 alphanumeric characters.

  • minLength: 3
  • maxLength: 6
telephone_number String (error) Telephone number of the passenger, including country code. This is an alphanumeric field that can include the '+' and '-' signs.
  • minLength: 3
  • maxLength: 30
date_of_birth String (error) Date of birth of the passenger.
  • Date format: yyyy-MM-dd
  • minLength: 10
  • maxLength: 10

Invoice line specification

Klarna and AfterPay require merchants to send a detail specification of the items shoppers purchase.

To do this, submit invoice lines including the details about each purchased item.

You can submit invoice line specifications through an API call or via the HPP solution:

  • Invoice line specification through the API: you need to implement a dedicated service that Adyen can call to retrieve invoice lines.
  • Invoice line specification through the HPP solution: you send the invoice line specification along with the corresponding payment request.

    We recommend sending invoice lines through HPP because it is easier to implement.

If you do not immediately send the invoice detail specification, our system can make a SOAP call to your server to retrieve them: after the shopper sends the payment request from the HPP to the open invoice acquirer, Adyen makes a callback to a web service hosted by the merchant to request the order line specification of the invoice.

Your SOAP server needs to implement the WSDL file provided through the following URLs:

Test open invoice WSDL

https://ca-test.adyen.com/ca/services/OpenInvoiceDetail?wsdl

Live open invoice WSDL

https://ca-live.adyen.com/ca/services/OpenInvoiceDetail?wsdl

 

The order line specification SOAP service needs to be available during the entire lifecycle of a payment because it may be necessary to access this information at different stages of a transaction, for example when capturing a payment or in case of a refund.

Currently, the URL of your order line specification SOAP service needs to be configured by the Adyen Support Team with the necessary information so they can set it up for you.

Line specification request by Adyen

The line specification request contains the following fields:

Name Type Required Description
merchantAccount String (tick)
The merchant account identifier you want to process the (transaction) request with.

amount

String (tick)

A container object for the payable amount information for the transaction.

It contains the following elements:

  • currency
  • value

currency String (tick)
The three-character ISO currency code.
value int (tick)
The payable amount that can be charged for the transaction, in minor units.

reference

String (tick)

The original reference the merchant specifies when initiating a payment.

Example

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <ns1:retrieveDetail xmlns:ns1="http://openinvoice.services.adyen.com">
       <ns1:request>
         <amount xmlns:ns1="http://openinvoice.services.adyen.com">
           <currency xmlns="http://common.services.adyen.com">EUR</currency>
           <value xmlns="http://common.services.adyen.com">1950</value>
         </amount>
         <merchantAccount xmlns:ns1="http://openinvoice.services.adyen.com">TestMerchant</merchantAccount>
         <reference xmlns:ns1="http://openinvoice.services.adyen.com">TheMerchantReference</reference>
       </ns1:request>
     </ns1:retrieveDetail> 
  </soap:Body>
</soap:Envelope>

Line specification response from the merchant

The line specification response contains the following fields:

Name Type Required Description
lines class (tick)

A container for all invoiceLines.

invoiceLine

class (tick)

A container for the information about individual invoice lines.

It contains the following elements:

  • currency
  • description
  • itemPrice
  • itemVAT
  • itemVATPercentage
  • lineReference
  • numberOfItems
  • vatCategory
currency String (tick)

The currency used to charge for the product.
It must be the same on all invoice lines.

description String (tick)

A text description of the product the invoice line refers to.

itemPrice

int
(long)

(tick)

The price for one item in the invoice line, represented in minor units.

This amount is exclusive of VAT. 

itemVAT

int
(long)

(tick)

The VAT due for one item in the invoice line, represented in minor units.

itemVATPercentage

int
(long)

(tick)

The VAT percentage for one item in the invoice line, represented in minor units. For example, 19% VAT should be specified as 1900.

lineReference Integer (tick)

Every line item need to start with a lineReference. It's a control number which always starts with 1, and is increased with 1 for every new line you add.

numberOfItems int (tick)

The number of units purchased of a specific product.

vatCategory enum (tick)

The country-specific VAT category a product falls under. Allowed values:

  • High
  • Low
  • None

Example

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soap:Body>
  <ns1:retrieveDetailResponse xmlns:ns1="http://openinvoice.services.adyen.com">
      <ns1:result>
        <lines xmlns="http://openinvoice.services.adyen.com">
          <InvoiceLine>
            <currency>EUR</currency>
            <description>Product 1</description>
            <itemPrice>325</itemPrice>
            <itemVAT>75</itemVAT>
            <lineReference>1</lineReference>
            <numberOfItems>4</numberOfItems>
            <vatCategory>High</vatCategory>
          </InvoiceLine>
          <InvoiceLine>
            <currency>EUR</currency>
            <description>Product 2</description>
            <itemPrice>350</itemPrice>
            <itemVAT>0</itemVAT>
            <lineReference>2</lineReference>
            <numberOfItems>1</numberOfItems>
            <vatCategory>None</vatCategory>
          </InvoiceLine>
        </lines>
      </ns1:result>
    </ns1:retrieveDetailResponse>
 </soap:Body>
</soap:Envelope>

Calculate total amounts

The merchant's open invoice detail service should respond with the invoice lines corresponding to the specified reference, i.e. the reference originally included in the initial payment request.

The total amount in the line specification response has to match the amount included in the line specification request. To calculate the total amount of the invoice lines, you can refer to the following pseudo-code:

value = 0;

for each (InvoiceLine in lines) {
  value += (itemPrice + itemVAT) * numberOfItems;
}

totalValue = value;

In the request and response code examples, the requested amount (EUR 19,50) matches the total amount of the invoice lines in the response:

(325 + 75) * 4 = 1600
(350 +  0) * 1 = 350
Total: 1600 + 350 = 1950

For HPP, all invoice lines have to be sent as part of the initial payment request. All invoice lines have to be part of the additional data container.

After submitting the invoice lines together with the payments, you do not need submit them again when making payment modifications.
Name Type Required Description
openinvoicedata class (tick) A container for all open invoice lines address information.

It contains the following elements:

  • numberOfLines
  • refundDescription
  • sig
  • line<lineNr.>
  • merchantData
numberOfLines int (tick)

The number of invoice lines included in openInvoiceData.

There needs to be at least one line, so numberOfLines needs to be at least 1.

refundDescription String  

The refund/correction description, usually specified with the merchant reference.

sig String (tick)

The open invoice signature for openInvoiceData.

The signature is calculated using all of the invoice line items names sorted alphabetically and separated by a colon (:), and then by connecting them with a pipe character (|) to all the remaining values that are still separated by a colon (see our GitHub repository for code examples).

line<lineNr.> class (tick) A container for a specific line.
The <lineNr.> placeholder is replaced with an integer that increments by one unit.

It contains the following elements:

  • currencyCode
  • description
  • itemAmount
  • itemVatAmount
  • itemVatPercentage
  • lineReference
  • numberOfItems
  • vatCategory

currencyCode

String (tick)

The three-character ISO currency code.

description String (tick)

A text description of the product the invoice line refers to.

itemAmount int
(long)
(tick)

The price for one item in the invoice line, represented in minor units.

The due amount for the item, VAT excluded.

itemVatAmount

int
(long)

(tick)

The VAT due for one item in the invoice line, represented in minor units.

itemVatPercentage

int
(long)

(tick) The VAT percentage for one item in the invoice line, represented in minor units.
For example, 19% VAT is specified as 1900.
lineReference String (tick)

A control number starting at 1 at the first line and summing up to the total number of lines (items are displayed in this order).

numberOfItems int (tick)

The number of units purchased of a specific product.

vatCategory enum (tick)

The country-specific VAT category a product falls under.
Allowed values:

  • High
  • Low
  • None
merchantData String (error)

Holds different merchant data points like product, purchase, customer and so on.
It takes data in a
Base64 encoded string.

merchantData needs to be added to the openInvoiceData signature at the end.

Since the field is optional, if it's not included it does not impact computing the merchant signature.

Applies only to Klarna.

You can contact Klarna for the format and structure of the string.


Example

<input type="hidden" name="merchantSig" value="Or3eSxF4/+f0Gfckma3/3wAqt7m=" />
<!-- Invoice Line Specification -->
<input type="hidden" name="openinvoicedata.numberOfLines" value="2" />
<input type="hidden" name="openinvoicedata.refundDescription" value="Refund for testReference" />
<input type="hidden" name="openinvoicedata.line1.numberOfItems" value="1" />
<input type="hidden" name="openinvoicedata.line1.itemAmount" value="3500" />
<input type="hidden" name="openinvoicedata.line1.currencyCode" value="EUR" />
<input type="hidden" name="openinvoicedata.line1.itemVatAmount" value="665" />
<input type="hidden" name="openinvoicedata.line1.itemVatPercentage" value="1900" />
<input type="hidden" name="openinvoicedata.line1.vatCategory" value="High" />
<input type="hidden" name="openinvoicedata.line1.description" value="Description 1" />
<input type="hidden" name="openinvoicedata.line2.numberOfItems" value="1" />
<input type="hidden" name="openinvoicedata.line2.itemAmount" value="2100" />
<input type="hidden" name="openinvoicedata.line2.currencyCode" value="EUR" />
<input type="hidden" name="openinvoicedata.line2.itemVatAmount" value="399" />
<input type="hidden" name="openinvoicedata.line2.itemVatPercentage" value="1900" />
<input type="hidden" name="openinvoicedata.line2.vatCategory" value="Low" />
<input type="hidden" name="openinvoicedata.line2.description" value="Description 2" />
<!-- openinvoicedata.merchantData needs to be added to the openInvoiceData signature at the end. -->
<input type="hidden" name="openinvoicedata.merchantData" value="Base64 encoded merchant data" />

Calculate the open invoice data signature

You can calculate the invoice data signature using SHA 256 key.

For more info, see HPP HMAC calculation.

While choosing the algorithm to calculate the signature, ensure that your skin supports it.

String to calculate the signature:

<?php
/*
This PHP code provides a payment form for the Adyen Hosted Payment Pages
*/
/*
account details
$skinCode:        the skin to be used
$merchantAccount: the merchant account we want to process this payment with.
$sharedSecret:    the shared HMAC key.
*/
$skinCode        = "[skin code e.g. GBIMwmE4]";
$merchantAccount = "[merchant Account e.g. TestCompanyCOM]";
$hmacKey         = "[HMAC key e.g. D21EB2ASD44BA234C8A0AF13CF0BCACA3D4727C6162630D712C857124B213270]";

/*
payment-specific details
*/
$params = array(
    "merchantReference" => "SKINTEST-1435226439255",
    "merchantAccount" => $merchantAccount,
    "currencyCode" => "EUR",
    "paymentAmount" => "199",
    "sessionValidity" => "2015-12-25T10:31:06Z",
    "shipBeforeDate" => "2015-07-01",
    "shopperLocale" => "en_GB",
    "skinCode" => $skinCode,
    "brandCode" => "klarna",
    "shopperEmail" => "test@adyen.com",
    "shopperReference" => "123",
    "shopperIP" => "62.128.7.69",
    
    // Shopper information
    "shopper.firstName" => "Testperson-nl",
    "shopper.infix" => "",
    "shopper.lastName" => "Approved",
    "shopper.dateOfBirthDayOfMonth" => "10",
    "shopper.dateOfBirthMonth" => "07",
    "shopper.dateOfBirthYear" => "1970",
    "shopper.gender" => "MALE",
    "shopper.telephoneNumber" => "0104691602",
    "shopperType" => "1",
    
    // Billing Address fields (used for AVS checks)
    "billingAddress.street" => "Neherkade",
    "billingAddress.houseNumberOrName" => "1",
    "billingAddress.city" => "Gravenhage",
    "billingAddress.postalCode" => "2521VA",
    "billingAddress.stateOrProvince" => "NH",
    "billingAddress.country" => "NL",
    "billingAddressType" => "1",
    
    // Delivery/Shipping Address fields
    "deliveryAddress.street" => "Neherkade",
    "deliveryAddress.houseNumberOrName" => "1",
    "deliveryAddress.city" => "Gravenhage",
    "deliveryAddress.postalCode" => "2521VA",
    "deliveryAddress.stateOrProvince" => "NH",
    "deliveryAddress.country" => "NL",
    "deliveryAddressType" => "1",
    
    // Invoice lines for Open Invoice payment methods such as Klarna and Afterpay
    "openinvoicedata.numberOfLines" => "4",
    "openinvoicedata.refundDescription" => "test data",
    
    "openinvoicedata.line1.currencyCode" => "EUR",
    "openinvoicedata.line1.description" => "Courgette",
    "openinvoicedata.line1.itemAmount" => "5876",
    "openinvoicedata.line1.itemVatAmount" => "1117",
    "openinvoicedata.line1.itemVatPercentage" => "1900",
    "openinvoicedata.line1.numberOfItems" => "1",
    "openinvoicedata.line1.vatCategory" => "High",
    
    "openinvoicedata.line2.currencyCode" => "EUR",
    "openinvoicedata.line2.description" => "Onions",
    "openinvoicedata.line2.itemVatPercentage" => "1900",
    "openinvoicedata.line2.numberOfItems" => "1",
    "openinvoicedata.line2.itemAmount" => "2500",
    "openinvoicedata.line2.itemVatAmount" => "650",
    "openinvoicedata.line2.vatCategory" => "High",
    
    "openinvoicedata.line3.currencyCode" => "EUR",
    "openinvoicedata.line3.description" => "Watermelons",
    "openinvoicedata.line3.itemVatPercentage" => "1900",
    "openinvoicedata.line3.numberOfItems" => "1",
    "openinvoicedata.line3.itemAmount" => "5500",
    "openinvoicedata.line3.itemVatAmount" => "650",
    "openinvoicedata.line3.vatCategory" => "High",
    
    "openinvoicedata.line4.currencyCode" => "EUR",
    "openinvoicedata.line4.description" => "Steak",
    "openinvoicedata.line4.itemVatPercentage" => "1900",
    "openinvoicedata.line4.numberOfItems" => "1",
    "openinvoicedata.line4.itemAmount" => "2500",
    "openinvoicedata.line4.itemVatAmount" => "650",
    "openinvoicedata.line4.vatCategory" => "High"
);
/*
process fields
*/
// The character escape function
$escapeval = function($val)
{
    return str_replace(':', '\\:', str_replace('\\', '\\\\', $val));
};
// Sort the array by key using SORT_STRING order
ksort($params, SORT_STRING);
// Generate the signing data string
$signData = implode(":", array_map($escapeval, array_merge(array_keys($params), array_values($params))));
// base64-encode the binary result of the HMAC computation
$merchantSig           = base64_encode(hash_hmac('sha256', $signData, pack("H*", $hmacKey), true));
$params["merchantSig"] = $merchantSig;
?>

<!-- Complete submission form -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Adyen Payment</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<form name="adyenForm" action="https://test.adyen.com/hpp/select.shtml" method="post">
<?php
foreach ($params as $key => $value) {
    echo '        <input type="hidden" name="' . htmlspecialchars($key, ENT_COMPAT | ENT_HTML401, 'UTF-8') . '" value="' . htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, 'UTF-8') . '" />' . "\n";
}
?>
<input type="submit" value="Submit" />
</form>
</body>
</html>

The resulting calculated SHA-256 signature:

T19bd9oCj3aau4vHYKudOc2iCDcD9ueH9YLhhoLIqKQ=

 

Open invoice modifications

Modification on open invoices can be submitted as normal payment modifications requests. However, there are few considerations that have to be taken into account when performing them.

Capture modifications

When the transaction is authorised, and the goods are sent/delivered to the shopper, a capture modification must be submitted to Adyen. This modification triggers the invoice to be sent to the shopper.

When performing a manual capture:

  1. Capture the full amount of the authorised payment.

  2. Capture a partial amount of the authorised payment.

    This functionality is not enabled by default, as it requires additional configuration on Adyen's end. Contact the  Adyen Support Team to request enabling it for you.

It is not possible to do partial captures if there is only one invoice line.

In case you have not submitted the invoice lines together with the payment request, then a call is done to the merchant's open invoice detail service to retrieve them. The amount in the request is equal to the amount that is requested for capturing.

There is no auto-capture for open invoice payments by default; you need to manually submit a capture modification. However, Adyen can configure auto-capture for open invoice payments for your account: contact the Adyen Support Team to request implementing this feature.

Other modifications

Depending on the selected open-invoicing partner there are several modifications applicable on a open invoice transaction:

  • Cancel

    Cancels the payment before money is collected. This needs to be sent pre-capture.

  • Refund

    If the money is already collected but the shopper should be credited, a refund can be submitted to refund (part of) the transaction amount. For example, when the shopper returns (part of) his order.

    Similar as with captures, if you have not submitted the invoice lines together with the payment request, a call is done to the Merchants Open Invoice Details Service. The amount in the request is equal to the amount that is requested for refund, but in this case negative.

Examples

 

Request:

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <ns1:retrieveDetail xmlns:ns1="http://openinvoice.services.adyen.com">
      <ns1:request>
        <amount xmlns:ns1="http://openinvoice.services.adyen.com">
          <currency xmlns="http://common.services.adyen.com">EUR</currency>
          <value xmlns="http://common.services.adyen.com">-350</value>
        </amount>
        <merchantAccount xmlns:ns1="http://openinvoice.services.adyen.com">YourMerchantAccount</merchantAccount>
        <reference xmlns:ns1="http://openinvoice.services.adyen.com">TheMerchantReference</reference>
      </ns1:request>
    </ns1:retrieveDetail> 
  </soap:Body>
</soap:Envelope>

Response:

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <ns1:retrieveDetailResponse xmlns:ns1="http://openinvoice.services.adyen.com">
      <ns1:result>
        <lines xmlns="http://openinvoice.services.adyen.com">
          <InvoiceLine>
            <currency>EUR</currency>
            <description>Product 2</description>
            <itemPrice>350</itemPrice>
            <itemVAT>0</itemVAT>
            <lineReference>1</lineReference>
            <numberOfItems>-1</numberOfItems>
            <vatCategory>None</vatCategory>
          </InvoiceLine>
        </lines>
      </ns1:result>
    </ns1:retrieveDetailResponse>
  </soap:Body>
</soap:Envelope>

Klarna specifications

Open invoice through Klarna has the following additional requirements:

  1. It is recommended that the billing and delivery address to always match and It should not be possible to modify billing/delivery address or shopper details on the HPP. Therefore, the following fields you send to the HPP with your payment request need to be set to either 1 (values are displayed on HPP) or 2 (values are not shown on HPP):

    • billingAddressType

    • deliveryAddressType

    • shopperType

Klarna requires linking to merchant specific URLs on the HPP and to your own checkout page in case of API. You can adjust these links yourself by editing the value klarna.more_information and klarna.privacy_policy in the language files of each skin. 

The default value for klarna.more_information is:

<a href="{0}" onclick="return wopen(this,600,450)">More information</a>

You can define the specific URL you are receiving from Klarna by exchanging the {0} parameter. 

Different shipping and billing addresses are not possible in Sweden by default. To allow this go to your Skin → Edit → Payment Methods → Klarna Invoice → enable Enable different shipping and billing addresses in SE and cilck Save.

You have to adjust this value in all locales you are offering. For more info see Extra options in the skin.

To receive the Klarna specific refused reason codes:

  • HPP - Go to your Skin -> Edit -> Payment Methods -> Klarna Invoice and enable Include refusal reason in result url and click Save.
  • API - The reason codes are returned in additionalData.refusalReasonRaw.

It is possible that the shows a Pending status; AuthResult:PENDING for HPP; resultCode:Received for API, in case there is need for additional risk checks by Klarna.