Contributing 2 3dsecure payment gateways

184 views
Skip to first unread message

Morgan Christiansson

unread,
Dec 16, 2010, 10:57:37 AM12/16/10
to Active Merchant
Hello,

I would like to contribute 2 payment gateways for Realex and DataCash
w/ 3dsecure to AM which we have new features and 3dsecure for. (All UK
payment providers).

AFAIK there's currently no 3dsecure in AM, but our current
implementation works basically like this:

response = @gateway.purchase(@amount, @credit_card, @options)
if response.requires_authentication?
# redirect user to the 3dsecure ACS gateway contained in:
response.access_control_server
elsif response.success?
# transaction successful
end

# Once returned from 3dsecure gateway:
response = @gateway.authenticate(response.authorization, :md =>
params[:md], :payment_authorisation_response => params[:pares])
if response.success?
# transaction successful
end

Would you be open to accepting these patches more or less as is?
There's been some discussion about 3dsecure on the list previously and
a fork on github (https://github.com/tekin/active_merchant ) supports
3dsecure in ProtX, so I'm not sure why there's no gateways in AM
already supporting it.

We use a different API from the one tekin uses for ProtX 3dsecure but
we would be open to some refactoring if they the gateways are accepted
upstream (as we're in the process of switching payment providers
anyway).

Regards,
Morgan
Message has been deleted

Nathaniel Talbott

unread,
Dec 20, 2010, 10:48:00 AM12/20/10
to activem...@googlegroups.com
On Mon, Dec 20, 2010 at 6:13 AM, Tekin Suleyman <te...@tekin.co.uk> wrote:

> It shouldn't be too difficult to come up with a common interface. Maybe it
> should simply be:
>
> gateway.authenticate(response.authorization, pares, md)

I haven't done anything with 3DSecure (it's a nightmare for automated
renewals, so Spreedly has skipped it so far), but I'd love to hear
what (if anything) Shopify is doing about it since it seems very
apropos to the e-commerce space. Does Shopify support 3DSecure for any
gateways today?


