网游支付SDK客户端文档

1. 申请支付接口

登录4399手机开放平台https://open.4399.cn,点击 [新建游戏] 填写相关信息完成游戏创建, 进入游戏详细页面,选择 [支付SDK] - [配置管理] 填写配置并提交申请。

平台会将所提交申请,先审核成为 测试模式 测试模式 主要是服务器端回调接口联调,该模式下 客户端 调用支付接口直接模拟充值,无充值界面。 测试模式 联调成功后,告知平台开通 正式模式 后进行RMB充值测试。

2. 环境搭建

下载SDK包

SDK下载地址: 点击这里

关联类库项目

Eclipse接入方式:

假设现在你的工程目录名字叫project,下面将具体介绍如何将SDK接入project中

① 将 operate 导入到eclipse中

② 右键点击 operate 工程名→Properties Android

③ 勾选 Is Library →OK

④ 右键点击 project 工程名→ Properties → Add

⑤ 在弹出的对话框中点选资源工程 operate →OK

注意:如果游戏使用Eclipse作为开发IDE,需要手动拷贝uniaccount_classez.jar到应用工程下

若游戏仅支持部分指令集,需要在引入资源工程后将operate\lib\目录下未使用的指令集文件夹删除。

如游戏仅支持arm6(armeabi),即可将其余的x86、arm64-v8a、armeabi-v7a文件夹删除。

Android Studio接入方式:

① 将 operate 导入到Android Studio中

② 游戏主 module 依赖operate

包名要求

联运游戏apk包名必须以  m4399 结尾,如 com.xxx.xxx.m4399

配置Androidmanifest.xml

添加SDK所需权限 和Android11跳转外部应用兼容

    <!--  4399 运营SDK:以下是权限配置,包括第三方SDK需要的,以jar+res 方式接入需要打开以下内容,aar则不需 -->
    <!-- 一般性权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <!-- 一键登录 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <!-- suppress DeprecatedClassUsageInspection -->
    <uses-permission android:name="android.permission.GET_TASKS"/>
	
    <!-- 4399 运营SDK:Android 11兼容,声明所要进行交互的应用包名,主要用于外部授权登录,以jar+res 方式接入需要打开以下内容,aar则不需 -->
    <queries>
        <package android:name="com.m4399.gamecenter" />
        <package android:name="com.tencent.mobileqq" />
        <package android:name="com.sina.weibo" />
        <package android:name="com.tencent.mm" />
    </queries>

