Zen Cart Logo
Forums / Contribution-Writing Guidelines / Which Method should the module use to launch payment

Which Method should the module use to launch payment

Locked

Views: 7,263

Results 1 to 17 of 17
This thread is locked. New replies are disabled.
25 Jan 2008, 11:49 AM
#1
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France & Luxembourg
Posts:
37
Plugin Contributions:
0

Which Method should the module use to launch payment

Hello Zenners
I have a custom payment module, which i did not program.
The problem is, i feel there should be a change to the module.

-Problem-
The module makes zen-cart send out the order confirmation mail
right after clicking confirm, before sending the customer to a payment server.

-Consequence-
When the payment fails, the customer is sent back to the confirm page,
but the order number increments (because the processing script deletes the order in case of a failure)
and the customer can click confirm again, where again the mail is again sent.
This quickly gets messy, because one customer might make two tries or even doesn't convert,
but we remain with confirmation emails that are not valid anymore. (as well as the customer)
This doesn't seem to happen when i use the paypal IPN, where there's no mail
being sent, at least NOT RIGHT AFTER the customer clicks confirm.

How is the module designed:
The module uses a table to associate "order id" to "transaction id".
The module redirects to a payment server, passing along variables formated in the module's runtime.
During the interaction between server and payment server,
processing happens through external files (not in the module) which
verify the infos,
exchange response (and update order status, delete orders that failed) and
redirect to checkout pages.
success (with session_cart reset, _sess_destroy variables) or
failure )

My actions so far :
--I've read through the wiki subject about payment modules,
http://www.zen-cart.com/wiki/index.php/Developers_-_Payment_Classes
--Compared the module code to these payment modules , COD, CC.
--Took a close look onto the processing scripts / functions.

**My Questions: **

  • Which Method should the module use to launch payment procedure decribed ontop.
  • Is it necessary to remove an order when the payment fails or can the order id be used again ? So that when the user clicks confirm again no new order is created.
  • I cannot find out where the heck the email confirmation is triggered,
    possibly using one of the methods.

I would really appreciate getting help on this one,
it's way over my capabilities.

25 Jan 2008, 2:14 PM
#2
absolute avatar

absolute

Totally Zenned

Join Date:
May 2005
Location:
Bath, Somerset
Posts:
1,054
Plugin Contributions:
2

Re: Which Method should the module use to launch payment

1 - Payment modules make use of 2 main methods. The process_button and before_process. The process_button function is the one which should handle sending the data to your gateway, if using POST data transfer, or the before_process if you are using CURL data transfer. The before_process then checks your data response from the gateway, and acts accordingly. If it detects a failure, then it should redirect to the payment page with a waring. If all is good, then it just carries on to place the order.

2 - as the order is never placed, until the payment is confirmed, you do not have to remove any order data from the database if the order payment fails. This means that to get an order_id for a payment transaction, you need to be a little clever, and grab the highest order_id currently in the order table, and tehn increment it by 1 to get the probable next order id.

3 - The email trigger is in the order.php class, and is triggered automatically after the payment before_process function has run. If your payment class is allowing the routine t get this far, then the order is placed automatically.

Hope this helps,

Absolute

25 Jan 2008, 4:54 PM
#3
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France & Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

All your anwers really helped out to move on into the problem,
and i already improved the module because of gained confidence.
It was also quite helpful to explain that the order is not placed unless the order
is confirmed, you proposed to get the probable next order id.
Many Many thanks for helping out so quickly:clap:

The script is still working, until some point.
Now i could need a little help with Objects/classes
and "invoking" methods. At the moment, other functions are in external files.
I guess i could add some of those functions inside the module.

My actions:

  • I added check for the current zone to show/hide the module.
  • I moved the "checkpayment-launching"-process into the before_process method.
    This already fixed the problem with the email that was sent too early, but now no email comes at all, because i moved it entirely
    (In fact it was all in one piece in the after_process method)
    Also it turned out to make the confirm button to disappear when inserted into
    the "process_button" method, that's why it is now in the before_process.
    Also even tough the payment succeeds, zen cart redirects to the confirm page.
    this might be because the order doesn't exist.

During a payment events happen this order :
The Payment Module
before_process method (*should be *process_button)
1 - generates a reference and attaches order infos.
2 - redirects to payment page sending variables using GET

The external files for processing do this:
verify.php
sends back to payment server values from the transaction table && they must match those sent over redirect's GET.

