### Get Launch Options Source: https://developer.mosapp.app/guide/sdk.html Retrieves the Mini-App's launch query parameters. ```APIDOC ## Get Launch Parameters ### Description Retrieves the Mini-App's launch query parameters, useful for understanding how the Mini-App was initiated. ### Method `mos.getLaunchOptions()` ### Endpoint N/A (SDK method) ### Parameters None ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure. - **query** (object) - Launch parameters. ``` -------------------------------- ### POST open-apis/mp/v1/customerServ/getInfo Source: https://developer.mosapp.app/guide/backend.html Get customer service account information. ```APIDOC ## POST open-apis/mp/v1/customerServ/getInfo ### Description Get customer service account information. ### Method POST ### Endpoint /open-apis/mp/v1/customerServ/getInfo ### Parameters #### Request Body - **token** (String) - Yes - Customer service account identifier ### Response #### Success Response (200) - **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 #### Response Example ```json { "token": "string", "webHook": "string", "name": "string", "headPortrait": "string", "descriptor": "string", "idNumber": "string", "link": "string" } ``` ``` -------------------------------- ### Mini-App Backend Service Injection Source: https://developer.mosapp.app/guide/backend.html Example of how to inject and use MiniAppCommonService and MiniAppPayService in your backend code. ```APIDOC ## Mini-App Backend Service Injection ### Description This snippet demonstrates how to inject and utilize the `MiniAppCommonService` and `MiniAppPayService` within your Java backend application. These services provide access to various Mini-App functionalities. ### Usage Example ```java @Resource private MiniAppCommonService miniAppCommonService; @Resource private MiniAppPayService miniAppPayService; ApplicationVo application = miniAppCommonService.getApplication(); // ... ``` ### Configuration Before using these services, ensure that your Mini-App's `appKey` and `appSecret` are correctly configured. These are essential for signing requests to the Mos server. The public service handles the signing process internally. ``` -------------------------------- ### POST /open-apis/mp/v1/pay/prepay Source: https://developer.mosapp.app/guide/payment-to-user.html Initiates a prepay order for a mini-app payment. This is the first step in the payment process, generating an order that can then be used for further actions. ```APIDOC ## POST /open-apis/mp/v1/pay/prepay ### Description Initiates a prepay order for a mini-app payment. ### Method POST ### Endpoint /open-apis/mp/v1/pay/prepay ### Parameters #### Request Body - **ao** (CreatePrepayOrderAo) - Required - The request payload for creating a prepay order. ### Request Example ```json { "example": "CreatePrepayOrderAo object" } ``` ### Response #### Success Response (200) - **PrepayOrderVo** - The response object containing details of the created prepay order. #### Response Example ```json { "example": "PrepayOrderVo object" } ``` ``` -------------------------------- ### 1.1.9 Get Device Information API Source: https://developer.mosapp.app/guide/sdk.html Retrieves base application information for the device. Supports Promise-style invocation. ```APIDOC ## GET /api/getAppBaseInfo ### Description Retrieves base application information for the device. Supports Promise-style invocation. ### Method GET ### Endpoint /api/getAppBaseInfo ### Parameters None ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure #### Response Example ```json { "result": "SUCCESS" } ``` ``` -------------------------------- ### Get Short Link Source: https://developer.mosapp.app/guide/sdk.html Generates a short link from a long URL. ```APIDOC ## Get Short Link ### Description Generates a shortened version of a given long URL. ### Method `mos.getShortLink(Object object)` ### Parameters #### Request Body - **link** (string) - Required - The long link to shorten. - **showLoading** (string) - Optional - Whether to display a loading indicator. `1`: show, `0`: hide. Defaults to `1`. ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure. - **message** (string) - Error message if the operation fails. - **data** (string) - The generated short link. ``` -------------------------------- ### 1.1.8 Get Window Information API Source: https://developer.mosapp.app/guide/sdk.html Retrieves information about the current window, including status bar height. Supports Promise-style invocation. ```APIDOC ## GET /api/getWindowInfo ### Description Retrieves information about the current window, including status bar height. Supports Promise-style invocation. ### Method GET ### Endpoint /api/getWindowInfo ### Parameters None ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **statusBarHeight** (number) - Status Bar Height #### Response Example ```json { "result": "SUCCESS", "statusBarHeight": 24 } ``` ``` -------------------------------- ### Web Configuration with Interceptor Registration (Java) Source: https://developer.mosapp.app/guide/login.html This Java code configures the web application's interceptor setup using Spring's `WebMvcConfigurer`. It registers the `LoginInterceptor` to intercept requests to the '/mp/**' path, while excluding specific paths related to Swagger documentation and the mini-app login endpoint. ```java package testproject.interceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfigure implements WebMvcConfigurer { private static final String[] EXCLUDE_PATH_PATTERNS_FOR_SWAGGER = {"/doc.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"}; @Override public void addInterceptors(InterceptorRegistry registry) { // Register custom interceptor registry.addInterceptor(new LoginInterceptor()) // Intercept all mp mini-app requests .addPathPatterns("/mp/**") // Exclude swagger interface documentation .excludePathPatterns(EXCLUDE_PATH_PATTERNS_FOR_SWAGGER) // Exclude mini-app login path .excludePathPatterns("/mp/login/miniAppLogin"); } } ``` -------------------------------- ### Login with Code and Token Handling (Java) Source: https://developer.mosapp.app/guide/login.html This snippet demonstrates the process of logging in using a provided code, validating the token, and extracting user information. It handles potential login failures and returns a token upon successful authentication. Dependencies include the MiniAppCommonService. ```java TokenVo tokenVo = miniAppCommonService.miniAppLogin(param.getCode()); if(tokenVo == null) { throw new RuntimeException("login failed, checking the parameter of code"); } // check is the openid new in your db // ... do it use tokenVo.getOpenId return tokenVo.getToken(); } } ``` -------------------------------- ### Java MiniAppPayService for MOS Payment Gateway Integration Source: https://developer.mosapp.app/guide/payment-to-user.html The MiniAppPayService in Java provides a comprehensive solution for integrating with the MOS mini-app payment gateway. It handles API calls, request signing using MD5, and response parsing. Key functionalities include initiating prepay orders, transferring funds to users, and querying transaction status. Dependencies include Spring Boot, Alibaba Fastjson, and Hutool crypto. It requires configuration of MOS mini-app base URL, appKey, and appSecret. ```java import cn.hutool.crypto.digest.MD5; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.Map; import java.util.TreeMap; /** * Mini-App Payment Common Service * * @author tom */ @Slf4j @Component public class MiniAppPayService { /** * MOS mini-app base URL */ @Value("${mos.mini-app.base-url}") private String baseUrl; /** * MOS mini-app appKey */ @Value("${mos.mini-app.app-key}") private String appKey; /** * MOS mini-app appSecret */ @Value("${mos.mini-app.app-secret}") private String appSecret; private final RestTemplate restTemplate; public MiniAppPayService() { SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory(); httpRequestFactory.setConnectTimeout(30000); httpRequestFactory.setReadTimeout(60000); this.restTemplate = new RestTemplate(httpRequestFactory); } /** * Call MOS server mini-app open API * * @param uri API URI * @param ao Request parameters * @param clazz Response type * @return Response object */ private T call(String uri, BaseSignedAo ao, Class clazz) { // Signature ao.setAppKey(this.appKey); Map data = JSON.parseObject(JSON.toJSONString(ao), new TypeReference>() {}); String sign = MiniAppUtil.generateSignature(data, this.appSecret); ao.setSign(sign); // Make request String url = this.baseUrl + uri; ResponseEntity responseEntity = restTemplate.postForEntity(url, ao, String.class); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { log.error("Mini-app request exception uri={} ao={}", uri, JSON.toJSONString(ao)); return null; } // Parse response code(int) message(String) data(T) JSONObject result = JSON.parseObject(responseEntity.getBody()); if ((int)result.get("code") != 200) { log.error("Mini-app request exception uri={} ao={} result={}", uri, JSON.toJSONString(ao), JSON.toJSONString(result)); return null; } return JSON.to(clazz, result.get("data")); } public PrepayOrderVo prepay(CreatePrepayOrderAo ao) { return this.call("/open-apis/mp/v1/pay/prepay", ao, PrepayOrderVo.class); } public PayToMiniAppUserVo payToMiniAppUser(PayToMiniAppUserAo ao) { return this.call("/open-apis/mp/v1/pay/payToMiniAppUser", ao, PayToMiniAppUserVo.class); } public OrderQueryVo orderQuery(OrderQueryAo ao) { return this.call("/open-apis/mp/v1/pay/orderQuery", ao, OrderQueryVo.class); } @Data public static class BaseSignedAo { /** * Mini-app appKey */ @NotNull private String appKey; /** * Signature */ @NotNull private String sign; } @Data @AllArgsConstructor @NoArgsConstructor public static class PayToMiniAppUserAo extends BaseSignedBo { /** * Random string, must be unique in the system */ private String nonceStr; /** * Merchant mini-app system order number */ @NotNull private String outTradeNo; /** * Currency unit USD-US dollar KHR-Cambodian riel */ @NotNull private String currency; /** * Order amount */ @NotNull private String amount; /** * Openid */ @NotNull private String openid; } @Data public PayToMiniAppUserVo extends BaseSignedBo { /** * Random string, must be unique in the system */ private String nonceStr; /** * Merchant mini-app system order number */ private String outTradeNo; /** * MOS order number */ private String paymentNo; } public static class MiniAppUtil { /** * Generate signature */ public static String generateSignature(Map data, String appSecret) { ``` -------------------------------- ### Initiate Mini-App Login with mos.login() - JavaScript Source: https://developer.mosapp.app/guide/login.html This JavaScript code snippet demonstrates how a Mini-App frontend can initiate the login process by calling `mos.login()` to obtain a login credential code. It then sends this code to the Mini-App's backend service for further processing and authentication. The received custom token is stored in local storage for future authenticated requests. Dependencies include the `mos` API and `axios` for making HTTP requests. ```javascript ```javascript // Call mos.login to get login credential code mos.login("your_app_key").then((res) => { // Mini-app backend service login axios.post("https://demo-test.miniapp.xxx/api/login/miniAppLogin", { code: res.data.code, }).then((res1) => { // Save Token to cache, carry it in subsequent requests localStorage.setItem("token", res1.data); }); }); ``` ``` -------------------------------- ### Local Cache APIs Source: https://developer.mosapp.app/guide/sdk.html APIs for managing local data cache, including setting, getting, removing, and clearing data. ```APIDOC ## 1.5.1 Set Local Cache ### Description Stores data in local cache specified by key. Overwrites the original content of the key. Data will remain available unless manually deleted. Maximum data size per key is 100KB, and total data size limit is 1MB. ### Method POST ### Endpoint /api/storage/set ### Parameters #### Request Body - **appDataKey** (string) - Required - Storage key, 1-500 characters - **appDataValue** (any) - Optional - Storage data, maximum size is 100KB. Supports string, number, boolean, object, array. Data is encrypted and stored. ### Request Example ```json { "appDataKey": "userSettings", "appDataValue": { "theme": "dark", "fontSize": 14 } } ``` ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **message** (string) - Error message #### Response Example ```json { "result": "SUCCESS", "message": "Data stored successfully." } ``` ## 1.5.2 Get Local Cache ### Description Retrieves data from local cache using the specified key. ### Method GET ### Endpoint /api/storage/get ### Parameters #### Query Parameters - **appDataKey** (string) - Required - Storage key, 1-500 characters ### Request Example ``` /api/storage/get?appDataKey=userSettings ``` ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **message** (string) - Error message - **data** (string) - Stored data #### Response Example ```json { "result": "SUCCESS", "message": "Data retrieved successfully.", "data": "{\"theme\": \"dark\", \"fontSize\": 14}" } ``` ## 1.5.3 Remove Local Cache ### Description Removes data from local cache using the specified key. ### Method DELETE ### Endpoint /api/storage/remove ### Parameters #### Query Parameters - **appDataKey** (string) - Required - Storage key, 1-500 characters ### Request Example ``` /api/storage/remove?appDataKey=userSettings ``` ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **message** (string) - Error message #### Response Example ```json { "result": "SUCCESS", "message": "Data removed successfully." } ``` ## 1.5.4 Clear Local Cache ### Description Clears all data from the local cache. ### Method DELETE ### Endpoint /api/storage/clear ### Parameters None ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **message** (string) - Error message #### Response Example ```json { "result": "SUCCESS", "message": "Cache cleared successfully." } ``` ``` -------------------------------- ### 1.1.3 Get User Information API Source: https://developer.mosapp.app/guide/sdk.html Retrieves user information, optionally with silent authorization. Supports Promise-style invocation. ```APIDOC ## POST /api/getUserInfo ### Description Retrieves user information, optionally with silent authorization. Supports Promise-style invocation. ### Method POST ### Endpoint /api/getUserInfo ### Parameters #### Request Body - **authorizedDesc** (string) - Required - Purpose of Obtaining Authorization Information - **closeOnClickOverlay** (string) - Optional - Whether to close the pop-up window after clicking the mask layer, 0: do not close, 1: close (Default: 1) ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure | 'CANCEL': User cancel - **authorized** (number) - 0: Not Authorized | 1: Authorized | 2: No Corresponding Information - **firstName** (string) - Surname - **lastName** (string) - Given Name - **headPortrait** (string) - Avatar URL - **descriptor** (string) - Profile Bio #### Response Example ```json { "result": "SUCCESS", "authorized": 1, "firstName": "John", "lastName": "Doe", "headPortrait": "http://example.com/avatar.jpg", "descriptor": "Software Engineer" } ``` ``` -------------------------------- ### POST /open-apis/mp/v1/pay/orderQuery Source: https://developer.mosapp.app/guide/payment-to-user.html Queries the status of a specific payment order. This allows you to check if a payment has been completed, failed, or is pending. ```APIDOC ## POST /open-apis/mp/v1/pay/orderQuery ### Description Queries the status of a specific payment order. ### Method POST ### Endpoint /open-apis/mp/v1/pay/orderQuery ### Parameters #### Request Body - **ao** (OrderQueryAo) - Required - The request payload for querying an order. ### Request Example ```json { "example": "OrderQueryAo object" } ``` ### Response #### Success Response (200) - **OrderQueryVo** - The response object containing the order details and status. #### Response Example ```json { "example": "OrderQueryVo object" } ``` ``` -------------------------------- ### Call Mini-App Open Interface with Signature Generation (Java) Source: https://developer.mosapp.app/guide/auto-subscription.html This Java code snippet demonstrates how to call open interfaces of the Mos mini-app backend service. It includes generating a signature for secure communication, sending HTTP POST requests using RestTemplate, and parsing JSON responses. Dependencies include Hutool for MD5 hashing and Fastjson2 for JSON processing. ```java import cn.hutool.crypto.digest.MD5; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.Map; import java.util.TreeMap; @Slf4j @Component public class MiniAppPayService { /** * Mos mini-app call address */ @Value("${mos.mini-app.base-url}") private String baseUrl; /** * Mos mini-app appKey */ @Value("${mos.mini-app.app-key}") private String appKey; /** * Mos mini-app appSecret */ @Value("${mos.mini-app.app-secret}") private String appSecret; private final RestTemplate restTemplate; public MiniAppPayService() { SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory(); httpRequestFactory.setConnectTimeout(30000); httpRequestFactory.setReadTimeout(60000); this.restTemplate = new RestTemplate(httpRequestFactory); } /** * Request Mos server mini-app open interface * * @param uri Interface URI * @param ao Request parameters * @param clazz Response type * @return Response object */ private T call(String uri, BaseSignedAo ao, Class clazz) { // Signature ao.setAppKey(this.appKey); Map data = JSON.parseObject(JSON.toJSONString(ao), new TypeReference>() { }); String sign = MiniAppUtil.generateSignature(data, this.appSecret); ao.setSign(sign); // Send request String url = this.baseUrl + uri; ResponseEntity responseEntity = restTemplate.postForEntity(url, ao, String.class); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { log.error("Mini-app request exception uri={} ao={}", uri, JSON.toJSONString(ao)); return null; } // Parse response code(int) message(String) data(T) JSONObject result = JSON.parseObject(responseEntity.getBody()); if ((int)result.get("code") != 200) { log.error("Mini-app request exception uri={} ao={} result={}", uri, JSON.toJSONString(ao), JSON.toJSONString(result)); return null; } return JSON.to(clazz, result.get("data")); } public CancelAutoSubscriptionVo cancelAutoSubscription(CancelAutoSubscriptionAo ao) { return this.call("/open-apis/mp/v1/pay/cancelAutoSubscription", ao, CancelAutoSubscriptionVo.class); } public AutoSubscriptionQueryVo autoSubscriptionQuery(AutoSubscriptionQueryAo ao) { return this.call("/open-apis/mp/v1/pay/autoSubscriptionQuery", ao, AutoSubscriptionQueryVo.class); } @Data public static class BaseSignedAo { /** * Mini-app appKey */ @NotNull private String appKey; /** * Signature */ @NotNull private String sign; } @Data @EqualsAndHashCode(callSuper = true) public class CancelAutoSubscriptionAo extends BaseSignedBo { /** * Random string, must be unique within the system */ @NotNull private String nonceStr; /** * Merchant mini-app system order number */ @NotNull private String outTradeNo; } @Data public class CancelAutoSubscriptionVo { /** * Merchant mini-app system order number */ private String outTradeNo; } @Data @EqualsAndHashCode(callSuper = true) public class AutoSubscriptionQueryAo extends BaseSignedAo { /** * Random string, must be unique within the system */ @NotNull private String nonceStr; /** * Merchant mini-app system order number */ @NotNull private String outTradeNo; } @Data public class AutoSubscriptionQueryVo { /** * Merchant mini-app system order number */ private String outTradeNo; /** * billing Cycle */ private String billingCycle; /** * status */ private String status; /** * start time */ private Date startTime; /** * currency */ private String currency; /** * subscribe amount */ private BigDecimal subscribeAmount; /** * pay time */ private Date payTime; /** ``` -------------------------------- ### Mini-App Backend Service Implementation (Java) Source: https://developer.mosapp.app/guide/login.html This Java class, `MiniAppCommonService`, handles common operations for a mini-app backend. It includes methods for making authenticated requests to an external MOS server, retrieving mini-app user information, and performing the login process by exchanging a temporary code for a session and generating a JWT token. Dependencies include Spring Boot, JWT, and various utility libraries for JSON parsing and encryption. ```java package testproject.service.impl; import cn.hutool.crypto.digest.MD5; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonValue; import testproject.domain.vo.TokenVo; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.*; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import java.util.Date; import java.util.Map; import java.util.TreeMap; /** * Mini-app user common service * * @author tom */ @Slf4j @Component public class MiniAppCommonService { // Login signing key public static final String LOGIN_SIGNING_KEY = "your_complex_key_it_can_be_random"; /** * Mos mini-app call address */ @Value("${mos.mini-app.base-url}") private String baseUrl; /** * Mos mini-app appKey */ @Value("${mos.mini-app.app-key}") private String appKey; /** * Mos mini-app appSecret */ @Value("${mos.mini-app.app-secret}") private String appSecret; @Autowired private Environment env; private final RestTemplate restTemplate; public MiniAppCommonService() { SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory(); httpRequestFactory.setConnectTimeout(30000); httpRequestFactory.setReadTimeout(60000); this.restTemplate = new RestTemplate(httpRequestFactory); } /** * Request Mos server mini-app open interface * * @param uri Interface URI * @param ao Request parameters * @param clazz Response type * @return Response object */ private T call(String uri, BaseSignedAo ao, Class clazz) { // Signature ao.setAppKey(this.appKey); Map data = JSON.parseObject(JSON.toJSONString(ao), new TypeReference>() { }); String sign = MiniAppUtil.generateSignature(data, this.appSecret); ao.setSign(sign); // Send request String url = this.baseUrl + uri; ResponseEntity responseEntity = restTemplate.postForEntity(url, ao, String.class); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { log.error("Mini-app request exception uri={} ao={}", uri, JSON.toJSONString(ao)); return null; } // Parse response code(int) message(String) data(T) JSONObject result = JSON.parseObject(responseEntity.getBody()); if ((int)result.get("code") != 200) { log.error("Mini-app request exception uri={} ao={} result={}", uri, JSON.toJSONString(ao), JSON.toJSONString(result)); return null; } return JSON.to(clazz, result.get("data")); } public MiniAppUserBo getMiniAppUser() { HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); String appKey = (String) request.getAttribute("appKey"); String openid = (String) request.getAttribute("openid"); String language = request.getHeader("Lang"); LanguageEnum languageType; if (StringUtils.isBlank(language)) { languageType = LanguageEnum.EN_US; } else { languageType = LanguageEnum.getByCode(language); } return new MiniAppUserBo(appKey, openid, languageType); } public TokenVo miniAppLogin(String code) { MosSessionVo mosSessionVo = this.code2session(code); if (mosSessionVo == null) { return null; } String token = Jwts.builder() .setSubject(this.appKey + "-" + mosSessionVo.getOpenid()) .setIssuedAt(new Date()) // Valid for 360 days .setExpiration(new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 360)) .signWith(SignatureAlgorithm.HS256, LOGIN_SIGNING_KEY).compact(); return new TokenVo().setToken(token); } public MosSessionVo code2session(String code) { ``` -------------------------------- ### POST /open-apis/mp/v1/pay/payToMiniAppUser Source: https://developer.mosapp.app/guide/payment-to-user.html Transfers funds directly to a mini-app user's account. This is used for scenarios like refunds or payouts to users. ```APIDOC ## POST /open-apis/mp/v1/pay/payToMiniAppUser ### Description Transfers funds directly to a mini-app user's account. ### Method POST ### Endpoint /open-apis/mp/v1/pay/payToMiniAppUser ### Parameters #### Request Body - **ao** (PayToMiniAppUserAo) - Required - The request payload for transferring funds to a mini-app user. - **nonceStr** (string) - Required - A random string, must be unique in the system. - **outTradeNo** (string) - Required - Merchant mini-app system order number. - **currency** (string) - Required - Currency unit (e.g., USD, KHR). - **amount** (string) - Required - Order amount. - **openid** (string) - Required - The openid of the mini-app user. ### Request Example ```json { "nonceStr": "random_string_123", "outTradeNo": "MERCHANT_ORDER_12345", "currency": "USD", "amount": "100.50", "openid": "USER_OPENID_XYZ" } ``` ### Response #### Success Response (200) - **PayToMiniAppUserVo** - The response object containing details of the transfer. - **nonceStr** (string) - Random string. - **outTradeNo** (string) - Merchant mini-app system order number. - **paymentNo** (string) - MOS order number. #### Response Example ```json { "nonceStr": "random_string_123", "outTradeNo": "MERCHANT_ORDER_12345", "paymentNo": "MOS_PAY_ABC789" } ``` ``` -------------------------------- ### Java OrderService Implementation for Merchant Payment to User Source: https://developer.mosapp.app/guide/payment-to-user.html This Java code demonstrates the implementation of an OrderService class responsible for processing payments to mini-app users. It utilizes the MiniAppPayService to handle the payment transaction, requiring parameters like currency, amount, order IDs, and the destination user's open ID. The `payToMiniAppUser` method constructs a `PayToMiniAppUserAo` object and calls the `miniAppPayService.payToMiniAppUser` method to execute the payment. ```java import com.testproject.mos.miniapp.common.api.ApiResult; import com.testproject.mos.miniapp.common.entity.vo.TokenVo; import com.testproject.mos.miniapp.vet.ao.LoginAo; import org.springframework.validation.annotation.Validated; @Service public class OrderService { @Resource private MiniAppPayService miniAppPayService; public String payToMiniAppUser(String currency, String amount, String realOrderId, String orderId, String dstOpenId) { PayToMiniAppUserAo payToMiniAppUserAo = new PayToMiniAppUserAo(); payToMiniAppUserAo.setCurrency(currency); payToMiniAppUserAo.setAmount(amount); payToMiniAppUserAo.setNonceStr(MiniAppUtil.generateUuidStr()); payToMiniAppUserAo.setOutTradeNo(orderId); payToMiniAppUserAo.setOpenid(dstOpenId); PayToMiniAppUserVo payToMiniAppUserVo = miniAppPayService.payToMiniAppUser(payToMiniAppUserAo); } } ``` -------------------------------- ### Invoke Micro-App Payment Page (JavaScript) Source: https://developer.mosapp.app/guide/auto-subscription.html This JavaScript code snippet demonstrates how to invoke the micro-app payment page to initiate a subscription. It requires the 'mos' object and handles the payment completion logic based on the result. ```javascript const payRes = await mos.subscribe({ subscribeAmount: "16.99", currency: "USD", billingCycle: "CONTINUOUS_MONTHLY_SUBSCRIPTION", billingCycleDesc: "Monthly Continuous Renewal", notifyUrl: "https://yourdomain.com/mos/pay/callback", extData: "your bisiness data", }); const { result } = payRes; if (result === "SUCCESS") { // Business logic after payment completion, such as redirecting to payment completion page } ``` -------------------------------- ### Detect PC Environment using JS-SDK (JavaScript) Source: https://developer.mosapp.app/guide/multi-platform-adaptation.html This JavaScript code snippet demonstrates how to detect if a micro-app is running in a PC environment using the `mos.getAppBaseInfo()` API from the JS-SDK. It checks the 'platform' property of the returned information to identify Windows, macOS, or Linux operating systems. ```javascript // Example code if (window.mos) { window.mos.getAppBaseInfo().then((info) => { if (info.platform === 'WINDOWS' || info.platform === 'MAC' || info.platform === 'LINUX') { // PC-specific logic } }) } ``` -------------------------------- ### Configure Micro-app Display Orientation (JSON) Source: https://developer.mosapp.app/guide/multi-platform-adaptation.html The `config.json` file is used to set the global display orientation for micro-apps. Developers can specify either 'portrait' or 'landscape' mode. This configuration ensures the app adheres to the intended layout for the target device. ```json { "deviceOrientation": "portrait" } ``` -------------------------------- ### Mini App Login Controller Endpoint Source: https://developer.mosapp.app/guide/login.html This Java Spring Boot controller defines a REST endpoint for Mini App login. It accepts `LoginAo` parameters, validates them, and delegates the actual login process to the `MiniAppCommonService` to obtain a `TokenVo`. ```java @RestController @RequestMapping("/mp/") public class MiniAppController { /** * The Mini-app common service. */ @Resource private MiniAppCommonService miniAppCommonService; /** * Mini-app login * * @param param the login parameters * @return the token */ @PostMapping("/login/miniAppLogin") public TokenVo miniAppLogin(@RequestBody @Validated LoginAo param) { // Directly call the common login method provided by the common module to get Token ``` -------------------------------- ### Mini-App Backend Service: Core Functionality (Java) Source: https://developer.mosapp.app/guide/payment.html This Java code implements the core logic for interacting with the Mos mini-app backend service. It handles request signing, making HTTP calls using RestTemplate, and parsing responses. The `call` method is a private utility that manages the entire request lifecycle, from building the request object and generating the signature to sending the request and processing the response. It includes error logging for failed requests and ensures that only successful responses with a 'code' of 200 are processed. Dependencies include Spring Boot, Fastjson2 for JSON manipulation, and Hutool for utility functions like MD5 hashing (though not directly shown in the `call` method, it's implied by `MiniAppUtil.generateSignature`). ```java import cn.hutool.crypto.digest.MD5; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.TypeReference; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.Map; import java.util.TreeMap; /** * Mini-app payment common service * * @author tom */ @Slf4j @Component public class MiniAppPayService { /** * Mos mini-app call address */ @Value("${mos.mini-app.base-url}") private String baseUrl; /** * Mos mini-app appKey */ @Value("${mos.mini-app.app-key}") private String appKey; /** * Mos mini-app appSecret */ @Value("${mos.mini-app.app-secret}") private String appSecret; private final RestTemplate restTemplate; public MiniAppPayService() { SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory(); httpRequestFactory.setConnectTimeout(30000); httpRequestFactory.setReadTimeout(60000); this.restTemplate = new RestTemplate(httpRequestFactory); } /** * Request Mos server mini-app open interface * * @param uri Interface URI * @param ao Request parameters * @param clazz Response type * @return Response object */ private T call(String uri, BaseSignedAo ao, Class clazz) { // Signature ao.setAppKey(this.appKey); Map data = JSON.parseObject(JSON.toJSONString(ao), new TypeReference>() { }); String sign = MiniAppUtil.generateSignature(data, this.appSecret); ao.setSign(sign); // Send request String url = this.baseUrl + uri; ResponseEntity responseEntity = restTemplate.postForEntity(url, ao, String.class); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { log.error("Mini-app request exception uri={} ao={}", uri, JSON.toJSONString(ao)); return null; } // Parse response code(int) message(String) data(T) JSONObject result = JSON.parseObject(responseEntity.getBody()); if ((int)result.get("code") != 200) { log.error("Mini-app request exception uri={} ao={} result={}", uri, JSON.toJSONString(ao), JSON.toJSONString(result)); return null; } return JSON.to(clazz, result.get("data")); } public PrepayOrderVo prepay(CreatePrepayOrderAo ao) { return this.call("/open-apis/mp/v1/pay/prepay", ao, PrepayOrderVo.class); } public OrderQueryVo orderQuery(OrderQueryAo ao) { return this.call("/open-apis/mp/v1/pay/orderQuery", ao, OrderQueryVo.class); } @Data public static class BaseSignedAo { /** * Mini-app appKey */ @NotNull private String appKey; /** * Signature */ @NotNull private String sign; } @Data @AllArgsConstructor @NoArgsConstructor public static class CreatePrepayOrderAo extends BaseSignedAo { /** * mcId */ @NotNull private String mcId; /** * Random string, must be unique within the system */ private String nonceStr; /** * Order description */ private String desc; /** * Merchant mini-app system order number */ @NotNull private String outTradeNo; /** * Currency unit USD-Dollar KHR-Riel */ @NotNull private String currency; /** * Order amount */ @NotNull private String totalAmount; /** * Callback address */ @NotNull private String notifyUrl; /** * openid */ @NotNull private String openid; /** * Order expiration time (timestamp) */ private String expireTime; } @Data public class PrepayOrderVo { /** * Prepay order id */ private String prepayId; } @Data @EqualsAndHashCode(callSuper = true) public class OrderQueryAo extends BaseSignedAo { /** * 32-bit random string, must be unique within the system */ @NotNull private String nonceStr; /** ``` -------------------------------- ### Authenticate Mini App User with Code2Session Source: https://developer.mosapp.app/guide/login.html This Java code demonstrates how to exchange a temporary code obtained from the Mini App login process for a user session. It requires the 'code' parameter and returns user session details like 'openid' and 'sessionKey'. ```java Code2SessionAo ao = new Code2SessionAo().setCode(code); return this.call("/open-apis/mp/v1/auth/code2session", ao, MosSessionVo.class); ``` -------------------------------- ### Invoke MOS Payment Page (JavaScript) Source: https://developer.mosapp.app/guide/payment.html This JavaScript code snippet demonstrates how to invoke the MOS payment page using the `mos.pay()` function. It requires payment details like amount, currency, app key, and prepay ID. After the user completes payment, the result is checked for success, allowing for subsequent business logic implementation. ```javascript const payRes = await mos.pay({ amount: "16.99", currency: "USD", appKey: "your_app_key", prepayId: "your_prepay_id", }); const { result } = payRes; if (result === "SUCCESS") { // Business logic after payment completion, such as redirecting to payment completion page } ``` -------------------------------- ### Generate MD5 Signature for Mosapp API Calls Source: https://developer.mosapp.app/guide/payment-to-user.html This Java code snippet demonstrates how to generate an MD5 signature for API requests. It sorts parameters alphabetically, concatenates them with a secret key, and then computes the MD5 hash. Ensure that the 'sign' parameter and any null or empty values are excluded from the signature calculation. ```java Map sortedData = new TreeMap<>(data); StringBuilder sb = new StringBuilder(); for (Map.Entry entry : sortedData.entrySet()) { if ("sign".equals(entry.getKey()) || entry.getValue() == null || entry.getValue().isEmpty()) { continue; } sb.append(entry.getKey()).append("=").append(entry.getValue().trim()).append("&"); } sb.append("secret=").append(appSecret); return new MD5().digestHex(sb.toString()); ``` -------------------------------- ### Launch Parameters Source: https://developer.mosapp.app/guide/sdk.html Defines the parameters for launching a Mini-App, including sharing and description settings. ```APIDOC ## Launch Parameters ### Description Defines parameters for launching a Mini-App, including sharing options, page description, and image URLs. ### Request Body #### Parameters - **query** (string) - Optional - Launch Parameters. Can include `ogLang`, `ogTitle`, `ogDesc`, `ogImg`, `ogURL` for customizing shared content and language. - **shareDisabled** (string) - Optional - Disable Sharing. `1`: Disabled, `0`: Enabled. - **desc** (string) - Optional - Page Description. Typically the current page title. - **imageUrl** (string) - Optional - Image URL for Mini-App messages. Network image path, https address recommended. - **screenShotDisabled** (string) - Optional - Screenshot setting. `1`: Disable Screenshot, `0`: Auto-screenshot. ### Image Display Rules - If `imageUrl` is provided, it takes precedence. - If `imageUrl` is empty: - `screenShotDisabled=1`: Show default image (no screenshot). - `screenShotDisabled=0`: Use system auto-screenshot. ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure. - **shareLink** (string) - Current page link, e.g. https://mp.mos.me/mp/?query=xxxxx ``` -------------------------------- ### POST /open-apis/application/v1/getApplication Source: https://developer.mosapp.app/guide/backend.html Retrieves information about the Mini-App application. ```APIDOC ## POST /open-apis/application/v1/getApplication ### Description This endpoint retrieves the basic information associated with the Mini-App application, such as its name, key, secret, and status. ### Method POST ### Endpoint `/open-apis/application/v1/getApplication` ### Parameters No specific parameters are required for this endpoint, but the standard signature and `appKey` in the request body are necessary. ### Request Body (Signature and `appKey` are required as per the signature generation rules) ### Response #### Success Response (200) - **appName** (String) - Application name - **appKey** (String) - Application key - **appSecret** (String) - Application secret - **description** (String) - Application description - **status** (Boolean) - Application status - **notifyUrl** (String) - Callback URL #### Response Example ```json { "appName": "MyMiniApp", "appKey": "your_app_key", "appSecret": "your_app_secret", "description": "A sample Mini-App", "status": true, "notifyUrl": "https://example.com/callback" } ``` ``` -------------------------------- ### 1.1.1 Login API Source: https://developer.mosapp.app/guide/sdk.html Initiates the login process for a Mini-App using its appKey. Supports Promise-style invocation. ```APIDOC ## POST /api/login ### Description Initiates the login process for a Mini-App using its appKey. Supports Promise-style invocation. ### Method POST ### Endpoint /api/login ### Parameters #### Request Body - **appKey** (string) - Required - Mini-App appKey ### Response #### Success Response (200) - **result** (string) - 'SUCCESS': Success | 'FAILURE': Failure - **code** (string) - Login credential #### Response Example ```json { "result": "SUCCESS", "code": "login_credential_string" } ``` ```