<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Erum Qamar</title>
    <description>The latest articles on DEV Community by Erum Qamar (@erum_qamar_3a765d76797704).</description>
    <link>https://dev.to/erum_qamar_3a765d76797704</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3878984%2F55d11d97-ee5c-4859-b3a9-0a64fa9af205.jpeg</url>
      <title>DEV Community: Erum Qamar</title>
      <link>https://dev.to/erum_qamar_3a765d76797704</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erum_qamar_3a765d76797704"/>
    <language>en</language>
    <item>
      <title>How to integrate UAE payment gateways (Telr, PayTabs) into an app</title>
      <dc:creator>Erum Qamar</dc:creator>
      <pubDate>Fri, 22 May 2026 20:47:06 +0000</pubDate>
      <link>https://dev.to/erum_qamar_3a765d76797704/how-to-integrate-uae-payment-gateways-telr-paytabs-into-an-app-4fic</link>
      <guid>https://dev.to/erum_qamar_3a765d76797704/how-to-integrate-uae-payment-gateways-telr-paytabs-into-an-app-4fic</guid>
      <description>&lt;h1&gt;
  
  
  Integrating UAE Payment Gateways into Your App: A Practical Guide to Telr and PayTabs
&lt;/h1&gt;

&lt;p&gt;If you're building a commercial app for the UAE market, you will eventually hit the payment gateway question.&lt;/p&gt;

&lt;p&gt;Stripe works globally but isn't the default choice here. The UAE has its own dominant gateways — &lt;strong&gt;Telr&lt;/strong&gt; and &lt;strong&gt;PayTabs&lt;/strong&gt; are the two you'll encounter most — and while both have documentation, the docs leave a lot of gaps that only show up when you're actually integrating.&lt;/p&gt;

&lt;p&gt;This is the guide I wish existed before we built our first payment flow for a UAE client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use Stripe?
&lt;/h2&gt;

&lt;p&gt;Stripe does operate in the UAE, but there are real reasons local gateways get chosen instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local acquiring banks&lt;/strong&gt; — Telr and PayTabs process through UAE banks, which means lower decline rates on local cards and faster settlement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network International and Mashreq support&lt;/strong&gt; — common UAE card networks that local gateways handle natively&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arabic interface support&lt;/strong&gt; — important for consumer-facing checkouts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance familiarity&lt;/strong&gt; — local gateways understand UAE Central Bank (CBUAE) requirements out of the box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client preference&lt;/strong&gt; — many UAE businesses specifically request a local gateway in their contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most UAE-market apps, you'll be integrating one of these two. Here's how they differ in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Telr vs PayTabs — the practical difference
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Telr&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SDKs: iOS, Android, Web&lt;/li&gt;
&lt;li&gt;Hosted payment page: yes&lt;/li&gt;
&lt;li&gt;Direct API (card data): yes, requires PCI compliance&lt;/li&gt;
&lt;li&gt;Recurring billing: yes&lt;/li&gt;
&lt;li&gt;Multi-currency: yes&lt;/li&gt;
&lt;li&gt;Sandbox: yes&lt;/li&gt;
&lt;li&gt;Documentation: patchy — expect to fill gaps yourself&lt;/li&gt;
&lt;li&gt;Best for: enterprise clients who specifically request it, established UAE merchants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PayTabs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SDKs: iOS, Android, Web, &lt;strong&gt;Flutter&lt;/strong&gt; (official package)&lt;/li&gt;
&lt;li&gt;Hosted payment page: yes&lt;/li&gt;
&lt;li&gt;Direct API (card data): yes, requires PCI compliance&lt;/li&gt;
&lt;li&gt;Recurring billing: yes&lt;/li&gt;
&lt;li&gt;Multi-currency: yes&lt;/li&gt;
&lt;li&gt;Sandbox: yes&lt;/li&gt;
&lt;li&gt;Documentation: better structured, still has gaps&lt;/li&gt;
&lt;li&gt;Best for: Flutter apps, faster integrations, Arabic checkout out of the box&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Flutter SDK is the deciding factor for most mobile projects — PayTabs has one, Telr doesn't. If your client hasn't specified a gateway, start with PayTabs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Telr
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Get your credentials
&lt;/h3&gt;

