Direct Debit
This part of the documentation describes the direct debit (Autogiro) flow for Sweden.
# Concepts
-
Autogiro Mandate: is agreed between the end user and Zimpler, allowing Zimpler to withdraw money from the account on the mandate.
-
If the
Autogiro Mandate
is cancelled (by the end user for instance):- Any associated
Consent
will also be cancelled - All associated
Payments
that have statepending
will be cancelled
- Any associated
-
-
Consent: is agreed between the end user and the Merchant, allowing the merchant to create a new, or use an existing, valid
Autogiro Mandate
.- If the
Autogiro Mandate
is cancelled, so is theConsent
. -
Side effects of Cancelling a
Consent
:- Cancelling all
Payments
with thepending
state. - It does NOT affect the associated
Autogiro Mandate
.
- Cancelling all
- If the
-
Payment: is a scheduled deposit from the end user to the Merchant
- Only payments that are in the state
pending
may be cancelled
- Only payments that are in the state
-
Batch: is a batch/group of
Payments
.Payments
in a batch do not need to be for the same end user, the only restriction is that they must all be for the same Merchant.
# 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
- Create consent between the user and you, the merchant: POST /v4/direct_debit/consents
- User gives the merchant consent
- Consent becomes
accepted
and merchant is notified, which means the merchant can now create payments using it. - Merchant creates payments using the consent: POST /v4/direct_debit/payments or POST /v4/direct_debit/batches
- Merchant receives notifications for payment (or batch) state changes
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
- POST /v4/direct_debit/consents
- GET /v4/direct_debit/consents/:id
- POST /v4/direct_debit/payments
- GET /v4/direct_debit/payments/:id
- PATCH /v4/direct_debit/payments/:id
- POST /v4/direct_debit/batches
- GET /v4/direct_debit/batches/:id
- PATCH /v4/direct_debit/batches/:id
- DELETE /v4/direct_debit/batches/:id
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.
# Pending consent
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"
}
]
}
# Signed consent
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"
}
]
}
# Only one consent
Status: 409
{
"errors": [
{
"code": "conflict",
"message": "only one consent may exist per individual"
}
]
}
# No usable consent
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"
}
]
}