Closed csdougliss closed 7 years ago
@craigcarnell thank you for your feedback. The GitHub issue tracker is intended for technical issues only. Please refer to the Community Forums or the Magento Stack Exchange site for technical questions. If you think some of your questions are caused by issues, please create separate GitHub report for each issue according to the Issue reporting guidelines: with steps to reproduce, actual result and expected result. Please, also identify which version of Magento you are running.
Hi @craigcarnell. Some answers to your questions:
\Magento\Payment\Gateway\Request\BuilderInterface
(introduced in 2.0 with Payment Gateway) uses to implement requests builders, it's a goal to create request data.
How to use it, you can find in Payment Gateway Sample Module or in existing payment integrations, like Braintree.
You can use an observer to catch needed information from Storefront, save in payment additional information and delete it from additional information after your builder read it.\Magento\Payment\Model\InfoInterface::setAdditionalInformation
and \Magento\Payment\Model\InfoInterface::getAdditionalInformation
to store all addtional details.
Also, you can use extension attributes
to store more complicated data like objects.\Magento\Payment\Model\InfoInterface::setAdditionalInformation
, for more complicated structure it better to use extension attributes.For more information, please, use Community Forums or Magento Stack Exchange
@joni-jones Thank you for answering. I'm making some good progress and I have finished implementing authorization, capture and sale (authorize+capture) (using the sale command workaround).
I am now in the process of adding 3dsecure. I have added a new command called authorize_3d (but I may rename it based on the below).
What this does is run this command instead of authorize if 3d secure is enabled. It will collect the data and send the data to the bank to check enrollment. This is done through API and no need to redirect yet.
If the card is enrolled, I store the result in my response handler and forward them onto a controller with form which passes the customer onto the bank. I intend to do this by using afterPlaceOrder in method JS. But this happens after the order is placed which may be a bad thing as I haven't got to the authorize stage yet.
in my method.js I have added the necessary libs so that I can do the redirect:
'Magento_Payment/js/view/payment/cc-form',
'jquery',
'Magento_Payment/js/model/credit-card-validation/validator',
'Magento_Checkout/js/view/payment/default'
But when I add payment/default it always throws a javascript error. But I need to add payment/default to find window.checkoutConfig.somepayment.somevalue
Upon returning from the bank I will send them to a controller which checks the response and then forwards to checkout success.
The issue with the whole process is for me that once the authorize_3d command has finished I am now outside the "command" way of doing things. The following requests to 1) check their password 2) authorize/capture the payment is now done in the controller which I don't like.
Does it make sense or if possible to run additional commands to get back into that logic way of doing things?
I can see that I need to do 3 requests:
enroll_3d - checks if they are enrolled (API) password_3d - check they entered the correct password (redirect to external host) authorize_3d - authorizes the payment and if so, captures the payment. (API)
Should these be represented as commands? or am I going about this the wrong way..
If they are run as command I get the benefit of using the builder response and validator handlers set in di.
You can use commandManagerPool
for using commands anywhere in your code:
<virtualType name="CustomCommandManager" type="Magento\Payment\Gateway\Command\CommandManager">
<arguments>
<argument name="commandPool" xsi:type="object">CustomCommandPool</argument>
</arguments>
</virtualType>
<type name="Magento\Payment\Gateway\Command\CommandManagerPool">
<arguments>
<argument name="executors" xsi:type="array">
<item name="custom" xsi:type="string">CustomCommandManager</item>
</argument>
</arguments>
</type>
@joni-jones Thank you for your help so far.
In my controller I have:
$commandExecutor = $this->commandManagerPool->get(
$this->provider->getCode()
);
/** @var ResultInterface $passwordResult */
$passwordResult = $commandExecutor->executeByCode(
'password_3d',
$order->getPayment(),
[
'amount' => $order->getGrandTotal()
]
);
/** @var ResultInterface $authorizeResult */
$authorizeResult = $commandExecutor->executeByCode(
'authorize_3d',
$order->getPayment(),
[
'amount' => $order->getGrandTotal()
]
);
Question 1
Even tho the password result code runs fine, the result is always null. How am I supposed to check for a successful response? The validator returns an instance of ResultInterface and it definitely returns success.
I need to check the result was succesful before moving on to the next command and finally before redirecting the user to the success page.
Question 2 One more question - right now I am doing this afterPlaceOrder by re-directing the user to the 3dsecure page
Is there any way of running my code before placeOrder and then continuing the flow? I am not sure this is required, but it would be interesting to know.
Question 3
Nothing is written to sales_payment_transaction after 3dsecure was successful. I am calling the same txn id handler that I used before. But no record is ever created.
If your commands extend \Magento\Payment\Gateway\Command\GatewayCommand
via virtual type, your commands will not return anything (see Gateway Command) and in case, if response failed, you will get \Magento\Payment\Gateway\Command\CommandException
.
About placeOrder
method, you can override it in your custom payment UI component and process anything what you need before order processing.
@joni-jones regarding placeOrder method, if I place code in before placeOrder and redirect the user to the 3dauth page, how do I then return them to continue to run the placeOrder method, as it is javascript?
Also what is the OrderCommand?
Here is my current issue with the state of play:
Payment Method calls Authorize. This is intercepted and I run the commands below instead. I call Enroll 3D, redirect the user to the controller. User returns to the controller. I call Password 3D I call Authorize 3D
In my controller I now have an fully auth'd 3d secure transaction. But I must manually call:
$payment->authorize(
false,
$order->getGrandTotal()
);
This is so a record is created in sales_payment_transaction. Is their another way to do this?
If I set my payment method to Capture, I do the same above except below which I need to once again to create a record in sales_payment_transaction
$payment->capture($invoice);
The issue with this is first I must find the invoice (the default capture creates an invoice). If I don't I get two invoices. The invoice always says Pending however despite being paid.
@joni-jones or alternatively, still run placeOrder but run code before authorize() and capture() depending on the method
Hi @craigcarnell
Please refer to the Community Forums or the Magento Stack Exchange site for such kind of technical questions. Closing this issue, if you experience a bug please create separate GitHub report according to Issue reporting guidelines: with steps to reproduce, actual result and expected result.
1st. Question:
I am developing a custom payment method and I have a few questions. Using the new builder interface method introduced in 2.1, it seems natural to store the cc_number in the data assign observer, use it in the builder interface and then pass this on to the client.
But due to PCI compliance - I don't wish to store the cc number at all. How can access / store this temporarily without doing so using the new builder interface?
2nd. Question:
Do I need my own tables any more to store transaction information. I've since discovered sales_payment_transaction which I can use the additional_data to store a hash used for refunds. Is this the preferred method? or is it advisable to create an additional table to store this information in?
3rd. Question:
I need to implement 3d secure. This is normally done through a redirect to the bank secure page. Any ideas how I would implement this in m2?
4th. Question
Am I supposed to store response from gateway additional information in setTransactionAdditionalInfo (sales_payment_transaction) or setAdditionalInfo (sales_order_payment)?
5th. Question
Some payment gateways implement authorize, capture and sale. I don't see any references to sale in the code base. How is this interpreted?
Relating to the 1st question:
Preconditions
Development of custom payment method
Steps to reproduce
Expected result
Actual result