Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider making Omnipay do more of the work #157

Open
eileenmcnaughton opened this issue Jan 10, 2021 · 12 comments
Open

Consider making Omnipay do more of the work #157

eileenmcnaughton opened this issue Jan 10, 2021 · 12 comments

Comments

@eileenmcnaughton
Copy link
Contributor

eileenmcnaughton commented Jan 10, 2021

The advantage of Omnipay is it's possible to re-use the same code across multiple processors. However, Sagepay makes that quite tricky because is supports multiple methods and requires the integrator to have a pretty full understanding of them.

I'm wondering if Omnipay could respond more similarly to other processors by taking a queue from the context.

For example after calling

$gateway->purchase();

there is no getToken function to retrieve the json string that I could use to call repeatPurchase. However, it would be fairly easy for this function to be added & for it to return a json string that could be stored & later passed to repeatPurchase as a 'token' Further the purchase'function could actually call repeatPurchase if it is called with a token consistent with what repeatPurchase requires. Doing this would make it possible to use the same code for sagePay without understanding then inner workings (it would still be necessarly to know the initial call uses purchase`` rather than createCard'``` with ['action' => 'purchase'] as we are currently doing for other gateways but it would be close to compatible and that could be addressed too.)

I can try to work up a patch if you are open to it

@eileenmcnaughton
Copy link
Contributor Author

Also another gotcha is that passing in an empty 'card' causes it to fail so

if ($card)

could check if any params are actually set....

eileenmcnaughton added a commit to eileenmcnaughton/omnipay-sagepay that referenced this issue Jan 10, 2021
Wiping out the whole array is pretty extreme. Only do it if the card array actually has
meaningful values. The code that calls this might be trying to support multiple
processors so don't assume it 'knows' not to pass an empty card if the processor is sagepay

thephpleague#157 (comment)
eileenmcnaughton added a commit to eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor that referenced this issue Jan 10, 2021
Hopefully thephpleague/omnipay-sagepay#158
will be merged but for now SagePay assumes that an empty card is an ignore-everything-else-card

Also declare support sagepay alternate function choices per
thephpleague/omnipay-sagepay#157
eileenmcnaughton added a commit to eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor that referenced this issue Jan 10, 2021
This works but there are a few outstanding considerations

1) Sagepay uses actions that are inconsistent. I have gone with declaring this as metadata
as the 'most' transparent metadata - ie each piece of metadata should not
have a bunch of interwoved assumptions like 'if it's this
action then it's also this action and card is handled this way' but
I hope we can do some upstream work
to make it less ad hoc  - thephpleague/omnipay-sagepay#157

2) I'm a bit on the fence about the approach of creating a token only when it is recurring
and still using transaction data from the contribution.trxn_id. I think overall I prefer
to always create a token since any contribution could be used for a token and not
to save transaction data (over and above the trxn_id) in the contributon.trxn_id
but given I had written it this way I have not preferred that enough to re-write it. Test
cover should facilitate future changes (more or less)
eileenmcnaughton added a commit to eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor that referenced this issue Jan 10, 2021
This works but there are a few outstanding considerations

1) Sagepay uses actions that are inconsistent. I have gone with declaring this as metadata
as the 'most' transparent metadata - ie each piece of metadata should not
have a bunch of interwoved assumptions like 'if it's this
action then it's also this action and card is handled this way' but
I hope we can do some upstream work
to make it less ad hoc  - thephpleague/omnipay-sagepay#157

2) I'm a bit on the fence about the approach of creating a token only when it is recurring
and still using transaction data from the contribution.trxn_id. I think overall I prefer
to always create a token since any contribution could be used for a token and not
to save transaction data (over and above the trxn_id) in the contributon.trxn_id
but given I had written it this way I have not preferred that enough to re-write it. Test
cover should facilitate future changes (more or less)
@judgej
Copy link
Member

judgej commented Jan 10, 2021

Yes, that makes a lot of sense.

So:

  • The JSON transactionReference it also returned by getToken().
  • The purchase() method calls repeatPurchase() (similarly for authorize) if the token is set.

Is that the gist of it?

There are also some unusual flags to "set token" and "store token" that need to be used in the request if yout want to be able to reuse a payment for repeat payments. I think "set token" allows a token that has been previously stored to be used, and "store token" sets a token for reuse in the current transaction. You need to kind of juggle the two, but setting "store token" to yes as a default has some security implications, in that every single transaction effectively becomes a repeatable transaction, which you don't really want unless the user has excplicitely agreed to it.

I'm a little rusty, so need to reed up on what the latest is, expecially since SagePay was purchased, and who knows what direction it will be going. I get the impression there is a tonne of technical debt in this gateway, and it will either have the tiniest of incremental changes, or will be replaced completely with a new system.

@eileenmcnaughton
Copy link
Contributor Author

@judgej yep - that's pretty much the gist of it - I'll take a look since you seem open to it - I did put up #158 which is a bit tangential but part of the same thing

@judgej
Copy link
Member

judgej commented Jan 10, 2021

You caught that heavy-lifting word "assumption" on #158 ;-)

@eileenmcnaughton
Copy link
Contributor Author

@judgej do you have any thoughts about the travis issues on #158 ?

@judgej
Copy link
Member

judgej commented Jan 10, 2021

Just looking at that, and much of it (as is often the case with travis) is above my head and I just end up poking it and seeing what happens. This looks like it could be worth trying: sebastianbergmann/php-code-coverage#834 (comment)

@judgej
Copy link
Member

judgej commented Jan 10, 2021

Also Barry is using php4snapshot here, which may help: https://github.com/thephpleague/omnipay-payfast/blob/master/.travis.yml However, I think the problem is only in December 2020's PHP releases, so it could be other drivers have not actually hit this problem yet, but will.

eileenmcnaughton added a commit to eileenmcnaughton/omnipay-sagepay that referenced this issue Jan 10, 2021
Wiping out the whole array is pretty extreme. Only do it if the card array actually has
meaningful values. The code that calls this might be trying to support multiple
processors so don't assume it 'knows' not to pass an empty card if the processor is sagepay

thephpleague#157 (comment)
@eileenmcnaughton
Copy link
Contributor Author

I looked at making it call repeatPurchase rather than purchase if cardReference is set but it seemed to work better to simply make purchase & authorize adapt their behaviour if it is a repeat. The code that figures that out is actually lower in the chain that they extend so it was pretty available to them. On the other hand repeatPurchase & repeatAuthorize don't share methods the others use so I felt that deprecating rather than changing them would work.

Also the task of determining which to call would need to be done in the gateway class - and it would not pick up . be able to respond if the setTransactionReference function were called after the initial construct.

@eileenmcnaughton
Copy link
Contributor Author

I also opened this to raise the way 'confirm' is handled thephpleague/omnipay-common#245

@eileenmcnaughton
Copy link
Contributor Author

@judgej I'll look at the remaining bits & pieces in a couple of weeks if you get a chance to check out the PRs I've opened so far

@judgej
Copy link
Member

judgej commented Jan 15, 2021

Okay, thanks. I'll try to find some time this weekend. Just been unfeasibly busy this week.

@eileenmcnaughton
Copy link
Contributor Author

eileenmcnaughton commented Jan 17, 2021

@judgej fair enough ! (I'll be AFK from 19 to 27 Jan myself)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants