EcomSolveBD

· বাংলাদেশ সময়

Next.js ইন্টিগ্রেশন

Next.js শপ EcomSolveBD-তে কানেক্ট করুন

  1. অ্যাকাউন্ট খুলুন

    আপনি
    • ecomsolvebd.com এ রেজিস্টার / লগইন
    • ড্যাশবোর্ডে ঢুকুন
  2. Custom / Headless → Next.js

    আপনি
    • Integrations → Custom / Headless → Next.js
    • শপ URL দিন — https://myshop.com
    • চাইলে GA4 ID (G-…)
    • Connect Next.js চাপুন

    Tracking Merchant ID + Webhook Secret কপি করুন — Secret এখনই সেভ করুন।

  3. ডেভেলপারকে পাঠান

    আপনি
    • Tracking Merchant ID
    • Webhook Secret
    • লাইভ শপ URL
  1. ডেভেলপার: SDK কন্ট্রাক্ট

    ডেভেলপার
    • npm install @ecomsolvebd/next
    • Path contract: collect + attribution-config + order-status
    • Root layout: EsbTracker (funnelAuto={false} recommended)
    • Host maps checkout → postOrder + esbTrack call sites
    • নিচের SDK reference — ডেমো শপ কপি নয়

    প্রতি স্টোরের cart/ORM আলাদা — শুধু কন্ট্রাক্ট ইমপ্লিমেন্ট করুন।

    ↓ SDK রেফারেন্স
  2. টেস্ট করুন

    দুজনে
    • শপ হোম → Events-এ page_view
    • টেস্ট অর্ডার → Dashboard → Orders
    • SaaS স্ট্যাটাস বদলান → Next.js চেক
    • https://yoursite.com/feed/products.xml

SDK রেফারেন্স

@ecomsolvebd/next — App Router

ইন্টিগ্রেশন SDK — path কন্ট্রাক্ট + factories। স্টোর বিল্ড (কার্ট, ORM, CMS, UI) হোস্টের। ডেমো শপ কপি করবেন না; কন্ট্রাক্ট ইমপ্লিমেন্ট করুন।

কন্ট্রাক্ট

Path contract (host must expose these; package does not inject files):

  POST|GET  /api/ecomsolvebd/collect
  GET|POST  /api/ecomsolvebd/attribution-config
  POST      /api/ecomsolvebd/order-status

Exports:
  @ecomsolvebd/next                 → buildOrderPayload, OrderWebhookPoster, …
  @ecomsolvebd/next/client          → EsbTracker (sets window.esbTrack)
  @ecomsolvebd/next/route-handlers  → create*RouteHandlers factories

Out of scope for this SDK: your catalog UI, cart store, ORM, CMS, checkout UX.
Prefix paths with src/ when using src/app.

Identity: never fabricate visitor ids. Forward Cookie via buildOrderPayload(..., { cookieHeader }).