--
Nathaniel Talbott
<:((><

Morgan Christiansson

unread,
Dec 20, 2010, 12:54:36 PM12/20/10
to activem...@googlegroups.com
On 20/12/10 15:48, Nathaniel Talbott wrote:
On Mon, Dec 20, 2010 at 6:13 AM, Tekin Suleyman <te...@tekin.co.uk> wrote:

It shouldn't be too difficult to come up with a common interface. Maybe it
should simply be:

gateway.authenticate(response.authorization, pares, md)
I haven't done anything with 3DSecure (it's a nightmare for automated
renewals, so Spreedly has skipped it so far), but I'd love to hear
what (if anything) Shopify is doing about it since it seems very
apropos to the e-commerce space.
I don't think 3dsecure affects renewals, only interactive purchases. Although I haven't looked at renewals.

Anyway 3d secure can be enabled/disabled for certain transactions by passing in an option in the options hash. In Tekins implementation the option is :skip_3d_secure => true whereas in my implementation it's :authentication => false
Does Shopify support 3DSecure for any gateways today?
No official support, AFAIK Tekins fork on github and my 2 gateways are the only ones to support 3dsecure.

Regards,
Morgan

Morgan Christiansson

unread,
Dec 20, 2010, 1:13:07 PM12/20/10
to activem...@googlegroups.com, Tekin Suleyman
I would be open to refactoring my methods to match yours, but I would need to change the APi used in our application though.

Would it be a problem for you to refactor any of the names? Do you have many users?

I agree that #authenticate is a too generic name that could mean other things in some gateways. three_d_complete is a better name.

Regards,
Morgan

On 20/12/10 11:13, Tekin Suleyman wrote:

Hi Morgan,

Sounds good, I would be more than happy to contribute to get 3D Secure support into AM proper.

It looks like there are only minor differences between your API and the one I did for ProTX/SagePay:

Mine: gateway.three_d_complete(pa_res, md)

Yours:  gateway.authenticate(response.authorization, :md => md, :payment_autorisation_response => pares)

It shouldn't be too difficult to come up with a common interface. Maybe it should simply be:


gateway.authenticate(response.authorization, pares, md)

In the ProTX/SagePay gateway, I'd simply ignore the response.authorization as it's not required.

I called my method "three_d_complete" partly because I thought it would be good to be explicit about the fact you are completing a 3D Secure transaction and partly because "authenticate" has another meaning in the SagePay gateway API.

Regards,

Tekin Suleyman

--
You received this message because you are subscribed to the Google Groups "Active Merchant" group.
To post to this group, send email to activem...@googlegroups.com.
To unsubscribe from this group, send email to activemerchan...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/activemerchant?hl=en.

Tekin Suleyman

unread,
Dec 20, 2010, 2:06:41 PM12/20/10
to activem...@googlegroups.com

Anyway 3d secure can be enabled/disabled for certain transactions by passing in an option in the options hash. In Tekins implementation the option is :skip_3d_secure => true whereas in my implementation it's :authentication => false

In fact, I go one stage further by requiring that you explicitly enable 3D Secure when you instantiate your gateway:

ActiveMerchant::Billing::ProtxGateway.new(:login => 'login', :password => 'password', :enable_3d_secure => true)

Unless you do, the Gateway will behave as normal. This way, those that want (and can) ignore 3D Secure can continue to do so.

Does Shopify support 3DSecure for any gateways today?
No official support, AFAIK Tekins fork on github and my 2 gateways are the only ones to support 3dsecure.


Cody was attempting to implement it for Payflow but I'm not sure how far he got.


Tekin Suleyman


Tekin Suleyman

unread,
Dec 20, 2010, 2:59:17 PM12/20/10
to activem...@googlegroups.com

> In actual fact, I think #authenticate may be closer to what we'd want for a common API. Remember, Active Merchant is meant to abstract away all the weird idiosyncrasies of gateways like SagePay so I don't think we should let the fact that one Gateway uses the same term stop us from using it if it makes more sense. Maybe something like #complete_authentication would make more sense as "Payment Authentication" is what happens when the user completes the card issuer's 3D Secure form. Or possibly #confirm_authentication.
>

Or, how about #complete_3d_authentication?


Tekin Suleyman

Tekin Suleyman

unread,
Dec 20, 2010, 3:03:53 PM12/20/10
to activem...@googlegroups.com, Tekin Suleyman


Would it be a problem for you to refactor any of the names? Do you have many users?

It's not really an issue for me - I'd keep my fork as it is so as not to break compatibility for all the people currently using it and then write a completely new patch against the main Shopify/active_merchant repo.

 
I agree that #authenticate is a too generic name that could mean other things in some gateways. three_d_complete is a better name.

In actual fact, I think #authenticate may be closer to what we'd want for a common API. Remember, Active Merchant is meant to abstract away all the weird idiosyncrasies of gateways like SagePay so I don't think we should let the fact that one Gateway uses the same term stop us from using it if it makes more sense. Maybe something like #complete_authentication would make more sense as  "Payment Authentication" is what happens when the user completes the card issuer's 3D Secure form. Or possibly #confirm_authentication.
 
Tekin Suleyman

Morgan Christiansson

unread,
Dec 21, 2010, 5:44:17 AM12/21/10
to activem...@googlegroups.com
I like complete_3d_authentication, it is self-explanatory and uses "3d"
instead of "three_d".

I'll be working on this for another 2 days before the Christmas holiday
starts and I'm focusing on finishing and stabilizing everything under
the current API.

Once that's done I will push the gateways to a public github repo, do
the refactorings and merge with Tekin and we will soon have a
active_merchant with 3x3dsecure enabled gateways. :-)

Regards,
Morgan

Nathaniel Talbott

unread,
Dec 21, 2010, 12:29:04 PM12/21/10
to activem...@googlegroups.com
On Tue, Dec 21, 2010 at 5:44 AM, Morgan Christiansson
<mor...@notonthehighstreet.com> wrote:

> I like complete_3d_authentication, it is self-explanatory and uses "3d"
> instead of "three_d".

Is "3D Secure" the common name for this across all gateways? It seems
so much like a marketing buzzword that I wonder if it's wise to
include it in the API vs. using something more generically
descriptive.


