- 按金额付费,以小米应用支付服务器通知的结果为准为用户进行虚拟币充值。所以必须提供接收订单支付结果通知的地址(必选)
- 按计费代码计费,也可以提供接收订单支付结果通知的地址(可选)
- 服务器代码示例下载地址,密码:aa11。 包含签名实现,登录验证,订单查询,回调接口,有php和java的示例
一、订单支付结果通知(必选)
1、流程说明
此接口由开发者负责开发并在开发者后台进行配置。在订单支付成功后,小米应用支付服务器会将支付结果通知给开发者预先提供的服务器上。若开发者所提供的服务器地址不可用,在一定时间段内游戏平台服务器会按照周期进行轮询(前10次,每分钟通知1次;10次后每小时通知1次)。 具体流程如下:

注:由于是异步通知模型,(3)和(4)不一定是按序号产生。因此(4)和(5)需要进行轮询处理或者使用接口进行支付结果查询。 相比后面提到的开发者主动查询订单的模式,我们推荐使用此模式。
2、接口及参数说明
- 接口地址:各开发者服务器的通知地址(提前申请,在小米开发者站进行配置,要求配置https接口)
- 请求方法:GET
请求参数说明
名称 | 重要性 | 说明 |
appId | 必须 | 游戏ID |
cpOrderId | 必须 | 开发商订单ID |
cpUserInfo | 可选 | 开发商透传信息 |
uid | 必须 | 用户ID |
orderId | 必须 | 游戏平台订单ID |
orderStatus | 必须 | 订单状态,TRADE_SUCCESS 代表成功 |
payFee | 必须 | 支付金额,单位为分,即0.01米币。(请务必使用payFee字段值与游戏发起订单金额做校验,确保订单金额一致性) |
productCode | 必须 | 商品代码 |
productName | 必须 | 商品名称 |
productCount | 必须 | 商品数量 |
payTime | 必须 | 支付时间,格式 yyyy-MM-dd HH:mm:ss |
orderConsumeType | 可选 | 订单类型:10:普通订单11:直充直消订单 |
partnerGiftConsume | 可选 | 使用游戏券金额 (如果订单使用游戏券则有,long型),如果有则参与签名 |
signature | 必须 | 签名,签名方法见后面说明 |
注意:如果开发者允许使用游戏礼券则必须使用partnerGiftConsume参数,否则使用游戏礼券的消费订单会出现掉单情况。
例如:
https://ccc.com/notify.do?appId=2882303761517239138&cpOrderId=9786bffc-996d-4553-aa33-f7e92c0b29d5&orderConsumeType=10&orderId=21140990160359583390&orderStatus=TRADE_SUCCESS&payFee=1&payTime=2014-09-05%2015:20:27&productCode=com.demo_1&productCount=1&productName=%E9%93%B6%E5%AD%901%E4%B8%A4&uid=100010&signature=1388720d978021c20aa885d9b3e1b70cec751496
返回参数说明
名称 | 重要性 | 说明 |
errcode | 必须 | 状态码: 200 成功 1506 cpOrderId 错误 1515 appId 错误 1516 uid 错误 1525 signature 错误 3515 订单信息不一致,用于和 CP 的订单校验 |
errMsg | 可选 | 错误信息 |
注意:对于同一个订单号的多次通知,开发商要自己保证只处理一次发货。 例如: {"errcode":200}
服务器IP地址
42.62.48.246
223.202.68.237
42.62.103.0/26 (42.62.103.1 ~ 42.62.103.62)
120.134.34.0/26 (120.134.34.1 ~ 120.134.34.62)
124.251.57.0/24 (124.251.57.0 ~ 124.251.57.255)
120.133.84.0/24 (120.133.84.0~120.133.84.255)
220.181.100.0/24(220.181.100.0~220.181.100.255)
101.126.25.119
101.126.27.120
101.126.29.31
请开发商服务器开发人员加到ip白名单内,以免因为ip限制造成回调不成功。
二、主动查询订单支付状态接口(可选)
此接口由小米为开发者提供。
1、流程说明

