Lash up a command to suspend subscriptions

This commit is contained in:
Ben Sturmfels 2022-10-28 13:39:56 +11:00
parent 15c9fbfe6f
commit 6102d39759
Signed by: bsturmfels
GPG key ID: 023C05E2C9C068F0

View file

@ -44,15 +44,18 @@ def main():
transactions = get_all_transactions(access_token, args.start_date, args.end_date) transactions = get_all_transactions(access_token, args.start_date, args.end_date)
if args.report == 'profiles': if args.report == 'profiles':
report_on_unique_profiles(transactions) report_on_unique_profiles(transactions)
else: elif args.report == 'transactions':
report_on_transactions(transactions) report_on_transactions(transactions)
else:
suspend_subscriptions_interactively(transactions, args.pattern, access_token)
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='Download PayPal subscriber info.') parser = argparse.ArgumentParser(description='Download PayPal subscriber info.')
parser.add_argument('report', help='report to run"', choices=['profiles', 'transactions']) parser.add_argument('report', help='report to run"', choices=['profiles', 'transactions', 'suspend'])
parser.add_argument('start_date', help='start date inclusive (eg. 2021-11-01T00:00:00-07:00)', type=parse_iso_time) parser.add_argument('start_date', help='start date inclusive (eg. 2021-11-01T00:00:00-07:00)', type=parse_iso_time)
parser.add_argument('end_date', help='end date inclusive (eg. 2021-11-30T23:59:59-07:00)', type=parse_iso_time) parser.add_argument('end_date', help='end date inclusive (eg. 2021-11-30T23:59:59-07:00)', type=parse_iso_time)
parser.add_argument('pattern')
return parser.parse_args() return parser.parse_args()
@ -153,6 +156,23 @@ def report_on_unique_profiles(transactions):
print(f'Reference IDs with changing subject: {dupes}', file=sys.stderr) print(f'Reference IDs with changing subject: {dupes}', file=sys.stderr)
def get_subscriptions_matching_subject(transactions, pattern):
records = set()
for t in transactions:
transaction_info = t['transaction_info']
if 'paypal_reference_id' in transaction_info and pattern.lower() in transaction_info.get('transaction_subject', 'CANT MATCH ME').lower():
records.add(
(
transaction_info['paypal_reference_id'],
transaction_info.get('transaction_subject', 'NO TRANSACTION SUBJECT'),
),
)
else:
# print(f'Skipping transaction {transaction_info["transaction_id"]} with no PayPal Reference ID.', file=sys.stderr)
pass
return records
def report_on_transactions(transactions): def report_on_transactions(transactions):
"""Print a formatted list of transactions.""" """Print a formatted list of transactions."""
for t in transactions: for t in transactions:
@ -164,5 +184,59 @@ def report_on_transactions(transactions):
print(f'Skipping transaction {transaction_info["transaction_id"]} with no PayPal Reference ID.', file=sys.stderr) print(f'Skipping transaction {transaction_info["transaction_id"]} with no PayPal Reference ID.', file=sys.stderr)
def suspend_subscriptions_interactively(transactions, pattern, access_token):
subscriptions = get_subscriptions_matching_subject(transactions, pattern)
for (id, subject) in subscriptions:
sub_before = paypal_request(f'https://api.paypal.com/v1/billing/subscriptions/{id}', access_token)
status_before = sub_before['status']
# Donor name / total donations / last donation / donation amount / FULL text of the profile Memo description / profile-id " with "Should I cancel this one? (y/n)"
given_name = sub_before['subscriber'].get('name', {}).get('given_name', '')
surname = sub_before['subscriber'].get('name', {}).get('surname', '')
name = ' '.join(filter(bool, [given_name, surname]))
payments = sub_before['billing_info']['cycle_executions'][0]['cycles_completed']
last_payment = sub_before['billing_info']['last_payment']
last_payment_total = last_payment['amount']['value']
last_payment_currency = last_payment['amount']['currency_code']
last_payment_time = last_payment['time']
print(f'Subscriber {id} {subject} {status_before}: {name}, {payments} payments with last payment {last_payment_time}, {last_payment_total} {last_payment_currency}')
if status_before == 'ACTIVE':
url = f'https://api.paypal.com/v1/billing/subscriptions/{id}/suspend'
if input('Cancel this one? (y/n) ') == 'y':
response = paypal_post_request(url, access_token)
print(f'PayPal said: {response.text}')
sub_after = paypal_request(f'https://api.paypal.com/v1/billing/subscriptions/{id}', access_token)
status_after = sub_after['status']
print(f'Subscriber {id} status after: {status_after}')
else:
print(' ignoring inactive status')
def paypal_request(url, access_token):
response = requests.get(
url,
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}',
},
)
data = response.json()
return data
def paypal_post_request(url, access_token):
response = requests.post(
url,
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}',
},
json={
'reason': 'suspended',
},
)
return response
if __name__ == '__main__': if __name__ == '__main__':
main() main()