--
Nathaniel Talbott
<:((><

Morgan Christiansson

unread,
Dec 21, 2010, 12:44:39 PM12/21/10
to activem...@googlegroups.com, Nathaniel Talbott
Yes. http://en.wikipedia.org/wiki/3-D_Secure

Apparantly MasterCard calls it SecureCode and Visa calls it Verified by Visa. But 3dsecure is the common name I've heard it called.

Regards,
Morgan

Ed W

unread,
Jan 1, 2011, 5:53:50 AM1/1/11
to activem...@googlegroups.com
On 21/12/2010 10:44, Morgan Christiansson wrote:
> I like complete_3d_authentication, it is self-explanatory and uses
> "3d" instead of "three_d".

I would recommend going back to something like your original name?

There may be other authorisation services in the future and a more
generic "need_more_auth" and "complete_transaction" style api is more
accomodating of this

Quite a few of the "Integrations" can be refactored like this, ie setup
the transaction, redirect to authorise and complete, confirm and
complete. Also Outsourced card collection can be viewed like this.

Basically the abstraction is that:
- Try and request a payment
- Further authentication is needed
- Redirect to take additional auth
- Complete

Specific eg:

- The paypal gateway (is it called Payflow?) works in roughly the same
way, ie setup the transaction, redirect to Paypal to get customer to
enter PP password, redirect back to complete transaction
- Sagepay Server. Here you setup the transaction, but then you need to
redirect to Sagepay to actually let them collect the card details (and
they do the 3D Secure while they are there).
- Solve a lot of compliance issues by "blackboxing" the card collection
code. Now your app behaves more like an integration, setup the
transaction, "need more auth" so redirect to your blackbox'ed server to
collect the card details (in some VM so there is much less to "audit"),
redirect back to complete
- Current 3D secure, it's almost uninteresting that you already have the
card details because it's still the same process: request purchase,
discover more auth needed, redirect to get the additional auth, complete
- can anyone see any difference?


So it's really no different that in the 3D secure case we find we need
only one extra bit of auth information, and in the SagePay Server case
we need to collect ALL the card details, from an API point of view it's
basically the same? Further, given the limited success of 3D secure,
and next year we will see a bunch of increasingly powerful smartphones,
it seems very likely that we will see alternative security ideas in the
timeframe of less than a few years?

So, my vote would be flexible API that is basically like Morgan's
original API, ie the response object can indicate either success, or it
fails, but indicates that some additional authentication is required.
This covers the case of a bunch of eventualities, including the
currently slightly icky Paypal gateway and would also wrap some stuff
which is currently an "integration" and also provide a path for more
services along the lines of the SagePay outsourced service to collect
the card details?

Cheers

Ed W

Morgan Christiansson

unread,
Jan 4, 2011, 12:10:55 PM1/4/11
to activem...@googlegroups.com, Ed W
Your examples do not use creditcards in the first step ("Try and request
payment", authorize and capture) which is very different from how AM
currently works.

But I agree that it's a good idea to use a name that is not 3dsecure
specific and it opens up to future flexibility for these kind of gateways.

I like the complete_ prefix suggested by Telkin though as it separates
it from the authorize() method and makes it clear that it's called
post-authentication.

So:
def complete_authentication(identification, options = {})

Thanks for your ideas,
Morgan

Ed W

unread,
Jan 5, 2011, 11:56:36 AM1/5/11
to activem...@googlegroups.com, mor...@notonthehighstreet.com
On 04/01/2011 17:10, Morgan Christiansson wrote:
> Your examples do not use creditcards in the first step ("Try and
> request payment", authorize and capture) which is very different from
> how AM currently works.

I disagree? Take a step back and look at the problem more generally:

- Gateway might additionally require the customer to enter some extra
"3D Secure" password
- Gateway might additionally ask customer for their CC details securely
(avoiding your app needing to collect them)
- Gateway might additionally ask customer for username/password instead
of "credit card" (eg paypal)
- Gateway might take a "token" instead of a "credit card", (perhaps this
allows for a repeat against a previous transaction, or similar)
- Gateway might find "credit card" details incomplete and additionally
need to prompt for some of them again, eg consider "token" entered and
card either expired (prompt new expiry date), or 3 security digits must
be collected (seems to be new rules with repeat payments)

OK, some of the above looks like a kind of "repeat", but disregard,
because I think the point is that the abstraction for "Purchase" is really:

- Send over everything you have got (might not be enough) and attempt a
purchase
- This may be sufficient and payment is authorised
OR
- Knocked back and asked to redirect to collect MORE
information/authorisation (could happen multiple times in theory)
- Once additional details collected, complete payment


eg with Paypal you don't send over the CC Details, you just attempt to
auth, you are told to redirect to Paypal for the customer to enter
username and password and assuming it's valid you get redirected back to
your app. Do you not feel this is exactly the same as: attempt to auth
WITH CC Details, told to redirect to some 3D secure for customer to
enter username and password and assuming it's valid you get redirected
back to your app? This feels like the same process to me, just
different info being collected?

Or whatabout: You send over some token, attempt to auth, you are told to
redirect to 3D secure to enter username/password, redirect back to app.
Other than taking a token, not card details, what's the difference to
normal 3D secure?

Or: You send over no token or CC details, you just attempt to auth, you
are told to redirect to the payment gateway so *it* can collect the CC
details, redirected back to your app on completion. (Sagepay Server).
What's the difference? In this case there is no CC sent intially, so the
"redirect" collects both 3D secure AND card details?

I really don't see how the above *process* is different to the 3D Secure
case? In all cases it's kind of "have a go, if you don't have enough
details then redirect to get the extra stuff, then back to your app for
a second go"

Are you with me..?


Ed W

Morgan Christiansson

unread,
Jan 5, 2011, 12:39:06 PM1/5/11
to activem...@googlegroups.com, Ed W
Your examples do not use creditcards in the first step ("Try and request
payment", authorize and capture) which is very different from how AM
currently works.

But I agree that it's a good idea to use a name that is not 3dsecure

specific and it opens up to future flexibility for these kind of gateways.

I like the complete_ prefix suggested by Telkin though as it separates
it from the authorize() method and makes it clear that it's called
post-authentication.

So:
def complete_authentication(identification, options = {})

Thanks for your ideas,
Morgan

On 01/01/11 10:53, Ed W wrote:

Morgan Christiansson

unread,
Jan 5, 2011, 12:39:58 PM1/5/11
to Ed W, activem...@googlegroups.com
Yes I see your point.

I meant in terms of API design there's a CreditCard class which
authorize/purchase expect an instance of and all gateways (afaik) expect
a CreditCard object to build the network requests.
Also (almost) all applications that use AM have HTML forms and
validations expecting creditcards.


But seeing it from your perspective - nil could be passed in instead of
a CreditCard object, or the API could be refactored to pass creditcard
as :creditcard in options. So - yes I agree that your process fits well
with the AM design.
Even though the AM API was not designed for non-creditcard payments.

Regards,
Morgan

Morgan Christiansson

unread,
Jan 5, 2011, 12:40:44 PM1/5/11
to activem...@googlegroups.com
Sorry, accidentally re-sent the wrong message from drafts!
/Morgan

Ed W

unread,
Jan 5, 2011, 2:07:50 PM1/5/11
to Morgan Christiansson, activem...@googlegroups.com
Hi

> Also (almost) all applications that use AM have HTML forms and
> validations expecting creditcards.

But that's simply a statement that it's only possible to work this way
because the API is currently too limited to do otherwise?

Also note that quite a few of the gateways now have non standard APIs to
handle these warts and alternatives - my proposal (I think) unifies
quite a number of the other non standard APIs back into a standardised
process?

(eg the Paypal API knows in advance that it doesn't have a CC so it uses
something (from memory) like setup_purchase, redirects and then calls
purchase. However, we can easily treat is as a "surprise" that the
purchase call requires a redirect and work it into the process I
described where we basically try and take a payment, redirect in the
case more info is required and then complete? Cool huh. Additionally
token payments for repeats, credits and outsources CC strongboxes neatly
fit into the API?)

>
> But seeing it from your perspective - nil could be passed in instead
> of a CreditCard object, or the API could be refactored to pass
> creditcard as :creditcard in options. So - yes I agree that your
> process fits well with the AM design.

I like the second option. OR make the parameter more generally named so
that it makes sense to pass in a "token" object or leave it nil.

After all the goal is to take a payment from a specific payment source.
A Credit Card object is a direct reference to a payment source, but
other payment sources could be a bank account, paypal account, "an
alias" to a card (ie a Token), etc. It takes only trivial changes to
the API to encompass these sources?

> Even though the AM API was not designed for non-creditcard payments.

This "not designed" statement sounds like there is a mountain of formal
design documentation and a committee involved in coming up with the
current API? Is it not fairer to say that "some arbitrary choices were
made in the past and these currently make it tricky to process non
(direct) CC payments or payments which require additional authentication
such as 3D Secure"?

After all the API doesn't support your proposed change either (which is
why you are proposing a change!). But, with only trivial additions to
the API (and basically I'm supporting/advocating *your* original
proposed API change), we will support both 3D secure, Paypal and perhaps
token payments and outsourced CC collection processes (Sagepay Server
a-likes)

So I would personally like to see your original changes become the
"standardised API" that other gateways will copy going forward... ie if
you could re-cut your patch with an eye on the "redirect for more auth"
procedure being quite generic to support Sagepay server and Paypal, then
I think we have a really good (and quite minor) adjustment to the API?

I have a private adjustment to Sagepay supporting basically what you
have just done to accomodate the "Server" (they collect the CC details
on your behalf, no PCI to pass...) and so if you standardise your
approach I will adjust my code to match and submit it also?

Cheers and good luck

Ed W

Cody Fauser

unread,
Jan 8, 2011, 2:56:51 PM1/8/11
to activem...@googlegroups.com, adr...@shopify.com
We at Shopify are in the process of implementing several 3D Secure
gateways and have slightly altered Tekin's fork for SagePay. We're
currently incorporating 3D Secure into our checkout and we're trying
to distill a nice API between the various implementations.

We are using the name "Buyer Authentication" for 3D Secure, which is
the name Payflow Pro gives to the process. I like this, as you don't
end up with 3 or three anywhere in the code, which makes the code more
pleasant to look at.

There are two concepts or processes to deal with when performing buyer
authentication:

1) Verifying card enrollment, sending the buyer to the 3D secure site
managed by the card brands, getting back the authentication data and
validating it.
2) Passing the buyer authentication results (XID, CAVV, etc) to the
payment gateway when performing the authorization or purchase

Fortunately or unfortunately, depending on your perspective, some of
the gateways like SagePay have decided to try to "help out" and have
essentially scrambled process #1 and #2 together. This is great when
you only care about using SagePay, but makes generic abstractions
across a library like Active Merchant a lot more difficult.

There are a few things that we can get started on to speed the
inclusion of real support for 3D Secure in Active Merchant:

1) Identify the various 3D Secure implementations provided by
gateways. I've currently seen two models: SagePay style and Payflow
Pro / Cardinal Centinel style

For those of you not familiar with Cardinal Centinel, they provide a
generic 3D Secure API that can be used with any payment gateway that
is implemented with distinct steps #1 and #2 above. i.e. Not SagePay.
You simply integrate their platform and then pass the authentication
data to the payment gateway when doing the auth or purchase. PayPal UK
did exactly this by offloading the 3D Secure process to Cardinal
Centinel for PayPal Website Payments Pro UK. PayPal covers the
Centinel transaction fees for the merchants. Without SagePay style
implementations Shopify could have offloaded 3D Secure for all support
gateways to one integration with Cardinal Centinel. However, SagePay
doesn't provide any facility for passing back 3d secure response data
you acquired elsewhere.

2) Come up with a standard object/format for buyer authentication
results and add support for this object to all non-SagePay style
gateways. Of course, each gateway names the buyer authentication
response params differently.

