zimpler-developers

Direct Debit

This part of the documentation describes the direct debit (Autogiro) flow for Sweden.

# Concepts

# Cutoffs

A payment amount or due_date can be changed while it is still pending. It can also still be cancelled. Once the payment is sent then it can no longer be changed or cancelled.

We send payments to autogiro every 15 minutes on the business day before the due_date, after which it is marked as sent.

Autogiro’s own cutoff for processing payments due on a given business day is 19:00 the previous business day. If Autogiro gets a payment at 19:00:01 or later, it will be processed on the second business day from the arrival date.

NOTE: A payment must be created before 18:45 on a given business day for it to make the 19:00 autogiro cutoff.

# Scenarios

Payment submitted Due Date Sent to Autogiro Executed
Wednesday (any time) +1 Week (Wednesday) Tuesday 00:00 CEST Wednesday (On due date)
Wednesday 13:01 empty Same day 13:15 CEST Thursday (On due date)
Wednesday 13:01 +1 Day (Thursday) Same day 13:15 CEST Thursday (On due date)
Wednesday 19:01 +1 Day (Thursday) Thursday 00:00 CEST Friday (1 day late)
       
Friday 13:01 empty Same day 13:15 CEST Monday (On due date)
Friday 19:01 empty Same day 13:15 CEST Tuesday (1 day late)

# Flow

  1. Create consent between the user and you, the merchant: POST /v4/direct_debit/consents
  2. User gives the merchant consent
  3. Consent becomes accepted and merchant is notified, which means the merchant can now create payments using it.
  4. Merchant creates payments using the consent: POST /v4/direct_debit/payments or POST /v4/direct_debit/batches
  5. Merchant receives notifications for payment (or batch) state changes

Flow

Note: Make sure to load the user_form_url in a redirect or popup on mobile, loading user_form_url in an iframe on mobile will cause issues.

** […] in response objects the below documentation indicates omitted fields.**

# Endpoints

Note the following errors are possible for nearly all endpoints:

# POST /v4/direct_debit/consents

# REQUEST

{
  // required
  "country_code": "SE",
  "success_url": "http://example.com/success",
  "failure_url": "http://example.com/failure",
  "close_url": "http://example.com/close",
  "notification_url": "http://example.com/notify",
  "site": "http://example.com/",
  "site_display_name": "Best Website.com",
  // optional
  "national_identification_number": "19810101-0000",
  "user_id": "string"
}

# RESPONSES

{
  "id": "d687e283-f7ba-4cd5-9a74-6a482b4dc242",
  "country_code": "SE",
  "user_form_url": "https://account-sandbox.zimpler.com?code=6a734480-a051-4a05-8405-ac2d8f49102f",
  "success_url": "http://example.com/success",
  "failure_url": "http://example.com/success",
  "close_url": "string",
  "notification_url": "http://example.com/notify",
  "national_identification_number": "19810101-0000",
  "state": "pending",
  "state_reason": "waiting for mandate to be signed",
  "created_at": "2022-11-12T15:38:21.376Z",
  "updated_at": "2022-11-12T15:38:21.377Z"
}

# Errors

# GET /v4/direct_debit/consents/:id

Will return the full consent object with the current state.

The user should be redirected to the user_form_url so they can start the accounts flow.

{
  "id": "6a734480-a051-4a05-8405-ac2d8f49102f",
  "state": "pending",
  "user_form_url": "https://account-sandbox.zimpler.com?code=6a734480-a051-4a05-8405-ac2d8f49102f",
  "user_id": null,
  "kyc_info": null,
  "bank_account": [],
  ...
}
# Identified (will be sent in the notification)

The user has been identifed and has chosen account. Then the kyc_info object is populated as well as the bank_account.

{
  ...
  "id": "6a734480-a051-4a05-8405-ac2d8f49102f",
  "state": "identified",
  "user_id": "9b9047da-175f-d29a-dae8-85b428488c2e",
  "kyc_info": {
    "country_code": "SE",
    "user_id": "9b9047da-175f-d29a-dae8-85b428488c2e",
    "national_identification_number": "19810101-0000",
    "first_name": "Henrik Testperson",
    "last_name": "Testson",
    "date_of_birth": "1981-01-01",
    "pep": false,
    "address": {
      "line_1": "Box 1529 / Prod Utv",
      "line_2": null,
      "postcode": "17229",
      "city": "Sundbyberg",
      "country": "Sweden"
    }
  },
  //will be provided or partial provided depending on the information we receive. 
  "bank_account": [
    {
      "type": "iban",
      "account_number": "XXX"
    },
    {
      "type": "national-SE",
      "clearing_number": "XXX",
      "account_number": "XXX"
    },
    {
      "type": "bic",
      "bic": "ELLFSESS"
    }
  ]
}

