Integrating Stripe into OFN

Tags: #<Tag:0x00007f7a0230c338>

Thanks for taking this on Rob. It will be very well-received in the UK. We really don’t like Paypal! I have heard good things about Stripe and several of the potential new OFN users we are talking to are already either using Stripe or interested in using it, I don’t have any better options to suggest.

Option 1 (Stripe Connect) sounds preferable to me but I am a bit confused about the Spree consequences of this and I must admit that I don’t understand enough to follow your ‘next steps’ but I do agree that it will be great to keep the development as generic as possible so that we can include things like Mangopay in the future.

Thanks again for all your work - UK shoppers are very very pleased with the performance improvements!

Rob, I think if option 2 makes things easier for Spree integration than the risk is acceptable. I don’t know if the work needed for PCI compliance negates the time saving but just saying. If the worst case is an unauthorised charge to the instance’s Stripe account, I could live with that.

Thanks for the detailed info @oeoeaio this was really informative.
@sigmundpetersen any thoughts on this?

Thanks for getting cracking on this @oeoeaio

Stripe Connect seems like the obvious option. I feel that there would be huge UX advantages for having a Stripe account per instance, benefiting both users and enterprises and thus the enterprise.

Along these same lines I feel that for Next Steps Round One Point 2 it would make sense to store the stripe acc ids per user. This would then allow a user to input their details once and easily shop from any enterprise on OFN. In theory this could also be done per payment method, but I feel that enterprises would need extra support to ensure they set up their payment methods as we intend to benefit from this. Storing ids per user would guarantee that users and enterprises benefit from super simple payments, making it easier for customers to shop between OFN enterprises.

in Next Steps Round One Point 3 my feeling is that it would be ideal to integrate the sign up process into OFN as much as possible. I know even personally that when a website redirects me I am less likely to complete the order, so I imagine for less tech savvy people the drop out rate increases significantly. UK can have budget to contribute to the extra dev it would entail… but obviously if complex this could be a phase 2 feature.

Another thought. It would be great if in designing these changes we think longer term to @MyriamBoure’s requirements to enable multi-party payments for marketplaces. I guess this won’t affect the current implementation a great deal as much of this is more the customer experience. But ensuring a modular level that can be extended within the payment process might make this future enhancement easier to slot in. I’m sure you’ll be best-practising the f$%k out of it anyway :slight_smile:

Awesome. Thanks for that feedback everybody! @lin_d_hop @nick @CynthiaReynolds @Oliver

Just looking at the docs a little further, and found another argument in favour of Stripe Connect. It will allow us to store customer card details centrally (against the instance’s stripe account) and then use those to charge customers to any connected enterprise. This way we only have to ask customers to enter their card details once (ever), and we can make that card available as a payment option anywhere on the instance. Obviously this need to be explained but I think it is a fairly palatable proposition. More info in the Sharing Customers section of the Stripe docs.

The alternative where we store individual API keys would mean that we need to ask customers to enter their details at least once per shop, as there is no mechanism for sharing details across (from Stripe’s perspective) two completely disconnected accounts.

@oliver Thanks for those thoughts. I certainly don’t feel confident enough to say that the API keys option (option 2) is the easier route. Yes we have a solution that ‘works’ out of the box, but IMHO simply running with this as-is creates an unacceptable level of risk unless we do some serious work on encryption/decryption of keys (not very pretty or fun), or on enforcing some serious protocols for downloading and managing access to copies of the database (which means ongoing work). I’ve been looking at the code and I am hopeful that tweaking Spree’s Stripe gateway to work with Stripe Connect may not be huge amount of work - the API, and the existing Spree gateway appear to be well written and quite flexible. Fingers crossed, will report back when I know more.

@lin_d_hop: I think perhaps there is a little confusion about what is being proposed: at this stage I am not suggesting that customers be asked to connect their stripe accounts to the OFN, merely that they enter their card details which we can ask Stripe to store for later use. We can certainly look into supporting this as a next step, but I don’t think it should be part of the initial round of work? The flow for customers entering their card details will be entirely ‘in-house’, so no need to redirect customers to Stripe. In fact Stripe need not be mentioned to the customer at all.

The component that will require users to be directed through Stripe is the ‘Connect’ aspect for enterprise users wishing to use Stripe as a payment method ie. enterprise users connecting their stripe accounts to the instance, which authorises the instance to charge customers on their behalf. The flow for connection is relatively straight-forward: enterprises users would click a ‘Connect to Stripe’ button somewhere in the admin section, which would send them to Stripe to confirm authorisation, and then they would be sent back to the OFN. There is an example of what this might look like on this page (about halfway down). Once enterprises have ‘connected’ to the instance, they can create payment methods based on that connection, which then behaves like any other payment method (except that we can do cool stuff like auto-load info for any customers with stored card details, or charge customers with standing orders without them having to touch the site).

I am still completely undecided as to whether we should ‘Connect’ stripe accounts to users or to enterprises. What is clear to me is that if we connect them to users, we will need to allow each user to link multiple Stripe accounts to their OFN user, because a single user can foreseeably own two enterprises that need to use two separate Stripe accounts to charge customers. It is important to note that Stripe accounts connected in this way would not be at all equivalent to those connected via the front-end (if we decide to implement that at some point): the former represents an authorisation for the instance to charge on behalf of the Stripe account holder, the second represents an authorisation for the instance to charge the Stripe account holder on behalf of another. Stripe treats these as two very different classes of relationship: the first is a ‘Connected Account’ and the second is a ‘Customer’.

1 Like

Latest: @stveep and I are going to attempt to get a proof of concept using Stripe Connect working. Then we’ll move on to data model, UI and UX design.

1 Like

Thank you @oeoeaio for this extensive investigation :slight_smile:
I dont feel very competent on the tech dimension of what you said, but there is something I don’t understand on the “features” and UX side, I would need some clarification :wink:

What I understand is that proposing Stripe as a payment method would enable standing orders as a hub will be able to charge a customer the the basket at every OC, when the standing order repeats.
But for me the most important feature I had in mind with implementing a multi-vendor payment gateway, and that I think Stripe Connects does (but not the regular Stripe API keys) is saving a lot of work for the hub, who won’t have to collect the money from the customers and then pay the suppliers, the money flowing directly as “mapped” in the system (see my post on it here: How to offer Mangopay as a payment method to hubs? [Split Payments])
Is this feature included in Stripe Connect? I don’t read anything about it here so I’m not sure, sorry if I don’t understand everything :wink:
And that means also reworking some of the existing processes (like adding a step where the hub manager has to validate that the order has been delivered so that the money flows from the e-wallet of the customer to the e-wallets of the suppliers, hubs, and instance. I listed them in the other discussion, they apply to Mangopay or any multi-vendor payment gateway system).

If Stripe does that job in the way you plan to implement it, then it sounds like a more international option than Mangopay and would probably be a better value-for-work/money option for the whole community as it would benefit much more countries at once! We would probably need to propose Mangopay in France as well, but once the work has been done with Stripe, I guess it would be pretty similar with Mangopay later on. And we can start proposing Stripe to the hubs who can’t “collect and pay the suppliers” for legal reasons, so that would answer our need on a short term.

Hi @MyriamBoure!

I suspect that the best solution for your particular requirement is still going to be to an implementation of Mangopay. I understand your use case and it is certainly in my mind, but unfortunately I don’t think that Stripe Connect (or any other platform) is going to be our silver bullet for all payment gateway features we would like. Stripe Connect gives us a lot of the high priority features in a relatively universal gateway, but it is really designed to model a set of relationships between a single platform (eg. the OFN) and its users (eg. OFN shops). There is no provision for the users to then have connected accounts themselves which they can distribute funds to, so I don’t think we will be able to use it for multi-vendor payment gateway support.

###Scenario: using multiple Stripe Connect accounts on one platform

