Jump to content

Need Help Building A Payment Gateway Module


randvegeta

Recommended Posts

Hi,

 

I'm new to Blesta. Been using WHMCS for over 10 years but as I needed some automation features of which were not developed to work on WHMCS, I thought I'd give Blesta a try.

 

 

I created a payment gateway module for WHMCS that works very well, and was very easy to implement. Unfortunately I'm finding it very difficult to understand how Blesta works and have not been able to make any progress at all in porting over the module.

 

The gateway is a non-merchant gateway type. The gateway is CarrotPay (http://carrotpay.com).

 

It's a very simple gateway and requires only a few params. The payment requires some javascript be included on the payment page.

 

If anyone is willing/able to help, I'm happy to provide the WHMCS module I wrote before.

 

Thanks in advance!

 

 

 

Link to comment
Share on other sites

Have you taken a look at the Payment Gateway documentation for Non-merchant Gateways? The SDK provides a sample non-merchant gateway to help get started with one yourself. If you need to set javascript on the payment page, you can do so in YourGateway::buildProcess(), which is where you render the view that includes the pay button a client will click to be taken offsite for payment.

Link to comment
Share on other sites

File: /whmcs/modules/gateways/carrot.php 

<?php

	function carrot_config() {

		$configarray = array(
		 "FriendlyName" => array("Type" => "System", "Value"=>"CarrotPay"),
		 "merchant" => array("FriendlyName" => "Merchant ID", "Type" => "text", "Size" => "30", "Description" => "Your Merchant ID", ),
		 "hashSeed" => array("FriendlyName" => "Hash Seed", "Type" => "text", "Size" => "30", "Description" => "Your Secret/HashSeed", ),
		 "btnURL" => array("FriendlyName" => "Button URL", "Type" => "text", "Size" => "30", "Value"=>"http://www.carrotpay.com/images/buttons/btn88x31.gif","Description" => "URL to Button (Do not change for default)", ),
		);
		return $configarray;

	}// end function carrot_config()

	function carrot_link($params) {

		# Gateway Specific Variables
		$gatewayusername = $params['merchant'];
		$gatewayhashSeed = $params['hashSeed'];
		$btnURL = $params['btnURL'];

		# Invoice Variables
		$invoiceid = $params['invoiceid'];
		$description = $params["description"];
		$amount = $params['amount'];
		$currency = $params['currency']; # Currency Code

		$word = "id".$invoiceid.$amount; // Used to create Hash
		//$duedate = $params['duedate'];

		# Client Variables
		$firstname = $params['clientdetails']['firstname'];
		$lastname = $params['clientdetails']['lastname'];
		$email = $params['clientdetails']['email'];
		$address1 = $params['clientdetails']['address1'];
		$address2 = $params['clientdetails']['address2'];
		$city = $params['clientdetails']['city'];
		$state = $params['clientdetails']['state'];
		$postcode = $params['clientdetails']['postcode'];
		$country = $params['clientdetails']['country'];
		$phone = $params['clientdetails']['phone'];

		# System Variables
		$companyname = $params['companyname'];
		$systemurl = $params['systemurl'];
		$currency = $params['currency'];

		# Enter your code submit to the gateway...

		$code = '<br/>
				<script src="http://cdn.carrot.org/js/carrot.js" ></script>

				<script type="text/javascript">

				<!-- <![CDATA[

				function payWithCarrots(thePrice) {

				Carrot.pay({

				price: thePrice,

				merchant: "'.$gatewayusername.'",

				description: "'.$description.'",

				return_url: "'.$systemurl.'/modules/gateways/callback/carrotPayCB.php?invoiceid='.$invoiceid.'&value='.$amount.'&currency='.$currency.'&hash=['.$word.']"

				});

				};

				function showPurse() {

				Carrot.purse();

				}


				$(document).ready(function() {

				//Only for testing - not needed with live site

				// Carrot.debug = 1;

				// Carrot.purse_url = "https://secure.test.carrot.org:8443/webPurse.do";

				// Carrot.payment_url = "https://secure.test.carrot.org:8443/payment";


				$("#debug").html("<p>Looking for ID ...</p>");

				Carrot.get_id(function(id) {

				if(id==null)

				$("#debug").html("<p>No id found</p>");

				else

				$("#debug").html("<p>"+id+"</p>");

				});

				});

				// ]]> -->

				</script>

				<a href="javascript:payWithCarrots(\''.$amount.':'.$currency.'\')"><img src="'.$btnURL.'" alt="Pay with CarrotPay"/></a>
				
				';

		return $code;
	}

?>

File: /whmcs/modules/gateways/carrot/hashword.php

<?php
	function hash_word($word, $price, $seed)
	{
	  // Lower case and strip dashes from seed
	  $seed = strtolower($seed);
	  $seed = str_replace("-", "", $seed);
		
	  // Construct hash text from seed, price and word
	  // Note space delimited
	  $text = "$word $price $seed";

	  // Get md5 (hex string)
	  $md5 = md5($text);

	  // Get last 8 hex chars (32 bits, unsigned)
	  $hex = substr($md5, -8);

	  // Replace with 'safe' alphabet
	  $safe = strtr($hex, "0123456789abcdef", "bcdghjklmpqrsvwz");

	  // Trim off leading 'b' (zero)
	  return ltrim($safe, "b");
	}
?>

File: /whmcs/modules/gateways/callback/carrotPayCB.php

<?php

	# Required File Includes
	include("../../../dbconnect.php");
	include("../../../includes/functions.php");
	include("../../../includes/gatewayfunctions.php");
	include("../../../includes/invoicefunctions.php");
	
	$gatewaymodule = "carrot"; # Enter your gateway module name here replacing template

	$GATEWAY = getGatewayVariables($gatewaymodule);
	if (!$GATEWAY["type"]) die("Module Not Activated"); # Checks gateway module is active before accepting callback

	# Required by CarrotPay for verification
	include ("../carrot/hashword.php");
	
	$hash = $_GET['hash'];
	$invoiceid = $_GET['invoiceid'];
	$amount = $_GET['value']; //Gets the actual price
	$currency = $_GET['currency'];
	$word = "id".$invoiceid.$amount; // Used to create Hash
	$price = $amount.":".$currency; //Converts the pirce into carrots
	$seed = $GATEWAY["hashSeed"];
	$hashval = hash_word($word,$price,$seed);
	$systemurl = $params['systemurl'];

	#Checks if transaction is valid
	$status="0";
	if ($hashval == $hash) {
		$status = "1"; // set to '1' if valid
	}	

	$transid = $hash;
	$fee = 0;

	//$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY["name"]); # Checks invoice ID is a valid invoice number or ends processing

	//checkCbTransID($transid); # Checks transaction number isn't already in the database and ends processing if it does

	if ($status=="1") {
		# Successful
		echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=/billing/viewinvoice.php?id=$invoiceid\"><h2>Redirecting</h2><p>Your payment was <b>sucessful</b> and you are being redirected now.</p><p>If you page does not redirect in 5 seconds, click <a href=\"/billing/viewinvoice.php?id=$invoiceid\">here</a>.</p>";
		addInvoicePayment($invoiceid,$transid,$amount,$fee,$gatewaymodule);
		logTransaction($GATEWAY["name"],$_POST,"Successful");
		
	} else {
		# Unsuccessful
		echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=/billing/viewinvoice.php?id=$invoiceid\"><h2>Redirecting</h2><p>Your payment has <b>failed</b>. An error occured during payment and you are being redirected now.</p><p>If your page does not redirect in 5 seconds, click <a href=\"/billing/viewinvoice.php?id=$invoiceid\">here</a>.</p>";
		logTransaction($GATEWAY["name"],$_POST,"Unsuccessful");		
	}

?>

Link to comment
Share on other sites

Thanks for the feedback guys.

 

 

 

Have you taken a look at the Payment Gateway documentation for Non-merchant Gateways? The SDK provides a sample non-merchant gateway to help get started with one yourself. If you need to set javascript on the payment page, you can do so in YourGateway::buildProcess(), which is where you render the view that includes the pay button a client will click to be taken offsite for payment.

 

Yes I have taken a look at the documentation and the SDK sample as well as looked at the Paypal module to see how it works.

However I just don't get it. The documentation, to me, is less than clear and there are many irrelevant components in the Paypal example. I have no idea what can be removed, what I can add, or how to implant HTML/Javascript code into the invoice pages. For the life of me, I cannot find any information on  this in the documentation.

 

I thought I would try and take baby steps and at first just get the demo gateway uploaded with the name changed to carrotpay. Doing this resulted in the following error:

 

 

 

Oh noes!

Gateway 'CarrotPay' does not exist on line 42 in /home/vpsbit/public_html/my/components/gateways/gateways.php 

Printing Stack Trace:
#0 /home/vpsbit/public_html/my/app/models/gateway_manager.php(618): Gateways::create('carrot_pay', 'nonmerchant')
#1 /home/vpsbit/public_html/my/app/models/gateway_manager.php(309): GatewayManager->loadGateway('carrot_pay', 'nonmerchant')
#2 /home/vpsbit/public_html/my/app/controllers/admin_company_gateways.php(159): GatewayManager->add(Array)
#3 /home/vpsbit/public_html/my/lib/dispatcher.php(111): AdminCompanyGateways->install()
#4 /home/vpsbit/public_html/my/index.php(21): Dispatcher::dispatch('/admin/settings...')
#5 {main}

Link to comment
Share on other sites

I should probably explain the module a bit.

 

For CarrotPay, there are only 2 important peices of information that need to be configured within the admin area.

 

1.) Merchant ID - The ID of the merchant account (equivalent to Paypal e-mail address)

2.) HashSeed - A secret code/string that is used to generate hashes for verification.

 

-------------------------------------------------------------------------------------------------------------------------------

In the file /whmcs/modules/gateways/carrot.php

 

The first function [carrot_config]  is responsible for defining the variables that need to be set in the admin area (merchant ID, hash seed and the url to the image for the payment button)

 

The second function [carrot_link] generates the payment button. It takes all the relavent account information to populate the Javascript function, using the merchant ID, invoice number, amount and currency. It is then passed onto CarrotPay.

 

-------------------------------------------------------------------------------------------------------------------------------

In the file /whmcs/modules/gateways/callbackCarrotPayCB.php

 

This file handles what happens during the call back. CarrotPay takes the variables passed to it and returns the hash of those variables.

 

The callback file takes the original variables, and hashes it with the hash seed. It then takes the returned hash and compares it with the one it just made. If they are the same, the payment is genuine and valid. Otherwise it's not.

 

-------------------------------------------------------------------------------------------------------------------------------

In the file /whmcs/modules/gateways/carrot/hashword.php

 

This file contains the actual function that generates the hash.
Link to comment
Share on other sites

Each gateway has its own specific requirements, so we mostly include information on integrating it into Blesta by describing the required file structure and providing an example gateway.

 

There probably should be documentation on required/optional methods, similar to modules. In the meantime, you can determine the required methods by looking at the Gateway and NonmerchantGateway classes included in Blesta under /components/gateways/lib/. Each abstract public function must be implemented in your gateway. These include:

setCurrency
getSettings
editSettings
encryptableFields
setMeta

validate
success

You must also set a name, version, author, and list of supported currencies for the gateway. There are methods you can write for this, but you should use a config file instead. You should also write the buildProcess method, as this creates the payment page that customers will go to just before they continue offsite. Optionally, your gateway may support voiding or refunding payments, which you can implement via void and refund respectively.

 

 

 

For CarrotPay, there are only 2 important peices of information that need to be configured within the admin area.
 
1.) Merchant ID - The ID of the merchant account (equivalent to Paypal e-mail address)
2.) HashSeed - A secret code/string that is used to generate hashes for verification.

