Stripe payments 使用条带API时,对每个请求进行排序或本地存储并执行查询是否更好?

Stripe payments 使用条带API时,对每个请求进行排序或本地存储并执行查询是否更好?,stripe-payments,Stripe Payments,这是我的第一篇帖子,我已经潜伏了一段时间 我的问题的一些背景 我正在使用StripeAPI来提取事务数据,并将这些数据与来自另一个API源的预订号码进行匹配。财产保留->收到用于对账的资金 我一开始只是调用API并使用Python3对数据进行就地排序,但是它开始变得非常复杂,我认为应该将数据持久化到存储在localhost上的mongodb中。我开始这样做,但是我决定存储排序后的数据仍然很复杂,请求时间也很长,我想,也许我应该提取所有的条带数据并将其存储在本地,然后查询我需要的任何内容 所以我在

这是我的第一篇帖子,我已经潜伏了一段时间

我的问题的一些背景

我正在使用StripeAPI来提取事务数据,并将这些数据与来自另一个API源的预订号码进行匹配。财产保留->收到用于对账的资金

我一开始只是调用API并使用Python3对数据进行就地排序,但是它开始变得非常复杂,我认为应该将数据持久化到存储在localhost上的mongodb中。我开始这样做,但是我决定存储排序后的数据仍然很复杂,请求时间也很长,我想,也许我应该提取所有的条带数据并将其存储在本地,然后查询我需要的任何内容

所以我在这里,有一堆我为这两个项目编写的代码,但仍然没有多少进展。下一步我有点不知所措。我觉得我应该选择一条路并坚持下去。在使用API时,我有点不确定什么是最佳实践,通常我会转到YouTube,但我还没有找到一个涵盖此特定场景的视频。每个请求从API中提取的数据量大约为100kb

下面是获取每个查询的原始代码。最近我学会了我可以使用扩展方法,我想这就是它的名称,所以我不需要在for循环中挖掘这么多级别

我们的目标是只获取包含预订参考号的元数据,然后可以与my property management systems API的响应进行匹配。我的代码有点让人尴尬,我是在过去的一段时间里,在我下班休息的时候才学会的

import csv
import datetime
import os
import pymongo
import stripe

""" 
We need to find a Valid reservation_ref or reservation_id in the booking.com Metadata. Then we need to match this to a property ID from our list of properties in the book file.

"""
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
stripe_payouts = mydb["stripe_payouts"]
stripe.api_key = "sk_live_thisismyprivatekey"

r = stripe.Payout.list(limit=4)

payouts = []

for data in r['data']:
    if data['status'] == 'paid':
        p_id = data['id']
        amount = data['amount']
        meta = []
        txn = stripe.BalanceTransaction.list(payout=p_id)
        amount_str = str(amount)
        amount_dollar = str(amount / 100)
        txn_len = len(txn['data'])
        for x in range(txn_len):
            if x != 0:
                charge = (txn['data'][x]['source'])
                if charge.startswith("ch_"):
                    meta_req = stripe.Charge.retrieve(charge)
                    meta = list(meta_req['metadata'])
                elif charge.startswith("re_"):
                    meta_req = stripe.Refund.retrieve(charge)
                    meta = list(meta_req['metadata'])

                if stripe_payouts.find({"_id": p_id}).count() == 0:

                    payouts.append(
                        {
                            "_id": str(p_id),
                            "payout": str(p_id),
                            "transactions": txn['data'],
                            "metadata": {
                                charge: [meta]
                            }
                        }
                    )

# TODO: Add error exception to check for po id already in the database.

if len(payouts) != 0:
    x = stripe_payouts.insert_many(payouts)
    print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
    print("No entries made")
