Account Funding (AFT) request
This method allows you to initiate an Account Funding Transaction (AFT) server-to-server: a card is debited and the funds are credited to a beneficiary bank account (IBAN). The beneficiary may be the cardholder themselves (default) or a third party.
The endpoint reuses the standard SysPay payment lifecycle (direct, preauth, mandate, rebill) and adds three required blocks describing the sender of the funds, the recipient of the funds and the destination account.
- URL syntax: /api/v2/merchant/account-funding
- Method: POST
Operating modes
The endpoint dispatches to a payment subtype based on preauth, token_id and mandate:
| Mode | preauth | token_id | mandate |
|---|---|---|---|
| Direct | false | absent | false |
| Direct + mandate | false | absent | true |
| Preauth | true | absent | false |
| Preauth + mandate | true | absent | true |
| Rebill | false | int | rejected |
| Preauth + rebill | true | int | rejected |
mandate=truecombined withtoken_idis rejected (a rebill reuses an existing token).- Preauth modes require the
ROLE_PREAUTHfeature permission. - Rebill modes require the
ROLE_BILLING_AGREEMENTfeature permission.
Request parameters
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| flow | string | API | Y | Only API is accepted on this endpoint. |
| reference | string | UNIQUE, max 85 ascii printable characters | Y | Your own payment identifier for the request. Must be unique per feature. |
| amount | string | numeric string, minor units | Y | The payment amount in cents ("5000" = 50.00). |
| currency | string | [A-Z]3 | Y | ISO 4217 currency code. Must be allowed by the feature. |
| description | string | Max length 300 | N | Free-form description. |
| extra | string | Max length 300 | N | Free-form metadata, returned in the response and in webhooks. |
| return_url | string | URI | N | Overrides the default return_url configured on your SysPay account. |
| ems_url | string | URI | N | Server-to-server notification URL. Overrides the default ems_url. |
| preauth | boolean | N* | Authorize only; capture later through POST /merchant/capture. * Defaults to false. | |
| token_id | int | N | Switches the request to rebill mode (replays AFT against a stored token). | |
| mandate | boolean | N* | Store the card as a token reusable for future rebills. Incompatible with token_id. * Defaults to false. | |
| capture_date | unix timestamp | N | Schedules capture (preauth modes only). | |
| interactive | boolean | N | See Server-to-server payment. | |
| payment_method | array | See section below | N* | Required on direct, preauth and mandate modes. Must be omitted on rebill (token_id set) modes. |
| customer | array | Customer | Y | The customer's details. |
| device | array | Device | N | Extra parameters for improved 3D Secure Assessment. |
| funds_sender | array | See section below | Y | Identity of the cardholder funding the operation. |
| funds_recipient | array | See section below | Y | Identity of the recipient of the funds. |
| funds_destination | array | See section below | Y | Destination bank account. |
payment_method parameter
Same structure as for the Server-to-server payment endpoint. The most common case for AFT is raw card data:
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| type | string | CREDITCARD | Y | The type of payment method. |
| cardholder | string | Max length 100 | Y | Cardholder name. |
| number | string | [0-9]19 | Y | Valid credit card number, only digits. |
| exp_month | string | [0-9]2 | Y | Card expiry month (ex: 05). |
| exp_year | string | [0-9]4 | Y | Card expiry year (ex: 2030). |
| cvc | int | [0-9]4 | N* | Card verification code. Required for raw card flows unless your settings allow otherwise. |
token_key (client-side tokenization) and token_id (stored token) are also accepted — see Server-to-server payment.
funds_sender parameter
Information about the cardholder funding the operation.
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| date_of_birth | string | YYYY-MM-DD | Y | Cardholder date of birth. |
| source_of_funds | string | credit_card | debit_card | prepaid_card | cash | debit_account | credit_account | mobile_money | N* | Required when customer.billing_address.country = US. |
| state | string | Max length 100 | N* | Required when customer.billing_address.country ∈ {US, CA}. |
| country_of_birth | string | ISO 3166-1 alpha-2 | N | Country of birth of the cardholder. |
funds_recipient parameter
Information about the recipient of the funds.
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| same_as_sender | boolean | N* | When true (default), the cardholder is the recipient. SysPay automatically reuses the customer identity and the billing address on the network side. | |
| firstname | string | Max length 30 | N* | Required when same_as_sender=false. |
| lastname | string | Max length 30 | N* | Required when same_as_sender=false. |
| date_of_birth | string | YYYY-MM-DD | N | Recipient date of birth. |
| country_of_birth | string | ISO 3166-1 alpha-2 | N | Recipient country of birth. |
| address | array | See section below | N* | Required when same_as_sender=false or when funds_destination.holder_country ∈ {CA, US, COL, NIC}. |
| phone | string | ^\+?\d{6,20}$ | N | Recipient phone number. |
funds_recipient.address parameter
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| address | string | Max length 255 | Y | Street address. |
| city | string | Max length 100 | Y | City. |
| state | string | Max length 100 | Y | State / region. |
| country | string | ISO 3166-1 alpha-2 | Y | Country code. |
| postal_code | string | Max length 12 | Y | Postal code. |
funds_destination parameter
Destination bank account.
| Name | Type | Details | Mandatory | Description |
|---|---|---|---|---|
| type | string | iban | Y | Only iban is supported today. |
| iban | string | ^[A-Z]{2}\d{2}[A-Z0-9]{1,30}$ | Y | Destination IBAN. Masked in responses as [country][checksum]****. |
| bic | string | ^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$ | N | Bank Identifier Code. |
| holder_country | string | ISO 3166-1 alpha-2 | Y | Country of the account holder. |
Authentication
All endpoints require WSSE authentication via the X-WSSE header:
X-WSSE: AuthToken MerchantAPILogin="{login}", PasswordDigest="{digest}", Nonce="{nonce}", Created="{timestamp}"
Where:
PasswordDigest = base64(sha1(binary_nonce + unix_timestamp + passphrase))Nonce = base64(binary_nonce)Created = unix_timestamp(must be within 5 minutes of server time)- Each nonce can only be used once.
Example requests
Direct AFT — third-party recipient
{
"flow": "API",
"reference": "aft-20260522-001",
"amount": "5000",
"currency": "EUR",
"description": "Funding to John Doe IBAN",
"preauth": false,
"return_url": "https://merchant.example.com/return",
"ems_url": "https://merchant.example.com/notify",
"customer": {
"email": "alice@example.com",
"firstname": "Alice",
"lastname": "Martin",
"ip": "203.0.113.10",
"language": "en",
"billing_address": {
"address1": "12 rue de la Paix",
"city": "Paris",
"postal_code": "75002",
"country": "FR"
}
},
"payment_method": {
"type": "CREDITCARD",
"number": "4111111111111111",
"cardholder": "ALICE MARTIN",
"exp_month": "12",
"exp_year": "2030",
"cvc": "123"
},
"funds_sender": {
"date_of_birth": "1985-04-12",
"country_of_birth": "FR"
},
"funds_recipient": {
"same_as_sender": false,
"firstname": "John",
"lastname": "Doe",
"date_of_birth": "1988-05-26",
"country_of_birth": "FR",
"address": {
"address": "8 avenue de la République",
"city": "Montpellier",
"state": "Occitanie",
"country": "FR",
"postal_code": "34000"
},
"phone": "+33600000000"
},
"funds_destination": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"bic": "BNPAFRPP",
"holder_country": "FR"
}
}
Direct AFT — cardholder is the recipient
{
"flow": "API",
"reference": "aft-20260522-002",
"amount": "20000",
"currency": "EUR",
"customer": {
"email": "tom@example.com",
"firstname": "Tom",
"lastname": "Chucky",
"ip": "8.8.8.8",
"language": "en",
"billing_address": {
"address1": "760 Celestine Inlet",
"city": "North Lillie",
"postal_code": "STJ2041",
"country": "AQ"
}
},
"payment_method": {
"type": "CREDITCARD",
"number": "4111111111111111",
"cardholder": "Meghan Rodriguez",
"exp_month": "06",
"exp_year": "2030",
"cvc": "123"
},
"funds_sender": {
"date_of_birth": "1985-04-12",
"country_of_birth": "AQ"
},
"funds_recipient": {
"same_as_sender": true
},
"funds_destination": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"holder_country": "FR"
}
}
Direct AFT with mandate (tokenize the card)
{
"flow": "API",
"reference": "aft-20260522-003",
"amount": "5000",
"currency": "EUR",
"mandate": true,
"customer": {
"email": "alice@example.com",
"firstname": "Alice",
"lastname": "Martin",
"ip": "203.0.113.10",
"language": "en",
"billing_address": {
"address1": "12 rue de la Paix",
"city": "Paris",
"postal_code": "75002",
"country": "FR"
}
},
"payment_method": {
"type": "CREDITCARD",
"number": "4111111111111111",
"cardholder": "ALICE MARTIN",
"exp_month": "12",
"exp_year": "2030",
"cvc": "123"
},
"funds_sender": {
"date_of_birth": "1985-04-12"
},
"funds_recipient": {
"same_as_sender": true
},
"funds_destination": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"holder_country": "FR"
}
}
Rebill AFT against a stored token
{
"flow": "API",
"reference": "aft-20260522-004",
"amount": "5000",
"currency": "EUR",
"token_id": 123456,
"customer": {
"email": "alice@example.com",
"ip": "203.0.113.10"
},
"funds_sender": {
"date_of_birth": "1985-04-12"
},
"funds_recipient": {
"same_as_sender": true
},
"funds_destination": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"holder_country": "FR"
}
}
Response parameters
The response is a standard SysPay V2 Payment object enriched with AFT-specific fields:
funding: true for AFT transactions, false for any other payment.funds_sender: echo of the requestfunds_senderblock.funds_recipient: echo of the requestfunds_recipientblock. Theaddresssub-object is omitted whensame_as_sender=true(no third-party address persisted).funds_destination: echo of the requestfunds_destinationblock. Theibanis masked as[country][checksum]****(e.g.FR76****).
A Token object is also returned when a billing agreement was created (mandate=true) or used (token_id set).
Possible status values: OPEN, WAITING, AUTHORIZED, PROCESSED, SUCCESS, FAILED, TIMED_OUT.
Example response
{
"class": "payment",
"id": 4711,
"reference": "aft-20260522-001",
"amount": 5000,
"currency": "EUR",
"status": "SUCCESS",
"flow": "API",
"processing_time": 1779820800,
"account_id": 10033,
"merchant_id": 139112,
"merchant_login": "139112001",
"description": "Funding to John Doe IBAN",
"funding": true,
"funds_sender": {
"class": "funds_sender",
"date_of_birth": "1985-04-12",
"country_of_birth": "FR"
},
"funds_recipient": {
"class": "funds_recipient",
"same_as_sender": false,
"firstname": "John",
"lastname": "Doe",
"date_of_birth": "1988-05-26",
"country_of_birth": "FR",
"address": {
"class": "funds_recipient_address",
"address": "8 avenue de la République",
"city": "Montpellier",
"state": "Occitanie",
"country": "FR",
"postal_code": "34000"
},
"phone": "+33600000000"
},
"funds_destination": {
"class": "funds_destination",
"type": "iban",
"iban": "FR76****",
"bic": "BNPAFRPP",
"holder_country": "FR"
},
"customer": {
"class": "customer",
"email": "alice@example.com"
},
"payment_method": {
"class": "payment_method",
"type": "CREDITCARD"
}
}
Error responses
400 — Validation error
Returned when a required parameter is missing or malformed.
{
"error_code": 400,
"errors": [
{
"class": "error",
"code": 10006,
"property": "funds_sender.date_of_birth",
"message": "Missing required parameter"
}
]
}
Common cases:
| Code | Property | Reason |
|---|---|---|
| 10006 | funds_sender.date_of_birth | Missing required parameter. |
| 10006 | funds_recipient.address | Missing recipient address with strict-KYC destination. |
| 10007 | mandate | Extra parameter — mandate=true is incompatible with token_id. |
| 10009 | funds_destination.iban | Invalid data format (malformed IBAN). |
403 — Authentication error
Returned when the X-WSSE header is missing, invalid, or the timestamp / nonce is rejected.
{
"error_code": 403,
"errors": [
{
"class": "error",
"message": "Authentication required"
}
]
}