This information is handled via getSettings, editSettings, setMeta, and encryptableFields in the gateway, and in a template view settings.pdt where you set those fields.

 

 

The second function [carrot_link] generates the payment button. It takes all the relavent account information to populate the Javascript function, using the merchant ID, invoice number, amount and currency. It is then passed onto CarrotPay.

This would be set in buildProcess and in the template view you create for that page, process.pdt.

 

 

This file handles what happens during the call back. CarrotPay takes the variables passed to it and returns the hash of those variables.
 
The callback file takes the original variables, and hashes it with the hash seed. It then takes the returned hash and compares it with the one it just made. If they are the same, the payment is genuine and valid. Otherwise it's not.

This would be handled via validate and success in the gateway.

 

 

 

In the file /whmcs/modules/gateways/carrot/hashword.php
 
This file contains the actual function that generates the hash.

You would probably include this as a helper method in your gateway.

Link to comment
Share on other sites

Also, what about the error I see when I just renamed the module demo... What is causing the error?

 

The error is likely caused by the name of the class or directory. The class name of the gateway should be in camel-case format, while the directory name should be separated by underscores as described in the Programming Style Guide, following the gateway file structure. You can use the other gateways as reference.

 

i.e. The class name "CarrotPay" means the directory it is within should be "carrot_pay" @ /components/gateways/nonmerchant/carrot_pay/carrot_pay.php

 

 