3) Once we have a format decided we can implement the additional
option in supporting gateways' authorize and purchase methods:

gateway.authorize(amount, cc, :buyer_authentication_result => data)

You'd still have to implement the actual 3d secure process for the
gateway like verify_enrollment and verify_authentication, but if all
non-sage gateways at least had support for the 3D Secure response data
then Cardinal Centinel would at least be an option for those.

I suggest to move forward we create some pages on the wiki documenting
the various styles, flows, and params required for the gateways that
people care about right now. Looks like we'd, based on this
discussion, that we should be able to compile info on the following
gateways right away:

Realex, DataCash, SagePay, Payflow Pro, PayPal Website Payments Pro UK
(Cardinal), Cardinal Centinel

I also have the documentation for PSL Payment Solutions lying around somewhere.

> --
> You received this message because you are subscribed to the Google Groups
> "Active Merchant" group.
> To post to this group, send email to activem...@googlegroups.com.
> To unsubscribe from this group, send email to
> activemerchan...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/activemerchant?hl=en.
>
>

--
Cody Fauser
http://shopify.com - e-commerce done right
http://www.codyfauser.com - blog
http://peepcode.com/products/activemerchant-pdf - ActiveMerchant PeepCode

Morgan Christiansson

unread,
Jan 19, 2011, 7:00:48 AM1/19/11
to activem...@googlegroups.com, Cody Fauser, adr...@shopify.com
Sorry for late reply I've been busy completing projects.

I'm happy to add the details to a wiki page if you set it up.

My current plan is to contribute the gateways upon completion the
integration of the new payment provider.

Regards,
Morgan

Tekin Suleyman

unread,
Jan 19, 2011, 7:05:55 AM1/19/11
to activem...@googlegroups.com, adr...@shopify.com

All looks good to me.

It sounds like you've got it under control but do let me know if you need any help with the SagePay gateway.


Tekin Suleyman

Ed W

unread,
Jan 20, 2011, 9:24:02 AM1/20/11
to activem...@googlegroups.com
Hi Cody

Do please just make sure you looked all the way through my design
suggestion? I'm basically suggesting that we should be able to
consolidate much more than just the "Buyer Authentication" piece if we
get this change right?

Seems to me that if we assume there is just some generic "redirect to
get some more" step introduced then we cover everything from Paypal,
through to the Sagepay (and others) outsourced card collection pages? I
think even the various "token" based card storage systems could work
through this pattern also?

Just hoping we can get this change right?

Cheers

Ed W

Reply all
Reply to author
Forward
0 new messages