目录
1、SDK组成和接口说明

SDK公开的接口包括:


1.1、Purchase API说明

Purchase对象是SDK提供给开发者发起订购,查询的接口。
开发者在实例化该对象后,调用其中的函数可以处理相应的业务。


构造实例:


Purchase对象的创建使用了单例模式,不需要重复创建:


       purchase = Purchase.getInstance();
      


各参数设置:



       purchase.setAppInfo(appid, appkey); // 设置计费应用ID和Key (必须)
          purchase.setTimeout(10000, 10000); // 设置超时时间(可选),可不设置,缺省都是10s
   


初始化:


Init(),初始化函数。此函数主要实现用户身份数字证书申请。开发者须在APP初始化中调用,这样可减少用户在订购,查询业务中的等待时间。
(注:强联网IAP2.3以上版本,Init()函数会在应用首次启动时会弹出“MM伴我移动生活”的LOGO。如果无此LOGO,将无法通过测试中心的测试,从而影响应用商用流程。测试方法详见《IAP2.3以上版本应用启动时初始化SDK测试方案》。)


        purchase.init(context, listener); //初始化,传入监听器
      

调用后,请等待onInitFinish()完成后,再发起其他业务请求,否则其他业务不会处理。


订购:


调用Purchase对象中的order函数,传入相应的参数:
1. payCode,计费点(见本文档2.3)
2. orderCount,订购数量。(包月、约定租期和不可重复订购计费点只能传入1,可重复订购计费点可以传入10以下数值)
3. nextCycle, 对于租赁类业务,可以预订下一期租赁周期。
4. Listener,本参数是开发实现OnPurchaseListener对象的实例,主要用于监听各个业务的结果。
5. data,本参数是可透传到开发者服务器的自定义数据,长度为64字节以内。


           // 订购一个商品
           String tradeid = purchase.order(context, paycode, listener); 
           // 订购5个商品
           String tradeid = purchase.order(context, paycode, 5, listener); 
            // 租赁当前周期
           String tradeid = purchase.order(context, MONTH_PAYCODE, 1, false, listener); 
           // 租赁下一周期
           String tradeid = purchase.order(context, MONTH_PAYCODE, 1, true, listener);
           // 调用购买接口并传入自定义数据
           String tradeid = purchase.order(context, paycode, 1, data, true, listener);
          

订购返回的tradeid代表当次交易ID,可以在查询接口中传入该交易ID查询交易有无成功订购具体的结果在OnPurchaseListener中的onBillingFinish()中获得。
如果未能初始化成功,或者之前未调用init(),那么第一次订购,会申请用户身份数字证书,导致第一次订购时间略长。


查询:


调用Purchase对象中的query函数,传入相应参数:
payCode,计费点(见本文档2.3)
TradeID, 调用order()接口返回的交易ID,用于查询交易是否成功
Listener,本参数是开发实现OnPurchaseListener对象的实例,主要用于监听各个业务的结果。


     // 查询单次或者租赁类商品是否订购成功
      purchase.query(context, paycode, listener);
     // 带交易ID查询重复类商品是否交易成功
     purchase.query(context, paycode, tradeid, listener);
    


退订:


调用Purchase对象中的unsubscribe函数,传入相应参数:
payCode,计费点(见本文档2.4)
Listener,本参数是开发实现OnPurchaseListener对象的实例,主要用于监听各个业务的结果。


     // 退订包月业务
            purchase.unsubscribe(context, Paycode, Listener);
    

注意:目前只有包月业务允许退订。其他类型业务均不允许退订。

1.2、OnPurchaseListener

应用内计费各种操作(查询,订购)监听器。开发者通过实现该接口中各个接口来监听各种业务操作的状态:


     // 初始化返回接口
      void onInitFinish(final int returnCode)
     // 查询返回接口
     void onQueryFinish(final int returnCode, final HashMap returnObject)
      // 订购返回接口:
      void onBillingFinish(final int returnCode, final HashMap returnObject) 
     //退订返回接口:
     public void onUnsubscribeFinish(final int returnCode)
   

Returncode的定义在PurchaseCode类中,具体含义可以通过getDescription()获取。

1.3、OnPurchaseListener中返回数据说明

正如前面所描述的一样,初始化,查询,订购接口的返回值在OnPurchaseListenr中得到。returnObject中定义的数据主要有几种:


     // 订单号 
     public final static String ORDERID = "OrderId";
     // 计费点代码 
     public final static String PAYCODE = "Paycode";
     // 租赁剩余时间 
      public final static String LEFTDAY = "LeftDay";
     // 交易ID
     public final static String TRADEID = "TradeID";
     //订购类型
      public final static String ORDERTYPE = "OrderType";
   

上面这些值包含在onXXFinish中参数Hashmap中。各个接口返回的数据不一样。
上面这些值所代表的意义如下:
OrderId,表示此次订单,mm平台形成的订单流水号
Paycode,表示此次交易的商品id
LeftDay,表示此次交易商品的有效期。
TradeID,表示此次交易的交易ID,供查询用。
OrderType,表示此次交易的类型。如果返回0,则表示是生成测试订单;如果返回1,则表示生成正式订单。


初始化接口


初始化接口不返回任何数据。