Can you give me an example how I set and get a variable so I can use it in the generating of payment button?

 

Curious, are you a developer by trade? I ask because I have been tailoring my explanations assuming that you are familiar with object-oriented programming in PHP--classes, abstract methods, inheritance, etc., following the MVC design pattern that Blesta uses. If not, there is going to be a learning curve to overcome first.

 

In CarrotPay::buildProcess, you would create a view, set variables to the view, and return the view. Setting variables can be done by calling set on the View object by setting a name for it in the view (first parameter) and the value (as the second parameter).

 

e.g. (This is copied from the Payza gateway)

        $fields = array();
        $this->view = $this->makeView("process", "default", str_replace(ROOTWEBDIR, "", dirname(__FILE__) . DS));
        Loader::loadHelpers($this, array("Form", "Html"));
		
	//Sets sandbox or production URL based on "test_mode" parameter value.
	$this->view->set("post_to", ($this->ifSet($this->meta['test_mode']) == "true" ? $this->payza_sandbox_url : $this->payza_url));
        $this->view->set("fields", $fields);
        return $this->view->fetch();

You would output the data in your view template under /components/gateways/nonmerchant/carrot_pay/view/default/process.pdt. The Form and Html helpers are used to simplify creating form fields and for outputting content html-safe.

Link to comment
Share on other sites

 

