PAYATHON 2026

mindbody-php-api 使用 stored card payment 时授权失败

支付阿杰

结论

StoredCardInfo 不能只包含 LastFour 和 Amount。银行卡后四位无法确定卡片品牌,因此 MINDBODY 会在授权时报错:

Could not determine the type of credit card.

请求中还要包含已保存卡片的 CardType。这个值应直接取自 MINDBODY 返回的 stored card 数据,不能根据卡号后四位推断。

修改方式

$storedCardPayment = array(
    'LastFour' => $clientCreditCard->LastFour,
    'CardType' => $clientCreditCard->CardType,
    'Amount'   => round($OnlinePrice, 2),
);

$shoppingCart = array(
    'ClientID' => $client_id,
    'Test'     => false,
    'InStore'  => true,

    'CartItems' => array(
        'CartItem' => array(
            'Quantity' => $product_qty,
            'Item' => new SoapVar(
                array('ID' => $product_id),
                SOAP_ENC_ARRAY,
                'Service',
                'http://clients.mindbodyonline.com/api/0_5'
            ),
            'DiscountAmount' => 0
        )
    ),

    'Payments' => array(
        'PaymentInfo' => new SoapVar(
            $storedCardPayment,
            SOAP_ENC_ARRAY,
            'StoredCardInfo',
            'http://clients.mindbodyonline.com/api/0_5'
        )
    )
);

需要增加的字段是:

'CardType' => $clientCreditCard->CardType,

CardType 应该从哪里取得

先通过相应的 MINDBODY client/card 查询接口获取客户保存的银行卡信息,再把响应中的字段原样用于付款:

$clientCreditCard->LastFour
$clientCreditCard->CardType

不要根据后四位判断卡片类型,也不要自行填写 "Visa"、"MasterCard" 等字符串。具体的枚举值和大小写应以当前 SOAP WSDL 或查询接口实际返回的内容为准。不同版本的 MINDBODY API 可能使用不同的枚举表示方式。

如果查询结果中没有 CardType,请检查:

  • 当前接口是否返回完整的 stored card 信息;
  • 该卡是否保存在同一个客户和站点下;
  • 当前 WSDL/API 版本是否支持 stored card payment;
  • PHP SOAP 客户端是否遗漏了响应字段;
  • 保存的卡片记录是否已经失效或不完整。

还需要检查的事项

LastFour 通常不是全局唯一标识。同一客户可能保存多张后四位相同但类型不同的卡,所以 LastFour 和 CardType 必须来自同一条 stored card 记录。

SOAP 接口也可能对类型名称、命名空间和字段顺序较为敏感。请确认生成的 XML 确实包含类似内容:

<PaymentInfo xsi:type="StoredCardInfo">
    <LastFour>1234</LastFour>
    <CardType>Visa</CardType>
    <Amount>100.00</Amount>
</PaymentInfo>

这里的 Visa 只是示例,实际值必须使用 MINDBODY 返回的值,或当前 WSDL 允许的值。

如果加入 CardType 后仍然失败,可以输出实际发送的 SOAP XML:

echo $soapClient->__getLastRequest();

检查 PaymentInfo 是否被序列化为 StoredCardInfo,请求中是否包含 CardType,以及字段名称和命名空间是否与当前 WSDL 一致。

备注:内容仅供参考。