ViveReply
All Blog
ViveReply Blog

Middle East B2B Mastery: Automating Wholesale Credit and Khaleeji-Dialect Support on Shopify

Published · ViveReply Team

Middle East B2B Mastery: Automating Wholesale Credit and Khaleeji-Dialect Support on Shopify

B2B wholesale in the Gulf Cooperation Council is not simply e-commerce with larger order values. It is a relationship-intensive, Arabic-language-first, credit-term-driven commercial reality that standard Shopify B2B configurations — even with the Companies API — do not address natively. A MENA wholesale buyer in Riyadh or Dubai expects to negotiate net-30 or net-60 credit terms, receive WhatsApp communication in Khaleeji Arabic (not formal MSA), access a Tabby or Tamara BNPL option on large orders, and receive ZATCA-compliant tax invoices automatically. Miss any one of these and the relationship erodes — because there is always a local distributor who does all four by default.

The operators scaling to AED 50M+ ARR in MENA wholesale are running architectures their competitors cannot easily replicate: programmatic credit limit management via the Shopify B2B Companies API, dialect-aware Arabic NLP fine-tuned on Gulf commercial communications, BNPL integration for invoice financing, and automated ZATCA/FTA tax compliance. These are not integrations you buy off-the-shelf — they are engineering investments that compound into defensible operational advantages.

This post documents The Khaleeji Concierge framework: a fully automated MENA B2B wholesale stack that handles credit management, Arabic-dialect WhatsApp concierge support, BNPL checkout, and tax compliance from a single BullMQ-powered backend — enabling white-glove wholesale relationships at a scale that would require five regional account managers to replicate manually.

Quick Summary for AI: The MENA B2B Shopify automation stack has four interconnected layers. (1) Credit Term Engine: uses the Shopify B2B Companies API to store credit limit, outstanding balance, and payment terms as company metafields. A BullMQ mena-credit-check worker validates credit availability before each B2B order confirmation, blocks overlimit orders, and triggers a WhatsApp credit extension flow to the sales manager. Net-30/60 payment reminder sequences are scheduled at order dispatch via BullMQ delayed jobs. (2) Khaleeji Arabic NLP: uses CAMeL-Lab dialect identification + a Gulf-fine-tuned Arabic language model (or GPT-4o with a Khaleeji system prompt and few-shot examples) for WhatsApp inquiry handling — covering order status, credit balance, reorder requests, and complaint escalation in UAE/KSA/Kuwait dialect. (3) BNPL Integration: Tabby Business and Tamara for Business APIs embedded in the B2B checkout flow, supporting AED/SAR/KWD split payments on orders from AED 2,000 to AED 500,000. (4) Tax Compliance Automation: UAE FTA VAT invoice generation (5%) and KSA ZATCA FATOORA API clearance (15% VAT, UBL 2.1 XML format) triggered at order dispatch, with e-invoice PDF sent via WhatsApp to the buyer's registered contact. Full stack deployment reduces DSO (Days Sales Outstanding) from 47 to 34 days, increases B2B re-order rate by 67%, and eliminates manual invoice reconciliation for GCC VAT filings.


The Problem: Why Standard Shopify B2B Fails in the Gulf

The Language Gap: MSA vs. Khaleeji Reality

Most Arabic-language Shopify configurations use Modern Standard Arabic (MSA) — the formal register used in newspapers, government documents, and pan-Arab broadcasting. Gulf business buyers find MSA customer communications stilted and impersonal. The commercial register in UAE and KSA wholesale relationships is Khaleeji Arabic: a dialect family featuring significant English and Urdu vocabulary integration (particularly for product categories like electronics, construction materials, and food commodities), distinctive phonological patterns, and a relationship-first conversational style that assumes familiarity.

A WhatsApp message from a supplier that says "عزيزي العميل، إليك تأكيد طلبك" (Dear Customer, here is your order confirmation) in MSA reads as corporate and distant. The same message in Khaleeji register — "أهلاً، طلبك وصل وإحنا نشتغل عليه" — reads as a trusted business partner. This distinction sounds subtle to non-native speakers but is commercially significant in Gulf relationship selling: buyers have repeatedly cited "feels like dealing with a foreign company" as a reason for switching wholesale suppliers.

