americanhandelsociety / americanhandelsociety-members

0 stars 0 forks source link

[SPIKE] Figure out if we can send "bundled" membership using django-paypal #122

Closed reginafcompton closed 2 years ago

ecedmondson commented 2 years ago

I've started on looking into this. Nowhere near finished. But, did start. I think...I'm confused.

As far as I can tell, the "join other memberships" flow WILL let you bundle...membership to the other organizations:

Screen Shot 2022-07-18 at 9 31 34 PM

I couldn't complete an end-to-end flow because I was brought to real paypal, despite having test settings on:

Screen Shot 2022-07-18 at 9 32 00 PM Screen Shot 2022-07-18 at 9 36 35 PM

I didn't join, though that might have been amusing.

So I think I might have misunderstood a few things when we last met. I think I had understood how to bundle at all and I think the real question is: how to bundle AHS membership with other organizations?

Additionally, am I misunderstanding, or are the other orgs integrating with paypal differently than AHS? (I am assuming this based on the views, the template, and the fact that paypal thought sure, Emily Edmondson probably actually wants to bundle and joins these organizations.

Sorry I didn't ask these questions when we met. I guess I should have looked at things a little more closely.

ecedmondson commented 2 years ago

Oh, also, unrelated, I was thinking about our (brief) convo about user flows. At rackspace I was on a team that built a dashboard for leadership. One of the things leadership needed was a guide through the dashboard. We built one using this: User Onboarding and Product Walkthrough Library | Intro.js

Our app was flask, not django, but I don't actually think (either from memory or perusing the docs briefly) that it was framework dependent on anything. Anyway, I'm not sure if this tooltip type thing is something you would be interested from a design/user-workflow perspective, but I thought I would throw it out there after a few minutes re-skimming their docs.

ecedmondson commented 2 years ago

~Oh one more thing: I found this, which isn't django-paypal, but is at least confidence (besides my experience above) that we can do what we want. Though maybe we'll need to submit a PR? ~

EDIT:

So following up on the above messages, specifically the part about multiseller payments that I found.

There is this: https://developer.paypal.com/docs/multiparty/checkout/multiseller-payments/#link-httpmultistatus

At first I was thinking that since there were models in django-paypal for the order, that we could simply do some stuff with Django Form s Library or JS or both, write a new view, and write our own order objects for multi-seller orders (i.e. AHS + choice([*other_orgs_in_join_other_orgs_flow])).

I ran into two things that seemed to block this:

  1. The first is that here seems to be partial, but not complete, overlap between the fields returned from PayPal for purchase units on multi-seller orders and the fields managed by django-paypal (I’m looking here: https://github.com/spookylukey/django-paypal/blob/master/paypal/standard/models.py#L40).

  2. The second is that it doesn’t seem like django-paypal supports the status (“PARTIALLY_COMPLETED”/http 207) that seems integral to the multi-seller order flow.

https://developer.paypal.com/docs/multiparty/checkout/multiseller-payments/#link-httpmultistatus

Status supported start here: https://github.com/spookylukey/django-paypal/blob/1ceb83df09e271efed74bf4d57da79c345d31c56/paypal/standard/models.py#L10

So multi-seller PayPal orders, using their order api, doesn’t seem like it would work as it/out of the box. It’s possible PayPal has other multi-seller options that I haven’t found, but I don’t think this one will work.

Have you found anything different?

ecedmondson commented 2 years ago

One more thing. We spoke about scheduling e-mails last time we met. I went off looking for some stuff.

Scheduling: https://github.com/Miksus/rocketry https://devcenter.heroku.com/articles/scheduler https://github.com/algorithm-visualizer/algorithm-visualizer https://pypi.org/project/schedule/

Of these, I've only used the pypi scheduling library, and even that was a few years ago. It worked, and was easy enough I remember, and I actually used it to send e-mails. Ha!

Rocketry and the Heroku one I've never used. Honestly, until I get more info, the Heroku task add on seems like the best option to me solely because AHS is deployed on heroku. I need to look into it more to see if it actually does what we expect/costs. Rocketry is something that showed up in a software developed newsletter I read under "cool libraries to be aware of" and it caught my attention in that it seemed to be in the same realm of what we're trying to accomplish.

So, options are good.

reginafcompton commented 2 years ago

I am very late here. And I have nothing to say. I will ingest these wonderful, helpful comments soon.

ecedmondson commented 2 years ago

I know you've been busy and out of the country but I did want to know if this work is still intended for the upcoming months. Mostly because I am trying to plan some trips.

Edit: the trips will not preclude me helping

reginafcompton commented 2 years ago

Hello. @ecedmondson

I am very, very, very sorry for being a terrible collaborator.

Yes, the renewal flow (with option to join multiple organizations) still needs to be implemented....and it should be done SOON. I am hoping to sneak away from Bevy for a few hours new week to get started. I think you should plan your trips! And then you can help whenever makes sense.

ecedmondson commented 2 years ago

I am very, very, very sorry for being a terrible collaborator.

No worries, and you are not. You had a busy summer!

I am hoping to sneak away from Bevy for a few hours new week to get started

I have a slow sprint...if you need assitance? IDK.

I think you should plan your trips! And then you can help whenever makes sense.

Sounds good. Whenever you're ready do you want to plan to decide what to do/who does what?

reginafcompton commented 2 years ago

I finally investigated this a little. Some notes:

We currently use the "Legacy" (not deprecated) Paypal integration, wherein an HTML button determines what data gets sent to Paypal (see docs here: https://developer.paypal.com/api/nvp-soap/paypal-payments-standard/integration-guide/Appx-websitestandard-htmlvariables/). This seems fine for two reasons: (1) we do not need to use Javascript (which can be annoying in Django templates), and (2) we can rely on the django-paypal library for some out-of-the-box help.

However, this also creates some complexities with a multi-item purchase. We can solve this in two ways:

  1. Stuff everything in one button.
  2. Use "Add to cart" buttons.

Reference: https://blog.learn-or-die.com/submitMultipleItemsInPayPalIPNmethod/

I would like to play around with both options locally and see what makes sense.

Additional considerations

It would be nice to store in our database which memberships people buy. I am not sure how to do this with the Paypal integration....since I do not think Paypall will send this data back to our site, but I might be wrong.

Oh no – a bug!

Before we can do anything...this needs to get resolved. I'll try to prioritize it SOON. https://github.com/americanhandelsociety/americanhandelsociety-members/issues/128

reginafcompton commented 2 years ago

At rackspace I was on a team that built a dashboard for leadership.

intro.js looks VERY USEFUL. It might be the sort of thing that the site needs, since we do not have 100% member participation (perhaps because technology is scary).

ecedmondson commented 2 years ago

This seems fine for two reasons: (1) we do not need to use Javascript (which can be annoying in Django templates), and (2) we can rely on the django-paypal library for some out-of-the-box help.

Agree re JS. I'm not sure I understand how the library helps but admittedly I think I've forgotten quite a bit of this at this point. I am sorry. I will try to review/catch up next I have some free time.

I would like to play around with both options locally and see what makes sense.

Let me know if you would like to pair, unless that would be distracting/counterproductive.

It would be nice to store in our database which memberships people buy.

I think...I understood this to be the purpose of this spike. Which, after reading your comment here, seems I totally misunderstood. Apologies.

reginafcompton commented 2 years ago

However, this also creates some complexities with a multi-item purchase. We can solve this in two ways:

  1. Stuff everything in one button.
  2. Use "Add to cart" buttons.

I played around with option number 2. Here's what I did:

Fake button

Screen Shot 2022-10-01 at 10 00 36 PM

Our existing "Go to Paypal" button

Screen Shot 2022-10-01 at 10 01 32 PM

I should have known that this would not work. Heh.

In any case....there might be a way to use the _cart option with django-paypal, as suggested by the code. https://github.com/spookylukey/django-paypal/blob/62c43a915766298497d53f1a56f893b8c8747bf1/paypal/standard/forms.py#L134 But I do not see a way use a "cart"; when I tried the POST to Paypal failed.

As a next step, I am going to ask about this here: https://github.com/spookylukey/django-paypal/discussions?discussions_q=

reginafcompton commented 2 years ago

Another note!

I also thought through No. 1 ("Stuff everything in one button."). I am mostly opposed to this, because it will make book keeping very, very, very difficult. Our treasurer will not be able to easily find who joined which organizations, since all the membership receipts will be crammed into a single string in the "item" field of the Paypal purchase (rather than being separately itemized).

reginafcompton commented 2 years ago

And one last note! THE MOST IMPORTANT NOTE!

I am inclined to delay this feature improvement until we solve the more immediate need: https://github.com/americanhandelsociety/americanhandelsociety-members/issues/119

I suppose that was the point of our SPIKE, eh? To figure out feasibility of bundling the membership purchases. I vote: it's too complicated to do now; let's just get a renewal flow in place ASAP.

reginafcompton commented 2 years ago

@ecedmondson - thoughts? (And thanks!)

ecedmondson commented 2 years ago

Hello @reginafcompton. Apologies for the slow response here, I've had a bit of a chaotic work week.

also thought through No. 1 ("Stuff everything in one button."). I am mostly opposed to this, because it will make book keeping very, very, very difficult

I'm glad you brought this up, because it reminded me of something else that was said in this convo:

It would be nice to store in our database which memberships people buy. I am not sure how to do this with the Paypal integration....since I do not think Paypal will send this data back to our site, but I might be wrong.

I worry that not being able to track which memberships people buy could result in a potentially frustrating customer experience in some weird scenarios? My concerns might be over cautious...but I am mainly worried about not being able to store some sort of record of financial transactions tangential to AHS, but not properly AHS, in order to help customers with any data needed in the event of transaction errors. Logging could maybe begin to address part of that concern, if it is legitimate, though logging is significantly more tedious than a relational database. Perhaps paypal handles this as a service and my concerns are unmeritied?

As a next step, I am going to ask about this here

Thank you.

I am inclined to delay this feature improvement until we solve the more immediate need:

I think I agree 100%, mostly because of my above mentioned concerns. Also, to re-iterate, I think I misunderstood the purpose of this spike. I think I sort of understood our bundling as "all or nothing" re feature development so I am happy to hear that I was both wrong (about what the purpose of the spike was) and right (about our current limitations re django-paypal) and also happy you are following up.

Let's plan out the feature?

reginafcompton commented 2 years ago

Let's plan out the feature?

Yep! I am doing a little work today. I am going to close this spike.

ecedmondson commented 2 years ago

Okay. Do you want to divide up work?

reginafcompton commented 2 years ago

Possibly. Let me get my bearings, first. I'll likely need help with the email stuff.

reginafcompton commented 2 years ago

Hello @ecedmondson !

All right. I accomplished a few things:

  1. I put together a scaffold for the Renewal flow (via the Profile page): https://github.com/americanhandelsociety/americanhandelsociety-members/issues/133
  2. I opened some tickets with subtasks:

https://github.com/americanhandelsociety/americanhandelsociety-members/issues/131 https://github.com/americanhandelsociety/americanhandelsociety-members/issues/132 https://github.com/americanhandelsociety/americanhandelsociety-members/issues/133

Would you like to do any of these? Either #131 or #132 would be good to start with. Happy to jump on a call, too!

ecedmondson commented 2 years ago

Thank you @reginafcompton. The PR for #133 isn't assigned out so I'm going to assume you're still working on it and not look quite yet.

Either 131 or 132 seems fine. Before I commit to one or both, I have questions.

From #131:

NOTE! This solution assumes a "rolling membership" (rather than annual one). The board may decide to revert to the annual membership solution, depending on the outcome of the November board meeting.

When is the November board meeting?

and we do not want users being "cheated" for early renewals or "cheating us" for later renewals

I understand this cheating avoidance to mean use the datetime math listed in the issue? Or does cheating mean something else here? Perhaps, cost of membership?

From #132

add renewal_confirmation html, view, and url conversely, we could redirect to the users Profile page

These seem different...do you have a preference? Is this something board will decide at the above mentioned meeting?

reginafcompton commented 2 years ago

https://github.com/americanhandelsociety/americanhandelsociety-members/issues/133 isn't assigned out so I'm going to assume you're still working on it and not look quite yet.

Nope. It's not ready for review.

When is the November board meeting?

TBD. We're waiting on the results of a Doodle poll.

"cheating"

Right, if you renew early, then your membership for the previous year should not end early, i.e., the newly set renewal date should be one year after the date your annual membership start date. Does that make sense? Or am I mis-thinking this? Or maybe we do not need that field? Anyway, let's move this convo to the Github issue itself.