Curious, are you a developer by trade? I ask because I have been tailoring my explanations assuming that you are familiar with object-oriented programming in PHP--classes, abstract methods, inheritance, etc., following the MVC design pattern that Blesta uses. If not, there is going to be a learning curve to overcome first.

 

In CarrotPay::buildProcess, you would create a view, set variables to the view, and return the view. Setting variables can be done by calling set on the View object by setting a name for it in the view (first parameter) and the value (as the second parameter).

 

 

No I am not a developer by trade. I am more of a network/server engineer than software developer. I have some programming experience and am familiar with the concept of object-oriented programming, classes, abstract methods etc. But I have never been a developer, and the last bit of OOP programming I have done was back in my uni days in Java... which by the way I have long since forgotten.

You can see from my WHMCS module, it is more procedural, and not OOP at all.

 

And even though I am familiar with the concept of OOP, I am not at all familiar with the PHP implementation.

 

In fact, I have found a number of integration tasks with Blesta to be exceedingly difficult compared to WHMCS. For example, getting the template to look right was exceedingly difficult using the bootstrap method.

 

Are most hosts using Blesta developers? It would seem to be less accessible for customization. No?

Link to comment
Share on other sites

No I am not a developer by trade. I am more of a network/server engineer than software developer. I have some programming experience and am familiar with the concept of object-oriented programming, classes, abstract methods etc. But I have never been a developer, and the last bit of OOP programming I have done was back in my uni days in Java... which by the way I have long since forgotten.

You can see from my WHMCS module, it is more procedural, and not OOP at all.

 

Are most hosts using Blesta developers? It would seem to be less accessible for customization. No?

 

Blesta is more flexible in terms of the customizations you can create as a developer, and it probably helps that so much of the source code is unencoded. You could write a plugin to do just about anything with the system, and you can integrate with the API, which supports all public model methods. So I would say it is more developer-friendly than WHMCS is, although they certainly have more customizations currently available at the moment.

 

 

