如何获取自动付款的原始费用和退款 ID

Per*_*ids 5 ruby stripe-payments stripe-connect

Stripe 连接帐户可配置为按照定期付款计划合并付款,例如在我们的案例中为每月付款。对于这些每月付款,我们需要向账户所有者解释我们平台上的哪些交易(在我们的例子中是预订和退款)产生了他们收到的总金额。我们将条带费用 ID(或退款 ID)存储在数据库的预订(或退款)对象中。因此,问题归结为:

给定一个 Stripe 帐户 ID,如何获取促成上次付款的 Stripe 费用和退款 ID 列表?

Per*_*ids 6

我与 Stripe 的支持团队进行了广泛的交流,要实现这一目标,需要解决几个难题:

\n\n

付款范围按账户划分

\n\n

如果您查询 stripe 以获得支出列表,您将只会收到您(平台所有者)从 stripe 获得的支出对象。要获取特定帐户的支付对象,您可以使用平台的正常身份验证,但将条带帐户 ID 作为 header 发送。因此,获取最后一次付款的代码片段如下所示(我将使用 ruby​​ 片段作为答案其余部分的示例):

\n\n
Stripe::Payout.list({limit: 1}, {stripe_account: \'acct_0000001234567890aBcDeFgH\'})\n=> #<Stripe::ListObject:0x0123456789ab> JSON: {\n  "object": "list",\n  "data": [\n    {"id":"po_1000001234567890aBcDeFgH",\n     "object":"payout",\n     "amount":53102,\n     "arrival_date":1504000000,\n     "balance_transaction":"txn_2000001234567890aBcDeFgH",\n     "created":1504000000,\n     "currency":"eur",\n     "description":"STRIPE TRANSFER",\n     "destination":"ba_3000001234567890aBcDeFgH",\n     "failure_balance_transaction":null,\n     "failure_code":null,\n     "failure_message":null,\n     "livemode":true,"metadata":{},\n     "method":"standard",\n     "source_type":"card",\n     "statement_descriptor":"[\xe2\x80\xa6]",\n     "status":"paid",\n     "type":"bank_account"\n    }\n  ],\n  "has_more": true,\n  "url": "/v1/payouts"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

有了支付 ID,我们就可以查询余额交易列表,范围为支付

\n\n
Stripe::BalanceTransaction.all({\n    payout: \'po_1000001234567890aBcDeFgH\',\n    limit: 2,\n}, {\n    stripe_account: \'acct_0000001234567890aBcDeFgH\'\n})\n
Run Code Online (Sandbox Code Playgroud)\n\n

与被视为平台所有者的对象相比,被视为帐户的对象被剥夺了大部分信息

\n\n

即使您现在拥有付款 ID,该对象的范围仍然是该账户,您无法以平台所有者的身份检索它。但从账户的角度来看,支付仅显示类似这样的伪收费和退款对象(请注意,第二笔交易有一个py_7000001234567890aBcDeFgH对象作为来源,而不是常规的来源)ch_收费对象):

\n\n
Stripe::BalanceTransaction.all({\n    payout: \'po_1000001234567890aBcDeFgH\',\n    limit: 2,\n}, {\n    stripe_account: \'acct_0000001234567890aBcDeFgH\'\n})\n=> {\n    :object => "list",\n    :data => [\n        {\n            :id => "txn_4000001234567890aBcDeFgH",\n            :object => "balance_transaction",\n            :amount => -53102,\n            :available_on => 1504000000,\n            :created => 1504000000,\n            :currency => "eur",\n            :description => "STRIPE TRANSFER",\n            :fee => 0,\n            :fee_details => [],\n            :net => -53102,\n            :source => "po_5000001234567890aBcDeFgH",\n            :status => "available",\n            :type => "payout"\n        },\n        {\n            :id => "txn_6000001234567890aBcDeFgH",\n            :object => "balance_transaction",\n            :amount => 513,\n            :available_on => 1504000000,\n            :created => 1504000000,\n            :currency => "eur",\n            :description => nil,\n            :fee => 0,\n            :fee_details => [],\n            :net => 513,\n            :source => "py_7000001234567890aBcDeFgH",\n            :status => "available",\n            :type => "payment"\n        }\n    ],\n    :has_more => true,\n    :url => "/v1/balance/history"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以让 stripe 自动扩展响应中的对象

\n\n

作为附加参数,您可以提供您希望条带在其响应中扩展的对象的条带路径。因此,我们可以通过传输从伪对象回到原始电荷对象:

\n\n
Stripe::BalanceTransaction.all({\n    payout: \'po_1000001234567890aBcDeFgH\',\n    limit: 2,\n    expand:[\'data.source.source_transfer\',]\n}, {\n    stripe_account: \'acct_0000001234567890aBcDeFgH\'\n}).data.second.source.source_transfer.source_transaction\n=> "ch_8000001234567890aBcDeFgH"\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您想处理整个列表,您需要消除source.object属性之间的歧义:

\n\n
Stripe::BalanceTransaction.all({\n    payout: \'po_1000001234567890aBcDeFgH\',\n    limit: 2,\n    expand:[\'data.source.source_transfer\',]\n}, {\n    stripe_account: \'acct_0000001234567890aBcDeFgH\'\n}).data.map do |bt| \n  if bt.source.object == \'charge\'\n    [\'charge\', bt.source.source_transfer.source_transaction]\n  else\n    [bt.source.object]\n  end\nend\n=> [["payout"], ["charge", "ch_8000001234567890aBcDeFgH"]]\n
Run Code Online (Sandbox Code Playgroud)\n\n

退款没有连接到原始 ID 的对象路径

\n\n

不幸的是,目前无法从退款交易的 BalanceTransaction 列表调用返回的re_伪对象中获取原始对象。pyr_我发现的最佳替代方案是通过路径获取data.source.charge.source_transfer.source_transaction发出退款的费用的费用 ID,并将其与 的属性结合使用createdpyr_匹配我们的数据库退款对象。不过,我不确定该方法到底有多稳定。提取该数据的代码:

\n\n
Stripe::BalanceTransaction.all({\n    payout: \'po_1000001234567890aBcDeFgH\',\n    limit: 100, # max page size, the code to iterate over all pages is TBD\n    expand: [\n        \'data.source.source_transfer\', # For charges\n        \'data.source.charge.source_transfer\', # For refunds\n    ]\n}, {\n    stripe_account: \'acct_0000001234567890aBcDeFgH\'\n}).data.map do |bt|\n  res = case bt.source.object\n    when \'charge\'\n      {\n          charge_id: bt.source.source_transfer.source_transaction\n      }\n    when \'refund\'\n      {\n          charge_id: bt.source.charge.source_transfer.source_transaction\n      }\n    else\n      {}\n  end\n  res.merge(type: bt.source.object, amount: bt.amount, created: bt.created)\nend\n
Run Code Online (Sandbox Code Playgroud)\n