订购接口


订购接口在订购成功后,会返回上面5个值。如果订购失败,则不返回上面任何值。


查询接口


查询接口在查询成功后,返回上面的OrderId,Paycode ,LeftDay这三个值。失败则不返回任何值。

1.4、AndroidManifest 设置

此版本需要开发者在AndroidManifest.xml中增加iap声明。


1、打开应用的AndroidManifest.xml文件,增加权限和内部Service 与 Activity声明



   <service 
android:name="mm.purchasesdk.iapservice.PurchaseService"
android:exported="true" >
<!-- android:process="mm.iapServices" > -->
<intent-filter android:priority="230" >
<action android:name="com.aspire.purchaseservice.BIND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter android:priority="230" >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAFIAP.COMPONENT" >
</category>
</intent-filter>
</service>
<!-- android:excludeFromRecents="true" -->
<!-- android:launchMode="singleInstance" -->
<activity
android:name="mm.purchasesdk.iapservice.BillingLayoutActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.Translucent">
<intent-filter android:priority="230" >
<action android:name="您程序的包名.com.mmiap.activity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- android:process="safiap.framework.safframeworkmanager" begin -->
<service
android:name="safiap.framework.SafFrameworkManager"
android:exported="true"
android:process="safiap.framework" >
<intent-filter android:priority="600" >
<!-- ID for services declared in AIDL -->
<action android:name="safiap.framework.sdk.ISAFFramework" />
</intent-filter>
<intent-filter android:priority="600" >
<!-- ID for services declared in AIDL -->
<action android:name="safiap.framework.ACTION_START_DOWNLOAD" />
</intent-filter>
<intent-filter android:priority="600" >
<!-- ID for services declared in AIDL -->
<action android:name="safiap.framework.ACTION_CHECK_UPDATE" />
</intent-filter>
</service>
<!-- receivers -->
<receiver android:name="safiap.framework.CheckUpdateReceiver" >
<intent-filter>
<action android:name="safiap.framework.ACTION_CANCEL_NOTIFICATION" />
</intent-filter>
<intent-filter>
<action android:name="safiap.GET_SHARED_DATA" />
</intent-filter>
<intent-filter>
<action android:name="safiap.framework.ACTION_SET_TIMER" />
</intent-filter>
</receiver>
<activity
android:name="safiap.framework.ui.UpdateHintActivity"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:configChanges="orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="safiap.framework.ACTION_TO_INSTALL" />
</intent-filter>
<intent-filter>
<action android:name="safiap.framework.ACTION_TO_INSTALL_IAP" />
</intent-filter>
<intent-filter>
<action android:name="safiap.framework.ACTION_NETWORK_ERROR_IAP" />
</intent-filter>
<intent-filter>
<action android:name="safiap.framework.ACTION_NETWORK_ERROR_FRAMEWORK" />
</intent-filter>
</activity>
<service android:name="safiap.framework.logreport.monitor.handler.LogreportHandler" android:process=":remote"/>
<!-- android:process="safiap.framework.safframeworkmanager" end -->

</application>


2、Action声明(重点)


在上述声明中,需要注意声明BillingLayoutActivity中的Action


     <activity 
android:name="mm.purchasesdk.iapservice.BillingLayoutActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.Translucent">
<intent-filter android:priority="230" >
<action android:name="com.aspire.demo.com.mmiap.activity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

请将action声明为您程序的包名.com.mmiap.activity


3、增加权限声明



     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
      <uses-permission android:name="android.permission.READ_SMS" />

以确保可以正常读取手机的IMSI/IMEI,读取和网络访问。

2、SDK调用时序

2.1、构造及初始化



注意:
1. 构造函数中的needCache参数,是用于指定是否缓存授权文件。如果授权文件缓存在本地,那么之后的鉴权将会首先在本地进行,减少不必要的网络交互。 建议对于无时间限制的一次性计费点,如关卡,缓存授权文件。而对于租赁类的计费点,建议不缓存,这样可以在后台获取精确的状态。
2. 开发者需要在在游戏或者程序启动是调用初始化接口init(),比如界面进入时,调用初始化方法init(),这样可以避免在计费过程中申请用户身份数字证书,以节省一些时间
3. 一旦调用了初始化方法init(),在init()没有完成之前,调用其他的业务接口(查询、订购、退订)是不允许的。所以应用最好在监听器中等到初始化结束(不管成功失败),再允许订购。
4. Init()方法不是必须调用的,是为了优化用户体验,提供出来,如果某些业务场景不适合这种做法,也可以直接调用业务接口。


2.2、查询



注意:
1. 由于版权文件采用了预置方式,所以onBeforeDownload/onAfterDownload这两个接口被调用的可能性很小。
2. 只有在数字证书无效或者未申请的情况下,才会触发onBeforeApply/onAftreApply。并不是每次都会被调用。
3. 查询到已成功的订单,可以拿到orderID


2.3、订购



注意:
1. 本期SDK在触发订购之后,接管全部UI,所以应用在调用order接口之后不需要做任何处理, 所有UI处理均已由SDK处理。
2. onBillingFinish()方法在订购界面退出后,才会返回给应用。
3. 鉴权成功或者订购成功,均会返回OrderID