In fact, I have found a number of integration tasks with Blesta to be exceedingly difficult compared to WHMCS. For example, getting the template to look right was exceedingly difficult using the bootstrap method.

 

Bootstrap markup has been increasing in use on websites for a while now, and WHMCS currently uses it as well. It's a good platform to work from for standardizing markup. I think WHMCS also incorporates Smarty templates to aid in their creation, which we do not. But with anything new, there's going to be a learning curve to overcome. Feel free to ask more questions if something isn't making sense.

Link to comment
Share on other sites

The error is likely caused by the name of the class or directory. The class name of the gateway should be in camel-case format, while the directory name should be separated by underscores as described in the Programming Style Guide, following the gateway file structure. You can use the other gateways as reference.


i.e. The class name "CarrotPay" means the directory it is within should be "carrot_pay" @ /components/gateways/nonmerchant/carrot_pay/carrot_pay.php

Like randvegeta, not certain if I'm a developer by trade, I learned code (php, html) by my own, and lately created payment gateway extensions for MVC CMS like joomla or magento, and I was also with whmcs before.

 

Using my word, comparing Blesta vs whmcs at coding is like compare WP vs a MVC CMS like joomla so whmcs is less structured/formal code, so it's flexible to start little things but unflexible for more (and most files are encrypted). So Blesta do have is few more learning curve to get it, but more powerfull at doing what you want, hopefully a payment gateway plugin/module is certainly not the more harder to do or start at doing custom code and there are existing models.

 

Good luck :-)

Link to comment
Share on other sites

Not to sound ungrateful, but I don't feel I am much better off than before I started this thread. I am still a bit stuck with how to proceed.

 

 

 

whmcs is less structured/formal code, so it's flexible to start little things but unflexible for more (and most files are encrypted). So Blesta do have is few more learning curve to get it, but more powerfull at doing what you want

 

You see, all I want to do is something very simple. Flexible as Blesta, it is inaccessible to more novice developers like myself, to the point where simple things become seemingly over complicated. My WHMCS module literally took me less than 2 hours to read the documentation, implement and deploy. The code is exceedingly simple. I understand there may be more hoops to jump through with Blesta, but as it stands, I have no idea how to do that.

 

Perhaps someone can provide a quote to port over?

Link to comment
Share on other sites

thxs for the feedback, I will let other people answer about the quote as I only code for my business project.

 

Other, I found carrotpay interresting at first look, and I would like to know from you, in what are you thinking there are the most differents or advantageous than other gateways?

Link to comment
Share on other sites

There are 2 advantages for us, which may not necessarily relevant to others.

 

1.) They are an HK based gateway so it makes things a little easier for us since we too are based in HK.

 

2.) We can issue something called 'SiteCoins'. Basically it's kind of like a coupon but it appears in the clients 'wallet' as money that can be spent on our site. This is independent of the billing system.

 

You can see how it works here: http://hosthongkong.net/?page=free

 

We really want to take advantage of this sitecoin feature and it's just not available with anyone else.

Link to comment
Share on other sites

I am making some progress but I am finding that Blesta is a bit too rigid (or I am just not familiar with how things are done?).

 

As you can see from my WHMCS module, there is no 'form' submission. Instead there is some JavaScript which loads the wallet directly into the browser and everything is done on the page.

 

CarrotPay IS NOT a merchant gateway but what Blesta describes as NON-MERCHANT as no details are collected about the client in order to process the transaction.

 

Is the payment button the only thing that can be displayed because I am not sure what options are available to me. The Processes.pdt does not have any HTML generating a form, but it is there on the payment page.... 

Link to comment
Share on other sites

I have not read the doc and will not answer you on specific technical point, but regarding Merchant VS Non merchant definition, I'm also not certain, I think there is no an unique definition.

 

- some say merchant, because you need a merchand card from a bank

 

- other say merchant when you do not redirect customer on the payment gateway website, because all is embed on your website

 

- other say, it when you collect & store credit card detail on your database.

 

- or a mix of all above

 

So this is just from my understanding or missunderstanding...

Link to comment
Share on other sites

as inspiration to transpose, have a look at this link for stripe gateway, this use also javascrip in a form

