Shoppingate Logo
HomePartnerSell on E-commAbout UsContact UsDevelopers
Documentation
  • Getting started
  • Choosing your path
  • Introduction
    • Introduction
    • Sign up & login
    • Dashboard & analytics
    • Mini-Programs
    • Submit & publish a version
    • App Binding
    • Privacy Settings
    • Allowed URL
    • Users & roles
    • Introduction
    • Install & log in
    • Create a project
    • The workspace
    • Preview & upload
  • app.json config
  • Lifecycle
  • Routing & query
  • Host functions
  • orderPayment
  • Permissions
  • User info
  • Deep links
  • Overview & SDK
  • The wrapper
  • What a page can reach
  • Host functions
  • Permissions
  • Look and feel
  • Testing
  • Authentication
  • Endpoints
  • Webhooks
Web view

Host functions

Shoppinggate adds its own APIs on top of the standard Mini App ones — orders, payment, refunds, support tickets and the app language. A page inside a web-view calls them with ft.callNativeAPI, through the JSSDK.

What goes in SGConf.js — and what does not

Registering a name in SGConf.js is what creates ft.<name> on the mini-app runtime, for a native page to call. Your page reaches the host through ft.callNativeAPI instead, which does not read that table.

Called from
Needs registering?
Called as
Your page — any extended API: orderPayment, getUserOrders, createTicket, …
No
ft.callNativeAPI('orderPayment', …)
A native page in your shell, if you add one that calls an extended API directly
Yes
ft.orderPayment(…)
Built-in Mini App APIs — getUserInfo, getSetting, authorize, showModal, … called by your shell
No
ft.getUserInfo(…)

So a wrap that takes payment and opens tickets ships SGConf.js with an empty extApi array and leaves it that way — see the wrapper.

Step 1 — load the JSSDK in your page

ft.callNativeAPI comes from the JSSDK, so your page needs it before it can reach any host function. One file, no build step.

<!-- Load it in the TOP-LEVEL document of your page. -->
<script src="https://shoppinggate-public.s3.ap-south-1.amazonaws.com/webview-sdk/sg-jssdk-1.4.20.js"></script>

It must load in the top-level document, and ft.callNativeAPI needs 1.4.1 or later — both covered in Overview & SDK.

Step 2 — get your API list from the developer portal

Every API your Mini App can use is listed in the Shoppinggate developer portal. Public APIs are available to every Mini App. Private APIs must be requested first and approved by an admin before your Mini App can call them.

1. Open API Configuration

In the developer portal, open:

Mini-Program  →  your Mini App  →  Information Details  →  App Binding
              →  API Configuration
The App Binding tab of a Mini App, with the API Configuration action on the host app row
2. Find the API

API Configuration shows two lists:

  • Public API — the APIs your Mini App can call right now.
  • Restricted API — the APIs that need permission before use. Request them as shown in the next step.

Each row has the same columns:

  • API name — the exact name to pass as the first argument to ft.callNativeAPI
  • API category — e.g. user api, order apis, tickets apis
  • Usable Range — Public or Private
  • API Description — one line on what it does
  • Action — Details opens the API and, for a restricted API, the request form
API Configuration with the Public API list and the Restricted API list, and the Details action on orderPayment
3. Request a restricted API

Click Details on the API in the Restricted API list. In API use application, write why your Mini App needs it, then click Application use.

The API details dialog for orderPayment, with the API use application field and the Application use button
4. After approval

Once an admin approves the request, the API moves to the Public API list. Its Usable Range still says Private — that is expected. It is now available to your Mini App, and your page can call it.

API Configuration after approval, with orderPayment now in the Public API list

The portal gives you the name and a one-line description only. The parameters and the response for each API are in the API reference below. The extended APIs at the time of writing:

API
What it does
Category
Range
getAppLang
Returns the host app's current language — 'en' or 'ar'. The one extended API that takes no miniappId.
user api
Public
orderPayment
Creates the order and opens the payment sheet. See the full page: orderPayment.
order apis
Private
getUserOrder
Returns one order of the current user.
orders apis
Private
getUserOrders
Returns the current user's orders in this Mini App, one page at a time.
orders apis
Private
refundOrder
Requests a refund for an order — the full amount or part of it.
orders apis
Private
getOrderRefunds
Returns the refunds of one order.
orders apis
Private
getTicketIssues
Returns the list of issue types a user can pick when opening a ticket. Pass the chosen id to createTicket.
tickets apis
Private
createTicket
Opens a support ticket for an order on behalf of the user.
tickets apis
Private
getUserTickets
Returns the current user's tickets for an order, one page at a time.
tickets apis
Private

Step 3 — calling an API

One call for all of them: the API name first, the parameters second, and a single callback third. There is no success/fail split — everything the host says arrives in that one callback, which is why the result field in Step 4 is what tells you the outcome.