response.php
gets the response from the payment server
updates TABLE_ORDERS, TABLE_ORDERS_STATUS_HISTORY
adds message to the messageStack
and updates transactions table
in case of a failure, it deletes the order
(can be dropped, since order doesn't exist yet.)

success
updates transactions
destroys session variables
and redirects to checkout success

failure
updates transactions
destroys session variables
and redirects to checkout _confirmation

i can imagine they can be included into the module itself,
but i don't know
-- in which method the different parts belong
and the most unobvious to me
-- how to call the corresponding method from the payment server,
who is supposed to get echoed string with the details (verify) and how to handle his "response". Maybe there a way to include the content of the external files
into the paymentmodule's correct methods and have them triggered by the external files if not possible to have the payment server trigger them.
Also note that calls to the method will be protected by checking the IP of the originating server.

Many thanks in advance.
:blush:

28 Jan 2008, 4:00 PM
#4
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France & Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

I have a small but crucial question.
I can see how i could place / distribute the code inside the "payment class"
but i am stuck with the fact that i don't know
how to call it from an external server,
since it's inside the class, inside a method.
maybe it's much easier than i expect ? Any help welcome

28 Jan 2008, 4:09 PM
#5
absolute avatar

absolute

Totally Zenned

Join Date:
May 2005
Location:
Bath, Somerset
Posts:
1,054
Plugin Contributions:
2

Re: Which Method should the module use to launch payment

If you send ALL responses from your payment gateway to https://www.yourstore.com/index.php?main_page=checkout_process, then the order process will trigger automatically. When the order process resumes, a full cart is created, and then the payment class before_process is fired again.

At this point, you need to include some code to test if this there are any posted response variables available. If there are, you know that this function is called as a response to the order being processed. Now you can test these responses with the appropriate MD5/security checks to ensure that it is definately a post from your gateway, and obviously to test that the transaction was a success. If anything goes wrong with your checks at this stage, you need to add a session message alert, and then forcefully redirect the user to the payment page. This will stop the order process immediately, and no order will be placed.

If your checks are successful, then its just a case of returning true from this function and the order will proceed successfully.

Good luck,

Absolute

29 Jan 2008, 2:19 PM
#6
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France & Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

Anyway, i am progressing good in consolidating the module in one file,
calling the before_process() method is automatic, as you said by going to payment_process.
the switches for talking to the payment gateway already work fine.

Absolute:

2 - as the order is never placed, until the payment is confirmed, you do not have to remove any order data from the database if the order payment fails. This means that to get an order_id for a payment transaction, you need to be a little clever, and grab the highest order_id currently in the order table, and tehn increment it by 1 to get the probable next order id.

Maybe this is basic, but how SHOULD THIS BE DONE?

ALSO I encountered trouble with passing variables from a method to another,
but for $order 'total' i simply redefined it like in the previous method.
Is it possible to pass variables from a method to another ?

29 Jan 2008, 2:35 PM
#7
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France & Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

$lastidlist = 	mysql_query('SELECT orders_id FROM orders ORDER BY orders_id DESC LIMIT 0, 1');
$lastid = mysql_fetch_row($lastidlist);
$nextid = ++$lastid[0];
echo ('<br>$nextid='.$nextid);

i guess it's not perfect but this works for getting the last order_id.
but can i pass variables from a method to another ?
how does it work?

29 Jan 2008, 4:08 PM
#8
absolute avatar

absolute

Totally Zenned

Join Date:
May 2005
Location:
Bath, Somerset
Posts:
1,054
Plugin Contributions:
2

Re: Which Method should the module use to launch payment

Firstly, you should use the built in Zen db class for ALL your db queries. It's there for a reason.

$lastidlist =     $db->Execute('SELECT orders_id FROM orders ORDER BY orders_id DESC LIMIT 0, 1');
$nextid = $lastidlist->fields['orders_id'] + 1;
echo ('<br>$nextid='.$nextid); 

Secondly, why do you want to pass this from one function to another? You should include this just before you create your transaction post for the gateway. Update the database with the transaction details, and send the data to the gateway in the same function. Then on return, you jsut use the transaction id to pull the data back out of the database if you need it.

You should only ever need to get the next possible order_id once, and after that the order either goes through, and creates its own order_id, or it fails in which case you just ignore any further code, and go back to the previosu page with the error message.

Absolute

30 Jan 2008, 11:13 AM
#9
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

tanks for correcting the syntax. In fact i am not used to the zencart core functions, but it seems important to stick to using them.
I have an issue with another core function

the zen_redirect() function makes the process button disappear,
although the "URL" is correctly formatted with all the query params.
(displays correctly with echo)
:frusty:

// Build the data and actions to process
// when the "Submit" button is pressed on the order-confirmation screen.
//PROCESS BUTTON **********************************************************
Some LINES are SKIPPED for UNCLUTTERED OVERVIEW
***********
    function process_button() {
		if($amount) {
			if($transactions_id = $db->Insert_ID()) { // Generates reference
				if(fields){    // Verifies parameters in form
					$redirect_params = array();
				} // endif (Verifies parameters in form)
			} //endif (transactions_id = $db->Insert_ID)
		} // end if amount	 
	// Redirect to payment page
		echo $redirectit = $url.'?'.implode('&', $redirect_params);
		zen_redirect($redirectit);
	 return false;
	// exit();

    } // end function(processbutton);

Also, i am a bit confused by the fact that the echo (zen_redirect) happens,
without having displayed the button nor clicked it.
i tried, but i can't find the :wacko:
my next try ... include application_top if the redirect function is declared within that one.

30 Jan 2008, 12:18 PM
#10
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

same trouble as ZEN_REDIRECT FUNCTION

with

$messageStack->add_session(SUCCESS_ORDER_UPDATED, 'success')

doesn't execute and stops PHP

OK, the order isn't yet created, but it's just about to be.
Maybe Update order makes no sense, but i mentionned this
error because i feel it might be the same isssue as for the redirect core function that doens't work

31 Jan 2008, 11:28 AM
#11
absolute avatar

absolute

Totally Zenned

Join Date:
May 2005
Location:
Bath, Somerset
Posts:
1,054
Plugin Contributions:
2

Re: Which Method should the module use to launch payment

Firstly, why are you echoing out the return url? The process_button function is called to create the process button. The return here should be a bunch of hidden variables, so that when the containing form is submitted, these are submitted with it. If you need to send the CC number, name, and amount to the gateway, you can eitehr do this here, as hidden variables, or send them by CURL In a later function. You should never need to reirect from this function, as it is loaded half-way down a page.

Secondly, with the $messageStack, have you included the line: global $messageStack within the function, as $messageStack is a global variable, and so it's not normally available within functions due to its scope.

Absolute

31 Jan 2008, 1:04 PM
#12
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

Thanks again aboslute for getting back to me.

The echo of the URL is to check if it´s the correct one i am redirecting to.

OK i understand now the purpose of the method,
it´s not intended for redirecting. :oops:

I will move it down to the before_process() to make it happen then.
I guess this will fix redirect to work, since you didn´t say it has dependecies of some other files like "application_top".

I have another problem with the payment process,
and then it might be completely streamlined to zencart.

In fact, when i try on my localhost, payment transaction tracking works,
so does order creation and such.
BUT when called by the payment provider or another machine on my network,
it fails to execute verify & response handling, sending them to a session-time-out page of zencart. I guess this is because the cookies aren´t set or some other session variables are gone.
How could i fix this ?

Today i won´t be able to try out too much as i am afk this afternoon.
Anyway , many thanks for any help.

4 Feb 2008, 10:29 AM
#13
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

Sometimes a weekend can help to get another look at the code.

  • How to pass variables from one method to another.
    Well this was a little bit tricky for someone who is not used to working with methods and forms.
    My final technique was more obvious than i expected. To pass variables from process_button() to before_process(),
    i just used it as zencart was designed.
    Added a hidden form fields into the final confirmation form
    to pass my URL to the next method where then the redirect happens.

But how will i avoid the session expired message when calling
checkout_process.php from another server ?

4 Feb 2008, 11:18 AM
#14
absolute avatar

absolute

Totally Zenned

Join Date:
May 2005
Location:
Bath, Somerset
Posts:
1,054
Plugin Contributions:
2

Re: Which Method should the module use to launch payment

It depends on how you are transferring the data between servers. If you are redirecting your customers to the payment gateway, and then they are returning, then you can include the ZenID in the URL to recreate the session if you need to.

Absolute

4 Feb 2008, 12:07 PM
#15
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

i tried hard,
it still redirects to time_out (session expired error)
i can retrieve the session_id correctly and

i copypaste it into firefox on another machine and call
index.php?main_page=checkout_process?ZenID=somession_id_here

just like the payment server would, with some more variables added.

zen cart redirects to gateway, along with infos & now also zen id
gateway calls checkout_process (POST) to verify
gateway calls checkout_process (POST) to respond
gateway redirects to checkout_process (LINK on their page)
to send customer to success/fail

In either stages, it makes an time-out happen,
making verification impossible because of HTML being outputted instead of variable/value pairs.

:frusty:
what is the security token related to ?

4 Feb 2008, 12:25 PM
#16
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

i just tried calling

checkout_process
with zenid= zen id of the session
and securitytoken of the session

same result , time out

it seems it cannot retrieve the session.

maybe the way it's called is not correct ?
at the moment the variables are passed by GET calling the URL,
but the gateway will send thru POST ?

4 Feb 2008, 5:35 PM
#17
mypashop avatar

mypashop

New Zenner

Join Date:
Oct 2007
Location:
France &amp; Luxembourg
Posts:
37
Plugin Contributions:
0

Re: Which Method should the module use to launch payment

Hi again...

Getting it done, it seems impossible.

While there's a solution to the session time out by
making the verify / response actions happen in external files
(no html will be outputted, since no timeout occurs),

there's still a problem to trigger the before_process() method,
once the transactions are updated.

I tried this
in a file called in case of a success

make some updates to the order
set a message to be displayed in message stack
> zen_redirect(zen_href_link(filename_checkout_process, null, SSL));

:yuck: lost :censored::frusty::frusty:
:lamo: going home