<form action=" method="POST">
  <script
    src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"
    data-key="pk_test_G5YhIkq2PEq84lwU064TZENT"
    data-amount="2000"
    data-name="Demo Site"
    data-description="2 widgets ($20.00)"
    data-image="/128x128.png">
  </script>
</form>

http://code.tutsplus.com/tutorials/how-to-accept-payments-with-stripe--pre-80957

Link to comment
Share on other sites

I have no problem loading the javascript on the payment page. The problem was that the example does not have an HTML form but rather one is generated.

I built the WHMCS without problem and without example code or a demo. There were no 'tools' that were included, which allowed very free reign over what I could do. Blesta seems to have certain 'tools' and pre-set variables which are irrelevant to some merchant gateways and I am unsure if I should/could do away with them or if they are mandatory. Or if indeed there are other tools available I could use rather than hard coding into the processes.pdt file.

 

 

- some say merchant, because you need a merchand card from a bank

 

- other say merchant when you do not redirect customer on the payment gateway website, because all is embed on your website

 

- other say, it when you collect & store credit card detail on your database.

 

- or a mix of all above

 

Well you see this is why my feeling is that Blesta can be quite rigid. It's not so obvious, and the definitions coined by Blesta do not cover the CarrotPay system. At least not in an absolute clear way. I  would say it is more NON-MERCHANT than anything else however.

 

 

 

and you have maybe to create you own form

 

I know I have to create my own 'code' for this but a form is not what I want/need. Again, there is a function within the processes.pdt file that auto generates a form. I do not need a form, so I am not 100% sure if this is something I can simply remove.

 

In any case, I have made some good progress and should be able to get it working and tested within a couple days.

 

Sadly, I must say I have found the documentation completely useless. And I'm not convinced that OOP serves any purpose at the gateway module stage. Just over complicates things in my opinion. Ahh what do I know any way. I'm not a developer.

Link to comment
Share on other sites

I believe I have made good progress with generating the payment page.

 

I have been able to get the wallet to appear on screen with all the neccessary information. Now I just need to work on the callback/return_URL. But I can't see how it's supposed to work. I just see:

 

 

 

The gateway does not support that action.

 

 

I am looking at the 'validate' function but I can't see how it is supposed to be used. And the return URL may invalidate the 'get' params set in the URL itself.  What do I do?

Link to comment
Share on other sites

my answer could be very generic but I believe there is 2 ending points in Blesta, and same way for most CMS gateway integration:

 

- the return url ( for html customer display), & saying success transaction or failled etc depending of transaction status after customer is redirected back from payment gateway to Blesta here most of the time ist' only GET data, meaning you can see data in the URL structure  like   .?param1=xx&param2=yy, etc

 

- the callback url, is here for update the transaction/order status in Blesta, it's only server-to-server communication (no html display), it's most of the time POST data, it's depend specifically of the given gateway., when it's post data, data can not be seen in the url structure.

 

example:

--------------------

 

   function gateway_response(){

        ## Get data response (GET & POST) from gateway

        $gateway_response_txnid = $_REQUEST['txnid'];       
        $gateway_response_refno = $_REQUEST['refno'];
        $gateway_response_status = $_REQUEST['status'];
        $gateway_response_message = $_REQUEST['message'];
        $gateway_response_digest = $_REQUEST['digest'];
        $gateway_response_param1 = $_REQUEST['param1'];
        $gateway_response_param2 = $_REQUEST['param2'];
 

 

 

etc...

 

-------------------------

 

here in the example it's using $_REQUEST vs $_POST vs $_GET, request will take data from any method (post, get, cookies, etc)

 

and you need to have a condition (if) to check response authenticity by cheking the digest or key depending of your gateway

 

regarding 2 url to use:

http://www.blesta.com/forums/index.php?/topic/4339-payment-gateway-redirect-problem/#entry32356

http://www.blesta.com/forums/index.php?/topic/3530-ipn-listener-in-pesapal-gateway/

Link to comment
Share on other sites

ight... with CarrotPay, there is no 'callback' to the server. The only thing used is the 'return_url'.

 

Can the transaction be completed only with the return_url?

 

All I need to do is fetch the variables (in a GET) from the URL, and reproduce the hash to verify payment. If the hash matches, then accept the transaction, otherwise, return an error. I am finding it difficult to do this.

 

As for where I am getting stuck, I understand that I can get the variables using $_GET['var'] or $_REQUEST['var']. But where am I supposed to be doing this, given I only have a return_url, and no call back is made. AND what do I need to do after I get the variables and confirm the payment is made.

 

Perhaps someone could explain this to me?

 

From the 2CO gateway module

	public function validate(array $get, array $post) {
		
		// Order number to verify key must be "1" if demo mode is set
		$order_number = ($this->ifSet($post['demo']) == "Y") ? "1" : $this->ifSet($post['order_number']);
		
		// Validate the response is as expected
		$rules = array(
			'key' => array(
				'valid' => array(
					'rule' => array("compares", "==", strtoupper(md5($this->ifSet($this->meta['secret_word']) . $this->ifSet($this->meta['vendor_id']) . $order_number . $this->ifSet($post['total'])))),
					'message' => Language::_("_2Checkout.!error.key.valid", true)
				)
			),
			'credit_card_processed' => array(
				'completed' => array(
					'rule' => array("compares", "==", "Y"),
					'message' => Language::_("_2Checkout.!error.credit_card_processed.completed", true)
				)
			),
			'sid' => array(
				'valid' => array(
					'rule' => array("compares", "==", $this->ifSet($this->meta['vendor_id'])),
					'message' => Language::_("_2Checkout.!error.sid.valid", true)
				)
			)
		);
		
		$this->Input->setRules($rules);
		$success = $this->Input->validates($post);
		
		// Log the response
		$this->log($this->ifSet($_SERVER['REQUEST_URI']), serialize($post), "output", $success);
		
		if (!$success)
			return;
		
		return array(
			'client_id' => $this->ifSet($post['client_id']),
			'amount' => $this->ifSet($post['total']),
			'currency' => $this->ifSet($post['currency_code']),
			'invoices' => unserialize(base64_decode($this->ifSet($post['invoices']))),
			'status' => "approved",
			'reference_id' => null,
			'transaction_id' => $this->ifSet($post['order_number']),
			'parent_transaction_id' => null
		);
	}
	
	/**
	 * Returns data regarding a success transaction. This method is invoked when
	 * a client returns from the non-merchant gateway's web site back to Blesta.
	 *
	 * @param array $get The GET data for this request
	 * @param array $post The POST data for this request
	 * @return array An array of transaction data, may set errors using Input if the data appears invalid
	 *  - client_id The ID of the client that attempted the payment
	 *  - amount The amount of the payment
	 *  - currency The currency of the payment
	 *  - invoices An array of invoices and the amount the payment should be applied to (if any) including:
	 *  	- id The ID of the invoice to apply to
	 *  	- amount The amount to apply to the invoice
	 * 	- status The status of the transaction (approved, declined, void, pending, reconciled, refunded, returned)
	 * 	- transaction_id The ID returned by the gateway to identify this transaction
	 * 	- parent_transaction_id The ID returned by the gateway to identify this transaction's original transaction
	 */
	public function success(array $get, array $post) {
		
		return array(
			'client_id' => $this->ifSet($post['client_id']),
			'amount' => $this->ifSet($post['total']),
			'currency' => $this->ifSet($post['currency_code']),
			'invoices' => unserialize(base64_decode($this->ifSet($post['invoices']))),
			'status' => "approved",
			'transaction_id' => $this->ifSet($post['order_number']),
			'parent_transaction_id' => null
		);
	}
Link to comment
Share on other sites

From What I can understand, and please correct me if I'm wrong,

 

the 'success' function is the function related to the return_url parameter. It  does nothing but serve as a place for client's to be sent back to after payment is made. Nothing in there saves the transaction details or applies them to invoices.

 

It is instead the 'validate' function which relates to actually processing the payment, but there is no html to be displayed to the client here as it is intended for server to server communication.

 

Is this right?

 

If yes, how am I to proceed given CarrotPay does not use the 'callback' feature, and instead only gives a return URL for the client. The return_url then includes all transaction data to be verified by the merchant.

 

Can I use the callback URL in place of the return URL?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...