The user has signed the consent. This does not mean that payments can be created yet, for that the consent must be ‘ accepted’.

{
  "id": "6a734480-a051-4a05-8405-ac2d8f49102f",
  "state": "signed",
  ...
}

# Errors

# DELETE /v4/direct_debit/consents/:id

Cancel the consent. Doing so will cancel all pending payments. In order to create payments for the user in the cancelled consent, a new consent must be created, signed and then accepted first.

# REQUEST

No payload

# RESPONSE

{
  "id": "6a734480-a051-4a05-8405-ac2d8f49102f",
  "state": "cancelled",
  ...
}

# Errors

# POST /v4/direct_debit/payments

Create a payment.

# REQUEST

{
  // required
  "amount": "100.00",
  "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
  "country_code": "SE",
  "currency": "SEK",
  "notification_url": "http://example.com/notify",
  "ref": "payment_xyz",
  // optional
  "payment_prefix": "string",
  "due_date": "2022-04-27"
  // defaults to next possible business day if empty
}

# RESPONSE

{
  "amount": "100.00",
  "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
  "country_code": "SE",
  "currency": "SEK",
  "due_date": "2022-04-27",
  "id": "7ec1cfec-348c-46dd-8eb3-99cee8485dae",
  "national_identification_number": "19810101-0000",
  "notification_url": "http://example.com/notify",
  "payment_prefix": "PRF1X",
  "payment_ref": "Z 123456789012",
  "ref": "payment_xyz",
  "state": "pending"
}

# Errors

# GET /v4/direct_debit/payments/:id

Will return the full payment object with the current state.

# RESPONSE

{
  "amount": "100.00",
  "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
  "country_code": "SE",
  "currency": "SEK",
  "due_date": "2022-04-27",
  "id": "7ec1cfec-348c-46dd-8eb3-99cee8485dae",
  "national_identification_number": "19810101-0000",
  "notification_url": "http://example.com/notify",
  "payment_prefix": "PRF1X",
  "payment_ref": "Z 123456789012",
  "ref": "payment_xyz",
  "state": "pending"
}

# Errors

# PATCH /v4/direct_debit/payments/:id

Update the amount or due-date of a pending payment.

Only these fields may be changed.

Payments that have been registered with autogiro cannot be changed.

Will return the full payment object with the current state.

# REQUEST

{
  "amount": "110.00",
  "due_date": "2022-04-28"
}

# RESPONSE

{
  "amount": "110.00",
  "due_date": "2022-04-28",
  "state": "pending",
  ...
}

# Errors

# DELETE /v4/direct_debit/payments/:id

Use this to cancel a pending payment.

Payments that have been registered with autogiro cannot be cancelled.

Will return the full payment object with the current state.

# RESPONSE

{
  "amount": "100.00",
  "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
  "country_code": "SE",
  "currency": "SEK",
  "due_date": "2022-04-27",
  "id": "7ec1cfec-348c-46dd-8eb3-99cee8485dae",
  "national_identification_number": "19810101-0000",
  "notification_url": "http://example.com/notify",
  "payment_prefix": "PRF1X",
  "payment_ref": "Z 123456789012",
  "ref": "payment_xyz",
  "state": "cancelled",
  "state_reason": "cancelled by merchant"
}

# Errors

# POST /v4/direct_debit/batches

Create a batch of payments.

# REQUEST

{
  "payments": [
    {
      "amount": "100.00",
      "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
      "country_code": "SE",
      "currency": "SEK",
      "due_date": "2022-04-27",
      "notification_url": "http://example.com/notify",
      "payment_prefix": "string",
      "ref": "payment_xyz"
    }
  ]
}

# RESPONSE

{
  "id": "a398da09-da5f-40d1-af75-e6c45b9d136b",
  "state": "pending",
  "payments": [
    {
      "amount": "100.00",
      "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
      "country_code": "SE",
      "currency": "SEK",
      "due_date": "2022-04-27",
      "id": "7ec1cfec-348c-46dd-8eb3-99cee8485dae",
      "national_identification_number": "19810101-0000",
      "notification_url": "http://example.com/notify",
      "payment_prefix": "PRF1X",
      "payment_ref": "Z 123456789012",
      "ref": "payment_xyz",
      "state": "pending"
    }
  ],
  "errors": [],
  "notification_url": "http://example.com/notify"
}

In case of errors:

Note that this format differs from the normal response errors. The error value will just be the text normally sent in the message field of the error examples at the bottom.

{
  "id": "a398da09-da5f-40d1-af75-e6c45b9d136b",
  "state": "failed",
  "payments": [],
  "errors": [
    {
      "ref": "ref",
      "error": "consent not usable"
    }
  ],
  "notification_url": "http://example.com/notify"
}

# Errors

# GET /v4/direct_debit/batches/:id

Retrieve payment batch.

# RESPONSE

{
  "id": "a398da09-da5f-40d1-af75-e6c45b9d136b",
  "state": "pending",
  "payments": [
    {
      "amount": "100.00",
      "consent_id": "34013cf3-a464-4895-8915-e69cc6663f72",
      "country_code": "SE",
      "currency": "SEK",
      "due_date": "2022-04-27",
      "id": "7ec1cfec-348c-46dd-8eb3-99cee8485dae",
      "national_identification_number": "19810101-0000",
      "notification_url": "http://example.com/notify",
      "payment_prefix": "PRF1X",
      "payment_ref": "Z 123456789012",
      "ref": "payment_xyz",
      "state": "pending"
    }
  ],
  "notification_url": "http://example.com/notify"
}

# PATCH /v4/direct_debit/batches/:id

Change amount or due date in payment batch.

If you wish to change an individual payment’s amount or due date, use PATCH /v4/direct_debit/payments/:id.

# REQUEST

{
  "amount": "99.00",
  "due_date": "2023-01-01"
}

# RESPONSE

{
  "id": "b41dce49-837a-44ec-95ef-c6236b753648",
  "state": "pending",
  "payments": [
    {
      "id": "0d0ba4e95ab21e1fd73a",
      "state": "pending",
      "country_code": "SE",
      "ref": "ref",
      "amount": "99.00",
      "currency": "SEK",
      "national_identification_number": "19810101-0000",
      "notification_url": "http://example.com/notify",
      "due_date": "2023-01-01",
      "consent_id": "0abf486e-74dc-4f9b-825e-35e0d26fc0b1",
      "payment_prefix": "DTest",
      "payment_ref": "",
      "created_at": "2023-01-02T11:18:43.035547Z",
      "updated_at": "2023-01-02T11:18:48.859623Z"
    }
  ],
  "errors": [],
  "notification_url": "http://example.com/notify"
}

# Errors

# DELETE /v4/direct_debit/batches/:id

Cancel payment batch.

# RESPONSE

{
  "id": "b41dce49-837a-44ec-95ef-c6236b753648",
  "state": "cancelled",
  "payments": [
    {
      "id": "0d0ba4e95ab21e1fd73a",
      "state": "cancelled",
      "country_code": "SE",
      "ref": "ref",
      "amount": "99.00",
      "currency": "SEK",
      "national_identification_number": "19810101-0000",
      "notification_url": "http://example.com/notify",
      "due_date": "2023-01-01",
      "consent_id": "0abf486e-74dc-4f9b-825e-35e0d26fc0b1",
      "payment_prefix": "DTest",
      "payment_ref": "",
      "created_at": "2023-01-02T11:18:43.035547Z",
      "updated_at": "2023-01-02T11:18:48.859623Z"
    }
  ],
  "errors": [],
  "notification_url": "http://example.com/notify"
}

# ERRORS

# Internal error

Status: 500

{
  "errors": [
    {
      "code": "internal",
      "message": "internal server error"
    }
  ]
}

# Validation failed

Status: 422

{
  "errors": [
    {
      "code": "unprocessable",
      "message": "<various validation errors>"
    }
  ]
}

# Not found

Status: 404

{
  "errors": [
    {
      "code": "notfound",
      "message": "<Entity> not found"
    }
  ]
}

# User underage

Status: 409

{
  "errors": [
    {
      "code": "conflict",
      "message": "user underage"
    }
  ]
}

Status: 409

{
  "errors": [
    {
      "code": "conflict",
      "message": "only one consent may exist per individual"
    }
  ]
}

Status: 401

{
  "errors": [
    {
      "code": "unauthorized",
      "message": "consent not usable"
    }
  ]
}

# Merchant not authorized

Status: 403

{
  "errors": [
    {
      "code": "forbidden",
      "message": "merchant is not authorized for this individual"
    }
  ]
}

# Payment must be pending

Status: 409

{
  "errors": [
    {
      "code": "conflict",
      "message": "payment must be in state 'pending'"
    }
  ]
}

# User pep

Status: 403

{
  "errors": [
    {
      "code": "forbidden",
      "message": "user is PEP"
    }
  ]
}

# User sanctioned

Status: 403

{
  "errors": [
    {
      "code": "forbidden",
      "message": "user is sanctioned"
    }
  ]
}