_id:strp_id, 付款:strp_id, 交易记录:txn[“数据”], 元数据:{ 费用:[元]

最后一部分工作不正常,我在这里停止并开始调用所有数据,并将其存储在mongodb本地

我很感激你能读到这么多的文字

谢谢

编辑: 我不确定添加附加信息的最佳做法是什么,但根据给出的答案,我弄乱了下面的代码。我现在在尝试将条目插入数据库时遇到了一个键错误。我感觉它不知何故复制了键


payouts = []

def add_metadata(payout_id, transaction_type):
    transactions = stripe.BalanceTransaction.list(payout=payout_id, type=transaction_type, expand=['data.source'])
    for transaction in transactions.auto_paging_iter():
        meta = [transaction.source.metadata]
        if stripe_payouts.Collection.count_documents({"_id": payout_id}) == 0:
            payouts.append(
                {
                    transaction.id: transaction
                }
            )

for data in r['data']:
    p_id = data['id']
    add_metadata(p_id, 'charge')
    add_metadata(p_id, 'refund')


# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
    x = stripe_payouts.insert_many(payouts)
    #print(payouts)
    print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
    print("No entries made")```

回答您的高级问题。如果您经常访问相同的数据,而这些数据变化不大,那么尝试保持数据的本地副本同步并对本地数据进行频繁查询是有意义的

不必为你的代码感到尴尬:我们在某些方面都是新的

查看您的代码时,我注意到以下几点:

不要获取所有支出,然后使用if语句跳过除payed之外的所有支出,相反,您可以通过另一个过滤器仅查询那些已支付的支出。 r=stripe.Payout.listlimit=4,状态为“已支付”

你提到了扩展[B]API的功能,但没有使用它,因此我想在这里用一个示例来分享如何做到这一点。在本例中,您将进行1次API调用以获取付款列表,然后每次付款进行1次API调用以获取交易,然后每次收费或退款进行1次API调用以获取收费元数据或退款元数据。这将导致1*n次付款*m收费或退款是一个相当大的数字。为了减少这一点,在获取交易时,让我们传递expand=['data.source'],该交易将包括关于收费或退款的所有元数据以及交易。 transactions=stripe.BalanceTransaction.listpayout=p_id,expand=['data.source']

这样获取BalanceTransaction列表只会在您的结果适合一页结果的情况下起作用。API返回分页的[A]结果,因此,如果您每个支出有10个以上的事务,这将错过一些。相反,您可以使用stripe python库的自动分页功能来迭代BalanceTransaction列表中的所有结果。 对于transactions.auto_paging_iter中的事务:

我不太清楚为什么我们要跳过索引0,如果x!=0:

我不知道amount\u str或amount\u dollar的实际用途是什么

与其通过检查ID前缀(如ch_u或re_u)来确定对象的类型,不如使用type属性。同样,在这种情况下,最好按类型进行筛选,以便只从API获得所需的准确数据:

transactions=stripe.BalanceTransaction.listpayout=p_id,type='charge',expand=['data.source']

我无法测试,因为我缺少与您相同的数据库,但希望共享您可以考虑的代码的重构。

r = stripe.Payout.list(limit=4, status='paid')

payouts = []

for data in r['data']:
    p_id = data['id']
    amount = data['amount']
    meta = []
    amount_str = str(amount)
    amount_dollar = str(amount / 100)
    transactions = stripe.BalanceTransaction.list(payout=p_id, type='charge', expand=['data.source'])
    for transaction in transactions.auto_paging_iter():
        meta = list(transaction.source.metadata)
        if stripe_payouts.find({"_id": p_id}).count() == 0:
            payouts.append(
                {
                    "_id": str(p_id),
                    "payout": str(p_id),
                    "transactions": transactions,
                    "metadata": {
                        charge: [meta]
                    }
                }
            )
    transactions = stripe.BalanceTransaction.list(payout=p_id, type='refund', expand=['data.source'])
    for transaction in transactions.auto_paging_iter():
        meta = list(transaction.source.metadata)
        if stripe_payouts.find({"_id": p_id}).count() == 0:
            payouts.append(
                {
                    "_id": str(p_id),
                    "payout": str(p_id),
                    "transactions": transactions,
                    "metadata": {
                        charge: [meta]
                    }
                }
            )

# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
    x = stripe_payouts.insert_many(payouts)
    print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
    print("No entries made")
下面是进一步的重构,使用定义的函数来封装添加到 数据库:

r = stripe.Payout.list(limit=4, status='paid')

payouts = []

def add_metadata(payout_id, transaction_type):
    transactions = stripe.BalanceTransaction.list(payout=payout_id, type=transaction_tyep, expand=['data.source'])
    for transaction in transactions.auto_paging_iter():
        meta = list(transaction.source.metadata)
        if stripe_payouts.find({"_id": payout_id}).count() == 0:
            payouts.append(
                {
                    "_id": str(payout_id),
                    "payout": str(payout_id),
                    "transactions": transactions,
                    "metadata": {
                        charge: [meta]
                    }
                }
            )

for data in r['data']:
    p_id = data['id']
    add_metadata('charge')
    add_metadata('refund')


# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
    x = stripe_payouts.insert_many(payouts)
    print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
    print("No entries made")
[A]
[B]

那真是太好了。我已经阅读了你的回复好几次了,它为我提供了一些非常有价值的应用程序,我读过一些东西,但不确定如何实现它们类型、扩展等。第4点,第一个条目是支出的负金额,因此这显示为离开条带帐户的金额,即所有交易的负总额。5我用它只是为了调试:这真是太棒了,我要用你的代码来运行数据库,看看这是怎么回事!令人惊叹的到目前为止,你的回答对我帮助很大,谢谢。我在上面更新了我的帖子,做了一些额外的修改。我现在感觉很快就要解决这个问题了,我想我需要多花一点时间。不幸的是,我认为下一个错误与我不熟悉的数据库有关。可能值得创建另一个问题,仅仅是关键错误和数据库信息标签。我认为这与退款响应没有来源有关,因此它无法扩展。也许我错了,还是有点卡住了。这个调用似乎可疑:payouts.append{transaction.id:transaction}