📄
End User Agreement SDK
An SDK to present and capture user consent for terms of service and agreements, handling display, acceptance tracking, and secure consent storage.
Compliance & Audit Trail: All user acceptances and declines are automatically logged to RAMFi's servers with timestamps for compliance and audit purposes.

Installation

HTML <link rel="stylesheet" href="https://FQDN/end-user-agreement/assets/style.css"> <script src="https://FQDN/end-user-agreement/end-user-agreement-sdk.umd.js"></script>

Basic Usage

JavaScript const { EndUserAgreementSDK } = window; const sdk = new EndUserAgreementSDK(); await sdk.init({ userId: 'user-123', onError: (error) => console.error(error) }); const result = await sdk.open(); if (result.status === 'accepted') { console.log('Agreement accepted at:', result.timestamp); } else if (result.status === 'declined') { console.log('Agreement declined'); } else if (result.status === 'error') { console.error('Error:', result.error); }

Configuration Options

Required Parameters
ParameterTypeDescription
userIdstringUnique identifier for the user (matches clientID from NewClient endpoint).
onErrorfunctionError handler callback: function(error).
Optional Callbacks
CallbackParametersDescription
onAgreementAcceptedresultCalled when the user accepts the agreement: function(result).
onAgreementDeclinedresultCalled when the user declines the agreement: function(result).

Result Structure

The open() method returns a Promise that resolves with a result object.

JSON // Accepted { "status": "accepted", "userId": "user-123", "timestamp": "2024-01-15T10:30:00.000Z" } // Declined { "status": "declined", "userId": "user-123", "timestamp": "2024-01-15T10:30:00.000Z" } // Error { "status": "error", "userId": "user-123", "timestamp": "2024-01-15T10:30:00.000Z", "error": "Agreement has expired. Please refresh and try again." }

SDK Methods

Methods
MethodDescription
sdk.init(config)Initializes the SDK with your configuration. Returns a Promise that resolves when initialization is complete. Must be called before calling open().
sdk.open()Displays the end user agreement dialog. Returns a Promise that resolves with a result object when the user accepts, declines, or an error occurs. The dialog is modal and blocks user interaction until a choice is made.
sdk.destroy()Cleans up and destroys the SDK instance. Removes event listeners, clears DOM elements, and frees up resources. Important for SPAs to prevent memory leaks.

Integration Pattern: Client Onboarding

1

Create Client

Call POST /api/FE/NewClient to create the client account.

2

Initialize Agreement SDK

Use the returned clientID as the userId parameter.

3

Present Agreement

Call sdk.open() to display the terms and conditions.

4

Handle Acceptance

If the user accepts, proceed with bank connection or the next onboarding step.

5

Handle Decline

If the user declines, display a message and optionally prevent further access.

6

Continue Onboarding

Proceed with the Bank Connection SDK or other integration steps.

Best Practices

Await init() before present(). Calling the present method before initialization completes will fail. Initialize, then open in response to a user action.
Destroy on unmount. Call the SDK's destroy method when navigating away in single-page apps to release listeners and avoid memory leaks.
Persist the agreement reference. Store the returned agreement or document identifier with the client so you can prove consent later.
Handle decline explicitly. Treat a declined agreement as a stop in onboarding, not an error. Give the user a clear path to revisit it.
🔗
Bank Connection SDK
A client-side SDK for the bank linking flow: authentication, account selection, and secure credential management, in a few lines of code.
🔒
Data Privacy & Security: Account numbers and routing numbers are automatically saved to RAMFi's servers and are never passed to your client application. All callbacks (except onError and onLinkExit) are notification-only and do not receive any data parameters.

Quick Start

1

Include the SDK

Add the SDK stylesheet and script to your HTML page.

HTML <link rel="stylesheet" href="https://FQDN/open-bank-connect{environment}/{version}/style.css"> <script src="https://FQDN/open-bank-connect{environment}/{version}/sdk.umd.js"></script>

Replace {environment} and {version} with the values provided during onboarding.

2

Initialize and Open

Initialize the SDK with your configuration and open the bank connection widget.

