API Integrations
This checklist applies to direct API integrations using standard, preauthorized, and/or payout transactions.
User Creation & Management
User Authentication
- Aeropay may require SMS MFA when a user is created or when an existing Aeropay network user is being confirmed with a merchant for the first time.
- Email-only MFA is not an approved production authentication method.
- VOIP, landline, and prepaid phone numbers are not supported in production.
- If your application already enforces SMS OTP verification during registration or before the user enters the cashier, share the details of that authentication flow with Aeropay.
- Aeropay can review the existing verification controls and, where appropriate, configure the merchant so a newly created user is not prompted for a second, redundant Aeropay OTP.
- This configuration applies to new users only.
- Existing Aeropay network users will still be required to complete a one-time Aeropay SMS MFA challenge when they are first confirmed with that merchant.
Handling mfaType
mfaTypeUse the mfaType returned by POST /user to determine whether an MFA prompt is required.
- When MFA is required,
mfaTypewill contain the applicable supported MFA method (smsoremail). - When no MFA challenge is required, mfaType will be returned as null.
- Do not expect the string
"none".
Your UI should only display the MFA/OTP prompt when mfaType contains a supported MFA value.
If mfaType is null, skip the OTP prompt and continue the flow.
OTP Resend Guidance
Aeropay currently supports OTP resend behavior through the existing user authentication flow. You should avoid aggressively prompting users to request additional codes while the original OTP is still valid.
At this time:
- OTPs remain valid for 15 minutes. Additional codes resent before expiry will be the same.
- You should wait at least 3 minutes before presenting a Resend Code option.
- Avoid short resend timers such as 30–60 seconds, as these can encourage unnecessary duplicate sends while the original code is still valid.
- Repeated calls to
POST /usershould not be treated as a normal resend pattern. - If a resend is requested, the user should first be encouraged to use the code already sent unless they have not received it.
Aeropay is actively scoping improvements to OTP resend behavior, including:
- reducing OTP expiration from 15 minutes to 10 minutes
- adding a dedicated OTP resend endpoint
- introducing progressive resend cooldowns
allowing the first resend after approximately 3 minutes - applying a longer cooldown, such as 5 minutes, for subsequent resends
- limiting OTP sends within rolling hourly and daily windows
- returning
retryAfterwhen a resend is temporarily unavailable - using downstream SMS delivery results to determine whether another send is likely to succeed
- preventing additional sends for terminal delivery conditions with an email fallback and graceful path directing users to [email protected] for additional investigation
Until these updates are available, integrations should use 3 minutes as the minimum recommended resend interval and should not rely on repeated POST /user calls to generate additional OTPs.
User Management
- Only call
POST /userafter the user has selected Aeropay or Pay by Bank at checkout. - Use
POST /user only when the user needs to be created or initially confirmed. - Once a user has been successfully created and confirmed, or an existing network user has completed the required one-time confirmation, use
GET /userfor subsequent visits and transaction flows. - Do not repeatedly call
POST /userfor a user who has already been confirmed, as this can unnecessarily restart the authentication flow.
When mfaType indicates that SMS MFA is required:
- Display an OTP capture screen instructing the user to enter the verification code sent to their phone.
- Example: “Please enter the verification code sent to
***-***-XXXX.” -
XXXXshould represent the last four digits of the phone number provided in thePOST /userrequest. - Submit the OTP through
POST /confirmUser.
When mfaType is null:
- Do not display an OTP screen.
- Continue directly to the next step in the Pay by Bank flow.
User Status
Before allowing a user to submit a payment/payout:
- Check the
userStatusfield returned byPOST /confirmUserorGET /user, and - Subscribe to the
user_suspendedanduser_activewebhooks to maintain the user’s current status.
If the user is suspended:
- Do not allow the payment to proceed. Disable the payment option before they can click pay/deposit.
- Display a user-friendly message like
Your account is currently suspended. Please contact[email protected]to reactivate your account.
Recommended Flow
New user — merchant SMS verification approved by Aeropay
Merchant performs SMS OTP → POST /user → mfaType: null → continue without an additional Aeropay OTP → use GET /user thereafter
New user — Aeropay SMS MFA required
POST /user → mfaType indicates SMS MFA → POST /confirmUser → use GET /user thereafter
Existing Aeropay network user — first merchant confirmation
POST /user → one-time SMS MFA → POST /confirmUser → check userStatus → use GET /user thereafter
Returning confirmed user
GET /user → check userStatus → continue to payment
The key integration principle is that you should respond to mfaType rather than assuming every user requires an OTP, and should use GET /user once the user has already been created and authenticated to your merchant.
Bank Account Management
- Call GET /bankAccounts (or the equivalent GET /user response containing bank accounts) at least once at the beginning of every authenticated user session.
- Always display the user's current list of connected bank accounts returned by the API. If the user already has bank accounts connected through the Aeropay network, present those accounts immediately with the option to Link a New Bank if desired.
- Preselect the account where isSelected: true.
- Allow the user to select another connected account or link a new one prior to transacting (all newly linked accounts become isSelected).
Do not assume a user's previously connected banks are unchanged or rely on locally cached bank account information.
Why this is important
One of the primary benefits of the Aeropay network is that a user's linked bank accounts travel with them across participating merchants. Refreshing the user's bank connections each session ensures your application fully leverages this network experience.
Failing to retrieve the latest connections can:
- Force users through unnecessary bank connection flows even though they already have valid linked accounts.
- Increase user friction and reduce payment conversion.
- Produce misleading analytics by attributing bank-linking abandonment to payment failures.
Again, avoid persisting bankAccountId.
Persisting historical bankAccountId values can lead to unintended failures if a user has since:
- Closed a bank account.
- Changed their default/selected account and expect transactions elsewhere
- Result in dispute out of confusion
By always retrieving the latest bank connections before initiating payments, your application ensures it is transacting against the user's current, valid accounts while delivering the seamless cross-merchant experience the Aeropay network is designed to provide.
Testing
- Run a test of creating a new user.
- Run a test for a returning network user.
- Ensure you are retrieving the network user's available banks.
Aerosync Bank Connections
Aerosync Customization Preferences
If applicable, provide the following so we can configure your Aerosync widget appearance:
- Light mode or dark mode preference
- Your logo in
.svgformat (horizontal orientation preferred) - Preferred button color (hex code)
Aerosync SDK Configuration
- Ensure you are passing the correct
configurationIdvalue when launching the Aerosync SDK to render customizations (if applicable). - Confirm that any requested Aerosync customizations (light/dark mode, logo, button color) are rendering correctly.
- If using the Web NPM Aerosync SDK, ensure your application's origin URLs are whitelisted. Refer to the SDK guide for details (if applicable).
- For mobile applications (if applicable): Implement OAuth support and deep linking. OAuth flows work without additional setup on web, but mobile experiences require a deeplink to redirect users back from the OAuth login. See our OAuth Connections guide.
Bank Connection Tests
- Run a test of a new user linking their first bank account.
- Run a test of an OAuth bank connection to verify the redirect flow. Use the Aerosync (OAuth) test bank in the sandbox environment. This is especially critical for mobile applications.
- If a user wants to remove a bank account, direct them to [email protected]. This ensures the user is not attempting to circumvent pending payments or outstanding recovery.
Separate Bank Linking from Payment Initiation
Whenever possible, launch the Aerosync bank connection experience before the user initiates a payment, rather than embedding bank linking directly within the checkout or transaction flow.
Examples include:
- Prompt users to connect a bank during cashier onboarding or wallet setup.
- Encourage bank linking during or immediately after account creation.
- Allow users to manage their linked bank accounts independently of making a payment.
Once a bank is connected, the payment flow should simply allow the user to select an existing bank account and authorize the transaction.
Why we recommend this
Our user studies have consistently shown higher payment conversion when bank linking and payment authorization are separated into two distinct user experiences.
Separating these flows provides several benefits:
- Higher conversion. Users are more likely to complete a payment when bank linking has already been completed.
- More accurate payment metrics. Falloff during the Aerosync bank connection experience is no longer counted as payment abandonment, giving merchants a clearer view of true payment conversion.
- Improved returning-user experience. Returning users can proceed directly to payment without unnecessarily re-entering the bank connection flow.
- Cleaner operational analytics. Teams can independently measure bank connection conversion and payment authorization conversion, making optimization significantly easier.
Payments
Run the following tests for each transaction type your integration supports. Not all test cases will be applicable.
Standard Transactions
- Run a successful test of a standard transaction (pay-in):
/transaction - Run a test of a rejected payment. Ensure you handle this gracefully - how to test
Preauthorized Transactions
- Run a successful test of creating and capturing a preauth transaction:
/preauthTransaction&/capturePreauthTransaction - Ensure you are capturing payments before they expire. Preauthorized transactions expire 72 hours after creation.
- Ensure you have logic in place to update preauth transactions with
PATCH /preauthTransaction. - Ensure you have logic in place to cancel preauth transactions with
DELETE /preauthTransaction.
Payout Transactions
- Run a successful test of a standard payout (same-day ACH):
/payoutTransaction- If applicable, ensure you have logic to route payouts to RTP rails (real-time payment) via
rtpparam.
- If applicable, ensure you have logic to route payouts to RTP rails (real-time payment) via
- If a payout is declined or voided, your system should re-credit the user's wallet or balance with the payout amount.
Refunds & Reversals
- Ensure you are able to void, partially refund, or fully refund a transaction using
POST /reverseTransaction.
Tipping
- If you are accepting tips on your UI: run a successful transaction with the
tipobject populated in the/transactioncall.
Checkout & Payment Page
-
Display a combination of the last 4 digits (accountNumberDisplay), the
nameandbankNamereturned fromGET /bankAccounts(e.g., Bank of America, Adv. Checking, *1234). -
At every user session, call
GET /bankAccountsto fetch the most up to date list of bank connections for the user.- Do not store
bankAccountIdvalues, as these can change outside of your flow.
- Do not store
-
Display popular bank logos on your checkout page near the Aeropay or "Pay by Bank" option. Customers are more likely to select "Pay by Bank" when they see their bank's logo at checkout. More info: UX Guidelines.
-
Show Aeropay "Pay by Bank" as the first payment option for highest conversion and cost savings.
-
Remove redundant "Pay by Bank," "eCheck," or "ACH" payment options.
-
Use "Pay by Bank" language and Aeropay assets in your Aeropay payment option. This has been shown to outperform alternative wording and provide useful context.
Webhooks
General Webhook Requirements
- Webhook subscriptions are required for all API integrations.
- Ensure your system can receive webhooks from Aeropay's IP range (if applicable)
- Optional: implement webhook signature validation to verify the authenticity of incoming payloads.
- Webhooks in sandbox are a separate subscription from webhooks in prod. Subscribe to prod webhooks when you receive prod credentials.
Required
| Webhook | Action Required |
|---|---|
transaction_voided | Pay-ins: Do not deliver product or credit the user's wallet/balance. Payouts: Re-credit the user's wallet/balance with the payout amount. Void events can occur hours after a transaction has been marked as completed — your system must be able to handle these asynchronous events. Testing: void any transaction via the sandbox merchant portal. Ensure correct logic is in place in response to a void. |
transaction_declined | Pay-ins: No action needed — Aeropay handles recovery of funds. Payouts: Re-credit the user's wallet/balance with the payout amount. This webhook is informational and helps you stay aware of disputes and declined charges. Testing: ACH return / declined testing guide. Ensure correct logic is in place in response to a declined payment. |
user_suspended | Prevent the user from initiating further transactions. Suspend the user's activity on your platform until the suspension is resolved. Testing: this will fire when a payment for a user is declined on any Aeropay network merchant. See decline testing in section above. |
user_active | Re-enable the user's ability to transact on your platform. Testing: on the declined transaction in the sandbox merchant portal, select "Resolve." |
Strongly Recommended
You should subscribe to the following webhooks. If you choose not to, be prepared to explain your reasoning during integration review.
| Webhook | Action Required |
|---|---|
transaction_completed | Confirm transaction completion. Depending on your implementation, this may provide the same information as the synchronous API response to POST /transaction. |
Error Handling
- Ensure your integration has graceful error-handling in place. See the full Error Glossary.
Fraud Prevention
-
Name matching on user creation: When calling
POST /v2/user, compare the name your system provides in the request against the name returned in the response.- For network users, the phone number may already be associated with a saved name in Aeropay's system. If the name returned in the response differs from what your system passed, this may indicate a mismatch worth reviewing.
- Note: Aeropay automatically verifies that the user's Aeropay name matches the bank account holder identity returned during the Aerosync bank connection flow. Accounts that fail this check will be prevented from linking.
- Implementing name-matching logic on your end is part of your KYC process and is recommended as an additional layer of fraud prevention.
-
User communication for voids: When a transaction is voided, surface the following message to the user:
"We couldn't verify the full payment details for this transaction. Please try again with a different payment method, or contact [email protected]."
Stored Funds & Wallet Use Cases (If Applicable)
This section applies if your platform allows users to deposit funds into a wallet, player balance, or similar stored-value account.
- Ensure your system can freeze or deduct funds in the event of a major fraud event.
- Void handling best practices: A
transaction_voidedwebhook can arrive hours after atransaction_completedwebhook. A user may have already been credited and could attempt to withdraw funds before the void is processed. To mitigate this:- Implement a withdrawal waiting period for new users (min. 3 business days recommended).
- Consider "play-through" requirements — require users to use deposited funds before allowing withdrawal.
- Immediately suspend account activity when a
user_suspendedwebhook is received. Re-activate on receivinguser_activewebhook.
Integration Approval - Deliverables
Once you've worked through the checklist above, submit the following to your Aeropay Solutions Engineer to complete your integration review.
Demo Videos
Share the following demos as screen-recorded videos or live on a video call. Each demo should cover the applicable transaction types in your integration (standard, preauth, payout).
- New user flow (new bank) — A new user on your platform goes through the MFA flow (
/confirmUser) and completes a payment by linking a new bank. - Network user flow (previously linked bank) — A new user on your platform goes through the MFA flow and completes a payment using a previously linked bank.
- In this scenario, a new user to your platform bypasses the bank linking flow because they have bank account(s) already linked with another Aeropay merchant (network user).
- Scenario setup: remove the test user from your platform database. Then you can go through the user onboarding flow where you call
POST /user, then/bankAccountsto display the user's existing banks.
- Returning user flow — A returning user completes a payment with a previously linked bank account.
- For mobile applications (if applicable): Provide a mobile demo including a bank connection test using the Aerosync (OAuth) test bank to verify deep linking is working correctly. See our OAuth Connections guide.
Integration Questions
Provide answers or confirmation for each item:
- Does your integration call
GET /v2/bankAccountsat least once per user session? (Yes/No) - For returning users and network users, are their linked banks always displayed at checkout before payment completion? (Yes/No)
- What webhooks is your system subscribed to? What automations are in place when webhook payloads are received? (List webhooks + describe logic)
- Are you using your provided
configurationIdvalue when launching Aerosync? (Yes/No) - If using the Web NPM Aerosync SDK, share your application's origin URL (base URL/domain) in both sandbox and production.
- Have you added Aeropay's Terms of Service excerpt to your Terms of Service? (Provide link — see Integration Agreement, Section 6)
- Added hyperlink within excerpt: https://www.aeropay.com/legal/terms-of-service---end-user
- Have you added Aeropay's Privacy Policy excerpt and hyperlink to your Privacy Policy? (Provide link — see Integration Agreement, Section 6)
- Added hyperlink within excerpt: https://www.aeropay.com/legal/privacy-policy
Updated 10 days ago

