取消授权

授权完成后,您需为买家提供授权协议取消功能,主要原因如下:

  • 保障买家对其授权协议的自主管理权,允许买家根据个人账户安全策略或服务使用需求,随时终止已建立的授权关系。
  • 由于部分支付方式存在系统级限制,同一电子钱包账户在单一商户维度仅允许维持一个或者少量有效授权凭证。

处理取消授权

买家取消授权的场景分为以下两种,您需要针对具体场景执行不同的操作:

  • 如果买家在商户侧发起取消授权,您需要调用 取消授权 接口进行处理。
  • 如果买家在支付方式侧取消授权,取消授权成功后您将收到通知。

买家在商户侧取消授权

如果买家在您的应用内取消授权,您需要调用 取消授权 接口使支付方式的支付令牌失效。

在接口请求中传入该代扣服务对应的支付令牌(accessToken),接口调用成功后可使该支付令牌(accessToken)失效。以下是调用 取消授权 接口的代码示例:

copy
public static void Cancel() {
    AlipayAuthRevokeTokenRequest alipayAuthRevokeTokenRequest = new AlipayAuthRevokeTokenRequest();

    // 替换为您的 accessToken
    alipayAuthRevokeTokenRequest.setAccessToken("281010033AB2F588D14B43238637264FCA5Axxxx");

    AlipayAuthRevokeTokenResponse alipayAuthRevokeTokenResponse = null;
    try {
        alipayAuthRevokeTokenResponse = CLIENT.execute(alipayAuthRevokeTokenRequest);
    } catch (AlipayApiException e) {
        String errorMsg = e.getMessage();
        // 处理错误情况
    }
}

以下是请求报文的代码示例:

copy
{
  "accessToken": "281010033AB2F588D14B43238637264FCA5Axxxx"
}

以下是响应的代码示例:

copy
{
  "result": {
    "resultCode": "SUCCESS",
    "resultStatus": "S",
    "resultMessage": "Success"
  }
}

下表展示了 取消授权 接口的响应报文中 result.resultStatus 字段可能返回的值,请您根据指引进行处理。您也可以根据 授权结果通知 发送给您的授权取消结果进行处理。

result.resultStatus

信息

后续操作

S

取消授权成功。

无需进一步操作。

U

取消授权状态未知。

建议保持 accessToken 不变重新调用接口以解决问题或者等待异步通知。如果问题未解决,请联系 Antom 技术支持。

F

取消授权失败。

建议检查并验证当前接口所需的请求字段(包括头部字段和正文字段)是否正确传递并有效。

注意:如果您未收到响应报文,可能是网络超时所致。建议保持 accessToken 不变重新调用接口以解决问题或者等待异步通知。如果问题未解决,请联系 Antom 技术支持。

买家在支付方式侧取消授权

如果买家在支付方式侧取消授权,您会接收到 授权结果通知 发送给您的授权取消通知。如果需要接收取消授权的异步通知,您需要提前配置接收 授权结果通知 的地址。

  1. 配置接收异步授权通知的 webhook URL。按照 Antom Dashboard > 开发者 > 通知地址 路径,为 alipay.ams.authorizations.notify 接口增加通知地址。具体操作请参阅通知地址AD-authorizations.notify-cn.png
  2. 买家取消授权后,您将收到 Antom 发送的 授权结果通知,通知中会指明被成功取消代扣服务对应的支付令牌(accessToken)信息。若您收到 Antom 的异步通知,需要您在返回中按照示例代码格式返回响应,但无需做加签处理。

以下是异步授权通知请求的代码示例:

copy
{
  "authorizationNotifyType": "TOKEN_CANCELED",
  "accessToken": "281010033AB2F588D14B43238637264FCA5Axxxx",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success",
    "resultStatus": "S"
  }
}

根据授权结果的请求中 result.resultStatus 的值(仅返回 S)进行处理:

    • S:授权取消成功,并返回以下字段:
      • accessToken:表示由 Antom 生成的代扣 ID,用于后续支付
      • authorizationNotifyType:本场景下仅会返回 TOKEN_CANCELED表示取消授权。当您收到该通知后,您需要解除您系统里与买家的签约关系。
  1. 您需要按照以下方法对 Antom 发送的授权取消通知进行验签:
copy
/**
 * receive notify
 *
 * @param request    request
 * @param notifyBody notify body
 * @return Result
 */
@PostMapping("/receiveNotify")
@ResponseBody
public Result receiveNotify(HttpServletRequest request, @RequestBody String notifyBody) {
    // 从 HTTP 请求中获取所需的参数
    String requestUri = request.getRequestURI();
    String requestMethod = request.getMethod();

    // 从请求头中获取所需的参数
    String requestTime = request.getHeader("request-time");
    String clientId = request.getHeader("client-id");
    String signature = request.getHeader("signature");

    try {
        // 验签
        boolean verifyResult = WebhookTool.checkSignature(requestUri, requestMethod, clientId,
                                                          requestTime, signature, notifyBody, ANTOM_PUBLIC_KEY);
        if (!verifyResult) {
            throw new RuntimeException("Invalid notify signature");
        }

        // 反序列化通知体
        JSONObject jsonObject = JSON.parseObject(notifyBody);
        String notifyType = (String)jsonObject.get("notifyType");
        if("TOKEN_CANCELED".equals(notifyType)){
            AlipayAuthNotify authNotify = jsonObject.toJavaObject(AlipayAuthNotify.class);
            if (authNotify != null && "SUCCESS".equals(authNotify.getResult().getResultCode())) {
                // 处理您自身的业务逻辑
                // 例如,解除 accessToken 与买家的关联关系
                System.out.println("receive auth notify: " + JSON.toJSONString(authNotify));
                return Result.builder().resultCode("SUCCESS").resultMessage("success.").resultStatus(ResultStatusType.S).build();
            }
        }
        // 其他类型的通知

    } catch (Exception e) {
        // 处理错误情况
        return Result.builder().resultCode("FAIL").resultMessage("fail.").resultStatus(ResultStatusType.F).build();
    }

    return Result.builder().resultCode("SYSTEM_ERROR").resultMessage("system error.").resultStatus(ResultStatusType.F).build();
}
  1. 每个通知请求均需按以下固定格式响应:
copy
{
    "result": {
        "resultCode": "SUCCESS",
        "resultStatus": "S",
        "resultMessage": "success"
    }
}