Geocompliance
Geocompliance enforces geographic restrictions on money movement. Frame Sonar — running in your client via frame-js or a mobile SDK — captures the account holder's location continuously; at charge time, Frame evaluates that location against your platform's geofences and blocks the transaction before it reaches the network if the account holder is inside a restricted territory.
Geocompliance is a background service. There's no hosted UX for the account holder, no consent screen, no "verify your location" step. The capability sits on the account; enforcement happens at the moment a charge is created.
Geocompliance requires Frame Sonar to be initialized in your client (frame-js, Frame iOS, or Frame Android SDK). Without a valid Sonar session, charges on geocompliance-enabled accounts are blocked — there's no fallback to "we don't have data, allow it." Geocompliance fails closed by design.
When to use it
Request geo_compliance on accounts where regulatory or platform policy requires keeping money movement out of specific jurisdictions:
- Gaming and gambling platforms blocking states where their license doesn't apply.
- Cannabis or alcohol platforms restricted to licensed jurisdictions.
- Sanctions-adjacent compliance where a buyer's physical location matters more than their billing address.
- Any product where "where the account holder physically is right now" is a policy input.
If the policy concerns the destination of money (a payout to a sanctioned country, for example), that's a different shape — geocompliance evaluates the account holder's current location, not destination economics.
How it works
Location capture
When your client initializes Frame Sonar (automatically on Frame.init(), or whatever the mobile-SDK equivalent is), Sonar runs in the background and captures location signals. The captured location is bound to a Sonar session scoped to that client instance and associated with the account.
VPN detection runs alongside location capture. A detected VPN doesn't block account creation but does flag the session — and a flagged session can be blocked at transaction time depending on your platform's policy.
Evaluation at transaction time
When you create a charge for an account with geo_compliance active, Frame:
- Pulls the account's most recent Sonar session.
- Evaluates the location against your platform's geofences (Frame-provided defaults plus any custom ones configured for your account).
- Returns a binary outcome — proceed or block — before the charge hits the network.
The GET/v1/accounts/{account_id}/geo_compliance endpoint returns the current evaluation as a status + reason pair:
status | reason (typical values) | Charge outcome |
|---|---|---|
clear | — | Charge proceeds |
blocked | restricted_territory, vpn_detected | Charge rejected |
unknown | no_location_data | Charge rejected (fails closed) |
You can pre-query an account's evaluation state if you want to check before initiating a charge — surface a "this product isn't available in your region" message in your UI rather than letting the charge attempt fail.
Charge-time block error codes
When a charge is blocked at transfer-create time, the failure carries a distinct error code (separate from the reason field on the evaluation endpoint above):
geo_compliance_blocked— the account holder's location is inside a restricted geofence.geo_compliance_vpn_detected— a VPN was detected on the session, and your platform's policy treats VPN-flagged sessions as restricted.sonar_session_required— no Sonar session exists for this account (the client didn't initialize Sonar, or the session expired).
Geofences
A geofence is a geographic boundary plus a set of rules. Frame ships with platform-level defaults covering common regulatory cases (state-level boundaries for gaming, etc.) that apply automatically once geocompliance is enabled on your platform.
Two geofence shapes:
- Polygon — state, regional, or arbitrarily shaped boundaries.
- Circle — radius-based restrictions around a point.
Each geofence has one or more rules with a trigger and an action:
| Trigger | Description |
|---|---|
enter | Block when the account holder crosses into the area |
exit | Block when the account holder leaves the area |
dwell | Block after the account holder has been inside the area for a configured duration |
Custom geofences (different shapes, different rules, different jurisdictions than the defaults) are configured per-platform — talk to Frame about your specific needs.
Enabling geocompliance
Geocompliance is platform-gated — it has to be enabled on your account by Frame before you can request the geo_compliance capability on individual accounts. Reach out to Frame support to enable it. Once enabled:
- Make sure Frame Sonar is initialized in your client (frame-js, iOS, Android — whichever your platform uses).
- Add
geo_complianceto thecapabilitiesarray when creating accounts. - Frame handles the rest at charge time.
Requesting geo_compliance on a platform where it hasn't been enabled returns a 422 validation error with a message indicating geocompliance is not enabled for the merchant.
Platform scope
Frame Sonar runs in frame-js (browser) and in the native iOS / Android SDKs. The signal quality and refresh cadence depend on the client SDK and the user's device permissions — browser-based Sonar uses standard geolocation APIs; mobile SDKs use platform-native location services with permission prompts you handle in your app. V1 docs focus on the web flow; the mobile-SDK integration shape lives in the respective SDK docs.
Gotchas
Symptom: every transaction on a geocompliance-enabled account is blocked with sonar_session_required. Why: the client never initialized Frame Sonar before the charge call. Fix: confirm Frame.init() runs on page load (or whatever the mobile-SDK equivalent is) and that the user hasn't blocked geolocation permissions. Geocompliance fails closed — no session, no transaction.
Symptom: a charge succeeds in your test environment but fails in production with geo_compliance_vpn_detected. Why: your test setup is geographically clean; production users are more likely to be on corporate VPNs, mobile-VPN privacy apps, or networks Sonar flags. Fix: decide your platform's VPN policy explicitly — either accept the false positive rate, or work with Frame support to whitelist specific session patterns.
Symptom: an account holder physically moves into a restricted territory mid-session and the next charge succeeds. Why: the session's last location capture may pre-date the move. Sonar refreshes location, but there's a window between capture events. Fix: this is generally acceptable from a compliance standpoint — geofencing operates on captured snapshots, not real-time tracking. If your use case demands stricter freshness, contact Frame support.
Reference
For the geocompliance evaluation endpoint, see GET/v1/accounts/{account_id}/geo_compliance.