১) ইনস্টল npm install @ecomsolvebd/next

  1. 2) Environment

    Merchant Key + Webhook Secret ড্যাশবোর্ড Connect থেকে। Secret শুধু সার্ভার রানটাইমে।

    .env
    ECOMSOLVEBD_API_BASE=https://api.ecomsolvebd.com
    ECOMSOLVEBD_MERCHANT_KEY=<tracking_merchant_id>
    ECOMSOLVEBD_WEBHOOK_SECRET=<webhook_secret>
    ECOMSOLVEBD_GA4_MEASUREMENT_ID=G-XXXXXXXX   # optional
    NEXT_PUBLIC_STORE_URL=https://your-store.example
    # ECOMSOLVEBD_DEPLOY_ENV=staging            # when connected via staging dashboard
  2. 3) Browser tracker

    EsbTracker transport মাউন্ট করে (window.esbTrack)। funnelAuto={false} = হোস্ট ইভেন্ট ওয়্যারিং।

    root layout
    // Root layout — path may be app/layout.tsx or src/app/layout.tsx
    import { EsbTracker } from "@ecomsolvebd/next/client";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <EsbTracker
              merchantKey={process.env.ECOMSOLVEBD_MERCHANT_KEY!}
              // Public store origin (scheme + host). Used to build same-origin collect URL.
              storeBaseUrl={process.env.NEXT_PUBLIC_STORE_URL!}
              apiBase={process.env.ECOMSOLVEBD_API_BASE}
              deployEnv={process.env.ECOMSOLVEBD_DEPLOY_ENV}
              ga4MeasurementId={process.env.ECOMSOLVEBD_GA4_MEASUREMENT_ID}
              // Prefer explicit host events (see Events API section)
              funnelAuto={false}
            />
            {children}
          </body>
        </html>
      );
    }
  3. 4) Collect proxy

    First-party Auto ladder: browser → same-origin → API। Thin wrapper only.

    app/api/ecomsolvebd/collect/route.ts
    // app/api/ecomsolvebd/collect/route.ts
    import { createCollectRouteHandlers } from "@ecomsolvebd/next/route-handlers";
    
    export const { POST, GET } = createCollectRouteHandlers({
      merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!,
      apiBase: process.env.ECOMSOLVEBD_API_BASE,
      deployEnv: process.env.ECOMSOLVEBD_DEPLOY_ENV,
    });
  4. 5) Attribution config proxy

    Same-origin attribution config — path ঠিক রাখুন।

    app/api/ecomsolvebd/attribution-config/route.ts
    // app/api/ecomsolvebd/attribution-config/route.ts
    import { createAttributionConfigRouteHandlers } from "@ecomsolvebd/next/route-handlers";
    
    export const { GET, POST } = createAttributionConfigRouteHandlers({
      merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!,
      apiBase: process.env.ECOMSOLVEBD_API_BASE,
      deployEnv: process.env.ECOMSOLVEBD_DEPLOY_ENV,
    });
  5. 6) Inbound order status

    SaaS → store। findOrder / updateOrder আপনার persistence-এ ম্যাপ — ORM বাধ্যতামূলক নয়।

    app/api/ecomsolvebd/order-status/route.ts
    // app/api/ecomsolvebd/order-status/route.ts  (or src/app/…)
    import { createOrderStatusRouteHandlers } from "@ecomsolvebd/next/route-handlers";
    
    // Wire find/update to YOUR persistence (Prisma, Drizzle, SQL, REST CMS, …).
    // The factory only needs: load by orderNumber → read status → write status.
    
    export const { POST } = createOrderStatusRouteHandlers({
      webhookSecret: process.env.ECOMSOLVEBD_WEBHOOK_SECRET!,
      allowedStatuses: ["pending", "confirmed", "delivered", "cancelled", "returned"],
      findOrder: async (orderNumber) => {
        // return await db.orders.findByNumber(orderNumber)
        return null; // replace — null → handler reports not found
      },
      getCurrentStatus: (order) => {
        // return order.status
        return (order as { status?: string }).status;
      },
      updateOrder: async (order, update) => {
        // Prefer business key orderNumber over PK type (Int vs String/cuid).
        // await db.orders.updateStatus(order.orderNumber, update.status)
        void order;
        void update;
      },
    });
  6. 7) Order ingest

    Checkout success call site (যেখানেই অর্ডার কমিট হয়)। Ads Purchase নয়।

    call site · server
    // Call from YOUR checkout success path (Route Handler, Server Action, etc.)
    // Exact file path depends on your storefront — not prescribed by this SDK.
    import { cookies } from "next/headers";
    import { buildOrderPayload, OrderWebhookPoster } from "@ecomsolvebd/next";
    
    // 1) Persist the order in your own database first, then:
    const poster = new OrderWebhookPoster({
      merchantKey: process.env.ECOMSOLVEBD_MERCHANT_KEY!,
      webhookSecret: process.env.ECOMSOLVEBD_WEBHOOK_SECRET!,
      apiBase: process.env.ECOMSOLVEBD_API_BASE,
    });
    
    const payload = buildOrderPayload(
      {
        orderNumber: order.number,
        // Use your store currency (ISO 4217) — do not hardcode
        currency: order.currency,
        customer: {
          fullName: order.customerName, // name
          phone: order.phone,
          // email: order.email,
        },
        items: order.lines.map((l) => ({
          sku: l.sku,
          title: l.title,
          quantity: l.qty,
          unitPrice: String(l.unitPrice),
          // productId: l.productId,
          // variantTitle: l.variantTitle,
        })),
        // Shipping / address (uncomment when your checkout collects them)
        // district: order.district,
        // upazila: order.upazila,
        // address: order.address,
        // notes: order.notes,
        // Money (flat fields — not a nested totals object)
        // shippingTotal: String(order.shippingTotal),
        // discountTotal: String(order.discountTotal),
        // taxTotal: String(order.taxTotal),
      },
      { cookieHeader: (await cookies()).toString() },
    );
    
    try {
      await poster.postOrder(payload);
    } catch (err) {
      console.error("[ecomsolvebd] postOrder failed", err);
    }
    // Ingest only — ads Purchase is sent later from the EcomSolveBD dashboard / courier flow.