&lt;p&gt;After creating a merchant account, you'll receive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;store_id&lt;/code&gt; — your merchant identifier&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authkey&lt;/code&gt; — your API authentication key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These go in your server-side environment variables. Never expose them client-side.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a payment order (server-side)
&lt;/h3&gt;

&lt;p&gt;Telr uses a hosted payment page approach for most integrations. You create an order from your backend and redirect the user to Telr's checkout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Node.js example&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createTelrOrder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cancelUrl&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;create&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELR_STORE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authkey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELR_AUTH_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;cartid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 1 = test mode&lt;/span&gt;
      &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Order &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;authorised&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;declined&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cancelUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cancelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cancelUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://secure.telr.com/gateway/order.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes an &lt;code&gt;order.url&lt;/code&gt; — redirect the user there to complete payment.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Handle the return
&lt;/h3&gt;

&lt;p&gt;Telr redirects back to your &lt;code&gt;authorised&lt;/code&gt; or &lt;code&gt;declined&lt;/code&gt; URL with an &lt;code&gt;order_ref&lt;/code&gt; parameter. You then verify the payment status server-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyTelrPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;orderRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELR_STORE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authkey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TELR_AUTH_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orderRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://secure.telr.com/gateway/order.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 3 = authorised, -1 = declined, -2 = cancelled&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Always verify server-side. Never trust a client-side redirect parameter to confirm payment.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Sandbox gotchas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use test card &lt;code&gt;4111 1111 1111 1111&lt;/code&gt; with any future expiry and CVV &lt;code&gt;123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;order.test&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; — forgetting this is the most common mistake in sandbox&lt;/li&gt;
&lt;li&gt;Telr sandbox and production use the same endpoint — the &lt;code&gt;test&lt;/code&gt; flag controls which environment processes the transaction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up PayTabs
&lt;/h2&gt;

&lt;p&gt;PayTabs has a cleaner API structure and better Flutter support, making it the faster integration for mobile-first apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Get your credentials
&lt;/h3&gt;

&lt;p&gt;From your PayTabs merchant dashboard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;profile_id&lt;/code&gt; — your merchant profile&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server_key&lt;/code&gt; — for server-side API calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;client_key&lt;/code&gt; — safe to use client-side (in their SDK)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Create a payment page (server-side)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Node.js example&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createPayTabsPayment&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callbackUrl&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;profile_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PAYTABS_PROFILE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tran_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tran_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ecom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cart_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cart_currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cart_amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cart_description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Order &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;paypage_lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// or 'ar' for Arabic checkout&lt;/span&gt;
    &lt;span class="na"&gt;customer_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customerEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;returnUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;callbackUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// server-to-server notification&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://secure.paytabs.com/payment/request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PAYTABS_SERVER_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// includes redirect_url&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redirect the user to &lt;code&gt;redirect_url&lt;/code&gt; from the response.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Handle the callback (IPN)
&lt;/h3&gt;

&lt;p&gt;PayTabs sends a server-to-server callback to your &lt;code&gt;callback&lt;/code&gt; URL when a transaction completes. This is more reliable than relying on the return redirect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Express.js callback handler&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/payment/callback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tran_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payment_result&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Verify the transaction server-side&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verifyResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://secure.paytabs.com/payment/query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;profile_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PAYTABS_PROFILE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;tran_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PAYTABS_SERVER_KEY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;verifyResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;payment_result&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;response_status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Payment authorised — update your order&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Always return 200 to acknowledge receipt&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Flutter SDK integration
&lt;/h3&gt;

