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

TransactionReference Not Set #18

Closed
jesseterry opened this issue Feb 19, 2015 · 22 comments
Closed

TransactionReference Not Set #18

jesseterry opened this issue Feb 19, 2015 · 22 comments

Comments

@jesseterry
Copy link

I have PayPal and Stripe successfully working through the Omnipay library but am having trouble with Mollie. The process successfully redirects the user to the Mollie site, lets them do their thing there, but when the user is returned back to the local site, there is no transactionReference set. There is an id set in the purchase response right before the user is redirected offsite to pay, but that value doesn't seem to be retained when they're redirected back to the local site after paying, so the library throws an exception in the getData method of CompletePurchaseRequest. I'm posting the question here because I've been struggling with this for a bit now, and I have a feeling it's something simple I'm missing.

Any assistance is appreciated more than you'll know...

@Jensdiep Jensdiep mentioned this issue Feb 25, 2015
@RickWong
Copy link

Hi Jesse, yes indeed the Mollie API does not redirect back with the payment id intentionally. However you can and should include the order reference into the redirectUrl so that you can look up the order and its status there. The redirectUrl should not perform any Mollie API requests, but only read from your database.

See https://www.mollie.com/en/docs/summary#how-does-the-mollie-api-work

To actually fetch the payment's status with the Mollie API to update the order, use the webhookUrl.

As for the omnipay implementation, perhaps the maintainers of this package can help you out.

@barryvdh
Copy link
Member

The webhookUrl is implemented as a notifyUrl in Omnipay. I think the transactionReference should be posted to the notifyUrl ($_POST['id']) but I'm not really sure if that's the case.

Edit: See https://www.mollie.com/en/docs/webhook

The webhook will be called with a single POST-parameter named id which for instance will contain the value tr_d0b0E3EA3v. You should use that id to actively fetch the payment to find out about it's status.

@magnolia61
Copy link

Probably this is helpfull for issue #15 as well

@jesseterry
Copy link
Author

Right - but what I'm trying to say is that this implementation is designed, for whatever reason, to expect an id / transactionReference back from Mollie, which obviously does not occur. It's an error in this library which I can't figure out how to fix. If anybody is successfully using this library, I'm not sure how they're doing it.

I understand what Mollie is doing - what I don't understand is what this library is doing.

@jesseterry
Copy link
Author

Ok, actually I think I just got it through my head. I'll come back to this issue and close in just a bit - have to leave atm but will test and make sure. Was my bad, of course.

@barryvdh
Copy link
Member

Don't forget to provide some feedback of you find it, or update some docs to clarify ;)

@jesseterry
Copy link
Author

This is not a problem with this library after all - it was a problem with my understanding (lack of). The notifyUrl doesn't seem to be documented anywhere, as far as I can see, and this is what I was missing. So far I have PayPal and Stripe both implemented using Omnipay - PayPal which returns the payment status along with the user's redirect (not a separate notification), and Stripe which returns it right away. I suppose I was expecting this library to work similarly to PayPal since I didn't see notifyUrl documented anywhere. Now that I know I need to pass the notifyUrl along with the request, and have a method to capture that POST request when it comes across, I'm good to go. Thanks all for your help.

@greydnls
Copy link
Contributor

Thanks, @jesseterry I'm going to work on getting that better documented shortly. I appreciate the feedback

@eileenmcnaughton
Copy link
Contributor

Hmm - this is closed but I'm not sure I understand it as closed.

My understanding is that the webhook is a similar concept to the IPN - with the difference simply being that an extra action is required by the gateway to retrieve data from that sent to the webhook

The code in my application that is called when the IPN /webhook is hit looks something like this.
$this->gateway = Omnipay::create('gateWayName');
$this->setProcessorFields(); // credentials etc.
$params = $_REQUEST;

$response = $this->gateway->completePurchase($params)->send();
if ($response->getTransactionReference()) {
  $this->setTransactionID($response->getTransactionReference());
}
if ($response->isSuccessful()) {
// do success stuff

}

It seems that in the case of Mollie it is necessary to call

$response = $this->gateway->fetchTransactionResponse($params)->send();

instead of

$response = $this->gateway->completePurchase($params)->send();

I looked at whether doing both would add any value - but it's not clear that it would - in which case what value does completePurchase add in this Gateway?

@dirkluijk
Copy link

👍 for clarification on this topic.

I am only using purchase($params) and completePurchase($params) and that does not seem to be enough, as @eileenmcnaughton already mentioned.

Edit: I tried setting the notifyUrl to the same location as the returnUrl, which is a localhost address. It looks like that is not supported.

@Alienpruts
Copy link

Hello,

first and foremost, why was this closed? Issue has not yet been resolved :)

Secondly, I managed to make this happen by including the 2 commits by @eileenmcnaughton (and referenced in PR #20 ) and making these changes myself :

diff --git a/CRM/Core/Payment/OmnipayMultiProcessor.php b/CRM/Core/Payment/OmnipayMultiProcessor.php
index 4a93e65..5caf824 100644
--- a/CRM/Core/Payment/OmnipayMultiProcessor.php
+++ b/CRM/Core/Payment/OmnipayMultiProcessor.php
@@ -152,6 +152,10 @@ class CRM_Core_Payment_OmnipayMultiProcessor extends CRM_Core_Payment_PaymentExt
         return $params;
       }
       elseif ($response->isRedirect()) {
+        // Store transactionReference for future use, only for Mollie response.
+        if ($this->_processorName === 'omnipay_Mollie') {
+          $_SESSION['omnipay_trans_ref'] = $response->getData()['id'];
+        }
         CRM_Core_Session::storeSessionObjects();
         if ($response->isTransparentRedirect() || !empty($this->gateway->transparentRedirect)) {
           $this->storeTransparentRedirectFormData($params['qfKey'], $response->getRedirectData() + array(

and

diff --git a/vendor/omnipay/mollie/src/Message/CompletePurchaseRequest.php b/vendor/omnipay/mollie/src/Message/CompletePurchaseRequest.php
index 5d5679f..cf5b942 100644
--- a/vendor/omnipay/mollie/src/Message/CompletePurchaseRequest.php
+++ b/vendor/omnipay/mollie/src/Message/CompletePurchaseRequest.php
@@ -22,6 +22,14 @@ class CompletePurchaseRequest extends FetchTransactionRequest
             $data['id'] = $this->httpRequest->request->get('id');
         }

+        // Retrieve transactionReference for Mollie gateway.
+        if (!isset($data['id']) && isset($_SESSION['omnipay_trans_ref'])) {
+            // Retrieve transactionreference out of session. We need this to
+            // reference our transaction status with our event. Destroy after.
+            $data['id'] = $_SESSION['omnipay_trans_ref'];
+            unset($_SESSION['omnipay_trans_ref']);
+        }
+
         if (empty($data['id'])) {
             throw new InvalidRequestException("The transactionReference parameter is required");
         }

I am however not sure if this really is the path to take (storing this in a Session I mean). Any thoughts?

Eileen, I am relatively new to github, I searched to create an issue on your fork and proposing the changes there, but ended up here. I hope this does not violate any unwritten rule of Github or something like that :)

@magnolia61
Copy link

We also had to include Eileens PR (#20) to get Mollie working in the Omnipaylibrary. Please merge those commits :-)

@hillelcoren
Copy link

While working on this I noticed it's important to call isCancelled() with the response to fetchTransaction to check if the user canceled. It looks like isSuccessful() in FetchTransactionResponse is returning true when the status is canceled.

@magnolia61
Copy link

@hillelcoren Possibly you should open a new issue for this.. But if you have some code you can submit as a PR that would be very helpful! (BTW. I think we experience the same, but let's discuss in a new issue)

@hillelcoren
Copy link

I've created a pull request with a potential fix

@Alienpruts
Copy link

@magnolia61 : you have a PR ready which fixed this problem, so it does not actually need the TransactionReference. (https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/pull/16/files)

I've tested this by reverting my changes above and incorporating your PR and it works. Thanks a lot :)

Discussion (at the bottom) :
#15

@veelineen
Copy link

We are struggling with mollie. We committed the changes described in:
https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/pull/16/files
Allthough we can't connect the transaction in civicrm with the Mollie payment. All payments are pending and needed to be manually completed.
I think the problem is that there isn't any transaction ID saved with the payment in civicrm. There is a invoice ID, but that one doesn't match with any of the ID's at Mollie.

Can anyone give me some hints on how to debug this?
Thanks.

@judgej
Copy link
Member

judgej commented Feb 21, 2016

For the transactionId, the CiviCRM payment gateways I've dealt with use the CIVI contributionID. Not sure if that helps (or even if that is the right thing to use), but it may give you some clues as to where to look.

@eileenmcnaughton
Copy link
Contributor

Yes, the contributionID should be be passed to Mollie as the transactionId - if that happens it should be retrievable from the IPN that comes back from Mollie. I've never actually had access to a site that receives the IPN so I can't tell what is actually happening

This where it should be set in Mollie

https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/pull/16/files#diff-480e8d4cd2f03701840955c423cb21cdR33

And this is where CiviCRM should be retrieving it
https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/blob/master/CRM/Core/Payment/OmnipayMultiProcessor.php#L788

@magnolia61
Copy link

We've got Mollie working in production with Eilieens civicrm Omnipay extension. For this we had to include #20 on the Mollie side (not yet merged) and https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/pull/16/files on the side of the civicrm extension. Weǘe put up a Contribution Testpage at https://www.onvergetelijk.nl/civicrm/contribute/transact?reset=1&id=2 (Feel free to try, no actual payment is made).

I am not sure were we should go from here as I know Eileen has some thoughts on her side of the PR, but I believe there is no reason why #20 wouldn be merged.

I would be happy to help out with providing any debug info that is needed, as we are very happy with our working Mollie integration!

@eileenmcnaughton
Copy link
Contributor

Note that it's worth commenting on #20 (or the issue #15 ) if you want to endorse it to the devs of that repo

@peter-mw
Copy link

I got it working on my end with the following code

$transactionReference = $_POST['id'];  //coming from webhook

$response = $gateway->completePurchase(
    array(

        'transactionReference'   => $transactionReference,

    )
)->send();

if ($response->isSuccessful()){
     //...
}

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