# Introduction ## Welcome to Super Qi Miniapps Docs Welcome to the Super Qi Miniapps documentation! This guide will help you build, develop, and deploy powerful lightweight applications that run seamlessly within the Super Qi ecosystem. Whether you're building your first Miniapp or you're an experienced developer looking to leverage Super Qi's platform, this documentation provides everything you need to succeed. ## About This Documentation This documentation is organized into two main sections designed to support you throughout your development journey: ### 1. Developers Guide The **Developers Guide** is your comprehensive, step-by-step companion that walks you through **taking your Miniapp from scratch to production**. This section provides a complete journey covering every aspect of development: - **Getting Started** - Understanding Miniapps, their lifecycle, and choosing your development approach - **Configuration & Setup** - Setting up your development environment, understanding Super Qi platforms, and configuring UAT access - **Creating Your First Miniapp** - Building a functional Miniapp from scratch, including configuration and testing - **Demo Miniapp** - Exploring a complete example application with detailed frontend and backend code walkthroughs - **Releasing to Production** - Completing security review, merchant registration, and deploying your Miniapp to production ::warning **Follow the Developers Guide Thoroughly** Start with the Developers Guide if you're new to Super Qi Miniapps. It provides a structured learning path that takes you from your first Miniapp to production deployment. **Please follow it thoroughly** - each section builds upon the previous one, ensuring you have all the knowledge and setup needed before moving to production. Skipping steps may lead to issues later in your development process. :: ### 2. API Reference The **API Reference** is your comprehensive technical reference for all Super Qi APIs, flows, and integration details. Use this section when you need: - **Flows** - End-to-end integration guides for authentication and payments - **Open APIs** - Backend-to-backend API specifications and request/response details - **JSAPIs** - Client-side JavaScript APIs for accessing platform features ::warning The API Reference is designed for quick lookup and detailed technical specifications. Bookmark specific APIs you use frequently for easy access. :: ## What You'll Need Before you start, make sure you have the following ready — missing any of these can block you partway through the journey: **Accounts & Access** - A **Super Qi Console account** (created in [Super Qi Platforms](https://superqi-dev-docs.pages.dev/developers-guide/config-setup/super-qi-platforms)). **Hardware** - A **physical phone** (Android or iOS) to install and test your Miniapp. - Your phone and development machine must reach the **same network** during local testing. **Development Tools** (for the demo Miniapp and local backend) - [Git](https://git-scm.com/){rel="nofollow"} and [Node.js](https://nodejs.org/){rel="nofollow"} v18+ (includes npm) - [Go](https://go.dev/){rel="nofollow"} v1.21+ — only if you use the Go backend Detailed install steps are covered in [Installation Steps](https://superqi-dev-docs.pages.dev/developers-guide/demo-miniapp/installation-steps). ## Miniapp Development Types Super Qi supports two distinct approaches to building Miniapps, each with its own advantages. Choose the one that best fits your team's skills and project requirements: ### DSL (Domain-Specific Language) DSL is Super Qi's custom development framework forked from JavaScript, specifically designed for Miniapp development. **Key Features:** - **Optimized Performance** - Built specifically for Miniapps with minimal overhead - **Native-like Experience** - Provides smooth, app-like user interactions - **Structured Framework** - Opinionated architecture that promotes best practices **Best For:** - Developers who want the best performance and native feel - Teams building feature-rich, complex Miniapps **Development Stack:** - DSL (JavaScript-based syntax) - Native APIs and services ### H5+ (Open Web Development) H5+ brings the familiar web development stack to Miniapps, allowing you to use standard web technologies. **Key Features:** - **Web Standards** - Build with HTML5, JavaScript, and TypeScript - **Familiar Tools** - Use your existing web development skills and tools - **Rapid Development** - Leverage existing web libraries and frameworks - **Cross-Platform** - Code can be more easily shared with web applications **Best For:** - Web developers transitioning to Miniapps - Projects with existing web codebases - Teams prioritizing development speed and familiarity - Simpler applications with standard web interactions **Development Stack:** - HTML5 - JavaScript / TypeScript - CSS3 - Web APIs ::warning Keep in mind that in the following docs, we will be going through H5+ and its our recommended approach so far, DSL Docs will be added later on in the future, but if you are interested, [Check it out here](https://miniapps.qi.iq/docs/miniprogram_qineo/mpdev/framework_overview){rel="noopener,noreferrer"} :: ::callout{type="info"} Both DSL and H5+ Miniapps have access to the same Super Qi platform features, including authentication, payments, and user data. The choice between them is primarily about developer experience and performance requirements. :: ## AI Integration Get help from AI tools while developing your Super Qi Miniapps. Our documentation is optimized for use with ChatGPT, Claude, and other AI assistants. Learn more about [using AI with Super Qi documentation](https://superqi-dev-docs.pages.dev/utilities/ai-integration). ## Getting Help Throughout your development journey, you'll have access to: - **This Documentation** - Comprehensive guides and API references - **Miniapp Demo** - ready implemented demo app that shows the features available - **Developer Portal** - Account management and app submission - **Technical Support** - Technical assistance when you need it by contacting the Miniapp team --- Let's build something amazing together! Start your journey by learning [What are Miniapps](https://superqi-dev-docs.pages.dev/developers-guide/getting-started/what-are-miniapps) in the next section. # What Are Miniapps ## What Are Super Qi Miniapps? Super Qi Miniapps are lightweight, WebView-based applications that run within the Super Qi ecosystem. They provide app-like experiences without requiring separate downloads or installations. ## Platform Architecture ### WebView-Based Runtime Miniapps run in a secure, sandboxed execution environment that ensures consistent rendering across devices while remaining isolated from the host application. ### Unified Authentication The platform provides single sign-on across all Miniapps using OAuth-based token management. Users don't need to create separate accounts for each Miniapp they use. ### Native Payment Integration Super Qi integrates with **QiCard** (Iraq's digital payment solution) and **Alipay+** (global payment network) to enable in-app transactions without external redirects. The platform supports both one-time and recurring payments. ### Security & Permissions Each Miniapp runs in sandboxed execution with a declarative permission model that provides fine-grained API access control. ::warning **Obtaining Permissions**: Contact the Miniapps team to request specific scopes (CONTACT\_INFO, AGREEMENT\_PAYMENT, etc...). Permissions are granted based on your use case and compliance requirements. :: ## Miniapps Structure Miniapps consist of three main components: the **Frontend**, the **Backend**, and the **Super Qi App**. ### How It Works | Component | Hosted By | Dependencies | | ---------------- | --------- | --------------------------------------- | | **Frontend** | Merchant | URL provided to Super Qi Console | | **Backend** | Merchant | None with Super Qi | | **Super Qi App** | Super Qi | URL from Console to display the Miniapp | The merchant is responsible for hosting both the frontend and the backend of their Miniapp. The **only dependency** between the Super Qi app and your Miniapp is the **URL** you provide to the Super Qi Console. - **Backend**: Has no dependencies with Super Qi. You can use any technology stack, hosting provider, or architecture that suits your needs. - **Frontend**: The only connection to Super Qi is the URL that the platform uses to load your Miniapp. Super Qi relies on this URL to generate the QR code and display your Miniapp within the Super Qi app. ::warning This architecture gives you full control over your Miniapp's infrastructure while leveraging Super Qi's distribution, authentication, and payment capabilities. :: ### Recommended Approach for Payment Handling Super Qi does not recommend having a direct dependency between each payment and a product in your Miniapp system. The **recommended approach** is to **track every payment in the merchant's backend**. This ensures you have full control over transaction records, can reconcile payments independently, and maintain a reliable audit trail for all financial transactions in your system. ## Key Features ### Deep-Linking & QR Triggers The platform supports versioned URIs for direct navigation to specific features and QR code entry points for offline-to-online experiences. You can pass dynamic parameters and track marketing campaigns through these entry points. ### Platform APIs Miniapps have access to essential capabilities including user profile and authentication, payment processing and refunds, device features like camera and location, and UI components such as dialogs and notifications. ## Development Environments ### Super Qi UAT (Testing) The UAT environment is designed for development and testing. It provides test payment processing (no real money), isolated data separate from production, and debugging capabilities. ::warning Always test your Miniapp in Super Qi UAT before submitting for production deployment. :: ### Super Qi Production The production environment handles live user transactions with real payment processing. All Miniapps require approval before deployment to this environment. ## Common Use Cases Miniapps power various services across Iraq's digital economy including e-commerce and shopping, loyalty programs, financial services, on-demand services, and entertainment and media. --- Next, explore the [MiniApps Lifecycle](https://superqi-dev-docs.pages.dev/developers-guide/getting-started/miniapp-lifecycle) to understand the end-to-end journey your Miniapp takes — from signing the commercial contract all the way to going live. # MiniApps Lifecycle ## Overview This guide walks you through the complete lifecycle of developing and launching a Miniapp on the Super Qi platform. From initial agreements to going live, follow these steps to ensure a smooth onboarding process. ## Development Journey ::mini-app-lifecycle-timeline :: ::developers-guide-callout :: --- Now that you understand the journey ahead, let's set up your development environment. Continue to [Super Qi Platforms](https://superqi-dev-docs.pages.dev/developers-guide/config-setup/super-qi-platforms) to create your console account. # Super Qi Console ## Overview Super Qi Console is your Miniapp management platform for creating, configuring, and releasing Miniapps. This guide will walk you through creating your account and understanding what the platform offers. ## Super Qi Console Super Qi Console is your Miniapp management platform where you create, configure, and manage your Miniapps throughout their lifecycle. ### Creating Your Super Qi Console Account Follow these steps to create your console account: #### Step 1: Navigate to Super Qi Console Visit the Super Qi Console at [miniprogram.alipay](https://miniapps.qi.iq/login?goto=/console){rel="nofollow"} #### Step 2: Register Account Click "Sign Up" or "Create Account" and provide the requested details ![Super Qi console](https://superqi-dev-docs.pages.dev/developer-guide/alipay-login.png) ![Super Qi console](https://superqi-dev-docs.pages.dev/developer-guide/alipay-signup.png) #### Step 3: Set Up Workspace ##### Fill in the necessary data to create your workspace ![Super Qi console](https://superqi-dev-docs.pages.dev/developer-guide/alipay-workspace.png) #### Step 4: Access Console Dashboard Once approved, access your console dashboard to start creating and managing Miniapps. ![Super Qi console](https://superqi-dev-docs.pages.dev/developer-guide/console-overview.png) ## Getting Help For issues with the console, Miniapp management, or developer resources, contact the developer support team . --- Ready to continue? The next section will guide you through setting up your Super Qi UAT to start development! # UAT and Credentials ## Overview Before releasing your Miniapp to production, all development and testing should be done in the **UAT (User Acceptance Testing)** environment. This ensures your Miniapp is thoroughly tested before real users interact with it. ## Why Develop in UAT First? The UAT environment provides a safe sandbox for development with several key benefits: | Feature | Description | | ------------------------ | ------------------------------------------------------------------------------ | | **Testing Accounts** | Pre-configured test user accounts for simulating real user interactions | | **Testing Money** | Virtual currency for testing payment flows without real financial transactions | | **Isolated Environment** | Separate from production, so testing won't affect live users or data | | **Debug-Friendly** | Enhanced logging and debugging capabilities for development | ::warning Always develop and test your Miniapp in the UAT environment first. Never test with real user accounts or real money during development. :: ## Downloading Super Qi UAT To develop and test your Miniapp, you'll need to install the **Super Qi UAT** application on your device. The UAT version is separate from the production Super Qi app and connects to the testing environment. ### Android Follow these steps to get Super Qi UAT on your Android device: #### Step 1: Request Access Visit the Firebase App Distribution link below and enter your email address to request access: [Request Android UAT Access](https://appdistribution.firebase.dev/i/e0638b5cc6eda1f2){rel="noopener,noreferrer"} #### Step 2: Check Your Email Once you submit your email, you'll be added to the Firebase App Distribution list. You will receive an email with instructions to download the latest Super Qi UAT Android version. #### Step 3: Install the App Follow the instructions in the email to download and install the Super Qi UAT app on your Android device. ::warning You will automatically receive notifications when new versions of Super Qi UAT are available through Firebase App Distribution. :: ### iOS Follow these steps to get Super Qi UAT on your iOS device: #### Step 1: Contact the Miniapps Team Reach out to the Miniapps development team with an organization email (or the sponsor organization email) to request TestFlight access: **Contact:** Provide the following information: - Your Apple ID organization email address () - (Optional) Sponsor Email address - Your company/organization ::caution in case your apple id email is not an organization email, you will need an organization email address to send the email and mention the Apple ID email along with the sponsor email to be added :: #### Step 2: Accept TestFlight Invitation Once added, you'll receive an email invitation from TestFlight. Accept the invitation to gain access to the Super Qi UAT iOS version. #### Step 3: Download via TestFlight Open the TestFlight app on your iOS device and download the latest Super Qi UAT version. ::warning TestFlight will notify you automatically when new versions of Super Qi UAT are available for download. :: ## Developer Menu Once you have Super Qi UAT installed, you'll notice a **floating burger icon** on the screen. This icon provides access to the Developer Menu, which contains essential tools and settings for development. ![Floating Burger Icon](https://superqi-dev-docs.pages.dev/developer-guide/superqi-uat.png){style="width: 250px; height: auto;"} ### Environment The Environment feature allows you to switch between different server environments within the app. ::warning **Important:** After installing Super Qi UAT, you must open the Developer Menu and change the environment to **UAT**. This is a critical step to ensure your Miniapp connects to the testing environment. :: Follow these steps to configure your environment: 1. Tap the floating burger icon to open the Developer Menu 2. Select **Environment** from the menu options ![Environment Menu](https://superqi-dev-docs.pages.dev/developer-guide/superqi-uat-burger-environment.png){style="width: 250px; height: auto;"} 3. Choose **UAT** from the available environments 4. The app will reload with the UAT environment active ![Environment Menu](https://superqi-dev-docs.pages.dev/developer-guide/superqi-uat-burger-env-options.png){style="width: 250px; height: auto;"} ### Qi Tools The Qi Tools section provides various developer utilities to help with testing and debugging your Miniapp. Available tools include: - **Disable Screenshot Protection** - Allows you to take screenshots within the app for documentation or debugging purposes - Additional debugging and testing utilities ![Tools Menu](https://superqi-dev-docs.pages.dev/developer-guide/superqi-uat-burger-tools.png){style="width: 250px; height: auto;"} ::warning These developer tools are only available in the Super Qi UAT version and are not present in the production app. :: ## Testing Credentials For development in the UAT environment, you'll need testing merchant credentials. Follow the steps below to request your UAT credentials. ::note For obtaining the public keys for UAT and Prod, see the [Signature Validation](https://superqi-dev-docs.pages.dev/utilities/signature-validation) guide. :: ### How to Request UAT Credentials To obtain your UAT credentials, send an email request to the Miniapps team with the following details: **Email Details:** - **To:** - **CC:** - **Subject:** UAT Credentials Request - [Your Miniapp Name] ::warning The email must be sent from your organization email address, not a personal email account. :: ### Required Information Your email should include: 1. **Miniapp Name** - The name of your Miniapp 2. **Organization Details** - Your company/organization name 3. **Contact Information** - Primary contact person and phone number 4. **Additional Scopes** (if needed) - If you require access to additional scopes beyond the standard APIs, please: - Specify which scopes you need - Attach any approval documents or authorization letters ### Email Template Copy and use this template for your credentials request: ```text Subject: UAT Credentials Request - [Your Miniapp Name] Dear Miniapps Team, I am writing to request UAT credentials for our Miniapp development. Miniapp Name: [Your Miniapp Name] Organization: [Your Organization Name] Contact Person: [Your Name] Phone Number: [Your Phone Number] Email: [Your Email Address] Additional Scopes (if applicable): [List any additional scopes you need, or write "None"] [If requesting additional scopes, mention attached documents here] Thank you for your assistance. Best regards, [Your Name] [Your Title] [Your Organization] ``` ### What Happens Next After submitting your request: 1. The Miniapps team will review your request 2. If additional scopes are requested, they will verify the attached approvals 3. Your UAT credentials will be generated and shared via the established communication channel 4. You will receive: - Client ID - Merchant ID - Gateway URL - Private Key (the matching public key is published in the [Signature Validation](https://superqi-dev-docs.pages.dev/utilities/signature-validation) guide) - Super Qi UAT Test User ::note Keep your credentials secure. Store them in environment variables and never commit them to version control. :: --- Ready to continue? The next sections will guide you through creating your first Miniapp and using the testing credentials for UAT development. # Create Miniapp ## Overview Now that you have your development environment set up, it's time to create your first Miniapp on the Super Qi Console. This guide will walk you through the process of creating a new Miniapp project. ## Prerequisites Before creating a Miniapp, ensure you have: - A Super Qi Console account (see [Super Qi Platforms](https://superqi-dev-docs.pages.dev/developers-guide/config-setup/super-qi-platforms)) - An approved workspace from the Miniapps team ::note Your workspace must be approved by the Miniapps team before you can create Miniapps. If your workspace is pending approval, please wait for confirmation before proceeding. :: ## Creating Your Miniapp Follow these steps to create your first Miniapp: ### Step 1: Navigate to Super Qi Console Visit the Super Qi Console and log in to your account: [Open Super Qi Console](https://miniapps.qi.iq/login?goto=/console){rel="noopener,noreferrer"} ### Step 2: Create New Miniapp Once your workspace has been approved, you can create a new Miniapp. Click on the **Create** button to start the creation process. Fill in the required information for your Miniapp: ![Create Miniapp Form](https://superqi-dev-docs.pages.dev/developer-guide/console-create-miniapp.png) After filling in all the required fields, click the **Create** button to create your Miniapp. ::warning **Important:** You must select **H5+** as your Miniapp type. This setting cannot be changed after creation. Other information such as the name and description can be modified later. :: ### Step 3: Choose the Correct Tag After creating your miniapp, edit the information to select the appropriate tag for your Miniapp based on your target audience: ![Miniapp Tag Selection](https://superqi-dev-docs.pages.dev/developer-guide/miniapp-tag.png) There are two types of tags available: - **Customer Tag (Mini Service A)**: Select this if your Miniapp is targeting customers - **Business Tag (Mini Service B)**: Select this if your Miniapp is targeting businesses ::note Most default apps target customers, so please proceed with **Customer (Mini Service A)** for now. :: ### Step 4: View Your Miniapp Once completed, you will be redirected to your Miniapp's dashboard. Navigate to your Miniapp that you just created, Here you can view and manage your Miniapp settings. ![Miniapp Dashboard](https://superqi-dev-docs.pages.dev/developer-guide/console-miniapp-created.png) ## Congratulations! You have successfully created your first Miniapp! Follow along with the documentation to learn more about configuring and developing your Miniapp. --- Ready to continue? The next sections will guide you through understanding Miniapps and configuring your development environment. # Configure & Test Miniapp ## Overview In this section, we will configure your Miniapp credentials and set it to the UAT environment so you can test it in the Super Qi UAT app. Follow the steps below to generate a QR code that will display your first Miniapp. As you will notice later, Miniapps consist of **versions**. You can add UAT, Production, or any other environment to each version. For now, we will be creating the UAT environment for the versions. Later on, in the last section of the Developer's Guide ([Releasing to Production](https://superqi-dev-docs.pages.dev/developers-guide/releasing-to-production/release-prod-miniapp)), we will create a Production environment for that specific version. ## Configuring Your Miniapp ### Step 1: Open Global Configuration Navigate to your Miniapp and click on **Global Configuration** to configure your Miniapp settings. ![Global Configuration](https://superqi-dev-docs.pages.dev/developer-guide/configure-miniapp.png) ### Step 2: Set Environment and Credentials In the configuration panel: 1. Select **Test** as the environment for both the Client ID and Merchant ID 2. Enter your **Client ID** 3. Enter your **Merchant ID** ![Set Credentials](https://superqi-dev-docs.pages.dev/developer-guide/configure-client-merchant.png) ::warning You can find your Client ID and Merchant ID in the [UAT and Credentials](https://superqi-dev-docs.pages.dev/developers-guide/config-setup/uat) guide. :: ### Step 3: Save and Publish After entering your Client ID and Merchant ID, click on **Save & Publish**. ![Save and Publish](https://superqi-dev-docs.pages.dev/developer-guide/configure-save.png) ### Step 4: Confirm Version You will be prompted to confirm the version. Click on **Save & Publish** again to confirm. ![Confirm Version](https://superqi-dev-docs.pages.dev/developer-guide/save-and-publish.png) ### Step 5: Navigate Back to Miniapp After publishing, you will be redirected to that version. However, this is set to the **Production** environment by default, which is not what we want for testing. Navigate back to your Miniapp dashboard. ![Production Environment](https://superqi-dev-docs.pages.dev/developer-guide/prod-version.png) ### Step 6: Select App Version Back in your Miniapp dashboard, go to the **Versions** tab. Click on **Select app** for the latest version you have created. ::warning If you want to see the environments available in this version, click on the **+** sign in front of the version. :: ![Versions Tab](https://superqi-dev-docs.pages.dev/developer-guide/selecting-version.png) ### Step 7: Select Target App In the selection dialog: 1. Select the Target app with your **/ Test**{workspace=""} 2. The Client ID and Merchant ID will be automatically filled 3. Click **Select** to confirm ![Select Target App](https://superqi-dev-docs.pages.dev/developer-guide/select-uat.png) ### Step 8: Generate QR Code Now you can see that the environment is set to **Test**. Click on **Temporary Testing QR Code** to generate your QR code. ![Generate QR Code](https://superqi-dev-docs.pages.dev/developer-guide/correct-testing-env.png) ### Step 9: Scan QR Code in Super Qi UAT Open your Super Qi UAT app and press the scan button to open the camera. Scan the QR code to open your first Miniapp. ![Scan QR Code](https://superqi-dev-docs.pages.dev/developer-guide/scanning-qr.png){style="width: 250px; height: auto;"} ::warning You will notice that your Miniapp displays Google (google.com) instead of your actual application. This is because the Miniapp URL is currently set to `https://www.google.com` as a placeholder. In the next section, we will change this to create your first Demo Miniapp. :: ## What's Next? You have successfully configured your Miniapp for UAT testing! In the next documentation, we will set up a Demo Miniapp that has most of the functionalities used in Super Qi including authentications, payments, etc... and we will have it up and running when scanning the QR Code instead of getting Google.com --- Ready to continue? The next section will guide you through creating your first Demo Miniapp. # Installation Steps ## Overview This section of the documentation covers installing, running, and exploring the Demo Miniapp code. It is recommended to follow these steps to understand: - How testing locally works - How the Super Qi APIs function in code By the completing the "Demo Miniapp" section, you will have a fully functional Demo Miniapp running locally and a solid understanding of how to integrate with Super Qi. ## Prerequisites Before you begin, ensure you have the following installed: - **Git** - for cloning the repository - **Node.js** (v18 or higher recommended) - **npm** or **yarn** - for package management - **Go** (v1.21 or higher recommended) - for the backend ### Git Check if Git is installed: ```bash git --version ``` If you see an error or "command not found", install Git: - **macOS**: Install via Homebrew ```bash brew install git ``` - **Windows**: Download from [git-scm.com](https://git-scm.com/downloads){rel="noopener,noreferrer"} - **Linux (Ubuntu/Debian)**: ```bash sudo apt update && sudo apt install git ``` ### Node.js and npm Check if Node.js and npm are installed: ```bash node --version npm --version ``` If you see an error or "command not found", install Node.js (npm is included): - **macOS/Linux**: We recommend using **nvm** (Node Version Manager) ```bash # Install nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash # Restart terminal, then install Node.js nvm install 18 nvm use 18 ``` - **Windows**: Download from [nodejs.org](https://nodejs.org/){rel="noopener,noreferrer"} (LTS version recommended) ### Yarn (Optional) Check if Yarn is installed: ```bash yarn --version ``` If you prefer using Yarn instead of npm and it's not installed: ```bash npm install -g yarn ``` ### Go Check if Go is installed: ```bash go version ``` If you see an error or "command not found", install Go: - **macOS**: Install via Homebrew ```bash brew install go ``` - **Windows**: Download from [go.dev/dl](https://go.dev/dl/){rel="noopener,noreferrer"} - **Linux (Ubuntu/Debian)**: ```bash sudo apt update && sudo apt install golang-go ``` ## Installation Guide Follow these steps to install the Demo Miniapp locally: ### Step 1: Clone the Repository Open your terminal, move to the folder where you want the project to live, and clone the Demo Miniapp: ```bash # Using HTTPS git clone https://github.com/Qi-Mobile/superqi-demo-miniapp.git # Or, using SSH git clone git@github.com:Qi-Mobile/superqi-demo-miniapp.git ``` ::note **If the clone command doesn't work** — for example, Git isn't installed or your access isn't set up — you can get the code manually instead: open the [Super Qi Demo Miniapp repository](https://github.com/Qi-Mobile/superqi-demo-miniapp/){rel="noopener,noreferrer"} on GitHub, click the green **Code** button, and either copy the clone URL or choose **Download ZIP**. :: ![Clone Repository](https://superqi-dev-docs.pages.dev/developer-guide/demo-repo.png) ### Step 2: Navigate to the Project Once the cloning is complete, navigate into the project directory: ```bash cd superqi-demo-miniapp ``` ### Step 3: Install Dependencies Open **two separate terminal windows** to install dependencies for both the frontend and backend. #### Terminal 1: Frontend Navigate to the frontend directory and install npm packages: ```bash cd superqi-demo-miniapp/frontend npm install ``` #### Terminal 2: Backend Navigate to the backend directory and install its dependencies. The demo ships **two interchangeable backends** — pick Go *or* Node.js: ::code-group ```bash [go] cd superqi-demo-miniapp/backend-go go mod tidy go mod download ``` ```bash [Node.js] cd superqi-demo-miniapp/backend-node npm install ``` :: ## Installation Complete You have successfully installed the Demo Miniapp and all its dependencies. Everything is now ready, and you can proceed to testing the Miniapp locally. --- Ready to continue? The next section will guide you through running and testing your Demo Miniapp. # Testing Locally ## Overview In this section, we will configure and run the Demo Miniapp locally for testing. This allows you to develop and debug your Miniapp before deploying it to a remote server. ### How Local Testing Works Local testing requires running both the **backend** and **frontend** simultaneously on your machine. Here's how it works: 1. The backend runs on your machine and exposes an API 2. The frontend runs on your machine and connects to the backend 3. Your phone (with Super Qi UAT) scans the QR code and loads the frontend 4. The frontend communicates with the backend over your local network ::warning **Important:** Your phone and your machine (laptop or PC) must be connected to the **same network** for local testing to work. If they are on different networks, your phone won't be able to reach the backend. :: ## Backend Configuration The backend requires credentials to communicate with the Super Qi APIs. ### Step 1: Create the .env File Navigate to the backend directory and create a `.env` file (Below is bash command, but select whether you want to run NodeJS or Go): ::code-group ```bash [go] cd superqi-demo-miniapp/backend-go touch .env ``` ```bash [Node.js] cd superqi-demo-miniapp/backend-node touch .env ``` :: ### Step 2: Get Credentials Obtain your UAT credentials following the instructions in the [UAT and Credentials](https://superqi-dev-docs.pages.dev/developers-guide/config-setup/uat) guide. Add the following variables to your `.env` file (both the Go and Node.js backends use the same format): ```bash # Gateway Configuration ALIPAY_GATEWAY_URL= ALIPAY_CLIENT_ID= # RSA Keys — paths to the key files you save in Step 3 ALIPAY_MERCHANT_PRIVATE_KEY_PATH= ALIPAY_PUBLIC_KEY_PATH= # Token Encryption — a 32-byte key required by the demo backend JWT_KEY=<32-byte key for JWE> ``` ::note Your **Merchant ID** is used inside the Super Qi Console dashboard, not in the backend `.env` — so it does not appear here. :: ### Step 3: Save Your Keys You receive only the **private key** from the Miniapps team. Obtain the matching **public key** for your environment from the [Signature Validation](https://superqi-dev-docs.pages.dev/utilities/signature-validation) guide. Save both key files in the backend directory and reference their paths in your `.env` file (`ALIPAY_MERCHANT_PRIVATE_KEY_PATH` and `ALIPAY_PUBLIC_KEY_PATH`). ### Step 4: Save the .env File After adding all the required credentials, save the `.env` file. Your backend is now configured. ### Step 5: Install Dependencies Install the required dependencies for your backend: ::code-group ```bash [go] go mod download ``` ```bash [Node.js] npm install ``` :: ### Step 6: Run the Backend Start the backend server by running the following command: ::code-group ```bash [go] go run main.go ``` ```bash [Node.js] npm run dev ``` :: The server should now be up and running. Keep this terminal open. ## Frontend Configuration The frontend needs to know the IP address of the machine running the backend so it can make API requests. ### Step 1: Get Your Machine's IP Address Open a terminal and run the following command to get your machine's network IP address: **macOS/Linux:** ```bash ifconfig | grep "inet " | grep -v 127.0.0.1 ``` **Windows:** ```bash ipconfig ``` Look for the IP address that is [**not**]{style="color: red;"} `127.0.0.1` (loopback). This is your machine's IP on the local network (e.g., `192.168.1.100`). ::warning Why not use localhost or 127.0.0.1 ? When you scan the QR code with your phone, the Miniapp runs on your phone's browser. If you use `127.0.0.1` or `localhost`, the phone will look for the backend on itself (the phone), not on your machine. You need to use your machine's network IP address so the phone can reach the backend over the network. :: ### Step 2: Update BASE\_URL Open the file `common/main.js` in the frontend directory: ```bash cd superqi-demo-miniapp/frontend ``` Find the `BASE_URL` variable and update it with your machine's IP address: ```javascript // Before const BASE_URL = "http://localhost:8080"; // After (replace with your IP address) const BASE_URL = "http://192.168.1.100:8080"; ``` ### Step 3: Save the File Save the `main.js` file after updating the `BASE_URL`. ### Step 4: Update the dependencies ```bash npm install ``` ### Step 5: Run the Frontend Start the frontend development server with host mode enabled: ```bash npm run dev -- --host ``` This will start the development server and expose it on your network. Copy the IP address that is **not** the loopback address (127.0.0.1). This is the URL you will use in the Super Qi Console. ![Frontend Dev Server](https://superqi-dev-docs.pages.dev/developer-guide/frontend-ip.png) ## Super Qi Console Configuration Now that both the backend and frontend are running, you need to update the Miniapp URL in the Super Qi Console and release a new version. ### Step 1: Navigate to Your Miniapp Log into [Super Qi Console](https://miniapps.qi.iq/login?goto=/console){rel="noopener,noreferrer"} and navigate to your Miniapp. ### Step 2: Go to Information Click on **Information** to view your Miniapp details. ![Miniapp Information](https://superqi-dev-docs.pages.dev/developer-guide/console1.png) ### Step 3: Edit Information Click on **Edit** to modify your Miniapp information. ![Edit Information](https://superqi-dev-docs.pages.dev/developer-guide/console2.png) ### Step 4: Update the URL Update the Miniapp URL with the IP address you copied from the frontend development server. Click **Save** to save your changes. ![Update URL](https://superqi-dev-docs.pages.dev/developer-guide/console3.png) ### Step 5: Release a New Version After saving the new URL, you need to release a new version of your Miniapp for the changes to take effect. ::note For detailed steps on releasing a new version, follow the instructions in [Configure Miniapp](https://superqi-dev-docs.pages.dev/developers-guide/create-your-first-miniapp/configure-and-test-miniapp). :: ### Step 6: Get the QR code Click on the "Temporary Testing QR Code" for the QR code to appear, and now the Demo Miniapp is ready to be explored! ## Super Qi UAT Now it's time to see your Demo Miniapp in action! ### Step 1: Open Super Qi UAT Open the **Super Qi UAT** application on your phone. ### Step 2: Scan the QR Code Use the scan feature to scan the QR code displayed in the Super Qi Console. ### Step 3: Explore the Demo Miniapp The Super Qi Demo Miniapp home page will open: ![Demo Miniapp Home](https://superqi-dev-docs.pages.dev/developer-guide/demo-miniapp.png){style="width: 250px; height: auto;"} This is the Demo Miniapp! You can explore all of its features by navigating through the pages. Each functionality has its own dedicated page with a terminal that prints the results, allowing you to see exactly how the Super Qi APIs work. **Happy Exploration!** ## Troubleshooting If your Miniapp doesn't load or API calls fail, work through these common issues: | Symptom | Likely cause | Fix | | ---------------------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Miniapp loads but API calls fail / time out | Phone and machine are on different networks | Connect both to the **same Wi-Fi**. Guest/corporate networks often isolate devices — use a shared network or a phone hotspot. | | API calls go to the wrong place | `BASE_URL` still points to `localhost`/`127.0.0.1` | Set `BASE_URL` in `common/main.js` to your machine's **network IP** (e.g. `http://192.168.1.100:8080`), not loopback. | | Connection refused | Backend isn't running, or the port in `BASE_URL` doesn't match the backend's port | Keep the backend terminal running, and make sure the port in `BASE_URL` matches the port the backend prints on startup. | | Phone can't reach the backend at all | Your machine's firewall is blocking incoming connections | Allow incoming connections on the backend port, or temporarily disable the firewall while testing. | | Frontend URL not reachable from phone | Frontend wasn't started in host mode | Restart with `npm run dev -- --host`. | | IP stopped working after a while | Machine got a new IP via DHCP, or a VPN changed it | Re-run the IP lookup, update `BASE_URL`, and disable any VPN during local testing. | | Miniapp opens but shows the wrong or old build | The scanned Miniapp is set to the **Prod** environment, not **Testing** | In **Super Qi UAT**, make sure you scan the Miniapp that is in the **Testing environment**, not the **Prod environment**. | | Changes don't appear after updating the URL | New version wasn't released in the Console | Release a new version after editing the Miniapp URL, then regenerate the testing QR code. | Still stuck? See the [FAQ](https://superqi-dev-docs.pages.dev/faq) or contact the Miniapps team. --- Ready to continue? The next section will guide you through exploring the code. # Frontend ## Overview The Demo Miniapp frontend is written in **Vanilla JavaScript** - no frameworks, no libraries, just pure JavaScript. This keeps the codebase simple and easy to understand, making it a great reference for learning how to integrate with Super Qi APIs. ## Project Structure The frontend code is organized into the following structure: ```text frontend/ ├── common/ # Shared utilities and helpers │ ├── main.js # Main configuration (BASE_URL, etc.) │ ├── console.js # Terminal/console output utilities │ └── ... # Other shared utilities ├── category files # Navigation and grouping pages └── feature files # Individual API/feature implementations ``` ## Common Folder The `common` folder contains shared utilities and helper functions that are used across all pages: | File | Description | | -------------- | --------------------------------------------------------------------------- | | **main.js** | Contains the main configuration including `BASE_URL` for API requests | | **console.js** | Provides terminal/console output functionality for displaying API responses | These common files ensure consistency across the application and reduce code duplication. ::warning The only configuration you need to change in the frontend is the `BASE_URL` inside `main.js`. This is the URL where the frontend connects to the backend. See [Testing Locally](https://superqi-dev-docs.pages.dev/developers-guide/demo-miniapp/testing-locally) for instructions on setting this up. :: ## File Types Outside the `common` folder, there are two types of files: ### Category Files ![Category Files](https://superqi-dev-docs.pages.dev/developer-guide/category-files.png) Category files serve as navigation pages that group related features together. They help organize the Demo Miniapp into logical sections. The Demo Miniapp includes the following categories: - **auth** - Authentication and authorization features - **device** - Device information and capabilities - **network** - Network-related functionality - **file** - File system operations - **location** - Location and geolocation services - **media** - Media handling (audio, video, images) - **messages** - Messaging and communication features - **storage** - Data storage and persistence - **UI** - User interface components and interactions ### Feature Files ![Feature Files](https://superqi-dev-docs.pages.dev/developer-guide/features-files.png) Feature files are dedicated to specific Super Qi APIs or functionalities. Each file demonstrates a particular feature with: - A user interface for triggering the API - A terminal/console that displays the results - Example code showing how to integrate with Super Qi This structure allows you to explore each Super Qi feature independently and see exactly how it works in practice. ## Code Structure The frontend follows a **linear structure** where all files are organized in the same directory. This simple, flat organization is intentional - since this is a demo application built with vanilla JavaScript, there's no need for complex hierarchies or nested folder structures. Each feature file is self-contained and can be understood independently, making it easy to: - Find specific examples quickly - Copy code snippets for your own projects - Understand how individual APIs work without navigating through multiple directories This straightforward approach keeps the focus on learning Super Qi's capabilities rather than dealing with complicated project organization. # Backend ## Overview The Demo Miniapp backend is available in two implementations - **Go** and **Node.js** - both providing the same RESTful API that integrates with the Alipay+ payment gateway. Choose the implementation that best fits your technology stack and preferences. Both versions demonstrate Super Qi's core capabilities including authentication, payments, refunds, agreement payments, and inbox notifications. The backends are intentionally kept simple and straightforward - they're demo applications designed to show you how to integrate with Super Qi APIs, not production-ready systems. ## Tech Stack ::code-group ```text [go] Technology Version Purpose ───────────────────────────────────────────────────────────── Go 1.24.2 Programming language Fiber v2 Fast web framework (Express-inspired) go-jose v3 JWE token encryption uuid v1.6 Unique ID generation godotenv v1.5 Environment variable management ``` ```text [Node.js] Technology Version Purpose ───────────────────────────────────────────────────────────── Node.js 18+ JavaScript runtime Express v5 Web application framework node-jose v2.2 JWE token encryption uuid v13 Unique ID generation dotenv v17 Environment variable management axios v1.13 HTTP client for API requests ``` :: ## Project Structure The backend code is organized into focused modules: ::code-group ```text [go] backend-go/ ├── main.go # Application entry point ├── api/ # HTTP endpoint handlers │ ├── authEndpoint.go # Auth token exchange & user info │ ├── paymentEndpoint.go # Online payment creation │ ├── refundEndpoint.go # Payment refunds with polling │ ├── agreementEndpoint.go # 3-step agreement payments │ └── notificationEndpoint.go # Inbox message sending ├── alipay/ # Alipay+ SDK client │ ├── client.go # HTTP client, RSA signing │ ├── alipay.go # API method implementations │ ├── model.go # Request/response types │ ├── constants.go # Product codes (ONLINE_PURCHASE, AGREEMENT_PAYMENT) │ └── util.go # RSA key loading utilities └── jwe/ # Token encryption └── jwe.go # JWE create/parse with A256GCM ``` ```text [Node.js] backend-node/ ├── src/ # Source code directory │ ├── index.js # Application entry point │ ├── api/ # HTTP endpoint handlers │ │ ├── index.js # Exports all endpoint initializers │ │ ├── authEndpoint.js # Auth token exchange & user info │ │ ├── paymentEndpoint.js # Online payment creation │ │ ├── refundEndpoint.js # Payment refunds with polling │ │ ├── agreementEndpoint.js # 3-step agreement payments │ │ └── notificationEndpoint.js # Inbox message sending │ ├── alipay/ # Alipay+ SDK client │ │ ├── index.js # Exports alipay functions │ │ ├── client.js # HTTP client, RSA signing with Axios │ │ ├── alipay.js # API method implementations │ │ ├── constants.js # Product codes (ONLINE_PURCHASE, AGREEMENT_PAYMENT) │ │ └── util.js # RSA key loading utilities │ └── jwe/ # Token encryption │ └── jwe.js # JWE create/parse with A256GCM └── res/ # Resources (crypto keys) └── crypto/ # RSA key files directory ``` :: ## Application Entry Point The application entry point bootstraps the server and sets up routing: ::code-group ```text [go] File: main.go (lines 15-42) • Load environment variables from .env file • Initialize Alipay+ client with credentials • Create Fiber app instance • Configure CORS and recovery middleware • Register API route handlers under /api prefix • Start server on port 1999 (default) or PORT env variable ``` ```text [Node.js] File: src/index.js (lines 13-48) • Load environment variables from .env file • Initialize Alipay+ client with credentials (async) • Create Express app instance • Configure CORS middleware • Parse JSON and URL-encoded request bodies • Register API route handlers under /api prefix • Start server on port 1999 (default) or PORT env variable ``` :: ::warning Both backend implementations require several environment variables to function. See the [Configuration](https://superqi-dev-docs.pages.dev/#configuration) section below for required settings. :: ## API Endpoints All endpoints are prefixed with `/api` and organized by functionality: ### Authentication **POST /api/auth/apply-token** Exchanges an authorization code for an access token and retrieves user information. **Purpose:** Establishes authenticated session for the user. ::code-group ```go [go] // File: api/authEndpoint.go // Receives auth_code, calls ApplyToken(), then InquiryUserInfo(), // and returns a JWE token containing user_id and access_token ``` ```javascript [Node.js] // File: src/api/authEndpoint.js // Receives auth_code, calls applyToken(), then inquiryUserInfo(), // and returns a JWE token containing user_id and access_token ``` :: ### Online Payment **POST /api/payment/create** Creates a one-time payment transaction. ### Refund **POST /api/payment/refund** Refunds a completed payment transaction. ### Agreement Payment Agreement payments enable recurring charges without user interaction each time. **POST /api/agreement/prepare** Prepares authorization for agreement payment setup. **POST /api/agreement/apply-token** Exchanges agreement authorization code for agreement access token. **POST /api/agreement/pay** Executes payment using a previously established agreement. **Use Cases:** Subscriptions, recurring billing, automated payments ### Inbox Notification **POST /api/notification/send-inbox** Sends inbox messages to user's Super Qi wallet app. ## Alipay+ Client Implementation Both backends provide a complete SDK for interacting with Alipay+ APIs with identical functionality. ### Client Structure The client implements: - **RSA256 signature** generation for request authentication - **Signature format:** `{METHOD} {PATH}\n{ClientId}.{RequestTime}.{JSONBody}` - **Required headers:** Client-Id, Request-Time, Signature, Content-Type ::code-group ```go [go] // Package: alipay/client.go // Generate signature for API request signContent := fmt.Sprintf("%s %s\n%s.%s.%s", httpMethod, path, clientID, requestTime, jsonContent) hash := sha256.Sum256([]byte(signContent)) signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:]) base64Signature := base64.StdEncoding.EncodeToString(signature) ``` ```javascript [Node.js] // Module: src/alipay/client.js // Generate signature for API request const signContent = `${httpMethod} ${path}\n${clientId}.${requestTime}.${content}`; const sign = crypto.createSign('SHA256'); sign.update(signContent); sign.end(); const signature = sign.sign(privateKey, 'base64'); ``` :: ### Available Methods ::code-group ```go [go] // Package: alipay/ ApplyToken(authCode) → ApplyTokenResponse InquiryUserInfo(accessToken) → InquiryUserInfoResponse PrepareAuthorization(contractDesc) → PrepareAuthorizationResponse InquiryUserCardList(accessToken) → InquiryUserCardListResponse Pay(PaymentRequest) → PaymentResponse Refund(RefundRequest) → RefundResponse InquiryRefund(InquiryRefundRequest) → InquiryRefundResponse SendInbox(SendInboxRequest) → SendInboxResponse ``` ```javascript [Node.js] // Module: src/alipay/ applyToken(authCode) → Promise inquiryUserInfo(accessToken) → Promise prepareAuthorization(contractDescription) → Promise inquiryUserCardList(accessToken) → Promise pay(request) → Promise refund(request) → Promise inquiryRefund(request) → Promise sendInbox(request) → Promise ``` :: ### Response Handling All API responses contain a `Result` struct with: - **resultStatus:** "S" (success), "F" (fail), "U" (unknown), "A" (accepted) - **resultCode:** SUCCESS, PAYMENT\_NOT\_EXIST, REFUND\_NOT\_EXIST, etc. - **resultMessage:** Human-readable error message ## Security & Token Management ### JWE Encryption Both backends use **JWE (JSON Web Encryption)** to securely transmit sensitive data: - **Algorithm:** A256GCM (AES-256-GCM) - **Key encryption:** Direct (jose.DIRECT) - **Key size:** 32-byte symmetric key from `JWT_KEY` environment variable - **Format:** Base64-encoded full serialization - **Claims:** `{user_id, access_token}` ::code-group ```go [go] // Package: jwe/jwe.go // Create encrypted token claims := jwe.TokenClaims{ UserID: userId, AccessToken: accessToken, } token, err := jwe.CreateJWE(claims) // Parse encrypted token claims, err := jwe.ParseAndValidateJWE(token) userId := claims.UserID accessToken := claims.AccessToken ``` ```javascript [Node.js] // Module: src/jwe/jwe.js // Create encrypted token const token = await createJWE({ user_id: userId, access_token: accessToken }); // Parse encrypted token const claims = await parseJWE(token); const userId = claims.user_id; const accessToken = claims.access_token; ``` :: ::warning The main purpose behind using JWE here is to send the data to the frontend and store it in the frontend because we are not using a database in this demo to simplify the whole process. In normal scenarios there won't be a need to use JWE and send the data to the frontend again - just store it in the backend with proper database security. :: ### Configuration Create a `.env` file in the backend directory (`backend-go` or `backend-node`) with the following variables: ```bash # Alipay+ Gateway Configuration ALIPAY_GATEWAY_URL= ALIPAY_CLIENT_ID= # RSA Keys (PEM format) ALIPAY_MERCHANT_PRIVATE_KEY_PATH= ALIPAY_PUBLIC_KEY_PATH= # Token Encryption JWT_KEY=<32-byte key for JWE> ``` ::warning Never commit your `.env` file or RSA private keys to version control. Keep these credentials secure and separate from your codebase. Both Go and Node.js implementations use the same `.env` format. :: ## Key Implementation Details ### Request ID Generation All API requests use unique IDs following the pattern: `{PREFIX}-{UUID}-{TIMESTAMP}` **Prefixes:** - Online payment: `PAY-...` - Agreement payment: `AGREEMENT-PAY-...` - Refund: `REFUND-...` - Notification: `NOTIF-...` **Purpose:** Ensures idempotency and enables request tracing. ::code-group ```go [go] import ( "github.com/google/uuid" "time" ) requestId := fmt.Sprintf("PAY-%s-%d", uuid.New().String(), time.Now().Unix() ) // Example: PAY-550e8400-e29b-41d4-a716-446655440000-1640000000 ``` ```javascript [Node.js] import { v4 as uuidv4 } from 'uuid'; const requestId = `PAY-${uuidv4()}-${Date.now()}`; // Example: PAY-550e8400-e29b-41d4-a716-446655440000-1640000000000 ``` :: ### Error Handling Both backends use consistent error responses: | HTTP Status | Scenario | | ----------------------------- | ------------------------ | | **400 Bad Request** | Invalid request body | | **401 Unauthorized** | Token validation failure | | **500 Internal Server Error** | API call failures | All errors return JSON with: `success`, `resultStatus`, `resultCode`, `resultMessage` ::code-group ```go [go] // Error response example c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "resultStatus": "F", "resultCode": "INVALID_REQUEST", "resultMessage": "Invalid request body", }) ``` ```javascript [Node.js] // Error response example res.status(400).json({ success: false, resultStatus: "F", resultCode: "INVALID_REQUEST", resultMessage: "Invalid request body" }); ``` :: ## Next Steps Now that you understand the backend structure in both Go and Node.js, you can: 1. **Choose your stack** - Pick the implementation that fits your team's expertise 2. **Develop your miniapp** - Use these demos as a reference for your own implementation 3. **Test locally** - See [Testing Locally](https://superqi-dev-docs.pages.dev/developers-guide/demo-miniapp/testing-locally) for deployment instructions 4. **Go to production** - Once complete, move on to the "Releasing to Production" section Both backends provide identical functionality, so you can even build a hybrid approach or migrate between them later! # Security Review ## Overview Once you've completed development and thoroughly tested your Miniapp, it's time to prepare it for the security review, once you pass the security review, you can go live! The first step in this process is obtaining a UAT/test **permanent QR code** that will be used for the security test. ## Important Security Considerations The Security Team conducts a thorough review of your Miniapp according to standardized security frameworks. In average cases, the security team will report back to the Miniapps development team **multiple security issues** that need to be patched. ::warning It can easily take **more than one report** back from the security team for your Miniapp to receive the green light to go live. Sometimes issues cannot be fully patched from the first report, requiring multiple review cycles. :: ## Prerequisites Before proceeding, ensure you have: - Completed development of your Miniapp - Tested all features thoroughly - Hosted your frontend application - Hosted your backend application - Updated the frontend URL in the Super Qi Console ::warning Make sure your Miniapp is production-ready before applying for a permanent UAT/test QR code. The security team will review your application, so ensure everything is working correctly. :: ## Step-by-Step Guide ### Step 1: Navigate to Your Miniapp Log in to the **Super Qi Console** and navigate to your Miniapp. Select the UAT/test **version** that you want to release to production. ![Select UAT Version](https://superqi-dev-docs.pages.dev/developer-guide/test-release.png) ### Step 2: Apply for Release Click on the **"Apply Release"** button. ![Apply Release Button](https://superqi-dev-docs.pages.dev/developer-guide/apply-to-release.png) This will initiate the process of generating a permanent QR code for your Miniapp. ### Step 3: Confirm Release Application A confirmation popup will appear. Review the details and click **"Apply"** to confirm. ![Confirm Release](https://superqi-dev-docs.pages.dev/developer-guide/confirm-apply-release.png) ::note Once you click "Apply", the system will begin processing your request. This may take a few moments. :: ### Step 4: Refresh and View QR Code After clicking "Apply", wait a few moments and then **refresh the page**. You should now see your **permanent QR code** displayed. ![Permanent QR Code](https://superqi-dev-docs.pages.dev/developer-guide/permanent-testing-qr.png) This QR code is unique to your Miniapp and will be used for the security review. ## Submitting for Security Review Once you have obtained the permanent QR code, follow these steps: ### 1. Contact Miniapp Team Send an email to **** and CC **** with the following information: - The permanent QR code - Miniapp name - The purpose of the Miniapp and how it operates - API Documentation (Swagger/Postman) - Test user in your dashboard (the one that generally manages, adminstrates... etc) credentials for all roles in the MiniApp (e.g., User, Admin) ::note If your Miniapp doesn't use tools like Swagger/Postman, or uses different technologies that are not specified, you can still describe in your email how your Miniapp behaves. :: **Example email:** ```text To: hani.salih@qi.iq CC: mouamle.hameed@qi.iq Subject: Miniapp Security Review Request - [Your Miniapp Name] Hello team, Our Miniapp "Example App" (v1.0.0) is ready for production release and security review. Attached is the permanent QR code. Miniapp Name: Example App Miniapp Purpose: This Miniapp is an e-commerce platform that allows users to browse products, add items to cart, and make payments using QiCard. Users can view their order history and track deliveries. How it operates: - Users authenticate using my.getAuthCode and applyToken - Product browsing and cart management - Payment processing via cashier payment flow (my.tradePay) - Order tracking and history API Documentation: - Swagger: https://api.example.com/swagger - Postman Collection: https://api.example.com/postman-collection.json - Manual API description: Our backend exposes REST APIs for product management (GET /api/products, POST /api/orders), user authentication (POST /api/auth/login), and payment processing (POST /api/payments). All endpoints require Bearer token authentication. Request/response formats follow JSON standards. Test User Credentials: We will provide a dedicated test account in our dashboard for your security testing with the following roles: - Admin Role (full access to dashboard and administrative functions) - Regular User Role (standard customer access) Username: securityTestUser Password: abc123 Please proceed with the security review. Thank you! ``` ### 2. Wait for Security Team Review After you submit the email: 1. The **Miniapp team** and the **Security Team** will review your submission 2. The security team will perform a thorough review of your Miniapp 3. They will test functionality, security, and compliance ::warning **Be patient during the review process.** The security team needs time to thoroughly evaluate your Miniapp. This is an important step to ensure the safety and quality of all Miniapps on the Super Qi platform. :: ## Next Steps After receiving security approval, proceed to **[Merchant Registration](https://superqi-dev-docs.pages.dev/developers-guide/releasing-to-production/merchant-registration)** to complete the production release process. # Merchant Registration ## Overview After receiving security approval for your Miniapp, the next step is to complete **Merchant Registration**. This process involves submitting your business information so that the Super Qi team can create production credentials for your Miniapp. ## Prerequisites Before proceeding with merchant registration, ensure: - Your Miniapp has been approved by the security team - You have your business information ready ::warning Production credentials are different from your testing/UAT credentials. These credentials will be used for your live Miniapp in production. :: ## Step-by-Step Guide ### Step 1: Wait for Qi Team Contact Once your Miniapp has passed the security review, **wait for the Qi team to contact you**. They will reach out to initiate the merchant registration process. ::warning If you haven't been contacted after your Miniapp's approval, feel free to notify the Miniapps team to let them know your Miniapp has been approved. The team may be busy and might not have noticed the approval yet. :: ### Step 2: Receive and Complete the Excel Sheet The Qi team will send you an **Excel sheet** containing the fields that need to be filled in for merchant credential creation. ::warning Fill in all the required information accurately and completely. This information will be used to create your production credentials. :: ### Step 3: Submit the Completed Excel Sheet Once you have filled in all the required details, submit the completed Excel sheet back to the Qi team. ::warning Make sure all information is accurate and matches your official business documentation. Incorrect information may delay the credential generation process. :: ## What Happens Next After submitting your completed Excel sheet: 1. **Document Review** - The Qi team will review your submitted information 2. **Additional Requests** - The Qi team might contact you multiple times during the credential creation process if they need: - Additional official documents - Clarification on any information - Further business verification details 3. **Credential Generation** - Production credentials will be created for your Miniapp 4. **Credential Delivery** - The Miniapps team will contact you with your new production credentials ::warning Be responsive to any inquiries from the Qi team. The credential generation process may take some time, especially if additional documentation is required. :: ## Receiving Your Credentials The Miniapps team will contact you and **provide your production credentials** once they are ready. ::warning **Keep your production credentials secure!** Never share them publicly or commit them to version control. Store them securely using environment variables or a secrets management service. :: ## Next Steps Once you have received your production credentials, you can proceed to **[Release Production Miniapp](https://superqi-dev-docs.pages.dev/developers-guide/releasing-to-production/release-prod-miniapp)** to complete the final steps and launch your Miniapp to production. # Release Production Miniapp ## Overview You're almost there! By now, you should have received your unique production credentials from the Miniapps team. This final step involves creating a new version of your Miniapp with production credentials and applying for the official release. ## Prerequisites By this point, you should have received your production credentials from the Miniapps team. These include your Client ID, Merchant ID, and the Gateway URL. Your production frontend and backend should already be deployed and tested, and you'll need access to Super Qi Console to proceed. ::warning Production credentials are different from your UAT/testing credentials. Make sure you're using the correct production credentials for this step. :: ## Step-by-Step Guide ### Step 1: Create New Version with Production Credentials Log in to **Super Qi Console** and navigate to your Miniapp. You need to create a **new version** with your production credentials. The process for creating a new version is almost the same as creating your testing version, except at the end, dont create UAT version, stay with the prod version. For detailed instructions, refer to: **[Configure and Test Miniapp](https://superqi-dev-docs.pages.dev/developers-guide/create-your-first-miniapp/configure-and-test-miniapp)** When creating this new version, make sure to use your **Production Client ID** and **Production Merchant ID** - not your testing credentials. You'll also need to configure your **deployed production frontend URL** in this version. ::warning Double-check that you're using production credentials, not testing credentials. Using the wrong credentials will cause issues when your Miniapp goes live. :: ### Step 2: Verify Your Configuration Before applying for release, take a moment to verify that all your credentials are correctly entered. Make sure your production frontend URL is configured properly, and double-check that your backend is using the production credentials in its `.env` file. ### Step 3: Apply to Release Once you've created the new version with production credentials and verified everything works, navigate to the **latest version** (the one with production credentials) and click on **"Apply to Release"**. ![Apply to Release](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release.png) A confirmation dialog will appear. Review the details carefully and confirm the release application. ### Step 4: Wait for Miniapps Team Approval After you apply for release, your application will be sent to the **Miniapps team** for final review. The team will verify your production setup to ensure everything meets the required standards. Once approved, You will be notified to proceed to the next step. ::warning **Be patient during the approval process.** The Miniapps team will review your submission to ensure everything meets production standards. You will be notified once your Miniapp is approved and goes live. :: ### Step 5: Pilot Testing Once approved, you'll move on to the **Pilot Testing** stage. Click on the **"Add Testers"** button to begin. ![Pilot Testing - Add Testers](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release2.png) Add anything in the input and click on **Add**. Note that you don't actually have to add real testers - we just need the input to not be empty so it can be submitted. ![Add Testers Input](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release3.png) Next, click on the **"Complete Testing"** button to proceed. ![Complete Testing](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release4.png) Then click on the **"Complete"** button for confirmation. ![Complete Confirmation](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release5.png) ### Step 6: Grayscale Release In the **Grayscale Release** stage, select **"Final Release"** and then click on **"Confirm"** so that the Miniapp can go live. ![Grayscale Release - Final Release](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release6.png) ### Step 7: Miniapp Released Congratulations - your Miniapp is now going live! ![Miniapp Released](https://superqi-dev-docs.pages.dev/developer-guide/prod-apply-to-release7.png) Now wait **30 minutes** and then the Miniapp will be available in Super Qi search. ::note To have your Miniapp appear in a designated section, you will need to communicate with the Miniapps team via the communication channel agreed on. :: ## Congratulations! You have successfully completed the development and release process for your Miniapp! Your Miniapp is now awaiting final approval before going public on the Super Qi platform. ## Need Help? If you have questions or encounter issues, check the **[FAQ](https://superqi-dev-docs.pages.dev/faq)** for frequently asked questions. You can also contact the Miniapps team through your communication channel # Overview ## Overview This section contains the complete API reference documentation for building Super Qi Mini Programs. Here you'll find detailed guides on authentication flows, payment integration, backend APIs, and client-side JavaScript APIs. ## Documentation Sections The API Reference is organized into three main sections to help you quickly find what you need: ### Flows End-to-end integration guides that walk you through complete user journeys and workflows. **What it contains:** - Step-by-step flow diagrams - Complete authentication and payment workflows - Request/response examples - Integration best practices **When to use:** - Understanding how different APIs work together - Implementing user authentication - Setting up payment flows (cashier or agreement) - Learning the complete integration process **Available Flows Examples:** - [Authentication](https://superqi-dev-docs.pages.dev/api-reference/flows/authentication) - User authorization and token management - [Cashier Payment](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment) - Standard payment with wallet cashier - [Agreement Payment](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) - Recurring auto-debit payments --- ### Open APIs Backend-to-backend HTTP APIs called from your merchant server to the Super Qi backend. **What it contains:** - REST API endpoints - Request/response structures - Authentication and signature requirements - Error codes and handling **When to use:** - Exchanging authorization codes for tokens - Creating payment orders - Querying payment status - Processing refunds - Any server-side operations **Key Characteristics:** - Called from **merchant backend** - Requires digital signature authentication - Uses POST method with JSON payloads - Backend-to-backend communication **Available Categories:** - [Authorization APIs](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - Token exchange and agreement preparation - [Payment APIs](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - Payment processing and inquiry --- ### JSAPIs Client-side JavaScript APIs called from your Mini Program to access platform features. **What it contains:** - JavaScript function references - SDK integration guide - Callback and promise patterns **When to use:** - Requesting user authorization in the Mini Program - Launching the payment cashier - Signing agreement contracts - Accessing device features - Making HTTP requests from the client - Displaying UI elements (alerts, toasts) **Key Characteristics:** - Called from **Mini Program client** (front-end) - Uses JavaScript with callbacks/promises - Requires JSBridge SDK integration - Direct user interaction **Available Categories:** - [Essential APIs](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - Authentication and payment APIs - UI, Network, Storage, Device, Location, and Media APIs --- ## Quick Decision Guide **Need to authenticate a user?** 1. Start with the [Authentication Flow](https://superqi-dev-docs.pages.dev/api-reference/flows/authentication) 2. Use [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) JSAPI in your Mini Program 3. Call [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) Open API from your backend **Need to process a payment?** 1. Start with the [Cashier Payment Flow](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment) 2. Call [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) Open API from your backend 3. Use [my.tradePay](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) JSAPI to launch the cashier **Need recurring payments?** 1. Start with the [Agreement Payment Flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) 2. Use [prepare](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/prepare) and [qicardSignContract](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) 3. Call [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) with agreement parameters # Cashier Payment ## Overview This flow covers the standard cashier payment experience where the Mini Program hands off to the wallet hosted cashier page. Use `POST /v1/payments/pay` (cashier mode) to create the order, then open the cashier via `my.tradePay`. ::warning Cashier payment is part of the [`pay` API](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay), which supports both cashier and agreement payment scenarios. :: ![Cashier payment diagram](https://superqi-dev-docs.pages.dev/api-reference/cashier-payment.png) ### Flow Steps 1. The Mini Program calls this my.getAuthCode JSAPI with specific scopes(USER\_ID) to request an authorization code. 2. The E-wallet App service calls authorization service to processes the authorization information. 3. The E-wallet backend verifies the authorization information, generates the authCode and returns. 4. The E-wallet App service returns the authCode to the Mini Program. 5. The Mini Program sends the authCode to the merchant backend. 6. The merchant backend calls the applyToken API with authCode to apply the accessToken. 7. The E-Wallet backend returns accessToken information to the merchant backend, such as customerId, accessToken, refreshToken, etc. 8. The Mini Program creates an order with customerId. 9. The merchant backend calls the payment API to initiate payment flow, including customerId as referenceBuyerId, paymentNotifyUrl(optional), etc. 10. The E-Wallet backend returns payment detail information the merchant backend, such as redirectionUrl. 11. The merchant backend passes the payment detail information to the Mini Program. 12. The Mini Program calls the my.tradePay JSAPI with redirectionUrl to conduct the payment. 13. The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc. 14. The user confirms the payment in the cashier page. 15. The E-Wallet App Service calls payment service and execute the payment process. 16. When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 18). 17. Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 10(Step 19). 18. Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message (Step 20). ## Request Structure ```json POST /v1/payments/pay Content-Type: application/json { "productCode": "51051000101000000011", "paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGkydOQC6", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "order_description", "buyer": { "referenceBuyerId": "216610000000003660xxxx" } }, "paymentExpiryTime": "2024-01-18T16:10:36+03:00", "paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx", "paymentRedirectUrl": "https://www.merchant.com/order/return", "voidNotifyUrl": "https://www.merchant.com/payment/void", "extendInfo": "{\"memo\":\"channel=miniapp\"}" } ``` ### Field Notes - `productCode`: cashier product identifier defined by the wallet (e.g., `"51051000101000000011"`). - `paymentRequestId`: unique ID per payment (max 64 characters) for idempotence. - `paymentAmount.value`: value in IQD fils; ensure it matches the order total. - `order.buyer.referenceBuyerId`: must match the `customerId` returned by `applyToken`. - `paymentExpiryTime`: optional ISO 8601 timestamp to auto-close the order. - `paymentNotifyUrl`: HTTPS endpoint to receive asynchronous payment results. - `paymentRedirectUrl`: optional URL for post-payment completion/cancel page. - `voidNotifyUrl`: optional endpoint for void notifications. - `extendInfo`: JSON string for custom metadata (max 2048 chars). ## Response ```json { "result": { "resultCode": "ACCEPT", "resultStatus": "A", "resultMessage": "accept" }, "paymentId": "2023120611121280010016600900000xxxx", "redirectActionForm": { "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx" } } ``` ### Response Interpretation - `result.resultStatus = A`: payment accepted; redirect the user using `redirectActionForm.redirectionUrl` via `my.tradePay`. - `result.resultStatus = S`: payment completed instantly; update order status and wait for notifications. - `result.resultStatus = U`: wallet returned an unknown status; do not mark success/failure yet—wait for notification or poll `/v1/payments/inquiryPayment`. - `result.resultStatus = F`: payment failed. Inspect `result.resultCode` (e.g., `USER_BALANCE_NOT_ENOUGH`, `RISK_REJECT`, `REPEAT_REQ_INCONSISTENT`) and provide remediation to the user. ## Common Error Codes | Status | resultCode | Description | Recommended Action | | ------ | ----------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------- | | `U` | `PAYMENT_IN_PROCESS` | Payment still processing. | Wait for wallet notification or poll `/v1/payments/inquiryPayment`. | | `F` | `PAYMENT_AMOUNT_EXCEED_LIMIT` | Amount exceeds wallet limit. | Send smaller amount or request higher limit. | | `F` | `USER_BALANCE_NOT_ENOUGH` | User’s wallet balance insufficient. | Prompt user to top up balance. | | `F` | `USER_STATUS_ABNORMAL` | User account restricted. | Instruct user to resolve with wallet support. | | `F` | `PARTNER_STATUS_ABNORMAL` | Merchant account restricted. | Resolve merchant compliance issues before retrying. | | `F` | `RISK_REJECT` | Blocked by risk engine. | Request user to try later or different channel. | | `F` | `CURRENCY_NOT_SUPPORT` | Unsupported currency. | Use IQD or permitted currency. | | `F` | `INVALID_ACCESS_TOKEN` | Access token invalid/expired. | Re-run `applyToken`. | | `F` | `REPEAT_REQ_INCONSISTENT` | Duplicate `paymentRequestId` with different payload. | Reuse original payload or change `paymentRequestId`. | ## Related APIs - [`my.getAuthCode`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - [`my.tradePay`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) - [`inquiryPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) - [`refund`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/refund) # Authentication ## Overview This flow covers the user authentication process in Mini Programs, enabling merchants to obtain user authorization and access tokens. The flow consists of two key steps: requesting an authorization code via `my.getAuthCode` and exchanging it for access tokens via `applyToken`. These tokens allow merchants to access user data and perform authorized operations. ::warning Authentication is a prerequisite for both [Cashier Payment](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment) and [Agreement Payment](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) flows. :: ::warning Merchants do not need to implement any additional authentication or authorization mechanisms beyond Super Qi's authentication flow. This authentication system is sufficient for all user authorization and API access requirements. :: ![Authentication flow diagram](https://superqi-dev-docs.pages.dev/api-reference/get-auth-code.png) ### Flow Steps #### Authorization Request Phase 1. The Mini Program calls the my.getAuthCode JSAPI with specific scopes to request an authorization code. 2. The E-wallet App processes the request and displays the authorization page that needs to be authorized. 3. The user confirms the authorization in the super app. 4. The E-wallet App service calls authorization service to processes the authorization information. 5. The E-wallet backend verifies the authorization information, generates the authCode and returns. 6. The E-wallet App service returns the authCode to the Mini Program. 7. The Mini Program sends the authCode to the merchant backend. 8. The merchant backend calls the applyToken API with authCode to apply the accessToken. 9. The E-Wallet backend returns accessToken information to the merchant backend, such as accessToken, refreshToken, etc. ::warning Silent scopes like `auth_base`, `USER_ID`, `USER_LOGIN_ID`, and `HASH_LOGIN_ID` do not require explicit user consent and are granted automatically. :: #### Token Exchange Phase After obtaining the authorization code, the merchant exchanges it for access tokens: **1. Request Authorization Code (`my.getAuthCode`)** The Mini Program initiates the authentication flow by calling [`my.getAuthCode`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) with the required scopes. This JSAPI prompts the user (if needed) and returns an `authCode` that represents the user's consent. For more details, check the [`my.getAuthCode` documentation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code). **2. Exchange for Access Token (`applyToken`)** The merchant backend securely exchanges the `authCode` for access tokens by calling [`POST /v1/authorizations/applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). This endpoint returns an `accessToken`, `refreshToken`, and `customerId` which are used for subsequent API calls. For more details, check the [`applyToken` endpoint documentation](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). **3. Token Refresh (`applyToken` with REFRESH\_TOKEN)** When the `accessToken` expires, merchants can obtain a new token without user interaction by calling `applyToken` with `grantType: REFRESH_TOKEN` and the stored `refreshToken`. This maintains seamless user experience without re-authorization. For more details, check the [`applyToken` endpoint documentation](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). ## Authorization Code Request ### my.getAuthCode Parameters ```js my.getAuthCode({ scopes: ['USER_ID'], success: (res) => { // Send res.authCode to merchant backend my.request({ url: 'https://merchant.com/api/auth', method: 'POST', data: { authCode: res.authCode } }); }, fail: (err) => { console.log('Authorization failed:', err.authErrorScopes); } }); ``` ### Available Scopes For the complete, authoritative list of scopes — covering both **Customer User** and **Business (Merchant) User** scopes and which support silent authorization — see the [Scope Reference](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#scope-reference) in `getAuthCode`. ::warning Scopes marked with "Silent Authorization: No" require explicit user consent and will display an authorization dialog. :: ::warning **Scope Access by Merchant Type:** - **Internal Qi Merchants**: Have access to all available scopes listed above. - **External Merchants**: Can only access `auth_base` and `USER_ID` scopes. :: ### Success Response ```json { "authCode": "0000000001T1dc0W0tv44B0BD00007826", "authSuccessScopes": ["USER_ID"] } ``` ### Failure Response ```json { "authErrorScopes": { "auth_user": "10001" } } ``` ## Token Exchange Request ### applyToken Request Structure ```json POST /v1/authorizations/applyToken Content-Type: application/json { "grantType": "AUTHORIZATION_CODE", "authCode": "2810111301lGzcM9CjlF91WH00039190xxxx" } ``` ### Field Notes - `grantType`: Use `AUTHORIZATION_CODE` to exchange an authCode, or `REFRESH_TOKEN` to refresh an expired access token. - `authCode`: The authorization code obtained from `my.getAuthCode` (required when `grantType` is `AUTHORIZATION_CODE`). - `refreshToken`: The refresh token from a previous `applyToken` call (required when `grantType` is `REFRESH_TOKEN`). - `extendInfo`: Optional JSON string for additional metadata (max 4096 characters). ::warning Never expose `accessToken` or `refreshToken` to the Mini Program client. Store them securely on your backend server. :: ## Token Exchange Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx", "accessTokenExpiryTime": "2023-06-06T12:12:12+08:00", "refreshToken": "2810100334F62CBC577F468AAC87CFC6C9107811xxxx", "refreshTokenExpiryTime": "2023-06-08T12:12:12+08:00", "customerId": "1000001119398804xxxx" } ``` ### Response Interpretation - `result.resultStatus = S`: token exchange successful; store the tokens and `customerId` securely. - `result.resultStatus = U`: unknown exception; retry the request or check server logs. - `result.resultStatus = F`: exchange failed. Inspect `result.resultCode` (e.g., `INVALID_CODE`, `EXPIRED_CODE`, `USED_CODE`) and handle accordingly. ### Response Fields - `accessToken`: Token used to authenticate API requests on behalf of the user. Has a shorter lifespan. - `accessTokenExpiryTime`: ISO 8601 timestamp indicating when the access token expires. - `refreshToken`: Token used to obtain a new access token without user interaction. - `refreshTokenExpiryTime`: ISO 8601 timestamp indicating when the refresh token expires. - `customerId`: Unique identifier for the user; use this as `referenceBuyerId` in payment requests. ## Token Refresh Request When the `accessToken` expires, use the refresh token to obtain a new one: ```json POST /v1/authorizations/applyToken Content-Type: application/json { "grantType": "REFRESH_TOKEN", "refreshToken": "2810110033AAB2F588D14B43238637264FCA5AAF35xxxx" } ``` ::warning If the `refreshToken` also expires, the user must re-authorize via `my.getAuthCode` to obtain a new authorization code. :: ## Common Error Codes ### my.getAuthCode Errors | Code | Description | Recommended Action | | ------ | --------------------------------- | ---------------------------------------------------------------- | | `3` | Unknown error occurred. | Retry the request or check app logs. | | `1000` | Unknown error occurred. | Retry the request or check app logs. | | `1001` | User cancelled the authorization. | Prompt user to try again or explain why authorization is needed. | | `1002` | App service error occurred. | Check network connectivity and retry. | | `1003` | Request timed out. | Retry with a stable network connection. | | `2001` | Pending agreement authorization. | Complete agreement setup first. | ### applyToken Errors | resultCode | resultStatus | Description | Recommended Action | | ------------------------------------ | ------------ | -------------------------------- | ----------------------------------------------------- | | `AUTH_CLIENT_UNSUPPORTED_GRANT_TYPE` | `F` | Unsupported grant type. | Use `AUTHORIZATION_CODE` or `REFRESH_TOKEN`. | | `INVALID_CODE` | `F` | Authorization code is invalid. | Obtain a new authCode via `my.getAuthCode`. | | `USED_CODE` | `F` | Authorization code already used. | Obtain a new authCode via `my.getAuthCode`. | | `EXPIRED_CODE` | `F` | Authorization code expired. | Obtain a new authCode via `my.getAuthCode`. | | `INVALID_REFRESH_TOKEN` | `F` | Refresh token is invalid. | Re-authorize with `my.getAuthCode` to get new tokens. | | `EXPIRED_REFRESH_TOKEN` | `F` | Refresh token expired. | Re-authorize with `my.getAuthCode` to get new tokens. | | `USED_REFRESH_TOKEN` | `F` | Refresh token already used. | Use the tokens from the previous successful refresh. | ## Related APIs - [`my.getAuthCode`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [`prepare`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/prepare) - [`qicardSignContract`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) # Agreement Payment ## Overview This flow covers the agreement payment experience where users authorize recurring or auto-debit payments without requiring approval for each transaction. The merchant first obtains user consent via `qicardSignContract`, then can charge the user automatically using `POST /v1/payments/pay` (agreement mode) with the signed agreement token. ::warning Agreement payment is part of the [`pay` API](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) and requires the special scope `AGREEMENT_PAY` to be authorized during the agreement setup phase. :: ![Agreement payment diagram](https://superqi-dev-docs.pages.dev/api-reference/agreement-payment.png) ### Flow Steps 1. The Mini Program calls merchant backend to prepare the contract. 2. The merchant backend calls this prepare API with contract information to prepare the contract. 3. The E-Wallet backend returns authorization information to the merchant backend, such as authorizationUrl. 4. The merchant backend passes the authorization information to the Mini Program. 5. The Mini Program calls the my.call("qicardSignContract") JSAPI with authorizationUrl to conduct the authorization. 6. The E-Wallet App Service displays the authorization page with contract information provided in Step 2. 7. The user confirms the authorization agreement pay in the authorization page. 8. The E-Wallet App Service calls authorization service and execute the authorization process. 9. When the authorization reaches the final status, the E-wallet backend returns the authCode to the Mini Program (Step 10). 10. The Mini Program sends the authCode merchant backend. 11. The merchant backend calls this applyToken API with authCode to apply the accessToken(Step 12). 12. The E-Wallet backend returns accessToken information to the merchant backend, such as accessToken, refreshToken, etc. 13. The merchant backend calls this payment API with accessToken to deduct money from user's balance silently without user operation(Step 14). 14. The E-wallet backend returns the payment result to the merchant backend instantly(Step 15). 15. Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 14(Step 16). 16. Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message (Step 17). ## Request Structure ```json POST /v1/payments/pay Content-Type: application/json { "productCode": "51051000101000100031", "paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGKydOQC6", "paymentAuthCode": "0000000002202310013fQ6vpiUNV79nT00006725", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "Monthly subscription payment" }, "paymentExpiryTime": "2024-01-18T16:10:36+03:00", "paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx" } ``` ### Field Notes - `productCode`: agreement payment product identifier defined by the wallet (e.g., `"51051000101000100031"`). - `paymentRequestId`: unique ID per payment (max 64 characters) for idempotence. - `paymentAuthCode`: **required** for agreement payments; this is the `accessToken` obtained from `applyToken` after agreement signing. - `paymentAmount.value`: value in IQD fils; ensure it matches the order total. - `order.buyer.referenceBuyerId`: **optional** in agreement payment; if provided, must match the `customerId` associated with the agreement. - `paymentExpiryTime`: optional ISO 8601 timestamp to auto-close the order. - `paymentNotifyUrl`: HTTPS endpoint to receive asynchronous payment results. - `extendInfo`: JSON string for custom metadata (max 2048 chars). ::warning Ensure the `paymentAuthCode` is valid and matches the user who signed the agreement. Mismatches will be rejected by the wallet. :: ## Response ```json { "result": { "resultStatus": "S", "resultCode": "SUCCESS", "resultMessage": "Success." }, "paymentId": "2023103011121280010016679410005274x", "paymentTime": "2023-10-30T09:17:13+03:00" } ``` ### Response Interpretation - `result.resultStatus = S`: payment completed successfully; update order status immediately. - `result.resultStatus = U`: wallet returned an unknown status; wait for notification or poll `/v1/payments/inquiryPayment`. - `result.resultStatus = F`: payment failed. Inspect `result.resultCode` (e.g., `USER_BALANCE_NOT_ENOUGH`, `INVALID_ACCESS_TOKEN`, `AUTH_CODE_ALREADY_USED`) and provide remediation to the user. ::warning Agreement payments typically complete synchronously (status `S` or `F`), unlike cashier payments which return status `A` (accepted) and require a redirect. :: ## Common Error Codes | Status | resultCode | Description | Recommended Action | | ------ | ----------------------------- | ------------------------------------ | ------------------------------------------------------------------- | | `U` | `PAYMENT_IN_PROCESS` | Payment still processing. | Wait for wallet notification or poll `/v1/payments/inquiryPayment`. | | `F` | `PAYMENT_AMOUNT_EXCEED_LIMIT` | Amount exceeds wallet limit. | Send smaller amount or request higher limit. | | `F` | `USER_BALANCE_NOT_ENOUGH` | User's wallet balance insufficient. | Notify user to top up balance. | | `F` | `USER_STATUS_ABNORMAL` | User account restricted. | Instruct user to resolve with wallet support. | | `F` | `PARTNER_STATUS_ABNORMAL` | Merchant account restricted. | Resolve merchant compliance issues before retrying. | | `F` | `RISK_REJECT` | Blocked by risk engine. | Request user to try later or different channel. | | `F` | `CURRENCY_NOT_SUPPORT` | Unsupported currency. | Use IQD or permitted currency. | | `F` | `INVALID_ACCESS_TOKEN` | Access token invalid/expired. | Re-run agreement signing flow to obtain new token. | | `F` | `AUTH_CODE_ALREADY_USED` | Authorization code already consumed. | Generate new authCode via prepare + qicardSignContract. | | `F` | `INVALID_CODE` | Authorization code is illegal. | Verify authCode format and expiry. | | `F` | `USER_AMOUNT_EXCEED_LIMIT` | Payment amount exceeds user's limit. | Reduce amount or request user to increase limit. | ## Related APIs - [`prepare`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/prepare) - [`qicardSignContract`](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) - [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - [`inquiryPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) - [`refund`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/refund) # Escrow Payment ## Overview Escrow payment provides buyer protection by holding funds in escrow until the customer confirms receipt of goods or services. This flow requires multiple API calls throughout the transaction lifecycle: payment initiation, merchant acceptance, and customer confirmation (or void/cancel if issues arise). The escrow flow ensures that: - Funds are held securely until the merchant fulfills the order - Merchants must explicitly accept orders before fulfillment - Customers can confirm receipt to release funds - Merchants can void/cancel if fulfillment cannot be completed ::warning Escrow payment uses the special product code `51051000101000100008`. Standard cashier payments use a different product code and complete immediately without the acceptance/confirmation steps. :: ## Complete Escrow Flow ### 1. Initial Payment (Cashier Mode) The flow starts like a standard cashier payment, but uses the escrow product code. **Steps 1-18:** Follow the standard [cashier payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment): 1. Mini Program gets authorization via `my.getAuthCode` 2. Merchant backend exchanges authCode for accessToken via `applyToken` 3. Mini Program creates order and sends to merchant backend 4. Merchant backend calls `pay` API with escrow product code 5. Customer completes payment in wallet cashier 6. Funds are held in escrow (not released to merchant yet) **Request to `/v1/payments/pay`:** ```json { "productCode": "51051000101000100008", "paymentRequestId": "escrow_order_20240101_123456", "paymentAmount": { "currency": "IQD", "value": "500000" }, "order": { "orderDescription": "iPhone 15 Pro - Space Black", "buyer": { "referenceBuyerId": "216610000000003660xxxx" } }, "paymentNotifyUrl": "https://www.merchant.com/notify/payment", "paymentRedirectUrl": "https://www.merchant.com/order/return" } ``` **Response:** ```json { "result": { "resultCode": "ACCEPT", "resultStatus": "A", "resultMessage": "accept" }, "paymentId": "2024010111121280010016600900000xxxx", "redirectActionForm": { "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx" } } ``` ### 2. Merchant Accepts Order After payment is completed, the merchant reviews the order (checks inventory, validates delivery address, etc.) and must explicitly accept it to proceed with fulfillment. **API:** `POST /v1/payments/merchantAccept` **Request:** ```json { "paymentId": "2024010111121280010016600900000xxxx" } ``` **Response:** ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." } } ``` ::callout{type="info"} **Why Accept?** The acceptance step commits the merchant to fulfilling the order. If the merchant cannot fulfill (out of stock, delivery issue, etc.), they should not accept and should instead use the `cancel` API. :: ### 3. Fulfillment & Delivery After acceptance, the merchant: - Prepares and ships the goods - Provides tracking information to customer - Delivers the product/service During this phase, the funds remain in escrow. ### 4. Customer Confirms Receipt Once the customer receives and verifies the goods/services are satisfactory, they confirm receipt through the Mini Program. This releases the escrowed funds to the merchant. **API:** `POST /v1/payments/confirm` **Request:** ```json { "paymentId": "2024010111121280010016600900000xxxx", "confirmRequestId": "confirm_20240115_789012" } ``` **Response:** ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "confirmId": "202401151112128001016xxxx", "confirmTime": "2024-01-15T14:30:22+03:00" } ``` ::warning **Irreversible Action:** Once confirmed, funds are immediately released to the merchant and **cannot be reversed**. Customers should only confirm after verifying goods are satisfactory. :: ### Transaction Complete The escrow payment is now complete and the merchant receives the funds. ## Alternative Flows ### Cancel Before Acceptance If the merchant decides not to accept the order (e.g., out of stock, cannot deliver), they can cancel the payment **before** calling `merchantAccept`. This immediately returns the full amount to the customer. **API:** `POST /v1/payments/cancel` **Use when:** - Merchant is out of stock - Cannot deliver to customer's location - Pricing error on the order - Payment result delayed and merchant wants to cancel **Request:** ```json { "paymentId": "2024010111121280010016600900000xxxx" } ``` **Response:** ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "paymentId": "2024010111121280010016600900000xxxx", "cancelTime": "2024-01-01T15:20:10+03:00" } ``` ::callout{type="warning"} **Important:** After calling `merchantAccept`, you **cannot** use `cancel`. Use `void` instead. :: ### Void After Acceptance If issues arise **after** the merchant has accepted the order but before/during delivery, the merchant can initiate a void to return funds to the customer. **API:** `POST /v1/payments/void` **Use when:** - Merchant accepted but cannot fulfill (supplier issue, damaged goods, etc.) - Delivery failed or goods cannot be delivered - Goods were damaged and cannot be replaced - Any other fulfillment issue preventing order completion **Full Void Request:** ```json { "voidRequestId": "void_20240105_345678", "paymentId": "2024010111121280010016600900000xxxx" } ``` **Partial Void Request:** ```json { "voidRequestId": "void_20240105_345678", "paymentId": "2024010111121280010016600900000xxxx", "voidAmount": { "value": "200000", "currency": "IQD" } } ``` **Response:** ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "voidRequestId": "void_20240105_345678", "voidId": "202401051112128017xxxx" } ``` ::callout{type="info"} **Partial vs Full Void:** - **Full void**: Returns entire amount and closes the order - **Partial void**: Returns part of the amount; order remains open with timeout for remaining funds :: ### Refund After Completion If the customer already confirmed receipt but later discovers issues (defective product, wrong item, etc.), the merchant can issue a refund. **API:** `POST /v1/payments/refund` **Use when:** - Customer confirmed but goods were defective - Wrong item was delivered - Customer changed mind after confirmation (merchant's discretion) - Warranty claim or return processing **Request:** ```json { "refundRequestId": "refund_20240120_901234", "paymentId": "2024010111121280010016600900000xxxx", "refundAmount": { "value": "500000", "currency": "IQD" } } ``` ## Key Differences: Escrow vs Standard Payment | Aspect | Standard Cashier Payment | Escrow Payment | | ---------------- | ----------------------------- | -------------------------------------------- | | Product Code | `51051000101000000011` | `51051000101000100008` | | Fund Release | Immediate | After customer confirmation | | Merchant Action | None required | Must call `merchantAccept` | | Customer Action | None required | Must call `confirm` to release funds | | Buyer Protection | Standard wallet policies | Extended protection with escrow hold | | After Acceptance | Use `refund` after completion | Use `void` before completion, `refund` after | ## Polling Payment Status Since escrow payments involve multiple steps, use `inquiryPayment` to check the current transaction status: **API:** `POST /v1/payments/inquiryPayment` **Request:** ```json { "paymentId": "2024010111121280010016600900000xxxx" } ``` **Response includes:** - `paymentStatus`: Current payment status (`PROCESSING`, `SUCCESS`, `FAIL`, etc.) - `transactions`: Array of all transaction operations (PAY, VOID, REFUND, etc.) ## Common Error Codes ### merchantAccept Errors | resultCode | Cause | Action | | ---------------------------- | ----------------------------------------- | ------------------------------------------ | | `ORDER_STATUS_INVALID` | Payment not completed or already accepted | Verify payment status via `inquiryPayment` | | `ORDER_IS_MERCHANT_ACCEPTED` | Already accepted | No action needed | | `ORDER_NOT_EXIST` | Invalid payment ID | Verify `paymentId` | ### void Errors | resultCode | Cause | Action | | -------------------------------- | ---------------------------------------- | ------------------------------------------- | | `ORDER_STATUS_INVALID` | Order cannot be voided in current status | Check if already voided/cancelled/confirmed | | `VOID_AMOUNT_EXCEEDS_AUTH_LIMIT` | Void amount exceeds payment amount | Reduce void amount | | `MUTEX_OPERATION_IN_PROCESSING` | Another operation in progress | Wait and retry | | `ORDER_UNSUPPORTED_OPERATION` | Non-escrow payment | Only escrow payments support void | ### confirm Errors | resultCode | Cause | Action | | ------------------------------- | ---------------------------- | ---------------------------- | | `ORDER_STATUS_INVALID` | Merchant hasn't accepted yet | Wait for merchant acceptance | | `MUTEX_OPERATION_IN_PROCESSING` | Void/refund in progress | Wait and retry | | `ORDER_NOT_EXIST` | Invalid payment ID | Verify `paymentId` | ### cancel Errors | resultCode | Cause | Action | | ------------------------- | --------------------------- | ---------------------- | | `ORDER_HAS_BEEN_CAPTURED` | Already confirmed/completed | Use `refund` instead | | `ORDER_HAS_BEEN_VOIDED` | Already voided | No action needed | | `CANCEL_WINDOW_EXCEED` | Too late to cancel | Use `void` or `refund` | ## Related APIs - [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - Initiate escrow payment - [`merchantAccept`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) - Accept the order - [`confirm`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/confirm-order) - Confirm receipt and release funds - [`void`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) - Void payment after acceptance - [`cancel`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) - Cancel before acceptance - [`refund`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/refund) - Refund after completion - [`inquiryPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) - Query payment status ## Best Practices 1. **Always check payment status** before calling `merchantAccept` to ensure payment was successful 2. **Set reasonable timeouts** for acceptance and confirmation to avoid funds being held indefinitely 3. **Implement notifications** for all payment events (payment, acceptance, confirmation, void, etc.) 4. **Validate inventory** before accepting orders to avoid accepting orders you cannot fulfill 5. **Provide tracking information** to customers after acceptance to reduce disputes 6. **Handle async notifications** properly as some operations may complete asynchronously 7. **Use idempotent IDs** (`voidRequestId`, `confirmRequestId`) to safely retry failed operations 8. **Monitor for `UNKNOWN_EXCEPTION`** status and poll `inquiryPayment` rather than assuming failure # Overview ## Overview Mini Programs offer a comprehensive set of OpenAPIs to achieve various capabilities, such as payment processing, user authorization, and data exchange. These APIs are designed for **backend-to-backend communication** between your merchant backend and the Super Qi backend using HTTPS requests. ::warning Open APIs are called from your **merchant backend** to the **Super Qi backend**. They should never be called directly from the Mini Program client to ensure security and proper authentication. :: This guide covers the message structure, authentication, and signature generation required for all OpenAPI communications. ## Project Setup Before sending requests to the Super Qi backend, ensure you have: 1. **Client ID**: Provided during merchant onboarding 2. **Private Key**: Submitted when creating your merchant account (used to sign all requests) 3. **Public Key**: Registered with Super Qi for signature verification ::warning Keep your private key secure and never expose it in client-side code or public repositories. :: ## Versioning The current API version is **v1**. The version is specified in the URL path. **Example:** ```text https://{host}/v1/payments/pay ``` Different versions of the same API are treated as separate endpoints: - `/v1/payments/pay` is different from `/v2/payments/pay` ## Message Structure Understanding how OpenAPI requests and responses are structured is essential before making any API calls. The diagram below illustrates the complete request structure: ![Request structure diagram](https://superqi-dev-docs.pages.dev/api-reference/request-structure.png) ### Request URL The request URL follows this structure: ```text https://{host}/{restful_path} ``` **Components:** - **host**: The base gateway URL assigned to you by the Super Qi team. It is **shared privately during onboarding** and is not published here — always use the value you received. - **restful\_path**: The path to the specific API interface, formatted as `/{version}/{resource}/{action}` — for example, `/v1/payments/pay`. - **version**: The current API version is `v1`. **Examples:** ```text https://{host}/v1/payments/pay https://{host}/v1/authorizations/applyToken https://{host}/v1/payments/refund ``` Each interface is uniquely identified by its `restful_path`. ## Request Method All OpenAPI requests use the **POST** method for HTTP requests. ```http POST /v1/payments/pay Host: {host} ``` ## Authentication and Security All requests to Super Qi OpenAPIs require proper authentication through request headers and digital signatures. ### Request Headers Each request must include the following headers: | Header | Required | Description | Example | | -------------- | -------- | ----------------------------------------------------------- | ------------------------------------------------ | | `Content-Type` | Yes | Media type of the request body. Always use JSON with UTF-8. | `application/json; charset=UTF-8` | | `Client-Id` | Yes | Your unique merchant identifier provided during onboarding. | `2021001234567890` | | `Request-Time` | Yes | ISO 8601 timestamp when the request is sent. | `2024-01-01T12:00:00-07:00` | | `Signature` | Yes | Digital signature for request authentication and integrity. | `algorithm=RSA256, keyVersion=1, signature=****` | **Complete Header Example:** ```http Content-Type: application/json; charset=UTF-8 Client-Id: 2021001234567890 Request-Time: 2024-01-01T12:00:00-07:00 Signature: algorithm=RSA256, keyVersion=1, signature=base64_encoded_signature ``` ::warning Header field names are **case-insensitive**, but values are case-sensitive. :: ### Signature Generation The signature ensures request authenticity and prevents tampering. Follow these steps to generate a valid signature: #### Step 1: Create Sign Content Combine the HTTP method, path, and request details in this format: ```text {HTTP_METHOD} {PATH}\n {CLIENT_ID}.{REQUEST_TIME}.{JSON_CONTENT} ``` **Example:** ```text POST /v1/authorizations/applyToken 2021001234567890.2024-01-01T12:00:00-07:00.{"grantType":"AUTHORIZATION_CODE","authCode":"281011130..."} ``` #### Step 2: Hash the Content Use **SHA-256** to hash the sign content created in Step 1. ```javascript const hash = SHA256(signContent); ``` #### Step 3: Sign with RSA Sign the hash using your **private key** with: - **Algorithm**: RSA - **Padding**: PKCS1v15 - **Hash**: SHA-256 ```javascript const signature = RSA_Sign(hash, privateKey, PKCS1v15); ``` #### Step 4: Base64 Encode Encode the signature in **base64** format. ```javascript const base64Signature = Base64.encode(signature); ``` #### Step 5: Add to Header Include the signature in the request header: ```http Signature: algorithm=RSA256, keyVersion=1, signature={base64Signature} ``` **Signature Header Components:** | Component | Description | Value | | ------------ | ---------------------------------------------- | --------------------------------- | | `algorithm` | Digital signature algorithm (case-insensitive) | `RSA256` (default) | | `keyVersion` | Version of the key used for signing | `1` (or your current key version) | | `signature` | Base64-encoded signature value | Generated in Step 4 | ### Code Examples Here are complete signature generation examples in different programming languages: ::code-group ```go [go] signContent := fmt.Sprintf("%s %s\n%s.%s.%s", httpMethod, path, clientID, requestTime, content ) hash := sha256.Sum256([]byte(signContent)) signature, err := rsa.SignPKCS1v15(nil, privateKey, crypto.SHA256, hash[:]) base64Signature := base64.StdEncoding.EncodeToString(signature) ``` ```javascript [Node.js] import crypto from "crypto"; const signContent = `${httpMethod} ${path}\n${clientID}.${requestTime}.${content}`; const hash = crypto.createHash("sha256").update(signContent).digest(); const signature = crypto.sign("RSA-SHA256", hash, privateKey); const base64Signature = signature.toString("base64"); ``` :: ## Request Body The request body contains detailed request information in **JSON format**. All request bodies are JSON objects with parameters specific to each API endpoint. ### Parameter Structure Each API has its own required parameters. Here are some common examples: **applyToken Request:** ```json { "grantType": "AUTHORIZATION_CODE", "authCode": "2810111301lGzcM9CjlF91WH00039190xxxx" } ``` **pay Request (Cashier Payment):** ```json { "productCode": "51051000101000000011", "paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGkydOQC6", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "order_description", "buyer": { "referenceBuyerId": "216610000000003660xxxx" } }, "paymentNotifyUrl": "https://www.merchant.com/paymentNotify" } ``` ::callout{type="info"} For detailed information about specific request body parameters, refer to the individual API documentation. :: ## Response Structure All OpenAPI responses follow a consistent structure with a `result` object containing status information. ### Response Header Response headers contain metadata about the response: | Header | Description | | --------------- | ----------------------------------------------------------------------------- | | `Response-Time` | ISO 8601 timestamp when the response was generated | | `Content-Type` | Media type of the response body (typically `application/json; charset=UTF-8`) | ### Response Body **General Structure:** ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "additionalField1": "value1", "additionalField2": "value2" } ``` **Result Object Fields:** | Field | Type | Description | | --------------- | -------- | --------------------------------------------------------------------------------- | | `resultCode` | `string` | Specific result code (e.g., `SUCCESS`, `INVALID_PARAMETER`, `PAYMENT_IN_PROCESS`) | | `resultStatus` | `string` | General result status: `S` (Success), `F` (Failed), `U` (Unknown), `A` (Accepted) | | `resultMessage` | `string` | Human-readable description of the result | ### Result Status Values | Status | Meaning | Action Required | | ------ | -------------------------------------------------------- | ----------------------------------------------------- | | `S` | **Success** - Operation completed successfully | Proceed with business logic | | `A` | **Accepted** - Request accepted, further action required | Follow instructions in response (e.g., redirect user) | | `U` | **Unknown** - Result uncertain due to system error | Retry or query status; do not assume success/failure | | `F` | **Failed** - Operation failed | Check `resultCode` and handle error appropriately | ## Response Example ```http HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Response-Time: 2024-11-15T14:30:01.234+03:00 { "result": { "resultCode": "ACCEPT", "resultStatus": "A", "resultMessage": "accept" }, "paymentId": "2023120611121280010016600900000xxxx", "redirectActionForm": { "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx" } } ``` ## Related Documentation - [inquireUserInfo](https://superqi-dev-docs.pages.dev/api-reference/open-apis/users/inquiry-user-info) - Inquiring the user's information - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - payment APIs guide - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - Exchanging authCode for an accessToken # applyToken ## Overview `POST /v1/authorizations/applyToken` issues wallet access tokens for merchants. Call this endpoint after obtaining an authorization code (for example via `my.getAuthCode` or `qicardSignContract`) or when you need to refresh an existing token. The app returns `accessToken` and `refreshToken` values that must be stored securely on your server. ::warning - The client should invoke `my.getAuthCode` before calling `applyToken` to collect the `authCode`. - Use `grantType: REFRESH_TOKEN` with the `refreshToken` to renew expiring tokens without user interaction. - Never expose the resulting tokens to the Mini Program; keep them on the merchant backend. :: ::warning To view the end-to-end diagram, see the [Authentication flow](https://superqi-dev-docs.pages.dev/api-reference/flows/authentication). :: ## Endpoint | Method | Path | | ------ | ------------------------------- | | `POST` | `/v1/authorizations/applyToken` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | -------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | | `grantType` | `string` | Yes | Token exchange mode. Accepted values: `AUTHORIZATION_CODE` (exchange `authCode`), `REFRESH_TOKEN` (exchange `refreshToken`). | `"AUTHORIZATION_CODE"` | | `authCode` | `string` | Conditional | Authorization code obtained from the wallet. Required when `grantType` is `AUTHORIZATION_CODE`. Max length 64; no special characters `@#?`. | `"2810111301lGzcM9CjlF91WH00039190xxxx"` | | `refreshToken` | `string` | Conditional | Refresh token issued previously. Required when `grantType` is `REFRESH_TOKEN`. Max length 128; no `@#?`. | `"2810110133AB2F588D14B43238637264FCA5AAF35xxxx"` | | `extendInfo` | `string` | No | Additional metadata (max 4096 characters, no `@#?`). | `{ "memo": "Recurring agreement" }` | ```json { "grantType": "AUTHORIZATION_CODE", "authCode": "2810111301lGzcM9CjlF91WH00039190xxxx" } ``` ```json { "grantType": "REFRESH_TOKEN", "refreshToken": "2810110033AAB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response | Field | Type | Required | Description | Example | | ------------------------ | -------- | ----------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | | `result` | `object` | Yes | Outcome metadata including status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }` | | `accessToken` | `string` | Conditional | Access token for user data APIs. Present when exchange succeeds. Max length 128; no `@#?`. | `"281010033AB2F588D14B43238637264FCA5AAF35xxxx"` | | `accessTokenExpiryTime` | `string` | Conditional | Expiry timestamp (ISO 8601). Required when `accessToken` is issued. | `"2023-06-06T12:12:12+08:00"` | | `refreshToken` | `string` | Conditional | Refresh token for future exchanges. Required when exchange succeeds. | `"2810100334F62CBC577F468AAC87CFC6C9107811xxxx"` | | `refreshTokenExpiryTime` | `string` | Conditional | Expiry timestamp (ISO 8601). Required when `refreshToken` is issued. | `"2023-06-08T12:12:12+08:00"` | | `customerId` | `string` | Yes | Identifier of the authorizing user or merchant app. Max length 64; no `@#?`. | `"1000001119398804xxxx"` | | `extendInfo` | `string` | No | Extended response metadata (max 4096 characters, no `@#?`). | `null` | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx", "accessTokenExpiryTime": "2023-06-06T12:12:12+08:00", "refreshToken": "2810100334F62CBC577F468AAC87CFC6C9107811xxxx", "refreshTokenExpiryTime": "2023-06-08T12:12:12+08:00", "customerId": "1000001119398804xxxx" } ``` ### Result Processing Logic | Status | Description | | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Request succeeded. `resultCode` is `SUCCESS` and `resultMessage` is `success`. | | `U` | Outcome unknown. `resultCode` is `UNKNOWN_EXCEPTION`; retry after checking [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) or logs. | | `F` | Request failed. Inspect `resultCode` and cross-reference [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | Error Code | Result Status | Message | Next Step | | ------------------------------------ | ------------- | -------------------------------------------------- | ----------------------------------------------------------------- | | `AUTH_CLIENT_UNSUPPORTED_GRANT_TYPE` | `F` | Merchant client does not support this `grantType`. | Use `AUTHORIZATION_CODE` or `REFRESH_TOKEN`. | | `INVALID_REFRESH_TOKEN` | `F` | Refresh token is invalid. | Request a new refresh token via `applyToken`. | | `EXPIRED_REFRESH_TOKEN` | `F` | Refresh token expired. | Re-authorize with `my.getAuthCode` to obtain a new refresh token. | | `USED_REFRESH_TOKEN` | `F` | Refresh token already used. | Acquire a new refresh token via `applyToken`. | | `INVALID_CODE` | `F` | Authorization code invalid. | Obtain a new `authCode` via `my.getAuthCode`. | | `USED_CODE` | `F` | Authorization code already used. | Request a new `authCode` via `my.getAuthCode`. | | `EXPIRED_CODE` | `F` | Authorization code expired. | Request a new `authCode` via `my.getAuthCode`. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [qicardSignContract](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) - [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) # prepare ## Overview `POST /v1/authorizations/prepare` issues an `authUrl` that merchants use to launch the QiCard signing experience. Supply the agreement scope and descriptive metadata; upon success the API returns a hosted URL for `qicardSignContract`. ::warning To view the end-to-end diagram, see the [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment). :: ## Endpoint | Method | Path | | ------ | ---------------------------- | | `POST` | `/v1/authorizations/prepare` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | | ------------ | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `scopes` | `string` | Yes | Scope to authorize. Use `AGREEMENT_PAY` to initiate agreement payments. Max length 16 characters. | | `extendInfo` | `string` | Yes | JSON string describing the contract. Max length 4096 characters; disallow `@`, `#`, `?`. Include keys such as `language` (`"en-US"` or `"ar-IQ"`) and `contractDesc`. | ```json { "scopes": "AGREEMENT_PAY", "extendInfo": "{\"language\":\"en-US\",\"contractDesc\":\"agreement payment description.\"}" } ``` ### Response | Field | Type | Required | Description | | --------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata with status and codes. | | `authUrl` | `string` | No | Hosted authorization URL to pass into `qicardSignContract`. Returned when `result.resultStatus` is `S`. Max length 256 characters. | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "authUrl": "https://xxxxx.wallet.iq?authId=xxxxx" } ``` ### Result Processing Logic | Status | Description | | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Request succeeded. The merchant can redirect users via `authUrl`. | | `U` | Result unknown (`resultCode`: `UNKNOWN_EXCEPTION`). Retry or inspect [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes). | | `F` | Request failed. Check `resultCode` and the [Error codes](https://superqi-dev-docs.pages.dev/#error-codes) table. | ## Error Codes | Error Code | Result Status | Message | Next Step | | --------------- | ------------- | -------------------------------------------------------------------------- | ---------------------------------------------- | | `INVALID_SCOPE` | `F` | The provided scope is invalid. | Use a supported scope such as `AGREEMENT_PAY`. | | `PARAM_ILLEGAL` | `F` | Request parameters are invalid (e.g., non-numeric fields, malformed JSON). | Validate payload fields before retrying. | ## Related Links - [qicardSignContract](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) # inquiryPayment ## Overview `POST /v1/payments/inquiryPayment` returns the latest status of a wallet payment. Merchants poll this API when asynchronous callbacks (for example via `paymentNotifyUrl`) do not arrive in time. Always send requests in the smallest currency unit (IQD fils). ::warning - Poll at a round-robin interval between 5 seconds and 1 minute to avoid throttling. - Monetary values must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD is `100000`. :: ![Inquiry payment flow](https://superqi-dev-docs.pages.dev/api-reference/inquiry-payment.png) 1. Mini Program calls `my.getAuthCode` with the required scopes to request authorization. 2. Wallet app service processes the authorization request and displays the consent page to the user. 3. User approves the authorization, and the wallet backend verifies the request and issues an `authCode`. 4. Wallet app service returns the `authCode` to the Mini Program. 5. Mini Program forwards the `authCode` to the merchant backend. 6. Merchant backend calls [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) with the `authCode` to obtain tokens. 7. Wallet backend returns `accessToken`, `refreshToken`, and `customerId` information to the merchant backend. 8. Mini Program creates the payment order using the received `customerId` and sends it to the merchant backend. 9. Merchant backend invokes `/v1/payments/pay` to initiate the payment and receives a `redirectionUrl` and optional `paymentNotifyUrl` confirmation. 10. Merchant backend relays the `redirectionUrl` to the Mini Program. 11. Mini Program calls `my.tradePay` with the `redirectionUrl` to open the cashier experience. 12. Wallet app service presents the cashier UI, the user confirms the payment, and the wallet backend processes the transaction. 13. Wallet backend returns the payment result to the Mini Program and pushes notifications to the merchant backend via `paymentNotifyUrl`. 14. Merchant backend polls `/v1/payments/inquiryPayment` with `paymentId` or `paymentRequestId`, and the wallet backend responds with the latest payment status and transaction details. ## Endpoint | Method | Path | | ------ | ----------------------------- | | `POST` | `/v1/payments/inquiryPayment` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------------ | -------- | ----------- | ------------------------------------------------------------------------------------------------- | -------------------------------------- | | `paymentId` | `string` | Conditional | Wallet-generated payment ID. Max 64 characters. Provide either `paymentId` or `paymentRequestId`. | `"202312061112128001001660090000xxxx"` | | `paymentRequestId` | `string` | Conditional | Merchant-generated payment ID. Max 64 characters. Used when `paymentId` is unavailable. | `"20230101234567890133333xxxx"` | ```json { "paymentRequestId": "102217200000000000001xxxx" } ``` ```json { "paymentId": "202312061112128001001660090000xxxx" } ``` > Provide either `paymentId` or `paymentRequestId` (not both). If both are provided, `paymentId` takes precedence. ### Response | Field | Type | Required | Description | Example | | ------------------ | -------- | -------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `result` | `object` | Yes | Request outcome metadata (status and error codes). | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }` | | `paymentId` | `string` | No | Wallet payment ID. | `"202312061112128001001660090000xxxx"` | | `paymentRequestId` | `string` | No | Merchant payment ID. | `"20230101234567890133333xxxx"` | | `paymentAmount` | `object` | No | Amount/value pair in smallest currency unit. | `{ "value": "100000", "currency": "IQD" }` | | `paymentTime` | `string` | No | Payment completion timestamp in ISO 8601 format. | `"2023-01-01T12:01:01+08:00"` | | `paymentStatus` | `string` | No | Status of the payment. Possible values: `PROCESSING`, `AUTH_SUCCESS`, `SUCCESS`, `FAIL`. | `"SUCCESS"` | | `transactions` | `array` | No | Detailed transaction records (amount, type, status, timestamp). | `[{"transactionAmount":{"value":"100000","currency":"IQD"},"transactionId":"20231206111212800100xxxx","transactionTime":"2023-01-01T12:01:01+08:30","transactionType":"PAY","transactionStatus":"SUCCESS"}]` | | `extendInfo` | `string` | No | Additional information supplied by wallet or merchant. Max length 2048 characters. | `"extendInfo": "additional information"` | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "paymentId": "202312061112128001001660090000xxxx", "paymentRequestId": "20230101234567890133333xxxx", "paymentAmount": { "value": "100000", "currency": "IQD" }, "paymentTime": "2023-01-01T12:01:01+08:00", "paymentStatus": "SUCCESS", "transactions": [ { "transactionAmount": { "value": "100000", "currency": "IQD" }, "transactionId": "20231206111212800100xxxx", "transactionTime": "2023-01-01T12:01:01+08:30", "transactionType": "PAY", "transactionStatus": "SUCCESS" } ] } ``` ### Result Processing Logic | Status | Description | | ------ | ---------------------------------------------------------------------------------------------------------------------------- | | `S` | Inquiry succeeded. Check `paymentStatus` for the actual payment outcome. | | `U` | Result unknown (`resultCode`: `UNKNOWN_EXCEPTION`). Retry later and monitor notifications. | | `F` | Inquiry failed. Review `resultCode` and `resultMessage`; see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | resultStatus | resultCode | resultMessage | Recommended Action | | ------------ | ----------------- | --------------------- | ----------------------------------------------------------------------- | | `F` | `ORDER_NOT_EXIST` | Order does not exist. | Verify `paymentId`/`paymentRequestId`; treat as unpaid until clarified. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [tradePay](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # inquiryRefund ## Overview `POST /v1/payments/inquiryRefund` retrieves the current status of a wallet refund. Use this endpoint when the refund completion callback takes longer than expected. All monetary amounts must be sent in the smallest currency unit (IQD fils). ::warning - Poll no more than once every 5 seconds (up to 1 minute) to reduce load. - Refund amounts and amounts in responses use the smallest currency unit, e.g. 100 IQD → `100000`. :: ![Inquiry refund flow](https://superqi-dev-docs.pages.dev/api-reference/inquiry-refund.png) 1. Mini Program calls `my.getAuthCode` with `USER_ID` scope to request authorization. 2. Wallet app service calls the authorization service to validate the request. 3. Wallet backend returns `authCode` to the wallet app service. 4. Wallet app service returns `authCode` to the Mini Program. 5. Mini Program sends the `authCode` to the merchant backend. 6. Merchant backend invokes [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) with the `authCode` to obtain tokens. 7. Wallet backend returns token data (`accessToken`, `refreshToken`, `customerId`) to the merchant backend. 8. Mini Program creates an order using `customerId`. 9. Merchant backend initiates the payment request with `/v1/payments/pay`, providing `customerId`, `paymentNotifyUrl`, etc. 10. Wallet backend returns payment details (including `redirectionUrl`) to the merchant backend. 11. Merchant backend forwards the payment details to the Mini Program. 12. Mini Program calls `my.tradePay` with the `redirectionUrl`. 13. Wallet app service opens the cashier page with order information. 14. Wallet app service displays the cashier UI to the user. 15. User confirms payment within the cashier UI. 16. Wallet app service triggers the payment execution in the backend. 17. Wallet backend processes the payment and returns the result to the wallet app service. 18. Mini Program receives the payment result from the wallet backend. 19. Wallet backend sends payment notifications to the merchant backend via `paymentNotifyUrl`. 20. Wallet backend notifies the user via SMS/email/inbox of the payment outcome. 21. User initiates a full or partial refund after receiving goods/services. 22. Mini Program submits the refund request to the merchant backend. 23. Merchant backend calls `/v1/payments/refund` to request the refund from the wallet backend. 24. Wallet backend returns the refund processing result to the merchant backend. 25. Wallet backend returns refund status to the Mini Program (displayed to user). 26. Mini Program shows the refund result in the UI. 27. If `resultCode` of the refund is `REFUND_IN_PROCESS`, merchant backend polls `/v1/payments/inquiryRefund` using `refundId` or `refundRequestId`. 28. Wallet backend responds with the latest refund inquiry result to the merchant backend. ## Endpoint | Method | Path | | ------ | ---------------------------- | | `POST` | `/v1/payments/inquiryRefund` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ----------------- | -------- | ----------- | ----------------------------------------------------------------------------------------------- | -------------------------------------- | | `refundId` | `string` | Conditional | Wallet-generated refund ID (max 64 characters). Provide either `refundId` or `refundRequestId`. | `"202312061112128013001660090000xxxx"` | | `refundRequestId` | `string` | Conditional | Merchant-generated refund ID (max 64 characters). Used when `refundId` is not available. | `"2023010123456789013255xxxx"` | ```json { "refundId": "202312061112128013001660090000xxxx", "refundRequestId": "2023010123456789013255xxxx" } ``` > If both identifiers are supplied, `refundId` takes precedence and `refundRequestId` is ignored. ### Response | Field | Type | Required | Description | Example | | ------------------ | -------- | -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | | `result` | `object` | Yes | Outcome metadata, including `resultCode`, `resultStatus`, and `resultMessage`. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }` | | `refundId` | `string` | No | Wallet refund ID. | `"202312061112128013001660090000xxxx"` | | `refundRequestId` | `string` | No | Merchant refund ID. | `"2023010123456789013255xxxx"` | | `refundAmount` | `object` | No | Refund amount/value in smallest currency unit. | `{ "value": "100000", "currency": "IQD" }` | | `refundReason` | `string` | No | Reason for the refund, if supplied (max 256 characters). | `"Customer requested order cancellation."` | | `refundTime` | `string` | No | Timestamp when funds were deducted from the merchant (ISO 8601). | `"2023-01-02T12:01:01+08:30"` | | `refundStatus` | `string` | No | Refund processing state: `PROCESSING`, `SUCCESS`, or `FAIL`. | `"SUCCESS"` | | `refundFailReason` | `string` | No | Description explaining why the refund failed (present when `refundStatus` is `FAIL`). | `"Refund declined by issuer."` | | `extendInfo` | `string` | No | Additional metadata provided by wallet or merchant (max 2048 characters). | `"extendInfo": "additional info"` | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "refundId": "202312061112128013001660090000xxxx", "refundRequestId": "2023010123456789013255xxxx", "refundAmount": { "value": "100000", "currency": "IQD" }, "refundReason": "Order cancelled by user.", "refundTime": "2023-01-02T12:01:01+08:30", "refundStatus": "SUCCESS" } ``` ### Result Processing Logic | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------ | | `S` | Refund inquiry succeeded. Inspect `refundStatus` for the current state. | | `U` | Unknown result (`resultCode`: `UNKNOWN_EXCEPTION`). Retry later or review logs. | | `F` | Inquiry failed. Review `resultCode`/`resultMessage`; see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | resultStatus | resultCode | resultMessage | Recommended Action | | ------------ | ------------------ | ---------------------- | ------------------------------------------------------------------------------------ | | `F` | `REFUND_NOT_EXIST` | Refund does not exist. | Verify `refundId`/`refundRequestId`; treat as pending if refund is still in process. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [tradePay](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [inquiryPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) # pay ## Overview `POST /v1/payments/pay` creates payment orders within the wallet. The endpoint supports three flows: - **Cashier payment (standard commerce)** – redirect the Mini Program to the wallet cashier where users approve each payment. - **Agreement payment (auto-debit)** – reuse a previously signed agreement (`paymentAuthCode`) to charge the user without presenting the cashier. - **Escrow payment** – funds are held securely in escrow until the merchant accepts and fulfills the order, protecting both buyer and seller. All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning A payment which takes place at wallets. The merchant/partner initiates a payment request to wallet through this interface, and the wallet will handle different payment scenarios based on the parameters in the request. :: ## Endpoint | Method | Path | | ------ | ------------------ | | `POST` | `/v1/payments/pay` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Shared Request Fields | Field | Type | Required | Description | | ------------------------------ | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `productCode` | `string` | Yes | Defined by wallets. The wallet uses the productCode to get the contract configuration which includes fee, limitation information, and so on. Max. length: 32 characters. :br:br**Examples:**:br • Online Purchase: `"51051000101000000011"`:br • Online Purchase (Auth Capture): `"51051000101000000012"`:br • Agreement Payment: `"51051000101000100031"`:br • Escrow Payment: `"51051000101000100008"` | | `paymentRequestId` | `string` | Yes | The unique ID of a payment generated by merchants. :br • Max. length: 64 characters. :br • This field is used for **idempotence** control. For the payment requests which are initiated with the same `paymentRequestId` and reach a final status (`S` or `F`), the wallet must return the unique result. | | `paymentAuthCode` | `string` | No\* | The payment auth code generated by the wallet, such as the `accessToken` in the agreement pay scenario. Max. length: 128 characters. :br:br \*Required for Agreement Payment scenario only. | | `paymentAmount` | `object` | Yes | The order amount, displaying users' consumption records, payment results page. :br:br**Note:** The monetary unit of value is fils, e.g. if the price is 100 IQD, then the `paymentAmount.value` should be `"100000"`. | | `paymentAmount.currency` | `string` | Yes | Currency code (e.g., `"IQD"`). | | `paymentAmount.value` | `string` | Yes | Amount value in smallest currency unit (fils). | | `order` | `object` | Yes | The purchase order details, such as Merchant, Buyer, Goods, etc. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc. It will not make use of the amount in the order for fund operation. :br:br**Note:** The buyer field is **optional only in the Agreement Payment** scenario. | | `order.orderDescription` | `string` | Yes | Description of the order. | | `order.buyer` | `object` | No\* | Buyer information. :br:br \*Optional in Agreement Payment, required in Cashier Payment. | | `order.buyer.referenceBuyerId` | `string` | Yes | The unique userId, which can be the `customerId` obtained from accessToken information in applyToken API. It must not be default. :br:br ️ **Important:** Please make sure the buyer and the payer is the same person. | | `paymentExpiryTime` | `string/datetime` | No | The payment order close time defined by merchant, which means the payment order will be `closed` automatically after `paymentExpiryTime`. If empty, the expiryTime will be defined by E-wallet. It follows the ISO 8601 standard. | | `paymentRedirectUrl` | `string` | No | The redirect URL defined by merchants. Max. length: 1024 characters. | | `paymentNotifyUrl` | `string` | No | The payment success notification URL defined by merchants. Max. length: 1024 characters. | | `voidNotifyUrl` | `string` | No | The url that void notification will be sent to. Max. length: 1024 characters. | | `extendInfo` | `string` | No | The extensive information. The wallet and merchant can put extensive information in this property. The format should be JSON format. Max. length: 2048 characters. | ::callout{type="warning"} Ensure `referenceBuyerId` in `order.buyer` matches the `customerId` retrieved from [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). :: ### Cashier Payment In this mode the merchant redirects the user to the wallet cashier embedded in the Mini Program. #### Flow Overview For example, a user purchases a 100 IQD good at the merchant/partner (online merchant usually), the merchant/partner calls this API to create the payment order first, the wallet will return the payment order ID and wallet cashier page URL to the merchant/partner, then merchant/partner can redirect user to wallet cashier page with the `my.tradePay` API. ::warning To view the end-to-end diagram, see the [Cashier Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment). :: #### Cashier Payment Request Additional Fields | Field | Type | Required | Description | | -------------------- | -------- | -------- | ------------------------------------------------------------------------------------------ | | `paymentRedirectUrl` | `string` | No | Merchant URL displayed when the user finishes or cancels the payment. Max 1024 characters. | | `order.buyer` | `object` | Yes | Required for cashier payment. | #### Sample Cashier Payment Request ```json { "productCode": "51051000101000000011", "paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGkydOQC6", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "order_description", "buyer": { "referenceBuyerId": "216610000000003660xxxx" } }, "paymentExpiryTime": "2024-01-18T16:10:36+03:00", "paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx" } ``` #### Key Points for Cashier Payment - `paymentRequestId` is generated by the merchant/partner, which uniquely identifies the payment. Wallet must make use of `paymentRequestId` for idempotent control. For example, if a payment with `paymentRequestId=2023112719074101000700000077771` has been processed successfully by Wallet, when the merchant/partner uses the same `paymentRequestId` for payment, Wallet will respond with successful payment. - `productCode` is the product code. The wallet uses the `productCode` to get the contract configuration which includes fee, limitation information, and so on. - `paymentNotifyUrl` is the URL defined by the merchant/partner. In the cashier payment scenario, after the user finished payment in the wallet cashier page, the wallet will notify the merchant of the payment result based on this URL. - `paymentAmount` describes the amount of 100 IQD to be collected by Wallet from user's account for this payment. - `order` describes the order details of the purchase of the 100 IQD merchandise by the user at the merchant. Such as Merchant, Buyer, Goods, etc are included in order. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc. - `referenceBuyerId` is the unique userID, which can be the `customerId` obtained from `accessToken` information in `applyToken` API. It must not be default. **Please make sure the buyer and the payer is the same person.** - `paymentExpiryTime` is the payment order close time defined by merchant, which means the payment order will be `closed` automatically after `paymentExpiryTime`. If empty, the `expiryTime` will be defined by E-wallet. #### Sample Cashier Payment Response ```json { "result": { "resultCode": "ACCEPT", "resultStatus": "A", "resultMessage": "accept" }, "paymentId": "2023120611121280010016600900000xxxx", "redirectActionForm": { "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx" } } ``` #### Response Field Details - `result.resultStatus == A` shows that the payment is accept success. After user finish payment in cashier page, payment will change to success. - `paymentId` is generated by Wallet, uniquely identifies the payment. - `redirectActionForm` returns the cashier page URL to the merchant/partner. After the merchant/partner receives the accept result, which will be redirected to this URL. ### Agreement Payment Agreement payments charge the user using an existing contract established via `qicardSignContract`. #### Flow Overview For example, a user authorizes an AgreementPay contract at the merchant/partner (online merchant usually), such as monthly subscription, the merchant/partner can call this API to automatically deduct money from the user's wallet without user's operation. ::warning To view the end-to-end diagram, see the [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment). :: #### Agreement Payment Request Additional Fields | Field | Type | Required | Description | | ------------------------------ | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paymentAuthCode` | `string` | Yes | Authorization token obtained during agreement signing (e.g., from `qicardSignContract` + `applyToken`). Max 128 characters. This was generated by the wallet as the `accessToken` in the agreement pay scenario. | | `order.buyer.referenceBuyerId` | `string` | No | Optional in agreement payment, but if provided must match the `customerId` associated with the agreement. | Other fields (such as `paymentRedirectUrl`) are optional and often unused because no cashier is displayed. ::callout{type="warning"} Ensure the payer represented by `referenceBuyerId` matches the user who signed the agreement; mismatches are rejected. :: #### Sample Agreement Payment Request ```json { "productCode": "51051000101000100031", "paymentRequestId": "UDQzzvxwvyvUDxGqhMHUlIBpGKydOQC6", "paymentAuthCode": "0000000002202310013fQ6vpiUNV79nT00006725", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "order_description" }, "paymentExpiryTime": "2024-01-18T16:10:36+03:00", "paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx" } ``` #### Key Points for Agreement Payment - `paymentRequestId` is generated by the merchant/partner, which uniquely identifies the payment. Wallet must make use of `paymentRequestId` for idempotent control. For example, if a payment with `paymentRequestId=2023112719074101000700000077771` has been processed successfully by Wallet, when the merchant/partner uses the same `paymentRequestId` for payment, Wallet will respond with successful payment. - `productCode` is the product code. The wallet uses the `productCode` to get the contract configuration which includes fee, limitation information, and so on. - `paymentNotifyUrl` is the URL defined by the merchant/partner. In the cashier payment scenario, after the user finished payment in the wallet cashier page, the wallet will notify the merchant of the payment result based on this URL. - `paymentAmount` describes the amount of 100 IQD to be collected by Wallet from user's account for this payment. - `order` describes the order details of the purchase of the 100 IQD merchandise by the user at the merchant. Such as Merchant, Buyer, Goods, etc are included in order. The information in the Order is only used to display user's payment result page and transactions history, regulation reporting, etc. - `paymentAuthCode` was generated by the wallet as the `accessToken` in the agreement pay scenario. - `paymentExpiryTime` is the payment order close time defined by merchant, which means the payment order will expire automatically after `paymentExpiryTime`. If empty, the `expiryTime` will be defined by E-wallet. #### Sample Agreement Payment Response Agreement payments usually complete synchronously. The wallet returns the payment result without a redirect form. ```json { "result": { "resultStatus": "S", "resultCode": "SUCCESS", "resultMessage": "Success." }, "paymentId": "2023103011121280010016679410005274x", "paymentTime": "2023-10-30T09:17:13+03:00" } ``` #### Response Field Details - `result.resultStatus == S` shows that the payment is success. - `paymentId` is generated by Wallet, uniquely identifies the payment. - `paymentTime` is generated by Wallet, it shows the payment finish time. ### Escrow Payment Escrow payments hold funds securely until the merchant accepts and fulfills the order, protecting both buyer and seller. The buyer pays upfront, but funds remain in escrow until the merchant completes delivery and the buyer confirms receipt. #### Flow Overview For example, a user purchases a 100 IQD product from a merchant. The merchant creates an escrow payment, and the user completes payment through the cashier. The funds are held in escrow until the merchant accepts the order, ships the product, and the customer confirms receipt. ::warning To view the complete escrow flow, see the escrow payment APIs: [`merchantAccept`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept), [`confirmOrder`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/confirm-order), [`cancelPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment), and [`voidPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment). :: #### Escrow Payment Request Additional Fields | Field | Type | Required | Description | | -------------------- | -------- | -------- | ------------------------------------------------------------------------------------------ | | `productCode` | `string` | Yes | Must be `"51051000101000100008"` for escrow payments. | | `paymentRedirectUrl` | `string` | No | Merchant URL displayed when the user finishes or cancels the payment. Max 1024 characters. | | `order.buyer` | `object` | Yes | Required for escrow payment. | | `paymentExpiryTime` | `string` | No | Payment expiry time. If not provided, wallet defines the expiry time. | #### Sample Escrow Payment Request ```json { "productCode": "51051000101000100008", "paymentRequestId": "ESCROW-PAY-550e8400-1702123456", "paymentAmount": { "currency": "IQD", "value": "100000" }, "order": { "orderDescription": "Premium Cotton T-Shirt", "buyer": { "referenceBuyerId": "216610000000003660xxxx" } }, "paymentExpiryTime": "2024-01-18T16:10:36+03:00", "paymentRedirectUrl": "http://merchant.com/order-tracking", "paymentNotifyUrl": "https://www.merchant.com/paymentNotifyxxxx" } ``` #### Key Points for Escrow Payment - `productCode` must be `"51051000101000100008"` for escrow payments. - After payment, funds are held in escrow. - Merchant must call [`merchantAccept`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) to accept the order. - After fulfillment, customer calls [`confirmOrder`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/confirm-order) to release funds. - Merchant can cancel before acceptance using [`cancelPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment). - After acceptance, merchant can use [`voidPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) to void if fulfillment cannot be completed. #### Sample Escrow Payment Response ```json { "result": { "resultCode": "ACCEPT", "resultStatus": "A", "resultMessage": "accept" }, "paymentId": "2023120611121280010016600900000xxxx", "redirectActionForm": { "redirectionUrl": "https://www.wallet.com/cashier?orderId=xxxxxxx" } } ``` #### Alternative Flows - **Early Cancellation**: Merchant can call `cancelPayment` if they cannot fulfill before accepting - **Void After Acceptance**: Merchant can call `voidPayment` if fulfillment cannot be completed after acceptance - **Fulfillment Issues**: Merchant can call `voidPayment` if goods cannot be delivered - **Post-Completion Refund**: After completion, merchant can issue `refund` if needed ### Response | Field | Type | Required | Description | | ----------------------------------- | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | The request result, which contains information related to the request result, such as status and error codes. | | `result.resultCode` | `string` | Yes | Result code (e.g., `"SUCCESS"`, `"ACCEPT"`, `"UNKNOWN_EXCEPTION"`). | | `result.resultStatus` | `string` | Yes | Result status: `S` (Success), `A` (Accepted), `U` (Unknown), `F` (Failed). | | `result.resultMessage` | `string` | Yes | Result message description. | | `paymentId` | `string` | No | The unique ID of a payment generated by Wallet. Max. length: 64 characters. Present when payment is accepted or successful. | | `paymentTime` | `string/datetime` | No | Payment success time, which follows the ISO 8601 standard. Present when `resultStatus` is `S`. | | `redirectActionForm` | `object` | No | Indicates a redirect URL for cashier payment. Present when `resultStatus` is `A`. | | `redirectActionForm.redirectionUrl` | `string` | No | The wallet cashier page URL. | ### Result Processing Logic In the response, the `result.resultStatus` field indicates the result of processing a request as follows: | resultStatus | Description | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `S` | **Success** – The corresponding `result.resultCode` is `"SUCCESS"` and the `result.resultMessage` is `"Success."`. That means that this transaction is successful. The merchant/partner can update transaction to success. | | `A` | **Accepted** – The corresponding `result.resultCode` is `"ACCEPT"`, and the `result.resultMessage` varies based on different situations. That means that the transaction is already accepted by wallets. The merchant/partner needs to continue the next operation according to the `redirectActionForm` response, such as display the order code to users or redirect to the wallet cashier page. | | `U` | **Unknown** – The corresponding `result.resultCode` is `"UNKNOWN_EXCEPTION"` and `result.resultMessage` is `"An API calling is failed, which is caused by unknown reasons."`. For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. :br:br That means that unknown exception occurs on the wallet side. The merchant/partner can inquiry the payment result or wait for the payment status notification to get the real payment result. What needs to do is: :br • Payment evaluation scenario can not be inquired. :br • `U` status can not set to fail or success on the merchant/partner system. :br • `U` status can not refund to users by offline (Maybe will make fund loss). | | `F` | **Failed** – That means this transaction is failed. The corresponding `result.resultCode` and `result.resultMessage` vary based on different situations. For details, see the following Error codes section. :br:br Usually the `F` transactions can not be successful again if use the same payment request to call wallets. | #### Result Status Reference | resultStatus | Meaning | Merchant Action | | ------------ | ------------------------------------------------- | ---------------------------------------------------------------------------- | | `S` | Payment succeeded. | Mark order as paid; expect notification at `paymentNotifyUrl`. | | `A` | Accepted; further action required (cashier flow). | Redirect user using `redirectActionForm`. | | `U` | Unknown exception. | Retry later or wait for notifications; do not duplicate charges immediately. | | `F` | Failed. | Inspect `resultCode` and decide whether to retry or alert the user. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)**: are common for all Mini Program OpenAPIs. - **API-specific error codes**: are listed in the following table. | resultStatus | resultCode | resultMessage | | ------------ | ----------------------------- | --------------------------------------------------- | | `U` | `PAYMENT_IN_PROCESS` | The payment is still under process. | | `F` | `REPEAT_REQ_INCONSISTENT` | Repeated submission, and requests are inconsistent. | | `F` | `PAYMENT_AMOUNT_EXCEED_LIMIT` | Payment amount exceeds limit. | | `F` | `USER_NOT_EXIST` | The user does not exist. | | `F` | `USER_STATUS_ABNORMAL` | The user status is abnormal. | | `F` | `USER_BALANCE_NOT_ENOUGH` | The user balance is not enough for this payment. | | `F` | `PARTNER_NOT_EXIST` | The partner does not exist. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | | `F` | `RISK_REJECT` | Risk reject. | | `F` | `CURRENCY_NOT_SUPPORT` | The currency is not supported. | | `F` | `ORDER_STATUS_INVALID` | Order is in invalid status such closed. | | `F` | `INVALID_ACCESS_TOKEN` | Invalid accesstoken. | | `F` | `USER_AMOUNT_EXCEED_LIMIT` | Payment amount exceeds user's amount limit. | | `F` | `AUTH_CODE_ALREADY_USED` | Auth code already used. | | `F` | `INVALID_CODE` | Auth code illegal. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [tradePay](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [qicardSignContract](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/qicard-sign-contract) - [merchantAccept](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) (Escrow) - [confirmOrder](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/confirm-order) (Escrow) - [cancelPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) (Escrow) - [voidPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) (Escrow) # refund ## Overview `POST /v1/payments/refund` deducts funds from the merchant and returns them to the user for a successful payment. Partial or full refunds are supported, and multiple refund requests can be made against a single payment as long as the cumulative amount does not exceed the original payment value. All monetary amounts must be provided in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning - Submit refunds after confirming the underlying payment reached a final success state. - Poll `/v1/payments/inquiryRefund` if the refund status remains `REFUND_IN_PROCESS` after submission. - **For escrow payments:** Use [`cancelPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) before merchant accepts, or [`voidPayment`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) after acceptance. Use `refund` only after order completion or void. :: ![Refund flow](https://superqi-dev-docs.pages.dev/api-reference/refund.png) 1. Mini Program obtains authorization via `my.getAuthCode`. 2. Wallet app service validates the authorization with the wallet backend. 3. Wallet backend issues an `authCode`. 4. Wallet app service returns the `authCode` to the Mini Program. 5. Mini Program forwards the `authCode` to the merchant backend. 6. Merchant backend exchanges the `authCode` for tokens using [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). 7. Wallet backend returns token information (`accessToken`, `refreshToken`, `customerId`) to the merchant backend. 8. Mini Program creates the original payment order with `customerId`. 9. Merchant backend initiates payment via `/v1/payments/pay`. 10. Wallet backend responds with cashier details (including `redirectionUrl`). 11. Merchant backend sends payment details to the Mini Program. 12. Mini Program calls `my.tradePay` to launch the cashier. 13. Wallet app service displays the cashier UI with order info. 14. Wallet app service shows the order page to the user. 15. User confirms the payment. 16. Wallet app service executes the payment. 17. Wallet backend processes the payment and returns the result to the wallet app service. 18. Mini Program receives the payment result. 19. Wallet backend notifies the merchant backend via `paymentNotifyUrl`. 20. Wallet backend notifies the user via SMS/email/inbox. 21. User or merchant initiates a full or partial refund request. 22. Mini Program submits the refund request to the merchant backend. 23. Merchant backend calls `/v1/payments/refund`. 24. Wallet backend returns the refund result to the merchant backend. 25. Wallet backend returns the refund result to the Mini Program. 26. Mini Program displays the refund status to the user. 27. If refund status is `REFUND_IN_PROCESS`, merchant backend polls `/v1/payments/inquiryRefund`. 28. Wallet backend responds with the latest refund inquiry result. ## Endpoint | Method | Path | | ------ | --------------------- | | `POST` | `/v1/payments/refund` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------------ | -------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | | `refundRequestId` | `string` | Yes | Merchant-generated refund ID (max 64 characters). Used for idempotence—repeat submissions with the same ID yield the same final result. | `"202311271907410100070000008881xxxx"` | | `paymentId` | `string` | Conditional | Wallet payment ID associated with the refund. Provide either `paymentId`, `paymentRequestId`, or `captureId`. | `"202312061112128001001660090000xxxx"` | | `paymentRequestId` | `string` | Conditional | Merchant payment ID associated with the refund. | `"20230101234567890133333xxxx"` | | `captureId` | `string` | Conditional | Wallet capture ID (used in capture flows). | `"202311271907410100070000007777xxxx"` | | `refundAmount` | `object` | Yes | Refund amount object. `value` must not exceed the remaining refundable amount. | `{ "currency": "IQD", "value": "100000" }` | | `refundReason` | `string` | No | Description of why the refund is issued (max 256 characters). | `"Returned goods to merchant"` | | `extendInfo` | `string` | No | Additional metadata in JSON format (max 2048 characters). | `"extendInfo": "additional information"` | ```json { "refundRequestId": "202311271907410100070000008881xxxx", "paymentId": "202312061112128001001660090000xxxx", "refundAmount": { "currency": "IQD", "value": "100000" }, "refundReason": "Customer requested cancellation." } ``` > At least one of `paymentId`, `paymentRequestId`, or `captureId` must be provided. If multiple are supplied, the wallet prioritizes `paymentId`, then `paymentRequestId`, then `captureId`. ### Response | Field | Type | Required | Description | Example | | ------------ | -------- | ----------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata including `resultCode`, `resultStatus`, and `resultMessage`. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }` | | `refundId` | `string` | Conditional | Wallet-generated refund ID. Present when `resultStatus` is `S`. | `"202312061112128013001660090000xxxx"` | | `refundTime` | `string` | Conditional | ISO 8601 timestamp indicating when funds were deducted from the merchant (returned when `resultStatus` is `S`). | `"2023-11-27T12:01:01+08:30"` | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "refundId": "202312061112128013001660090000xxxx", "refundTime": "2023-11-27T12:01:01+08:30" } ``` ### Result Processing Logic | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Refund succeeded—funds deducted from merchant; await user settlement. | | `U` | Refund request encountered an unknown exception. Do not retry immediately; use `/v1/payments/inquiryRefund` to check status. | | `F` | Refund failed. Review `resultCode` and `resultMessage`; see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). Common reasons include exceeding refund window or amount. | ## Error Codes | resultStatus | resultCode | resultMessage | Recommended Action | | ------------ | ---------------------------- | ----------------------------------------- | ------------------------------------------------------- | | `U` | `REFUND_IN_PROCESS` | Refund is under processing. | Poll `/v1/payments/inquiryRefund`. | | `F` | `MULTI_REFUND_NOT_ALLOWED` | Multiple refund not allowed in agreement. | Verify agreement rules; issue a single refund. | | `F` | `REFUND_NOT_ALLOWED` | Refund not allowed in agreement. | Check agreement configuration. | | `F` | `REPEAT_REQ_INCONSISTENT` | Data inconsistent with prior request. | Ensure idempotent parameters match original submission. | | `F` | `PARTNER_STATUS_ABNORMAL` | Merchant status abnormal. | Resolve merchant account issues before retrying. | | `F` | `ORDER_NOT_EXIST` | The order does not exist. | Confirm payment identifiers. | | `F` | `ORDER_STATUS_INVALID` | Order has invalid status (e.g., closed). | Verify payment lifecycle. | | `F` | `REFUND_WINDOW_EXCEED` | Exceeded allowable refund window. | Decline refund or seek manual intervention. | | `F` | `REFUND_AMOUNT_EXCEED` | Requested refund exceeds payment amount. | Adjust to remaining refundable amount. | | `F` | `PARTNER_BALANCE_NOT_ENOUGH` | Merchant balance insufficient. | Top up merchant account before retrying. | | `F` | `CURRENCY_NOT_SUPPORT` | Currency not supported. | Use supported currency (e.g., IQD). | | `F` | `USER_NOT_EXIST` | User identifier invalid. | Verify user account. | | `F` | `USER_STATUS_ABNORMAL` | User account status abnormal. | Resolve user status before retrying. | ## Related Links - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) - [inquiryRefund](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-refund) - [inquiryPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [cancelPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) (Escrow - before acceptance) - [voidPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) (Escrow - after acceptance) # merchantAccept ## Overview `POST /v1/payments/merchantAccept` is used in escrow payment scenarios. After the mini-app merchant reviews the customer's order and verifies that the items are in stock and everything is fine (conditions are satisfied, etc.), the merchant may call this OpenAPI to accept the order. All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning - Only payments with escrow product code (`51051000101000100008`) can use this API. - The payment must be successfully completed before the merchant can accept. - Once accepted, the merchant is committed to fulfilling the order. :: ![Merchant Accept flow](https://superqi-dev-docs.pages.dev/api-reference/merchantAccept.png) 1. The Mini Program calls this `my.getAuthCode` JSAPI with specific `scopes`(USER\_ID) to request an authorization code. 2. The E-wallet App service calls authorization service to processes the authorization information. 3. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 4. The E-wallet App service returns the `authCode` to the Mini Program. 5. The Mini Program sends the `authCode` to the merchant backend. 6. The merchant backend calls the applyToken API with `authCode` to apply the `accessToken`. 7. The E-Wallet backend returns `accessToken` information to the merchant backend, such as `customerId`, accessToken, refreshToken, etc. 8. The merchant backend returns customerId to mini program. 9. The Mini Program creates an order with `customerId`. 10. The merchant backend calls the payment API to initiate payment flow, including `customerId` as referenceBuyerId, paymentNotifyUrl(optional), etc. 11. The E-Wallet backend returns payment detail information the merchant backend, such as `redirectionUrl`. 12. The merchant backend passes the payment detail information to the Mini Program. 13. The Mini Program calls the `my.tradePay` JSAPI with `redirectionUrl` to conduct the payment. 14. The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc. 15. The user confirms the payment in the cashier page. 16. The E-Wallet App Service calls payment service and execute the payment process. 17. When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 19). 18. The E-Wallet App Service returns the payment result to mini program. 19. Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 10. 20. Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message. 21. Merchant backend calls the `merchantAccept` API to accept this order. 22. The E-Wallet backend returns the merchantAccept result to the merchant backend. ## Endpoint | Method | Path | | ------ | ----------------------------- | | `POST` | `/v1/payments/merchantAccept` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ----------- | -------- | -------- | ----------------------------------------------------------------------------------------------- | ------------------------- | | `paymentId` | `string` | Yes | The unique ID that is assigned by the wallet to identify a payment. Max. length: 64 characters. | `"202312061112128001016"` | #### Sample Request ```json { "paymentId": "2024071911121280010016601720002644" } ``` ### Response | Field | Type | Required | Description | Example | | -------- | -------- | -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `result` | `object` | Yes | The request result, which contains information such as result status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }` | #### Sample Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." } } ``` ## Result Process Logic In the response, the `result.resultStatus` field indicates the result of processing a request. The following table describes each result status: | resultStatus | Description | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | It means that the merchant accept is successful. The corresponding `result.resultCode` is `"SUCCESS"`, and the `result.resultMessage` is `"Success."`. | | `U` | It means that the status of the merchant accept result is unknown. The corresponding `result.resultCode` is `UNKNOWN_EXCEPTION`, and `result.resultMessage` is `"An API calling is failed, which is caused by unknown reasons"`. For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. | | `F` | It means that the merchant accept fails. The corresponding `result.resultCode` and `result.resultMessage` may vary based on different situations. For details, see the Error codes section. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)** are common across all mini program's APIs. - **API-specific error codes** are listed in the following table. | resultStatus | resultCode | resultMessage | | ------------ | ----------------------------- | ------------------------------------------------------------------ | | `F` | `ORDER_UNSUPPORTED_OPERATION` | The order not supported the operation. | | `F` | `ORDER_STATUS_INVALID` | The order status is invalid. | | `F` | `ORDER_NOT_EXIST` | The order does not exist. | | `F` | `ORDER_IS_FROZEN` | The order is frozen. | | `F` | `ORDER_IS_MERCHANT_ACCEPTED` | The order has been accepted by merchant. | | `F` | `CURRENCY_NOT_SUPPORT` | The currency of a user's payment is not supported by the merchant. | | `F` | `USER_NOT_EXIST` | The user does not exist. | | `F` | `USER_STATUS_ABNORMAL` | The user status is abnormal. | | `F` | `PARTNER_NOT_EXIST` | The partner does not exist. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | ## Related Links - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) (Use product code `51051000101000100008` for escrow) - [confirm](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/confirm-order) - [cancel](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) - [void](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) # confirm ## Overview `POST /v1/payments/confirm` is used to capture the total authorized payment amount from a user's account, and then transfer the total amount of the payment to a merchant's account after the user confirms receipt. The confirm can only be initiated once and in full. **Note:** The merchant may call the confirm API to notify A+ that the order has been confirmed only after the customer has actually completed the order confirmation. All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning - Only payments with escrow product code (`51051000101000100008`) can use this API. - The merchant must have already accepted the payment using [`merchantAccept`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) before the customer can confirm. - Once confirmed, funds are immediately released to the merchant and cannot be reversed. - Customers should only confirm after verifying the goods are satisfactory. :: ![Confirm flow](https://superqi-dev-docs.pages.dev/api-reference/confirm.png) 1. The Mini Program calls this `my.getAuthCode` JSAPI with specific `scopes`(USER\_ID) to request an authorization code. 2. The E-wallet App service calls authorization service to processes the authorization information. 3. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 4. The E-wallet App service returns the `authCode` to the Mini Program. 5. The Mini Program sends the `authCode` to the merchant backend. 6. The merchant backend calls the applyToken API with `authCode` to apply the `accessToken`. 7. The E-Wallet backend returns `accessToken` information to the merchant backend, such as `customerId`, accessToken, refreshToken, etc. 8. The merchant backend returns customerId to mini program. 9. The Mini Program creates an order with `customerId`. 10. The merchant backend calls the payment API to initiate payment flow, including `customerId` as referenceBuyerId, paymentNotifyUrl(optional), etc. 11. The E-Wallet backend returns payment detail information the merchant backend, such as `redirectionUrl`. 12. The merchant backend passes the payment detail information to the Mini Program. 13. The Mini Program calls the `my.tradePay` JSAPI with `redirectionUrl` to conduct the payment. 14. The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc. 15. The user confirms the payment in the cashier page. 16. The E-Wallet App Service calls payment service and execute the payment process. 17. When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 19). 18. The E-Wallet App Service returns the payment result to mini program. 19. Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 10. 20. Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message. 21. Merchant backend calls the `merchantAccept` API to accept this order. 22. The E-Wallet backend returns the merchantAccept result to the merchant backend. 23. The Mini Program sends the confirm request to merchant backend, and the merchant backend calls the `confirm` API to capture the money(Step 25). 24. (This step is internal - see step 25) 25. Send confirm request via `/v1/payments/confirm`. 26. The E-Wallet backend returns the confirm result to the merchant backend. 27. The merchant backend returns confirm result. 28. And the Mini Program displays the confirm result to the user(Step 28). **Alternative flow:** When the E-Wallet backend returns the resultCode as `CONFIRM_IN_PROCESS`, the merchant can call `inquiryPayment` API to query confirm result (Step 29). ## Endpoint | Method | Path | | ------ | ---------------------- | | `POST` | `/v1/payments/confirm` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------------ | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | | `paymentId` | `string` | Yes | The unique ID that is assigned by the wallet to identify a payment. Max. length: 64 characters. | `"202312061112128001016"` | | `confirmRequestId` | `string` | Yes | The unique ID is assigned by a merchant to identify a confirm request. Max. length: 64 characters. | `"1022188000000000001xxxx"` | | `extendInfo` | `string` | No | The extension information that wallets and merchants want to describe. The format should be JSON format. Max. length: 2048 characters. | - | #### Sample Request ```json { "paymentId": "202312061112128001001660090000xxxx", "confirmRequestId": "1022188000000000001xxxx" } ``` > The `confirmRequestId` is used for idempotence—repeat submissions with the same ID will yield the same final result. ### Response | Field | Type | Required | Description | Example | | ------------- | -------- | -------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `result` | `object` | Yes | The request result, which contains information such as result status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }` | | `confirmId` | `string` | No | The unique ID for a confirm request generated by the wallet. Max. length: 64 characters. | `"202312061112128001016x"` | | `confirmTime` | `string` | No | The processing time for a confirm request. The format of the value follows the ISO 8601 standard. | `"2025-07-08T12:12:12+08:00"` | #### Sample Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "confirmId": "202312061112128001016x", "confirmTime": "2025-07-08T12:12:12+08:00" } ``` ## Result Process Logic In the response, the `result.resultStatus` field indicates the result of processing a request. The following table describes each result status: | resultStatus | Description | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `S` | It means that the confirm is successful. The corresponding `result.resultCode` is `"SUCCESS"`, and the `result.resultMessage` is `"Success."`. | | `U` | It means that the status of the confirm result is unknown. The corresponding `result.resultCode` is `UNKNOWN_EXCEPTION`, and `result.resultMessage` is `"An API calling is failed, which is caused by unknown reasons"`. For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. | | `F` | It means that the confirm fails. The corresponding `result.resultCode` and `result.resultMessage` may vary based on different situations. For details, see the Error codes section. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)** are common across all mini program's APIs. - **API-specific error codes** are listed in the following table. | resultStatus | resultCode | resultMessage | | ------------ | ------------------------------- | ------------------------------------------------------------------ | | `F` | `ORDER_UNSUPPORTED_OPERATION` | The order is not support capture. | | `F` | `ORDER_STATUS_INVALID` | The order status is invalid. | | `F` | `ORDER_NOT_EXIST` | The order does not exist. | | `U` | `CONFIRM_IN_PROCESS` | The confirm is processing. | | `F` | `CURRENCY_NOT_SUPPORT` | The currency of a user's payment is not supported by the merchant. | | `F` | `USER_NOT_EXIST` | The user does not exist. | | `F` | `USER_STATUS_ABNORMAL` | The user status is abnormal. | | `F` | `REPEAT_REQ_INCONSISTENT` | The submitted request is not consistent with the repeated one. | | `F` | `MUTEX_OPERATION_IN_PROCESSING` | There is another payment void, confirm, or capture in processing. | | `F` | `PARTNER_NOT_EXIST` | The partner does not exist. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | ## Related Links - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) (Use product code `51051000101000100008` for escrow) - [merchantAccept](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) - [void](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) - [inquiryPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) # cancel ## Overview `POST /v1/payments/cancel` is used to cancel a payment when the payment result has not been returned for an extended period, or when the merchant, after reviewing the customer's order, decides not to accept it. Upon successful invocation of the `cancel` API, the full amount paid by the customer will be returned. To cancel a payment, you need to provide one of the following parameters: - `paymentId`: The original payment ID of the payment request to be canceled. It is generated by Alipay when a merchant initiates the original payment. - `paymentRequestId`: The original `paymentRequestId` of the payment request to be canceled. All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning **Note:** After merchant initiated capture, void, refund for a payment, it is not allowed to initiate a cancel. :: ![Cancel flow](https://superqi-dev-docs.pages.dev/api-reference/cancel.png) 1. The Mini Program calls this `my.getAuthCode` JSAPI with `scopes`=USER\_ID. 2. The E-wallet App service calls authorization service to processes the authorization information. 3. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 4. The E-wallet App service returns the `authCode` to the Mini Program. 5. The Mini Program sends the `authCode` to the merchant backend. 6. The merchant backend calls the applyToken API with `authCode` to apply the `accessToken`. 7. The E-Wallet backend returns `accessToken` information to the merchant backend, such as `customerId`, accessToken, refreshToken, etc. 8. The merchant backend returns customerId to mini program. 9. The Mini Program creates an order with `customerId`. 10. The merchant backend calls the payment API to initiate payment flow, including `customerId` as referenceBuyerId, paymentNotifyUrl(optional), etc. 11. The E-Wallet backend returns payment detail information the merchant backend, such as `redirectionUrl`. 12. The merchant backend passes the payment detail information to the Mini Program. 13. The Mini Program calls the `my.tradePay` JSAPI with `redirectionUrl` to conduct the payment. 14. The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc. 15. The user confirms the payment in the cashier page. 16. The E-Wallet App Service calls payment service and execute the payment process. 17. When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 19). 18. The E-Wallet App Service returns the payment result to mini program. 19. Send cancel request within T day via `/v1/payments/cancel`. 20. The E-Wallet backend returns cancel result to the merchant backend. ## Endpoint | Method | Path | | ------ | --------------------- | | `POST` | `/v1/payments/cancel` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------------ | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `paymentId` | `string` | No | The unique ID that is assigned by the wallet to identify a payment. Max. length: 64 characters. | `"202312061112128001001660x"` | | `paymentRequestId` | `string` | No | The unique ID is assigned by a merchant to identify a payment request. Max. length: 64 characters. | `"20231127190741010007000x"` | | `extendInfo` | `string` | No | The extension information that wallets and merchants want to describe. The format should be JSON format. Max. length: 2048 characters. | `"extendInfo: This is additional information"` | ::callout{type="info"} At least one of `paymentId` or `paymentRequestId` must be provided. :: #### Sample Request ```json { "paymentId": "202312061112128001001660090000xxxx" } ``` ### Response | Field | Type | Required | Description | Example | | ------------------ | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `result` | `object` | Yes | The request result, which contains information such as result status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }` | | `paymentId` | `string` | No | The unique ID is assigned by the wallet to identify a payment. Max. length: 64 characters. | `"202312061112128001001660x"` | | `paymentRequestId` | `string` | No | The unique ID is assigned by a merchant to identify a payment request. Max. length: 64 characters. | `"20231127190741010007000x"` | | `cancelTime` | `datetime` | No | The actual time when the payment cancellation process is completed. This property is returned only when the cancellation succeeds. The value follows the ISO 8601 standard. | `"2023-01-08T12:12:12+08:00"` | #### Sample Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "paymentId": "202312061112128001001660090000xxxx", "paymentRequestId": "20231127190741010007000070000xxxx", "cancelTime": "2023-01-08T12:12:12+08:00" } ``` ## Result Process Logic In the response, the `result.resultStatus` field indicates the result of processing a request. The following table describes each result status: | resultStatus | Description | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | It means that the cancellation is successful. The corresponding `result.resultCode` is `"SUCCESS"`, and the `result.resultMessage` is `"Success."`. | | `U` | It means that the status of the cancellation result is unknown. The corresponding `result.resultCode` is `UNKNOWN_EXCEPTION`, and `result.resultMessage` is `"An API calling is failed, which is caused by unknown reasons"`. For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. | | `F` | It means that the cancellation fails. The corresponding `result.resultCode` and `result.resultMessage` may vary based on different situations. For details, see the Error codes section. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)** are common across all mini program's APIs. - **API-specific error codes** are listed in the following table. | resultStatus | resultCode | resultMessage | | ------------ | ---------------------------- | -------------------------------------------------------------------------------- | | `F` | `ORDER_STATUS_INVALID` | The order is in invalid status such as CLOSED. | | `F` | `ORDER_HAS_BEEN_CAPTURED` | The cancellation does not support when the order has been captured. | | `F` | `ORDER_HAS_BEEN_REFUNDED` | The cancellation does not support when the order has been refunded. | | `F` | `ORDER_HAS_BEEN_VOIDED` | The cancellation does not support when the order has been voided. | | `F` | `CANCEL_NOT_ALLOWED` | The cancellation not allowed in agreement. | | `F` | `CANCEL_WINDOW_EXCEED` | The cancellation date is beyond the period that is agreed in the contract. | | `F` | `ORDER_NOT_EXIST` | The order does not exist. | | `F` | `KEY_NOT_FOUND` | The key is not found. | | `F` | `CLIENT_INVALID` | The client is invalid. | | `F` | `INVALID_SIGNATURE` | The signature is invalid. | | `F` | `METHOD_NOT_SUPPORTED` | The server does not implement the requested HTTP method. | | `F` | `MEDIA_TYPE_NOT_ACCEPTABLE` | The server does not implement the media type that can be accepted by the client. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | | `F` | `PARTNER_BALANCE_NOT_ENOUGH` | The partner balance is not enough. | ## Samples The merchant can call this `cancel` API to cancel the payment transaction within T day under these circumstances and E-Wallet will not settle payment this transaction in T+N day either. - when the merchant decides to provide a full refund before settlement. - when the payment result does not return for a long time. - when the merchant cannot fulfill the order before accepting it. For refunds after the money has been settled to the merchant, the merchant backend should call `refund` API instead. ## Related Links - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) (Use product code `51051000101000100008` for escrow) - [merchantAccept](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) - [void](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/void-payment) - [refund](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/refund) # void ## Overview `POST /v1/payments/void` is used to void a paid order before the payment is captured, and then return money to the payer. There are the following two types of voiding a paid order: - **Partially void:** To partially void a paid order will return a part of the payment amount to the payer. It will not change the order status. There is a timeout setting for the remaining payment amount. Once the time is out of the setting, the remaining payment amount will be voided or confirmed automatically. - **Fully void:** To fully void an order will close the order automatically. The timeout setting is available when the remaining payment amount is voided or confirmed automatically if the session timeout is set. All monetary amounts in requests and responses must be expressed in the smallest currency unit (IQD fils). For example, 100 IQD equals `100000`. ::warning - Only payments with escrow product code (`51051000101000100008`) can use this API. - This API is used after the merchant has accepted the payment. - For payments not yet accepted by the merchant, use [`cancel`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) instead. :: ![Void flow](https://superqi-dev-docs.pages.dev/api-reference/void.png) 1. The Mini Program calls this `my.getAuthCode` JSAPI with specific `scopes`(USER\_ID) to request an authorization code. 2. The E-wallet App service calls authorization service to processes the authorization information. 3. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 4. The E-wallet App service returns the `authCode` to the Mini Program. 5. The Mini Program sends the `authCode` to the merchant backend. 6. The merchant backend calls the applyToken API with `authCode` to apply the `accessToken`. 7. The E-Wallet backend returns `accessToken` information to the merchant backend, such as `customerId`, accessToken, refreshToken, etc. 8. The merchant backend returns customerId to mini program. 9. The Mini Program creates an order with `customerId`. 10. The merchant backend calls the payment API to initiate payment flow, including `customerId` as referenceBuyerId, paymentNotifyUrl(optional), etc. 11. The E-Wallet backend returns payment detail information the merchant backend, such as `redirectionUrl`. 12. The merchant backend passes the payment detail information to the Mini Program. 13. The Mini Program calls the `my.tradePay` JSAPI with `redirectionUrl` to conduct the payment. 14. The E-Wallet App Service displays the cashier page with order information, such as amount, order details, etc. 15. The user confirms the payment in the cashier page. 16. The E-Wallet App Service calls payment service and execute the payment process. 17. When the payment reaches the final status, the E-wallet backend returns the payment result to the Mini Program (Step 18). 18. The E-Wallet App Service returns the payment result to mini program. 19. Also the E-wallet backend notifies the merchant backend of the payment result with paymentNotifyUrl provided in Step 10(Step 19). 20. Finally, E-wallet backend notifies the user of the payment result via SMS/Email/Inbox message (Step 20). 21. If the merchant cannot fulfill the order or needs to void the transaction, the merchant initiates the void process (Step 21). 22. The merchant backend calls the `void` API to return the money to the customer (Step 23). 23. Send void request via `/v1/payments/void`. 24. The E-Wallet backend returns the void result to the merchant backend. 25. The merchant backend returns void result. 26. And the Mini Program displays the void result to the user(Step 26). **Alternative flow:** When the E-Wallet backend returns the resultCode as `VOID_IN_PROCESS`, the merchant can call `inquiryPayment` API to query void result (Step 27). ## Endpoint | Method | Path | | ------ | ------------------- | | `POST` | `/v1/payments/void` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | --------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `voidRequestId` | `string` | Yes | The unique ID of a void request generated by a merchant. Max. length: 64 characters. | `"2023010123456789013"` | | `paymentId` | `string` | Yes | The payment ID of the original authorization to be voided. Max. length: 64 characters. | `"202312061112128001016xx"` | | `voidAmount` | `object` | No | The void payment amount. The voidAmount is **mandatory** in partial void scenario. The voidAmount is **optional** in full void scenario. | `{ "value":"40000", "currency":"IQD" }` | | `extendInfo` | `string` | No | The extension information that wallets and merchants want to describe. The format should be JSON format. Max. length: 2048 characters. | `"extendInfo: This is additional information"` | #### Sample Request ```json { "voidRequestId": "2023010123456789013", "paymentId": "202312061112128001016xx", "voidAmount": { "value": "40000", "currency": "IQD" } } ``` > The `voidRequestId` is used for idempotence—repeat submissions with the same ID will yield the same final result. ### Response | Field | Type | Required | Description | Example | | --------------- | -------- | -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `result` | `object` | Yes | The request result, which contains information such as result status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }` | | `voidRequestId` | `string` | No | The unique ID of a void request generated by a merchant. Max. length: 64 characters. | `"2023010123456789013"` | | `voidId` | `string` | No | The unique ID of a void request generated by the wallet. Max. length: 64 characters. | `"202312061112128017xxx"` | #### Sample Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success." }, "voidRequestId": "2023010123456789013", "voidId": "202312061112128017xxx" } ``` ## Result Process Logic In the response, the `result.resultStatus` field indicates the result of processing a request. The following table describes each result status: | resultStatus | Description | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | It means that the void is successful. The corresponding `result.resultCode` is `"SUCCESS"`, and the `result.resultMessage` is `"Success."`. | | `U` | It means that the status of the void is unknown. The corresponding `result.resultCode` is `UNKNOWN_EXCEPTION`, and `result.resultMessage` is `"An API calling is failed, which is caused by unknown reasons"`. For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. :br:br What needs to note is as follow: :br • U status (inquiry/retry still gets U) can not set to fail or success on merchant/partner system. :br:br If other response (almost never occur), the merchant/partner should process like U. | | `F` | It means that the void fails. The corresponding `result.resultCode` and `result.resultMessage` may vary based on different situations. For details, see the Error codes section. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)** are common across all mini program's APIs. - **API-specific error codes** are listed in the following table. | resultStatus | resultCode | resultMessage | | ------------ | -------------------------------- | ---------------------------------------------------------------------------------- | | `F` | `ORDER_NOT_EXISTS` | The order does not exist. | | `F` | `ORDER_STATUS_INVALID` | The order status is invalid. | | `U` | `VOID_IN_PROCESS` | The void is still under process. | | `F` | `CURRENCY_NOT_SAME` | The currency of a user's payment is not the same as the original payment currency. | | `F` | `VOID_AMOUNT_EXCEEDS_AUTH_LIMIT` | The total void amount exceeds the limit of the authorized payment amount. | | `F` | `MUTEX_OPERATION_IN_PROCESSING` | There is another payment void, confirm, or capture in processing. | | `F` | `ORDER_UNSUPPORTED_OPERATION` | The order is not support void. | | `F` | `REPEAT_REQ_INCONSISTENT` | Repeated submit, and requests are inconsistent. | | `F` | `PARTNER_NOT_EXIST` | The partner does not exist. | | `F` | `USER_NOT_EXISTS` | The user does not exist. | | `F` | `USER_STATUS_ABNORMAL` | The user status is abnormal. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | ## Related Links - [pay](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) (Use product code `51051000101000100008` for escrow) - [merchantAccept](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/merchant-accept) - [cancel](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/cancel-payment) - [refund](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/refund) - [inquiryPayment](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/inquiry-payment) # inquiryUserInfo ## Overview `POST /v1/users/inquiryUserInfo` returns user attributes based on scopes granted through `my.getAuthCode`. Pass the `accessToken` issued by [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token); the response includes profile details such as login identifiers, name, avatar, and contact info when authorized. ![Inquiry user flow](https://superqi-dev-docs.pages.dev/api-reference/inquiry-user-info.png) 1. Mini Program calls `my.getAuthCode` with the desired scopes to request authorization. 2. Wallet app renders the authorization page to the user. 3. User reviews and approves the authorization in the super app. 4. Wallet app service submits the authorization result to the wallet backend. 5. Wallet backend validates the authorization and generates an `authCode`. 6. Wallet app service returns the `authCode` to the Mini Program. 7. Mini Program forwards the `authCode` to the merchant backend. 8. Merchant backend invokes `/v1/authorizations/applyToken` with the `authCode` to obtain tokens. 9. Wallet backend returns `accessToken` (and refresh token) to the merchant backend. 10. Merchant backend calls `/v1/users/inquiryUserInfo` with the `accessToken`. 11. Wallet backend responds with user information corresponding to the granted scopes. ## Endpoint | Method | Path | | ------ | --------------------------- | | `POST` | `/v1/users/inquiryUserInfo` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `accessToken` | `string` | Yes | Access token for querying user info (max 128 characters; disallow `@`, `#`, `?`). Obtain via `applyToken`. | `"281010033AB2F588D14B43238637264FCA5AAF35xxxx"` | | `extendInfo` | `string` | No | Optional metadata (max 4096 characters; no `@`, `#`, `?`). | `{ "memo": "memo" }` | ```json { "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response | Field | Type | Required | Description | | ---------- | -------- | -------- | --------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata containing status and error codes. | | `userInfo` | `object` | No | User attributes allowed by the authorized scopes. Returned when `result.resultStatus` is `S`. | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }, "userInfo": { "userId": "1000001119398804", "loginIdInfos": [ { "loginIdType": "MOBILE_PHONE", "maskLoginId": "964*******01" } ], "userName": { "fullName": "Jack Second Third Sparrow", "firstName": "Jack", "secondName": "Second", "thirdName": "Third", "lastName": "Sparrow" }, "avatar": "https://example.com/avatar.png", "gender": "M", "birthDate": "2020-07-25", "nationality": "IRQ", "contactInfos": [ { "contactType": "MOBILE_PHONE", "contactNo": "964*******01" } ], "extendInfo": {} } } ``` ### Result Processing Logic | Status | Description | | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Inquiry succeeded. Use `userInfo` data per the authorized scopes. | | `U` | Result unknown (`resultCode`: `UNKNOWN_EXCEPTION`). Retry or review [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes). | | `F` | Inquiry failed. Inspect `resultCode` and see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | Error Code | Result Status | Message | Next Step | | ---------------------- | ------------- | --------------------- | --------------------------------------------------------------------------------------- | | `INVALID_ACCESS_TOKEN` | `F` | Access token invalid. | Obtain a new authorization code via `my.getAuthCode`, then exchange using `applyToken`. | | `EXPIRED_ACCESS_TOKEN` | `F` | Access token expired. | Refresh using `applyToken` with the `refreshToken`. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # inquiryUserCardList ## Overview `POST /v1/users/inquiryUserCardList` returns user bank card list based on scopes granted through `my.getAuthCode`. Pass the `accessToken` issued by [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token); the response includes the list of bank cards associated with the user when authorized. ::warning{icon="i-lucide-info"} To access user card information, you must request the `CARD_LIST` scope when calling `my.getAuthCode` to obtain the authorization code. :: ## Endpoint | Method | Path | | ------ | ------------------------------- | | `POST` | `/v1/users/inquiryUserCardList` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `accessToken` | `string` | Yes | Access token for querying user bank card list (max 128 characters; disallow `@`, `#`, `?`). Obtain via `applyToken`. | `"281010033AB2F588D14B43238637264FCA5AAF35xxxx"` | ```json { "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response | Field | Type | Required | Description | | ---------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata containing status and error codes. | | `cardList` | `array` | No | User bank card list queried by the merchant. Must be returned when `result.resultStatus` is `S`. Returns empty array `[]` when user has not bound any bank card. | #### CardInfo | Property | Type | Required | Description | | --------------- | -------- | -------- | --------------------------------------- | | `accountNumber` | `string` | Yes | Account number (max 32 characters). | | `maskedCardNo` | `string` | Yes | Masked card number (max 32 characters). | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success" }, "cardList": [ { "maskedCardNo": "123*****789", "accountNumber": "123456789" }, { "maskedCardNo": "987*****321", "accountNumber": "987654321" } ] } ``` ### Result Processing Logic | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `S` | Inquiry succeeded. Use `accessToken` to access user information within the corresponding scope. | | `U` | Result unknown (`resultCode`: `UNKNOWN_EXCEPTION`, `resultMessage`: "An API calling is failed, which is caused by unknown reasons."). Retry or review [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes). | | `F` | Inquiry failed. Inspect `resultCode` and see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | Error Code | Result Status | Message | Next Step | | ---------------------------------- | ------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `INVALID_ACCESS_TOKEN` | `F` | The access token is not valid. | Obtain a new authorization code via `my.getAuthCode`, then exchange using `applyToken`. | | `ACCESS_TOKEN_NOT_COVER_THE_SCOPE` | `F` | The access token permission scope does not contain specified scope. | Check the permission for the access token and try again. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # inquiryUserAccountList ## Overview `POST /v1/users/inquiryUserAccountList` returns user bank account list based on scopes granted through `my.getAuthCode`. Pass the `accessToken` issued by [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token); the response includes the list of bank accounts associated with the user when authorized. ::warning{icon="i-lucide-info"} To access user account information, you must request the `ACCOUNT_LIST` scope when calling `my.getAuthCode` to obtain the authorization code. :: The `ACCOUNT_LIST` scope provides a more privacy-conscious alternative to `CARD_LIST` by returning only account numbers without any sensitive card information such as masked card numbers. ## Flow ![Inquiry Account List Flow](https://superqi-dev-docs.pages.dev/api-reference/inquiry-account-list.png) 1. **User enters Mini-app** - The buyer opens the merchant's Mini Program within the Super Qi App. 2. **Call my.getAuthCode JSAPI** - The Mini Program calls `my.getAuthCode` with `scopes=['ACCOUNT_LIST']` to request user authorization. 3. **Display authorization page** - Super Qi App displays the authorization consent page to the user. 4. **Confirm authorization** - The user reviews and confirms the authorization request. 5. **Call authorization service** - Super Qi App sends the authorization request to Super Qi Backend. 6. **Return authCode** - Super Qi Backend generates and returns the authorization code. 7. **Callback authCode** - Super Qi App passes the authorization code back to the Mini Program. 8. **Send authCode** - The Mini Program sends the authorization code to the Merchant Backend. 9. **Apply access token** - Merchant Backend exchanges the authorization code for an access token via `/v1/authorizations/applyToken`. 10. **Return accessToken** - Super Qi Backend returns the access token to the Merchant Backend. 11. **Get user account list** - Merchant Backend calls `/v1/users/inquiryUserAccountList` with the access token. 12. **Return user account list** - Super Qi Backend returns the user's account list to the Merchant Backend. 13. **Return user account list** - Merchant Backend passes the account list to the Mini Program. 14. **Business logic** - The Mini Program processes the account information according to business needs. ## Endpoint | Method | Path | | ------ | ---------------------------------- | | `POST` | `/v1/users/inquiryUserAccountList` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `accessToken` | `string` | Yes | Access token for querying user bank account list (max 128 characters; disallow `@`, `#`, `?`). Obtain via `applyToken`. | `"281010033AB2F588D14B43238637264FCA5AAF35xxxx"` | ```json { "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response | Field | Type | Required | Description | | ------------- | -------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata containing status and error codes. | | `accountList` | `array` | No | User bank account list queried by the merchant. Must be returned when `result.resultStatus` is `S`. Returns empty array `[]` when user has not bound any bank account. | #### AccountInfo | Property | Type | Required | Description | | --------------- | -------- | -------- | ----------------------------------- | | `accountNumber` | `string` | Yes | Account number (max 32 characters). | ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success" }, "accountList": [ { "accountNumber": "12340001" }, { "accountNumber": "12340002" }, { "accountNumber": "12340003" } ] } ``` ### Result Processing Logic | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `S` | Inquiry succeeded. Use `accessToken` to access user information within the corresponding scope. | | `U` | Result unknown (`resultCode`: `UNKNOWN_EXCEPTION`, `resultMessage`: "An API calling is failed, which is caused by unknown reasons."). Retry or review [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes). | | `F` | Inquiry failed. Inspect `resultCode` and see [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | Error Code | Result Status | Message | Next Step | | ---------------------------------- | ------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `INVALID_ACCESS_TOKEN` | `F` | The access token is not valid. | Obtain a new authorization code via `my.getAuthCode`, then exchange using `applyToken`. | | `ACCESS_TOKEN_NOT_COVER_THE_SCOPE` | `F` | The access token permission scope does not contain specified scope. | Check the permission for the access token and try again. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) - [inquiryUserCardList](https://superqi-dev-docs.pages.dev/api-reference/open-apis/users/inquiry-user-card-list) # sendInbox ## Overview `POST /v1/messages/sendInbox` enables merchants or Independent Software Vendors (ISV) to send inbox messages to wallet users using access tokens. This API allows you to deliver notifications, updates, and other messages directly to users' wallet inbox. The message content is customizable through templates, allowing you to include dynamic parameters such as titles, content text, and deep links to specific pages within your Mini Program. ::warning - Ensure the access token has the `NOTIFICATION_INBOX` scope before attempting to send messages. - The `requestId` is idempotent—submitting the same ID multiple times will only send the message once. - Verify the access token is valid and not expired before making the API call. :: ![sendInbox flow](https://superqi-dev-docs.pages.dev/api-reference/sendInbox.png) 1. The Mini Program calls the `my.getAuthCode` JSAPI with specific scopes(`NOTIFICATION_INBOX`) to request an authorization code. 2. The E-wallet App processes the request and displays the authorization page that needs to be authorized. 3. The user confirms the authorization in the super app. 4. The E-wallet App service calls authorization service to processes the authorization information. 5. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 6. The E-wallet App service returns the `authCode` to the Mini Program. 7. The Mini Program sends the `authCode` to the merchant backend. 8. The merchant backend calls the `applyToken` API with `authCode` to apply the `accessToken`. 9. The E-wallet backend returns `accessToken` information to the merchant backend, such as accessToken, refreshToken, etc. 10. The merchant backend calls this API with the `accessToken` to send inbox message to the user. 11. The E-wallet backend returns the send result, including `messageId`. ## Endpoint | Method | Path | | ------ | ------------------------ | | `POST` | `/v1/messages/sendInbox` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: - Request header - Response header [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | -------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | `accessToken` | `string` | Yes | Access token used to send inbox messages. Obtain via `applyToken` with `NOTIFICATION_INBOX` scope. Max length 128; no `@#?`. | `"20191127190741010007000000777771xxxx"` | | `requestId` | `string` | Yes | Unique request identifier for idempotency. Resubmitting the same `requestId` will not send duplicate messages. Max length 128; no `@#?`. | `"20191127190741010007013213123xxxx"` | | `templateCode` | `string` | Yes | Template code distinguishing different message templates. Max length 256; no `@#?`. | `"MINI_APP_COMMON_INBOX"` | | `templates` | `array` | Yes | Array of content template objects. Each object contains `templateParameters` with `Title`, `Content`, and `Url` fields. | See structure below | **Template Structure:** Each item in the `templates` array must include: - `templateParameters.Title` (string, required): The inbox message title - `templateParameters.Content` (string, required): The inbox message content/body - `templateParameters.Url` (string, required): Deep link URL to navigate within the Mini Program (format: `mini://platformapi/startapp?_ariver_appid={appId}`) ```json { "accessToken": "20191127190741010007000000777771xxxx", "requestId": "20191127190741010007013213123xxxx", "templateCode": "MINI_APP_COMMON_INBOX", "templates": [ { "templateParameters": { "Title": "mini-inbox-title", "Content": "hello mini program", "Url": "mini://platformapi/startapp?_ariver_appid=888888" } } ] } ``` ### Response | Field | Type | Required | Description | Example | | ------------ | -------- | ----------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | | `result` | `object` | Yes | Outcome metadata including status and error codes. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }` | | `messageId` | `string` | Conditional | Unique message identifier. Present when message is sent successfully. Max length 258; no `@#?`. | `"20201235900212xxxx"` | | `extendInfo` | `string` | No | Extended response metadata (max 4096 characters, no `@#?`). | `"This is additional information"` | ```json { "messageId": "20201235900212xxxx", "extendInfo": "", "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" } } ``` ### Result Processing Logic | Status | Description | | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Request succeeded. `resultCode` is `SUCCESS` and `resultMessage` is `success`. The inbox message was sent successfully. | | `A` | Request accepted. `resultCode` is `ACCEPT`; message processing initiated. | | `U` | Outcome unknown. `resultCode` is `UNKNOWN_EXCEPTION`; retry after checking [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) or logs. | | `F` | Request failed. Inspect `resultCode` and cross-reference [Error codes](https://superqi-dev-docs.pages.dev/#error-codes). | ## Error Codes | Error Code | Result Status | Message | Next Step | | ---------------------------------- | ------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------- | | `ACCESS_TOKEN_NOT_COVER_THE_SCOPE` | `F` | Access token permission scope does not contain specified scope. | Ensure the access token includes the `NOTIFICATION_INBOX` scope. | | `INVALID_ACCESS_TOKEN` | `F` | Access token is invalid. | Refresh the access token via `applyToken` or re-authorize with `my.getAuthCode`. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # sendPush ## Overview `POST /v1/messages/sendPush` enables merchants or Independent Software Vendors (ISV) to send push messages to wallet users using access tokens. This API allows you to deliver push notifications, alerts, and other time-sensitive messages directly to users' devices. The message content is customizable through templates, allowing you to include dynamic parameters such as titles, content text, and deep links to specific pages within your Mini Program. ::warning - Ensure the access token has the `NOTIFICATION_PUSH` scope before attempting to send messages. - The `requestId` is idempotent—submitting the same ID multiple times will only send the message once. - Verify the access token is valid and not expired before making the API call. :: ![sendPush flow](https://superqi-dev-docs.pages.dev/api-reference/sendPush.png) 1. The Mini Program calls the `my.getAuthCode` JSAPI with specific scopes(`NOTIFICATION_PUSH`) to request an authorization code. 2. The E-wallet App processes the request and displays the authorization page that needs to be authorized. 3. The user confirms the authorization in the super app. 4. The E-wallet App service calls authorization service to processes the authorization information. 5. The E-wallet backend verifies the authorization information, generates the `authCode` and returns. 6. The E-wallet App service returns the `authCode` to the Mini Program. 7. The Mini Program sends the `authCode` to the merchant backend. 8. The merchant backend calls the `applyToken` API with `authCode` to apply the `accessToken`. 9. The E-wallet backend returns `accessToken` information to the merchant backend, such as accessToken, refreshToken, etc. 10. The merchant backend calls this API with the `accessToken` to send push message to the user. 11. The E-wallet backend returns the send result, including `messageId`. ## Endpoint | Method | Path | | ------ | ----------------------- | | `POST` | `/v1/messages/sendPush` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: - Request header - Response header [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | -------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | | `accessToken` | `string` | Yes | Access token used to send push messages. Obtain via `applyToken` with `NOTIFICATION_PUSH` scope. Max length 128 characters. | `"2019112719074101000700000077771xxxx"` | | `requestId` | `string` | Yes | Unique request identifier for idempotency. Resubmitting the same `requestId` will not send duplicate messages—if the same `requestId` is stored, the stored result is returned. Max length 128 characters. | `"20191127190741010007013213123xxxx"` | | `templateCode` | `string` | Yes | Unique code to distinguish different content templates. Max length 256 characters. | `"MINI_APP_COMMON_PUSH"` | | `templates` | `array` | Yes | Array of content template objects for push messages. The URL is generated by the mini program platform. Each object contains `templateParameters` with `Title`, `Content`, and `Url` fields. | See structure below | **Template Structure:** Each item in the `templates` array must include: - `templateParameters.Title` (string, required): The push message title - `templateParameters.Content` (string, required): The push message content/body - `templateParameters.Url` (string, required): Deep link URL to navigate within the Mini Program (format: `mini://platformapi/startapp?_ariver_appid={appId}`) ```json { "accessToken": "2019112719074101000700000077771xxxx", "requestId": "20191127190741010007013213123xxxx", "templateCode": "MINI_APP_COMMON_PUSH", "templates": [ { "templateParameters": { "Title": "mini-push-title", "Content": "hello mini program", "Url": "mini://platformapi/startapp?_ariver_appid=888888" } } ] } ``` ### Response | Field | Type | Required | Description | Example | | ------------ | -------- | -------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | | `result` | `object` | Yes | Request result containing status and error codes information. | `{ "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" }` | | `messageId` | `string` | No | Unique message identifier. Present when message is sent successfully. Max length 258 characters. | `"20201235900212xxxx"` | | `extendInfo` | `string` | No | Additional extensive information. Max length 4096 characters. | `"This is additional information"` | ```json { "messageId": "20201235900212xxxx", "extendInfo": "", "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "success" } } ``` ### Result Processing Logic The `result.resultStatus` field indicates the result of processing a request as follows: | Status | Description | | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `S` | Request succeeded. Sending push messages via access tokens is successful. `resultCode` is `SUCCESS` and `resultMessage` is `success`. | | `A` | Request accepted. The request is accepted by wallets. `resultCode` is `ACCEPT`; `resultMessage` varies based on different situations. | | `U` | Outcome unknown. Unknown exception occurred on wallet side. The merchant or ISV may try again. `resultCode` is `UNKNOWN_EXCEPTION` and `resultMessage` is "An API calling is failed, which is caused by unknown reasons." | | `F` | Request failed. Sending push messages via access tokens fails. Inspect `resultCode` and `resultMessage` which vary based on different situations. Cross-reference [Error codes](https://superqi-dev-docs.pages.dev/#error-codes) below. | ## Error Codes API-specific error codes: are listed in the following table. | Error Code | Result Status | Message | Next Step | | ---------------------------------- | ------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `ACCESS_TOKEN_NOT_COVER_THE_SCOPE` | `F` | The access token permission scope does not contain specified scope. | Check the permission for the access token and try again. Ensure the access token includes the `NOTIFICATION_PUSH` scope. | | `INVALID_ACCESS_TOKEN` | `F` | The access token is invalid. | Restart the OAuth again or refresh the token and try again. | | `PARAM_ILLEGAL` | `F` | Illegal parameters exist. For example, a non-numeric input, or an invalid date. | Check the templates content and try again. | | `UNKNOWN_EXCEPTION` | `U` | An API calling is failed, which is caused by unknown reasons. | 1. Check whether `templateCode` is `MINI_APP_COMMON_PUSH`. If it is not `MINI_APP_COMMON_PUSH`, modify it. :br 2. Check whether the `templateCode` value in the request parameter meets the document expectations. | ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # inquiryMerchantInfo ## Overview `POST /v1/merchants/inquiryMerchantInfo` returns merchant attributes based on the `accessToken` issued by [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). The response includes merchant profile details such as merchant ID, business name, and logo when authorized. ::warning This API requires **Business (Merchant) User Scopes**, not Customer User Scopes. When calling `my.getAuthCode`, use merchant-specific scopes such as `MERCHANT_ID`, `MERCHANT_NAME`, or `MERCHANT_LOGO`. For more details on scope types, see [getAuthCode - Scope Reference](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#scope-reference). :: ![Inquiry merchant flow](https://superqi-dev-docs.pages.dev/api-reference/inquiry-merchant-info.png) 1. Place order in Mini-app – The Buyer initiates an order through the Mini Program. 2. Call my.getDeviceInfo JSAPI – The Mini Program calls the Super Qi App to retrieve device information. 3. Return deviceInfo – The Super Qi App returns the device information back to the Mini Program. 4. Call my.getAutoCode JSAPI with user scopes – If the currentRole is "customer", the Mini Program requests an authorization code with user-level scopes. 5. Call my.getAutoCode JSAPI with merchant scopes – If the currentRole is "business", the Mini Program requests an authorization code with merchant-level scopes. 6. Display authorization page – The Super Qi App shows an authorization page to the Buyer. 7. Confirm authorization – The Buyer confirms/approves the authorization request. 8. Call authorization service – The Super Qi App calls the Super Qi Backend's authorization service. 9. Return authCode – The Super Qi Backend returns an authorization code. 10. Callback authCode – The Super Qi App sends the authCode back to the Mini Program via callback. 11. Send authCode and userType – The Mini Program sends the authCode and userType to the Merchant Backend. 12. Apply access token with authCode via /v1/authorizations/applyToken – The Merchant Backend exchanges the authCode for an access token by calling the Super Qi Backend. 13. Return accessToken and customerId – The Super Qi Backend returns the accessToken and customerId. 14. Inquiry user info with accessToken via /v1/users/inquiryUserInfo – If currentRole is "customer", the Merchant Backend fetches user details using the access token. 15. Return user information – The Super Qi Backend returns the user information. 16. Inquiry merchant info with accessToken via /v1/merchants/inquiryMerchantInfo – If currentRole is "business", the Merchant Backend fetches merchant details using the access token. 17. Return merchant information – The Super Qi Backend returns the merchant information. ## Endpoint | Method | Path | | ------ | ----------------------------------- | | `POST` | `/v1/merchants/inquiryMerchantInfo` | ## API Structure A message consists of a header and body. The following sections are focused on the body structure. For the header structure, see: [OpenAPIs Overview](https://superqi-dev-docs.pages.dev/api-reference/open-apis). ### Request | Field | Type | Required | Description | Example | | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `accessToken` | `string` | Yes | Access token for querying merchant info (max 128 characters; disallow `@`, `#`, `?`). Obtain via `applyToken`. | `"281010033AB2F588D14B43238637264FCA5AAF35xxxx"` | | `extendInfo` | `string` | No | Optional metadata (max 4096 characters; no `@`, `#`, `?`). | `{ "memo": "memo" }` | ```json { "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response | Field | Type | Required | Description | | -------------- | -------- | -------- | ------------------------------------------------------------------------------------------------- | | `result` | `object` | Yes | Outcome metadata containing status and error codes. | | `merchantInfo` | `object` | No | Merchant attributes allowed by the authorized scopes. Returned when `result.resultStatus` is `S`. | #### MerchantInfo | Field | Type | Description | | -------------------- | -------- | --------------------------------------------- | | `merchantId` | `string` | The unique merchant ID in Super Qi. | | `merchantName` | `string` | The English name of the merchant in Super Qi. | | `merchantNameArabic` | `string` | The Arabic name of the merchant in Super Qi. | | `merchantLogo` | `string` | The merchant logo URL. | ### Result Processing Logic | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `S` | The inquiry is successful. Use the `accessToken` to access merchant information within the corresponding scope. The corresponding `result.resultCode` is `SUCCESS` and the `result.resultMessage` is `Success`. | | `U` | The status of the inquiry is unknown. The corresponding `result.resultCode` is `UNKNOWN_EXCEPTION` and `result.resultMessage` is "An API calling is failed, which is caused by unknown reasons." For details, see the [Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes) section. | | `F` | The inquiry is failed. The corresponding `result.resultCode` and `result.resultMessage` are various based on different situations. For details, see the [Error codes](https://superqi-dev-docs.pages.dev/#error-codes) section. | ## Error Codes Error codes are usually classified into the following categories: - **[Common error codes](https://superqi-dev-docs.pages.dev/api-reference/common-error-codes)**: are common for all OpenAPIs. - **API-specific error codes**: are listed in the following table. | Result Status | Result Code | Result Message | | ------------- | ---------------------- | ------------------------------ | | `F` | `INVALID_ACCESS_TOKEN` | The access token is not valid. | | `F` | `EXPIRED_ACCESS_TOKEN` | The access token is expired. | ## Samples ### Request ```json { "accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx" } ``` ### Response ```json { "result": { "resultCode": "SUCCESS", "resultStatus": "S", "resultMessage": "Success" }, "merchantInfo": { "merchantId": "216629765986934560843", "merchantName": "KFC", "merchantNameArabic": "" } } ``` ## Related Links - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # Overview ## Overview The Super Qi framework provides developers with comprehensive JSAPI capabilities to build diversified and convenient services for users. JSAPIs are **client-side JavaScript functions** that Mini Programs call directly within the application to access device features, user data, and platform services. ::warning JSAPIs are called from your **Mini Program client** (front-end), while Open APIs are called from your **merchant backend**. Choose the appropriate API type based on where the functionality is needed. :: ## JS Bridge Architecture Mini Programs launched to different native apps run on different containers, which may support varying JSAPI implementations. To resolve this, Super Qi provides a **JavaScript Bridge (JS Bridge)** that standardizes JSAPI calls across different platforms. ![JS Bridge Architecture](https://superqi-dev-docs.pages.dev/api-reference/js-bridge.jpeg) ### How JS Bridge Works JS Bridge acts as a two-way communication channel between JavaScript code in your Mini Program and native code in the host application. This allows: - **Unified API calls** across different native apps - **Platform abstraction** - developers write once, run everywhere - **Native feature access** - camera, location, payments, etc. - **Consistent behavior** regardless of the host application ## SDK Integration To use Mini Program JSAPIs, you need to integrate the JSBridge SDK. ### Import the SDK Add the following script tag to your Mini Program's HTML file: ```html ``` ::warning This SDK provides access to all standard JSAPIs including `my.getAuthCode`, `my.tradePay`, `my.alert`, and more which are found under the "Essential APIs" section. :: ## API Conventions Super Qi JSAPIs follow consistent naming and usage patterns to make integration straightforward. ### API Naming Patterns JSAPIs use different prefixes based on their purpose: | Prefix | Purpose | Example | | --------------------- | ------------------------------------------- | ------------------------------------------- | | `my.*` | Standard synchronous or callback-based APIs | `my.alert()`, `my.httpRequest()` | | `AlipayJSBridge.call` | Special bridge calls for certain features | `AlipayJSBridge.call('qicardSignContract')` | ### Standard APIs All other JSAPI interfaces accept an **object as a parameter** with the following common properties: | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------- | | `success` | `Function` | No | Callback executed when the API call succeeds | | `fail` | `Function` | No | Callback executed when the API call fails | | `complete` | `Function` | No | Callback executed after success or failure | **Additional API-specific properties** vary depending on the functionality. ### Callback Results - Callback functions receive a result object as their parameter - If the result contains `error` or `errorMessage` fields, the call failed - Success callbacks receive API-specific data ### Promise Support All standard APIs return a **Promise object**, allowing you to use modern async/await syntax or promise chaining. **Callback Example:** ```javascript my.httpRequest({ url: '/api/data', success(res) { console.log('Success:', res.data); }, fail(res) { console.log('Error:', res.error, res.errorMessage); }, complete(res) { console.log('Request completed'); } }); ``` **Promise Example:** ```javascript my.httpRequest({ url: '/api/data', success(res1) { console.log('Callback result:', res1); } }).then((res2) => { // res1 === res2 console.log('Promise result:', res2.data); }).catch((res) => { console.log('Error:', res.error, res.errorMessage); }); ``` **Async/Await Example:** ```javascript async function fetchData() { try { const res = await my.httpRequest({ url: '/api/data' }); console.log('Data:', res.data); } catch (res) { console.log('Error:', res.error, res.errorMessage); } } ``` ## API Interface Definition Each JSAPI has a TypeScript-style interface definition that describes its parameters and callbacks. ### Example - `my.alert` The `my.alert` API displays a simple alert dialog. Here's how its interface is defined: ```typescript interface IAlertOptions { title?: string; // Alert dialog title content?: string; // Alert dialog content buttonText?: string; // Button label text success?: () => void; // Success callback fail?: () => void; // Failure callback complete?: () => void; // Completion callback } ``` **Usage:** ```javascript my.alert({ title: 'Payment Successful', content: 'Your order has been confirmed', buttonText: 'OK', success() { console.log('User closed the alert'); } }); ``` ### Common Interface Pattern Most JSAPIs follow this pattern: ```typescript interface IApiOptions { // API-specific required parameters requiredParam: string; // API-specific optional parameters optionalParam?: number; // Common callback functions success?: (res: SuccessResult) => void; fail?: (res: ErrorResult) => void; complete?: (res: Result) => void; } ``` **Properties marked with `?` are optional.** ## Related Documentation - [my.getAuthCode](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code) - Authorization API - [my.tradePay](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/trade-pay) - Payment API # getAuthCode ## Overview `my.getAuthCode` prompts the Mini Program user to authorize access and returns an `authCode`. Merchants exchange this code for access tokens to retrieve user identifiers and profile data. For scope definitions and token exchange, refer to [User authorization](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). ::warning To view the end-to-end diagram, see the [Authentication flow](https://superqi-dev-docs.pages.dev/api-reference/flows/authentication). :: ## Request Example ```js my.getAuthCode({ scopes: ['auth_base'], success: (res) => { my.alert({ content: res.authCode }); }, fail: (err) => { console.log(err.authErrorScopes); } }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `scopes` | `Array` | Yes | Authorization scopes to request. See [Scope reference](https://superqi-dev-docs.pages.dev/#scope-reference). | | `success` | `Function` | No | Callback executed on success. Receives the payload described in [Callback payload](https://superqi-dev-docs.pages.dev/#callback-payload). | | `fail` | `Function` | No | Callback executed on failure. Receives the payload described in [Callback payload](https://superqi-dev-docs.pages.dev/#callback-payload). | | `complete` | `Function` | No | Callback executed on completion, regardless of outcome. | ## Scope Reference ### Customer User Scope | Scope | Description | Silent authorization | | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | `auth_base` | Obtain the unique user ID. | Yes | | `USER_ID` | Obtain the unique user ID. | Yes | | `USER_LOGIN_ID` | Obtain the user login ID. | Yes | | `HASH_LOGIN_ID` | Obtain the hashed user login ID. | Yes | | `auth_user` | Obtain the user's basic profile information. | No | | `USER_NAME` | Obtain the user's name. | No | | `USER_AVATAR` | Obtain the user's avatar. | No | | `USER_GENDER` | Obtain the user's gender. | No | | `USER_BIRTHDAY` | Obtain the user's birthday. | No | | `USER_NATIONALITY` | Obtain the user's nationality. | No | | `USER_CONTACTINFO` | Obtain the user's contact information. | No | | `NOTIFICATION_INBOX` | Send notifications to the user's in-app inbox. | No | | `AGREEMENT_PAY` | Enable auto-debit payments from the user's balance or card. | No | | `CARD_LIST` | Access the user's linked bank card information (high permission scope). Required by [`inquiryUserCardList`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/users/inquiry-user-card-list). | No | | `ACCOUNT_LIST` | Access the user's bank account list (account numbers only, without sensitive card information). Required by [`inquiryUserAccountList`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/users/inquiry-user-account-list). | No | > `auth_base` supports silent authorization and does not interrupt the user. All other scopes require proactive user consent. ### Business (Merchant) User Scope | Scope | Description | Silent authorization | | ----------------------- | --------------------------------------------------------------------------- | -------------------- | | `auth_base` | Obtain the unique merchant ID. | Yes | | `MERCHANT_ID` | Obtain the unique merchant ID in Super Qi. | Yes | | `MERCHANT_NAME` | Obtain the merchant's business name. | No | | `MERCHANT_LOGO` | Obtain the merchant's logo. | No | | `AGREEMENT_PAY` | Enable auto-debit payments from the merchant's balance or card. | No | | `NOTIFICATION_PUSH` | Send push notifications to the merchant. | No | | `NOTIFICATION_INBOX` | Send notifications to the merchant's in-app inbox. | No | | `NOTIFICATION_WhatsApp` | Send WhatsApp notifications to the merchant. | No | | `CARD_LIST` | Access the merchant's linked bank card information (high permission scope). | No | > Scopes with silent authorization do not require explicit merchant approval. All other scopes require the merchant to grant consent. ## Callback Payload | Property | Type | Required | Description | | ------------------- | ------------------------ | -------- | ------------------------------------------------------ | | `authCode` | `string` | Yes | Authorization code to exchange via `applyToken`. | | `authErrorScopes` | `Record` | No | Map of scopes that failed with associated error codes. | | `authSuccessScopes` | `string[]` | No | List of scopes that were successfully authorized. | ### Success Example ```json { "authCode": "0000000001T1dc0W0tv44B0BD00007826" } ``` ### Failure Example ```json { "authErrorScopes": { "auth_user": "10001" } } ``` ## Error Codes | Code | Description | | ------ | ----------------------------------- | | `3` | `ERROR_CODE_UNKNOWN_ERROR` | | `1000` | `ERROR_CODE_UNKNOWN_ERROR` | | `1001` | `ERROR_CODE_USER_CANCEL` | | `1002` | `ERROR_CODE_APP_SERVICE_ERROR` | | `1003` | `ERROR_CODE_TIMEOUT` | | `2001` | `ERRORLCODE_AUTH_PENDING_AGREEMENT` | # qicardSignContract ## Overview The `qicardSignContract` JSAPI redirects the user to the QiCard authorization page. Invoke it with `AlipayJSBridge.call` to launch the hosted signing screen. After the user confirms the agreement, the Mini Program receives an `authCode` that your backend exchanges for an agreement token via [`applyToken`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token). Ensure the host app runtime is version **1.24.6** or higher. ::warning `AlipayJSBridge.call('qicardSignContract')` participates in the [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment) to capture long-term user consent. :: ::warning To view the end-to-end diagram, see the [Agreement Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/agreement-payment). :: ## Usage Example ```js AlipayJSBridge.call('qicardSignContract', { authUrl: 'https://wallet.example.com/sign?contract=xxxxxxx', // the auth URL returned by the wallet extParams: {} }, (res) => { if (!res.error && !res.errorCode && res.authCode) { // handle successful authorization (store authCode, advance UI) } else { // Handle error response (logging, user feedback) } }); ``` ## Parameters | Property | Type | Required | Description | | ----------- | ------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `authUrl` | `string` | Yes | Authorization URL returned by the wallet to start the signing experience. | | `extParams` | `Record` | No | Optional additional parameters, for example `subClientId`. | | `callback` | `Function` | No | Single callback invoked with the signing result (success or failure). Provides the payloads in [Callback payloads](https://superqi-dev-docs.pages.dev/#callback-payloads). | ## Callback Payloads `AlipayJSBridge.call` delivers a single response object to your callback. Inspect the returned fields to determine success or failure. ### Success | Property | Type | Description | | ---------- | -------- | ----------------------------------------------------------------------------------- | | `authCode` | `string` | Authorization code used to obtain an agreement token. Maximum length 32 characters. | ```json { "authCode": "663A8FA9D83648EE8AA11FF682989DC7" } ``` ### Failure | Property | Type | Description | | ----------------------------- | -------- | ------------------------------------------------------------------------------ | | `errorCode` | `string` | Error code describing why the signing failed. | | `errorMessage` / `errMessage` | `string` | Human-readable message for the failure (property may vary by runtime version). | ## Error Codes | Code | Description | | ------ | ------------------------------------ | | `6001` | User cancelled the signing process. | | `6002` | Network exception prevented signing. | | `6003` | Signing failed due to service error. | ## Related Links - [prepare](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/prepare) - [applyToken](https://superqi-dev-docs.pages.dev/api-reference/open-apis/authorization/apply-token) # tradePay ## Overview ::warning `my.tradePay` is part of the [Cashier Payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment) used to collect wallet payments. :: `my.tradePay` launches the wallet cashier so the user can confirm and complete a payment. Pass the cashier `paymentUrl` you obtained from the [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) API response — specifically the `redirectActionForm.redirectionUrl` field. On completion, the API returns a status code indicating whether the payment succeeded, failed, or is still processing. ## Usage Example ```js my.tradePay({ paymentUrl: 'https://wallet.example.com/cashier?orderId=xxxxxxx', success: (res) => { my.alert({ content: JSON.stringify(res) }); }, fail: (err) => { my.alert({ content: JSON.stringify(err) }); } }); ``` ## Parameters | Property | Type | Required | Description | | ------------ | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paymentUrl` | `string` | No | The redirect URL of the cashier page, obtained from the [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) response field `redirectActionForm.redirectionUrl`. See [Cashier payment flow](https://superqi-dev-docs.pages.dev/api-reference/flows/cashier-payment) for how to obtain it. | | `success` | `Function` | No | Callback executed when the API call succeeds. Provides the payload defined in [Callback payload](https://superqi-dev-docs.pages.dev/#callback-payload). | | `fail` | `Function` | No | Callback executed when the API call fails. | | `complete` | `Function` | No | Callback executed after success or failure. | > The [`pay`](https://superqi-dev-docs.pages.dev/api-reference/open-apis/payments/pay) API returns the cashier URL as `redirectActionForm.redirectionUrl`. Pass that exact value as `tradePay`'s `paymentUrl` to route the user to the correct cashier. ## Callback Payload | Property | Type | Required | Description | | ------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------- | | `resultCode` | `string` | Yes | Result code representing the payment outcome. See [Result codes](https://superqi-dev-docs.pages.dev/#result-codes). | ### Success Example ```json { "resultCode": "9000" } ``` ## Result Codes | `resultCode` | Description | | ------------ | ------------------------------------------- | | `9000` | Payment successful. | | `8000` | Payment processing; final status pending. | | `4000` | Payment failed. | | `6001` | User cancelled the payment. | | `6002` | Network exception occurred. | | `6004` | Unknown payment result; retry status query. | # getDeviceInfo ## Overview `my.getDeviceInfo` retrieves essential device information and the current user's role in the Super Qi app. This JSAPI plays a critical role in enabling developers to build Miniapps that serve both **Customer** and **Business** users effectively. The most important value returned by this API is `currentRole`, which indicates whether the logged-in user is a: - **`customer`** - An individual consumer using the Super Qi app - **`business`** - A merchant/business account using the Super Qi app By checking the `currentRole`, your Miniapp can dynamically adapt its behavior, UI, and authorization flows to match the user type. For example: - When `currentRole` is `"customer"`, call `my.getAuthCode` with [Customer User Scopes](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#customer-user-scope) - When `currentRole` is `"business"`, call `my.getAuthCode` with [Business (Merchant) User Scopes](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#business-merchant-user-scope) This allows you to build a single Miniapp that seamlessly works for both B2C and B2B scenarios. ## Usage Example ### DSL ```js my.getDeviceInfo({ success: (res) => { my.alert({ content: res.currentRole, }); }, fail: (res) => { console.log('getDeviceInfo call failed: ', JSON.stringify(res)); my.alert({ content: JSON.stringify(res), }); }, }); ``` ### H5+ ```js AlipayJSBridge.call( "getDeviceInfo", {}, function (data) { console.log(data); } ); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback executed when the API call succeeds. Provides the payload defined in [Callback payload](https://superqi-dev-docs.pages.dev/#callback-payload). | | `fail` | `Function` | No | Callback executed when the API call fails. | | `complete` | `Function` | No | Callback executed after success or failure. | ## Callback Payload | Property | Type | Description | | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `language` | `string` | The user's preferred language (e.g., `"en-US"`). | | `isProdEnv` | `string` | Indicates if the app is running in production environment (`"true"` or `"false"`). | | `currentRole` | `string` | The role of the current user. Possible values: `"customer"` (individual consumer) or `"business"` (merchant/business account). | | `systemInfo` | `string` | Operating system information (e.g., `"Android 15"`, `"iOS 16"`). | | `hardwareInfo` | `string` | Device hardware model information (e.g., `"HONOR_PGT-AN00"`). | | `loginTime` | `string` | Timestamp indicating when the user logged in (in milliseconds). | ### Success Example (Customer User) ```json { "language": "en-US", "isProdEnv": "true", "currentRole": "customer", "systemInfo": "Android 15", "hardwareInfo": "HONOR_PGT-AN00", "loginTime": "360307579" } ``` ### Success Example (Business User) ```json { "language": "en-US", "isProdEnv": "true", "currentRole": "business", "systemInfo": "Android 15", "hardwareInfo": "HONOR_PGT-AN00", "loginTime": "360307579" } ``` ## Related Links - [getAuthCode - Scope Reference](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#scope-reference) - [inquiryUserInfo (Customer API)](https://superqi-dev-docs.pages.dev/api-reference/open-apis/users/inquiry-user-info) - [inquiryMerchantInfo (Business API)](https://superqi-dev-docs.pages.dev/api-reference/open-apis/merchants/inquiry-merchant-info) - [FAQ: Customer vs Business Scopes](https://superqi-dev-docs.pages.dev/faq#whats-the-difference-between-customer-and-business-user-scopes) # navigateToMiniProgram ## Overview `my.navigateToMiniProgram` allows your Mini Program to jump to another Mini Program within the Super Qi ecosystem. You can pass data to the target Mini Program. ## Sample Code ```javascript my.navigateToMiniProgram({ appId: "xxxx", extraData: { data1: "test", }, success: (res) => { console.log(JSON.stringify(res)); }, fail: (res) => { console.log(JSON.stringify(res)); }, }); ``` ## Parameters | Property | Type | Required | Description | | ----------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `appId` | `String` | Yes | The appId of the target Mini Program to jump to. | | `path` | `String` | No | The path of the target Mini Program to jump to, opens the homepage if it is empty. | | `extraData` | `Object` | No | The extra data that needs to be passed to the target Mini Program. The target Mini Program can get it in `App.onLaunch()` or `App.onShow()`. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - The `appId` is the unique identifier of the target Mini Program - If no `path` is specified, the target Mini Program will open at its homepage - Data passed via `extraData` can be accessed in the target Mini Program's lifecycle methods ## Related Links - [my.navigateBackMiniProgram](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/navigate-back-miniprogram) # navigateBackMiniProgram ## Overview `my.navigateBackMiniProgram` allows your Mini Program to return to the previous Mini Program. This API is only used when another Mini Program has jumped to your foregrounded Mini Program, enabling you to navigate back and optionally pass data. ::callout{type="info"} This API should only be called when your Mini Program was opened by another Mini Program using `my.navigateToMiniProgram`. It returns control to the calling Mini Program. :: ## Sample Code ```javascript my.navigateBackMiniProgram({ extraData: { "data1": "test" }, success: (res) => { console.log(JSON.stringify(res)) }, fail: (res) => { console.log(JSON.stringify(res)) } }); ``` ## Parameters | Property | Type | Required | Description | | ----------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `extraData` | `Object` | No | The extra data that needs to be returned to the target Mini Program. The target Mini Program can get it in `App.onLaunch()` or `App.onShow()`. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - This API only works when your Mini Program was opened by another Mini Program - Data passed via `extraData` can be accessed in the previous Mini Program's lifecycle methods - The user will be returned to the Mini Program that originally navigated to yours ## Related Links - [my.navigateToMiniProgram](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/navigate-to-miniprogram) # setNavigationBar ## Overview `my.setNavigationBar` allows you to customize the navigation bar (top bar) of your Mini Program by setting the title, background color, border color, or displaying a custom image. This API provides dynamic control over your Mini Program's header appearance. ## Sample Code ```javascript my.setNavigationBar({ title: 'hello', backgroundColor: '#108ee9', success() { my.alert({ content: 'Success', }); }, fail() { my.alert({ content: 'Failed', }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `title` | `String` | No | Navigation bar title. | | `image` | `String` | No | Picture link address, must be https. Use 3x high-definition pictures. If the image is set, the title parameter is inactive. Currently, SVG images are not supported. | | `backgroundColor` | `String` | No | Navigation bar background color, supporting hex color value. | | `borderBottomColor` | `String` | No | Navigation bar bottom border color, supporting hex color value. If the `backgroundColor` is set, the `borderBottomColor` does not take effect. The `backgroundColor` is used by default. | | `reset` | `Boolean` | No | Whether the navigation bar is reset to the default color, false by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - **Image vs Title**: When `image` is set, the `title` parameter becomes inactive. Choose one or the other. - **Image Requirements**: Images must be served over HTTPS and should be 3x high-definition for optimal display. SVG format is not supported. - **Color Format**: Use hex color values for `backgroundColor` and `borderBottomColor` (e.g., `'#108ee9'`, `'#FFFFFF'`). - **Border Color Priority**: If `backgroundColor` is set, `borderBottomColor` will not take effect and the background color will be used for the border. - **Reset Option**: Set `reset: true` to restore the navigation bar to its default appearance. ## Examples ### Set Title and Background Color ```javascript my.setNavigationBar({ title: 'Payment Confirmation', backgroundColor: '#108ee9' }); ``` ### Use Custom Image ```javascript my.setNavigationBar({ image: 'https://example.com/images/header-3x.png', backgroundColor: '#FFFFFF' }); ``` ### Reset to Default ```javascript my.setNavigationBar({ reset: true }); ``` # multiLevelSelect ## Overview `my.multiLevelSelect` provides a cascade selection function, mainly used for selecting several levels of associated data, such as province, city, and district. Users can drill down through hierarchical options to make their selection. ## Sample Code ```javascript function openMultiLevelSelect() { my.multiLevelSelect({ title: 'Cascade selector', list: [ { name: "City", subList: [ { name: "District A", subList: [ { name: "Street A" }, { name: "Street B" } ] }, { name: "District B", subList: [ { name: "Street C" }, { name: "Street D" } ] } ] } ], success: (res) => { my.alert({ title: JSON.stringify(res) }); } }); } ``` ## Parameters The incoming parameter is of the Object type with the following attributes: | Property | Type | Required | Description | | ---------- | ----------- | -------- | -------------------------------------------------------------------------------------------- | | `title` | `String` | No | Title. | | `list` | `JsonArray` | Yes | Selection data list. | | `name` | `String` | Yes | Entry name. | | `subList` | `JsonArray` | No | Sub-entry list. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | --------- | ----------- | ---------------------------------------------------------------------------------------- | | `success` | `Boolean` | Selection completed or not, returning false for cancellation. | | `result` | `JsonArray` | Selection result, such as `[{"name":"City"},{"name":"District A"},{"name":"Street A"}]`. | ## Usage Notes - The `list` parameter defines the hierarchical structure of selectable items - Each item can have a `subList` array containing child items - Users can navigate through multiple levels before making a final selection - Canceling the selection returns `success: false` in the callback ## Related Links - [my.datePicker](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/date-picker) - Date picker dialog # alert ## Overview `my.alert` displays an alert box with customizable title, content, and button text. This is a modal dialog that requires user interaction to dismiss. ## Sample Code ```javascript my.alert({ title: 'Tips', content: 'Your bill for this month has been released', buttonText: 'Show', success: () => { my.alert({ title: 'Click "Show"', }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------ | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `title` | `String` | No | Title of the alert box. | | `content` | `String` | No | Contents of the alert box. | | `buttonText` | `String` | No | Button text, which is OK by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - The alert is a **modal dialog** - it blocks interaction with the rest of the Mini Program until dismissed - Default button text is "OK" if `buttonText` is not specified - Only one button is displayed (use `my.confirm` for two-button dialogs) - The `success` callback is triggered when the user taps the button ## Examples ### Basic Alert ```javascript my.alert({ title: 'Payment Successful', content: 'Your order has been processed', }); ``` ### Alert with Custom Button ```javascript my.alert({ title: 'Notification', content: 'You have a new message', buttonText: 'View', success: () => { console.log('User clicked View'); }, }); ``` ## Related Links - [my.confirm](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/confirm) - Confirmation dialog with two buttons - [my.prompt](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/prompt) - Prompt dialog with text input # confirm ## Overview `my.confirm` displays a confirmation box with two buttons, allowing users to confirm or cancel an action. The success callback receives a result indicating which button was pressed. ## Sample Code ```javascript my.confirm({ title: 'Tips', content: 'Do you want to check the courier number: 1234567890?', confirmButtonText: 'Inquire now', cancelButtonText: 'Not needed', success: (result) => { my.alert({ title: `${result.confirm}`, }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `title` | `String` | No | Title of the confirm box. | | `content` | `String` | No | Content of the confirm box. | | `confirmButtonText` | `String` | No | OK button text, which is "OK" by default. | | `cancelButtonText` | `String` | No | Cancel button text, which is "Cancel" by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | --------- | --------- | ----------------------------------------------------------- | | `confirm` | `Boolean` | Click Confirm to return true; click Cancel to return false. | ## Usage Notes - The confirm dialog is **modal** - it blocks interaction until the user makes a choice - Use `result.confirm` to determine which button was pressed: - `true` = Confirm button clicked - `false` = Cancel button clicked - Default button texts are "OK" and "Cancel" if not customized ## Examples ### Basic Confirmation ```javascript my.confirm({ title: 'Delete Item', content: 'Are you sure you want to delete this item?', success: (result) => { if (result.confirm) { console.log('User confirmed deletion'); // Proceed with deletion } else { console.log('User cancelled'); } }, }); ``` ### Custom Button Labels ```javascript my.confirm({ title: 'Leave Page', content: 'You have unsaved changes. Do you want to leave?', confirmButtonText: 'Leave', cancelButtonText: 'Stay', success: (result) => { if (result.confirm) { // Navigate away } }, }); ``` ## Related Links - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Simple alert dialog - [my.prompt](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/prompt) - Prompt dialog with text input # prompt ## Overview `my.prompt` displays a dialog that prompts the user to enter text. The dialog includes a text input field, confirmation and cancel buttons, and returns the user's input through the success callback. ## Sample Code ```javascript my.prompt({ title: 'Title', message: 'Explain the current status and prompt the user solution. It is best not to exceed 3 lines.', placeholder: 'Leave a message to a friend', okButtonText: 'Confirm', cancelButtonText: 'Cancel', success: (result) => { my.alert({ title: JSON.stringify(result), }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------------ | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `title` | `String` | No | Title of prompt box. | | `message` | `String` | Yes | Text of prompt box, which is "Enter contents here" by default. | | `placeholder` | `String` | No | Prompt text for the entry box. | | `align` | `String` | No | Message alignment. Valid values are: :br • `left`:br • `center`:br • `right`:br:br The default value is `center` for both iOS and Android. | | `okButtonText` | `String` | No | OK button text, which is OK by default. | | `cancelButtonText` | `String` | No | Cancel button text, which is Cancel by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | --------- | ------------------------------------------------------ | | `ok` | `Boolean` | Click OK to return true; click Cancel to return false. | | `inputValue` | `String` | When OK is true, return the user's entry. | ## Usage Notes - The `message` parameter is **required** - Use `placeholder` to provide helpful hints about what should be entered - The `align` property controls message text alignment (left, center, or right) - Check `result.ok` to determine if the user confirmed or cancelled: - `true` = OK button clicked, `inputValue` contains user input - `false` = Cancel button clicked - Default button texts are "OK" and "Cancel" if not customized ## Examples ### Basic Prompt ```javascript my.prompt({ title: 'Enter Name', message: 'Please enter your full name', placeholder: 'John Doe', success: (result) => { if (result.ok) { console.log('User entered:', result.inputValue); } else { console.log('User cancelled'); } }, }); ``` ### Custom Alignment and Buttons ```javascript my.prompt({ title: 'Feedback', message: 'How can we improve?', placeholder: 'Share your thoughts', align: 'left', okButtonText: 'Submit', cancelButtonText: 'Skip', success: (result) => { if (result.ok && result.inputValue) { // Process feedback console.log('Feedback:', result.inputValue); } }, }); ``` ### Validation Example ```javascript my.prompt({ title: 'Enter Email', message: 'Please provide your email address', placeholder: 'email@example.com', success: (result) => { if (result.ok) { const email = result.inputValue; if (email && email.includes('@')) { console.log('Valid email:', email); } else { my.alert({ title: 'Invalid Email', content: 'Please enter a valid email address', }); } } }, }); ``` ## Related Links - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Simple alert dialog - [my.confirm](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/confirm) - Confirmation dialog # showActionSheet ## Overview `my.showActionSheet` displays an operation menu with multiple action buttons. Users can select one option, and the selected index is returned through the success callback. This is commonly used for presenting a list of actions or options. ## Sample Code ### HTML ```html
Action sheet API

my.showActionSheet

``` ### JavaScript ```javascript function showActionSheet() { my.showActionSheet({ title: 'ActionSheet', items: ['Menu 1', 'Menu 2', 'Menu3'], cancelButtonText: 'Cancel', success: (res) => { const btn = res.index === -1 ? 'Cancel' : 'No' + res.index + ''; my.alert({ title: `You clicked ${btn} button`, }); }, }); } ``` ## Parameters | Property | Type | Required | Description | | ------------------------ | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `title` | `String` | No | The title of the menu. | | `items` | `String Array` | Yes | The text array of the menu button. | | `cancelButtonText` | `String` | No | Text on the cancel button, which is "Cancel" by default. :br:br**Note:** This field is invalid for Android and the cancel button will not be displayed. | | `destructiveButtonIndex` | `Number` | No | This field specifies the index number of a specific button. The value starts from 0. Used for buttons to delete or clear data or the ones in similar scenarios. The default color is red. | | `badges` | `Object Array` | No | For the array with red option. See badges parameters below for the fields in the array. | | `success` | `Function` | No | The callback function for a successful API call. | | `fail` | `Function` | No | The callback function for a failed API call. | | `complete` | `Function` | No | The callback function used when the API call is completed. This function is always executed no matter the call succeeds or fails. | ## Badges Parameters | Property | Type | Description | | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `index` | `Number` | The index of the option that needs use red marks, starting from 0. | | `type` | `String` | Red mark types. Valid values are: :br • `none`: no red mark :br • `point`: red mark :br • `num`: numerical red mark :br • `text`: texts in red | | `text` | `String` | Customized red mark. :br • This field is optional when the value of type is none/point/more. :br • When the value of type is num, but the value of this field has decimals, not greater than 0, or not less than 100, this field is not displayed. | ## Usage Notes - The `items` parameter is **required** and defines the menu options - On Android, the cancel button is not displayed - Use `destructiveButtonIndex` to highlight destructive actions (like delete) in red - The success callback receives `res.index`: - `-1` = Cancel button clicked - `0, 1, 2...` = Index of the selected menu item - Use `badges` to add visual indicators (dots, numbers, or text) to specific options ## Examples ### Basic Action Sheet ```javascript my.showActionSheet({ title: 'Choose Action', items: ['Edit', 'Share', 'Delete'], success: (res) => { if (res.index === 0) { console.log('Edit selected'); } else if (res.index === 1) { console.log('Share selected'); } else if (res.index === 2) { console.log('Delete selected'); } else if (res.index === -1) { console.log('Cancelled'); } }, }); ``` ### Destructive Action ```javascript my.showActionSheet({ title: 'Manage Item', items: ['Edit', 'Share', 'Delete'], destructiveButtonIndex: 2, // Highlights "Delete" in red cancelButtonText: 'Cancel', success: (res) => { if (res.index === 2) { my.confirm({ title: 'Confirm Delete', content: 'Are you sure?', success: (confirmRes) => { if (confirmRes.confirm) { // Proceed with deletion } }, }); } }, }); ``` ### With Badges ```javascript my.showActionSheet({ title: 'Notifications', items: ['Messages', 'Updates', 'Settings'], badges: [ { index: 0, type: 'num', text: '5' }, { index: 1, type: 'point' }, ], success: (res) => { console.log('Selected index:', res.index); }, }); ``` ## Related Links - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Simple alert dialog - [my.confirm](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/confirm) - Confirmation dialog # showLoading / hideLoading ## Overview `my.showLoading` displays a loading indicator dialog, typically used during asynchronous operations. `my.hideLoading` dismisses the loading dialog when the operation completes. ::callout{type="info"} Always pair `my.showLoading` with `my.hideLoading` to ensure the loading indicator is properly dismissed. The loading dialog blocks user interaction until it's hidden. :: ## my.showLoading Show the loading dialog. ### Sample Code ```javascript my.showLoading({ content: 'loading...', delay: 1000, }); ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------ | | `content` | `String` | No | Text contents of loading. | | `delay` | `Number` | No | Displaying delay, in ms, 0 by default. If `my.hideLoading` was called before this time, it is not displayed. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## my.hideLoading Hide the loading dialog. ### Sample Code ```javascript my.hideLoading(); ``` **Example with page context:** ```javascript // Show loading on page load window.onload = function() { my.showLoading(); setTimeout(() => { my.hideLoading({ page: this, // Prevents switching to other pages when execution }); }, 4000); } ``` ### Parameters | Property | Type | Required | Description | | -------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | | `page` | `Object` | No | Specifically it means the current page instance. In some scenarios, it is required to specify the exact page for hideLoading. | ## Usage Notes - **Delay behavior**: If `delay` is set and `my.hideLoading` is called before the delay expires, the loading indicator will not be displayed at all - **Page context**: Use the `page` parameter in `my.hideLoading` when you need to ensure the loading is dismissed on a specific page instance - **Modal behavior**: The loading dialog blocks user interaction while displayed - **Pairing**: Always call `my.hideLoading()` after `my.showLoading()` to avoid blocking the UI indefinitely ## Complete Example ### Basic Loading Flow ```javascript // Show loading my.showLoading({ content: 'Processing...', }); // Perform async operation setTimeout(() => { // Hide loading when done my.hideLoading(); my.alert({ title: 'Complete', content: 'Operation finished successfully', }); }, 2000); ``` ### With Delay ```javascript my.showLoading({ content: 'Loading data...', delay: 500, // Only show if operation takes longer than 500ms }); // Fetch data fetchData().then(() => { my.hideLoading(); }); ``` ### With Page Context ```javascript // Show loading on page load window.onload = function() { my.showLoading({ content: 'Loading...', }); // Simulate async operation setTimeout(() => { my.hideLoading({ page: this, // Ensures hideLoading targets correct page instance }); }, 3000); } ``` ### Fetch Data Example ```javascript function loadData() { my.showLoading({ content: 'Loading data...', }); fetch('/api/data') .then(response => response.json()) .then(data => { // Update your UI with data updateUI(data); my.hideLoading(); }) .catch(error => { my.hideLoading(); my.alert({ title: 'Error', content: 'Failed to load data', }); }); } ``` ## Related Links - [my.showToast / my.hideToast](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/show-toast) - Toast notifications # showToast / hideToast ## Overview `my.showToast` displays a toast notification that automatically disappears after a specified duration. Toasts are non-blocking notifications used for brief feedback messages. `my.hideToast` manually dismisses the toast before its duration expires. ::callout{type="info"} Toast notifications are lightweight and non-intrusive, making them ideal for success messages, status updates, and brief feedback that doesn't require user interaction. :: ## my.showToast Show the toast dialog, which disappears with the specified duration. ### Sample Code ```javascript my.showToast({ type: 'success', content: 'Success', duration: 3000, success: () => { my.alert({ title: 'toast is missing', }); }, }); ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `content` | `String` | No | Text content. | | `type` | `String` | No | Toast type, showing the related icon, none by default. Supporting `success`/`fail`/`exception`/`none`. If it is `exception`, `content` is mandatory. | | `duration` | `Number` | No | Displaying duration, in ms, 2000 by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## my.hideToast Hide the toast dialog. ### Sample Code ```javascript my.hideToast() ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | | `success` | `Function` | No | The callback function for a successful API call. | | `fail` | `Function` | No | The callback function for a failed API call. | | `complete` | `Function` | No | The callback function used when the API call is completed. This function is always executed no matter the call succeeds or fails. | ## Toast Types The `type` parameter controls the icon displayed with the toast: - `success` - Shows a success checkmark icon - `fail` - Shows a failure/error icon - `exception` - Shows an exception icon (requires `content` to be specified) - `none` - No icon, text only ## Usage Notes - **Auto-dismiss**: Toasts automatically disappear after the `duration` (default: 2000ms) - **Manual dismiss**: Call `my.hideToast()` to dismiss a toast before its duration expires - **Non-blocking**: Unlike loading dialogs, toasts don't block user interaction - **Type requirement**: When using `type: 'exception'`, the `content` parameter is mandatory - **Best practices**: Keep toast messages brief and use appropriate icons for the message type ## Complete Examples ### Success Message ```javascript my.showToast({ type: 'success', content: 'Saved successfully', duration: 2000, }); ``` ### Error Message ```javascript my.showToast({ type: 'fail', content: 'Failed to save', duration: 3000, }); ``` ### Exception with Manual Dismiss ```javascript my.showToast({ type: 'exception', content: 'Network error occurred', duration: 5000, }); // Manually hide after 2 seconds setTimeout(() => { my.hideToast(); }, 2000); ``` ### Text-Only Toast ```javascript my.showToast({ type: 'none', content: 'Processing your request', duration: 2000, }); ``` ### With Success Callback ```javascript my.showToast({ type: 'success', content: 'Operation completed', duration: 2000, success: () => { console.log('Toast displayed'); // Navigate or perform next action }, }); ``` ### Form Submission Example ```javascript function submitForm() { my.showLoading({ content: 'Submitting...', }); // Submit form fetch('/api/submit', { method: 'POST', body: JSON.stringify(formData), }) .then(response => { my.hideLoading(); if (response.ok) { my.showToast({ type: 'success', content: 'Form submitted successfully', duration: 2000, }); } else { my.showToast({ type: 'fail', content: 'Submission failed', duration: 3000, }); } }) .catch(error => { my.hideLoading(); my.showToast({ type: 'exception', content: 'Network error', duration: 3000, }); }); } ``` ## Related Links - [my.showLoading / my.hideLoading](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/show-loading) - Loading indicator - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Alert dialog # choosePhoneContact ## Overview `my.choosePhoneContact` allows users to select a phone number from their local system directory. This API opens the device's contact picker and returns the selected contact's information. ## Sample Code ```javascript my.choosePhoneContact({ success: (res) => { my.alert({ content: 'choosePhoneContact response: ' + JSON.stringify(res) }); }, fail: (res) => { my.alert({ content: 'choosePhoneContact response: ' + JSON.stringify(res) }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | -------- | -------- | ----------------------- | | `name` | `String` | Selected contact name. | | `mobile` | `String` | Selected contact phone. | ## Error Code | Error Code | Description | | ---------- | --------------------------------------------------------------------------------------- | | `10` | No permission. | | `11` | The user cancels the operation (or the device does not authorize use of the directory). | ## Usage Notes - Requires permission to access the device's contact list - User can cancel the operation at any time - The API will fail if permission is denied or not granted ## Related Links - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Alert dialog # datePicker ## Overview `my.datePicker` opens a date selection dialog that allows users to pick dates and times in various formats. By default, the current date and time are used if not manually selected. ## Sample Code ```javascript my.datePicker({ format: 'yyyy-MM-dd', currentDate: '2016-10-10', startDate: '2016-10-9', endDate: '2017-10-9', success: (res) => { my.alert({ title: 'datePicker response: ' + JSON.stringify(res) }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | | `format` | `String` | No | The returned date format. | | `currentDate` | `String` | No | The date and time initially selected. By default, the current time date and time are used. | | `startDate` | `String` | No | Minimum date and time. | | `endDate` | `String` | No | Maximum date and time. | | `success` | `Function` | Yes | The callback function for a successful API call. | | `fail` | `Function` | Yes | The callback function for a failed API call. | | `complete` | `Function` | Yes | The callback function used when the API call is completed. This function is always executed no matter the call succeeds or fails. | ## Date Formats The returned date formats include: - `yyyy-MM-dd` (default) - `HH:mm` - `yyyy-MM-dd HH:mm` - `yyyy-MM` - `yyyy` ## Success Callback Function | Property | Type | Description | | -------- | -------- | ------------------ | | `date` | `String` | The selected date. | ## Error Code | Error Code | Description | Solution | | ---------- | --------------------------------------------------------- | ----------------------------------------------------------- | | `11` | The user cancels the operation and no action is required. | The user cancelled the operation and no action is required. | ## Usage Notes - If `currentDate`, `startDate`, or `endDate` are not specified, the current date and time are used by default - The `format` parameter determines the date picker's mode and return format - Users can cancel the picker, which triggers the `fail` callback with error code `11` ## Related Links - [my.multiLevelSelect](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/multi-level-select) - Multi-level selector # chooseImage ## Overview `my.chooseImage` allows users to select an image from their device's camera or photo gallery. The API returns file paths to the selected images. ## Sample Code ```javascript my.chooseImage({ success: (res) => { img.src = res.apFilePaths[0]; }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------ | -------------- | -------- | -------------------------------------------------------------------------------------------- | | `sizeType` | `StringArray` | No | Original image, compressed image, both by default. | | `sourceType` | `String Array` | No | Camera or album, `['camera','album']` by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------- | -------------- | ----------------------- | | `apFilePaths` | `String Array` | Image file description. | ## Error Code | Error | Description | | ----- | ----------------------- | | `11` | User cancels operation. | ## Usage Notes - The `sizeType` parameter controls whether to return original or compressed images - The `sourceType` parameter lets you specify camera, album, or both - Users can cancel the image selection, triggering error code `11` ## Related Links - [my.previewImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/preview-image) - Preview images - [my.saveImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/save-image) - Save images # previewImage ## Overview `my.previewImage` displays images in full-screen preview mode. Users can swipe between images, zoom in/out, and view images from a list of URLs. ::callout{type="info"} The Preview image's "local image path" is not supported. :: ## Sample Code ```javascript my.previewImage({ current: 2, urls: [ 'https://img.example.com/example1.jpg', 'https://img.example.com/example2.jpg', 'https://img.example.com/example3.jpg' ], }); ``` ## Parameters The incoming parameter is of the Object type with the following attributes: \| Property | Type | Required | Description | \| --- | --- | --- | \| `urls` | `Array` | Yes | Http url list of the images to be previewed. | \| `current` | `Number` | No | Index of the current displayed image, 0 by default, indicating the first image in the URLs. | \| `success` | `Function` | No | Callback function upon call success. | \| `fail` | `Function` | No | Callback function upon call failure. | \| `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - Only HTTP/HTTPS URLs are supported - local image paths are not supported - The `current` parameter sets which image is displayed first (zero-indexed) - Users can swipe left/right to navigate between images - Pinch to zoom is supported ## Related Links - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose images - [my.saveImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/save-image) - Save images # saveImage ## Overview `my.saveImage` saves online images from a URL to the device's camera gallery. ## Sample Code ```javascript my.saveImage({ url: 'https://img.example.com/example.jpg' }); ``` ## Parameters | Property | Type | Required | Description | | ----------------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `url` | `String` | Yes | URL of the image to be saved. | | `showActionSheet` | `Boolean` | No | Whether to show the menu when saving image. By default, it is `false`. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Error Code | Error | Description | | ----- | --------------------------------------------------- | | `2` | Invalid parameter, no url parameter transferred. | | `15` | Album right not enabled (iOS only). | | `16` | Insufficient album storage on cellphone (iOS only). | | `17` | Other errors during picture saving. | ## Usage Notes - The `url` parameter is required and must be a valid image URL - Set `showActionSheet: true` to display a menu when saving - The image is saved directly to the device's photo gallery - Requires proper permissions to write to the gallery ## Related Links - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose images - [my.previewImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/preview-image) - Preview images # getImageInfo ## Overview `my.getImageInfo` retrieves detailed information about an image, including its width, height, path, orientation, and format. ## Sample Code ```javascript // Network picture path my.getImageInfo({ src: 'https://img.example.com/example.jpg', success: (res) => { console.log(JSON.stringify(res)); } }); // apFilePath from chooseImage my.chooseImage({ success: (res) => { my.getImageInfo({ src: res.apFilePaths[0], success: (res) => { console.log(JSON.stringify(res)); } }); }, }); // Relative path my.getImageInfo({ src: 'image/api.png', success: (res) => { console.log(JSON.stringify(res)); } }); ``` ## Parameters The incoming parameter is of the Object type with the following attributes: | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `src` | `String` | No | Picture path, supporting network picture path, apFilePath path and relative path. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------- | -------- | -------------------------------------------------------------- | | `width` | `Number` | Picture width (in px). | | `height` | `Number` | Picture height (in px). | | `path` | `String` | Local path of picture. | | `orientation` | `String` | Return picture orientation. Effective values are listed below. | | `type` | `String` | Return picture format. | ## Orientation Parameter Description | Enumerator | Description | | ---------------- | ---------------------------------------------- | | `up` | Default. | | `down` | 180-Degree rotation. | | `left` | Rotate by 90 degree counterclockwise. | | `right` | Rotate by 90 degree clockwise. | | `up-mirrored` | Same as up except for flipping horizontally. | | `down-mirrored` | Same as down except for flipping horizontally. | | `left-mirrored` | Same as left except for flipping vertically. | | `right-mirrored` | Same as right except for flipping vertically. | ## Usage Notes - Supports network URLs, apFilePath (from `my.chooseImage`), and relative paths - Returns comprehensive image metadata including dimensions and orientation - Useful for validating image properties before upload or display ## Related Links - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose images - [my.compressImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/compress-image) - Compress images # compressImage ## Overview `my.compressImage` compresses large images to fulfill the size restrictions from some mini programs. You can specify the compression quality level based on your needs. ## Sample Code ```javascript my.compressImage({ apFilePaths: ['path/to/image1.jpg', 'path/to/image2.jpg'], compressLevel: 2, success: (res) => { console.log('Compressed images:', res.apFilePaths); }, fail: (err) => { console.log('Compression failed:', err); } }); ``` ## Parameters | Property | Type | Required | Description | | --------------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `apFilePaths` | `Array` | Yes | An array of the image paths to be compressed. | | `compressLevel` | `int` | No | The image quality after the compress. Valid values are: :br • `0`: Low quality :br • `1`: Medium quality :br • `2`: High quality :br • `4`: The quality depends on the network. When the network is Wi-Fi, the image is compressed to the high-quality image. Otherwise, the image is compressed to the medium-quality image. :br:br The default value is `4`. | | `success` | `Function` | No | The callback method that indicates a successful call. | | `fail` | `Function` | No | The callback method that indicates a failed call. | | `complete` | `Function` | No | The callback method that indicates the call is completed (this will be executed regardless of whether the call succeeds or fails). | ## Success Callback Function | Property | Type | Required | Description | | ------------- | ------- | -------- | -------------------------------------------- | | `apFilePaths` | `Array` | Yes | The local file path of the compressed image. | ## Error Code | Error Code | Error Message | Description | | ---------- | ----------------- | ------------------------------------- | | `2` | Compress failed | Failed to compress all images. | | | Invalid parameter | Failed to compress one of all images. | ## Usage Notes - Multiple images can be compressed in a single call - The `compressLevel` parameter controls the quality-size tradeoff - Level `4` (default) automatically adjusts based on network conditions - Returns the compressed image paths in the success callback ## Related Links - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose images - [my.getImageInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/get-image-info) - Get image info # chooseVideo ## Overview `my.chooseVideo` allows users to shoot a video with the camera or choose a video from the device album. The API returns information about the selected video including its path, duration, size, and dimensions. ## Sample Code ```javascript my.chooseVideo({ sourceType: ['album', 'camera'], maxDuration: 60, camera: 'back', success: (res) => { console.log(res); }, fail: (error) => { console.log(error); }, complete: () => { console.log('The callback function to be executed whether the request is successful or fail'); } }); ``` ## Parameters The incoming parameter is of the Object type with the following properties: | Property | Data type | Required | Description | | ------------- | --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sourceType` | `Array` | No | Indicates the sources of the video. :br:br Valid values are: :br • `album`: Choose a video from the album on a mobile device. :br • `camera`: Shoot a video with the camera on a mobile device. :br:br By default, the value is `['album','camera']`. | | `compressed` | `Boolean` | No | Specifies whether to compress the selected video file. For iOS, the video file is always compressed. :br:br By default, the value is `true`, which means the selected video file is compressed. | | `maxDuration` | `Number` | No | Indicates the maximum amount of time to shoot a video, in seconds. :br:br By default, the value is `60`, which means the maximum amount of time is 60 seconds. | | `camera` | `String` | No | Indicates which camera (front or back camera) is opened when launching the camera app. :br:br For some Android devices, this configuration is not supported by the system ROM and thus cannot take effect. :br:br Valid values are: :br • `back`: The back camera is opened. :br • `front`: The front camera is opened. :br:br By default, the value is `back`. | | `success` | `Function` | No | The callback function to be executed when the request is successful. | | `fail` | `Function` | No | The callback function to be executed when the request is failed. | | `complete` | `Function` | No | The callback function to be executed when the request is completed (to be executed whether the request is successful or failed). | ## Success Callback Function The following table provides the properties in the `success` callback function: | Property | Type | Description | | -------------- | -------- | -------------------------------------------------------- | | `tempFilePath` | `String` | Indicates the temporary file path of the selected video. | | `duration` | `Number` | Indicates the length of the selected video. | | `size` | `Number` | Indicates the size of the selected video. | | `height` | `Number` | Indicates the height of the selected video. | | `width` | `Number` | Indicates the width of the selected video. | ## Error Codes The following table provides the possible error codes and messages in the API call: | Error code | Error message | Solution | | ---------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | `2` | Invalid parameters. | Check the values in your request and provide correct parameters. | | `3` | An unknown error occurs. | Check whether the calling process is normal. If not resolved, contact our technical support to troubleshoot this issue. | | `11` | The operation was canceled by the user. | Normal user interaction and no further processing is required. | | `12` | An error occurs in data processing. | Call the API again. | | `13` | The file size exceeds the limit. | Check whether you have enough RAM. | | `14` | No access to camera. | Check app permissions for camera. | | `15` | No access to album. | Check app permissions for album. | ## Usage Notes - The `sourceType` parameter controls whether to use camera, album, or both - For iOS devices, videos are always compressed regardless of the `compressed` setting - The `camera` parameter may not work on some Android devices due to ROM limitations - The `maxDuration` parameter only applies when shooting a new video, not when selecting from album ## Related Links - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose images # getStorage ## Overview `my.getStorage` retrieves cached data from local storage. This is an asynchronous interface that supports isolation between embedded webview cache and Mini Program cache. Getting the cache of the specified key of embedded webview will not return the cached data of the same key of the Mini Program. ## Sample Code ```javascript my.getStorage({ key: 'currentCity', success: function(res) { my.alert({content: 'Success' + res.data.cityName}); }, fail: function(res){ my.alert({content: res.errorMessage}); } }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | `String` | Yes | Cache data key. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | -------- | --------------- | --------------------------------- | | `data` | `Object/String` | Corresponding content of the key. | ## Usage Notes - This is an asynchronous interface - Storage is isolated between embedded webview and Mini Program - Retrieve data using the same key that was used in `my.setStorage` ## Related Links - [my.setStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/set-storage) - Store data - [my.removeStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/remove-storage) - Remove data - [my.clearStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/clear-storage) - Clear all data # setStorage ## Overview `my.setStorage` stores data with a specified key in the local cache. This will overwrite the original data using the same key. This is an asynchronous interface that supports the isolation of webview-embedded storage and the Mini Program storage. Specifying key storage data in embedded webview does not overlap the data corresponding to the same key of the Mini Program itself. ## Sample Code ```javascript my.setStorage({ key: 'currentCity', data: { cityName: 'London', adCode: '330100', spell: ' London', }, success: function() { my.alert({content: 'Set Success'}); } }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | --------------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | `String` | Yes | Cache data key. | | `data` | `Object/String` | Yes | Data to be cached. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - When a single data is converted into a string, the string length is maximum 200\*1024 - For the same user, the cache of one Mini Program has an upper limit 10MB - This is an asynchronous interface - Storage is isolated between embedded webview and Mini Program - Setting data with an existing key will overwrite the previous value ## Related Links - [my.getStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/get-storage) - Get data - [my.removeStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/remove-storage) - Remove data - [my.clearStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/clear-storage) - Clear all data # removeStorage ## Overview `my.removeStorage` removes cached data from local storage. This is an asynchronous interface. Removing the webview embedded storage data will not remove the storage data of the Mini Program. ## Sample Code ```javascript my.removeStorage({ key: 'currentCity', success: function(){ my.alert({content: 'remove success'}); } }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | `String` | Yes | Cache data key. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - This is an asynchronous interface - Storage is isolated between embedded webview and Mini Program - Removing embedded webview storage does not affect Mini Program storage - If the key does not exist, the operation will still succeed ## Related Links - [my.getStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/get-storage) - Get data - [my.setStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/set-storage) - Store data - [my.clearStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/clear-storage) - Clear all data # clearStorage ## Overview `my.clearStorage` clears the local data cache. This is an asynchronous interface. Clearing the webview embedded storage data will not clear the storage data of the Mini Program. ## Sample Code ```javascript my.clearStorage(); ``` ## Usage Notes - This is an asynchronous interface - Storage is isolated between embedded webview and Mini Program - Clearing embedded webview storage does not affect Mini Program storage - This operation removes all cached data and cannot be undone - Use with caution as it removes all stored key-value pairs ## Related Links - [my.getStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/get-storage) - Get data - [my.setStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/set-storage) - Store data - [my.removeStorage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/storage-apis/remove-storage) - Remove specific data # saveFile ## Overview `my.saveFile` saves a file in a local position. The total capacity of local file size is limited to 10 MB. ## Sample Code ```javascript my.chooseImage({ success: (res) => { my.saveFile({ apFilePath: res.apFilePaths[0], success: (res) => { console.log(JSON.stringify(res)); }, }); }, }); ``` ## Parameters Object type with the following attributes: | Property | Type | Required | Description | | ------------ | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `apFilePath` | `String` | Yes | File path. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | -------- | --------------- | | `apFilePath` | `String` | File save path. | ## Usage Notes - Total capacity of local file storage is limited to 10 MB - The saved file path is returned in the success callback - Use this API to persist temporary files (like those from `my.chooseImage`) ## Related Links - [my.getSavedFileInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-info) - Get saved file info - [my.getSavedFileList](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-list) - Get list of saved files - [my.removeSavedFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/remove-saved-file) - Remove saved file # getFileInfo ## Overview `my.getFileInfo` retrieves information about a file, including its size and an optional digest (hash) for verification. ## Sample Code ```javascript my.getFileInfo({ apFilePath: 'https://resource/apm1953bb093ebd2834530196f50a4413a87.video', digestAlgorithm: 'sha1', success: (res) => { console.log(JSON.stringify(res)); } }); ``` ## Parameters | Property | Type | Required | Description | | ----------------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `apFilePath` | `String` | Yes | File path. | | `digestAlgorithm` | `String` | No | Digest algorithm, supporting `md5` and `sha1`, md5 by default. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | -------- | -------- | -------------- | | `size` | `Number` | File size. | | `digest` | `String` | Digest result. | ## Usage Notes - Supports both `md5` and `sha1` digest algorithms - Default algorithm is `md5` if not specified - The digest can be used for file integrity verification - Works with network URLs and local file paths ## Related Links - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.getSavedFileInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-info) - Get saved file info # getSavedFileInfo ## Overview `my.getSavedFileInfo` retrieves information about a file that was previously saved using `my.saveFile`. The saved address is required to use this API. ## Sample Code ```javascript my.chooseImage({ success: (res) => { console.log(res.apFilePaths[0], 1212); my.saveFile({ apFilePath: res.apFilePaths[0], success: (result) => { console.log(result, 1212); my.getSavedFileInfo({ apFilePath: result.apFilePath, success: (resu) => { console.log(JSON.stringify(resu)); } }); }, }); }, }); ``` ## Parameters Object type with the following attributes: | Property | Type | Required | Description | | ------------ | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `apFilePath` | `String` | Yes | File path. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | -------- | ------------------------------- | | `size` | `Number` | File size. | | `createTime` | `Number` | Timestamp for the created time. | ## Usage Notes - The file must be previously saved using `my.saveFile` - Use the `apFilePath` returned from `my.saveFile` as the input - Returns file size and creation timestamp ## Related Links - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.getSavedFileList](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-list) - Get list of saved files - [my.removeSavedFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/remove-saved-file) - Remove saved file # getSavedFileList ## Overview `my.getSavedFileList` retrieves information about all files that have been saved locally using `my.saveFile`. ## Sample Code ```javascript my.getSavedFileList({ success: (res) => { console.log(JSON.stringify(res)); } }); ``` ## Parameters Object type with the following attributes: | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ---------- | ------ | ----------- | | `fileList` | `List` | File list. | ## File Object Attribute Each file object in the list contains: | Property | Type | Description | | ------------ | -------- | ------------- | | `size` | `Number` | File size. | | `createTime` | `Number` | Created time. | | `apFilePath` | `String` | File path. | ## Usage Notes - Returns a list of all files saved via `my.saveFile` - Each file object includes size, creation time, and path - Use this API to manage locally saved files ## Related Links - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.getSavedFileInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-info) - Get specific file info - [my.removeSavedFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/remove-saved-file) - Remove saved file # removeSavedFile ## Overview `my.removeSavedFile` deletes a file that was previously saved using `my.saveFile`. ## Sample Code ```javascript my.getSavedFileList({ success: (res) => { my.removeSavedFile({ apFilePath: res.fileList[0].apFilePath, success: (res) => { console.log('remove success'); } }); } }); ``` ## Parameters Object type with the following attributes: | Property | Type | Required | Description | | ------------ | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `apFilePath` | `String` | Yes | File path. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - The file must be previously saved using `my.saveFile` - Use the `apFilePath` from `my.getSavedFileList` or `my.saveFile` response - Once removed, the file cannot be recovered - Removing a file frees up storage space from the 10 MB limit ## Related Links - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.getSavedFileList](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-list) - Get list of saved files - [my.getSavedFileInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-saved-file-info) - Get specific file info # openDocument ## Overview `my.openDocument` enables users to preview a PDF file within the mini program. After clicking on the PDF file, the user can preview the file without leaving the mini program. After closing the preview, the user will still be at the current mini program page. ## Sample Code ```javascript my.downloadFile({ url: 'http://documentExample.com/alipay.pdf', success: ({ apFilePath }) => { my.hideLoading(); my.openDocument({ filePath: apFilePath, fileType: 'pdf', success: (res) => { console.log('open document success'); } }); } }); ``` ## Parameters Object type: | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `filePath` | `String` | Yes | Obtain file path via my.downloadFile. | | `fileType` | `String` | Yes | File type. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Legal values for fileType | Value | Description | | ----- | ----------- | | `pdf` | PDF format. | ## Error code | Error code | Description | Solution | | ---------- | -------------------------------------------------------------- | --------------------------------------------------- | | `4011` | File path is invalid or no permission to access incoming path. | Check the incoming file path. | | `4012` | Preview files do not exist. | Make sure files that correspond to file path exist. | | `4013` | File format is not supported. | Currently preview of PDF files is supported. | ## Usage Notes - Currently only PDF file format is supported - File path must be obtained via `my.downloadFile` - Preview opens within the mini program without navigation away - User returns to the same page after closing preview ## Related Links - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.getFileInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/get-file-info) - Get file information # chooseFileFromDisk ## Overview `my.chooseFileFromDisk` allows users to select a file from their device storage. You can view the details of the file or delete the file you have added. Supported types of mini programs: DSL, H5+ ## Sample Code ### DSL ```javascript my.chooseFileFromDisk({ success: (res) => { console.log(res); }, fail: (err) => { console.log(err); }, }); ``` ### H5+ ```javascript AlipayJSBridge.call("chooseFileFromDisk", {}, function (res) { alert("AlipayJSBridge chooseFileFromDisk result:\n" + JSON.stringify(res)); }); ``` ## Parameters Object type with the following attributes: | Property | Type | Required | Description | | ---------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- | | `success` | `Function` | No | The callback function for a successful API call. | | `fail` | `Function` | No | The callback function for a failed API call. | | `complete` | `Function` | No | The callback function used when the API call is completed. This function is always executed no matter the call succeeds or fails. | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | -------- | ------------------------------ | | `apFilePath` | `String` | The temporary local file path. | ## Failure Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | -------------- | -------- | -------------- | | `error` | `Number` | Error code. | | `errorMessage` | `String` | Error message. | ## Error Codes | Error code | Error message | Remark | | ---------- | --------------------------------------------------- | -------------------------------------------------------------------------------------- | | `4` | The JSAPI call is denied. | The mini program that is developed by the merchant/ISV has no right to call the JSAPI. | | `12` | Errors occur when copying the file. | | | `15` | The user cancels the file selection. | | | `16` | The user denies the permission to read the storage. | Android Only. | | `17` | No permission to read the storage. | Android Only. | | `18` | Choosing large file is not supported. | | **Note:** The following list describes the difference between the error code 16 and 17: - **16:** The user denies the permission to read the storage for the current request. ## File Size Limit If you choose a file that is too large, the mini program or the wallet app cannot run properly. For this reason, the file size is limited to 50 MB. When the file size exceeds 50 MB, the error code of 18 is returned, and the corresponding error message is displayed. ## Usage Notes - This API opens a file picker dialog allowing users to select files from their device storage - The selected file path is returned as a temporary local path (`apFilePath`) - The file size limit is 50 MB - larger files will return error code 18 - On Android, storage permissions may be required (error codes 16 and 17) - Use the returned `apFilePath` with other file APIs like `my.uploadFile` or `my.openDocument` ## Related Links - [my.uploadFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/upload-file) - Upload file to server - [my.openDocument](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/open-document) - Open document - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally # getLocation ## Overview `my.getLocation` retrieves the current geographical location of the user, including longitude, latitude, and accuracy information. ## Sample Code ```javascript my.getLocation({ success: (res) => { my.hideLoading(); console.log(res); // Update your location data hasLocation = true; location = formatLocation(res.longitude, res.latitude); }, fail: () => { my.hideLoading(); my.alert({ title: 'location failed' }); }, }); ``` ## Parameters | Property | Type | Required | Description | | -------------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `cacheTimeout` | `Number` | No | Longitude and latitude location cache expiry time in seconds. Default is 30s. Use of cache can speed up location process. Re-location is done upon cache expiry. | | `type` | `Number` | No | 0: default, get the longitude and latitude. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ----------- | -------- | --------------- | | `longitude` | `String` | Longitude. | | `latitude` | `String` | Latitude. | | `accuracy` | `String` | Accuracy, in m. | ## Error Code | Error | Description | Solution | | ----- | ------------------------------------------------------ | ---------------------------------------------- | | `11` | Make sure the location related right has been enabled. | Prompt the user to enable location permission. | | `12` | Network abnormity, try again later. | Prompt the user to check the current network. | | `13` | Location failure, try again later. | - | | `14` | Service location timeout. | Prompt the user to try again. | ## Usage Notes - Requires location permission to be enabled - The `cacheTimeout` parameter can improve performance by caching location data - Default cache expiry is 30 seconds - Returns longitude, latitude, and accuracy in meters - Network connectivity is required for location services ## Related Links - [my.chooseLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/choose-location) - Choose location from map - [my.openLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/open-location) - Open location in map # chooseLocation ## Overview `my.chooseLocation` opens a map interface that allows users to choose a specific location. The selected location's details, including longitude, latitude, name, and address, are returned through the success callback. ## Sample Code ```javascript my.chooseLocation({ success: (res) => { console.log(res); // Use the selected location data const selectedLocation = { name: res.name, address: res.address, latitude: res.latitude, longitude: res.longitude }; }, fail: (error) => { my.alert({ title: 'Failed to choose location' }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ----------- | -------- | ------------------------------------------ | | `name` | `String` | Name of the selected location. | | `address` | `String` | Detailed address of the selected location. | | `latitude` | `Number` | Latitude of the selected location. | | `longitude` | `Number` | Longitude of the selected location. | ## Error Code | Error | Description | Solution | | ----- | ----------------------------------- | ---------------------------------------------- | | `11` | Location permission not enabled. | Prompt the user to enable location permission. | | `12` | Network abnormity, try again later. | Prompt the user to check the current network. | | `13` | User cancelled the selection. | - | ## Usage Notes - Requires location permission to be enabled - Users can search for locations within the map interface - The selected location includes both coordinates and address information - Users can cancel the selection, which will trigger the fail callback ## Related Links - [my.getLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/get-location) - Get current location - [my.openLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/open-location) - Open location in map # openLocation ## Overview `my.openLocation` opens the map application to display a specific location using the provided longitude and latitude coordinates. You can also specify the location name, address, and zoom scale. ## Sample Code ```html ``` ## Parameters | Property | Type | Required | Description | | ----------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `longitude` | `String` | Yes | Longitude of the location to display. | | `latitude` | `String` | Yes | Latitude of the location to display. | | `name` | `String` | No | Name of the location. | | `address` | `String` | No | Detailed address of the location. | | `scale` | `Number` | No | Zoom scale of the map, ranging from 3 to 19. Default is 15. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The success callback is executed when the map is successfully opened. ## Error Code | Error | Description | Solution | | ----- | ----------------------------------- | ----------------------------------------------- | | `11` | Invalid coordinates provided. | Ensure longitude and latitude are valid values. | | `12` | Network abnormity, try again later. | Prompt the user to check the current network. | | `13` | Failed to open map application. | - | ## Usage Notes - Longitude and latitude are required parameters - The `scale` parameter controls the zoom level (3-19), with higher values showing more detail - Default zoom scale is 15 if not specified - The map application will open in a separate view - Providing a name and address helps users identify the location more easily ## Related Links - [my.getLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/get-location) - Get current location - [my.chooseLocation](https://superqi-dev-docs.pages.dev/api-reference/jsapi/location-apis/choose-location) - Choose location from map # request ## Overview `my.request` initiates a network request from a Mini Program. The API supports GET and POST methods and returns a RequestTask object that can be used to abort the request. ## Notes 1. Configure the domain name whitelist at first under `Mini Program > Configuration > Server Domain Whitelist`. The Mini Program can only communicate with the domain names in the whitelist during the API calls: `my.request` (send HTTP request), `my.uploadFile` (upload file), and `my.downloadFile` (download file). 2. During the Mini Program development, preview and debugging stages, you can select whether to ignore the `httpRequest` domain name validity check under `Details > Domain name information`. If yes, the domain name validity will not be checked in the simulator, preview and debug versions. Before the Mini Program goes online, you must maintain the domain names in the whitelist, otherwise, the domain names cannot be effective in the official release. ::callout{type="info"} **Important:** `my.request` request header is `{'content-type': 'application/json'}` by default, instead of `{'content-type': 'application/x-www-form-urlencoded'}`. :: ## Sample Code ```javascript my.request({ url: 'https://httpbin.org/post', method: 'POST', data: { from: 'Mini Program', production: 'JSAPI', }, dataType: 'json', success: function(res) { my.alert({content: 'success'}); }, fail: function(res) { my.alert({content: 'fail'}); }, complete: function(res) { my.hideLoading(); my.alert({content: 'complete'}); } }); const task = my.request({url: 'https://httpbin.org/post'}); task.abort(); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | `String` | Yes | Target server url. | | `headers` | `Object` | No | Set the request HTTP header. The default value is `{'content-type': 'application/json'}`. | | `method` | `String` | No | The default value is GET. Both GET and POST are supported. | | `data` | `Object` | No | Request parameter. | | `timeout` | `Number` | No | Timeout period in ms. The default value is 30000. | | `dataType` | `String` | No | Expected format of the returned data. The following formats are supported: :br • `json`:br • `text`:br • `base64`:br:br The default format is JSON. If an exception occurs, it may not be JSON in the callback. | | `success` | `Function` | No | The callback function for a successful API call. | | `fail` | `Function` | No | The callback function for a failed API call. | | `complete` | `Function` | No | The callback function used when the API call is completed. This function is always executed no matter the call succeeds or fails. | ## Data Parameter Description Data transferred to the server is eventually expressed in String. If the type is not String, the data will be converted into String. Conversion rules are: - If the method is `GET`, the data will be converted into query string: `encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...` - If the method is `POST` and the `headers['content-type']` is `application/json`, the data will be JSON serialized. - If the method is `POST` and the `headers['content-type']` is `application/x-www-form-urlencoded`, the data will be converted into query string: `encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...` ## Success Callback Function The type of the incoming parameter is Object with the following attributes: | Property | Type | Description | | --------- | -------- | ---------------------------------------------------------------------------- | | `data` | `String` | Response data. The format depends on the value of `dataType` in the request. | | `status` | `Number` | Response code. | | `headers` | `Object` | Response header. | ## Error Code | Error | Description | | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `2` | Incorrect parameter. Check whether the URL is in HTTPS format and all parameters are correct. | | `4` | Not authorized to call the interface. The error might result from the following: :br • The server domain is not configured. In this case, configure the domain whitelist under `Mini Program > Configuration > Server Domain Whitelist`. The mini program can only communicate with the domain names in the whitelist when calling the `my.request` and `my.uploadFile` APIs. If the server domain whitelist is updated, the whitelist comes effective only when a new version of the mini program is published. :br • Errors occur with your account and you cannot login to the mini program editor. In this case, when you debug in the Mini Program studio, select `ignore HttpRequest domain name validity check` or `ignore Webview domain name validity check` under `Details > Domain name information`, and then preview the debugging request. Check whether the HTTP request domain name is incorrect. | | `12` | Network error. | | `13` | Timeout. | | `14` | Decoding failure. | | `19` | HTTP error. | | `20` | Request stopped/service end traffic limit. | **Note:** The error code of 14 might be returned in the following cases: - When the value of `dataType` is `json`, the Mini Program framework firstly perform the `JSON.parse` operation on the returned results. If the parsing fails, the error code of 14 is returned. - When the value of `dataType` is `text` and the returned content has a bad format, the error code of 14 is returned. To solve the error, check whether the `dataType` setting is incorrect firstly. ## Return Value ### RequestTask Network request task object. **Method:** `RequestTask.abort()` **Note:** If `Not authorized to call the interface` is returned, configure the domain whitelist under `Mini Program > Configuration > Server Domain Whitelist` in the mini program platform. ## Usage Notes - Domain whitelist must be configured before making requests - Default content-type is `application/json`, not `application/x-www-form-urlencoded` - Default timeout is 30000ms (30 seconds) - The request can be aborted using the returned RequestTask object - Both GET and POST methods are supported ## Related Links - [my.uploadFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/upload-file) - Upload file (if available) - [my.downloadFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/download-file) - Download file # downloadFile ## Overview `my.downloadFile` downloads a file from a remote server to a local location. The downloaded file path is returned in the success callback and can be used with other APIs like `my.previewImage` or `my.openDocument`. ## Sample Code ```javascript my.downloadFile({ url: 'http://img.example.com/example.jpg', success: ({ apFilePath }) => { my.previewImage({ urls: [apFilePath], }); }, fail: (res) => { my.alert({ content: res.errorMessage || res.error, }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `url` | `String` | Yes | Downloading file address. | | `header` | `Object` | No | HTTP request Header. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | -------- | -------------------------------- | | `apFilePath` | `String` | Temporary file storage location. | ## Error Code | Error | Description | | ----- | ------------------- | | `12` | Downloading failed. | | `13` | No right. | ## Usage Notes - The downloaded file is stored in a temporary location - Use the returned `apFilePath` with APIs like `my.previewImage`, `my.openDocument`, or `my.saveFile` - The file must be accessible via HTTP/HTTPS - Custom headers can be set via the `header` parameter - The temporary file may be cleaned up by the system, use `my.saveFile` to persist it ## Related Links - [my.request](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/request) - Network request - [my.saveFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/save-file) - Save file locally - [my.openDocument](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/open-document) - Open document - [my.previewImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/preview-image) - Preview image # uploadFile ## Overview `my.uploadFile` uploads the local resource to the server. Supported types of mini programs: DSL, H5+ ## Sample Code ```javascript my.uploadFile({ url: "Please use your own server address", fileType: "image", fileName: "file", filePath: "...", success: (res) => { my.alert({ content: "Upload success", }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ------------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | `String` | Yes | Address of the developer server. | | `filePath` | `String` | Yes | Local location of the file resource to be uploaded. | | `fileName` | `String` | Yes | Filename, also the corresponding key. The developer uses this key at the server side to get the file binary content. | | `fileType` | `String` | Yes | The file type of the uploaded file. :br:br**Note:** This parameter is only used for backward compatibility with older super app versions. If you have previously set a specific value, no changes are necessary. If not, you can set the value to `image` for any file type. | | `header` | `Object` | No | The HTTP request header. You can specify this parameter using any common headers. :br:br**Note:** By default, the `Content-Type` request header is set to `multipart/form-data`. Do not change this value, otherwise your request will fail. | | `formData` | `Object` | No | Other additional form data in the HTTP request. | | `timeout` | `Object` | No | The timeout period of your request in milliseconds. The default value is `60000`. | | `hideLoading` | `Boolean` | No | Whether to hide a loading icon during the uploading process. Valid values are: :br • `true`: Hide a loading icon. :br • `false`: Show a loading icon. :br:br If not specified, the value defaults to `false`. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------ | -------- | -------------------------------- | | `data` | `String` | Data returned from the server. | | `statusCode` | `String` | HTTP status code. | | `header` | `Object` | Header returned from the server. | ## Error Code | Error | Description | | ----- | ---------------------- | | `11` | File nonexistent. | | `12` | File uploading failed. | | `13` | No right. | ## Usage Notes - Domain whitelist must be configured before uploading files - The `fileName` parameter specifies the form field name that the server will use to access the file - The default `Content-Type` is `multipart/form-data` - do not change this value - Use `formData` to send additional data along with the file - The default timeout is 60000ms (60 seconds) - Set `hideLoading: true` to prevent the default loading indicator from appearing - The file path should be obtained from other APIs like `my.chooseFileFromDisk` or `my.chooseImage` ## Example Usage ### Complete Example with Error Handling ```javascript my.uploadFile({ url: "https://your-server.com/api/upload", filePath: filePath, // From my.chooseFileFromDisk fileName: "file", fileType: "PDF", formData: { userId: "user-123", documentType: "invoice", timestamp: new Date().toISOString(), }, success: (uploadRes) => { console.log("Upload successful"); console.log("Status Code:", uploadRes.statusCode); console.log("Response Data:", uploadRes.data); my.alert({ title: "Success", content: "File uploaded successfully!", }); }, fail: (error) => { console.error("Upload failed:", error); let errorMessage = "Upload failed"; if (error.error === 11) { errorMessage = "File does not exist"; } else if (error.error === 12) { errorMessage = "File uploading failed"; } else if (error.error === 13) { errorMessage = "No upload permission"; } my.alert({ title: "Upload Error", content: errorMessage, }); }, complete: () => { console.log("Upload process complete"); }, }); ``` ## Related Links - [my.chooseFileFromDisk](https://superqi-dev-docs.pages.dev/api-reference/jsapi/file-apis/choose-file-from-disk) - Choose file from device - [my.request](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/request) - Network request - [my.downloadFile](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/download-file) - Download file - [my.chooseImage](https://superqi-dev-docs.pages.dev/api-reference/jsapi/media-apis/choose-image) - Choose image # share ## Overview `AlipayJSBridge.call("qicardShareAppMessage", ...)` shares a Miniapp message. You configure the share content (title/description/path/image) and receive the share result in the `success` callback. Supported types of mini programs: H5+ ## Sample Code ```javascript AlipayJSBridge.call("qicardShareAppMessage", { title: "Demo Share Title", desc: "Shared from Super Qi miniapp. Tap to open!", path: "share.html", success: (res) => { console.log("[from mini app], share call succeeded: ", JSON.stringify(res)); my.alert({ content: "success" + JSON.stringify(res) }); }, fail: (res) => { console.log("[from mini app], share call fail: ", JSON.stringify(res)); my.alert({ content: "fail" + JSON.stringify(res) }); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | -------- | -------- | -------------- | | `title` | `String` | Yes | share title | | `desc` | `String` | No | share desc | | `path` | `String` | No | share path | | `imageUrl` | `String` | No | share imageUrl | ## Success Callback Function The incoming parameter is an Object with the following attributes: | Property | Type | Description | | ------------- | --------- | --------------------------------------------------------------- | | `shareResult` | `Boolean` | The result that indicates whether if the sharing is successful. | ## Failure Callback Function The incoming parameter is an Object that contains error information (the exact fields may vary by runtime/version). ## Usage Notes - `title` is required; provide enough context so users know what they will open after sharing. - `path` and `imageUrl` are optional, but recommended to improve click-through. - Use this API only in the H5+ runtime where `AlipayJSBridge` is available. # getSystemInfo ## Overview `my.getSystemInfo` retrieves the system information of the current device, including model, operating system version, screen resolution, and other device characteristics. ## Sample Code ```javascript my.getSystemInfo({ success: (res) => { console.log(res.model); console.log(res.pixelRatio); console.log(res.windowWidth); console.log(res.windowHeight); console.log(res.language); console.log(res.version); console.log(res.platform); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ----------------- | -------- | ------------------------------- | | `model` | `String` | Device model. | | `pixelRatio` | `Number` | Device pixel ratio. | | `windowWidth` | `Number` | Window width in px. | | `windowHeight` | `Number` | Window height in px. | | `language` | `String` | System language. | | `version` | `String` | Version number. | | `storage` | `String` | Storage capacity of the device. | | `currentBattery` | `String` | Current battery level. | | `system` | `String` | System version. | | `platform` | `String` | System platform. | | `titleBarHeight` | `String` | Title bar height. | | `statusBarHeight` | `String` | Status bar height. | | `screenWidth` | `Number` | Screen width in px. | | `screenHeight` | `Number` | Screen height in px. | | `brand` | `String` | Device brand. | | `fontSizeSetting` | `Number` | User font size setting. | | `app` | `String` | Host app name. | | `safeArea` | `Object` | Safe area information. | ## Usage Notes - Asynchronously obtains comprehensive device information via the `success` callback - All measurements in pixels (px) - Returns both window and screen dimensions - Useful for responsive design and device-specific features - Safe area information helps with notch and gesture bar handling ## Related Links - [my.getNetworkType](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-network-type) - Get network type - [my.getBatteryInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-battery-info) - Get battery information # getNetworkType ## Overview `my.getNetworkType` retrieves the current network type of the device, such as WiFi, 2G, 3G, 4G, or offline status. ## Sample Code ```javascript my.getNetworkType({ success: (res) => { console.log(res.networkAvailable); console.log(res.networkType); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Success Callback Function The incoming parameter is of the Object type with the following attributes: | Property | Type | Description | | ------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `networkAvailable` | `Boolean` | Whether the network is available. | | `networkType` | `String` | Network type values: :br • `WIFI`: WiFi network :br • `2G`: 2G network :br • `3G`: 3G network :br • `4G`: 4G network :br • `UNKNOWN`: Unknown network :br • `NOTREACHABLE`: No network :br • `NONE`: None | ## Usage Notes - Returns current network connectivity status - Useful for optimizing data usage based on connection type - Can detect when device is offline - Network type helps determine appropriate content quality and caching strategies ## Related Links - [my.getSystemInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-system-info) - Get system information - [my.request](https://superqi-dev-docs.pages.dev/api-reference/jsapi/network-apis/request) - Network request # Clipboard ## Overview The clipboard APIs allow you to read from and write to the system clipboard, enabling copy and paste functionality within your mini program. ## my.getClipboard Retrieves the current content of the clipboard. ### Sample Code ```javascript my.getClipboard({ success: (res) => { my.alert({ content: res.text }); }, }); ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ### Success Callback Function | Property | Type | Description | | -------- | -------- | ------------------ | | `text` | `String` | Clipboard content. | ## my.setClipboard Sets text content to the clipboard. ### Sample Code ```javascript my.setClipboard({ text: 'copy content', success: () => { my.alert({ content: 'Copied successfully' }); }, }); ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | -------------------------------------------------------------------------------------------- | | `text` | `String` | Yes | The text content to copy to clipboard. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (to be executed upon either call success or failure). | ## Usage Notes - `my.setClipboard` overwrites any existing clipboard content - `my.getClipboard` retrieves text content only - Clipboard operations are synchronous from the user's perspective - Useful for implementing copy-to-clipboard features - Consider showing user feedback when clipboard operations complete ## Related Links - [my.alert](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/alert) - Show alert dialog - [my.showToast](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/show-toast) - Show toast message # getBatteryInfo ## Overview `my.getBatteryInfo` asynchronously obtains the battery level and the charging state of the current device. No input parameters are required. ## Sample Code ```javascript my.getBatteryInfo({ success: (res) => { my.alert({ content: "Battery: " + res.level + "%, Charging: " + res.isCharging, }); }, fail: (err) => { my.alert({ content: "Inquiry failed: " + JSON.stringify(err) }); }, complete: () => { console.log("Complete callback"); }, }); ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (executed whether the call succeeds or fails). | ## Success Callback Function The incoming parameter is an Object with the following attributes: | Property | Type | Description | | ------------ | --------- | -------------------------------------------- | | `level` | `Number` | Battery level of the current device (0–100). | | `isCharging` | `Boolean` | Whether the device is currently charging. | ## Related Links - [my.getSystemInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-system-info) - Get system information - [my.getNetworkType](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-network-type) - Get network type # Screen Brightness ## Overview The screen brightness APIs let you read and set the device screen brightness. Use `my.getScreenBrightness` to read the current value and `my.setScreenBrightness` to set it. Brightness is in the range 0–1. ## my.getScreenBrightness Gets the current screen brightness value. ### Sample Code ```javascript my.getScreenBrightness({ success: (res) => { my.alert({ content: "Current screen brightness: " + res.brightness, }); }, }); ``` ### Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (executed whether the call succeeds or fails). | ### Success Callback Function | Property | Type | Description | | ------------ | -------- | ------------------------------------- | | `brightness` | `Number` | Current screen brightness, range 0–1. | ## my.setScreenBrightness Sets the screen brightness. ### Sample Code ```javascript // Set brightness to 0.5 (50%) my.setScreenBrightness({ brightness: 0.5, success: () => { my.alert({ content: "Brightness updated" }); }, }); ``` ### Parameters | Property | Type | Required | Description | | ------------ | ---------- | -------- | ------------------------------------------------------------------------------------- | | `brightness` | `Number` | Yes | Screen brightness to set, range 0–1. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (executed whether the call succeeds or fails). | ## Usage Notes - Brightness value must be between 0 and 1. - Useful for in-app readers or night mode where you want to adjust screen brightness. - Getting brightness on load helps restore the user’s previous setting. ## Related Links - [my.getSystemInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-system-info) - Get system information - [my.vibrate](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/vibrate) - Device vibration # addPhoneContact ## Overview `my.addPhoneContact` lets users add a contact to their phone—either by filling a form (create new or add to existing) or by passing contact data from your Mini Program. All contact fields are optional; only the ones you provide are used. ## Sample Code ### HTML ```html ``` ### JavaScript ```javascript function addContact() { if (!my.canIUse("addPhoneContact")) { my.alert({ title: "Client version too low", content: "my.addPhoneContact() requires a higher version.", }); return; } my.addPhoneContact({ nickName: "Baking July", lastName: "Last", middleName: "Middle", firstName: "First", remark: "This is remarks", mobilePhoneNumber: "13000000000", success: (res) => { my.alert({ content: "addPhoneContact response: " + JSON.stringify(res) }); }, fail: (res) => { my.alert({ content: "addPhoneContact failed: " + JSON.stringify(res) }); }, }); } ``` ## Parameters Object type with the following attributes. All contact fields are optional. | Property | Type | Required | Description | | ----------------------- | ---------- | -------- | --------------------------------------- | | `photoFilePath` | `String` | No | Local file path of avatar. | | `nickName` | `String` | No | Nickname. | | `lastName` | `String` | No | Surname. | | `middleName` | `String` | No | Middle name. | | `firstName` | `String` | No | First name. | | `remark` | `String` | No | Remarks. | | `mobilePhoneNumber` | `String` | No | Cell number. | | `homePhoneNumber` | `String` | No | Home phone. | | `workPhoneNumber` | `String` | No | Work phone. | | `homeFaxNumber` | `String` | No | Home fax. | | `workFaxNumber` | `String` | No | Work fax. | | `hostNumber` | `String` | No | Company phone number. | | `addressCountry` | `String` | No | Country in contact address. | | `addressState` | `String` | No | Province in contact address. | | `addressCity` | `String` | No | City in contact address. | | `addressStreet` | `String` | No | Street in contact address. | | `addressPostalCode` | `String` | No | Postcode in contact address. | | `workAddressCountry` | `String` | No | Country in work address. | | `workAddressState` | `String` | No | Province in work address. | | `workAddressCity` | `String` | No | City in work address. | | `workAddressStreet` | `String` | No | Street in work address. | | `workAddressPostalCode` | `String` | No | Postcode in work address. | | `homeAddressCountry` | `String` | No | Country in home address. | | `homeAddressState` | `String` | No | Province in home address. | | `homeAddressCity` | `String` | No | City in home address. | | `homeAddressStreet` | `String` | No | Street in home address. | | `homeAddressPostalCode` | `String` | No | Postcode in home address. | | `organization` | `String` | No | Company. | | `title` | `String` | No | Job title. | | `email` | `String` | No | Email. | | `url` | `String` | No | Website. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion. | ::prose-note Depending on the contact app and device ROM, some fields may not support emoji or kaomoji; in such cases the option is ignored. :: ## Return Value **Success:** Callback receives an object with `success: true`. **Failure:** Callback receives an error object. Common cases: | Error | Description | | ----- | ----------------------------------------------- | | `11` | User cancelled the operation. | | `2` | Call failure; detail includes more information. | ## Related Links - [my.makePhoneCall](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/make-phone-call) - Make a phone call - [my.choosePhoneContact](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/choose-phone-contact) - Choose a phone contact # makePhoneCall ## Overview `my.makePhoneCall` opens the device dialer and initiates a call to the specified phone number. ::warning The Mini Program Studio simulator does not support this API. Use a real device to debug. :: ## Sample Code ```javascript function makePhoneCall() { my.makePhoneCall({ number: "00000", }); } ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | --------------------------------------- | | `number` | `String` | Yes | Phone number to call. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion. | ## Usage Notes - The system dialer is used; the user can cancel or complete the call there. - Simulator may show an "is not a function" error; test on a real device. ## Related Links - [my.addPhoneContact](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/add-phone-contact) - Add phone contact - [my.choosePhoneContact](https://superqi-dev-docs.pages.dev/api-reference/jsapi/ui-apis/choose-phone-contact) - Choose a phone contact # scan ## Overview `my.scan` opens the built-in scanner to read QR codes or barcodes. You can choose scan type (QR or bar) and whether to hide the album entry so the user scans only with the camera. ## Sample Code ```javascript function scan() { my.scan({ type: "qr", success: (res) => { my.alert({ title: "Scanned", content: res.code || res.qrCode || res.barCode, }); }, fail: (err) => { my.alert({ content: "Scan failed: " + JSON.stringify(err) }); }, }); } ``` ## Parameters | Property | Type | Required | Description | | ----------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | `type` | `String` | No | Scan type (default `qr`): :br • `qr` – QR code :br • `bar` – Barcode | | `hideAlbum` | `Boolean` | No | If `false`, user can pick an image from the album to scan. If `true`, only camera scan is used. Default `false`. | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion. | ## Success Callback Function The success callback receives an Object with: | Property | Type | Description | | --------- | -------- | -------------------------------------- | | `code` | `String` | Data returned from scanning (generic). | | `qrCode` | `String` | QR code data returned from scanning. | | `barCode` | `String` | Barcode data returned from scanning. | ## Error Codes | Error | Description | | ----- | ------------------ | | `10` | User cancelled. | | `11` | Operation failure. | ## Related Links - [my.getSystemInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-system-info) - Get system information - [my.vibrate](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/vibrate) - Device vibration # vibrate ## Overview `my.vibrate` triggers the device vibration. Use it for haptic feedback on button press or to get the user’s attention. ## Sample Code ```javascript function vibrate() { my.vibrate({ success: () => { my.alert({ title: "Vibration on" }); }, fail: (err) => { console.log("Vibrate failed", err); }, }); } ``` ## Parameters | Property | Type | Required | Description | | ---------- | ---------- | -------- | ------------------------------------------------------------------------------------- | | `success` | `Function` | No | Callback function upon call success. | | `fail` | `Function` | No | Callback function upon call failure. | | `complete` | `Function` | No | Callback function upon call completion (executed whether the call succeeds or fails). | ## Usage Notes - No input parameters are required; calling the API triggers a short vibration. - Useful for confirming user actions (e.g. long-press, success feedback). ## Related Links - [my.getBatteryInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-battery-info) - Get battery information - [my.getSystemInfo](https://superqi-dev-docs.pages.dev/api-reference/jsapi/device-apis/get-system-info) - Get system information # Common Error Codes ## Overview Error codes returned by Open APIs fall into two groups: - **Common error codes** — shared across all Open APIs. They are listed on this page. - **API-specific error codes** — listed in the **Error Codes** section of each endpoint's own page. When an endpoint references the "Common error codes", it refers to the tables below. ## Authentication & Signature | resultStatus | resultCode | resultMessage | | ------------ | ---------------------- | ------------------------------ | | `F` | `KEY_NOT_FOUND` | The key is not found. | | `F` | `CLIENT_INVALID` | The client is invalid. | | `F` | `INVALID_SIGNATURE` | The signature is invalid. | | `F` | `INVALID_ACCESS_TOKEN` | The access token is not valid. | | `F` | `EXPIRED_ACCESS_TOKEN` | The access token is expired. | ## Request & Transport | resultStatus | resultCode | resultMessage | | ------------ | --------------------------- | -------------------------------------------------------------------------------- | | `F` | `METHOD_NOT_SUPPORTED` | The server does not implement the requested HTTP method. | | `F` | `MEDIA_TYPE_NOT_ACCEPTABLE` | The server does not implement the media type that can be accepted by the client. | | `F` | `REPEAT_REQ_INCONSISTENT` | A repeated request is inconsistent with the original request. | ## Partner / Merchant | resultStatus | resultCode | resultMessage | | ------------ | ---------------------------- | ---------------------------------- | | `F` | `PARTNER_NOT_EXIST` | The partner does not exist. | | `F` | `PARTNER_STATUS_ABNORMAL` | The partner status is abnormal. | | `F` | `PARTNER_BALANCE_NOT_ENOUGH` | The partner balance is not enough. | ## System | resultStatus | resultCode | resultMessage | | ------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `U` | `UNKNOWN_EXCEPTION` | An API calling failed, which is caused by unknown reasons. Retry idempotently or query the result status — never assume success or failure based on a `U` response. | # Deep Links Deep links allow you to directly navigate users to specific content within the Super Qi app. This guide covers the deep link format specification and how to integrate them into your systems. ## Deep Link Format The deep link general structure is as follows: ```bash qicardwallet://qicard/deeplink.htm?action=& ``` ### H5+ Deeplink Format For opening H5+ Miniapps and passing data to them, use the following structure: ```bash qicardwallet://qicard/deeplink.htm?action=miniapp&miniappId=[0]&_griver_appended_url_part=[1] ``` ::prose-note Fields explanation 1. Use the Miniapp ID, obtained from the Miniapps console. 2. This part consists of the URL path, query string and fragment :: ## Integration & Usage As this is a **URI** and not a **URL** ([What's the difference?](https://www.hostinger.com/tutorials/uri-vs-url){rel="nofollow"}), we can't share it with users directly. However, we can use another approach where we direct the user to the Deep Link URI from a custom web page. ### Sample JavaScript Code The whole idea is to redirect the user visiting our web page to the Deep Link URI using this simple snippet: ```js const url = `qicardwallet://qicard/deeplink.htm?action=miniapp&miniappId=${appID}&_griver_appended_url_part=${pathAndQuery}` window.onload = () => { window.location.replace(url); } ``` ### Advanced Handling We always strive for better user experience. Since the link would be publicly accessible, we can take a couple of extra steps to enhance the user's interaction with our system. #### Users With Super Qi Not Installed If the user does not have Super Qi installed, then the `window.location.replace` will not work, so we can introduce a delay to redirect the user to the store page for their respective platform: ```js const url = `qicardwallet://qicard/deeplink.htm?action=miniapp&miniappId=${appID}&_griver_appended_url_part=${pathAndQuery}` const config = { timeout: 5 * 1000, appStoreUrl: "https://apps.apple.com/app/id1450079855", playStoreUrl: "https://play.google.com/store/apps/details?id=iq.qicard.qipay.prod" } window.onload = () => { window.location.replace(url); setTimeout(() => { if (/android/i.test(navigator.userAgent)) { window.location.replace(config.playStoreUrl); } else if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { window.location.replace(config.appStoreUrl); } }, config.timeout); } ``` ::prose-note If a user is opening the page from PC, we can redirect them to a page with a QR code they can scan to take them to the first page :: ## Ready Implementation You can use our own standard implementation for supporting deep links: {rel="nofollow"} ### Usage Example ```bash https://deeplink.qi.iq/[0]/[1] ``` ::prose-note 1. Your Miniapp ID obtained from the [Miniapps console](https://miniapps.qi.iq/console){rel="nofollow"} 2. Your path and query params :: ### Working Examples If you have the UAT build of Super Qi, try the following link on your pc and phone: :br{rel="nofollow"} If you're running the store version of Super Qi then open this link: :br{rel="nofollow"} ::prose-note The trailing forward slash (`/`) is mandatory :: # AI Integration This documentation is optimized for use with AI tools and Large Language Models (LLMs). You can use our documentation as context for AI assistants to help with your Super Qi Miniapp development. ## Available AI-Optimized Files We provide two static text files that contain the complete documentation in an AI-friendly format: - **`/llms.txt`** - Condensed version of the documentation - **`/llms-full.txt`** - Full comprehensive documentation with complete details ## How to Use ### With ChatGPT, Claude, or Other AI Chats 1. Copy the documentation URL for your environment: - **Condensed version**: `https://superqi-dev-docs.pages.dev/llms.txt` - **Full version**: `https://superqi-dev-docs.pages.dev/llms-full.txt` 2. In your AI chat, say: ```text Please read https://superqi-dev-docs.pages.dev/llms.txt and help me with Super Qi Miniapp development ``` 3. The AI will fetch the documentation and use it to answer your questions ### Model Context Protocol (MCP) - To Be Implemented An MCP (Model Context Protocol) server for Super Qi documentation is currently in development and will be deployed soon. This will provide a more seamless integration experience, allowing AI assistants to directly access and query the documentation through the MCP protocol. Note that MCP requires a server component, while the current documentation solution is plain and simple, using only frontend static files. ### Example Queries Once the AI has loaded the documentation, you can ask questions like: - "How do I implement cashier payment in my Miniapp?" - "What's the difference between UAT and production credentials?" - "Show me how to use the authentication flow" - "Help me set up deep links for my Miniapp" - "What APIs are available for payment integration?" - "How do I handle user authentication tokens?" ## Use Cases ### Quick Problem Solving Ask the AI to help debug issues or explain specific concepts from the documentation without manually searching through multiple pages. ### Code Examples Request code snippets and implementation examples based on the API reference and guides in the documentation. ### Learning & Onboarding New team members can use AI to get instant answers while learning the Super Qi platform, making onboarding faster. ::warning While AI can be incredibly helpful, always verify critical implementation details against the official documentation, especially for security-sensitive features like authentication and payments. :: # Overview Super Qi uses **RSA256 digital signatures** to sign all webhook notifications and API responses. Validating these signatures is critical to ensure that: - The request actually came from Super Qi (authentication) - The data has not been tampered with (integrity) - Your application processes only legitimate payment notifications ::warning **Always validate signatures before processing webhook data.** Skipping signature validation exposes your application to security risks including fraudulent payment notifications and data manipulation. :: ## When to Validate Signatures ### Webhooks (Incoming from Super Qi) **Always validate** signatures for webhook notifications including: - Payment notifications - Refund notifications - Order status updates - Any asynchronous callbacks from Super Qi ### Webhook Source IP Addresses If your infrastructure requires IP whitelisting, webhook calls from Super Qi will originate from the following IP addresses: - `8.209.108.80` - `47.254.141.238` - `47.254.132.7` ::prose-note Ensure these IPs are whitelisted in your firewall or security group settings to receive webhook notifications. :: ## Signature Format Super Qi sends signatures in the `Signature` HTTP header with this format: ```text Signature: algorithm=RSA256, keyVersion=2, signature= ``` **Components:** - `algorithm` - Always `RSA256` (SHA256withRSA) - `keyVersion` - Version number of the public key to use - `signature` - Base64-encoded RSA signature ::prose-note The `keyVersion` indicates which Super Qi public key to use for verification. Make sure you're using the correct public key version that matches the signatures you receive. :: ## Validation Process ### Step 1: Extract Required Headers Extract these headers from the webhook request: ```go clientID := request.Header.Get("Client-Id") requestTime := request.Header.Get("Request-Time") signatureHeader := request.Header.Get("Signature") ``` ### Step 2: Read the Request Body ```go bodyBytes, err := io.ReadAll(request.Body) if err != nil { return err } bodyString := string(bodyBytes) ``` ::warning **Important:** Read the raw body bytes exactly as received. Do not parse, format, or modify the JSON before validation. :: ### Step 3: Construct Content to be Validated Build the content string that was signed by Super Qi: **Format:** ```text .. ``` **Example:** ```go httpMethod := "POST" path := "/api/payment/webhook" signContent := fmt.Sprintf("%s %s\n%s.%s.%s", httpMethod, path, clientID, requestTime, bodyString, ) ``` **Result:** ```text POST /api/payment/webhook .. ``` ### Step 4: Parse the Signature Header Extract the base64-encoded signature from the header: ```go func parseSignature(signatureHeader string) (string, error) { parts := strings.Split(signatureHeader, ",") for _, part := range parts { part = strings.TrimSpace(part) if strings.HasPrefix(part, "signature=") { return strings.TrimPrefix(part, "signature="), nil } } return "", errors.New("signature not found in header") } signatureBase64, err := parseSignature(signatureHeader) if err != nil { return err } ``` ### Step 5: Decode the Signature ```go signature, err := base64.StdEncoding.DecodeString(signatureBase64) if err != nil { return fmt.Errorf("failed to decode signature: %v", err) } ``` ### Step 6: Verify the Signature Use the Super Qi public key to verify: ```go import ( "crypto" "crypto/rsa" "crypto/sha256" ) // Hash the sign content hash := sha256.Sum256([]byte(signContent)) // Verify using Super Qi's public key err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash[:], signature) if err != nil { return fmt.Errorf("signature verification failed: %v", err) } // Signature is valid! ``` ## Complete Example Here's a complete Go implementation: ```go package webhook import ( "crypto" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" "io" "net/http" "os" "strings" ) type SignatureValidator struct { publicKey *rsa.PublicKey } func NewSignatureValidator(publicKeyPath string) (*SignatureValidator, error) { publicKey, err := loadPublicKey(publicKeyPath) if err != nil { return nil, err } return &SignatureValidator{publicKey: publicKey}, nil } func loadPublicKey(path string) (*rsa.PublicKey, error) { pemData, err := os.ReadFile(path) if err != nil { return nil, err } block, _ := pem.Decode(pemData) if block == nil { return nil, errors.New("failed to parse PEM block") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } rsaPub, ok := pub.(*rsa.PublicKey) if !ok { return nil, errors.New("not an RSA public key") } return rsaPub, nil } func (v *SignatureValidator) ValidateWebhook( r *http.Request, path string, ) error { // Extract headers clientID := r.Header.Get("Client-Id") requestTime := r.Header.Get("Request-Time") signatureHeader := r.Header.Get("Signature") if clientID == "" || requestTime == "" || signatureHeader == "" { return errors.New("missing required headers") } // Read body bodyBytes, err := io.ReadAll(r.Body) if err != nil { return err } // Construct sign content signContent := fmt.Sprintf("POST %s\n%s.%s.%s", path, clientID, requestTime, string(bodyBytes), ) // Parse signature signatureBase64, err := parseSignatureHeader(signatureHeader) if err != nil { return err } // Decode signature signature, err := base64.StdEncoding.DecodeString(signatureBase64) if err != nil { return fmt.Errorf("failed to decode signature: %v", err) } // Hash sign content hash := sha256.Sum256([]byte(signContent)) // Verify signature err = rsa.VerifyPKCS1v15(v.publicKey, crypto.SHA256, hash[:], signature) if err != nil { return fmt.Errorf("signature verification failed: %v", err) } return nil } func parseSignatureHeader(header string) (string, error) { parts := strings.Split(header, ",") for _, part := range parts { part = strings.TrimSpace(part) if strings.HasPrefix(part, "signature=") { return strings.TrimPrefix(part, "signature="), nil } } return "", errors.New("signature not found in header") } ``` **Usage:** ```go func handleWebhook(w http.ResponseWriter, r *http.Request) { validator, err := NewSignatureValidator("path/to/superqi_public_key.pem") if err != nil { http.Error(w, "Server configuration error", 500) return } err = validator.ValidateWebhook(r, "/api/payment/webhook") if err != nil { log.Printf("Invalid signature: %v", err) http.Error(w, "Invalid signature", 401) return } // Signature is valid - safe to process webhook // ... process payment notification } ``` ## Public Key Management ### Obtaining the Public Key Use the RSA public key that matches your environment for signature verification (PEM format). Make sure you use the **UAT** key when validating signatures from the UAT environment and the **Production** key when validating signatures from production. #### UAT Public Key ```text -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA249W/txwtMNVMw2jv5uN u06atBtlvOon+EYopcBV1WzSKXsllq8k+5GEKaRw2n2A2Ix7IalDLfxf5cbPLLnC IdqyPEfeoQBN2xBL2m0cjFFoPL0JJIHHHvJs75MVR8bpUFuipGOxK+a4316mMlRv eX4F+YmpCJFXoHgJzJrQlglRNO/HZYQVaP3JRZg4KNSg1o2esxgaCImhCt8owegw ou9GgYlEYpQjlQYSAgGill36nIMEoUqUqVYUA0o4sOLYPb2hepUROED8Zuc0mW/q oGVQBihuZInhM2UOiuuw/tP/cpmNbMR9SeCbEDUt9HHd60KpXciNim96tz1zIZQv jQIDAQAB -----END PUBLIC KEY----- ``` #### Production Public Key ```text -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvTCsasBhpdL0juG1mql4 8efGDM//c/GBcVs/weV0BQKQ6fdBYbgLZ0uR+OSsd4krEw3CltsQKUjE5B3VSjD1 xB2aYNe2uF7xIdqPlYlYGnXiQUTuXtOuNQMc9myFGZlhPPVJwotySOFRgjgv79ua NLYaqlDYvUHyGaJACOfFAq9z2cn/KYysJPZQXikMToT2WaRzvmT1xjYDodd2jdq7 SDBNRZrp8loM25z4Q/MbcHxFYTssWU7i+DsIgUAsK7T832QXMLtYm45pa4UVPduP RG02LDRQfzQkyXkrIe/DyjSwBL+AjFTgWiecrmknCdTSiMyUd1CYmYyRfEuKFv0e CQIDAQAB -----END PUBLIC KEY----- ``` If you encounter any issues with signature validation, please contact the Super Qi MiniApp team. ## Common Issues & Troubleshooting ### Issue: "signature verification failed: crypto/rsa: verification error" **Possible Causes:** 1. **Wrong public key** - Ensure you're using the correct key for the `keyVersion` 2. **Incorrect path** - The HTTP path in sign content must match exactly (e.g., `/api/payment/webhook`) 3. **Modified body** - Don't parse or reformat JSON before validation 4. **Wrong timestamp header** - Use `Request-Time` for webhooks, not `Response-Time` **Debug Steps:** ```go // Log the exact sign content log.Printf("Sign Content:\n%s", signContent) // Verify it matches this format: // POST /api/payment/webhook // .. ``` ### Issue: "signature not found in header" The signature header has spaces after commas. Make sure to trim spaces: ```go part = strings.TrimSpace(part) // Important! if strings.HasPrefix(part, "signature=") { return strings.TrimPrefix(part, "signature=") } ``` ### Issue: "failed to parse PEM block" **Possible Causes:** 1. Public key file is corrupted or incomplete 2. Wrong file format (not PEM) 3. Extra spaces or characters in the key file **Verification:** ```bash # Check if it's a valid public key openssl rsa -pubin -in superqi_public_key.pem -text -noout ``` ### Issue: Different signatures for same content This is **normal**. RSA signatures include random padding (PKCS#1 v1.5), so the same content will produce different signatures each time. This doesn't affect verification. ## Summary Signature validation is essential for secure Super Qi integration: 1. **Extract** Client-Id, Request-Time, Signature headers 2. **Construct** sign content: `POST \n..` 3. **Parse** the base64 signature from the Signature header 4. **Verify** using RSA SHA256 with Super Qi's public key 5. **Process** webhook only if signature is valid # FAQ ## Before You Ask We highly recommend reviewing this FAQ before reaching out to the Miniapps team. Many common questions have already been answered here, which means you can get the information you need right away without waiting for a response. Taking a few minutes to browse through these frequently asked questions might save you time and help you resolve issues more quickly. If you don't find what you're looking for, we're always here to help! ## Frequently Asked Questions ::accordion :::accordion-item --- label: What's the difference between UAT and Production credentials? --- UAT (User Acceptance Testing) credentials are used for testing your Miniapp in a sandbox environment. They allow you to test all features without affecting real users or processing real transactions. Production credentials are used for your live Miniapp and process real transactions with actual money. Always test thoroughly with UAT credentials before moving to production. ::: :::accordion-item{label="How can I integrate with Qi Gateway Payment system?"} The documentation you're reading and the Miniapp system as a whole are specifically designed for building Miniapps within Super Qi. This is a different system from the standard Qi Payment Gateway integration. Miniapps use an internal payment system that is built into the Super Qi platform. If you're looking to integrate directly with the Qi Payment Gateway (outside of the Miniapp context), that is managed by a separate team with different documentation and integration procedures. To get in touch with the Payment Gateway team and obtain the necessary contact information and documentation for standard payment integration, please contact your account manager. They will provide you with the appropriate team contacts and resources for your integration needs. ::: :::accordion-item{label="How long does the security review process take?"} The security review process typically takes anywhere from a few days to a couple of weeks, depending on the complexity of your Miniapp and the current review queue. The security team will thoroughly test your Miniapp's functionality, security, and compliance with Super Qi guidelines. You'll be contacted if they have any questions or concerns during the review. ::: :::accordion-item{label="Can I update my Miniapp after it's released?"} Yes! You can create new versions of your Miniapp at any time. Simply create a new version in the Super Qi Console with your updated code, test it thoroughly with UAT credentials, then submit it for release following the same process. ::: :::accordion-item --- label: What should I do if I accidentally committed my credentials to version control? --- If you've committed credentials to Git, immediately rotate your credentials by contacting the Miniapps team. Remove the credentials from your repository history using tools like `git filter-branch` or BFG Repo-Cleaner. Never reuse exposed credentials, even if you delete them from your repository. ::: :::accordion-item --- label: I am receiving 'Operation Failed' in UAT, what should I do? --- There are many factors in UAT that can cause "Operation Failed" errors. First, make sure you have the following configured correctly: you're using the **latest UAT version** of the Super Qi app, your **environment is set to UAT** (not Production), and you're **logged into one of the KYC accounts** we provided for you. If you're developing and testing your Miniapp and still getting "Operation Failed", please ensure your **phone and machine are on the same network**, and verify that the **Miniapp version you're testing is configured for UAT** (not Production) since you're testing in the UAT environment. If problem still persists, then please contact the Miniapp team. ::: :::accordion-item --- label: If i want to create more than one Miniapp, do i need different Creds? --- No, you can use the same credentials since you are the same merchant ::: :::accordion-item --- label: What's the difference between cashier payment and agreement payment? --- Cashier payment (CASHIER\_PAYMENT) is a one-time payment where users authorize each transaction individually by scanning a QR code or payment link. Agreement payment (AGREEMENT\_PAYMENT) is a recurring payment setup where users grant permission once, and your Miniapp can charge them in the future without additional authorization. Agreement payments are ideal for subscriptions and recurring billing, while cashier payments are better for one-time purchases. Keep in mind that the agreement payment requires a special scope ::: :::accordion-item --- label: What's the difference between Customer and Business user scopes? --- Super Qi supports two distinct user types, each with their own set of authorization scopes: **Customer User Scopes** are used when your Miniapp needs to access information about individual end-users (consumers). These scopes allow you to retrieve personal information such as user ID, name, avatar, contact information, and preferences. Use Customer scopes when building Miniapps for regular consumers, such as shopping apps, food delivery services, or entertainment platforms. Examples include: `USER_ID`, `USER_NAME`, `USER_AVATAR`, `USER_CONTACTINFO`, and `auth_base`. **Business (Merchant) User Scopes** are used when your Miniapp needs to access information about business users or merchants on the platform to make purchases. These scopes are designed for B2B scenarios where one merchant needs to interact with another merchant and buy their products or related reasons. They allow you to retrieve business-specific information like merchant ID, business name, and merchant logo. Use Business scopes when building Miniapps that facilitate business-to-business transactions. Examples include: `MERCHANT_ID`, `MERCHANT_NAME`, `MERCHANT_LOGO`, and `auth_base` (for merchants). **Important**: You must use the appropriate scope type based on your target audience. Attempting to use Customer scopes to retrieve Business user data (or vice versa) will fail. For a complete list of available scopes, see the [getAuthCode Scope Reference](https://superqi-dev-docs.pages.dev/api-reference/jsapi/essential-apis/get-auth-code#scope-reference). ::: :::accordion-item --- label: What currency unit should I use when sending monetary values in API requests? --- All monetary values in payment APIs must be expressed in **fils**, which is the smallest currency unit of IQD (Iraqi Dinar). Since 1 IQD = 1000 fils, you need to multiply your IQD amount by 1000. For example, 150 IQD should be sent as `150000` fils. This applies to all payment-related API endpoints including pay, inquiry, and refund operations. ::: :: ## Still Need Help? If you couldn't find the answer to your question in this FAQ, don't hesitate to reach out to our Miniapps team. We're here to help you succeed with your Miniapp development. **Contact:** **Hani Salih** Miniapps Software Engineer Email: ::warning When contacting us, please include as much detail as possible about your issue: - What you're trying to accomplish - What you've already tried - Any error messages you're seeing - Your Super Qi / UAT version - Your Miniapp name This helps us provide you with faster and more accurate support. :: # Changelog