I suppose in theory, it could be possible to decentralise the model by creating a Stripe Connect account for each shop, but this is problematic for a bunch of reasons:

  • Stripe requires that each Connect user registers their “platform” before it is approved. My understanding is that registration of a platform is non-trivial. So we would have to somehow do this for each shop who wanted to use Stripe.
  • I am not even sure that Stripe themselves would allow us to register multiple Stripe Connect accounts on one platform - it is certainly not something they mention…
  • We would need customers to re-enter their details for each individual Shop they wanted to purchase through on the OFN, because the individual Stripe Connect accounts for each shop are not linked in any way.
  • All of the API key security headaches would resurface, because we would have to store a separate API key for each shop

There may be other issues too, but IMHO that is enough things to make this particular idea unworkable. We lose a lot of the benefits of the standard implementation (easy management of security for the platform, ease of use for customers and shops), for a system which looks fairly unpleasant to administrate to me…

Multi-vendor gateway support: ie. Mangopay

I understand the multi-vendor gateway use case and think it supporting it is a great idea, saving time, and allowing support of business models that require direct distributions of funds to producers for legal/tax reasons in your jurisdiction. Unfortunately however, I think the highest priority for now for the global community has to be a (relatively) universal gateway with a low barrier-to-entry, capable of handling recurring payments. I think Stripe Connect fits that bill.

As I said, from the little I know about it, I think Mangopay is absolutely the go-to for this feature, but think its implementation is going to need to be its own feature. It is a significant body of work, and sadly we simply don’t have the resources to implement both Stripe Connect and Mangopay at once.

As always, I’m very happy to work with you to map out exactly what features are required and what implementation looks like, so we can get an idea of next steps and budget, etc… :slight_smile:

1 Like

Ok, I understand @oeoeaio, thanks for the explanation, it was not clear to me… Stripe is anyway an must-have option to propose the hubs, so it’s needed anyway, and let’s continue que discussion on Mangopay here.

I’ve been making a start on this - have jotted down some thoughts on how to go about it here and on the issue https://github.com/openfoodfoundation/openfoodnetwork/issues/1143

(See issue for more techy stuff)