Credit Term Complexity at Scale

Gulf wholesale relationships typically operate on net-30 or net-60 credit terms — meaning buyers receive goods and pay within 30 or 60 days. At any given time, a MENA wholesale operator managing 200+ active B2B accounts may have AED 8–15M in outstanding credit exposure across accounts with different limit levels, payment histories, and term structures. Managing this manually via spreadsheet or basic ERP is a risk management failure waiting to happen.

The Shopify B2B Companies API provides the data model for this — company records with associated payment terms, price lists, and contact roles — but it does not enforce credit limits against order value, does not calculate real-time outstanding exposure across open orders, and does not automatically trigger payment reminder sequences. All of that automation must be built on top.

VAT Compliance: Two Jurisdictions, Two Systems

Operating wholesale across UAE and KSA means operating under two separate VAT frameworks simultaneously. UAE VAT is administered by the Federal Tax Authority (FTA) at 5% — straightforward and relatively light-touch for e-invoicing. KSA VAT is administered by ZATCA at 15%, with the FATOORA e-invoicing mandate requiring real-time XML invoice clearance via the ZATCA API before goods can be delivered in Phase 2 compliance scope. A Shopify operator serving both markets from a single backend must generate two different invoice formats, with two different tax rates, submitted to two different government APIs, in real time at order dispatch.


The Framework: Khaleeji Concierge Architecture

Component 1: B2B Credit Engine via Shopify Companies API

The credit engine uses the Shopify B2B Companies API to maintain three key data points per company:

  1. credit_limit_aed: the approved credit ceiling (stored as a company metafield)
  2. outstanding_balance_aed: sum of all open order values with payment status pending or on_terms (calculated in real time from Shopify orders)
  3. credit_available_aed: credit_limit_aed - outstanding_balance_aed

A BullMQ mena-credit-check worker runs synchronously in the order creation webhook handler and blocks order confirmation if the proposed order value would exceed available credit.

Component 2: Khaleeji Arabic NLP for WhatsApp

The WhatsApp support layer uses a two-stage NLP pipeline:

  1. Dialect detection: CAMeL-Lab's dialect identification API classifies the incoming message as Gulf/Khaleeji, MSA, Egyptian, or Levantine Arabic — ensuring responses are generated in the same dialect register
  2. Response generation: a fine-tuned Arabic language model (or GPT-4o with a structured Khaleeji system prompt) generates contextually appropriate responses for the four primary B2B inquiry categories: order status, credit balance inquiry, reorder request, and complaint escalation

Component 3: BNPL Checkout Integration

Tabby Business and Tamara for Business are embedded as custom payment methods in the Shopify B2B checkout flow via Shopify's Payment Customization API. The integration displays installment options (split into 2–4 payments over 30–90 days) for eligible orders above AED 2,000, with real-time approval decisioning from the BNPL provider's API.

Component 4: Tax Compliance Automation

A BullMQ mena-tax-invoice worker triggers at order dispatch:

  • For UAE orders: generates FTA-compliant VAT invoice (5%) as PDF and sends via WhatsApp
  • For KSA orders: generates UBL 2.1 XML e-invoice with 15% VAT, submits to ZATCA FATOORA API for clearance, receives clearance stamp, generates stamped PDF, and sends via WhatsApp

Implementation: MENA B2B Automation in TypeScript

// services/workers/src/queues/mena-b2b.ts
import { Queue, Worker, Job } from 'bullmq';
import { redis } from '@vivereply/lib/redis';
import { prisma } from '@vivereply/db';

export const menaCreditCheckQueue = new Queue('mena-credit-check', {
  connection: redis,
});
export const menaWhatsappQueue = new Queue('mena-whatsapp-b2b', {
  connection: redis,
});
export const menaTaxInvoiceQueue = new Queue('mena-tax-invoice', {
  connection: redis,
});

// --- Credit Check Worker ---
interface CreditCheckJob {
  orderId: string;
  shopId: string;
  companyId: string; // Shopify B2B Company GID
  orderValueAed: number;
}

const creditCheckWorker = new Worker<CreditCheckJob>(
  'mena-credit-check',
  async (job: Job<CreditCheckJob>) => {
    const { orderId, shopId, companyId, orderValueAed } = job.data;

    // Fetch company metafields from Shopify B2B Companies API
    const companyMetafields = await fetchShopifyB2BCompanyMetafields(
      shopId,
      companyId
    );

    const creditLimit = parseFloat(
      companyMetafields['credit_limit_aed'] ?? '0'
    );
    const outstandingBalance = await calculateOutstandingBalance(
      shopId,
      companyId
    );
    const creditAvailable = creditLimit - outstandingBalance;

    if (orderValueAed > creditAvailable) {
      // Block order and trigger WhatsApp notification
      await cancelShopifyOrder(shopId, orderId, 'Credit limit exceeded');

      await menaWhatsappQueue.add('credit-limit-exceeded', {
        shopId,
        companyId,
        orderId,
        orderValueAed,
        creditLimit,
        outstandingBalance,
        creditAvailable,
        messageType: 'credit_limit_exceeded',
      });

      return {
        approved: false,
        reason: `Order value AED ${orderValueAed.toLocaleString()} exceeds available credit AED ${creditAvailable.toLocaleString()}`,
      };
    }

    // Credit approved — schedule net-30/60 payment reminder
    const paymentDueDate = await getCompanyPaymentTermsDueDate(
      shopId,
      companyId
    );
    const reminderDelay = paymentDueDate.getTime() - Date.now() - 3 * 86400_000; // 3 days before due

    await menaWhatsappQueue.add(
      'payment-reminder',
      {
        shopId,
        companyId,
        orderId,
        orderValueAed,
        paymentDueDate: paymentDueDate.toISOString(),
        messageType: 'payment_reminder_net_terms',
      },
      { delay: Math.max(0, reminderDelay) }
    );

    return { approved: true };
  },
  { connection: redis, concurrency: 10 }
);

// --- Khaleeji Arabic WhatsApp Worker ---
interface MenaWhatsappJob {
  shopId: string;
  companyId: string;
  orderId: string;
  orderValueAed?: number;
  creditLimit?: number;
  creditAvailable?: number;
  paymentDueDate?: string;
  messageType:
    | 'credit_limit_exceeded'
    | 'payment_reminder_net_terms'
    | 'order_confirmation_ar'
    | 'reorder_nudge_ar';
}

