# 渠道登录与支付

> 来源：https://help.gravity-engine.com/docs/gravity-dock/integration/account-and-payment
> 使用统一 Android 接口调用渠道登录、登出、实名与支付，绑定玩家与商户订单，并区分客户端提示和服务端发货。
> 文档修改日期：2026-11-06




## 渠道登录 [#渠道登录]

在可交互的 Activity 中调用 `GravityDockSDKAccount.login(activity, listener)`，实现 `GravityDockSDKAccountListener`：

```java
import com.gravitydock.sdk.GravityDockSDKAccount;
import com.gravitydock.sdk.GravityDockSDKAccountListener;

import org.json.JSONObject;

GravityDockSDKAccount.login(activity, new GravityDockSDKAccountListener() {
    @Override
    public void onLoginSuccess(JSONObject properties) {
        // 读取 userId 关联玩家，进入游戏自己的账号流程
        // 登录成功后上报登录事件（内部自动 flush）
        GravityDockSDKTrack.trackLoginEvent();
    }

    @Override
    public void onLoginFail(String msg) {
        // 保持未登录状态，提示失败或恢复登录入口
    }

    @Override
    public void onLoginCancel() {
        // 用户取消登录
    }

    @Override
    public void onLogout() {
        // 渠道触发登出，清理游戏侧账号状态，回到登录流程
        // 登出后上报登出事件（内部自动 flush）
        GravityDockSDKTrack.trackLogoutEvent();
    }

    @Override
    public void onRealName() {
        // 实名认证完成，接入游戏实名认证后续流程
    }

    @Override
    public void onAntiAddiction() {
        // 防沉迷到期，渠道要求登出玩家
    }
});
```

回调处理要点：

| 回调                                          | 游戏侧处理                         |
| ------------------------------------------- | ----------------------------- |
| `onLoginSuccess(JSONObject properties)`     | 读取 `userId` 关联玩家，进入游戏自己的账号流程。 |
| `onLoginFail(String msg)`、`onLoginCancel()` | 保持未登录，提示失败或恢复登录入口。            |
| `onLogout()`                                | 清理游戏侧账号状态，回到登录流程。             |
| `onRealName()`、`onAntiAddiction()`          | 接入游戏实名认证后续流程及防沉迷退出。           |

SDK 会校验渠道凭证并维护 Dock 玩家会话。自有游戏服务端应通过自身可信的会话机制管理玩家身份，避免仅凭客户端上传的 `userId` 认领游戏账号。

### 账号辅助接口 [#账号辅助接口]

按渠道能力按需调用，不支持的渠道自动忽略：

| 方法                                    | 说明                                         |
| ------------------------------------- | ------------------------------------------ |
| `GravityDockSDKAccount.logout()`      | 登出当前玩家，建议随后调用 `trackLogoutEvent()` 上报登出事件。 |
| `GravityDockSDKAccount.userCenter()`  | 拉起渠道用户中心（切换账号、绑定等）。                        |
| `GravityDockSDKAccount.hasRealName()` | 返回当前玩家是否已完成实名认证。                           |
| `GravityDockSDKAccount.realName()`    | 拉起渠道实名认证流程。                                |

## 渠道支付 [#渠道支付]

在发起支付前，游戏服务端先创建商户订单，记录玩家、角色、区服、商品及应付金额。一次购买应使用同一个商户订单号，便于幂等与对账。

```java
import com.gravitydock.sdk.GravityDockPayParams;
import com.gravitydock.sdk.GravityDockSDKPay;
import com.gravitydock.sdk.GravityDockSDKPayListener;
import com.gravitydock.sdk.GravityDockSDKTrack;

import org.json.JSONObject;

// extra 为 JSONObject，包含该订单的角色和区服等信息，服务端发货通知会原样带回
JSONObject extra = new JSONObject();
try {
    extra.put("role_id", "10086");
    extra.put("server_id", "s1");
} catch (Exception ignore) {
}

GravityDockPayParams params = new GravityDockPayParams.Builder(1.00)
    .merchantOrderNo(merchantOrderNo)
    .productId("sku-1")
    .productName("60钻石")
    .productDesc("60钻石礼包")
    .productCount(1)
    .paypointCode("gravity_dock_product_1")
    .ext(extra)
    .build();

GravityDockSDKPay.pay(activity, params, new GravityDockSDKPayListener() {
    @Override
    public void onPaySuccess(JSONObject properties) {
        // 客户端仅用于更新支付界面
        // 支付成功后上报付费事件（payAmount 单位：分，内部自动 flush）
        GravityDockSDKTrack.trackPayEvent(100, "CNY",
                merchantOrderNo, "60钻石", "GravityDock");
    }

    @Override
    public void onPayFail(String msg) {
        // 支付失败，可调用 GravityDockSDKTrack 上报失败原因用于排查
    }

    @Override
    public void onPayCancel() {
        // 用户取消支付
    }
});
```

`GravityDockPayParams.Builder` 参数说明：

| 参数                        | 说明                                   |
| ------------------------- | ------------------------------------ |
| `Builder(double amount)`  | 应付金额，单位为元。                           |
| `merchantOrderNo(String)` | 商户订单号，同一笔购买保持唯一且幂等，必传。               |
| `productId(String)`       | 商品 ID，游戏侧自定义计费点。                     |
| `productName(String)`     | 商品名称，会展示在渠道收银台，游戏侧自定义品名描述。           |
| `productDesc(String)`     | 商品描述，选填。                             |
| `productCount(int)`       | 购买数量，默认 1。                           |
| `paypointCode(String)`    | 计费点 Key。开启计费点支付的渠道必传，须与渠道管理中配置的映射一致。 |
| `ext(JSONObject)`         | 透传参数，如角色、区服，随发货通知返回游戏服务端。            |

> **注意**
> 客户端 `onPaySuccess` 回调只代表渠道侧购买流程结束，**游戏道具由服务端收到[签名通知](/docs/gravity-dock/integration/payment-notifications)并校验订单后发放**，切勿仅凭客户端回调发货。支付待确认时，应核对原订单再决定下一步，避免用新订单盲目重复扣款。

支付成功后建议调用 `GravityDockSDKTrack.trackPayEvent` 上报付费事件（金额单位为分），用于渠道投放回收分析，详见[数据上报](/docs/gravity-dock/integration/event-tracking)。