Here are a few questions that came up for me when thinking it through:

  • When a Customer makes a payment using the Stripe gateway:
    • Create a Stripe Customer on the instance Stripe account (or should this be hub Stripe acct?) if it doesn’t already exist (https://stripe.com/docs/connect/shared-customers)
    • This can then be used to make future charges to that Customer account.
    • Should we store this locally or retrieve as needed via Stripe API?
    • Should we have a way of creating a Customer independently of placing an order?
  • What happens when…
    • A second co-ordinator of an enterprise tries to connect a new Stripe account?

To me, it makes sense to have the accounts associated with Enterprises in the OFN system, since we are not going to use them to authenticate users (although we could). It also allows multiple users to administer stripe connect for an enterprise. So I’ll try to build it like this as a start and we’ll see how it looks. Most of what we need to do is in these guides from the stripe docs:

https://stripe/docs/recipes/store-builder

In order to connect enterprise stripe accounts to the instance we need to have the instance one set up and activated (which involves some verification of business details). So maybe @nick or @lin_d_hop could set up & activate one for the UK if we don’t have one already? Then I can use this to test stuff - I’ll need API keys and ideally login details if possible.

Hi Steve - it was really good to see you and Claire yesterday - thanks for calling in and I hope your Stroudco order worked out well.

Here are my thoughts (in bold) on your questions:
When a Customer makes a payment using the Stripe gateway:
Create a Stripe Customer on the instance Stripe account (or should this be hub Stripe acct?) if it doesn’t already exist (https://stripe.com/docs/connect/shared-customers)
I think we might need individual hub Stripe accounts so that there is less chance of confusion with transactions, balances, etc

This can then be used to make future charges to that Customer account.
Should we store this locally or retrieve as needed via Stripe API?
I don’t know - let’s see if you get a more intelligent answer - if not we could talk through at the next hangout

Should we have a way of creating a Customer independently of placing an order?
I can’t imagine why we would need to do this

What happens when…
A second co-ordinator of an enterprise tries to connect a new Stripe account?
if this is going to be a problem could we make it so that only the enterprise owner (rather than any manager) can connect a new account?

@lin_d_hop have you already set up a stripe account? if not shall i set one up for OFN UK? Or shall I ask @Oliver to set one up for Stroudco so that we can test individual hubs having separate Stripe accounts?

I am pinging this to @Sara and @mags in case they want to chip in.

@nick We currently don’t have an OFN UK stripe account so would you go ahead and set one up?

OK we now have an OFN UK stripe account here https://dashboard.stripe.com/test/dashboard
the login email is hello@openfoodnetwork.org.uk I will send @stveep the password and api keys separately.

Do we want to ask @oliver to set up a separate stripe account for stroudco?

Hi @stveep and @nick,

Good questions Steve. I’ve had a bit of a think about this stuff and touched on some of it above, but here are my thoughts about your questions:

Create a Stripe Customer on the instance Stripe account (or should this be hub Stripe acct?) if it doesn’t already exist (https://stripe.com/docs/connect/shared-customers)
IMO Stripe Customers should be stored against the instance’s Stripe account. If we opt for storing Stripe Customer details per-shop, they will need to be re-entered for each shop, whereas if we store against the instance, we can reuse card details for any shop on the instance. Bear in mind that a Stripe customer is more closely related to an OFN User than an OFN Customer. Either way, this is a very low level question, which only developers will ever need to understand, this level of detail will never be exposed to customers or shop owners.

Should we store this locally or retrieve as needed via Stripe API?
As far as I understand, we only need to store a customer ID (given to us by Stripe when we register the customer) in order to create a charge against that customer using our instance API key. We will need to store that locally regardless, but there should be no reason to store anything else, or to retrieve any additional information from Stripe in order to create a charge. Does that sound right?

Should we have a way of creating a Customer independently of placing an order?
Yes, but this is possibly a next step - we don’t need to tackle it as part of the proof of concept. Given that we will need an interface for users to edit their stored card details anyway, it makes sense to allow them to add new cards in the same place (ie. Stripe call these ‘sources’, but we would need to create a new Stripe ‘customer’ for new OFN users with a linked Stripe customer ID, so that we can store the ‘source’ against it). Then we can support the use case where a user would like to set up their card details as soon as they create an account, so they ready to shop wherever we would like.

So this means (perhaps slightly confusingly for developers) we need to store the Stripe Customer ID against an OFN User. I think we can just retrieve all of the information about stored cards from Stripe using this Customer ID whenever we need it (eg. checkout).

What happens when a second co-ordinator of an enterprise tries to connect a new Stripe account?
Yeah, this is the part that I still haven’t gotten my head around. I think I am heading more towards the approach you mentioned of storing against an enterprise. I think having one Stripe account per enterprise is not too much of a constraint. What do you think? This way, a second coordinator would only be able to alter the existing Stripe account for a given enterprise, they would not be able to add a new one.

Hi All,

Stroudco already has a Stripe account because we have recently switched to Xero accounting software, where online payments are processed via Stripe.

@oeoeaio I’m not sure it will happen all that often that a customer shops at different food hubs so storing against the instance may only be more efficient in theory.

@Oliver that may be true but as far as I can see there are no advantages to storing the customer against the shop’s Stripe account. The disadvantages will be that the interface for adding/updating card details will need to be scoped to a particular shop (regardless of whether multiple shops are engaged with) which is confusing, and in the event that a customer does want to use a card at multiple shops, they will need to enter the exact same details for each shop, and any changes to card details will need to be replicated across the shops, I think this is fairly non-intuitive…

I agree @oeoeaio that storing customers against the instance is a better move. It has big UX advantages for OFN as a whole, making it super easy to try shopping with different enterprises. This should be a selling point of the platform as it develops.

Perfectly ok with me.

@oeoeaio
Rob, have you got a rough time line for the Standing Order feature? How far down the line do you think we are before users like me can start testing it?

Thanks
Oliver

Hi @Oliver, we’re hoping to have something ready to be played with in the first week or so of October. That’s when testing will start properly with @sstead and @mags, and we’ll be putting a link out for anyone to use it and provide feedback. All going well we hope to have it out by November, depending on the tweaks needed from the feedback we receive.

1 Like