Connect a taxpayer
Connecting a business involves two separate approvals: the taxpayer appoints Wafeq FZ LLC (Wafeq e-invoicing ASP) as its Accredited Service Provider in EmaraTax, then grants your app OAuth consent. Onboarding alone does not connect a taxpayer to your portal organization or give your API key access. Knowing a TIN or Taxpayer ID is not enough.
Journey: your app → Wafeq e-invoicing ASP connection page → EmaraTax onboarding, if needed → business verification → OAuth consent → your app's callback.
Prepare your app
In Developer → Settings, obtain your OAuth client ID and secret, and register your callback as an exact redirect URI. Keep the secret on your server. In Live, a new connection also requires an active subscription and an available taxpayer seat.
Start the browser at the matching mode's authorization endpoint:
| Mode | Authorization URL |
|---|---|
| Live | https://portal-einvoicing.wafeq.com/oauth/authorize |
| Sandbox | https://portal-einvoicing.wafeq.com/sandbox/oauth/authorize |
Send response_type=code, client_id, the registered redirect_uri, space-separated scope, code_challenge and code_challenge_method=S256. Generate a fresh PKCE verifier and random state tied to the user's session; retain both for the callback. Optionally send tin_hint to suggest a business, grant_label to name the connection, and external_id for your app's account or workspace. A TIN hint never grants access.
1. The taxpayer onboards
If the business is not onboarded, the connection page guides it to EmaraTax → e-Invoicing, where it selects Wafeq FZ LLC as its ASP. The taxpayer follows EmaraTax's link back to Wafeq e-invoicing ASP, verifies its TIN and the email registered with EmaraTax, and reviews and confirms its business details. Wafeq e-invoicing ASP completes FTA and Peppol registration. The portal shows progress if registration is still processing; verification alone is not completed onboarding.
Start from your app's authorization request so the pending connection can resume after EmaraTax. Once onboarding completes, the portal signs the taxpayer in and continues to consent. An already onboarded business skips onboarding and signs in through a one-time link sent to its FTA-verified email. An existing taxpayer session can go straight to consent. The taxpayer does not need to create a portal organization.
In Sandbox, choose Simulate EmaraTax onboarding instead of visiting EmaraTax. This creates test data and exercises verification and consent without onboarding a Live taxpayer.
2. The taxpayer gives OAuth consent
The consent page names the business and your app and shows the requested permissions. The taxpayer decides whether to connect. Approval creates an organization-to-taxpayer grant with approved scopes. Your app cannot approve on the taxpayer's behalf. A taxpayer can grant access to several apps or workspaces independently.
3. Handle the callback and exchange the code
The portal redirects to your registered callback with code and state. Verify state, then exchange the single-use code from your server at POST https://api.wafeq.com/ae/v1/oauth/token. Send grant_type=authorization_code, code, the same redirect_uri, the original code_verifier, and your client credentials. See the token endpoint for the request schema.
Store the returned taxpayer_id and grant_id against the correct account in your app, and store access and refresh tokens securely. Use the returned identity; do not assume the taxpayer selected was the tin_hint. If consent is declined, the callback receives error=access_denied and no new access is granted.
4. Keep the connection up to date
Use the taxpayer access token, or your organization API key with x-ae-taxpayer-id, as described in Authentication. API keys do not bypass consent. Live and Sandbox clients, grants, tokens and webhook endpoints remain separate.
The taxpayer can later revoke the grant under Connected apps. Subscribe to taxpayer webhooks: taxpayer.created reports first access, taxpayer.updated reports changes while access remains, and taxpayer.deleted reports loss of the last active grant.
Updated 5 days ago