跳到正文

YuPay 插件间 API

本页专注于其他插件如何接入 YuPay。命令、权限、PlaceholderAPI 和 Bukkit 事件已拆到独立页面:

接入前提

  • YuPay 通过 Bukkit ServicesManager 暴露 YuPayApi,也提供 YuPayProvider.get() 快捷获取方法。
  • API 方法大多返回 CompletableFuture,回调不保证在主线程;如需修改 Bukkit 玩家、背包、世界或 GUI,请调度回主线程。
  • 生产接入必须在请求里设置 sourcePlugin,并在 api.allowed-plugins 中逐项授权。
  • 商城、礼包、活动插件通常创建 noReward 订单,然后由调用方在支付成功后自行发货。

获取 YuPayApi

java
import org.yutay.yupay.api.YuPayApi;
import org.yutay.yupay.api.YuPayProvider;

YuPayApi api = YuPayProvider.get();
if (api == null) {
    // YuPay 未安装、未启用或服务尚未注册
    return;
}

也可以直接使用 Bukkit 服务:

java
RegisteredServiceProvider<YuPayApi> provider =
        Bukkit.getServicesManager().getRegistration(YuPayApi.class);
YuPayApi api = provider == null ? null : provider.getProvider();

创建订单

java
import org.bukkit.entity.Player;
import org.yutay.yupay.api.YuPayApi;
import org.yutay.yupay.api.YuPayOrderRequest;

public void createShopOrder(YuPayApi api, Player player, String shopOrderId) {
    YuPayOrderRequest request = YuPayOrderRequest
            .builder(player.getUniqueId(), player.getName(), 19.9)
            .payMethod("wechat")
            .sourcePlugin("ExampleShop")
            .externalOrderId(shopOrderId)
            .businessType("SHOP")
            .metadataJson("{\"item\":\"vip_30d\"}")
            .expireMinutes(10)
            .noReward(true)
            .build();

    api.createOrder(request).thenAccept(result -> {
        if (!result.isSuccess()) {
            player.sendMessage("订单创建失败: " + result.getMessage());
            return;
        }
        player.sendMessage("订单号: " + result.getOrderId());
        player.sendMessage("支付链接: " + result.getQrUrl());
    });
}
字段说明
sourcePlugin调用方插件名,用于 API 权限控制和审计。生产接入必须设置。
externalOrderId外部业务订单号,用于商城订单、礼包订单等业务绑定。
businessType业务类型,例如 SHOPVIPREDEEMCUSTOM
metadataJson / metadata业务元数据,YuPay 只保存和返回,不解释业务含义。
expireMinutes单订单过期分钟数;0 表示使用 YuPay 全局过期配置。
noReward是否跳过 YuPay 内部奖励。第三方商城通常设为 true,由调用方监听订单完成后发货。

常用 API

API用途
getOrder(sourcePlugin, orderId)查询订单详情。
getLatestPendingOrder(sourcePlugin, playerUuid)查询玩家最近待支付订单。
listOrders(sourcePlugin, type, limit, offset)按类型分页查询订单。
cancelOrderDetailed(sourcePlugin, orderId, reason)取消指定待支付订单,并返回详细结果。
cancelLatestPendingOrder(sourcePlugin, playerUuid, reason)取消玩家最近待支付订单。
refundOrderDetailed(sourcePlugin, orderId, amount, reason)直接退款,返回平台/本地处理结果。
retryReward(sourcePlugin, orderId)重试 YuPay 内部奖励步骤。
listRewardSteps(sourcePlugin, orderId)查看发奖步骤流水。
expirePendingOrders(sourcePlugin)触发待支付订单过期清理。
getDefaultPayMethod()获取默认支付方式。
isPayMethodAvailable(payMethod)判断支付方式是否可用。
generateOrderId(playerUuid, noReward)生成 YuPay 风格订单号。
createPaymentQrImage(qrUrl, size)生成二维码图片;免费版可能自动带 YuPay 标识。
isFreeEditionBrandingRequired()免费版是否要求支付展示带 YuPay 品牌。
getFreeEditionAdLink()免费版广告官网链接,付费版可为 null

退款示例

java
api.refundOrderDetailed("ExampleShop", orderId, 19.9, "商城订单取消")
        .thenAccept(result -> {
            if (result.isSuccess()) {
                getLogger().info("退款已提交/完成: " + result.getRefundStatus());
            } else {
                getLogger().warning("退款失败: " + result.getCode() + " " + result.getMessage());
            }
        });

API 授权配置

资金相关 API 会经过 api.allowed-plugins 校验。建议最小授权,例如商城插件只给创建、取消、查询订单权限,不给退款和绕过奖励权限:

yaml
api:
  enabled: true
  require-plugin-declaration: true
  audit-log: true
  default-permissions:
    create-order: false
    cancel-order: false
    query-order: false
    refund-order: false
    retry-reward: false
    no-reward-order: false
    expire-orders: false
  allowed-plugins:
    ExampleShop:
      create-order: true
      cancel-order: true
      query-order: true
      refund-order: false
      retry-reward: false
      no-reward-order: true
      expire-orders: false
权限项允许的 API 能力
create-ordercreateOrder 创建支付订单。
cancel-ordercancelOrder*cancelLatestPendingOrder*
query-ordergetOrder*listOrders*listRewardSteps*
refund-orderrefundOrder*,资金风险最高。
retry-rewardretryReward 重试 YuPay 内部奖励。
no-reward-order允许 API 创建跳过 YuPay 内部奖励的订单。
expire-ordersexpirePendingOrders 触发过期清理。

接入建议

  • 对第三方插件必须设置 sourcePlugin,并在 allowed-plugins 中逐项授权。
  • 商城或礼包插件建议创建 noReward 订单,然后监听 PaymentCompletedEvent 或查询订单状态后自行发货。
  • 退款 API 和直接退款命令涉及真实资金,建议启用审计日志并限制到少数可信身份。
  • 监听事件后如需操作 Bukkit 玩家、背包、世界、GUI,请使用 Bukkit.getScheduler().runTask(...) 回到主线程。