&lt;p&gt;PayTabs maintains an official Flutter package: &lt;code&gt;flutter_paytabs_bridge&lt;/code&gt; on pub.dev.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pubspec.yaml&lt;/span&gt;
&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;flutter_paytabs_bridge:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_paytabs_bridge/PaymentSdkConfigurationDetails.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_paytabs_bridge/flutter_paytabs_bridge.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;startPayment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;PaytabsFlutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;configuration:&lt;/span&gt; &lt;span class="n"&gt;PaymentSDKConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;profileID:&lt;/span&gt; &lt;span class="s"&gt;"your_profile_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;serverKey:&lt;/span&gt; &lt;span class="s"&gt;"your_server_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// use client_key here in mobile&lt;/span&gt;
      &lt;span class="nl"&gt;clientKey:&lt;/span&gt; &lt;span class="s"&gt;"your_client_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;cartID:&lt;/span&gt; &lt;span class="s"&gt;"order_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;cartDescription:&lt;/span&gt; &lt;span class="s"&gt;"Product description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;merchantCountryCode:&lt;/span&gt; &lt;span class="s"&gt;"AE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;currency:&lt;/span&gt; &lt;span class="s"&gt;"AED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;amount:&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;screenTitle:&lt;/span&gt; &lt;span class="s"&gt;"Checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;billingDetails:&lt;/span&gt; &lt;span class="n"&gt;BillingDetails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;"Customer Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="s"&gt;"customer@email.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;countryCode:&lt;/span&gt; &lt;span class="s"&gt;"AE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;callback:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// handle success&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// handle error&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that will catch you out
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. AED is the default but not always the setting&lt;/strong&gt;&lt;br&gt;
Both gateways support multi-currency but default behaviour varies by account configuration. Confirm your merchant account currency settings before going live — a mismatch causes silent failures in sandbox that only appear in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 3D Secure is mandatory for UAE-issued cards&lt;/strong&gt;&lt;br&gt;
UAE banks require 3DS authentication for card-not-present transactions. Both gateways handle this, but your integration needs to account for the additional redirect step in the payment flow. Don't design your UX assuming a single-step checkout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Test with real UAE cards before launch&lt;/strong&gt;&lt;br&gt;
Sandbox test cards pass through without 3DS. Real UAE-issued cards trigger it. Test your complete flow with an actual card in a staging environment before you go live — the 3DS redirect behaviour can break flows that seemed to work perfectly in sandbox.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Callback URLs must be publicly accessible&lt;/strong&gt;&lt;br&gt;
If you're developing locally, use ngrok or a similar tunnel for your callback URL. PayTabs and Telr can't reach &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Idempotency — build it in from the start&lt;/strong&gt;&lt;br&gt;
Network timeouts can cause duplicate payment attempts. Generate a unique &lt;code&gt;cart_id&lt;/code&gt; / &lt;code&gt;order_id&lt;/code&gt; per transaction attempt and check for it before processing. Both gateways will process duplicates if you let them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should you use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Building a Flutter app?&lt;/strong&gt; Start with PayTabs — the official Flutter SDK saves meaningful integration time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise client requiring Telr specifically?&lt;/strong&gt; Telr is fine; just expect to spend more time on the integration and account setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Need Arabic checkout?&lt;/strong&gt; Both support it. PayTabs makes it a single parameter (&lt;code&gt;paypage_lang: 'ar'&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Need recurring billing?&lt;/strong&gt; Both support it. Telr's implementation is more documented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most new projects in the UAE, PayTabs is the faster path to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Telr API docs: &lt;a href="https://docs.telr.com/reference/payment-page" rel="noopener noreferrer"&gt;docs.telr.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PayTabs technical portal: &lt;a href="https://docs.paytabs.com/PT2-API-Endpoints/Introduction/" rel="noopener noreferrer"&gt;docs.paytabs.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PayTabs developer hub: &lt;a href="https://dev.paytabs.com/" rel="noopener noreferrer"&gt;dev.paytabs.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PayTabs Flutter package: &lt;a href="https://pub.dev/packages/flutter_paytabs_bridge" rel="noopener noreferrer"&gt;pub.dev/packages/flutter_paytabs_bridge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PayTabs Postman collection: &lt;a href="https://documenter.getpostman.com/view/14575178/TWDRtfWG" rel="noopener noreferrer"&gt;documenter.getpostman.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;We build mobile and web apps for the UAE market at &lt;a href="https://daiyra.ae" rel="noopener noreferrer"&gt;Daiyra 360 Communications&lt;/a&gt; — payment gateway integration is something we set up on almost every project. If something in this guide is outdated or wrong, drop a comment and we'll update it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>flutter</category>
      <category>javascript</category>
      <category>uae</category>
    </item>
    <item>
      <title>What Nobody Tells You Before Building an App in the UAE</title>
      <dc:creator>Erum Qamar</dc:creator>
      <pubDate>Tue, 14 Apr 2026 17:10:16 +0000</pubDate>
      <link>https://dev.to/erum_qamar_3a765d76797704/what-nobody-tells-you-before-building-an-app-in-the-uae-5ega</link>
      <guid>https://dev.to/erum_qamar_3a765d76797704/what-nobody-tells-you-before-building-an-app-in-the-uae-5ega</guid>
      <description>&lt;p&gt;If you're a business owner in Dubai or anywhere across the UAE, you've probably Googled "app development company near me" at some point—and been immediately overwhelmed.&lt;/p&gt;

&lt;p&gt;Dozens of agencies. Wildly different prices. Promises that all sound identical.&lt;/p&gt;

&lt;p&gt;So you do what most people do: you go with whoever seems affordable and professional enough. That's where the problems begin to arise.&lt;br&gt;
I'm a content writer based in Dubai, and I've spent time researching and writing about the UAE tech landscape. Here's what I keep seeing—and what most businesses find out too late.&lt;/p&gt;

&lt;h2&gt;
  
  
  💸 Cheap doesn't mean cost-effective
&lt;/h2&gt;

&lt;p&gt;There's a big difference between a low upfront quote and an actually affordable project.&lt;/p&gt;

&lt;p&gt;A lot of agencies in the UAE offer tempting starting prices—but those quotes often don't include the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI/UX design (that's separate)&lt;/li&gt;
&lt;li&gt;Testing and QA&lt;/li&gt;
&lt;li&gt;Post-launch support&lt;/li&gt;
&lt;li&gt;Revisions beyond a certain number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the time you've signed the contract and work begins, the budget has quietly doubled.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌍 Built for "everywhere" means built for nowhere
&lt;/h2&gt;

