Mini-App Backend Development
1. Interface Description
The common server-side interfaces are encapsulated in the MiniAppCommonService service class from the public module. You can obtain an instance by injecting this service class. Usage example:
@Resource
private MiniAppCommonService miniAppCommonService;
@Resource
private MiniAppPayService miniAppPayService;
ApplicationVo application = miniAppCommonService.getApplication();
// ...Before using the server-side interfaces, you must correctly configure the Mini-App's appKey and appSecret. These are mainly used for signing request parameters when the Mini-App backend initiates requests to the Mos server. Developers do not need to concern themselves with the specific signing method — the public service has already encapsulated it. After injecting the corresponding service, you can directly call the specific methods.
1.1 Interface BaseURL
- Test environment: https://mos-test.mos.me
- Production environment: https://mos.mos.me
1.2 Interface Signature
If calling directly via HTTP, the request Body must include the following fields:
- appKey: Mini-App App Key
- sign: Signature
Signature generation rule: Sort all parameters (including appKey) in ascending order, convert them to QueryString format (e.g., key1=value1&key2=value2...), then append secret=appSecret at the end, and finally perform MD5 on the resulting string. Java example code:
import org.springframework.util.DigestUtils;
/**
* Get signature
*
* @param request Request object (Object used here as example; replace with actual request type or base class)
* @return Signature
*/
public String getSign(Object request) {
// Convert request to a key-ordered TreeMap (ascending by default), "appKey" must be included
Map<String, String> requestSortedMap = JSON.parseObject(JSON.toJSONString(request), new TypeReference<TreeMap<String, String>>() {
});
requestSortedMap.put("appKey", "<your_app_key>");
// Convert request to QueryString format, e.g., key1=value1&key2=value2...
StringBuilder qsBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : requestSortedMap.entrySet()) {
// "sign" or empty values do not participate in signing
if ("sign".equals(entry.getKey()) || entry.getValue() == null || entry.getValue().isEmpty()) {
continue;
}
qsBuilder.append(entry.getKey()).append("=").append(entry.getValue().trim()).append("&");
}
// Append "secret=your_app_secret" at the end
qsBuilder.append("secret=").append("<your_app_secret>");
// MD5 processing
return DigestUtils.md5DigestAsHex(qsBuilder.toString().getBytes(StandardCharsets.UTF_8));
}2. Login & Authentication
2.1 Get Application Information
API: MiniAppCommonService.getApplication()
HTTP: POST /open-apis/application/v1/getApplication
Get Mini-App application information
Parameters
None (signature still required)
Response
| Field | Type | Description |
|---|---|---|
| appName | String | Application name |
| appKey | String | Application key |
| appSecret | String | Application secret |
| description | String | Application description |
| status | Boolean | Application status |
| notifyUrl | String | Callback URL |
2.2 Universal Login
API: MiniAppCommonService.miniAppLogin(String code)
A universal login interface provided by the public module. It uses the code obtained from the Mini-App frontend and JWT to generate an identity token. After creating a new Mini-App module, a default login interceptor com.testproject.mos.miniapp.xxx.interceptor.LoginInterceptor is included. This interceptor validates the token passed from the Mini-App frontend in the format of Bearer token via HTTP Header:
Authorization: Bearer <token>After authentication passes, users can retrieve the logged-in user's openid and language type via the "Get Current User Information" interface, which can then be used to fetch the user's information within the Mini-App itself (the Mini-App must maintain its own user table with a column storing openid).
If the universal login does not meet your needs, you may override the login interceptor and implement your own login and current user information retrieval interfaces.
Note: Do not modify the code in the public module.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| code | String | Yes | Code obtained via mos.login in Mini-App |
Response TokenVo
| Field | Type | Description |
|---|---|---|
| token | String | Identity token |
2.3 Get Current User Information
API: MiniAppCommonService.getMiniAppUser()
A universal method provided by the public module to get the current logged-in user. It works only when used with the universal login interface and the default login interceptor.
Parameters
None (signature still required)
Response MiniAppUserBo
| Field | Type | Description |
|---|---|---|
| appKey | String | Application key |
| openid | String | User unique identifier |
| languageType | LanguageEnum | Language type |
2.4 Exchange Code for Mos Session
API: MiniAppCommonService.code2session(String code)
HTTP: POST /open-apis/mp/v1/auth/code2session
Get Mos session information using code
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| code | String | Yes | Code obtained via mos.login in Mini-App |
Response MosSessionVo
| Field | Type | Description |
|---|---|---|
| openid | String | User unique identifier |
| sessionKey | String | Session key (currently unused) |
3. QR Code Login
3.1 Generate QR Code
HTTP: POST /open-apis/mp/v1/auth/getLoginQrCodeUrl
Generate a QR code for Mini-App scan-to-login. Expires in 120 seconds. The Mini-App uses this string to generate the QR code image.
Request Body
None (signature still required)
Response Body
| Field | Type | Description |
|---|---|---|
| qrCode | String | QR code string, format: https://mos.me/miniapp-open/login/{uuid} |
| uuid | String | QR code UUID string |
3.2 Check QR Code Status
HTTP: POST /open-apis/mp/v1/auth/getLoginQrCodeStatus
Check the status of the QR code. Returns user information upon successful scan.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| qrCodeUuid | String | Yes | QR code UUID string |
Response Body
| Field | Type | Description |
|---|---|---|
| status | String | 'NO_SCAN': Not scanned | 'SCAN': Scanned |
| mosOpenUserVo | MosOpenUserVo | User info (available only after successful scan) |
Response MosOpenUserVo
| Field | Type | Description |
|---|---|---|
| openId | String | User unique identifier |
| firstName | String | First name |
| lastName | String | Last name |
| headPortrait | String | Avatar URL |
4. Payment
Before developing payment features, you must apply to become a Mos merchant and obtain the corresponding merchant ID (mcId), which is required in the payment flow.
4.1 Create Prepayment Order
API: MiniAppPayService.prepay(CreatePrepayOrderAo ao)
HTTP: POST /open-apis/mp/v1/pay/prepay
Create a prepayment order
Parameters CreatePrepayOrderAo
| Field | Type | Required | Description |
|---|---|---|---|
| mcId | String | Yes | Merchant ID |
| nonceStr | String | No | Random string, must be unique in the system |
| desc | String | No | Order description |
| outTradeNo | String | Yes | Merchant Mini-App system order number |
| currency | String | Yes | Currency: USD - US Dollar | KHR - Cambodian Riel |
| totalAmount | String | Yes | Order amount |
| notifyUrl | String | Yes | Callback URL |
| openid | String | Yes | User unique identifier |
| expireTime | String | No | Order expiration timestamp (milliseconds) |
Response PrepayOrderVo
| Field | Type | Description |
|---|---|---|
| prepayId | String | Prepayment order ID |
4.2 Merchant Pays User
API: MiniAppPayService.payToMiniAppUser(PayToMiniAppUserAo ao)
HTTP: POST /open-apis/mp/v1/pay/payToMiniAppUser
Call this interface to pay a user
Parameters PayToMiniAppUserAo
| Field | Type | Required | Description |
|---|---|---|---|
| nonceStr | String | No | Random string, must be unique in the system |
| outTradeNo | String | Yes | Merchant Mini-App system order number |
| currency | String | Yes | Currency: USD - US Dollar | KHR - Cambodian Riel |
| amount | String | Yes | Payment amount |
| openid | String | Yes | User unique identifier |
Response PayToMiniAppUserVo
| Field | Type | Description |
|---|---|---|
| prepayId | String | Prepayment order ID |
| nonceStr | String | Random string |
| outTradeNo | String | Merchant Mini-App system order number |
| paymentNo | String | Mos order number |
4.3 Query Order
API: MiniAppPayService.orderQuery(OrderQueryAo ao)
HTTP: POST /open-apis/mp/v1/pay/orderQuery
Query order status
Parameters OrderQueryAo
| Field | Type | Required | Description |
|---|---|---|---|
| nonceStr | String | Yes | Random string, must be unique in the system |
| outTradeNo | String | Yes | Merchant Mini-App system order number |
Response OrderQueryVo
| Field | Type | Description |
|---|---|---|
| openid | String | User unique identifier |
| prepayId | String | Prepayment order ID |
| outTradeNo | String | Merchant Mini-App order number |
| country | String | Country code |
| currency | String | Currency |
| totalAmount | String | Order amount |
| desc | String | Product description |
| status | String | Order status |
| expireTime | Long | Expiration time |
| createTime | Long | Creation time |
5. Customer Service Account
5.1 Create Customer Service Account
HTTP: POST /open-apis/mp/v1/customerServ/create
Create a customer service account
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| openid | String | Yes | User unique identifier |
| name | String | Yes | Customer service name |
| headPortrait | String | No | Customer service head portrait, no default value automatically generated |
Response Body
| Field | Type | Description |
|---|---|---|
| token | String | Customer service account identifier |
| webHook | String | Webhook address of the account |
| name | String | Customer service name |
| headPortrait | String | Customer service avatar |
| descriptor | String | Customer service description |
| idNumber | String | Unique ID of the customer service |
| link | String | Customer service link |
5.2 Send Message
HTTP: POST /open-apis/mp/v1/customerServ/{token}/sendMessage
Send a message to a specified user via the customer service bot (implemented by combining content and msgType fields in different ways)
Path Parameter
| Field | Type | Required | Description |
|---|---|---|---|
| token | String | Yes | Customer service account identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| openid | String | Yes | Recipient user unique identifier |
| content | Content | Yes | Message content, see Content |
Content
| Field | Type | Required | Description |
|---|---|---|---|
| msgType | String | Yes | Message type: TEXT (plain text) | CARD (card message) |
| text | String | No | Message text, max length 5000 characters (required when msgType=TEXT) |
| inlineButtons | List<List<InlineButton>> | No | Inline buttons (available for any message type), see InlineButton |
| cardMessage | CardMessage | No | Card message body (required when msgType=CARD), see CardMessage |
InlineButton
| Field | Type | Required | Description |
|---|---|---|---|
| text | String | Yes | Button label, max length 30 characters |
| type | String | Yes | Button type: callback (callback request) | miniApp (mini-app jump) | url (external link or internal link opened in Mos) |
| data | String | Yes | Button data, developer-defined content |
Inline Button Limits
- Up to 4 buttons per row (i.e., each inner list can contain at most 4
InlineButtonobjects) - No more than 40 buttons in total
Inline Button Type Details
callback: When the user clicks, MosApp sends an event to the customer service mini-app backend via webhook, passing the button’sdatavalue.url: Opens the specified link in the browser; for internal links (such as user, group, channel), opens inside MosApp.miniApp: Opens the bound mini-app directly when clicked.
Inline Button Data Description
- For
callback,datais a string configured by the customer service mini-app backend; MosApp forwards it transparently when the user clicks.
Callback webhook request body format:
{
"reqId": "Unique request id",
"data": "data"
}- For
url,datais an external URL or a MosApp internal link. - For
miniApp,datacan configure page path and other info; MosApp appends it to the mini-app URL as query parameters.
CardMessage
| Field | Type | Required | Description |
|---|---|---|---|
| title | String | Yes | Title, max length 50 characters |
| messageTitle | String | No | Message title, max length 50 characters |
| cover | String | No | Cover image URL, max length 1000 characters |
| price | String | No | Price, max length 30 characters |
| linePrice | String | No | Strikethrough price, max length 30 characters |
Response Body
None
5.3 Get Customer Service Account Info
HTTP: POST open-apis/mp/v1/customerServ/getInfo
Get customer service account information
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| token | String | Yes | Customer service account identifier |
Response Body
| Field | Type | Description |
|---|---|---|
| token | String | Customer service account identifier |
| webHook | String | Webhook address of the account |
| name | String | Customer service name |
| headPortrait | String | Customer service avatar |
| descriptor | String | Customer service description |
| idNumber | String | Unique ID of the customer service |
| link | String | Customer service link |
5.4 Update Customer Service Account Info
HTTP: POST /open-apis/mp/v1/customerServ/updateInfo
Update customer service account information
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| token | String | Yes | Customer service account identifier |
| name | String | No | Customer service name, max length 30 |
| headPortrait | String | No | Customer service avatar, max length 1000 |
| descriptor | String | No | Customer service description, max length 300 |
| idNumber | String | No | Unique ID of the customer service, max length 30 |
Notes
- At least one of name, headPortrait, descriptor, idNumber must be provided
- idNumber is the unique identifier of the customer service and must be unique
Response Body
| Field | Type | Description |
|---|---|---|
| token | String | Customer service account identifier |
| webHook | String | Webhook address of the account |
| name | String | Customer service name |
| headPortrait | String | Customer service avatar |
| descriptor | String | Customer service description |
| idNumber | String | Unique ID of the customer service |
| link | String | Customer service link |
5.5 Reset Customer Service Account Token
HTTP: POST /open-apis/mp/v1/customerServ/resetToken
Reset the customer service account token
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| token | String | Yes | Customer service account identifier |
Response Body
| Field | Type | Description |
|---|---|---|
| token | String | Customer service account identifier |
| webHook | String | Webhook address of the account |
| name | String | Customer service name |
| headPortrait | String | Customer service avatar |
| descriptor | String | Customer service description |
| idNumber | String | Unique ID of the customer service |
| link | String | Customer service link |
5.6 Set Customer Service Account Webhook
HTTP: POST /open-apis/mp/v1/customerServ/setWebHook
Set the webhook of the customer service account, i.e., the callback URL for button events
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| token | String | Yes | Customer service account identifier |
| webHook | String | Yes | Webhook URL , if empty then delete the webhook, max length 300 |
Response Body
| Field | Type | Description |
|---|---|---|
| token | String | Customer service account identifier |
| webHook | String | Webhook address of the account |
| name | String | Customer service name |
| headPortrait | String | Customer service avatar |
| descriptor | String | Customer service description |
| idNumber | String | Unique ID of the customer service |
| link | String | Customer service link |