注册SDK相关Activity&Service,注意必须放入<application>元素区块内

      
    <!-- 
    4399 运营SDK: 游戏application要注意对 android 9.+ 系统的http请求的兼容配置,参考
    android:networkSecurityConfig="@xml/m4399_network_policy"
    -->
    <application
        android:allowBackup="false"
        android:networkSecurityConfig="@xml/m4399_network_policy">
		
        <!-- 兼容7.0+ 文件访问权限变更 android:authorities="游戏包名.operate.FileProvider" -->
		
        <provider
            android:name="cn.m4399.operate.OpeFileProvider"
            android:authorities="${applicationId}.operate.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/m4399_ope_file_paths" />
		</provider>

        <uses-library android:name="org.apache.http.legacy" android:required="false">
        </uses-library>	
		
        <!-- 
        4399 运营SDK: 以下是 Activity 配置,以jar+res 方式接入需要打开以下内容,aar则不需
	    另外,第三方页面方向有时候需要明确设置,比如支付宝h5页面,可以设置为横屏

        activity的配置不能少于orientation|screenSize|keyboardHidden,这些配置是为了防止Activity被系统或第三方界面强 拉成竖屏时,发生重建而加入的。SDK的Activity支持横屏或竖屏,但不支持横竖屏切换,否则会包初始化问题 -->
		
        <activity
            android:configChanges="orientation|screenSize|keyboardHidden"
            android:multiprocess="false"
            android:name="cn.m4399.operate.permission.PermissionActivity"
            android:screenOrientation="behind"
            android:theme="@style/m4399.Operate.Theme.Transparent"/>

        <activity
            android:configChanges="orientation|screenSize|keyboardHidden"
            android:name="cn.m4399.operate.component.OperateActivity"
            android:screenOrientation="behind"
            android:theme="@style/m4399TranslucentFullscreenActivityTheme"/>
			
        <activity
            android:configChanges="orientation|screenSize|keyboardHidden"
            android:name="cn.m4399.operate.recharge.ui.activity.RechargeActivity"
            android:screenOrientation="behind"
            android:theme="@style/m4399TranslucentFullscreenActivityTheme"/>
		
        <activity
            android:configChanges="orientation|screenSize|keyboardHidden"
            android:name="cn.m4399.operate.deprecated.CommonActivity"
            android:screenOrientation="behind"
            android:theme="@style/m4399TranslucentFullscreenActivityTheme"/>

        <!-- 4399 运营SDK:以下是支付宝 H5 页面Activity -->        
        <activity
            android:configChanges="orientation|keyboardHidden|navigation|screenSize"
            android:exported="false"
            android:name="com.alipay.sdk.app.H5PayActivity"
            android:screenOrientation="behind"
            android:windowSoftInputMode="adjustResize|stateHidden"/>
		
        <!-- 4399 运营SDK:以下是短代充值相关SDK  -->
		
        <activity
            android:configChanges="keyboardHidden|screenSize|orientation"
            android:name="com.arcsoft.hpay100.HPaySdkActivity"
            android:screenOrientation="behind"
            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
			
        <activity
            android:configChanges="keyboardHidden|screenSize|orientation"
            android:name="com.arcsoft.hpay100.web.HPayWebActivity"
            android:screenOrientation="behind"
            android:theme="@style/hpay_custom_confim_dialog"/>
		
        <activity
            android:configChanges="keyboardHidden|screenSize|orientation"
            android:name="com.arcsoft.hpay100.web.HPayWebFullActivity"
            android:screenOrientation="behind"/>
		
        <!-- 4399 运营SDK:以下是一键登录SDK  -->
        <activity
            android:exported="false"
            android:name="cn.com.chinatelecom.account.sdk.ui.PrivacyWebviewActivity"
            android:screenOrientation="behind"
            android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"/>
			
        <activity
            android:exported="false"
            android:name="cn.com.chinatelecom.account.sdk.ui.AuthActivity"
            android:screenOrientation="behind"
            android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"/>
		
        <activity
            android:exported="false"
            android:name="cn.m4399.operate.account.onekey.wo.WoLoginActivity"
            android:screenOrientation="behind"
            android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"/>
			
        
    </application>

注:

1.第三方支付SDK与电信/移动一键登录的Activity需在AndroidManifest.xml中强制配置横竖屏,请游戏方根据游戏的横竖屏要求手工配置landscape|portrait

游戏Activity的配置不能少于orientation|screenSize|keyboardHidden这三项,这些配置是为了防止Activity被系统或第三方界面强 拉成竖屏时,发生重建而加入的。因为Activity重建有可能会因为某些初始化不全,发生crash。

2.SDK的Activity支持横屏或竖屏,但不支持横竖屏切换,缺少orientation|screenSize|keyboardHidden有可能发生初始化问题。

3.关于渠道开关:接入4399SDK的游戏,又希望在多个渠道投放apk,可以打开Manifest中的开关,并且联系运营使用专用打包工具打入渠道标识,但不需要游戏再针对每个渠道单独打包;如果不需渠道标识,请勿打开开关,否则会增加SDK初始化时间。

3. 代码实现

初始化SDK

初始化推荐在游戏初始化过程中进行。

mOpeCenter = OperateCenter.getInstance();
mOpeConfig = new OperateCenterConfig.Builder(this)
    .setGameKey("GAME_KEY")     //设置GameKey
    .setDebugEnabled(false)     //设置DEBUG模式,用于接入过程中开关日志输出,发布前必须设置为false或删除该行。默认为false。
    .setOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)  //设置横竖屏方向,默认为横屏,现支持横竖屏,和180度旋转
    .setSupportExcess(true)     //设置服务端是否支持处理超出部分金额,默认为false
    .setPopLogoStyle(PopLogoStyle.POPLOGOSTYLE_ONE) //设置悬浮窗样式,现有四种可选
    .setPopWinPosition(PopWinPosition.POS_LEFT) //设置悬浮窗默认显示位置,现有四种可选
    .build();
mOpeCenter.setConfig(mOpeConfig);
mOpeCenter.init(activity, new OperateCenter.OnInitGloabListener() {
    // 初始化结束执行后回调
    @Override
    public void onInitFinished(boolean isLogin, User userInfo) {
        assert(isLogin == mOpeCenter.isLogin());
    }

    // 注销帐号的回调, 包括个人中心里的注销和logout()注销方式
    // fromUserCenter区分是否是从悬浮窗-个人中心("4399游戏助手页面")注销的,若是则为true,不是为false
    @Override
    public void onUserAccountLogout(boolean fromUserCenter) {
    }

 // 切换帐号的回调 
 //fromUserCenter区分是否是从"4399游戏助手页面"切换的,若是则为true,不是为false
    @Override
    public void onSwitchUserAccountFinished(boolean fromUserCenter,User userInfo) {

    }
});
是否支持处理超出部分金额也可单独设置
mOpeCenter.setSupportExcess(support);

能否支持处理超出部分金额指在使用SDK充值时,由于用户选择的充值渠道不同,可能造成实际充值金额超出游戏下单时传入的金额。如果游戏服务端能够正确处理超出部分的金额,则本接口传入true。如果无法支持处理超出部分的金额,则传入false,SDK将会根据传入金额自动隐藏无法满足充值金额的渠道(例:开发者设置SupportExcess为false,充值时传入7元,此时4399一卡通中无7元面额的充值卡,此时4399一卡通的充值渠道将自动隐藏)。SupportExcess默认为false。

注:代码中MainActivity为当前Activity.下文的mOpeCenter指OperateCenter实例,通过getInstance()静态方法获得。

用户登录接口

用户在触发登录时,调用该接口,如果SDK内已包含未注销的用户凭证,将自动返回用户信息。如需强制调出登录界面,请使用【用户切换】接口。

mOpeCenter.login(MainActivity.this, new OnLoginFinishedListener() {

    @Override
    public void onLoginFinished(boolean success, int resultCode, User userInfo)
    {
        //登录结束后的游戏逻辑
    }
});

SDK会自动识别用户手机中是否安装了新版的4399游戏盒1.4.1以上版本,如果已安装,自动跳转至游戏盒授权登录。如果未安装,则弹出Web版4399统一登录界面。 在登录成功后,监听器返回的User类型的用户信息中将包含State登录凭证,该信息可用于游戏服务端进行用户信息二次验证。

注:登录后如果未注销,登录状态将一直保持直至登录凭证过期或失效(若用户修改平台账户密码,所有游戏授权凭证将失效,需重新登录)。建议游戏在初始化完成后调用登录状态查询接口查询用户当前登录状态。

获取用户信息

在SDK处于登录状态时,可通过该接口获取当前用户的信息(UID、用户名、昵称、登录凭证)。

注意:

1.防沉迷功能由SDK内部实现,不需要调用其他方法。

2.SDK返回的uid是字符串类型,无需进行类型转换。如有转换整型情况,请直接转换为long类型。强烈建议使用新注册账号进行测试,以免转型后长度溢出问题。

User user = mOpeCenter.getCurrentAccount();

账号切换

当用户需要注销当前登录状态,且同时弹出登录界面时,使用本接口。本接口的监听器类型与【用户登录】接口相同。

mOpeCenter.switchAccount(MainActivity.this, new OnLoginFinishedListener() {

    @Override
    public void onLoginFinished(boolean success, int resultCode, User userInfo)
    {
        //用户账号切换结束后的游戏逻辑
    }
});

用户注销

当用户需要注销当前登录状态时,使用本接口,注销回调在初始化接口回调中统一处理。

mOpeCenter.logout();

游戏关闭

如果游戏已经配置游戏圈、攻略、礼包等功能弹窗内容区域会显示以上功能的相关item,在关闭前,SDK会弹出对话框询问“退出游戏”还是“继续游戏”。

mOpeCenter.shouldQuitGame(MainActivity.this, new OnQuitGameListener() {

    @Override
    public void onQuitGame(boolean shouldQuit) {
        // 点击“退出游戏”时,shouldQuit为true,游戏处理自己的退出业务逻辑
        // 点击“游戏圈”内容区域时,SDK会进入游戏圈(攻略、礼包同上)
        //  点击“继续游戏”时,shouldQuit为false,SDK和游戏都不做任何处理
        if(shouldQuit) {
          //这边做退出游戏操作
        }
    }
});

登录状态查询

查询当前客户端是否有账号登录

boolean isLogin = mOpeCenter.isLogin();

设置服务器ID

当游戏有分服时,在用户选择角色进入分服时,请务必立即通过本接口设置所在服的ID。如果无分服,则可不设置。

//serverid为不超过10位的数字字符串
mOpeCenter.setServer("SERVER_ID");

充值接口

当用户需要充值时,可调用本接口启动充值中心界面。

