Search docs

Are you looking for test card numbers?

Would you like to contact support?

Start searching Adyen's documentation...

  Documentation

Klarna, AfterPay and RatePay open invoice

For information about a newer integration with Klarna, refer to our new Klarna documentation instead.

With open invoice payment methods such as Klarna, AfterPay, or RatePAY, the shopper pays after the goods have been delivered, while you get paid at the time of the purchase.

When making an open invoice payment, you need to: 

  1. Provide shopper information. This is used by the open invoice partner (Klarna, AfterPay, or RatePAY) to perform risk checks on the shopper before authorising the payment. 
  2. Provide price and product information about the purchased items. This will be included on the invoice sent to the shopper.
  3. Capture the payment after the goods have been sent. This triggers the invoice to be sent to the shopper. 

    Open invoice payments need to be captured manually, even if you have enabled automatic capture for other payment methods. If you want to enable automatic capture for open invoice payment methods, contact our Support Team.

You will receive the funds even if the shopper did not honor the invoice. Chargebacks can only occur if you didn't comply with the regulations of the open invoice partner, for example if you didn't ship the goods on time. For more information about these regulations, contact our Support Team.

When using our classic integration, you can accept Klarna, AfterPay, and RatePAY payments with our Hosted Payment Pages (HPP) integration. To accept AfterPay and RatePAY, you can also use our direct API integration

Step 1: Make an open invoice payment

In your payment request, provide: 

  • shopperEmail
  • shopperReference
  • additionalData.openinvoicedata: Price and product information to be included on the invoice sent to the shopper. For more information, refer to Invoice lines

Additional required fields depend on whether you are using HPP or API.

HPP integration specific fields

When using our HPP integration you can optionally provide the following fields. If you don't include these fields, the shopper will need to enter this information manually in the HPP. 

  • shopper.dateOfBirthDayOfMonth: For more information, refer to Shopper fields.

  • shopper.dateOfBirthMonth
  • shopper.dateOfBirthYear
  • shopper.telephoneNumber
  • socialSecurityNumber – required for Sweden, Finland, Norway, and Denmark. Provide either the last four digits, or the full social security number. For more information, refer to Open Invoice fields
  • billingAddress – This object contains billing address details. For more information, see Address.
  • deliveryAddress – only required if the delivery address is not the same as the billing address. This object contains delivery address details. For more information, see Address.

To specify what should be shown to the shopper, use the following fields: 

  • shopperType – Specifies whether the shopper is allowed to view and/or modify the billing address fields. For more information, refer to Shopper fields.
  • billingAddressType – Specifies whether the shopper is allowed to view and/or modify the billing address fields. For more information, refer to Billing address and AVS fields.
  • deliveryAddressType – Specifies whether the shopper is allowed to view and/or modify the delivery address fields. For more information, refer to Risk fields.

Klarna payment request: 

<html> 
  <body>
   <form method="post" action="https://test.adyen.com/hpp/select.shtml" id="adyenForm" name="adyenForm" target="_parent">      
      <input type="hidden" name="shopperEmail" value="test102@gmail.com" />
      <input type="hidden" name="shopperReference" value="test102@gmail.com" />
      <input type="hidden" name="merchantSig" value="3iWDU/V5RMtdaiZC4YRIpoX9/v0=" />
      <input type="hidden" name="sessionValidity" value="2014-10-11T10:30:00Z" />
      <input type="hidden" name="shipBeforeDate" value="2014-10-20" />
      <input type="hidden" name="shopperLocale" value="en_GB" />
      <input type="hidden" name="merchantAccount" value="TestMerchant" />
      <input type="hidden" name="paymentAmount" value="10000" />
      <input type="hidden" name="currencyCode" value="GBP" />
      <input type="hidden" name="skinCode" value="4aD37dJA" />
      <input type="hidden" name="merchantReference" value="Internet order 12345" />
      <input type="hidden" name="recurringContract" value="RECURRING,ONECLICK" />
<!--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" /> 
      <input type="hidden" name="openinvoicedata.merchantData" value="d2hhdGV2ZXIga2xhcm5hIHJlcXVlc3RzIGZvciBFTUQgY2FuIGJlIHB1dCBoZXJlLg==" />
<!-- Buttons and offset --> 
      <input type="hidden" name="offset" value="0" />
      <input type="submit" value="Send" />
      <input type="reset" />
   </form>   
  </body>
</html>

API integration specific fields

When using our direct API integration to make an AfterPay or a RatePAY payment, you need to provide:

  • shopperName: A container for the shopper information. For more information, see Name.

  • selectedBrand: The type of open invoice method that the shopper wants to use. Possible values: 

    • ratepay
    • afterpay_default
  • dateOfBirth
  • telephoneNumber: The telephone number of the shopper.
  • deviceFingerprint: Required for RatePAY only. To obtain this value, contact RatePAY.

  • billingAddress: This object contains billing address details. For more information, see Address.
  • deliveryAddress: Only required if the delivery address is not the same as the billing address. This object contains delivery address details. For more information, see Address.

RatePAY payment request:

{
   "merchantAccount":"YOUR_MERCHANT_ACCOUNT",
   "amount":{
      "currency":"EUR",
      "value":"1000"
   },
   "selectedBrand":"ratepay",
   "shopperEmail":"youremail@email.com",
   "shopperReference":"14411521",
   "shopperIP":"69.89.31.226",
   "reference":"Test invoice",
   "shopperName":{
      "firstName":"Johann",
      "lastName":"Strauss",
      "gender":"MALE"
   },
   "dateOfBirth":"1941-03-21",
   "telephoneNumber":"0765260000",
   "billingAddress":{
      "country":"DE",
      "city":"Neuss",
      "houseNumberOrName":"1",
      "street":"Hellersbergstrasse",
      "postalCode":"41460"
   },
   "additionalData":{
      "openinvoicedata.numberOfLines":"2",
      "openinvoicedata.line1.currencyCode":"EUR",
      "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":"EUR",
      "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"
   }
}

Step 2: Capture the payment

Unlike most other payments, open invoice payments have to be captured in order to be completed. Capturing the payment is what triggers the invoice to be sent to the shopper. 

Open invoice payments need to be captured manually, even if you have enabled automatic capture for other payment methods. If you want to enable automatic capture for open invoice payments, contact our Support Team.

You can capture open invoice payments in the same way as other payments, by making a call to the /capture endpoint. When partially capturing an open invoice payment, you also need to specify in your /capture call the price and product information to be included in the invoice. 

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

Partial captures

When making a partial capture, you only ask the shopper to pay for some of the goods that they originally purchased. This is useful, for example, when an item is out of stock.

When you partially capture a payment, the remaining amount that you did not capture is automatically cancelled. If you do not want this to happen, for example if you want to perform multiple partial captures, contact our  Support Team .

For multiple partial captures, Klarna and AfterPay work slightly different than RatePAY: 

  • RatePAY: One invoice is created per payment, and the shopper will receive a modified invoice on each capture.
  • Klarna and AfterPay: A new invoice is created upon every capture.

When submitting a partial capture, add invoice lines to the additionalData of the capture request, so an invoice can be sent to the shopper containing only captured items.

For AfterPay, you need to store the acquirerReference related to the capture, as you will need it when making a (partial) refund request. The acquirerReference can be included on the standard capture notifications.

Partial capture request:

{
  "merchantAccount" : "MyMerchantAccount",
  "modificationAmount" : {
    "currency" : "EUR",
    "value" : "800"
  },
  "originalReference" : "81234567890123456",
  "additionalData" : {
    "openinvoicedata.line1.currencyCode" : "EUR",
    "openinvoicedata.line1.description" : "Shoes",
    "openinvoicedata.line1.itemAmount" : "661",
    "openinvoicedata.line1.itemVatAmount" : "139",
    "openinvoicedata.line1.itemVatPercentage" : "2100",
    "openinvoicedata.line1.numberOfItems" : "1",
    "openinvoicedata.line1.vatCategory" : "High",
    "openinvoicedata.numberOfLines" : "1"
  }
}

Partial capture response:

{
  "pspReference" : "8515071322806376",
  "response" : "[capture-received]"
}

Refunds and cancellations

