PAYATHON 2026

如何用 CyberSource SOAP Toolkit API Token 发起支付?

支付阿杰

结论

recurringSubscriptionInfo_subscriptionID 可以用于调用已有的客户支付资料,但它必须是 CyberSource 创建并返回的 subscriptionID。普通交易的 requestID、requestToken 以及其他类型的 payment token 都不能用于这个字段。

当前请求提示缺少 billing info 和 credit card number,最可能是因为 SOAP Toolkit 的字段结构写错了。文档中的 recurringSubscriptionInfo_subscriptionID 是逻辑字段名,在 PHP SOAP 对象中应写成嵌套结构:

$request->recurringSubscriptionInfo->subscriptionID

不能写成:

$request->recurringSubscriptionInfo_subscriptionID

purchaseTotals_currency 和 purchaseTotals_grandTotalAmount 也要使用相同的嵌套结构。否则,这些字段可能不会被序列化到实际的 SOAP 请求中。CyberSource 收不到 token,就会把它当成没有 token 的普通信用卡交易,并要求提供 billTo 和 card_accountNumber。

使用已有 subscriptionID 发起 sale

同时运行 authorization 和 capture,就是一笔 sale。请求可以这样组织:

<?php

$referenceCode = uniqid('order_', true);

$client = new CybsSoapClient();
$request = $client->createRequest($referenceCode);

$request->merchantID = 'my_merchant_id';
$request->merchantReferenceCode = $referenceCode;

// Authorization
$request->ccAuthService = new stdClass();
$request->ccAuthService->run = 'true';

// Capture
$request->ccCaptureService = new stdClass();
$request->ccCaptureService->run = 'true';

// Amount
$request->purchaseTotals = new stdClass();
$request->purchaseTotals->currency = 'USD';
$request->purchaseTotals->grandTotalAmount = '25.00';

// Existing CyberSource subscription/customer profile
$request->recurringSubscriptionInfo = new stdClass();
$request->recurringSubscriptionInfo->subscriptionID = 'xxxxxxxx';

$reply = $client->runTransaction($request);

需要注意的是以下字段:

$request->purchaseTotals->currency
$request->purchaseTotals->grandTotalAmount
$request->recurringSubscriptionInfo->subscriptionID

它们都是 SOAP 复杂类型的子属性,不是请求根对象上的扁平字段。

如果只做 authorization

只运行 ccAuthService:

<?php

$referenceCode = uniqid('order_', true);

$client = new CybsSoapClient();
$request = $client->createRequest($referenceCode);

$request->merchantID = 'my_merchant_id';
$request->merchantReferenceCode = $referenceCode;

$request->ccAuthService = new stdClass();
$request->ccAuthService->run = 'true';

$request->purchaseTotals = new stdClass();
$request->purchaseTotals->currency = 'USD';
$request->purchaseTotals->grandTotalAmount = '25.00';

$request->recurringSubscriptionInfo = new stdClass();
$request->recurringSubscriptionInfo->subscriptionID = 'xxxxxxxx';

$reply = $client->runTransaction($request);

之后单独进行 capture 时,要引用 authorization 返回的请求标识,不能再次使用 subscriptionID 作为 capture 依据:

<?php

$referenceCode = uniqid('capture_', true);

$client = new CybsSoapClient();
$request = $client->createRequest($referenceCode);

$request->merchantID = 'my_merchant_id';
$request->merchantReferenceCode = $referenceCode;

$request->ccCaptureService = new stdClass();
$request->ccCaptureService->run = 'true';
$request->ccCaptureService->authRequestID = $authReply->requestID;

$request->purchaseTotals = new stdClass();
$request->purchaseTotals->currency = 'USD';
$request->purchaseTotals->grandTotalAmount = '25.00';

$reply = $client->runTransaction($request);

某些 Simple Order API 版本或处理器配置还可能要求提供 authorization reply 中的 request token。是否需要这个字段,应以当前使用的 WSDL 和 CyberSource 账户配置为准。recurring subscription ID 不能代替 authorization reference。

怎样确认手里的 token 能否这样使用

只有在上一笔操作确实创建了 CyberSource customer profile、recurring subscription,或者返回了可供该接口使用的 subscriptionID 时,才能将它写入:

$request->recurringSubscriptionInfo->subscriptionID

需要核对上一笔响应中 token 的来源和字段名称。例如,这个值应当是某次 subscription creation reply 返回的 subscriptionID。以下标识通常不能直接用于该字段:

  • 普通支付响应中的 requestID
  • SOAP 消息中的 requestToken
  • 第三方钱包 token
  • Flex transient token
  • TMS 的 customer、instrument 或 payment instrument token
  • 仅由商户系统内部生成的 token

CyberSource 有多套 tokenization 产品,各自的字段不能混用。如果手里的是 Token Management Service(TMS)token,而不是旧式 recurring subscription ID,就要使用该产品对应的请求字段和 API,不能将它放入 recurringSubscriptionInfo.subscriptionID。

为什么会要求 billing info 和 card number

这类报错通常不表示使用 token 时仍要提交完整卡号,而是说明 CyberSource 没有识别到可用的已存储支付资料。常见原因有:

  1. recurringSubscriptionInfo_subscriptionID 被当成不存在的根属性处理,没有写入最终的 SOAP XML。
  2. 提交的值并非 subscriptionID,而是其他类型的 token 或交易标识。
  3. subscription 不属于当前 merchant,或者混用了测试环境和生产环境。
  4. profile 中缺少当前交易所需的完整支付资料。
  5. 当前使用的 WSDL、SOAP Toolkit 版本或账户功能与参考文档不一致。

正常情况下,只要有效的 subscription 已经保存银行卡和必要的账单资料,on-demand 请求就不需要重新发送完整卡号。个别账单字段是否仍需提供,取决于处理器、风控规则和账户配置。但如果 subscription 没有被识别,重新发送 PAN 并不能解决这个问题。

排查时,应记录或查看 SOAP Toolkit 最终生成的 XML,确认请求中确实包含类似结构:

<recurringSubscriptionInfo>
    <subscriptionID>xxxxxxxx</subscriptionID>
</recurringSubscriptionInfo>

金额字段也应位于:

<purchaseTotals>
    <currency>USD</currency>
    <grandTotalAmount>25.00</grandTotalAmount>
</purchaseTotals>

只有在 token 类型正确、环境和 merchant 匹配,并且 SOAP XML 包含正确的嵌套字段时,CyberSource 才能使用 profile 中保存的支付资料处理 authorization 或 sale。

备注:内容仅供参考。