Account Funding Transactions (AFT)
An Account Funding Transaction (AFT) is a card payment used to load funds into an account rather than to buy goods or services. Typical use cases are wallet top-ups, prepaid card loads, remittances, and peer-to-peer transfers. Card schemes require AFT payments to carry details about the sender (the person funding the transaction) and the recipient (the person or account receiving the funds).
Moyasar Form lets you collect an AFT payment with the same integration you already use for regular payments. You supply the sender and recipient details in the form configuration, and the form attaches them to the payment request automatically.
Before Starting
Make sure you complete the following before enabling AFT:
- Your Moyasar entity must be enabled for AFT. Contact your account manager or Moyasar support to activate it. The form validates the shape of the data, but the API rejects AFT payments from entities that are not enabled.
- You have a working Moyasar Form integration. If not, follow the Basic Integration guide first.
- You are using the latest version of Moyasar Form.
How AFT Is Enabled
There is no separate switch. Passing both sender and recipient in Moyasar.init() turns AFT on for the form. When neither key is present, the form behaves exactly as before and nothing described in this guide applies.
Both keys must be provided together. Passing only one of them is a configuration error and the form does not render.
Supported Payment Methods
AFT is supported for the following payment methods:
- Credit and debit cards (
creditcard) - Apple Pay (
applepay) - Samsung Pay (
samsungpay)
STC Pay and Google Pay do not support AFT yet. When you enable AFT you must:
- Pass an explicit
methodsarray that does not includestcpay. If you omitmethods, the default list includes STC Pay and the form fails to initialize. - Leave out the
google_payconfiguration key.
Configuration Keys
sender
| Key | Required | Max length | Description |
|---|---|---|---|
first_name | Yes | 30 | Sender's first name. |
last_name | Yes | 35 | Sender's last name. |
address | Yes | 50 | Sender's street address. |
id_type | Yes | Type of the identification document. See Sender ID Types. | |
id | Yes | 50 | Identification number matching id_type. |
phone_number | Yes | 20 | Sender's phone number, including country code. |
locality | No | 25 | City or town. |
postal_code | No | 50 | Postal or ZIP code. |
administrative_area | No | 2 | State, province, or region code. |
country_code | No | 2 | Two-letter ISO 3166-1 alpha-2 country code, for example SA. |
recipient
| Key | Required | Max length | Description |
|---|---|---|---|
first_name | Yes | 30 | Recipient's first name. |
last_name | Yes | 35 | Recipient's last name. |
address | Yes | 50 | Recipient's street address. |
middle_name | No | 35 | Recipient's middle name. |
street_name | No | 50 | Street name, if kept separate from address. |
locality | No | 50 | City or town. |
postal_code | No | 50 | Postal or ZIP code. |
country | No | 2 | Two-letter ISO 3166-1 alpha-2 country code, for example SA. |
building_number | No | 50 | Building number. |
All values must be strings. Leading and trailing whitespace is trimmed before the values are sent. Optional keys that are empty, null, or undefined are removed from the request.
Sender ID Types
sender.id_type must be one of the following codes:
| Code | Document |
|---|---|
NTID | National ID |
PASN | Passport number |
DRLN | Driver's license number |
BTHD | Birth date |
CUID | Customer identification number |
SSNB | Social security number |
ARNB | Alien registration number |
CPNY | Company registration number |
EMAL | Email address |
PHON | Phone number |
PRXY | Proxy identifier |
LAWE | Law enforcement identification |
MILI | Military identification |
TRVL | Travel document |
Complete Example
The following configuration collects an AFT payment by card or Apple Pay. See the Form Configuration reference for the apple_pay keys.
Moyasar.init({
element: '.mysr-form',
amount: 20000, // 200.00 SAR in the smallest currency unit
currency: 'SAR',
description: 'Wallet top-up',
publishable_api_key: 'pk_test_YOUR_PUBLISHABLE_KEY',
callback_url: 'https://example.com/thanks',
// STC Pay must be excluded and google_pay must be omitted
methods: ['creditcard', 'applepay'],
apple_pay: {
country: 'SA',
label: 'Example Wallet',
validate_merchant_url: 'https://api.moyasar.com/v1/applepay/initiate',
},
// Providing both keys enables AFT
sender: {
first_name: 'Mohammed',
last_name: 'Ali',
address: 'King Fahd Road',
id_type: 'NTID',
id: '1234567890',
phone_number: '+966500000000',
locality: 'Riyadh',
country_code: 'SA',
},
recipient: {
first_name: 'Ahmed',
last_name: 'Ali',
address: 'Olaya Street',
locality: 'Riyadh',
country: 'SA',
},
on_completed: async (payment) => {
await savePaymentOnBackend(payment.id);
},
});
The method savePaymentOnBackend is a placeholder, and you must provide your own custom logic.
What Is Sent to the API
When the customer pays with a supported method, the form adds sender and recipient to the body of the payment request. Everything else in the request is unchanged.
Endpoint: POST /v1/payments
Authentication: Publishable key
{
"amount": 20000,
"currency": "SAR",
"description": "Wallet top-up",
"publishable_api_key": "pk_test_YOUR_PUBLISHABLE_KEY",
"callback_url": "https://example.com/thanks",
"source": {
"type": "creditcard",
"...": "..."
},
"sender": {
"first_name": "Mohammed",
"last_name": "Ali",
"address": "King Fahd Road",
"id_type": "NTID",
"id": "1234567890",
"phone_number": "+966500000000",
"locality": "Riyadh",
"country_code": "SA"
},
"recipient": {
"first_name": "Ahmed",
"last_name": "Ali",
"address": "Olaya Street",
"locality": "Riyadh",
"country": "SA"
}
}
Using AFT With Callbacks
All existing callbacks work unchanged with AFT payments: on_initiating, on_completed, on_redirect, and on_failure.
Note that on_initiating cannot add or change sender or recipient. The set of keys that callback may update is fixed to amount, currency, description, metadata, callback_url, splits, and publishable_api_key. Set the sender and recipient details at initialization time. If they depend on the logged-in customer, resolve them on your backend before calling Moyasar.init().
Configuration Errors
The form validates the AFT configuration when Moyasar.init() runs, before anything is rendered. If validation fails, the form is replaced by a red box titled Form configuration issue! and the exact reason is logged to the browser console. No request is sent to the API.
Common messages and how to fix them:
| Console message | Fix |
|---|---|
`sender` and `recipient` must be provided together for AFT payments | Provide both keys, or remove both to disable AFT. |
AFT payments support only creditcard, applepay, samsungpay; disable stcpay, googlepay when ... | Remove stcpay from methods and remove the google_pay key. |
Missing entry: sender.first_name is required | Add the missing required key. The message names the key. |
`sender.first_name` must be at most 30 characters | Shorten the value to the listed maximum. |
`sender.id_type` must be one of: NTID, PASN, ... | Use one of the codes from Sender ID Types. |
`sender.country_code` must be a 2-letter ISO 3166-1 alpha-2 code | Use a two-letter code such as SA. |
`recipient.foo` is not a supported field | Remove the unknown key. Only the keys listed above are accepted. |
Testing
Use a pk_test publishable key to test the integration. In test mode the validation messages are also printed to the console before the form throws, which makes misconfiguration easier to spot.
Merchants Not Using AFT
If you do not pass sender and recipient, nothing in this guide affects your integration. You may continue to use STC Pay and Google Pay, and the payment request body is unchanged.