When an open invoice payment has not yet been captured, you can cancel it by making a request to the /cancel endpoint as usual.  If an open invoice payment has already been captured and you want to return the funds to the shopper, you need to refund it by using the /refund endpoint.

When making a partial refund, for example if the shopper only returned a part of the order, you also need to include in the additionalData of your refund request information about the returned items.

For AfterPay, you also need to add the acquirerReference of the capture, in case there are multiple partial captures available for the payment.  When manually doing refunds via your , you can add the acquirerReference manually as well.

Partial refund request:

{
  "merchantAccount" : "MyMerchantAccount",
  "modificationAmount" : {
    "currency" : "EUR",
    "value" : "800"
  },
  "originalReference" : "81234567890123456",
  "additionalData" : {
    "acquirerReference" : "1004567890123",
    "openinvoicedata.line1.currencyCode" : "EUR",
    "openinvoicedata.line1.description" : "Shoes",
    "openinvoicedata.line1.itemAmount" : "661",
    "openinvoicedata.line1.itemVatAmount" : "139",
    "openinvoicedata.line1.itemVatPercentage" : "2100",
    "openinvoicedata.line1.numberOfItems" : "1",
    "openinvoicedata.line1.vatCategory" : "High",
    "openinvoicedata.numberOfLines" : "1"
  }
}

 Partial refund response:

{
  "pspReference" : "8515071322806376",
  "response" : "[refund-received]"
}

Invoice lines

When making an open invoice payment, you need to provide the price and product information, to be included on the invoice sent to the shopper. You can do this using the openinvoicedata fields. 

When using API integration, the openinvoicedata fields are child elements of additionalData. Each field represents a key and not a JSON structure. 

  "amount":{
      "currency":"SEK",
      "value":"1000"
   },
 
"additionalData":{
      "openinvoicedata.numberOfLines":"2",
      "openinvoicedata.line1.currencyCode":"SEK",
      "openinvoicedata.line1.description":"Shoes",
      "openinvoicedata.line1.itemAmount":"331",
      "openinvoicedata.line1.itemVatAmount":"69",
      "openinvoicedata.line1.itemVatPercentage":"2100",
      "openinvoicedata.line1.numberOfItems":"1",
      "openinvoicedata.line1.vatCategory":"High"
      "openinvoicedata.line2.currencyCode":"SEK",
      "openinvoicedata.line2.description":"Socks",
      "openinvoicedata.line2.itemAmount":"248",
      "openinvoicedata.line2.itemVatAmount":"52",
      "openinvoicedata.line2.itemVatPercentage":"2100",
      "openinvoicedata.line2.numberOfItems":"2",
      "openinvoicedata.line2.vatCategory":"High"
   }

For your request to be successful, the amounts stated in your request need to be correct: 

  1. For each line, the tax amount (itemVatAmount) has to match the tax percentage (itemVatPercentage), given the amount excluding tax (itemAmount):

    itemVatAmount = (itemAmount * itemVatPercentage)

    In the example above, 69 = (331 * 0,21), and 52 = (248 * 0,21).

  2. The value specified in the amount has to match the total amount of the invoice lines. To calculate the total amount of the invoice lines, refer to the following pseudo-code: 

    total = 0;
    
    for each (invoiceLine in lineItems) {
      total += (itemAmount + itemVatAmount) * quantity;
    }
    
    totalValue = total;

    In the example above: (331 + 69) * 1 = 400, and (248 + 52) * 2 = 600, so totalValue = 400 + 600 = 1000.

RatePAY Installments

RatePAY installments are currently only possible via an API integration.

Contact RatePAY to discuss installment rates you can offer your shoppers to prevent refusals.

Follow the same implementation process as open invoice with the following additions:

  • selectedBrand – set the value to ratepay (there is no separate value for installments).
  • Add the installment object to define the number of installments.
  • Add the following items in the additionalData object:

    • ratepay.installmentAmount - (required) - Amount the customer has to pay each month.
    • ratepay.lastInstallmentAmount - (required) - Amount of the last installment.
    • ratepay.interestRate - (required) - Interest rate for this installment.
    • ratepay.paymentFirstday - (optional) - Calendar day of the first payment. Example value: 28.

See also