JavaScript const sdk = new OpenBankConnectSDK(); sdk.init({ clientToken: 'user-uuid-123', onError: function (error) { alert('Error: ' + error.message); } }) .then(function () { // Open the bank connection widget sdk.open(); });
ℹ️
That's it. Banking details are automatically saved to RAMFi's servers and linked to the client account.

Configuration Options

Required Parameters
ParameterTypeDescription
clientTokenGuidYour user's unique ID (returned after the user is created).
onErrorfunctionError handler callback: function(error).
Optional Callbacks
CallbackParametersDescription
onLinkExitexitDataCalled when the user exits the connection flow: function(exitData).
onLinkedDefaultAccountnoneCalled when a default account is selected by the user (notification only).

Callback Reference

onError(error)

Called when an error occurs during initialization or the connection process. The error object has the following properties:

PropertyDescription
error.codeError code (see Error Codes below).
error.messageHuman-readable error message.
error.detailsAdditional error details (optional).

Common Error Codes: INIT_ERROR (SDK initialization failed), WIDGET_ERROR (error in bank selection widget), NO_TOKEN (missing or invalid clientToken), Error_Saving_Banking_Details (failed to save banking details to RAMFi servers).

onLinkExit(exitData)

Called when the user exits the bank connection flow, either successfully or by cancellation. The exitData object has the following properties:

PropertyDescription
exitData.statusSUCCESS, ACTION_ABANDONED, or FAILED.
exitData.userIdRAMFi user identifier.
exitData.reasonbank_connected, user_cancelled, terms_declined, connection_failed, or api_save_failed.

Note: Banking details (account/routing numbers) are not included in exitData, they are server-side only.

onLinkedDefaultAccount()

Parameters: none (notification only). Called when a default account is selected by the user during the connection flow.

SDK Methods

Methods
MethodDescription
sdk.init(config)Initializes the SDK with your configuration. Returns a Promise that resolves when initialization is complete. Must be called and awaited before calling any other SDK methods (especially open()).
sdk.open()Opens the bank connection widget UI. Call after successful initialization, typically in response to a user action. Returns a Promise that resolves when the widget closes.
sdk.destroy()Cleans up and destroys the SDK instance. Removes event listeners and frees up resources. Important for Single Page Applications (SPAs).

Integration Pattern: New Client Onboarding

1

Create Client

Call POST /api/FE/NewClient to create the client account (without bank details).

2

Initialize SDK

Use the returned clientID as the clientToken parameter.

3

Connect Bank

User completes bank connection via the SDK widget.

4

Verify Connection

onLinkExit fires with status: 'SUCCESS', banking details are saved server-side.

5

Upload ACH Agreement

Call POST /api/FE/AddDocument to upload the signed ACH authorization.

6

Begin Transactions

Client is ready for ACH drafts using POST /api/FE/AddClientFunds.

Best Practices

Await init() before open(). Opening the widget before initialization completes will fail. Initialize, then open in response to a user action.
Destroy on unmount. Call the SDK's destroy method when navigating away in single-page apps to release listeners and avoid memory leaks.
Never handle bank credentials. Login happens inside the hosted widget. Your application should only ever see the resulting linked account, never the username or password.
Confirm success server-side. Treat the account as linked only after the success callback fires and the linked account is saved server-side.
🔐
Card Capture SDK Coming soon
Browser SDK for tokenizing debit card details. Required before using PullFromCard or PushToCard.
Coming soon — not yet enabled. The integration below reflects the planned design, but the Card Capture SDK is not available yet and its API may still change before release. The card endpoints it pairs with are likewise not enabled. Contact your RAMFi integration specialist about availability and timing.
🔒
Data Privacy: Raw card numbers, expiry dates, and CVV values are not passed to the host application. Sensitive card data is captured directly by the SDK and tokenized server-side. The host application receives a cardId token for use in subsequent API calls.

Quick Start

1

Generate a Short-Lived Token (Backend)

On your server, call POST /api/FE/ProvisionToken to generate a short-lived bearer token. Pass this token to your browser via your own authenticated session, never expose your Main Token client-side.

2

Include the SDK

Add the SDK stylesheet and script to your HTML page.

HTML <link rel="stylesheet" href="https://FQDN/card-capture/assets/style.css"> <script src="https://FQDN/card-capture/card-capture-sdk.umd.js"></script>
3

Initialize and Open

Initialize with the short-lived bearer token and the clientID. The SDK renders a PCI-compliant hosted input form, card data never touches your page.

JavaScript const sdk = new CardCaptureSDK(); await sdk.init({ bearerToken: 'short-lived-token-from-ProvisionToken', // REQUIRED, fetched server-side clientID: 'user-uuid-123', // REQUIRED, clientID from NewClient onError: function(error) { console.error('Card Capture error:', error.message); } }); const result = await sdk.open(); if (result.status === 'success') { // Store result.cardId for PullFromCard / PushToCard console.log('Card tokenized:', result.cardId); }
ℹ️
That's it. The cardId in the result is a permanent token for this card. Store it in your system and use it for all future PullFromCard and PushToCard calls.

Configuration Options

Required Parameters
ParameterTypeDescription
bearerToken string Short-lived bearer token generated on your backend via POST /api/FE/ProvisionToken. Single-use and time-limited. Never hardcode or expose your Main Token.
clientID string (UUID) The client's unique ID, returned by NewClient. Binds the captured card to this client account.
onError function(error) Error handler callback. Always implement this to surface initialization and capture failures.
Optional Callbacks
CallbackParametersDescription
onCardCaptured none Notification-only. Called when card data is successfully captured and tokenized server-side. No card data is passed to this callback.
onLinkExit exitData Called when the user exits the card entry flow. See Exit Data Properties below.

sdk.open() Result Object

JavaScript // Accepted / Card captured successfully { "status": "success", "cardId": "string", // token, use for PullFromCard / PushToCard "clientID": "string", // matches clientID provided at init "last4": "string", // last 4 digits of card for display purposes "cardBrand": "Visa|Mastercard|Discover|Amex" } // User cancelled { "status": "abandoned", "clientID": "string" } // Error { "status": "error", "error": "string" }

onError. Error Codes

Error CodeDescription
INIT_ERRORSDK failed to initialize. Check network, bearerToken, and clientID.
NOT_INITIALIZEDopen() was called before init() completed.
WIDGET_ERRORError occurred within the card capture widget.
INVALID_TOKENMissing, malformed, or expired bearerToken. Generate a new token via ProvisionToken.
TOKEN_EXPIREDBearer token expired during the session. Re-fetch from your backend and re-init.
CARD_INELIGIBLECard type not supported for pull/push operations (e.g. credit card, prepaid).
CONNECTION_ERRORNetwork or API failure during tokenization.

SDK Methods

sdk.init(config)

Initializes the SDK. Returns a Promise that resolves when initialization is complete. Must be awaited before calling open().

sdk.open()

Renders the card entry widget. Returns a Promise resolving with a result object containing status and, on success, the cardId token. Call after successful init, typically on a user action.

sdk.destroy()

Cleans up event listeners and DOM elements. Required for Single Page Applications (SPAs), call on component unmount or page navigation to prevent memory leaks.

React / SPA Integration

React import { useState, useRef, useEffect } from 'react'; function CardCapture({ clientID, bearerToken, onCardSaved }) { const sdkRef = useRef(null); const [ready, setReady] = useState(false); useEffect(() => { const init = async () => { if (!window.CardCaptureSDK || !bearerToken) return; const sdk = new window.CardCaptureSDK(); sdkRef.current = sdk; await sdk.init({ bearerToken: bearerToken, // fetch fresh from your backend each session clientID: clientID, onError: (err) => console.error(err.message) }); setReady(true); }; init(); return () => sdkRef.current?.destroy(); }, [clientID, bearerToken]); const handleCapture = async () => { if (!sdkRef.current) return; const result = await sdkRef.current.open(); if (result.status === 'success') { onCardSaved(result.cardId, result.last4, result.cardBrand); } }; return ( <button onClick={handleCapture} disabled={!ready}> Add Debit Card </button> ); }

Integration Pattern: Card Onboarding

1

Create Client

Call POST /api/FE/NewClient to create the client account and obtain the clientID.

2

Generate Short-Lived Token

On your backend, call POST /api/FE/ProvisionToken to generate a short-lived bearer token. Pass it to the browser via your authenticated session.

3

Present Agreement

Use the End User Agreement SDK to capture consent before collecting card details.

4

Initialize Card Capture SDK

Pass the bearerToken and clientID. Await init() before calling open().

5

Tokenize Card

User enters card details in the hosted widget. On success, the cardId token is returned to your app. Store this securely.

6

Transact

Use the cardId token in PullFromCard (collect payment) or PushToCard (send funds) as needed.

Best Practices

Never collect raw card data. Always use the Card Capture SDK widget. Card numbers must never pass through your application code.
Store the cardId. This token is reusable for future pull and push transactions. Display last4 and cardBrand so users can identify saved cards.
Await init() before open(). Calling open() before init() completes will fail with NOT_INITIALIZED.
Destroy on unmount. Call sdk.destroy() when navigating away in single-page apps to prevent memory leaks.
HTTPS required. The Card Capture SDK will not initialize on non-HTTPS origins in production.
Check eligibility. Only debit cards are eligible for pull and push. Credit and prepaid cards return CARD_INELIGIBLE.
🅿️
PayPal Connect SDK
Lets users securely link their PayPal account to their RAMFi profile via a popup OAuth flow. The SDK handles the entire PayPal login and authorisation; your application never touches OAuth tokens or PayPal credentials.

The RAMFi PayPal Connect SDK opens the PayPal login, processes the authorisation, and validates the connection with RAMFi’s backend, then notifies your application of the result via a callback. On success you receive a RAMFi transactionId that your backend passes to WalletTransfer to initiate the payout.

🔒
Popup-based OAuth flow. The SDK opens the PayPal login in a popup window. To stop the browser blocking it, sdk.open() must be called directly inside a user gesture such as a button click — never from a timer or async callback.

Prerequisites

  • A RAMFi user ID for the authenticated user — provided by RAMFi when the user account is created.
  • A backend endpoint that returns a fresh token and totp from RAMFi’s auth service for each SDK session.
  • Pages served over HTTPS — PayPal OAuth does not work on plain HTTP.

Quick Start

1

Include the SDK

Add the SDK script to your HTML page.

HTML <script src="https://FQDN/paypal-connect/{version}/sdk.umd.js"></script>
2

Initialise the SDK

Create an SDK instance and call init() with the RAMFi user ID and event callbacks. Do this once when the page loads.

JavaScript const sdk = new PayPalConnectSDK(); sdk.init({ userId: currentUser.ramfiUserId, onError(error) { console.error(error.code, error.message); }, onLinkExit(result) { if (result.status === 'SUCCESS') { console.log('Linked! transactionId:', result.transactionId); } else if (result.status === 'FAILED') { console.error('Failed:', result.errorMessage); } } });
3

Open the PayPal flow on button click

When the user clicks Connect, fetch a fresh token and totp from your backend and pass them to sdk.open(). Fetch these immediately before each call — do not cache them between sessions.

JavaScript document.getElementById('connectBtn').addEventListener('click', async () => { const { token, totp } = await myBackend.getRamfiCredentials(); sdk.open({ token, totp }); });

User Flow

What the user sees
StepWhat happens
Click ConnectUser clicks the connect button — the SDK opens a centered popup immediately.
Loading screenThe popup shows a “Connecting to PayPal…” spinner while the session is prepared.
PayPal loginThe popup navigates to the PayPal login page.
AuthoriseUser logs in to PayPal and grants permission to link their account.
Connecting screenThe popup shows a connecting screen while RAMFi validates the authorisation.
Popup closesThe popup closes automatically once validation is complete. On mobile browsers where auto-close is blocked, a Return to app button is shown instead.
ResultThe onLinkExit callback fires with the outcome.

Configuration Reference

init( config )
ParameterTypeRequiredDescription
userIdstringREQUIREDThe RAMFi user ID of the account being linked. Obtain it from your backend after the user authenticates with RAMFi.
onErrorfunctionREQUIREDCalled when an SDK-level error occurs. See Callback Reference below.
onLinkExitfunctionOPTIONALCalled when the PayPal flow ends for any reason — success, failure, or the user closed the popup.
open( credentials )

Must be called directly from a user gesture (button click). Fetch credentials from your backend immediately before each call.

ParameterTypeDescription
tokenstringRAMFi API bearer token for the authenticated user. Obtain it from your backend — never hardcode it in client-side code.
totpstringOne-time security code generated by your backend using the RAMFi-provided secret. Fetch fresh for each open() call — do not reuse across sessions.

Callback Reference

onLinkExit( result )

Called when the PayPal flow ends for any reason. Check result.status: SUCCESS (linked and validated), FAILED (could not be validated), or ACTION_ABANDONED (user closed the popup without completing).

PropertyTypeWhen presentDescription
statusstringAlways'SUCCESS' | 'FAILED' | 'ACTION_ABANDONED'
transactionIdstringSUCCESS, FAILEDThe RAMFi transaction ID for this linking session. On SUCCESS, pass it to your backend to initiate a WalletTransfer.
errorMessagestringFAILEDHuman-readable reason the connection failed. Safe to display directly to the user (e.g. “Your name on PayPal doesn’t match our records.”).
onError( error )

Called when an SDK-level error occurs before or during the flow. The error object has a code and a message.

CodeCause
OPEN_ERRORFailed to start the PayPal session — check that the credentials are valid.
POPUP_ERRORAn unexpected error occurred in the popup.
STATE_ERRORThe response from PayPal could not be verified — do not retry automatically.
STATE_MISMATCHThe response from PayPal does not match the initiated session — possible replay attack.
VALIDATE_ERRORRAMFi could not validate the PayPal authorisation.
TIMEOUT_ERRORThe session expired before the flow could complete — ask the user to try again.

Complete Example

HTML <button id="connectBtn">Connect PayPal</button> <script src="https://FQDN/paypal-connect/{version}/sdk.umd.js"></script> <script> const sdk = new PayPalConnectSDK(); sdk.init({ userId: currentUser.ramfiUserId, onError(error) { showErrorBanner(error.message); }, onLinkExit(result) { if (result.status === 'SUCCESS') { showSuccessBanner('PayPal account linked!'); // Pass transactionId to backend to initiate the payout myBackend.initiateWalletTransfer(result.transactionId); } else if (result.status === 'FAILED') { showErrorBanner(result.errorMessage || 'Connection failed. Please try again.'); } // ACTION_ABANDONED — user closed popup, no action needed } }); document.getElementById('connectBtn').addEventListener('click', async () => { const { token, totp } = await myBackend.getRamfiCredentials(); sdk.open({ token, totp }); }); </script>

React Integration Example

JSX function ConnectPayPalButton({ ramfiUserId }) { const sdkRef = useRef(null); useEffect(() => { const sdk = new window.PayPalConnectSDK(); sdk.init({ userId: ramfiUserId, onError: (err) => setError(err.message), onLinkExit: (result) => { if (result.status === 'SUCCESS') { setLinked(true); myBackend.initiateWalletTransfer(result.transactionId); } else if (result.status === 'FAILED') { setError(result.errorMessage || 'Connection failed.'); } } }); sdkRef.current = sdk; return () => sdk.destroy(); }, [ramfiUserId]); const handleConnect = async () => { const { token, totp } = await myBackend.getRamfiCredentials(); sdkRef.current?.open({ token, totp }); }; return <button onClick={handleConnect}>Connect PayPal</button>; }

Required Backend API Calls

The SDK handles the PayPal OAuth flow entirely, but your server must also call these RAMFi backend endpoints.

0. Check if the user already has PayPal registered

Call this before initialising the SDK. If userRegistered is true, skip the SDK flow and proceed directly to WalletTransfer using the returned transactionId.

HTTP GET api/Disbursement/UserRegistered/{userId}/{paymentType}
ParameterLocationTypeDescription
userIdRouteGuidThe RAMFi user ID.
paymentTypeRouteintPayment type — use 6 for PayPal.

Response — WalletInformation

PropertyTypeDescription
userRegisteredbooleantrue if the user has an active, linked PayPal transfer method on file.
transactionIdstringThe existing portal request token — pass to WalletTransfer if userRegistered is true to skip the SDK flow.
1. Get session credentials (before sdk.open)

Your backend must obtain a fresh token and totp for each SDK session — the standard RAMFi auth values: obtain the bearer token via the authentication flow and generate the TOTP from the RAMFi-provided secret.

2. Initiate fund transfer (after SUCCESS)

After onLinkExit fires with status: 'SUCCESS', your backend calls WalletTransfer to initiate the disbursement.

HTTP POST api/RAMFiDisbursement/WalletTransfer/{campaignId}/{disbursementToken}/{transactionId} Authorization: Bearer {token} Content-Type: application/json // Body is optional — omit to use the disbursement record amount { "amount": 250.00 }
ParameterLocationTypeDescription
campaignIdRouteGuidThe RAMFi campaign identifier for this disbursement.
disbursementTokenRouteGuidThe user’s disbursement access token.
transactionIdRoutestringThe transactionId received from onLinkExit on SUCCESS.
amountBodydecimalOptional. Override disbursement amount; if omitted, the amount on the disbursement record is used.

Integration Pattern: PayPal Disbursement Onboarding

1

Get credentials

Your backend fetches a fresh token and totp for the user’s RAMFi session.

2

Initialise SDK

Call sdk.init() with the user’s RAMFi user ID and callbacks — once per page load.

3

Connect PayPal

On button click, pass the fresh credentials to sdk.open().

4

Handle result

onLinkExit fires — check result.status.

5

Initiate transfer (SUCCESS only)

Your backend calls WalletTransfer with result.transactionId.

6

Show outcome

Display confirmation or error based on the WalletTransfer response.

Best Practices

Open from a user gesture. Always call sdk.open() directly from a click handler — browsers block popups opened outside a user gesture.
Fresh credentials every time. Fetch token and totp immediately before each sdk.open(); never cache or reuse them across sessions.
Mind the session timeout. If the user does not finish the PayPal login within 10 minutes, the SDK closes the popup and calls onLinkExit with status: 'FAILED' and errorMessage: 'Session expired. Please try again.'
One instance per session. Create one SDK instance and call sdk.destroy() on unmount to clean up listeners.
Only transfer on SUCCESS. Use result.transactionId with WalletTransfer only when status is SUCCESS.
HTTPS required. PayPal OAuth needs HTTPS; the SDK will not work on plain HTTP pages.
RAMFi Developer Documentation · Version 1.1