2、接口及参数说明
- 接口地址:https://mis.migc.xiaomi.com/api/biz/service/queryOrder.do
- 请求方法:GET
请求参数说明
名称 | 重要性 | 说明 |
appId | 必须 | 游戏ID |
cpOrderId | 必须 | 开发商订单ID |
uid | 必须 | 用户ID |
signature | 必须 | 签名,签名方法见后面说明 |
例如:
https://mis.migc.xiaomi.com/api/biz/service/queryOrder.do?appId=2882303761517239138&cpOrderId=9786bffc-996d-4553-aa33-f7e92c0b29d5&uid=100010&signature=e91d68b864b272b6ec03f35ee5a640423d01a0a1
正确返回参数说明
名称 | 重要性 | 说明 |
appId | 必须 | 游戏ID |
cpOrderId | 必须 | 开发商订单ID |
cpUserInfo | 可选 | 开发商透传信息 |
uid | 必须 | 用户ID |
orderId | 必须 | 游戏平台订单ID |
orderStatus | 必须 | 订单状态, TRADE_SUCCESS 代表成功 WAIT_BUYER_PAY 代表未支付 REPEAT_PURCHASE 订购关系已经存在 |
payFee | 必须 | 支付金额,单位为分,即0.01米币。(请务必使用payFee字段值与游戏发起订单金额做校验,确保订单金额一致性) |
productCode | 必须 | 商品代码 |
productName | 必须 | 商品名称 |
productCount | 必须 | 商品数量 |
payTime | 必须 | 支付时间,格式 yyyy-MM-dd HH:mm:ss |
orderConsumeType | 可选 | 订单类型:10:普通订单11:直充直消订单 |
signature | 必须 | 签名,签名方法见后面说明 |
例如:
{
"signature": "eb30240cff8c66f856ec0e48354aa670b8cf037f",
"uid": "100010",
"appId": 2882303761517239300,
"cpOrderId": "9786bffc-996d-4553-aa33-f7e92c0b29d5",
"productCode": "com.demo_1",
"orderStatus": "TRADE_SUCCESS",
"productName": "%E9%93%B6%E5%AD%901%E4%B8%A4",
"productCount": 1,
"orderConsumeType": "10",
"orderId": "21140990160359583390",
"payFee": 1,
"payTime": "2014-09-05 15:20:27"
}
错误返回参数说明
名称 | 重要性 | 说明 |
errorcode | 必须 | 状态码: 1506 cpOrderId 错误 1515 appId 错误 1516 uid 错误 1525 signature 错误 |
errMsg | 可选 | 错误信息 |
三、用户session验证接口(必选)
此接口由小米应用支付为开发者提供,用于验证登录账户的有效性。
注意:用户的唯一标识是通过SDK获得的uid,而不是Session,Session用于校验登录验证的有效性,必须经过SDK、游戏中心服务器、开发者服务器进行三方验证,如果Session失效,需要重新调用miLogin()进行登录。
1、流程说明

2、接口及参数说明
- 接口地址:https://mis.migc.xiaomi.com/api/biz/service/loginvalidate
- 请求方法:POST
- Headers:Content-Type: application/x-www-form-urlencoded
请求参数说明
名称 | 重要性 | 说明 |
appId | 必须 | 游戏ID |
session | 必须 | 用户sessionID |
uid | 必须 | 用户ID |
signature | 必须 | 签名,签名方法见后面说明 |
例如:
POST https://mis.migc.xiaomi.com/api/biz/service/loginvalidate
appId=2882303761517239138&session=1nlfxuAGmZk9IR2L&uid=100010&signature=b560b14efb18ee2eb8f85e51c5f7c11f697abcfc
返回参数说明
名称 | 重要性 | 说明 |
errcode | 必须 | 状态码: 200 验证正确 1515 appId 错误(注意格式问题:比如appId必须是数字以及是否没传) 1516 uid 错误 1520 session 错误 1525 signature 错误 4002 appid, uid, session 不匹配(常见为session过期) |
errMsg | 可选 | 错误信息 |
adult | 可选 | 用户实名标识: 406 非身份证实名方式 (建议当做已实名成年用户处理) 407 实名认证通过,年龄大于18岁 408 实名认证通过,年龄小于18岁 409 未进行实名认证 |age|可选|用户年龄 |
age | 可选 | 用户年龄 |
例如:
{ "errcode": 200,"adult":409 }
四、接口格式说明
输入参数:?参数1=值1&参数2=值2&....&参数n=值n,如果遇到文本参数值,需要根据情况对参数值做 UrlEncode。
返回参数:在回调的时候,是 http get方式发送请求,参数拼接在url后面,你们的服务器返回的数据 要求是json格式的,如:{"errcode":200}这种格式。
五、signature签名方法说明
- 生成带签名字符串表中各参数按字母顺序排序(不包含signature),如果第一个字母相同,按第二个字母排序,依次类推。排序后拼接成par1=val1&par2=val2&par3=val3的格式,所生成的字符串即为待签名的字符串。没有值的参数请不要参与签名。由于有些数据根据HTTP协议需求,需要进行URLencoding,这样接收方才可以接收到正确的参数,但如果这个参数参与签名,那么待签名字符串必须是字符串原值而非URLencoding的值。 例如(具体参数请以收到的为准,不要依据此示例修改参数):
在订单通知接口收到的回调信息如下:
appId=2882303761517239138&cpOrderId=9786bffc-996d-4553-aa33-f7e92c0b29d5&orderConsumeType=10&orderId=21140990160359583390&orderStatus=TRADE_SUCCESS&payFee=1&payTime=2014-09-05%2015:20:27&productCode=com.demo_1&productCount=1&productName=%E9%93%B6%E5%AD%901%E4%B8%A4&uid=100010&signature=1388720d978021c20aa885d9b3e1b70cec751496
这时候需要对每个参数的值进行URLdecode,decode后的字符如下:
appId=2882303761517239138&cpOrderId=9786bffc-996d-4553-aa33-f7e92c0b29d5&orderConsumeType=10&orderId=21140990160359583390&orderStatus=TRADE_SUCCESS&payFee=1&payTime=2014-09-05 15:20:27&productCode=com.demo_1&productCount=1&productName=银子1两&uid=100010&signature=1388720d978021c20aa885d9b3e1b70cec751496
而需要进行签名的字符串为:
appId=2882303761517239138&cpOrderId=9786bffc-996d-4553-aa33-f7e92c0b29d5&orderConsumeType=10&orderId=21140990160359583390&orderStatus=TRADE_SUCCESS&payFee=1&payTime=2014-09-05 15:20:27&productCode=com.demo_1&productCount=1&productName=银子1两&uid=100010
签名算法以AppSecret作为key,使用hmac-sha1带密钥(secret)的哈希算法对待签字符串进行签名计算。签名的结果由16进制表示。密钥对应的值为开发者站申请到的AppSecret。
hmac-sha1 带密钥(secret)哈希算法的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";
/**
* 使用 HMAC-SHA1 签名方法对对encryptText进行签名
* @param encryptText 被签名的字符串
* @param encryptKey 密钥
* @return 返回被加密后的字符串
* @throws Exception
*/
public static String HmacSHA1Encrypt( String encryptText,
String encryptKey ) throws Exception{
byte[] data = encryptKey.getBytes( ENCODING );
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKey secretKey = new SecretKeySpec( data, MAC_NAME );
// 生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance( MAC_NAME );
// 用给定密钥初始化 Mac 对象
mac.init( secretKey );
byte[] text = encryptText.getBytes( ENCODING );
// 完成 Mac 操作
byte[] digest = mac.doFinal( text );
StringBuilder sBuilder = bytesToHexString( digest );
return sBuilder.toString();
}
/**
* 转换成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;
}
/**
* 使用 HMAC-SHA1 签名方法对对encryptText进行签名
*
* @param encryptData 被签名的字符串
* @param encryptKey 密钥
* @return 返回被加密后的字符串
* @throws Exception
*/
public static String hmacSHA1Encrypt( byte[] encryptData, String encryptKey ) throws Exception{
byte[] data = encryptKey.getBytes( ENCODING );
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKey secretKey = new SecretKeySpec( data, MAC_NAME );
// 生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance( MAC_NAME );
// 用给定密钥初始化 Mac 对象
mac.init( secretKey );
// 完成 Mac 操作
byte[] digest = mac.doFinal( encryptData );
StringBuilder sBuilder = bytesToHexString( digest );
return sBuilder.toString();
}
}