-
Notifications
You must be signed in to change notification settings - Fork 92
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
New API available - Accept.js #41
Comments
As an aside, AIM is now called "Payment Transactions". AIM looks to be a name being slowly phased out. I'm wondering if the old AIM should have been left untouched in this gateway driver, and a separate new gateway created for the XML upgrade. JSON is available in beta as an alternative to XML - would have been nice to have had the JSON first, as it is much easier to handle in PHP. All done now, I guess. |
+1 to adding it as a new gateway driver and not replacing the previous AIM gateway with any new features. |
Some details here: http://developer.authorize.net/api/reference/features/acceptjs.html If I understand it correctly, the AcceptJS interface sits in the web client only and just tokenises card details using AJAX. Those tokens can then be used in place of card numbers in the normal AIM gateway, which may need some small changes to accept a cut-down card detail (just a token, instead of all the card number/dates/CVV details). I've done something similar for PAYONE - there is a back end server-to-server direct payments gateway (called "Server") that can take either full card details (with PCI compliance needed) or a card token. The card token is generated on the web client with the help of a separate gateway (called "Client") that helps to generate the tokenization form. |
There are a lot of gateways that are moving towards having JS interfaces that sit on the client side and do the card tokenisation there. It's a really bad idea for a whole bunch of reasons but it does make some sense from a PCI compliance viewpoint (although base PCI compliance for card processing without local storage is not overly complicated and something that every eCommerce store should be doing IMHO). Anyway, I won't debate the politics of it. I agree with @lukeholder -- +1 to making anything that uses AcceptJS a separate gateway and not replacing the existing working code. |
Agreed |
Assuming someone has set up their frontend forms and js to generate the "opaqueData", does anyone know where exactly to pass this into the gateways? I'm finding the Authorize.net docs rather vague, and so far I've only found this code in the example app, but I haven't found the related code in the omnipay driver... from what I've read, it sounds like it might tie in with the cardReference on the AIM gateway requests, but that does not seem to be translated into similar XML anywhere that I can find. There's been talk about a new driver specific for accept.js in this issue, but it looks like that hasn't happened. Does anyone have any pointers on where to go from here? It is supposed to be possible but just not documented, or is support for it unavailable? |
Hi @Mark-H we'll get some example code together and get you working. I use the DPM API mostly, which POSTs direct to the gateway, and has a "nofify" redirect to feed the result back to your site. Is it SIM or AIM you are using, or DPM? The first step is probably to raise a new issue specifically on getting a working example into the documentation. We can follow it up there. If it is Accept.JS you need, then that would be a bit more involved if we need to write a new gateway driver for it, but I guess it's on the wishlist, so maybe worth it if you don't have and extreme deadline. When I first created this issue, Accept.JS was in beta and had little documentation. I haven't checked it since, so hopefully it is more stable now. |
Hi @judgej thanks for the reply :) This is for a new ecommerce addon for a CMS. There's no pressing deadline, but I was hoping to integrate Auth.net into it within the next few weeks as it's a popular request. I've used SIM in the past, and I'm trying to avoid AIM as I don't want to force PCI compliance on users. DPM is a bit tricky to implement, as the app doesn't create a transaction record until a payment method is selected and posted back to the server, so I can't track the transaction status the same way other gateways are handled. Accept.js seems like the most user-friendly offering from Auth.net at the moment (no off-site payment form, no raw credit card info on server) that fits the structure, so I've set my sights on that ;) The Accept.js documentation is probably a lot better than it was back in June, but still somewhat basic, especially the final part which seems to require prior knowledge of Auth.net's APIs that I'm missing. I'd be happy to contribute where I can, just a little lost in the auth.net woods. I'll see if I can figure out how it should work, and how to build an omnipay gateway in the next few days, but if that doesn't work out I'll gladly offer a bounty for you Jason or someone else to build support for Accept.js. |
I'm hoping that once we work out the front end, you can then just use AIM for the back end, but using the tokenised card rather than the original card details. I'm trying to get an Accept.JS working to try it out, but the examples are not quite there yet (e.g. the submit button does not wait for the response to the card tokenising before submitting the form to the server, so there are some things to be worked out there). It seems that the merchant site needs to create its own JS functions for submitting the card details and then putting the result back into the form to be submitted. Other gateways tend to include that type of functionality, with some options to change IDs of form items etc. This is lower level, but still workable. When I can get that working, we can see if the OmnaPay AIM gateway driver needs any tweaks to be able to accept a tokenised card. |
Okay so I've managed to get the client-side done (I can try to clean it up a bit by getting rid of app-specific code, and submit it for some documentation) and also managed to get the transaction to go through with the following tweaks to protected function addPayment(\SimpleXMLElement $data)
{
if ($this->getDataDescriptor() && $this->getDataValue()) {
$data->transactionRequest->payment->opaqueData->dataDescriptor = $this->getDataDescriptor();
$data->transactionRequest->payment->opaqueData->dataValue = $this->getDataValue();
}
else {
$this->validate('card');
/** @var CreditCard $card */
$card = $this->getCard();
$card->validate();
$data->transactionRequest->payment->creditCard->cardNumber = $card->getNumber();
$data->transactionRequest->payment->creditCard->expirationDate = $card->getExpiryDate('my');
$data->transactionRequest->payment->creditCard->cardCode = $card->getCvv();
}
} and adding these methods (I added them to the AIMAuthorizeRequest, but could also go on AIMAbstractRequest): public function getDataDescriptor()
{
return $this->getParameter('dataDescriptor') ? $this->getParameter('dataDescriptor') : $this->httpRequest->request->get('dataDescriptor');
}
public function getDataValue()
{
return $this->getParameter('dataValue') ? $this->getParameter('dataValue') : $this->httpRequest->request->get('dataValue');
} This allows implementations to pass the dataDescriptor and dataValue in the |
Looks great :-) This is where I wish we had different payment types - card, tokenisedCard, PayPal, blank account, ApplePay, saved card etc. that could handle all these things invisibly. Something for a future OmnPay... This Another approach could be to support set/get |
It sure would be nice if all things were standardised, but I personally think sticking to the names provided by the gateway is best until that day comes.
Those are the gateways I've worked with recently. In the case of Accept.js it's kinda vague what the names should be, so I went with the "suggestion" in the last example:
except they're written to a hidden input instead of logged in the console :) The suggested implementation in my previous post does need the setters (ugh, and now I realise that's why I needed to get it from the request, because it lacked setters), but I'd go with |
Here's a simplified version of my javascript, run it after the right js file is loaded and on dom ready. Note: I haven't tested it in this form, I just edited out the bits and pieces specific to my app. var form = document.getElementById('my-payment-form'), // Change ID to fit your form
btns = form.getElementsByTagName('button'); // Maybe change to class based selector if you don't use semantic <button>s
form.addEventListener('submit', function(e) {
e.preventDefault();
// Disable the submit button to prevent repeated clicks
for (var j = 0; j < btns.length; j++) {
btns[j].setAttribute('disabled', true);
}
var secureData = {}, authData = {}, cardData = {};
cardData.cardNumber = document.getElementById('cc-number').value; // Change ID to fit your form
cardData.month = document.getElementById('cc-exp-month').value; // Change ID to fit your form
cardData.year = document.getElementById('cc-exp-year').value; // Change ID to fit your form
secureData.cardData = cardData;
authData.clientKey = 'YOUR CLIENT KEY HERE';
authData.apiLoginID = 'YOUR API LOGIN ID HERE';
secureData.authData = authData;
Accept.dispatchData(secureData, 'responseHandler');
return false;
});
function responseHandler(response) {
if (response.messages.resultCode === 'Error') {
var msgs = [];
for (var i = 0; i < response.messages.message.length; i++) {
msgs.push(response.messages.message[i].code + ': ' + response.messages.message[i].text);
}
msgs = msgs.join('<br>');
var errorContainer = form.querySelector('.errors');
if (errorContainer.textContent !== undefined) {
errorContainer.textContent = msgs;
}
else {
errorContainer.innerText = msgs;
}
return;
}
// Add the hitten inputs with the dataDescriptor and dataValue
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'dataDescriptor');
input.setAttribute('value', response.opaqueData.dataDescriptor);
form.appendChild(input);
var input2 = document.createElement('input');
input2.setAttribute('type', 'hidden');
input2.setAttribute('name', 'dataValue');
input2.setAttribute('value', response.opaqueData.dataValue);
form.appendChild(input2);
// Submit the form
form.submit();
}; |
Okay, agreed There is a mention of |
I've been trying similar front end code to yours, but always get error:
The docs say that means:
I've tried adding the CVV ( |
Hmm no I didn't get that error, but only now notice that the cvv isn't being added in my request code. Will try it out tomorrow. |
Silly me - I was using my account login ID instead of the API login ID. Works fine now after swapping that over. The error message was a little misleading. Just realised also the dataDescriptor ( |
Something has always bothered me about these submit handlers. Here, the submit is caught, the card is tokenised, and the handler getting the token response puts the result into the form, then submits the form. That is great, and works, so long as you do not have any other form validation on the form. If you do, and it's JavaScript powered, then it all gets skipped since the I'm wondering if the approach is to catch the submit, then if the card has already been tokenised, just return Edit 2: been playing with this, an come up with this solution, which seems to work as I wanted. Take a look and see if it is any use. Try submitting with an error in the email field, then correct it and submit again. Going to see if I can apply this to Sage Pay now, because their JS approach has been driving me mad. They use the On top of this, if the form does submit with the tokenised card, then if the form fails any server-side validation, it would be nice to be able to get the form back for correction with the token intact and the credit card fields hidden so they don't need to be entered again. So many shops get this wrong - I've lost count of how uncomfortable it is entering my CC details multiple times because, say, the server did not like my postcode without a space in it. I've entered it once, godamnit, stop asking me to enter it again! :-) Sorry, ranting. |
Just a thought: the tokenised card consists of two strings, e.g.: array(3) {
["dataDescriptor"]=>
string(27) "COMMON.ACCEPT.INAPP.PAYMENT"
["dataValue"]=>
string(22) "9487554895312816104603"
} As well as accepting them as two separate values (no argument there) I wonder if the driver should also be able to accept them as a single string? For example |
@Mark-H If you would like to submit a PR for the set/get methods, preferably with a test, that would be very useful. If not, I'll do one, since it's a small change and opens up a new gateway API nicely. The front end bit we can work on as a section on the README. |
Hey guys, I'm currently facing the situation, therefore I created PR #77 I'm still wondering if we should pass opaque data via setters
or via the request params:
As far as I know, Omnipay Stripe does support a |
The card details (which is what the "opaque data" is) belongs in the request object rather then the gateway object. The gateway configuration data is for invariant settings - switching modes, authentication details, system-wide callback/notification URLs etc. So the first option is definitely the way to do it. |
Sorry for not responding about doing a PR. Was trying to find the time/energy to spin up a fork and figure out how to add tests to omnipay but it's been a rough week productivity wise. |
Ah, yes, sorry you are right. I misread that. I thought one of those examples was passing the data into the gateway object, but looking again, they are both creating the request object. What I said was technically right, but totally out of context here - with the setters in place, both those approaches will work (though the second one needs the "opaque" prefix to map onto the setters, i.e. $request = $gateway->purchase(
[
'notifyUrl' => 'https://www.perdu.com',
'amount' => $amount,
'opaqueDataDescriptor' => $data_descriptor,
'opaqueDataValue' => $data_value,
]
); |
Thanks all - I'm just adding a few notes to the README about this then I'll merge. It's all hard work for everyone trying to fit all this sharing into a day job and life in general, and everyone understands that :-) |
A PR has been merged which allows the AIM gateway to accept tokenized card details in place of the card details in the The method of giving this driver the card details (TWO values and not just one) is specific to this gateway. We can wrap those up in a method shared with other gateways next, but this gets people moving forward in the meantime. One thought is that the The resulting card reference will be massive long though. I suspect it contains the CC details encrypted rather than just an index for a what is cached on the gateway, but that's just a wild guess. So, thoughts on a wrapper function to make it fall in line with other gateways? |
Sorry to jump in and hijack this thread, but I'm Aaron (Developer Evangelist from Authorize.Net) and I wanted to clear up something in this comment from Jun 21:
AIM is not now being called "Payment Transactions" nor is it the same as anything in our current API. That's our fault, because in the upgrade guide you link to, there used to be some wording along the lines of "AIM is now called Payment Transactions". That's never been true, and I think the wording was due to some internal miscommunication and misunderstanding. It's more correct to say that AIM is and always will be a name for an older API of ours that was just for straight payment type of transactions based on doing an HTTP post with a bunch of name value pairs. We then had other similar APIs (CIM, ARB, DPM, SIM) to do things like hosted payment forms, card on file profiles, subscriptions, etc. Instead of maintaining a separate API for each type of interaction, we've supplanted all of these other APIs with one current API that serves all of those functions, and is hierarchical and extensible for future use. This current API can be used by sending requests as XML or JSON, but the parameter names and the hierarchy are the same in each. These older APIs like AIM are in some cases officially deprecated or EOL'ed, but in all cases will not be receiving any feature improvements. That's apparent with Accept.js, which returns a token that can only be used in a payment transaction request to our current API. There's no way to use this token with AIM. As to how this relates to this project, if we had been clear about this strategy from the start, perhaps you would have put the existing AIM implementation into maintenance mode and done the work for current XML/JSON requests in a separate project. Seems like you went the other way, so I'm really sorry about that. Please accept my deepest apologies, and please allow me to make it up to you by offering any possible assistance. Anything you need me for, let me know. |
This doesn't even get into the window of time a few years ago where we were trying to brand the new XML API as "AIM XML" and the old one as "AIM NVP". Don't get me started on that. |
So in other words, to be consistent we should not maintain AIMGateway but develop a newer Omnipay gateway AuthorizeNetGateway (let's call it so). AuthorizeNetGateway would contain the AIM methods + Opaque data handling. Assuming I'm right, technically, what we have to do is:
|
Well, maybe. It really depends on what your strategy is and how much backward compatibility you want maintain, things like that. Also, depends on how much XML you're already using in the AIM gateway vs the form posts with the name value pairs. I haven't been through the code yet to see what's XML and what's just form posts to the old endpoint. Also, I haven't seen whether this driver attempts to support other old APIs other than the payment transactions in the AIM API (like SIM or CIM or ARB). If this gateway is only supporting the AIM transactions, and the actual transactions requests are being converted to XML or are already XML, there's no reason to fork the project. The XML format for the AIM API is what was expanded into the current XML/JSON API. So, any "AIM" transactions that are using the XML format of AIM (what we used to call "AIM XML") are already structured correctly for the current API, and already going to the right endpoint. So, if you've already converted to XML, or were planning to anyway, then you don't really need to change course or fork the project. You just probably would want to drop "AIM" from the name since you're now including things like the opaque data from the current API. In that scenario, there's probably little value in keeping an old "AIM-only" version of the project since there's nothing that AIM did by itself that the new API can't do. That's my general thinking, but I could have more specific recommendations depending on what you've already done or are planning to do. |
Thanks @adavidw for clearing that up. I only read yesterday that the new Payment Transactions API is what used to be called "AIM". I think that may have been updated now, as the migration page now says the Payment Transactions API includes the functions that AIM supplied. That makes more sense. So on the opaque data (using Accept.JS), if I understand correctly you are saying that the card nonce collected will not work with the AIM API? I'm desperately looking for the documentation that led me down believing it worked this way, but it seems to have vanished - or I am going mad. Is this something we can fix here by simply using a different endpoint, assuming the same XML structure has been carried over from AIM to the new API? Last question: how stable is the JSON API? I ask because some of the XML structures do not translate directly into JSON structures (repeating elements inside a parent element likely need to be implemented as arrays) and I'm not sure the documentation has taken this on board yet. Thanks again. I've been thinking about starting a separate gateway driver anyway, so this kind of reinforces a need for that. Edit: just reread above - the AIM API here is now XML based. Does that mean it is now fully compatible with the new API, without any changes? |
Okay, just to quell my panic, I've completed an end-to-end test script. Have a play with it here: https://acadweb.co.uk/authorizenet/authorize-ajs.php This uses the latest OmniPay Authorize.Net AIM driver (with XML) and Accept.JS I've just exposed the credit card form, and when you submit it, it will pay £10 to a test API, and the results displayed. And...it works. Have a play, use test credit cards, valid cards, invalid dates, mess with form validation, fiddle with the nonces. Knock yourself out :-) |
Hi @judgej, Re: your edit - If what you're sending is all XML now, everything is probably just fine. You're probably fully compatible with what we are currently documenting as our Authorize.Net API. The sequence of events goes roughly like this:
So, if you're doing XML requests now, everything's probably fine. I say "probably", because there's a very small handful of API calls that have either changed or been superseded since we expanded the API. I don't know off the top of my head if any of those were the ones previously documented as AIM XML or if they were only in other parts of the system. However, if everything you're doing matches everything in our API reference, you have nothing to worry about. That API reference is the canonical truth of what's currently supported in our Authorize.Net API. Now that you've started sending the opaque data for Accept.js with the transactions, you're beyond anything that's previously been documented in the AIM API, so speaking from a pure semantic perspective, you are no longer using the AIM API. You're formatting the request the same way and sending to the same endpoint, but an API is more than the endpoint, it's the whole collection of documented behaviors, and there's nothing documented as the AIM API that includes the Accept.js nonce. It's far easier for us to say "sending the opaque data from an Accept.js call is not possible using AIM" instead of saying "sending the opaque data from an Accept.js call is not possible using the AIM name/value pair stuff, but if you take an AIM XML request and replace the card data with the opaque data that will work, despite not saying anything about that in any documentation labelled AIM". Just a lot easier to say "Don't use AIM for this. Here's the format for the request that you need to use" even though it sometimes results in head scratching and wondering, "wait, I thought this was AIM". I probably sound rather loony going on like this, but when I see a conversation like the above where everyone's confused about our API and where it's going, it kind of hurts me. It means we did a poor job of messaging and communicating our strategy. So, I'm trying hard to make sure everyone understands things at least on the same level that we do. This is especially important in the future as we start to communicate about things being deprecated or going away. If at some point in the future we say "AIM is deprecated" or "AIM is going away" or anything like that, it's easier for your users if they know that the gateway driver is not connected to anything that we would be referring to there. Of course it's also easier if we are more specific in our communications and make clean breaks where we need to instead of applying the name of one thing to an rather unrelated thing. Re: JSON - The JSON version of the API is as stable as the XML one. While we might make improvements to the way things are structured or parsed, we're committed to no breaking changes. So, if there's a structure that would work more logically as an array, and we can get our parser to recognize it as an array, we might change the way we document that structure, but only if we could still parse requests in the previous format correctly. So, if everything's working fine (and it appears like it is), the only change you'd want to make on your end is to just drop AIM from the name. |
Re: our upgrade guide. You're right that the wording was updated recently, basically as soon as I saw it and said "Uh oh. That ain't right". I don't know when the wording actually got changed on the production web site, though. Between the time we create a piece of text and the time it goes live, there's a long gantlet of various legal review, corporate review, pre-processing, processing, post-processing, build, QA, and scheduling release windows that's all done by other portions of the Visa behemoth. There's a future wording change in there that's even more specific, talking about the exact difference between AIM NVP and AIM XML and hopefully being even more clear, but that's still winding its way through the process. |
So there is an "AIM [NVP]" API, and there is an "AIM XML" API, and they are two different APIs, despite what the name may suggest? This probably means that in this OmniPay driver, rather than converting the AIM to use XML rather than NVP, we should have just created "AIM XML" alongside it, and people could use one or the other. It's becoming a little clearer now. It's a shame it wasn't worded like that a long time ago. |
Are the AIM NVP and AIM XML different APIs? In my view yes, because they have completely different formats and the parameter names are completely different. They both do the same things and effect the same transaction processes. So, we could get into a good discussion about when an API is different, but in my view, those are two completely different animals. Related question: Is a superset like our current API a different API than the AIM XML API or just a new version? |
Note: everything I said in all these posts before is AIM specific. There are similar stories for other APIs that we've had (SIM, DPM, CIM), etc. Since you're implementing those as well, there are other considerations for which direction you take the project. Those APIs are all on their way out, but they're at different levels. Some of them have a superior replacement already, some don't. Specifically addressing CIM, that's in a similar state as AIM. We have this thing called "CIM", we have an XML format for it going to the same endpoint as the other transactions, but along the way we move to packaging it as part of the consolidated API. One specific issue is that there's at least one call in the old CIM XML API that has a different name and format in the new API. createCustomerProfileTransactionRequest is superseded by new functionality available in the createTransactionRequest call. I think there might be other areas in CIM that are similar. Here's a relevant thing I typed up about createCustomerProfileTransactionRequest. |
I think, as has been suggested earlier, we create a brand new OmniPay driver for the latest JSON API to cover everything without any of the legacy stuff getting in the way (and vice-versa). People can carry on using the older APIs, or switch to the new APIs when ready, and both will be maintained as necessary. That's what I think we should do. |
Seems reasonable. I didn't want to suggest as much if it means doubling the work for you. But, as we add new features, they'll only be available in the current API, so the new driver is the only place you'd have to put in support. The old driver would only need maintenance in the form of bug fixes or security fixes. Then the new driver is the thing people use if they want to use the new features. Now, I don't want to complicate things further, but hypothetically speaking, what if we were to introduce a REST API somewhere down the road, like perhaps later this year? Not as a replacement for the current API, but just something additional where new features would get added to both and they both co-exist. Would that change your plans any? Like, would you wait until that was available and then build the new driver around that? Or, would you make a new driver now, then change the new one to the REST API when available? Or, make a third driver when REST is available? |
Hehe. Good question. I've been thinking about how the OmniPay drivers are generally structured for a while. They tend to operate on arrays of data that get passed around. They specifically do not have dependencies on SDKs or external libraries. I'm wondering whether that can be changed. What I suspect (?) will be common between the current API and the REST API will be the objects and messages. I'm guessing the same objects - data structures - can be modelled the same way for both the REST and the non-REST APIs. So I would see these APIs as a bunch of shared objects with different ways to throw them around. It makes sense IMO to put those data structures into a [PHP] package of their own, with the OmniPay driver just being a wrapper to communicate with the gateway using these objects. SDKs tend to try to do far too much in one big lump, but if the data objects could be pulled out on their own, with no reference to how they are used, then that could make a great base for both a REST and a non-REST driver, with a minimum of rewriting. I guess it would be a bunch of value objects. Not sure if that makes sense? |
From this comment:
I think the AIM gateway already uses the XML approach? The AIMAbstractRequest is definitely generating XML. So no conversion is necessary for that to use the new endpoints. Hence the opaqueData working with the AIM gateway. It also sounds to me like the JSON is the same API as the XML one, just with a different format. In which case my suggestion would be to just continue using XML. What would users gain from the different format? @felixmaier1989's suggestion to copy the AIMGateway driver and its tests to a new AuthorizeNetGateway sounds like it makes the most sense, and also shouldn't be as much work as completely redoing everything. |
@Mark-H yes, it uses XML now, but it used the NVP version before a PR converting it to XML late last year. The XML there now is fine and can stay. If starting again with a new driver, I think going for JSON would be easier to handle. I think there are, at the moment, too many XML objects being thrown around the package. It should probably deal with value objects internally, with conversion to/from XML or JSON at the HTTP interface to the gateway. |
I agree with @Mark-H regarding XML over JSON. There does not seem any benefit using JSOn at this stage. |
I'm constructing a set of value objects for the new API to play with as a kind of side-project, to what value they are, and whether I'm barking up the wrong tree. They will be able to produce the required JSON by simply using |
I wan to capture multiple payments in a single form submit. Like capture initial payment now and create Recurring subscription for later date. But opaque token gets expired after first capture. How can I achieve that? Thanks in advance. |
Hey @judgej, I just landed here and read status on the library. If I understood this issue correctly, Omnipay/authorizenet does not yet implement a Gateway to the now called "Authorize.net API", but AIMGateway can be used as a workaround. I have two projects currently using this library, with custom extensions for customer profiles and recurrent billing. Can I help out implementing the missing gateway? Cheers |
Hi @guiwoda This may be of interest: https://github.com/judgej/authorizenet-objects I've been trying to create a series of value objects for the new API, working from the API documentation. Trying it out as I go along, I've found little quirks and mistakes in the documentation, but it's mostly fine. The idea was to use the value objects to construct the messages to send to the gateway, then write an Omnipay wrapper to do the sending and to accept and parse the result. One aim was to keep JSON and XML out of the value objects and just serialize to JSON right before sending (the README shows how easy it is to do that). Whether this approach has wings or not, I don't yet know - it's just an experiment, and creating the value objects has taken me a lot longer than I expected (involves lots of cross-referencing between the new API docs, the demo API scripts and the older AIM/XML documentation). Maybe it's time to move to the Omnipay wrapper and to finish off the value objects later (it's the customer profile stuff I've been working on lately). Or maybe I've got it all wrong and this isn't the way forward. What do you think? One thing I will say, is that the Authorize.Net API is very rich - it does an awful lot with customers, customer profiles, payments, payment profiles, scheduled payments, etc. Omnipay is only interested in a small portion of that, but by building this up in layers, each layer can support what it wants to support today, hopefuly with the logic and knowledge in the right domains so they can be easily expanded tomorow, and parts reused in other projects. |
@guiwoda Here, I've knocked together the start of a driver for this API, for Omnipay 3.x alpha (just dev-master at the moment). It will send a create authorise transaction, with lots of missing data, and get the decoded data containing the inevitable errors as a result. Have a play and see what you think. (I've probablt messed up the |
Well, I've never liked but eventually understood why Omnipay decided to go for key/value pairs instead of DTOs. But I think each gateway implementation could benefit from a clearer object model. From a project dev perspective, key/value pairs are too vague on requirements and valid / invalid messaging, and don't allow portability between gateways.
Great! I'll do that. |
This new API makes use of JavaScript on the front end to build forms and (presumably) to avoid the need to send credit card numbers to your own server. It is an extension to the DPM API.
An example application is available here:
https://github.com/AuthorizeNet/accept-sample-app
I'm not sure what documentation is available apart from that. Authorize.Net are keen to help us incorporate this API into the gateway, so I'm opening this issue to log any discussions on what that may involve or any ideas or issues that anyone may have.
OmniPay has traditionally not got involved with the front end part of the UI, but most gateways are moving towards a very front-end centric approach (e.g. with "drop-in" forms generated through JavaScript, and card tokenisation APIs that can be used by the front end to avoid card numbers going anywhere near your server). How this fits into OmniPay 2.x or whether it should be something to expand OmniPay 3.0 with, is up for question. I personally don't have an answer for that at this time.
The text was updated successfully, but these errors were encountered: