Skip to content

Commercetools

Last updated: 17th January 2022

Learn how to get started with our integration for commercetools.

This guide assumes that you have already created a commercetools project. If you would like to test this integration, please contact partnerships.

Commercetools is an e-commerce platform that offers true cloud-native, headless commerce integration capabilities. The plugin makes it easier for those already using commercetools to integrate with Checkout.com's payment solutions.

Our integration has two parts:

  1. Configure our API Client in the commercetools Merchant Center.
  2. Set up the frontend, which involves integrating Frames for card payments and our Klarna SDK for Klarna payments.

Before you start

Create a test account

If you haven't already, create a test Checkout.com account.

Get your API keys

To set up our commercetools API Client, you'll need your public and secret API keys, which are generated automatically upon account creation.

  1. Log in to your test account on the Hub sandbox.
  2. In the left menu, go to Settings > Channels, and make a note of your secret and public API keys.
apple pay flow

Configure webhooks

Webhooks are notifications that we send when an event occurs on your account. For example, when a payment is captured. These are used by commercetools to update the status of an order. Read more about webhooks.

  1. Scroll down to the Webhooks section of the page and select New webhook.
  2. Enter the following URLs:
    Webhook URLEvents

    https://commercetools.integration.checkout.com/api/webhooks/payments

    • payment_approved
    • payment_declined
    • payment_pending
    • payment_canceled

    https://commercetools.integration.checkout.com/api/webhooks/transactions

    • payment_captured
    • payment_capture_pending
    • payment_capture_declined
    • payment_refunded
    • payment_refund_pending
    • payment_refund_declined
    • payment_voided
    • payment_void_declined
    • payment_expired
    1. Select API - v2.
    2. Select Create webhook.

    Correctly configuring your webhooks is important; if they're incorrectly formatted, our API Client will not work.

    How webhooks interact with commercetools

    When a webhook is triggered on our side, our integration is creating or updating a transaction in commercetools to reflect the change.

    These transactions are attached to a payment, and there may be multiple transactions attached to a single payment. This is all done automatically, and you don't have to do anything other than setting up the webhooks and configuring the API client.

    You can see these interactions in your commercetools Merchant Center by going to Order list > Order and selecting the Payment tab.

    WebhookTransaction created or updated?Transaction nameNew status of the transaction (if needed)

    payment_approved

    CreatedAuthorizationSuccess

    payment_declined

    Created

    Authorization

    Failure

    payment_pending

    Created

    Authorization

    Pending

    payment_captured

    Created or updated

    Charge

    Success

    payment_capture_pending

    Created

    Charge

    Pending

    payment_capture_declined

    Created

    Charge

    Failure

    payment_refunded

    Created or updated

    Refund

    Success

    payment_refund_pending

    Created

    Refund

    Pending

    payment_refund_declined

    Created or updated

    Refund

    Failure

    payment_voided

    Created

    Authorization canceled

    Success

    payment_void_declined

    Created

    Authorization canceled

    Failure

    payment_expired

    Created or Updated

    Authorization

    Failure

    payment_canceled

    Created or Updated

    Authorization

    Failure

    We do not automatically update the order or payment status. This allows you to build your own order flow.


    Configure API Client

    Follow the steps below to create and configure the Checkout.com API Client on your commercetools site.

    1. Log in to the commercetools Merchant Center, go to Settings > Developer Settings and select Create API Client.
    2. Enter a name for this new API Client (e.g., cko-payment-integration).
    3. Select the following scopes:
    • Manage: Orders
    • Manage: Payments
    1. Select Create API Client.
    2. Copy the following details from the window that appears, and send them to our Integration team at integration@checkout.com (you must save this information, as it is only displayed once):
    • project_key
    • client_id
    • secret
    • API URL
    • Auth URL
    1. Using commercetools' IMPEX, set Types as endpoint, and create as command. Then copy and paste in the following JSON files to install them (make sure you're in the right project when doing this):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    {
    "key": "ctp-cko-integration-interaction",
    "name": {
    "en": "Checkout.com Interaction"
    },
    "resourceTypeIds": ["payment-interface-interaction"],
    "fieldDefinitions": [
    {
    "name": "responseCode",
    "label": {
    "en": "Response Code"
    },
    "required": true,
    "type": {
    "name": "String"
    },
    "inputHint": "SingleLine"
    },
    {
    "name": "responseSummary",
    "label": {
    "en": "Response Summary"
    },
    "required": true,
    "type": {
    "name": "String"
    },
    "inputHint": "SingleLine"
    },
    {
    "name": "id",
    "label": {
    "en": "Action Id"
    },
    "required": true,
    "type": {
    "name": "String"
    },
    "inputHint": "SingleLine"
    }
    ]
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
    "key": "ctp-cko-integration-payment",
    "name": { "en": "Saved Payment Instrument" },
    "description": { "en": "Stores customer saved payments" },
    "resourceTypeIds": ["payment"],
    "fieldDefinitions": [
    {
    "name": "paymentInstrumentId",
    "type": { "name": "String" },
    "required": false,
    "label": { "en": "Payment Instrument" },
    "inputHint": "SingleLine"
    }
    ]
    }

    Set up the frontend

    Next, set up the frontend part of our commercetools integration.

    • Integrate Frames to accept card payments.
    • Add our Klarna SDK (follow steps 2 and 3 on that page; we'll take care of the rest) to support Klarna payments.

    If you are planning to accept SEPA payments, before any payment can occur, your customer must authorize the payment by accepting the terms of the mandate. By accepting, they are authorizing you to collect the specified amount from their bank account using SEPA Direct Debit. See Issue the mandate for more information

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    // create context
    const createContext = async ({ public_key, reference }) => {
    const data = await fetch(`https://commercetools.integration.checkout.com/api/contexts`, {
    method: 'post',
    headers: {
    'content-type': 'application/json',
    authorization: public_key
    },
    body: JSON.stringify({ reference })
    }).then(res => res.json())
    return data
    }
    // create payment
    const createPayment = async args => {
    const { token, public_key, context_id, success_url, failure_url, save_payment_instrument } = args
    const data = await fetch(`https://commercetools.integration.checkout.com/api/payments`, {
    method: 'post',
    headers: {
    'content-type': 'application/json',
    authorization: public_key
    },
    body: JSON.stringify({
    type: 'token',
    token,
    context_id,
    '3ds': args['3ds'],
    success_url,
    failure_url,
    save_payment_instrument
    })
    })
    const body = await data.json()
    return {
    success: data.status >= 200,
    redirectUrl: body.redirect_url
    }
    }
    // Credit card frames initialisation
    Frames.init({
    publicKey: config.cko.publicKey,
    cardValidationChanged: function () {
    console.log('CARD_VALIDATION_CHANGED: %o', event)
    payButton.disabled = !Frames.isCardValid()
    },
    cardTokenized: async data => {
    console.log('CARD_TOKENIZATION: %o', data)
    const paymentSuccess = await createContext({
    public_key: config.cko.publicKey,
    reference: order ? order.id : cart.id
    }).then(context =>
    createPayment({
    public_key: config.cko.publicKey,
    token: data.token,
    context_id: context.id,
    save_payment_instrument: true, // only works for if users is registered
    '3ds': {enabled: true | false}, // ability to send 3ds flag for a request (ideally configured through Hub, use only for testing)
    success_url: `https://example.com/3ds-success.html`, // ability to configure 3ds redirect
    failure_url: `https://example.com/3ds-error.html` // ability to configure 3ds redirect
    })
    )
    if (!paymentSuccess) {
    return console.error('Create payment error', payment)
    }
    const order = await createOrder()
    if (!order) {
    console.error('Create order error', order)
    return
    }
    window.location.href = `/confirmation.html?orderId=${order.id}`
    },
    cardTokenizationFailed: function (data) {
    console.log('CARD_TOKENIZATION_FAILED: %o', data)
    }
    })
    Frames.addEventHandler(Frames.Events.FRAME_ACTIVATED, () => window.dispatchEvent(paymentFormRendered))
    form.addEventListener('submit', async event => {
    event.preventDefault()
    Frames.submitCard()
    })
    // klarna
    const paymentSuccess = await createContext({
    public_key: config.cko.publicKey,
    reference: order ? order.id : cart.id
    }).then(context => {
    const reference = order.id : cart.id
    const apm = context.apms.find(a => a.name === 'klarna')
    const container = document.getElementById('payment-klarna')
    const buyWithKlarna = document.getElementById('payment-method-klarna')
    // button is disabled by default
    const payWithKlarna = document.getElementById('pay-klarna')
    buyWithKlarna.addEventListener(
    'click',
    () => {
    Klarna.Payments.authorize(
    // options
    {
    instance_id: context.id // Same as instance_id set in Klarna.Payments.load().
    },
    // data
    {},
    // callback
    response => {
    console.log('klarna payments authorize', response)
    buyWithKlarna.classList.add('hidden')
    payWithKlarna.classList.remove('hidden')
    // show button to pay with klarna now
    payWithKlarna.addEventListener('click', async () =>
    // pay
    createPayment({ type: apm.name, token: response.authorization_token, contextId: context.id })
    )
    }
    )
    },
    false
    )
    Klarna.Payments.init({
    client_token: apm.metadata.details.client_token
    })
    Klarna.Payments.load(
    // show the klarna component
    {
    container: '#klarna_container',
    payment_method_categories: apm.metadata.details.payment_method_category.map(cat => cat.identifier),
    instance_id: context.id
    },
    // use data from session
    apm.metadata.session,
    // callback
    function (response) {
    console.log('klarna payments load', response)
    // ...
    }
    )
    })

    Make a payment

    Now that you've set up the integration, you're ready to make a payment. You can make a payment in two steps:

    1. Create context
    2. Request payment

    Create context

    First, create a payment context. This returns the available payment options to the customer, and gives you a context_id, with which you can then request a payment.

    Expand the table below to see how our properties map to commercetools' properties.

    Note, the reference property in commercetools refers to the cart or order ID.

    Checkout.comcommercetoolsNotes

    amount

    required

    reference.taxedPrice.totalGross.centAmount

    You will get an error if taxedPrice is missing from reference.

    amount.discount_amount

    required

    n/a

    Set to zero because commercetools applies discounts across line items.

    currency

    required

    reference.taxedPrice.totalGross.currencyCode

    You will get an error if taxedPrice is missing from reference.

    reference

    required

    payload.id

    billing

    required

    reference.billingAddress

    You will get an error if billingAddress is missing from reference.

    billing.address.address_line1

    optional

    reference.billingAddress.(streetNumber ' ' streetName)

    billing.address.address_line2

    optional

    reference.billingAddress.additionalStreetInfo

    billing.address.zip

    optional

    reference.billingAddress.postalCode

    billing.address.city

    optional

    reference.billingAddress.city

    billing.address.state

    optional

    reference.billingAddress.(state|region)

    billing.address.country

    required

    reference.billingAddress.country

    shipping

    optional

    reference.shippingAddress

    shipping.address.address_line1

    optional

    reference.shippingAddress.streetNumber

    shipping.address.address_line2

    optional

    reference.shippingAddress.streetName

    shipping.address.city

    optional

    reference.shippingAddress.city

    shipping.address.state

    optional

    reference.shippingAddress.(state|region)

    shipping.address.zip

    optional

    reference.shippingAddress.postalCode

    shipping.address.country

    required

    reference.shippingAddress.country

    customer

    optional

    n/a

    Not set if firstName and lastName are missing from billingAddress.

    customer.name

    required

    reference.billingAddress.(firstName ' ' lastName)

    customer.email

    optional
    • payload.customerEmail
    • reference.billingAddress.email
    • reference.customerEmail

    products.items.name

    required

    reference.lineItems.variant.name

    Uses the language of the order country if present. Defaults to English if no country is included.

    products.items.quantity

    required

    reference.lineItems.quantity

    products.items.price

    required
    • reference.lineItems.price.value.centAmount

    • shippingInfo.price.centAmount

    products.items.amount

    required
    • reference.lineItems.taxedPrice.totalGross.centAmount
    • shippingInfo.taxedPrice.totalGross.centAmount

    You will get an error if taxedPrice is missing from lineItems or shippingInfo.

    products.items.discount_amount

    required

    (reference.lineItems.price.value.centAmount * reference.lineItem.quantity) - reference.lineItem.taxedPrice.totalGross.centAmount

    The value is calculated from the difference between the total gross (includes discount) and the item total price (excludes discount).

    We recommend that you create a context when your payment options page loads, and reload it if the customer makes a change to their basket or details.

    Endpoint

      post

      https://commercetools.integration.checkout.com/api/contexts

      Header parameters

      HeaderValue

      Authorization

      required

      public key

      Use the valid public key of your Checkout.com account. You can find this in the Hub.

      Content-Type

      required

      application/json

      Body parameters

      Field nameDescription

      reference

      string
      required

      The commercetools cart or order ID.

      customer_email

      string
      optional

      The customer's email.

      If not present, the billing email or the email from the order will be used.

      Request payment

      Creating the context above will give you a context_id. Use this to request a payment with the following endpoint.

      The commercetools integration currently supports the following payment methods:

      • Card
      • iDEAL
      • Sofort
      • Klarna
      • PayPal

      Endpoint

        post

        https://commercetools.integration.checkout.com/api/payments

        Header parameters

        HeaderValue

        Authorization

        required

        public key

        Use the valid public key of your Checkout.com account. You can find this in the Hub.

        Content-Type

        required

        application/json

        Body parameters

          Field nameDescription

          type

          string
          required

          The type of payment method. Set this to token.

          context_id

          string
          required

          The ID of the payment context created above.

          token

          string
          required

          The Checkout.com token.

          cvv

          string
          optional

          The three-digit (or four digits for Amex) card verification value/code.

          save_payment_instrument

          boolean
          optional

          Allows you to save the payment method for future use.

          3ds

          object
          optional

          Allows you to select whether the transaction should be 3D Secure authenticated.

          3ds.enabled

          boolean
          required

          Required the 3ds object is included in the request.

          reference

          string
          optional

          A reference you can use to later identify the payment. This populates the reference field in the Hub

          Leaving this blank will result in context.reference being used as the reference in the Hub.

          success_url

          string
          optional

          The URL to which the customer will be redirected if the payment is successful.

          failure_url

          string
          optional

          The URL to which the customer will be redirected if the payment fails.


          Manage saved payment instruments

          The following endpoints allow you to retrieve a customer's saved payment instruments or delete them.

          Retrieve saved payment instruments

          Use this endpoint to return a list of a customer's saved payment instruments.

          Endpoint

            get

            https://commercetools.integration.checkout.com/api/merchants/{public_key}/customers/{customer_id}

            Header and path parameters

            HeaderValue

            Authorization

            required

            secret key

            Use the valid secret key of your Checkout.com account. You can find this in the Hub.

            Content-Type

            required

            application/json

            PathDescription

            public_key

            required

            Your Checkout.com public key. You can find this in the Hub.

            customer_id

            required

            The customer's commercetools ID.

            Delete a saved payment instrument

            Use the endpoint below to delete a customer's saved payment instrument.

            Endpoint

              delete

              https://commercetools.integration.checkout.com/api/merchants/{public_key}/customers/{customer_id}/payment-instruments/{payment_instrument_id}

              Header and path parameters

              HeaderValue

              Authorization

              required

              secret key

              Use the valid secret key of your Checkout.com account. You can find this in the Hub.

              Content-Type

              required

              application/json

              PathDescription

              public_key

              required

              Your Checkout.com public key. You can find this in the Hub.

              customer_id

              required

              The customer's commercetools ID.

              payment_instrument_id

              required

              The unique identifier of the saved payment instrument.


              Postman collection

              For more testing, commercetools have created a Postman collection.