// Web page — one callback, OUTSIDE the argument object. No success/fail split.
ft.callNativeAPI("orderPayment", {
  orderInfo: { /* … */ },
  idempotencyKey: "…",
  miniappId: MINI_APP_ID,
}, function (res) {
  /* both outcomes arrive here */
});

Where miniappId comes from

Every API except getAppLang takes it, and a placeholder is rejected before anything else about the call is looked at. Read it from ft.getAppletInfo, which the JSSDK exposes to your page.

// Read it at runtime with ft.getAppletInfo, and keep a literal only as the fallback for
// running the page outside a web-view.
var MINI_APP_ID = "<your mini-app id>";

if (typeof ft !== "undefined" && typeof ft.getAppletInfo === "function") {
  ft.getAppletInfo({
    success: function (res) {
      var info = (res && (res.data || res)) || {};
      var id = info.appletId || info.appId || info.id;
      if (id) MINI_APP_ID = id;
    },
    fail: function () { /* keep the fallback */ },
  });
}

Two identifiers are easy to confuse. miniappId on these calls is the mini-app id; the appid in fide.project.config.json belongs to the project.

Step 4 — the response envelope

Extended APIs answer with a result field, not the errMsg string the built-in APIs use:

{ result: 'success', /* ...payload... */ }
{ result: 'failure', message: 'why it failed' }

Check result for the outcome and read message when it failed. The payload key differs per API — orders, order, refunds, tickets, issues, refundInfo — listed in the reference below.

Your callback firing means the call reached the host and came back. It does not mean the work happened — a declined payment arrives through the same callback with result: 'failure'. Check result before reading anything else, and when you log a failure print the host's response as it arrived rather than a field you picked out of it. Worked example in testing.

getUserInfo is not one of these

getUserInfo ships with the mini-app runtime rather than being an extended API, so it is not in the portal list above and not something ft.callNativeAPI reaches. Your shell calls it and relays the answer to your page.

Two things shape how you use it, and both differ from every API above:

  • It prompts on every call. No stored scope satisfies it the way getLocation is satisfied, so read it once and cache the result — a page that reads it per screen asks repeatedly.
  • Read it on first use, not at launch. The consent sheet appears the moment it is called, so reading it when the app opens asks for the user's name and mobile before they have done anything that needs it.

The relay, the cache and the invalidation that keeps it honest are in Permissions; the channel itself is in What a page can reach.

API reference

Every API with its parameters, an example call and what it returns. The parameters and responses are the same contract the native page documents, rendered from one shared definition; the examples are the web-view call.

getAppLang

Publicuser api

Returns the host app's current language — 'en' or 'ar'. The one extended API that takes no miniappId.

Parameters

None.

Example
ft.callNativeAPI("getAppLang", {}, function (res) {
  // The one host function that takes no miniappId.
  if (res.result === "success") console.log(res.language);   // 'en' | 'ar'
});
Response
{ result: 'success', language: 'en' }   // or 'ar'
{ result: 'failure', language: null }

orderPayment

Privateorder apis

Creates the order and opens the payment sheet. See the full page: orderPayment.

Parameters
orderInfoobject
The order — items, amounts, address, and your vendor_order_ref. All fields are on the orderPayment page.
idempotencyKeystring
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("orderPayment", {
  orderInfo: {
    vendor_order_ref: "1234567orderid",
    items: [{ sku: "d-1", name: "Dates", qty: 1,
              unit_price: "98.00", total_amount: "98.00" }],
    subtotal:     "98.00",
    delivery_fee: "12.00",
    tax_amount:   "16.50",
    total_amount: "126.50",      // subtotal + delivery_fee + tax_amount must balance
    currency: "SAR",
    order_type: "delivery",
  },
  // Stable per order. The same key on a retry is what stops a double charge.
  idempotencyKey: "1234567orderid",
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log("declined:", res.message);
  console.log(res.status, res.order_id);
});
Response
// failure
{ result: 'failure', message }

// success
{ result: 'success', status, order_id, message }

status is the outcome of the payment attempt, not an order status:

  • 'already_paid' — paid in an earlier session, nothing left to charge
  • 'created' — the order exists, the user backed out without paying
  • anything else — paid; the real status name from the backend

⚠️ order_id here is the super app's uuid, not your reference. This is the one API that returns the uuid. Your own reference goes out in orderInfo.vendor_order_ref, and that is what deep links come back on.

getUserOrder

Privateorders apis

Returns one order of the current user.

Parameters
orderIdstring
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("getUserOrder", {
  orderId: "1234567orderid",
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  console.log(res.order);
});
Response
{ result, order: { /* order */ } }
The order object is described in The order object.

getUserOrders

Privateorders apis

Returns the current user's orders in this Mini App, one page at a time.

Parameters
pagenumber
Page number, starting at 1.
perPagenumber
Orders per page.
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("getUserOrders", {
  page: 1,
  perPage: 10,
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  console.log(res.orders);
});
Response
{ result, total, page, per_page, orders: [ /* order */ ] }
Each item in orders is an order object.

refundOrder

