importers: Add an importer for Stripe payments.
This commit is contained in:
parent
f8a68c3a2e
commit
e5a0089eb9
5 changed files with 92 additions and 4 deletions
22
README.rst
22
README.rst
|
@ -108,6 +108,28 @@ Patreon
|
|||
withheld for
|
||||
============== ============================================================
|
||||
|
||||
Stripe
|
||||
^^^^^^
|
||||
|
||||
``template stripe payments``
|
||||
Imports one transaction per payment. Generated from Stripe's payments CSV export.
|
||||
|
||||
This template can use these variables:
|
||||
|
||||
============ ============================================================
|
||||
Name Contents
|
||||
============ ============================================================
|
||||
description The description given to the payment when it was created
|
||||
------------ ------------------------------------------------------------
|
||||
fee The amount of fees charged by Stripe for this payment, as a
|
||||
plain decimal number
|
||||
------------ ------------------------------------------------------------
|
||||
payment_id The id assigned to this payment by Stripe
|
||||
------------ ------------------------------------------------------------
|
||||
tax The amount of tax withheld by Stripe for this payment, as a
|
||||
plain decimal number
|
||||
============ ============================================================
|
||||
|
||||
Other output options
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
32
import2ledger/importers/stripe.py
Normal file
32
import2ledger/importers/stripe.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import decimal
|
||||
|
||||
from . import _csv
|
||||
from .. import util
|
||||
|
||||
class PaymentImporter(_csv.CSVImporterBase):
|
||||
NEEDED_FIELDS = frozenset([
|
||||
'Converted Currency',
|
||||
'Created (UTC)',
|
||||
'Fee',
|
||||
'Status',
|
||||
'Tax',
|
||||
])
|
||||
COPIED_FIELDS = {
|
||||
'Card Name': 'payee',
|
||||
'Converted Amount': 'amount',
|
||||
'Description': 'description',
|
||||
'id': 'payment_id',
|
||||
}
|
||||
TEMPLATE_KEY = 'template stripe payments'
|
||||
DATE_FMT = '%Y-%m-%d'
|
||||
|
||||
def _read_row(self, row):
|
||||
if row['Status'] != 'Paid':
|
||||
return None
|
||||
else:
|
||||
return {
|
||||
'currency': row['Converted Currency'].upper(),
|
||||
'date': util.strpdate(row['Created (UTC)'].split(None, 1)[0], self.DATE_FMT),
|
||||
'fee': decimal.Decimal(row['Fee']),
|
||||
'tax': decimal.Decimal(row['Tax']),
|
||||
}
|
3
tests/data/StripePayments.csv
Normal file
3
tests/data/StripePayments.csv
Normal file
|
@ -0,0 +1,3 @@
|
|||
id,Description,Created (UTC),Amount,Amount Refunded,Currency,Converted Amount,Converted Amount Refunded,Fee,Tax,Converted Currency,Mode,Status,Statement Descriptor,Customer ID,Customer Description,Customer Email,Captured,Card ID,Card Last4,Card Brand,Card Funding,Card Exp Month,Card Exp Year,Card Name,Card Address Line1,Card Address Line2,Card Address City,Card Address State,Card Address Country,Card Address Zip,Card Issue Country,Card Fingerprint,Card CVC Status,Card AVS Zip Status,Card AVS Line1 Status,Card Tokenization Method,Disputed Amount,Dispute Status,Dispute Reason,Dispute Date (UTC),Dispute Evidence Due (UTC),Invoice ID,Payment Source Type,Destination,Transfer,Transfer Group
|
||||
ch_oxuish6phae2Raighooghi3U,Payment for invoice #102,2017-11-08 16:56,100,0,usd,100,0,3,0,usd,Live,Paid,,cus_DohSheeQu8eng3,,one@example.org,true,card_na1joNohg9Aim6eg9eefooRe,0000,American Express,credit,1,2010,Dakota Smith,1 Example St,,City,State,United States,12345,US,queiheVu2ohyei2u,pass,pass,pass,,,,,,,,card,,,
|
||||
ch_hHee9ef1aeyee1ruo7ochee9,Payment for invoice #100,2017-10-28 02:32,50,0,usd,50,0,1.4,0,usd,Live,Paid,,cus_iepae2Iecae8Ei,,two@example.org,true,card_sitej3Xi2aNgo1ohfoahue8e,0001,Visa,credit,2,2011,Dakota Jones,2 Example St,,City,State,United States,12345,US,men2shi3xo1Mao4u,pass,pass,pass,,,,,,,,card,,,
|
|
|
@ -61,3 +61,23 @@
|
|||
currency: USD
|
||||
country_code: CZ
|
||||
country_name: Czech Republic
|
||||
|
||||
- source: StripePayments.csv
|
||||
importer: stripe.PaymentImporter
|
||||
expect:
|
||||
- payee: Dakota Smith
|
||||
date: [2017, 11, 8]
|
||||
amount: "100"
|
||||
fee: "3"
|
||||
tax: "0"
|
||||
currency: USD
|
||||
payment_id: ch_oxuish6phae2Raighooghi3U
|
||||
description: "Payment for invoice #102"
|
||||
- payee: Dakota Jones
|
||||
date: [2017, 10, 28]
|
||||
amount: "50"
|
||||
fee: "1.4"
|
||||
tax: "0"
|
||||
currency: USD
|
||||
payment_id: ch_hHee9ef1aeyee1ruo7ochee9
|
||||
description: "Payment for invoice #100"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import datetime
|
||||
import decimal
|
||||
import importlib
|
||||
import itertools
|
||||
import pathlib
|
||||
|
@ -10,6 +11,15 @@ from import2ledger import importers
|
|||
from . import DATA_DIR
|
||||
|
||||
class TestImporters:
|
||||
def _date(parts_list):
|
||||
return datetime.date(*parts_list)
|
||||
|
||||
DATA_TYPES = {
|
||||
'date': _date,
|
||||
'fee': decimal.Decimal,
|
||||
'tax': decimal.Decimal,
|
||||
}
|
||||
|
||||
with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file:
|
||||
test_data = yaml.load(yaml_file)
|
||||
for test in test_data:
|
||||
|
@ -20,10 +30,11 @@ class TestImporters:
|
|||
test['importer'] = getattr(module, class_name)
|
||||
|
||||
for expect_result in test['expect']:
|
||||
try:
|
||||
expect_result['date'] = datetime.date(*expect_result['date'])
|
||||
except KeyError:
|
||||
pass
|
||||
for key, type_func in DATA_TYPES.items():
|
||||
try:
|
||||
expect_result[key] = type_func(expect_result[key])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@pytest.mark.parametrize('source_path,importer', [
|
||||
(t['source'], t['importer']) for t in test_data
|
||||
|
|
Loading…
Reference in a new issue