5

我正在研究 Stripe 集成,我对从 PHP API 得到的实际响应感到困惑。我开始相信 API 参考是准确的,并且响应将是一个 JSON 字符串,如每个方法所示。我很快发现了显着的差异。大多数情况下,JSON 响应中缺少 id 字段。此外,响应似乎同时是一个字符串、一个对象,也许还有其他一些结构。

这是我的调试代码。我正在使用最新的 Stripe PHP 库,版本 1.7.15。

function var_dump_ret($mixed=null)
{
  ob_start();
  var_dump($mixed);
  $content=ob_get_contents();
  ob_end_clean();
  return($content);
}

$token=$_POST['stripeToken'];
$customer=Stripe_Customer::create(array(
  "card"=>$token,
  "plan"=>"agency")
);

$custVarDump=var_dump_ret($customer);
$cDecoded=json_decode($customer);
$Debug="Invidual attributes of JSON decoded customer object:"._EOL;
$Debug.="object:".$cDecoded->object._EOL;
$Debug.="created:".$cDecoded->created._EOL;
$Debug.="id:".$cDecoded->id._EOL;
$Debug.="livemode:".$cDecoded->livemode._EOL;
$Debug.="description:".$cDecoded->description._EOL;
$Debug.="active_card.object:".$cDecoded->active_card->object._EOL;
$Debug.="active_card.last4:".$cDecoded->active_card->last4._EOL;
$Debug.="active_card.type:".$cDecoded->active_card->type._EOL;
$Debug.="active_card.exp_month:".$cDecoded->active_card->exp_month._EOL;
$Debug.="active_card.exp_year:".$cDecoded->active_card->exp_year._EOL;
$Debug.="active_card.fingerprint:".$cDecoded->active_card->fingerprint._EOL;
$Debug.="active_card.country:".$cDecoded->active_card->country._EOL;
$Debug.="active_card.name:".$cDecoded->active_card->name._EOL;
$Debug.="active_card.address_line1:".$cDecoded->active_card->address_line1._EOL;
$Debug.="active_card.address_line2:".$cDecoded->active_card->address_line2._EOL;
$Debug.="active_card.address_city:".$cDecoded->active_card->address_city._EOL;
$Debug.="active_card.address_state:".$cDecoded->active_card->address_state._EOL;
$Debug.="active_card.address_zip:".$cDecoded->active_card->address_zip._EOL;
$Debug.="active_card.address_country:".$cDecoded->active_card->address_country._EOL;
$Debug.="active_card.cvc_check:".$cDecoded->active_card->cvc_check._EOL;
$Debug.="active_card.address_line1_check:".$cDecoded->active_card->address_line1_check._EOL;
$Debug.="active_card.address_zip_check:".$cDecoded->active_card->address_zip_check._EOL;
$Debug.="email:".$cDecoded->email._EOL;
$Debug.="delinquent:".$cDecoded->delinquent._EOL;
//$Debug.="subscription:".$cDecoded->subscription._EOL;
$Debug.="discount:".$cDecoded->discount._EOL;
$Debug.="account_balance:".$cDecoded->account_balance._EOL;
$Debug.="unaltered response from Stripe_Customer::create:"._EOL.$customer._EOL.
    "var dump of response:"._EOL.$custVarDump._EOL.
    "print_r of json_decode of response:"._EOL.print_r($cDecoded,true)._EOL;

file_put_contents(_LOGFILE,$Debug,FILE_APPEND);

下面是我的调试文件的内容,用于 JSON 解码的客户对象的个人属性。执行时,代码会发布一条通知。

注意:未定义的属性:第 51 行的 stripe/subscription.php 中的 stdClass::$id

另请注意,由于有关 stdClass 的致命错误,我不得不注释掉在调试字符串中添加“订阅”的行。

