Appearance
SEPA Direct Debits (SDD)
SEPA Direct Debit (SDD) allows the recipient of the transfer to collect Euro-denominated payments from SEPA countries accounts. This type of transfer is initiated by the creditor, hence requiring an IBAN and a debtor-approved Mandate.
At Treezor, SDD can be used in two directions:
SDDR
are Received into a Wallet and mapped to Payout objectsSDDE
are Emitted from a Wallet and mapped to Payin objects
Received Direct Debits (SDDR)
Treezor allows for the Wallets to be debited using SEPA Direct Debit (SDDR).
They can be received by Treezor between 24h and 14 days before the desired SDD effective date.
While the creditor of the SDDR is always a business, there are 2 types of SDDR depending on the nature of the debtor:
Type | Debtor | Specific policies |
---|---|---|
SDDR Core | Business or private individual |
|
SDDR B2B | Legal entity or individual acting for professional purposes |
|
Tip – Virtual IBAN SDD reception is also supported
You may provide a Virtual IBAN to receive a SEPA Direct Debit into a Wallet. Virtual IBANs have many benefits over your main IBAN (direction and validity period restrictions, easier funds movements categorization, etc.).
Receiving an SDDR
When an SDD is received, Treezor sends a sepa_sddr.reception
webhook, so you can inform the end user about the Direct Debit and its amount.
Treezor also controls the validity of the operation (e.g., the wallet is active, the Beneficiary not blacklisted, etc.). If the controls:
- Succeed: The Balance and Authorized Balance of the Wallet remain unaffected until the SDD effective date.
- Fail: Treezor sends a
sepa.reject_sddr_core
or asepa.reject_sddr_b2b
webhook.
Best practice – Inform your end users of the SDD reception
They need to provision their Wallet to cover the corresponding amount.
On the effective date of the SDD, Treezor:
- Re-runs the controls made when the SDD was initially received.
- Checks if the Wallet is sufficiently provisioned.
- Checks if the Beneficiary was created (SDDR B2B) or automatically creates the Beneficiary (SDDR Core), which sends a
beneficiary.create
webhook.
Then, if the controls:
- Succeed: Treezor creates the Payout and sends a
payout.create
webhook (VALIDATED
status). - Fail: Treezor sends a
sepa.return_sddr
or asepa.refund_sddr
webhook (no payout is created).
Reading – SDDR Rejection
Learn more about received SEPA Direct Debit rejection in the SDDR Rejection section.
The SDDR Payout object
The SDDR takes the form of a payout object, structured and valued as follows.
Please note that to retrieve the beneficiary IBAN, you can fetch the Beneficiary object using the beneficiaryId
.
json
{
"payouts":[
{
"payoutId":"12345",
"payoutTag":"some-tag",
"payoutStatus":"PENDING",
"payoutTypeId":2,
"payoutType":"Direct Debit",
"walletId":"258024",
"beneficiaryId":"33587",
"uniqueMandateReference":null,
"label":"Direct Debit SEAP ALEX OAK",
"payoutDate":"2018-01-10",
"amount":"100.00",
"currency":"EUR",
"partnerFee":"0",
"createdDate":"2018-01-01 11:00:00",
"modifiedDate":"0000-00-00 00:00:00",
"walletEventName":"Wallet-Client",
"walletAlias":"test-wallet",
"userLastname":"",
"userFirstname":"",
"userId":"98765",
"bankaccountIBAN":"ENCRYPTED IBAN",
"codeStatus":"160001",
"informationStatus":"",
"supportingFileLink":""
}
]
}
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
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
You can check the list of SDDR Errors Codes.
Rejection of an SDDR
Rejection upon reception by Treezor
If the SDD is not valid, you receive a sepa.reject_sddr_core
or a sepa.reject_sddr_b2b
webhook. The Wallet Balance is not affected.
Rejection on the effective date
If the SDD operation can't take place on (or after) the effective date, Treezor sends you:
- A
sepa.return_sddr
webhook (e.g., insufficient funds) or - A
sepa.refund_sddr
webhook (unexpected delays in the controls or transmission of the SDD).
Refund management
To oppose an SDDR, the User first contacts you. You then open a ticket with Treezor Support.
Treezor sends you a payoutrefund.create
webhook with its status set to PENDING
. Then, the refund can be either accepted or declined by the debiting bank:
- Accepted – You receive a
payoutrefund.update
webhook (VALIDATED
status) which concludes the refund. - Declined – You receive a
payoutrefund.update
webhook (CANCELED
status) and the refund doesn't take place.
Declines may occur if the SDDR is more than 8-week old or if the refund reason was improperly set for instance.
Emitted Direct Debits (SDDE)
Treezor allows Users to debit funds from somebody else's account using SEPA Direct Debit (SDDE).
Alert – SEPA Direct Debit limitations
While Treezor can receive SDDR
B2B and SDDR
Core, Treezor can only emit SDDE
Core (no B2B).
Creating an SDDE
Prerequisites – Prior to making an SDDE, you must have a:
- SEPA Creditor Identifier (SCI) – Contact Treezor to obtain one.
- Mandate signed by the debtor – With the correct
sddType
, explicitly allowing you to initiate a transfer.
Also, the debit date (payinDate
) must be on a SEPA Open Banking Day.
Parameters
Below are the main parameters of a SEPA Direct Debit Payin.
Attribute | Type | Description |
---|---|---|
paymentMethodId | integer | Must be 21 for SDDE. |
walletId | integer | The unique identifier of the credited Wallet. |
mandateId | integer | The unique identifier of the associated Mandate |
amount | number | The amount of the Payin. |
currency | string | The currency of the Payin. Must be EUR . |
payinDate | string | The desired date of the Payin, which must be a SEPA Open Banking Day. Format: YYYY-MM-DD The earliest date you can define depends on when the payin is made compared to cut-off time (7:55PM UTC+1):
|
Request
bash
curl -X POST {baseUrl}/v1/payins \
--header 'Authorization: Bearer {accessToken}' \
--header 'Content-Type: application/json' \
-d '{payload}'
1
2
3
4
2
3
4
Here is an example of {payload}
:
json
{
"walletId":{walletId},
"paymentMethodId":21,
"messageToUser":"Invoice number 089063",
"mandateId":{mandateId},
"amount":1.25,
"currency":"EUR"
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Returns the Payin object, with its status set to PENDING
. You will receive the corresponding webhook on the desired Payin date (payinDate
).
json
{
"payins": [
{
"payinId": "<string>",
"payinTag": "<string>",
"payinStatus": "<string>", // is set to PENDING until the payinDate
"codeStatus": <integer>,
"informationStatus": "<string>",
"walletId": <integer>, // the wallet to credit
"userId": "<string>", // valued to 3 initially in Production. DO NOT USE.
"cartId": <integer>,
"walletEventName": "<string>",
"walletAlias": "<string>",
"userFirstname": "<string>",
"userLastname": "<string>",
"messageToUser": "<string>", // commentary
"paymentMethodId": <integer>,
"amount": "<string>",
"currency": "<string>",
"distributorFee": "<string>",
"createdDate": "<string>",
"createdIp": "<string>",
"ibanFullname": "<string>",
"ibanId": "<string>",
"ibanBic": "<string>",
"ibanTxEndToEndId": "<string>",
"ibanTxId": "<string>",
"refundAmount": "<string>",
"totalRows": "<integer>",
"forwardUrl": "<string>",
"payinDate": "<string>", // desired date of effect, or "effective date"
"mandateId": "<integer>", // is ID of the associated Mandate
"creditorName": "<string>",
"creditorAddressLine": "<string>",
"creditorCountry": "<string>",
"creditorIban": "<string>",
"creditorBIC": "<string>",
"virtualIbanId": <integer>,
"virtualIbanReference": "<string>"
[...] // some attributes are hidden
}
]
}
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
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
Caution – userId
value in Production initially set to 3
.
It is strictly forbidden to use this value, this is a technical user for Treezor use only.
Processing flow
Depending on the evolution of the refund or return, you might receive the following webhooks for the payin refund.
Event | Status | Description | |
---|---|---|---|
payin.create | PENDING | Treezor issues an SDDE Payin. | |
payin.update | VALIDATED | The SDDE is accepted. | |
payin.cancel | CANCELED | The SDDE is rejected before the effective date. |
Here is the diagram for an SDDE processing.
Cancelling an SDDE
You can cancel an SDDE before Treezor processes it. SDDE processing at Treezor occurs daily at 8AM UTC+1.
Example
Payin creation time | Deletable until |
---|---|
2PM UTC+1 | 8:OOAM UTC+1 on the next day. |
7AM UTC+1 | 8:OOAM UTC+1 on the same day. |
Request
bash
curl -X DELETE {baseUrl}/v1/payins/{payinId} \
--header 'Authorization: Bearer {accessToken}' \
--header 'Content-Type: application/json'
1
2
3
2
3
Returns the Payin object, with its status set to CANCELED
. Treezor also sends a payin.cancel
webhook.
json
{
"payins": [
{
"payinId": "<string>",
"payinTag": "<string>",
"payinStatus": "CANCELED", // is set to CANCELED
"codeStatus": 140004,
"informationStatus": "<string>",
"walletId": <integer>,
"userId": "<string>",
"cartId": <integer>,
"walletEventName": "<string>",
"walletAlias": "<string>",
"userFirstname": "<string>",
"userLastname": "<string>",
"messageToUser": "<string>",
"paymentMethodId": <integer>,
"amount": "<string>",
"currency": "<string>",
"distributorFee": "<string>",
"createdDate": "<string>",
"createdIp": "<string>",
"ibanFullname": "<string>",
"ibanId": "<string>",
"ibanBic": "<string>",
"ibanTxEndToEndId": "<string>",
"ibanTxId": "<string>",
"refundAmount": "<string>",
"totalRows": "<integer>",
"forwardUrl": "<string>",
"payinDate": "<string>",
"mandateId": "<integer>",
"creditorName": "<string>",
"creditorAddressLine": "<string>",
"creditorCountry": "<string>",
"creditorIban": "<string>",
"creditorBIC": "<string>",
"virtualIbanId": <integer>,
"virtualIbanReference": "<string>"
[...] // some attributes are hidden
}
]
}
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
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
If it is too late for you to cancel the SDDE, you receive the following HTTP 400 error:
json
{
"errors": [
{
"type": "invalid_request",
"code": "input_validation_error",
"message": "The payin has already been sent to the scheme",
"docUrl": "https://docs.treezor.com/guide/api-basics/response-codes.html"
}
]
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Rejection of an SDDE
SDDE can be rejected either before or after the effective date.
Definitions
- Reject – Refusal of the direct debit by the debited PSP before the effective date.
- Return – Refusal of the direct debit by the debited PSP up to 5 days banking days after the effective date.
- Refund – Request of reimbursement from the debtor and initiated by their PSP after the effective date. This refund can be sent up to 13 months after the settlement date in case of a claim for unauthorized operation.
Rejection before effective date
If the debtor bank rejects the SDDE, Treezor sends you a payin.cancel
webhook with:
- The status set to
CANCELED
- The reason code for rejection (e.g., closed account) in the
informationStatus
field.
Rejection after effective date
Although SDDE Returns and Refunds are 2 distinct R-transactions, Treezor handles them the same way.
When receiving a return/refund for an SDDE, Treezor will try to refund the transaction and sends the corresponding webhooks. Those webhooks contain the reason for the return/refund in the informationStatus
field.
Event | Status | Description | |
---|---|---|---|
payinrefund.create | PENDING | Treezor received an SDDE refund or return request. | |
payinrefund.update | VALIDATED | The SDDE refund or return is accepted. | |
payinrefund.cancel | CANCELED | The SDDE refund or return is refused. |
If the refund is validated, then Treezor also sends a transaction.create
webhook with a transactionType
valued to "Payin Refund".
Processing flow
Here is the processing flow of a refund or return of an SDDE.