Lash up a command to suspend subscriptions
This commit is contained in:
		
							parent
							
								
									15c9fbfe6f
								
							
						
					
					
						commit
						6102d39759
					
				
					 1 changed files with 76 additions and 2 deletions
				
			
		|  | @ -44,15 +44,18 @@ def main(): | |||
|     transactions = get_all_transactions(access_token, args.start_date, args.end_date) | ||||
|     if args.report == 'profiles': | ||||
|         report_on_unique_profiles(transactions) | ||||
|     else: | ||||
|     elif args.report == 'transactions': | ||||
|         report_on_transactions(transactions) | ||||
|     else: | ||||
|         suspend_subscriptions_interactively(transactions, args.pattern, access_token) | ||||
| 
 | ||||
| 
 | ||||
| def parse_args(): | ||||
|     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('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() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -153,6 +156,23 @@ def report_on_unique_profiles(transactions): | |||
|     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): | ||||
|     """Print a formatted list of 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) | ||||
| 
 | ||||
| 
 | ||||
| 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__': | ||||
|     main() | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue