MiTV and MiBox Game Developer Guide (for Online Game) V1.0.1 2013-11-29 Modify history: Date Version Modify history 2013/11/08 1.0.1 The First Version Definition of Terms: Name of Terms Chinese name Definition mibi 米币 Virtual currency issued by xiaomi company,used for mobile payment MIUI 米柚操作系统 SDK 开发包 cpOrderId 订单号 Generated by developers’ Servers productCode 商品代码 Generated by developers, make sure it's unique in game , Only Single Player Game need applying Product Code appId App 的唯一编号 AppId is generated by xiaomi game center server, each game has a unique id, which is a number appKey App 的密钥 Needed when invoking SDK OfflineGame 单机游戏 Including weak networking games OnlineGame 网络游戏 1. XiaoMi game center 1.1. Introduction Xiaomi game center is released for all Miphone, MiBox, MiTV and MIUI users by xiaomi company. The whole center, striving to create a better Android ecosystem, includes many quality resources such as MIUI system, develop SDK,internet website,xiaomi Forum etc.. Xiaomi game center provides an easy and quick access of downloading, searching, charging(support online and single player) of games, it is the best choice for game developers. 1.2. Xiaomi account Xiaomi account is used for xiaomi.com, MIUI and MiTalk. Until now, there are more than 80 million registered users. The main registering method is binding a mobile phone number or an email address, the registered users could also enjoy xiaomi cloud service, voice assistant, MiTalk, game center service and so on. When signing in xiaomi account, users can use xiaomi ID,mobile phone number or email as the login name, easy and quickly. 1.3.Mibi Mibi is issued by xiaomi company, used for virtual production payment, like Qbi. Mibi has the characteristics of circulation in all xiaomi virtual production platform. Users could charge through xiaomi accounts(Buy Mibi via RMB), and pay for all the production in xiaomi and its cocompany production platform. 1RMB=1Mibi, the smallest unit is 1 cent, so something could be priced at 0.01Mibi . The Mibi amount spent by users for applications are the basis for settlement for the incoming of developers. 1.4.Quick start Before reading the belows, it is highly recommended that you install the two Demo programs(SDK_Demo_OfflineGame.apk and SDK_Demo_OnlineGame.apk) distributed with this document into MiTV or MiBox. Because the two programs demonstrate the whole work flow of xiaomi game SDK, and it is helpful to understand our SDK payment flow. 2.Production design and Implementation Notes 2.1.Online Game 2.1.1 Online Game flow outline The developers of online games need to manage the users' login and record the login status. When starting games, the user must invoke miLogin() to determine whether the user session is timeout, and invoke miUniPayOnline() to recharge in game if necessary. A typical business flow is as follows: 2.1.2 Online Game user account and login process Note: 1. UID is not Mi ID, but there is a relationship between them; 2. Developers must use UID as user's identification, not IMEI or IMSI; 3. In the future, Xiaomi game center will support one Mi ID corresponds to multiple UIDs, enabling users to create multi-roles in one game. 2.1.3 Mibi recharge process for online game users 2.1.4 Position of game icons for MiBox and MiTV Create four directories in directory 'res' of apk for the two game icons(For MiBox and MiTV): 1.drawable-mdpi 2.drawable-tvdpi 3.dawable-hdpi 4.drawable-xhdpi Put the icon for MiTV in drawable-hdpi and drawable-xhdpi Put the icon for MiBox in drawable-mdpi and drawable-tvdpi 2.1.5 SDK invoke methods As for developers, only need to add the following code to realize the single player game payment. 2.1.5.1Initialize Please obtain AppId and AppKey first, then invoke the following SDK initialization code to initialize the operation. Put MiGameCenterSDKService.apk of SDK package into the 'assets' directory of application, and SDK's jar the 'libs', referenced in buildpath, then initialize SDK.(Note: Check whether the package name of the game is the same with the package name of xiaomi server configuration, whether the Appid and Appkey are consistent with the applied. If not consistent, it would be failed when invoke login and other SDK interfaces.). Please invoke the following initialization method in Application.onCreate. MiAppInfo appInfo = new MiAppInfo(); appInfo.setAppId("Developer applied"); appInfo.setAppKey("Developer applied"); appInfo.setAppType(MiGameType.online); // online game MiCommplatform.Init( this, appInfo ); The permission that SDK needs to add: <uses-permission android:name="android.permission.GET_TASKS" /> 2.1.5.2 Code of Xiaomi account login MiCommplatform.getInstance().miLogin( context, new OnLoginProcessListener() { @Override public void finishLoginProcess( int code, MiAccountInfo arg1 ) { switch( code ) { case MiErrorCode.MI_XIAOMI_GAMECENTER_SUCCESS: // login successfully //get UID of user(unique ID) String uid = arg1.getUid(); //get login session of user(please refer to 2.1.6.3 User session verification interface) String session = arg1.getSessionId();//return null if not login //developers submit uid and session to their own servers to do session verification break; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_LOGIN_FAIL: // login failed break; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_CANCEL: // cancel login break; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_ACTION_EXECUTED: //login is in processing break; default: // login failed break; } } } ); The Login result can be captured by implementing the interface of OnLoginProcessListener. 2.1.5.3 Virtual currency recharge invoke MiBuyInfoOnline online = new MiBuyInfoOnline(); online.setCpOrderId(UUID. randomUUID().toString());//unique order ID(not null) online.setCpUserInfo( “cpUserInfo” ); //This parameter will be passed to CP server after user’s successful payment. online.setMiBi( 10 ); // Must be an integer greater than 1, 10 means 10 Mibi, which is 10 RMB(not null) //User information*Required* Bundle mBundle = new Bundle(); mBundle.putString( GameInfoField.GAME_USER_BALANCE, "1000" ); //User balance mBundle.putString( GameInfoField.GAME_USER_GAMER_VIP, "vip0" ); //vip level mBundle.putString( GameInfoField.GAME_USER_LV, "20" ); //User ' s role level mBundle.putString( GameInfoField.GAME_USER_PARTY_NAME, "hunter" ); //Party mBundle.putString( GameInfoField.GAME_USER_ROLE_NAME, "meteor" ); //Role name mBundle.putString( GameInfoField.GAME_USER_ROLEID, "123456" ); //Role ID mBundle.putString( GameInfoField.GAME_USER_SERVER_NAME, "valley" ); //The server where user ' s role is MiCommplatform. getInstance().miUniPayOnline(activity, online, new OnPayProcessListener() { @Override public void finishPayProcess( int code ) { switch ( code ) { case MiErrorCode.MI_XIAOMI_GAMECENTER_SUCCESS: // purchased successfully break ; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_PAY_CANCEL : // cancel purchase break ; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_PAY_FAILURE : // purchase failed break ; case MiErrorCode.MI_XIAOMI_GAMECENTER_ERROR_ACTION_EXECUTED: // processing break ; default : // purchase failed break ; } } }); Parameter Description: Parameter name usage remark cpOrderId Developer's order Required. ID 20~100 characters, must be generated by CP’s business server. This parameter is important because Xiaomi Game Center server will notifiy CP’s business server the payment result after the order is successfully paid. cpUserInfo Parameter passed Required . to online game Used for pass user info, this parameter will be passed to CP’s business server after user’s successful payment. (Can not be null or “”) mibi Purchased Required. quantity of Mibi Type is int, which means 1 Mibi can only buy the corresponding virtual currency. 2.1.6 Server interface Developers should recharge the virtual currency for users based on Xiaomi Game Center server’s notification. 2.1.6.1.Order notification interface 2.1.6.1.1 Process Description: After successful payment of the order, xiaomi game center will notify the developer's server provided in advance with the payment result. If the developer's server cannot be accessed, within a certain period of time, game center server would do the checking cycle(The former 10 times, notifying once a minute; then once an hour) Specific procedures are as follows: Note: Due to the asynchronous notification model,(3) and (4) may not follow the sequence, so (4) and (5) need to be checked cyclically, or use the interface to query the payment result. Compared to the later-mentioned developer's active query order mode, we recommend using this one. 2.1.6.1.2Interface and Parameters Description: Interface address: Please submit the address with <MiBox and MiTV Game SDK Application>. Request method: GET Request Parameter Description: Parameter Optional Description appId Required appId cpOrderId Required Developer's order ID cpUserInfo Optional Developer information uid Required User ID orderId Required Game center order ID orderStatus Required Order status name TRADE_SUCCESS means successful payFee Required Payment amount, unit is cent, which is 0.01MI. productCode Required Product code productName Required Product name productCount Required Product quantity payTime Required Payment time, format: yyyy-MM-dd HH:mm:ss signature Required Signature. Signature method description is in below. Response Parameter Description: Parameter Importance Description Required Status code, 200 success name errcode 1506 cpOrderId error 1515 appId error 1516 uid error 1525 signature error 3515 order info inconsistent, used for order's verification with CP errMsg Optional error message Note: Developers must guarantee that product be delivered only once for the same order's multiple notifications. 2.1.6.2. Active query order payment status interface 2.1.6.2.1 Process Description: This interface is provided for developers by Xiaomi Game Center. 2.1.6.2.2 Interface and Parameter Description: Interface address: http://mis.migc.xiaomi.com/api/biz/service/queryOrder.do Request method: GET Request Parameter Description: Parameter Optional Description appId Required appId cpOrderId Required Developer's order ID uid Required User ID signature Required Signature. Signature method description is name in below. Response Parameter Description(Correct): Parameter Optional Description appId Required appId cpOrderId Required Developer's order ID cpUserInfo Optional Developer information uid Required User ID orderId Required Order ID orderStatus Required Order status name TRADE_SUCCESS means successful WAIT_BUYER_PAY means not paid yet REPEAT_PURCHASE means order already exists payFee Required Payment amount, unit is cent, which is 0.01MI. productCode Required Product code productName Required Product name productCount Required Product quantity payTime Required Payment time, format: yyyy-MM-dd HH:mm:ss signature Required Signature. Signature method description is in below. Response Parameter Description(Error): Parameter Importance Description Required Status code, 200 success name errcode errMsg Optional 1506 cpOrderId error 1515 appId error 1516 uid error 1525 signature error Error message description 2.1.6.3. User session verification interface 2.1.6.3.1 Process Description: This interface is provided for developers by Xiaomi Game Center, using for verifying the login account. Note: The user's unique identifier is uid acquired from SDK, not Session. Session is used for verifying login. The verification must be based on three-part: SDK, Xiaomi Game Center server and developers's server. If Session is invalid, miLogin() should be re-callback to login. 2.1.6.3.2 Interface and Parameter Description: Interface address: http://mis.migc.xiaomi.com/api/biz/service/verifySession.do Request method: GET Request Parameter Description: Parameter Optional Description appId Required appId session Required User session ID uid Required User ID signature Required Signature. Signature method description is name in below. Response Parameter Description: Parameter Importance Description Required Status code, 200 verification correct name errcode errMsg Optional 1515 appId error 1516 uid error 1520 session error 1525 signature error Error message description Interface Format Description: Input parameters: ?parameter1=value1&parameter2=value2&...& parameterN=valueN, values required to do UrlEncode under the circumstances. Response parameters: use json format, for example:{“Response parameters1”:”Response value1”,“Response parameters2”:”Response value2”,...“Response parametersN”:”Response valueN”} Signature method description : 1. Generate the string with signature All parameters in the table are in alphabetical sequence(Excluding signature), if the first letters are same, then sort by the second letters, and so on. The generated string, which needs to be signed, is in the format like this: par1=val1&par2=val2&par3=val3. The parameter with no value will not be involved in the signature. Because some data are based on the HTTP protocol, the receiver needs URLencoding to get the right parameter, but if this parameter is involved in the signature, the generated string, which needs to be signed, must be the original value, not the URLencoding value. 2. Signature Algorithm Use appKey as key, and the hash algorithm of hmac-sha1 with secret to make the signature calculation of the generated string. The result is showed in hexadecimal. About the hash algorithm of hmac-sha1 with secret, please refer to appendix. 3. FAQ 3.1.APK packaged and release Note: SDK package is provided to developers in jar package, which is already in code obfuscation status, please add the following codes to your own 'proguard.cfg' to avoid a second code obfuscation when you obfuscate your own APK package. public <init>(...); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } 3.2.Online game server signature method Hmac-SHA1 algorithm in java: import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class HmacSHA1Encryption { private static final String MAC_NAME = "HmacSHA1"; private static final String ENCODING = "UTF-8"; /** * Use HMAC-SHA1 signature method to sign the encryptText * @param encryptText The signed string * @param encryptKey Secret key * @return Return the encrypted string * @throws Exception */ public static String HmacSHA1Encrypt( String encryptText, String encryptKey ) throws Exception{ byte[] data = encryptKey.getBytes( ENCODING ); // According to the given byte array to construct a key, the second parameter specifies the name of a key algorithm SecretKey secretKey = new SecretKeySpec( data, MAC_NAME ); // Generate a Mac instance of a specified Mac algorithm Mac mac = Mac.getInstance( MAC_NAME ); // Initialize the Mac instance with the given key mac.init( secretKey ); byte[] text = encryptText.getBytes( ENCODING ); // Complete Mac operation byte[] digest = mac.doFinal( text ); StringBuilder sBuilder = bytesToHexString( digest ); return sBuilder.toString(); } /** * Change to Hex * * @param bytesArray */ public static StringBuilder bytesToHexString( byte[] bytesArray ){ if ( bytesArray == null ){ return null; } StringBuilder sBuilder = new StringBuilder(); for ( byte b : bytesArray ){ String hv = String.format("%02x", b); sBuilder.append( hv ); } return sBuilder; } /** * Use HMAC-SHA1 signature method to sign the encryptText * * @param encryptData The signed string * @param encryptKey Secret key * @return Return the encrypted string * @throws Exception */ public static String HmacSHA1Encrypt( byte[] encryptData, String encryptKey ) throws Exception{ byte[] data = encryptKey.getBytes( ENCODING ); // According to the given byte array to construct a key, the second parameter specifies the name of a key algorithm SecretKey secretKey = new SecretKeySpec( data, MAC_NAME ); // Generate a Mac instance of a specified Mac algorithm Mac mac = Mac.getInstance( MAC_NAME ); // Initialize the Mac instance with the given key mac.init( secretKey ); // Complete Mac operation byte[] digest = mac.doFinal( encryptData ); StringBuilder sBuilder = bytesToHexString( digest ); return sBuilder.toString(); } } 3.3.Error Code Code Meaning 200 Success System error Database 1002 error 1001 Code Meaning CP ID error AppId 1515 error 1514 1516 uid error Http 1004 request error Channel 1517 number error Account 1518 status error Repeat 1005 Request Product id 1519 error Cache 1003 error Json Parse error RSA signature 1007 public key or private key error 1006 1520 Session error Mobile 1521 number error Code Meaning Recharge amount error Recharge type 1536 error Recharge order 1537 NO. error 1535 1538 Void signature 1539 Paging query Max ID Each page 1540 record NO. error Payment time 1541 error 1542 Pages Numbers when paging Code 3001 Meaning Product not exist or already removed 3004 Mibi amount error 3005 Authentication failed 3301 Get Mibi account error 3302 Order create error 3303 Card payment invoke error 3501 Order processing 3502 Order processing timeout No request 1501 parameter 1522 IP 1502 Authentica tion Error 1523 1503 1504 1505 1506 1507 1508 1509 Message NO. error Network Element error MI id error CP order NO. error Order Amount Error Payment Error Order id error Payment 1510 order id error Payment 1511 result error Payment 1512 amount error Order type 1513 error Order info inconsiste nt, used 3515 for order's verificati on with CP 1524 1525 1526 1527 Product price error Purchased quantity error No signature parameter Verify signature error ApkName error ApkSign error 1543 Start time Order processing 3510 failed, unknown reason 1544 End time 3511 Order not exist 1545 Order request time error 3512 Order paid 1546 Removed applications 3513 Input parameter miBi error 3514 Order already exists Insufficient money Repeat 2002 transaction 2001 4000 AuthToken expired 1528 SdkVersion Code error 2003 Signature error 4001 AuthToken illegal 1529 Card value error 2004 Repeat recharge 4002 ServiceToken expired 1530 CpUserInfo error 2005 Recharge order not exist 4003 Get serviceToken failed Collate 1531 start time error Collate 1532 end time error 1533 Parameter p error Order 1534 descriptio n error 2006 2007 2008 2009 Recharge order status not exist Business system public key not exist Charging system private key not exist Network element not exist Verify 4004 serviceToken failed 4005 Cancellation failure Upload games that 4006 users played failed 4007 Modify user information error