特别注意:mark为游戏方订单号,最大长度32位,由包含字母或数字组成的唯一字符串,该字段不可为空,不可重复

mOpeCenter.recharge(MainActivity.this,
                je,             //充值金额(元)
                mark,           //游戏方订单号
                productName,    //商品名称
                new OnRechargeFinishedListener() {

                    @Override
                    public void onRechargeFinished(
                        boolean success, int resultCode,
                        String msg)
                    {
                        if(success){
                            //请求游戏服,获取充值结果
                        }else{
                            //充值失败逻辑
                        }
                    }
                });

je充值金额:整型数字,4399充值中心仅支持整数金额充值,最小充值金额1元,最大不超过50000元。 

mark订单号:最大长度32位,支持大小写字母、数字、‘|’(竖线)、‘-’(中划线)、‘_’(下划线),该字段不可为空,不可重复。 

productName商品名称:最长不超过8个字符(尽量不要传入特殊字符,以免造成充值异常)。 如果传入商品名,充值中心将直接显示该商品名称,如果充值金额大于下单时传入的je时,将显示商品名+XXX游戏币,相关游戏币的兑换比例在接入时提供给运营人员配置。如果未传入商品名,则直接显示XXX游戏币。

测试模式

何为测试模式?
游戏申请支付接口,平台会先将该申请设置为测试模式。测试模式需要使用平台指定的账号进行登录,方可测试充值接口,
测试模式调用充值接口不会弹出充值界面,直接模拟充值,主要是与服务器端进行联调,客户端会根据服务器端返回的状态进行显示成功还是异常。

测试模式联调成功后,平台会开通正式模式,进行RMB测试。

获取状态信息

工具接口,用于将回调函数中的resultCode解析为中文的说明(充值接口recharge的resultCode对应的中文是回调中的msg)。

String resultMessage = OperateCenter.getResultMsg(resultCode);

获取SDK版本号

mOpeCenter.getVersion();

检查更新

SDK包含自动更新模块,SDK将检查后台是否有新版本游戏上线,如果有,则显示更新内容,并提示用户升级。 

该升级为增量升级,后台在提交新版游戏时自动制作差分包,更新时用户只需下载APK文件中新旧版本有差异的部分。

相关更新内容和版本提交事宜,请联系4399相关运营对接人员。 

4399SDK的增量升级为全自动增量更新(无需操作,默认初始化完成)

代码混淆

如果您的应用使用了混淆, 请不混淆SDK代码,可以在proguard.cfg文件里追加以下配置。

-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**

-dontwarn cn.m4399.operate.**
-keep class cn.m4399.operate.** {*;}
-keepclassmembers class cn.m4399.operate.R$* {*;}
-keep class com.m4399.gamecenter.** {*;}

-dontwarn com.arcsoft.hpay100.**
-keep class com.arcsoft.hpay100.**{*;}

-dontwarn android.net.**
-keep class android.net.SSLCertificateSocketFactory{*;}
-keep class com.ishumei.** { *; }

-keep class cn.com.chinatelecom.account.** {*;}
-dontwarn com.unicom.xiaowo.account.shield.**
-keep class com.unicom.xiaowo.account.shield.**{*;}

4. 注意事项

1.游戏打包的targetSdkVersion如果高于23,必须使用高于v24.0.0.0的SDK,最好使用最新版本,否则Android 7.0+手机在安装更新包时,会出现文件访问权限问题,而导致游戏崩溃。

2.配置FileProvider时,请务必保证”android:authorities“格式,建议变更后打一个旧版本的包测试下安装(此时会是全量更新)。

3.打包环境 targetSdkVersion >= 26 时,在 Android 8.0+手机上有安装权限问题,导致不能正常安装应用,需要在AndroidManifest中显示地声明权限 android:name="android.permission.REQUEST_INSTALL_PACKAGES"。

4.v2.30.0.12版本已内聚防沉迷实名认证功能,有奖实名功能不可在登录后直接调用,如在登录后直接调用有奖实名接口可能与防沉迷实名认证功能机制冲突,如游戏方开发者此前有调用过有奖实名接口(mOpeCenter.nameAuthentication......),请删除该接口调用,如无调用有奖实名接口者请忽略此项。

5.游戏方开发者如遇到前后台来回切换时导致的黑屏问题,可在游戏的主activity中的onResume()来启动游戏动画播放,在onPause()中移除,此操作可解决前后台来回切换时导致的黑屏问题(无此问题者可直接忽略此项)。