object:customer
created:1365951909
id:
livemode:
description:
active_card.object:card
active_card.last4:4242
active_card.type:Visa
active_card.exp_month:7
active_card.exp_year:2013
active_card.fingerprint:WTXPLgKDCXyp9xpD
active_card.country:US
active_card.name:charlie
active_card.address_line1:
active_card.address_line2:
active_card.address_city:
active_card.address_state:
active_card.address_zip:
active_card.address_country:
active_card.cvc_check:pass
active_card.address_line1_check:
active_card.address_zip_check:
email:
delinquent:
discount:
account_balance:0

最明显的缺失是客户 ID。它在 JSON 响应中不存在。但是,正如在一些 Stripe 示例程序中所见,可以使用 $customer->id 访问它。此外,var_dump 输出表明我无法弄清楚的结构中存在更多属性。整个调试文件位于http://www.helioza.com/stripe/debug.txt。我只展示了客户创建方法,但我遇到了类似的发票问题,并且在 Stripe_Invoice::all 或 Stripe_Invoice::upcoming 响应中的任何地方都找不到发票 ID。

问题

1) Stripe_Customer::create 返回的值如何同时是字符串和对象?

2) 我在哪里可以找到描述 API 方法返回值的文档,包括如何访问每个属性?

4

2 回答 2

6

尽管 Stripe 的 API 在 HTTP 级别返回 JSON(即实际通过网络发送的内容),但 Stripe PHP 库已经处理了对 JSON 响应的解码并将其转换为 PHP 对象。

应该没有必要将返回值从Stripe_Customer::createto传递json_decode——事实上,鉴于它已经是一个对象,我理解json_decode得不够好,无法理解为什么这不仅仅是错误。

在任何情况下,您都应该直接与返回的客户对象进行交互,例如$customer->description$customer->active_card->cvc_check。例如,您可以在Stripe 教程中看到这一点。

于 2013-04-14T16:49:18.120 回答
2

在埃文的帮助下,我想出了第二个问题的完整答案。正如 Evan 所说,关键是将 Stripe PHP 库返回的结构视为一个对象。根据原始方法响应的 JSON 结构中隐含的规则引用元素。

由于我无法阅读复杂的 JSON,特别是随着缩进深度的增加,我编写了一个脚本,将 JSON 结构的每个元素转换为完整的 PHP 引用,例如 $obj->arr[index]->obj2 等等。在www.helioza.com/decoders/explain-json.php,您可以粘贴 JSON 字符串,如 Stripe API 参考中的示例,并获取引用每个元素的 PHP 代码的完整列表。

2014 年 5 月 27 日更新

看着各种评论,在我看来,这里有几个隐藏的上下文在起作用。大多数都在我的脑海中,所以要清楚我做什么和不知道什么,这是我解释 Stripe API 文档的方式。

查看创建新客户的示例,PHP 代码选项。以下是 API 调用响应的一部分。

EXAMPLE RESPONSE
{
  "object": "customer",
  "created": 1401219085,
  "id": "cus_474RjipEtz2ff7",
  "livemode": false,
  "description": "payinguser@example.com",
  "email": null,
  "delinquent": false,
  "metadata": {
  },
  "subscriptions": {
    "object": "list",
    "total_count": 0,
    "has_more": false,
    "url": "/v1/customers/cus_474RjipEtz2ff7/subscriptions",
    "data": [

    ]
  },

现在,根据我的经验,每个 Web API 响应都是 HTTP 响应。Stripe 文档在某处说它是 POST。所以我查看了上面的响应,我看到了与 HTTP 兼容的 JSON。文档页面实际上并未将响应标识为 JSON 或其他任何内容。如果这不是 JSON,请识别它并告诉我你是如何知道的。称它为 StdClass 并没有帮助,因为 PHP 手册在该主题上相当迟钝,并且没有定义类的结构。

这确实是我最初问题的本质。Stripe 所记录的响应的性质是什么?当然看起来像通过 HTTP 传递的 JSON。我想接受教育。

是的,通过将 Stripe 库返回的内容视为对象,我得到了我想要的结果。但是食谱解决方案不会进一步加深任何人的知识。关于 SO 最有价值的答案是解释性的。

于 2013-04-20T15:35:37.947 回答