Privateorders apis

Requests a refund for an order — the full amount or part of it.

Parameters
orderIdstring
amountnumber
The amount to refund. Can be the full order amount or a partial amount.
reasonstring
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("refundOrder", {
  orderId: "1234567orderid",
  amount: 50.0,
  reason: "Item arrived damaged",
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  console.log(res.refund);
});
Response
{ result, refundInfo: { /* refund */ } }
The refund object is described in The refund object.

getOrderRefunds

Privateorders apis

Returns the refunds of one order.

Parameters
orderIdstring
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("getOrderRefunds", {
  orderId: "1234567orderid",
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  console.log(res.refunds);
});
Response
{ result, refunds: [ /* refund */ ] }
Each item in refunds is a refund object.

getTicketIssues

Privatetickets apis

Returns the list of issue types a user can pick when opening a ticket. Pass the chosen id to createTicket.

Parameters
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
ft.callNativeAPI("getTicketIssues", {
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  // Each issue has an `id` — that is what createTicket's issueId takes.
  console.log(res.issues);
});
Response
{ result, issues: [ { id, name, code } ] }
code is currently null on every issue. Use id.

createTicket

Privatetickets apis

Opens a support ticket for an order on behalf of the user.

Parameters
issueIdnumber
The id of an issue from getTicketIssues.
orderIdstring
reasonstring
affectedProductsarray
imageFilePathstring
A local file path from a picker: ft.chooseImage (res.tempFilePaths[0]), or in a native page ft.chooseMedia (res.tempFiles[0].tempFilePath). See Permissions → pickers.
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
Example
// imageFilePath comes from ft.chooseImage, which your PAGE calls directly —
// no relay needed for this one.
ft.chooseImage({
  count: 1,
  sizeType: ["compressed"],
  sourceType: ["camera", "album"],
  success: function (media) {
    ft.callNativeAPI("createTicket", {
      issueId: 3,                       // from getTicketIssues
      orderId: "1234567orderid",
      reason: "The order arrived damaged",
      affectedProducts: [],
      imageFilePath: media.tempFilePaths[0],
      miniappId: MINI_APP_ID,
    }, function (res) {
      if (res.result !== "success") return console.log(res.message);
      console.log(res.ticket);
    });
  },
});
Response
{ result, message, ticket: { /* ticket */ } }
The ticket object is described in The ticket object.

getUserTickets

Privatetickets apis

Returns the current user's tickets for an order, one page at a time.

Parameters
orderIdstring
miniappIdRequired
Your Mini App id. In a native page, ft.getAccountInfoSync(); in a web view, ft.getAppletInfo.
pagenumber
Page number, starting at 1.
limitnumber
Tickets per page, e.g. 10.
Example
ft.callNativeAPI("getUserTickets", {
  orderId: "1234567orderid",
  page: 1,
  limit: 10,
  miniappId: MINI_APP_ID,
}, function (res) {
  if (res.result !== "success") return console.log(res.message);
  console.log(res.tickets);
});
Response
{ result, total, page, limit, tickets: [ /* ticket */ ] }
Each item in tickets is a ticket object.

The order object

Returned by getUserOrder (as order) and getUserOrders (in orders).

order_id
Your reference, e.g. 1234567orderid — not the super app's uuid.
status
A plain localized string. 'created' means unpaid.
items[]
The items you sent in orderInfo.items when you created the order with orderPayment — so the shape is yours. For example name, qty, unit_price, sku, booking_date; there can be more fields or fewer.
subtotal, tax_amount, delivery_fee, total_amount
Strings, not numbers.
currency
e.g. SAR.
customer_address
An object in getUserOrder; a plain string in getUserOrders.
cancellation_reason
Empty unless cancelled.
created_at, updated_at
ISO strings.

The refund object

Returned by refundOrder (as refundInfo) and getOrderRefunds (in refunds).

refund_uuid
amount, settled_amount
is_partial
Boolean.
status
An object: { id, name }.
reason, rejection_reason
requested_at, completed_at, rejected_at

The ticket object

Returned by createTicket (as ticket) and getUserTickets (in tickets).

ticket_id, ticket_no
status
An object: { id, name }. Open statuses are open, pending and in_progress.
order_id
Your reference.
issue
An object: { name }.
reason
affected_product
Singular in the list from getUserTickets.
upload_image_url
admin_notes
created_at, updated_at

Attaching an image

createTicket takes an imageFilePath, and your page can produce one: ft.chooseImage is reachable directly, and res.tempFilePaths[0] is exactly what the field wants. No relay involved — the createTicket example above shows the whole flow.

Need help? We’re here.

Our team is ready to support you in every step of your experience.

Email Us
[email protected]
Sell With SGContact UsTerms of ServicePrivacy PolicyFAQTravel FAQ
Connect with us
X / TwitterLinkedInInstagramFacebookTiktok

Copyright © Shoppingate 2026

Mada
Visa
Mastercard
Apple Pay
Tamara