&lt;p&gt;Many agencies in the UAE use the same boilerplate app template for every client. Your food delivery app and someone's real estate app might be running on the same skeleton — just reskinned.&lt;/p&gt;

&lt;p&gt;The UAE market has specific needs: Arabic language support, local payment gateway integration (Telr, PayTabs, Network International), UAE PASS compatibility, and compliance with local data regulations.&lt;/p&gt;

&lt;p&gt;An app built generically and "retrofitted" for the UAE market will always underperform one built with the market in mind from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 The cheapest quote is often from the busiest team
&lt;/h2&gt;

&lt;p&gt;Agencies that race to the bottom on price usually do so because they're volume-dependent. They need 15 clients running at once to stay profitable. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project manager is juggling 8 other projects&lt;/li&gt;
&lt;li&gt;Communication gets slow after week 2&lt;/li&gt;
&lt;li&gt;Revisions take longer than building the feature did&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ What to look for instead
&lt;/h2&gt;

&lt;p&gt;Before signing with any app development partner in the UAE, ask these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can you show me apps you've built for UAE-based clients specifically? (Not just a global portfolio)&lt;/li&gt;
&lt;li&gt;Is Arabic support and RTL layout included in your quote?&lt;/li&gt;
&lt;li&gt;Who exactly will be working on my project — in-house or outsourced?&lt;/li&gt;
&lt;li&gt;What does post-launch support look like, and what does it cost?&lt;/li&gt;
&lt;li&gt;What happens if I'm not happy with the result?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The answers tell you everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The UAE's app market is growing fast—valued at $1.34 billion in 2024 and projected to reach $2.36 billion by 2030. That kind of growth attracts both excellent agencies and opportunistic ones.&lt;/p&gt;

&lt;p&gt;Doing your homework before you sign isn't just smart — it's the difference between a product that works and one that costs you twice to fix.&lt;/p&gt;

&lt;p&gt;You can find more of my insights on app development, digital products, and the UAE tech landscape over at &lt;a href="https://daiyra.ae/" rel="noopener noreferrer"&gt;daiyra 360 Communications&lt;/a&gt;&lt;/p&gt;

</description>
      <category>uae</category>
      <category>mobile</category>
      <category>career</category>
    </item>
  </channel>
</rss>
