In-App SDK Flows & Error Handling


This page outlines the steps and flows integrators may need to understand when integrating the In-App SDK. It will additionally provide some code snippets and try to expand on how error handling and potential custom flows may work.

Klarna Payments Standalone/Native Integration

Overview

The integration can be broken down into roughly two parts:

  • When the user enters checkout and the payment method is presented.
  • When the user chooses to pay with a given payment method and Klarna needs to evaluate if the user is eligible to pay with a given payment method.

A conceptual overview of the operations is available here .

Diagram

Init & Load Flow

When a user enters a checkout view or a view that should show Klarna’s payment methods.

Diagram

* Common errors include using an invalid session token. ** Common errors include sending in invalid order information or billing information. Error callback has an error object with an invalidFields parameter.

Some Notes

When receiving an error message, you may check the isFatal parameter to determine whether the error is “final”, and the payment method shouldn’t be made available to customers.

Authorization Flow

When a user confirms they want to pay with a given payment method category.

Diagram

Some Notes

Authorization is successful when:

  1. You have an authorization token and
  2. You have approved == true

Code Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?,
       finalizedRequired: Boolean?) {
       val success = !authToken.isNullOrBlank() && approved
       if (success) {
           // User successfully completed the auth. flow.
           // Send the auth token to Klarna.
       } else {
           // User closed the payment window (tap x).
           // Merchant may keep payment view in checkout view.
       }
    }

    override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) {
       if(error.name == "ShowFormFalseError"){
           // User is rejected in auth flow or payment method is not available.
           // Merchant may hide the payment method, as it's not available to the user.
       }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    func klarnaAuthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?, finalizeRequired: Bool) {

        if let token = authToken, approved == true {
            // Authorization approved! Send token to backend and create an order.
        } else {
            // User tapped close button, or maybe merchant may need to call finalize().
        }
    }

    func klarnaFailed(inPaymentView paymentView: KlarnaPaymentView, withError error: KlarnaPaymentError) {
        if error.name == "ShowFormFalseError" {
            // Klarna has determined that the customer is not eligible for this
            // payment method.
            //
            // This is final. Merchant may hide/remove this payment view. Should
            // not call authorize() again.
        }
    }

Error Handling

following errors might occur during the payment flow:

Invalid Client Token

Description:

This error happens when the client token used to initialize the SDK is invalid for any reason. Merchant should make sure that the client token value is not expired or tampered with.

Report:

When this error occurs, merchant’s app will receive an error in the onErrorOccurred callback method that contains this information:

  • action: Initialize
  • name: InvalidClientTokenError
  • message: Error performing Klarna.Payments.init().

Handling:

Merchant can fix this error by getting a valid client token and calling the init method again.

Code Example:

1
2
3
4
5
6
    override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) {
       if(error.name == "InvalidClientTokenError"){
           // Client token used to initialize the SDK is invalid.
           // Merchant should get a valid client token and use it to initialize the SDK again.
       }
    }
1
2
3
4
5
6
    func klarnaFailed(inPaymentView paymentView: KlarnaPaymentView, withError error: KlarnaPaymentError) {
        if error.name == "InvalidClientTokenError" {
          // Client token used to initialize the SDK is invalid.
           // Merchant should get a valid client token and use it to initialize the SDK again.
        }
    }

Invalid Payment Method

Description:

This error happens when the payment method is invalid and is not available for this session. Merchant should make sure that a valid payment method is set for the SDK by checking the “payment_method_categories” parameter inside the response object when creating a session and set one of these values:

  • KlarnaPaymentCategory.PAY_NOW (“pay_now”)
  • KlarnaPaymentCategory.PAY_LATER (“pay_later”)
  • KlarnaPaymentCategory.SLICE_IT (“pay_over_time”)

Report:

When this error occurs, the merchant’s app will receive an error in the onErrorOccurred callback method after calling the load function. The error contains this information:

  • action: Load
  • name: ShowFormFalseError
  • message: Error performing Klarna.Payments.load().

Handling:

This error is fatal, meaning that the merchant cannot fix it and call the load function again. Merchant should hide the payment view, set a valid payment method and start the SDK again by calling the init function.

Code Example:

1
2
3
4
5
6
    override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) {
       if(error.action == "Load" && error.name == "ShowFormFalseError"){
           // The selected payment method is invalid.
           // Merchant should set a valid payment method for SDK and initialize the SDK again.
       }
    }
1
2
3
4
5
6
    func klarnaFailed(inPaymentView paymentView: KlarnaPaymentView, withError error: KlarnaPaymentError) {
        if error.action == "Load" && error.name == "ShowFormFalseError" {
          // The selected payment method is invalid.
           // Merchant should set a valid payment method for SDK and initialize the SDK again.
        }
    }

Invalid Card Information

Description:

This error happens when the user sets invalid card information when authorizing the payment.

Report:

When this error occurs, merchant’s app will receive the onAuthorized callback method with these parameters:

  • approved: false
  • authToken: null

Handling:

Merchant can keep the payment view. User will see error messages on the card information field(s) and have to review the submitted information and try again.

Code Example:

1
2
3
4
5
6
7
8
9
10
11
12
    override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?,
       finalizedRequired: Boolean?
    ) {
       val success = !authToken.isNullOrBlank() && approved
       if (success) {
           // User successfully completed the auth. flow.
           // Send the auth token to Klarna.
       } else {
           // User provided invalid card information.
           // Merchant may keep the payment view in checkout view.
       }
    }
1
2
3
4
5
6
7
8
    func klarnaAuthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?, finalizeRequired: Bool) {
        if let token = authToken, approved == true {
            // Authorization approved! Send token to backend and create an order.
        } else {
          // User provided invalid card information.
           // Merchant may keep the payment view in checkout view.
        }
    }

User Cancels The Authorization

Description:

This error happens when the user closes the authorization window.

Report:

When this error occurs, merchant’s app will receive the onAuthorized callback method with these parameters:

  • approved: false
  • authToken: null

Handling:

Merchant keeps the payment view and the user can continue with the payment again.

Code Example:

1
2
3
4
5
6
7
8
9
10
11
12
    override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?,
       finalizedRequired: Boolean?
    ) {
       val success = !authToken.isNullOrBlank() && approved
       if (success) {
           // User successfully completed the auth. flow.
           // Send the auth token to Klarna.
       } else {
           // User closed the authorization window.
           // Merchant may keep the payment view in checkout view.
       }
    }
1
2
3
4
5
6
7
8
    func klarnaAuthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?, finalizeRequired: Bool) {
        if let token = authToken, approved == true {
            // Authorization approved! Send token to backend and create an order.
        } else {
            // User closed the authorization window.
           // Merchant may keep the payment view in checkout view.
        }
    }

Missing or Invalid Fields in Authorize Data

Description:

This error happens when the merchant doesn’t send some of the required billing or shipping information fields or sends invalid data when calling the authorize function on SDK.

Report:

If this error occurs, Klarna will show an error message to the user saying that some of the information is missing and might ask for the missing information then. In this case the user can fill the information and proceed. Otherwise, the user will acknowledge the error and close the payment view. In the latter case, this error is treated exactly like the user cancel the authorization flow and the merchant’s app will receive the onAuthorized callback method with these parameters:

  • approved: false
  • authToken: null

Handling:

Merchant should fix the error by sending all the required information to the authorize method and continue.

Code Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
    override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?,
       finalizedRequired: Boolean?
    ) {
       val success = !authToken.isNullOrBlank() && approved
       if (success) {
           // User successfully completed the auth. flow.
           // Send the auth token to Klarna.
       } else {
           // Authorize information is missing some of the required fields.
           // Merchant may keep the payment view in checkout view and call the
           // authorize function with valid information.
       }
    }
1
2
3
4
5
6
7
8
9
    func klarnaAuthorized(paymentView: KlarnaPaymentView, approved: Bool, authToken: String?, finalizeRequired: Bool) {
        if let token = authToken, approved == true {
            // Authorization approved! Send token to backend and create an order.
        } else {
           // Authorize information is missing some of the required fields.
           // Merchant may keep the payment view in checkout view and call the
           // authorize function with valid information.
        }
    }

User Getting Rejected on Authorize

Description:

This error happens when a user gets rejected for this payment method by Klarna. This error is fatal and can’t be fixed by the merchant.

Report:

When this error occurs, merchant’s app will receive an error in the onErrorOccurred callback method containing this information:

  • action: Authorize
  • name: ShowFormFalseError
  • message: Error performing Klarna.Payments.authorize().

Handling:

Since this is a fatal error, merchant should remove the Klarna view and stop the payment process.

Code Example:

1
2
3
4
5
6
    override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) {
       if(error.action == "Authorize" && error.name == "ShowFormFalseError"){
           // user is rejected when authorizing the payment.
           // Merchant should remove the Klarna view and stop the payment process.
       }
    }
1
2
3
4
5
6
    func klarnaFailed(inPaymentView paymentView: KlarnaPaymentView, withError error: KlarnaPaymentError) {
        if error.action == "Authorize" && error.name == "ShowFormFalseError" {
           // user is rejected when authorizing the payment.
           // Merchant should remove the Klarna view and stop the payment process.
        }
    }

FAQ About Standalone Integration

Q: What is the finalizeRequired parameter in the callback?

A: Some payment methods’ authorize() processes consist of two steps. By default, Klarna does both at once. When you call authorize() with autoFinalize = false, the aforementioned two steps are split into individual calls (authorize() and finalize()). In that case, if you receive finalizeRequired == true, you need to call finalize() to receive an authorization token.


Q: Can I set the return URL in the application to <some extended path>?

A: Anything that triggers a return to the application to the same view works. Ideally, don’t trigger a navigation and let the SDK evaluate whether the authorization flow is complete. It’ll close any dialogs it was presenting and call either your authorized or error callbacks.


Q: (iOS) I created a Payment View and added my event listener but nothing is happening when I call init(), etc.

A: The Payment View contains a web view which actually shows the payment method. On some versions of iOS, the web view needs to be added to the view hierarchy for it to function. Make sure you’ve also added the PaymentView to one of your app’s view’s before you call init().