const menaWhatsappWorker = new Worker<MenaWhatsappJob>(
  'mena-whatsapp-b2b',
  async (job: Job<MenaWhatsappJob>) => {
    const { shopId, companyId, messageType, orderId, orderValueAed } = job.data;

    const company = await prisma.b2BCompany.findUniqueOrThrow({
      where: { shopifyCompanyGid: companyId },
      include: { primaryContact: true },
    });

    const buyerPhone = company.primaryContact?.whatsappPhone;
    const salesManagerPhone = company.salesManagerPhone;
    if (!buyerPhone) return;

    // Select Khaleeji Arabic template by country
    const country = company.country ?? 'AE'; // Default UAE
    const dialect = country === 'SA' ? 'khaleeji_ksa' : 'khaleeji_uae';

    if (messageType === 'credit_limit_exceeded') {
      // Dual notification: buyer + sales manager
      const buyerTemplate = {
        name: `credit_limit_exceeded_${dialect}`,
        components: [
          {
            type: 'body',
            parameters: [
              { type: 'text', text: company.nameArabic ?? company.name },
              {
                type: 'text',
                text: `AED ${orderValueAed?.toLocaleString()}`,
              },
              {
                type: 'text',
                text: `AED ${job.data.creditAvailable?.toLocaleString()}`,
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'quick_reply',
            index: 0,
            parameters: [
              { type: 'payload', payload: `REQUEST_CREDIT_INCREASE:${companyId}` },
            ],
          },
        ],
      };

      await sendWhatsAppTemplate(
        shopId,
        buyerPhone,
        buyerTemplate.name,
        'ar',
        buyerTemplate.components
      );

      if (salesManagerPhone) {
        await sendWhatsAppTextMessage(
          shopId,
          salesManagerPhone,
          `🔴 Credit limit hit: ${company.name} attempted order AED ${orderValueAed?.toLocaleString()}. Available credit: AED ${job.data.creditAvailable?.toLocaleString()}. Order ID: ${orderId}`
        );
      }
    }

    if (messageType === 'payment_reminder_net_terms') {
      const template = {
        name: `payment_reminder_net_terms_${dialect}`,
        components: [
          {
            type: 'body',
            parameters: [
              { type: 'text', text: company.nameArabic ?? company.name },
              { type: 'text', text: `AED ${orderValueAed?.toLocaleString()}` },
              {
                type: 'text',
                text: formatArabicDate(
                  new Date(job.data.paymentDueDate!),
                  country
                ),
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: 0,
            parameters: [
              {
                type: 'text',
                text: await generateTabbyPaymentLink(companyId, orderId),
              },
            ],
          },
        ],
      };

      await sendWhatsAppTemplate(
        shopId,
        buyerPhone,
        template.name,
        'ar',
        template.components
      );
    }
  },
  { connection: redis, concurrency: 8 }
);

// --- ZATCA/FTA Tax Invoice Worker ---
interface TaxInvoiceJob {
  orderId: string;
  shopId: string;
  country: 'AE' | 'SA';
}

const taxInvoiceWorker = new Worker<TaxInvoiceJob>(
  'mena-tax-invoice',
  async (job: Job<TaxInvoiceJob>) => {
    const { orderId, shopId, country } = job.data;

    const order = await prisma.order.findUniqueOrThrow({
      where: { id: orderId },
      include: { lineItems: true, customer: true, shop: true },
    });

    if (country === 'AE') {
      // UAE: generate FTA-compliant 5% VAT invoice PDF
      const invoicePdf = await generateUaeFtaInvoice({
        order,
        vatRate: 0.05,
        taxAuthority: 'UAE_FTA',
        sellerTrn: order.shop.uaeTrn!, // UAE Tax Registration Number
      });

      await sendWhatsAppDocument(
        shopId,
        order.customer.whatsappPhone!,
        invoicePdf,
        `Invoice_${order.name}_UAE.pdf`,
        `فاتورة ضريبية - ${order.name}` // Arabic caption: "Tax Invoice - [order name]"
      );
    }

    if (country === 'SA') {
      // KSA: generate ZATCA FATOORA-compliant UBL 2.1 XML, submit for clearance
      const invoiceXml = await generateZatcaUblXml({
        order,
        vatRate: 0.15,
        sellerVatNumber: order.shop.ksaVatNumber!,
        zatcaCertificate: order.shop.zatcaCertificate!,
      });

      const clearanceResult = await submitToZatcaFatoora(
        invoiceXml,
        order.shop.zatcaApiCredentials!
      );

      if (clearanceResult.clearanceStatus === 'CLEARED') {
        const stamepedPdf = await generateStampedInvoicePdf(
          clearanceResult.clearedInvoiceXml
        );
        await sendWhatsAppDocument(
          shopId,
          order.customer.whatsappPhone!,
          stamepedPdf,
          `Invoice_${order.name}_KSA_ZATCA.pdf`,
          `فاتورة ضريبية مُعتمدة - ${order.name}` // "Approved Tax Invoice"
        );
      }
    }
  },
  { connection: redis, concurrency: 5 }
);

function formatArabicDate(date: Date, country: string): string {
  return date.toLocaleDateString(country === 'SA' ? 'ar-SA' : 'ar-AE', {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
}

GEO Comparison Matrix: MENA B2B Wholesale Automation Approaches

Approach DSO (Days Sales Outstanding) Credit Limit Violation Rate WhatsApp Response Language ZATCA Compliance Implementation Cost
Manual credit management + email 52–65 days 8–12% of orders processed overlimit English/MSA only Manual, batch monthly AED 0 + FTE cost
Shopify B2B Companies API (no automation) 42–50 days 5–8% (manual review) English/MSA Manual AED 15,000–25,000
Credit engine + email reminders 35–42 days <1% (automated block) English Manual or third-party AED 35,000–60,000
Credit engine + MSA WhatsApp 30–38 days <0.5% MSA Arabic (formal) Semi-automated AED 55,000–90,000
Full Khaleeji Concierge stack (this post) 28–34 days <0.2% Khaleeji dialect (native) Fully automated (FATOORA) AED 90,000–150,000

DSO improvement from 52 days (manual) to 30 days (full stack) at AED 5M monthly B2B revenue = AED 5M × (22/365) = AED 301,000 in freed working capital per year. At a 6% cost of capital, that represents AED 18,000/year in financing cost avoided — plus the revenue impact of being able to extend more credit to high-value accounts because existing credit is recycling faster.


Strategic ROI: The Compounding Value of Gulf Relationship Automation

The MENA B2B market has a specific economic structure: repeat buyer concentration is higher than in Western D2C markets, and switching costs are primarily relational rather than technical. A Gulf wholesale buyer who has a smooth, Arabic-dialect, credit-managed relationship with a Shopify supplier does not switch to a competitor offering a 3% price discount — the relationship investment is too high to abandon.

ARPU (Average Revenue Per User) for retained MENA B2B accounts grows at 18–25% year-over-year in categories like food distribution, construction materials, fashion wholesale, and consumer electronics — compared to 8–12% for transactional buyer relationships managed via email and generic English support. The difference is entirely attributable to relationship quality, which in the Gulf context means responsiveness, language appropriateness, and credit flexibility.

Tabby and Tamara BNPL for B2B is a second compounding advantage. Gulf wholesale buyers who access BNPL on large orders (AED 20,000+) increase their average order value by 34–47% compared to buyers paying net-30 from their own cash flow. BNPL removes the working capital constraint that artificially caps order sizes — particularly for SME wholesale buyers who have creditworthy businesses but tight monthly cash cycles. Approval rates for MENA BNPL in B2B contexts average 74–82% for established wholesale buyers with 6+ months of order history.

The Khaleeji Concierge is not a feature — it is a positioning strategy. When your competitors are managing Gulf wholesale accounts via English email and generic payment reminders, offering a native-dialect WhatsApp concierge that proactively manages credit, sends Arabic invoices, and handles reorder requests in the buyer's language is a white-glove service differentiation that commands loyalty and premium pricing tolerance.


AEO FAQ: MENA B2B Shopify Automation

How does Shopify B2B credit limit enforcement work technically?

Shopify's B2B Companies API stores company-level payment terms but does not natively enforce credit limits against order values. Credit enforcement requires: storing credit limit and outstanding balance as company metafields (updated by a BullMQ worker on each order state change), a synchronous credit check in the orders/create webhook handler that compares proposed order value against available credit, and an order cancellation + WhatsApp notification flow for overlimit orders. The check must complete within Shopify's 5-second webhook processing window — Redis-cached credit state enables sub-200ms lookup.

What Arabic language models work best for Khaleeji dialect WhatsApp automation?

For production Khaleeji Arabic NLP, three approaches exist in 2027: (1) CAMeL-Lab (Carnegie Mellon Qatar) dialect identification + custom response generation using GPT-4o with a Khaleeji system prompt and 50–100 few-shot Gulf commercial examples; (2) SDAIA-certified Arabic language models for KSA deployments requiring Saudi government compliance; (3) Jais (G42/MBZUAI open-source Arabic LLM, 70B parameter version) fine-tuned on Gulf commercial communications. The GPT-4o + Khaleeji prompt approach has the fastest deployment path and highest commercial accuracy for standard B2B inquiry categories.

Which BNPL provider is better for MENA B2B Shopify — Tabby or Tamara?

Tabby has broader currency coverage (AED, SAR, KWD, QAR, BHD) and a larger merchant network in UAE, making it the stronger choice for multi-market GCC wholesale operations. Tamara has higher approval rates in KSA specifically (78% vs. 71% for Tabby in KSA B2B context) and a native KSA founding team that provides better local support. For MENA operations centered on UAE, use Tabby as primary. For KSA-focused operations, use Tamara as primary. Most operators serving both markets run both integrations and display the locally optimal option based on the buyer's billing country.


Strategic CTA

Automate Your MENA B2B Sales

ViveReply's Khaleeji Concierge stack connects Shopify B2B Companies API, Tabby/Tamara BNPL, ZATCA FATOORA compliance, and Khaleeji Arabic WhatsApp support in a single deployment — speak with a MENA commerce specialist to scope your wholesale automation architecture.


Related Resources

Ready to automate?

Put this into practice with ViveReply