নোট

  • Client export: EsbTracker (@ecomsolvebd/next/client) — অন্য নাম নেই।
  • Route handlers হোস্ট অ্যাপে thin wrappers; লজিক প্যাকেজে।
  • Optional: /feed/[channel].xml + ProductFeedProvider — প্যাকেজ README।
  • NEXT_PUBLIC_STORE_URL = পাবলিক origin (https://shop.example) — proxy URL বানাতে লাগে।

আরও ফিচার

অর্ডার স্ট্যাটাস

EcomSolveBD ও Next.js অ্যাডমিন স্ট্যাটাস সিঙ্ক করে।

  • · SaaS → Next.js: order-status route handler
  • · Next.js → SaaS: status webhook (প্যাকেজ)
  • · Dashboard Create Order → Next.js: v1.0.1+ (`POST /api/ecomsolvebd/order-create`)
  • · ম্যাপ: pending · confirmed · delivered · cancelled · returned

প্রোডাক্ট ফিড

চারটা XML — প্রোডাক্ট Next.js/API-তেই ম্যানেজ।

  • /feed/products.xmlEcomSolveBD ক্যাটালগ
  • /feed/facebook.xmlMeta
  • /feed/tiktok.xmlTikTok (RSS/XML)
  • /feed/google.xmlGoogle Merchant

First-party ট্র্যাকিং

ইভেন্ট আপনার ডোমেইন দিয়ে — অ্যাড ব্লকারে কম হারায়।

  • · Auto: same-origin /api/ecomsolvebd/collect → API
  • · Dashboard: CNAME → Verify DNS → tracking.{domain}
  • · ডেভ: proxy routes; owner: DNS (কোড নয়)

কন্ট্রাক্ট

Transport (provided by EsbTracker in the root layout):
  window.esbTrack?.(eventName, props?)
  window.esbBindCheckoutForm?.(cssSelector, fieldMap?)

Host responsibility:
  Map YOUR domain moments → event names below.
  Do not invent visitor ids / fbp / gclid — collect + esb_vid handle identity.
  Recommended: <EsbTracker funnelAuto={false} … /> so heuristics do not double-fire.

Call sites are yours (RSC, client page, cart store, Server Action, Route Handler).
This SDK does not prescribe routes, ORM, CMS, or UI libraries.

পেজ ভিউ

স্ক্রিন/URL পরিবর্তনে হোস্ট থেকে ফায়ার। রুট স্ট্রাকচার SDK নির্ধারণ করে না।

call site · client
// Client call site — whenever the visible URL / screen changes in your SPA
// Requires EsbTracker mounted so window.esbTrack exists.
window.esbTrack?.("page_view");

// App Router example (optional helper — adapt to your router):
// "use client";
// import { useEffect } from "react";
// import { usePathname, useSearchParams } from "next/navigation";
// export function TrackPageViews() {
//   const pathname = usePathname();
//   const search = useSearchParams();
//   useEffect(() => { window.esbTrack?.("page_view"); }, [pathname, search]);
//   return null;
// }

SDK রেফারেন্স

Product feeds — host wiring

পাবলিক XML কন্ট্রাক্ট + ProductFeedProvider। ক্যাটালগ সোর্স হোস্টের — ডেমো শপ কপি নয়। কার্ডে ক্লিক → কপি।

কন্ট্রাক্ট

Public feed URLs (Woo parity — host must expose these GET endpoints):

  GET  {storeOrigin}/feed/products.xml   → EcomSolveBD catalog sync
  GET  {storeOrigin}/feed/facebook.xml → Meta Commerce Manager
  GET  {storeOrigin}/feed/tiktok.xml   → TikTok Ads catalog (RSS/XML)
  GET  {storeOrigin}/feed/google.xml   → Google Merchant Center

SDK:
  @ecomsolvebd/next/route-handlers → createFeedRouteHandlers
  Host implements ProductFeedProvider (map YOUR catalog → DTO below).

Out of scope: SaaS does not CRUD remote products. Cost fields (buying_cost, …)
stay in EcomSolveBD DB — feed sync must not wipe them.

Skip rules (same as Woo): missing public http(s) image OR price ≤ 0 → omit item.
Google: identifier_exists=no when GTIN/MPN absent.

Feed route

একটা dynamic route — চারটা channel। ORM/ফাইল ট্রি SDK নির্ধারণ করে না।

app/feed/[channel].xml/route.ts
// Path contract (public): /feed/{products|facebook|tiktok|google}.xml
// Next.js cannot reliably match folders named [channel].xml — use:
//   app/feed/[channel]/route.ts
// + next.config rewrite: /feed/:channel.xml → /feed/:channel
import type { NextRequest } from "next/server";
import { feedRouteGET } from "@ecomsolvebd/next/route-handlers";
import { productFeedProvider } from "@/lib/esb-product-feed"; // rename to your module

export async function GET(
  _req: NextRequest,
  ctx: { params: Promise<{ channel: string }> },
) {
  const { channel } = await ctx.params;
  return feedRouteGET(channel.replace(/\.xml$/i, ""), {
    storeOrigin: process.env.NEXT_PUBLIC_STORE_URL!,
    currency: process.env.ECOMSOLVEBD_CURRENCY || "BDT",
    storeName: process.env.ECOMSOLVEBD_STORE_NAME || "Store",
    provider: productFeedProvider,
  });
}

// next.config.ts
// async rewrites() {
//   return [{ source: "/feed/:channel.xml", destination: "/feed/:channel" }];
// }

সাধারণ প্রশ্ন

কোডিং জানি না — পারব?
হ্যাঁ। ধাপ ১–৩ আপনি। ধাপ ৪ ডেভেলপার।
প্রোডাক্ট EcomSolveBD থেকে এডিট?
না। প্রোডাক্ট Next.js/API-তেই।
অর্ডার কীভাবে আসে?
চেকআউট সফলে সার্ভার webhook — ব্রাউজার purchase নয়। Dashboard Create Order (v1.0.1+) Next.js অ্যাডমিনেও যায়।
Secret হারিয়ে গেলে?
Integrations → Next.js আবার Connect, নতুন Secret।

সমস্যা হলে

page_view / ecommerce আসছে না

Collect proxy + EsbTracker। ecommerce: হোস্ট esbTrack call sites (Events API)।

tracker-config CORS লাল

Collect same-origin proxy দিয়ে চলে; tracker-config API Origin reflect করে (SaaS)। Hard-refresh করে আবার দেখুন।

অর্ডার আসছে না

Connect Next.js আগে। Secret মিলিয়ে postOrder() লগ চেক করুন।

স্ট্যাটাস সিঙ্ক নয়

order-status route + HTTPS base URL + order_number মিলছে কিনা।

সাহায্য লাগলে

শপ URL + স্ক্রিনশট + এরর মেসেজ পাঠান।

· বাংলাদেশ সময়