
Name | Type | Required | Default value | Note |
scopes | array of string | True | - | Temporary authorization code scope list, please refer to the scope definition list, usually only USER_LOGIN_ID/USER_AVATAR/USER_NICKNAME/USER_CONTACTINFO_EMAIL is used |
Scope definition | Description |
SCOPE_PHONE_NUMBER | Authorize to obtain the user's phone number |
SCOPE_AVATAR | Authorize to obtain user avatar |
SCOPE_NICKNAME | Authorize to obtain user nickname |
SCOPE_EMAIL | Authorize access to user's email information |
Name | Type | Required | Default value | Note |
authCode | String | True | - | Temporary authorization code |
authErrorScopes | Key-value | True on failure | - | The permission scope for which authorization failed. The key is the permission scope and the value is the error message. |
authSuccessScopes | Array | True on success | - | The scope of authority that is successfully authorized |
wx.login({success: (res) => {console.log(res.code);},fail: (err) => {console.log(err);},});
Parameter | Parameter value | Required | Example | Note |
Content-Type | application/json | True | - | Content-type, the value is always application/json |
X-TIMESTAMP | Request time | True | - | Transaction date and time, in the format of YYYY-MM-DDTHH:mm:ss+07:00. For example, the Jakarta area time must use GMT+7 (Jakarta time) |
X-CLIENT-KEY | Unique identifier | True | - | A unique identifier generated by the partner, also known as clientId |
X-SIGNATURE | Request signature | True | - | Signatures can only be generated using the asymmetricSignature method. |
Name | Type | Required | Default value | Note |
grantType | String | True | AUTHORIZATION_CODE | The request type for requesting a token. The value is AUTHORIZATION_CODE |
authCode | String | True | - | The authorization code is used to redeem the access token, provided by superapp |
Parameter | Parameter value | Required | Example | Note |
Content-Type | application/json | True | - | Content-Type, the value is always application/json |
X-TIMESTAMP | Request time | True | - | Transaction date and time, in the format of YYYY-MM-DDTHH:mm:ss+07:00. For example, the Jakarta area time must use GMT+7 (Jakarta time) |
Name | Type | Required | Conditions | Note |
responseCode | String | True | - | Reference Response Code List |
responseMessage | String | True | - | Reference Response Code List |
tokenType | String | Conditional | responseCode=0 | Token Type |
accessToken | String | Conditional | responseCode=0 | This token is called a customer token and will be used in the header parameter "Authorization-Customer" of other APIs |
accessTokenExpiryTime | String | Conditional | responseCode=0 | The expiration time of the access token is provided to the user in the format of YYYY-MM-DDTHH:mm:ss+07:00. The time must be GMT+7 (Jakarta time) |
refreshToken | String | Conditional | responseCode=0 | This token is used to refresh the session when the existing token expires |
refreshTokenExpiryTime | String | Conditional | responseCode=0 | The expiration time of the refresh token is provided to the user in the format of YYYY-MM-DDTHH:mm:ss+07:00. The time must be GMT+7 (Jakarta time) |
additionalInfo | JSON object | Optional | - | Additional information |
additionalInfo.userInfo | JSON object | Optional | - | Additional information about the user. Contains user ID |
Content-Type: application/jsonX-TIMESTAMP: 2020-12-18T15:06:00+07:00{"responseCode": "2007400","responseMessage": "Successful","accessToken": "SQoHkw1tSfWsULjf3qrWpPqimAQi6IxcgmvO4200","tokenType": "Bearer","accessTokenExpiryTime": "2031-11-02T11:31:19+07:00","refreshToken": "NEcnzX7Aq2vv5Ot08ZDSmCzfO4aEWhnWTpbf4200","refreshTokenExpiryTime": "2031-11-02T11:31:19+07:00","additionalInfo": {"userInfo": {"publicUserId": "21779009320193133"}}}
Response code | Response message | Note | superapp operations |
2007400 | Successful | Processing succeeded. | Mark the token request process as successful |
4007400 | Bad Request | General request failure error | Mark the token request process as failed. Retry the request with the correct parameters |
4007401 | Invalid field format | The specific field format is invalid | Mark the token request process as failed. Retry the request with the correct parameters |
4007402 | Invalid required field | Required fields are missing or in invalid format | Mark the token request process as failed. Retry the request with the correct parameters |
4017400 | Not authorized. [reason] | General unauthorized error | Mark the token request process as failed. Retry the request with the correct parameters |
4297400 | Too many requests | Exceeding the maximum transaction limit | Mark the token request process as failed. Retry requests periodically |
5007400 | General error | General errors that are not retryable | Mark the token request process as failed. Retry requests periodically |
5007401 | Internal Server Error | Unknown internal server failure, please retry the process | Mark the token request process as failed. Retry requests periodically |
Total timeout | - | Total timeout, the client did not get any response from the server (maybe due to network problems, server slowdown, etc.) | Retry up to 3 times, sending the same request payload. If it still fails, mark the token application process as pending. |
Unexpected response (field is empty/field does not exist/undefined response code) | - | The server did not produce the expected response (possibly due to hardware failure, errors, etc.) | - If the response code prefix is 202 and 5XX, mark the token application process as pending - If the field is empty/does not exist, mark the token request process as pending |
Parameter | Required | Example | Note |
version | True | - | API version. According to the corresponding API reference |
Function | True | - | According to the specifications defined by each business area Value: dana.omniprod.openapi.oauth.userInfoInquiry.scopes |
clientId | True | - | Client identifier provided by superapp to identify partners and application systems |
clientSecret | False | - | Serves as the client's key. The client key assigned during registration |
reqTime | True | - | Request time, in the format of YYYY-MM-DDTHH:mm:ss+07:00. For example, the Jakarta area time must use GMT+7 (Jakarta time) |
reqMsgId | True | - | Identifies a unique system request. Each request will be assigned a unique identifier (UUID) |
accessToken | True | - | |
reserve | False | - | Reserved for future implementation (key/value) |
Name | Type | Required | Default value | Note |
scopes | array of string | True | - |
{"request": {"head": {"version": "1.0","function": "dana.omniprod.openapi.oauth.userInfoInquiry.scopes","clientId": "2022083116021575310778","clientSecret": "c1643a8a0eb1a19cbe817a5766de7a5f27db1f3e5e14c6c432e4e5fc8cbdcd51","accessToken": "pZHmQBs0B2SCrY8Q7rO0bvaztwe73Tmw9QcU6500","reqTime": "2020-06-09T23:24:26+07:00","reqMsgId": "8939eu9821u3891","reserve": "{}"},"body": {"scopes": ["USER_LOGIN_ID", "KYC_INFO"]}},"signature": "signature string"}
Name | Type | Required | Default value | Note |
version | String | True | - | API version. According to the corresponding API reference |
Function | String | True | - | According to the specifications defined by each business area Value: dana.omniprod.openapi.oauth.userInfoInquiry.scopes |
clientId | String | True | - | Client identifier provided by superapp to identify partners and application systems |
clientSecret | String | False | - | Serves as the client's key. The client key assigned during registration |
respTime | String | True | - | Response time, in the format of YYYY-MM-DDTHH:mm:ss+07:00. For example, Jakarta time must use GMT+7 (Jakarta time) |
reqMsgId | String | True | - | Identifies a unique system request. Each request will be assigned a unique identifier (UUID) |
accessToken | String | True | - | Contains the customer token, which has been obtained from the binding process. Please refer to the account binding and unbinding document |
reserve | String | False | - | Reserved for future implementation (key/value) |
Name | Type | Required | Default value | Note |
resultInfo | JSON object | True | - | Define the details of the result information |
userInfo | String | True | - | User information is encrypted using AES-128 |
{"response": {"head": {"version": "1.0","function": "dana.omniprod.openapi.oauth.userInfoInquiry.scopes","clientId": "2022083116021575310778","clientSecret": "c1643a8a0eb1a19cbe817a5766de7a5f27db1f3e5e14c6c432e4e5fc8cbdcd51","respTime": "2020-06-09T23:24:26+07:00","reqMsgId": "8939eu9821u3891","reserve": "{}"},"body": {"resultInfo": {"resultStatus": "S","resultCodeId": "00000000","resultCode": "SUCCESS","resultMsg": "success"},"userInfo": "/g99a8dkY989hABjn3A=="},"signature": "signature string"}}
{"response": {"head": {"version": "1.0","function": "dana.omniprod.openapi.oauth.userInfoInquiry.scopes","clientId": "2022083116021575310778","clientSecret": "c1643a8a0eb1a19cbe817a5766de7a5f27db1f3e5e14c6c432e4e5fc8cbdcd51","respTime": "2020-06-09T23:24:26+07:00","reqMsgId": "8939eu9821u3891","reserve": "{}"},"body": {"resultInfo": {"resultStatus": "S","resultCodeId": "00000000","resultCode": "SUCCESS","resultMsg": "success"},"userInfo": {"USER_LOGIN_ID": "62-85707121623","USER_KTP_NAME": "ahmad irfaan","USER_GENDER": "1","USER_KTP_ID": "124337489","USER_BIRTH_OF_PLACE": "Madrid","USER_BIRTHDAY": "2000-01-01","USER_ADDRESS_KYC": {"ADDRESS": "A","PROVINCE": "B","CITY": "C","DISTRICT": "D","SUB_DISTRICT": "E","POSTAL_CODE": "1"},"USER_MARITAL_STATUS": "10","USER_OCCUPATION": ""}}},"signature": "signature string"}
- (void)getAuthCode:(TMFMiniAppInfo *)app params:(NSDictionary *)params completionHandler:(MACommonCallback)completionHandler {NSString *token = [DemoUserInfo sharedInstance].token;if(token.length <= 0) {if(completionHandler) {NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"app not login"};completionHandler(nil,[NSError errorWithDomain:@"TCMPPLoginErrorDomain" code:-1001 userInfo:userInfo]);}return;}NSArray *scopeList = params[@"scopes"];NSString *appId = [[TMFMiniAppSDKManager sharedInstance] getConfigAppKey];NSArray *selectedScopes = [[[DemoUserInfo sharedInstance] scopeList] allKeys];[[LoginManager sharedInstance] getAuthCode:token appId:appId scopes:selectedScopes completionHandler:^(NSError * _Nullable err, NSDictionary* _Nullable datas) {if(err) {if(completionHandler) completionHandler(nil,err);} else {if(datas) {NSString *authCode = datas[@"authCode"];NSArray *authSuccessScopes = datas[@"authSuccessScopes"];NSString *code = datas[@"code"];if(completionHandler) {if(authCode.length <=0 && code.length <= 0) {completionHandler(@{@"authCode":authCode,@"authSuccessScopes":authSuccessScopes?:@[]},nil);} else {if(authCode.length >0) {completionHandler(@{@"authCode":authCode,@"authSuccessScopes":authSuccessScopes?:@[]},nil);} else {completionHandler(@{@"code":code,@"authSuccessScopes":authSuccessScopes?:@[]},nil);}}}} else {if(completionHandler) {NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"authCode is null"};completionHandler(nil,[NSError errorWithDomain:@"TCMPPLoginErrorDomain" code:-1002 userInfo:userInfo]);}}}}];}
@ProxyService(proxy = MiniOpenApiProxy.class)public class MiniOpenApiProxyImpl extends MiniOpenApiProxy {private static final String TAG = "MiniOpenApiProxyImpl";@Overridepublic void getAuthCode(IMiniAppContext miniAppContext, JSONObject params, AsyncResult result) {QMLog.d(TAG, "getAuthCode:" + params);JSONObject ret = new JSONObject();try {if (params == null) {ret.put("errno", -1);ret.put("errMsg", "invalid params");result.onReceiveResult(false, ret);return;}LoginApi.UserInfo userInfo = Login.g(miniAppContext.getContext()).getUserInfo();if (userInfo == null || TextUtils.isEmpty(userInfo.token)) {ret.put("errno", -2);ret.put("errMsg", "invalid token, please login app first");result.onReceiveResult(false, ret);return;}JSONArray scopes = params.optJSONArray("scopes");// Convert scopes to superapp's own scope// String[] scopeArr = scopeList.toArray(new String[0]);AuthApi.INSTANCE.getAuthCode(Login.g(miniAppContext.getContext()).getAppId(),userInfo.token, scopeArr, new MiniCallback<AuthApi.AuthCodeInfo>() {@Overridepublic void value(int code, String msg, AuthApi.AuthCodeInfo data) {try {if (code == 0) {if (data != null) {if (data.authSuccessScopes != null && data.authSuccessScopes.length > 0) {JSONObject ret = new JSONObject();try {ret.put("authCode", data.authCode);ret.put("code", data.code);ret.put("authSuccessScopes", new JSONArray(data.authSuccessScopes));result.onReceiveResult(true, ret);} catch (JSONException e) {result.onReceiveResult(false, ret);}} else {ret.put("authCode", data.authCode);ret.put("code", data.code);result.onReceiveResult(true, ret);}} else {ret.put("errno", -3);ret.put("errMsg", "invalid authCode");result.onReceiveResult(false, ret);}} else {ret.put("errno", code);ret.put("errMsg", msg);result.onReceiveResult(false, ret);}} catch (JSONException e) {result.onReceiveResult(false, ret);}}});} catch (JSONException e) {result.onReceiveResult(false, ret);}}}

<button bindtap='login' loading="{{isLoading}}">Authorized login</button>
import Config from './utils/configData';const app = getsuperapp();Page({<i>data</i>: {isLoading: false,},login: function () {this.setData({isLoading: true})wx.login({success: (res) => {console.log('wx.login success===', res)if (res.code) {wx.request({url: `${Config.BASEURL}/getUserInfo`,method: "POST",<i>data</i>: {appid: Config.APPID,code: res.code},success: (res) => {this.setData({isLoading: false})console.log('wx.request success===', res)const { code = -1, data = {} } = res?.data || {};if (code === 200) {wx.showToast({title: ?Logged in successfully',icon: 'success',duration: 500})// Or store via wx.setStorageapp.globalData.userInfo = {avatarUrl: data.avatarUrl,account: data.account,nickName: data.userName,id: data.id,token: data.token,phoneNumber: data.phone,emailAddress: data.email}setTimeout(() => {wx.navigateBack({delta: 1})}, 500)} else {const msg = res?.data?.data?.msg || '/getUserInfo request fail'const errcode = res?.data?.data?.errcode || codeconsole.log('/getUserInfo request fail', res)wx.showModal({title: ?Login failed',confirmText: ?Confirm',content: `/getUserInfo fail:${msg}[code:${errcode}]`,showCancel: false})}},fail: (err) => {this.setData({isLoading: false})console.log('wx.request fail', err)wx.showModal({title: ?Login failed',confirmText: ?Confirm',content: err.errMsg,showCancel: false})},})} else {this.setData({isLoading: false})console.log('wx.login does not return code', res)wx.showModal({title: ?Login failed',confirmText: ?Confirm',content: res.errMsg,showCancel: false})}},fail: (err) => {this.setData({isLoading: false})console.log('wx.login fail===', err)wx.showModal({title: ?Login failed',confirmText: ?Confirm',content: err.errMsg,showCancel: false})}})}})
`${Config.BASEURL}/getUserInfo` API, which is called by the mini program. The purpose of this API is to exchange a code for a unique user identifier and establish the login state of the mini program.GET https://xxx.xxx.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
Feedback