Magento payment module with Moneris - php

With the help of https://github.com/ph/magento-moneris I have managed to create a Moneris payment gateway in Magento and I am testing it now with Moneris Development site.
I have got a couple of questions where I am confused and don't know how to proceed.
Is there a way I can set 'Authorize only' to 'Authorize and Capture' some where in the code so that the capture is performed at the same time when the order is placed?
Also Is there a way that the invoicing can be done at the same time as the order is placed with the invoice mail sent to the customer n store owner.
Ex: when the 'Place Order' is clicked, the customer's card details are checked and validated. If they are ok, then the payment is captured at the same time in the merchant's account and the invoice emails are sent to the customer and store owner.
If the card details are not right, then show an appropriate message on front end to the customer as well keep that order as pending with appropriate reason for the store owner to see.
The code I have for now is for _authorize n _capture functions. Do they need to be modified or new functions needs to be created.
public function authorize(Varien_Object $payment, $amount)
{
$error = false;
// check for payment
if($amount > 0) {
$payment->setAmount($amount);
// Map magento keys to moneris way
$order = $payment->getOrder();
$billing = $order->getBillingAddress();
$avsTemplate = array('avs_zipcode' => $order->getBillingAddress()->getPostcode(), 'avs_street_number' => $order->getBillingAddress()->getStreet(1),'', 'avs_street_name' => $order->getBillingAddress()->getStreet(2),'');
$mpgAvsInfo = new mpgAvsInfo($avsTemplate);
$cvdTemplate = array('cvd_value' => $payment->getCcCid(),'cvd_indicator' => 1);
$mpgCvdInfo = new mpgCvdInfo($cvdTemplate);
$transaction = $this->_build($payment, self::TRANSACTION_PREAUTH);
$transaction->setAvsInfo($mpgAvsInfo);
$transaction->setCvdInfo($mpgCvdInfo);
$response = $this->_send($transaction);
$payment->setCcApproval($response->getReceiptId())
->setLastTransId($response->getReceiptId())
->setCcTransId($response->getTxnNumber())
->setCcAvsStatus($response->getAuthCode())
->setCcCidStatus($response->getResponseCode());
if($response->getResponseCode() > 0 && $response->getResponseCode() <= self::ERROR_CODE_LIMIT)
{
$payment->setStatus(self::STATUS_APPROVED);
$message = 'AVS Response: ' . Mage::helper('paygate')->__($this->_errors[$response->getAvsResultCode()]);
$message .= '<br>CVD Response: ' . Mage::helper('paygate')->__($this->_errors[$response->getCvdResultCode()]);
Mage::getSingleton('core/session')->addSuccess($message);
}
else if($response->getResponseCode() > self::ERROR_CODE_LIMIT && $response->getResponseCode() < self::ERROR_CODE_UPPER_LIMIT)
{
$error = Mage::helper('paygate')->__($this->_errors[$response->getResponseCode()]);
}
else
{
$error = Mage::helper('paygate')->__('Incomplete transaction.');
}
}
else
{
$error = Mage::helper('paygate')->__('Invalid amount for authorization.');
}
if ($error !== false)
Mage::throwException($error);
return $this;
}
/**
* Capture the authorized transaction for a specific order
* #var Variant_Object $payment
* #var Float $amount
*/
public function capture(Varien_Object $payment, $amount) {
$error = false;
// check for payment
if ($amount <= 0)
{
Mage::throwException(Mage::helper('paygate')->__('Invalid amount for capture.'));
}
if($amount > 0)
{
$payment->setAmount($amount);
// Map magento keys to moneris way
$transaction = $this->_build($payment, self::TRANSACTION_COMPLETION);
$response = $this->_send($transaction);
if($response->getResponseCode() > 0 && $response->getResponseCode() <= self::ERROR_CODE_LIMIT)
{
$payment->setStatus(self::STATUS_SUCCESS);
$message = 'AVS Response: ' . Mage::helper('paygate')->__($this->_errors[$response->getAvsResultCode()]);
$message .= '<br>CVD Response: ' . Mage::helper('paygate')->__($this->_errors[$response->getCvdResultCode()]);
Mage::getSingleton('core/session')->addSuccess($message);
}
else if($response->getResponseCode() > self::ERROR_CODE_LIMIT && $response->getResponseCode() < self::ERROR_CODE_UPPER_LIMIT)
{
$error = Mage::helper('paygate')->__($this->_errors[$response->getResponseCode()]);
}
else
{
$error = Mage::helper('paygate')->__('Incomplete transaction.');
}
}
else
{
$error = Mage::helper('paygate')->__('Invalid amount for capture.');
}
// we've got something bad here.
if ($error !== false)
Mage::throwException($error);
return $this;
}
Feel free to correct me anywhere or suggest a better way of doing what I'm trying to do.
In the end I'm looking forward to build a basic Moneris payment gateway in Magento which authorizes n captures the amount if the card details are right and sends invoice mails to customer n store owner all at the same time at the click of 'place order'.
And if the card details are wrong then show appropriate message to customer and keep it as pending with right reason for pending payment for the store owner to see.

Related

How to create order in magento programmatically with paypal payment method

How to create order in magento programmatically with paypal payment method.
We have implemented code for COD method or Check/Money order payment methods, now I need to implement payment, I searched alot but didn't found any answer, is there a proper way for this ?
first of all paypal is payment getaway which need authentication .
but you can try this code
file here : app/code/core/Mage/Paypal/Model/Express.php
function code here :
public function order(Varien_Object $payment, $amount)
{
$this->_placeOrder($payment, $amount);
$payment->setAdditionalInformation($this->_isOrderPaymentActionKey, true);
if ($payment->getIsFraudDetected()) {
return $this;
}
$order = $payment->getOrder();
$orderTransactionId = $payment->getTransactionId();
$api = $this->_callDoAuthorize($amount, $payment, $payment->getTransactionId());
$state = Mage_Sales_Model_Order::STATE_PROCESSING;
$status = true;
$formatedPrice = $order->getBaseCurrency()->formatTxt($amount);
if ($payment->getIsTransactionPending()) {
$message = Mage::helper('paypal')->__('Ordering amount of %s is pending approval on gateway.', $formatedPrice);
$state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
} else {
$message = Mage::helper('paypal')->__('Ordered amount of %s.', $formatedPrice);
}
$payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_ORDER, null, false, $message);
$this->_pro->importPaymentInfo($api, $payment);
if ($payment->getIsTransactionPending()) {
$message = Mage::helper('paypal')->__('Authorizing amount of %s is pending approval on gateway.', $formatedPrice);
$state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
if ($payment->getIsFraudDetected()) {
$status = Mage_Sales_Model_Order::STATUS_FRAUD;
}
} else {
$message = Mage::helper('paypal')->__('Authorized amount of %s.', $formatedPrice);
}
$payment->resetTransactionAdditionalInfo();
$payment->setTransactionId($api->getTransactionId());
$payment->setParentTransactionId($orderTransactionId);
$transaction = $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH, null, false,
$message
);
$order->setState($state, $status);
$payment->setSkipOrderProcessing(true);
return $this;
}
you can customize this code as per you basic requirement
and let me know if you have any issue

VirtueMart duplicate orders

I'm currently developing a payment plugin for VirtueMart. I have never used it before. The goal is:
When the user clicks to the confirm order button, he gets redirected to the bank interface (managed it, no work needed)
He then gets redirected back to the webshop with an answer from the bank (also done)
If the transaction is success, the order is stored as confirmed or if the transaction fails, the order is getting cancelled.
What I managed, is marked in the list above. For some reason, the order gets stored twice as pending, once when the user clicks the button, and once when the user gets redirected back to the shop. Also, if the transaction fails, the order is stored twice, also pending. I reused the standard payment plugin given with the VirtueMart aio package. All the above stuff is written in the plgVmConfirmedOrder function. I would post it here:
function plgVmConfirmedOrder ($cart, $order) {
if (!($method = $this->getVmPluginMethod ($order['details']['BT']->virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
if (!$this->selectedThisElement ($method->payment_element)) {
return FALSE;
}
VmConfig::loadJLang('com_virtuemart',true);
VmConfig::loadJLang('com_virtuemart_orders', TRUE);
if (!class_exists ('VirtueMartModelOrders')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'orders.php');
}
$this->getPaymentCurrency($method);
$currency_code_3 = shopFunctions::getCurrencyByID($method->payment_currency, 'currency_code_3');
$email_currency = $this->getEmailCurrency($method);
$totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total,$method->payment_currency);
$dbValues['payment_name'] = $this->renderPluginName ($method) . '<br />' . $method->payment_info;
$dbValues['order_number'] = $order['details']['BT']->order_number;
$dbValues['virtuemart_paymentmethod_id'] = $order['details']['BT']->virtuemart_paymentmethod_id;
$dbValues['cost_per_transaction'] = $method->cost_per_transaction;
$dbValues['cost_percent_total'] = $method->cost_percent_total;
$dbValues['payment_currency'] = $currency_code_3;
$dbValues['email_currency'] = $email_currency;
$dbValues['payment_order_total'] = $totalInPaymentCurrency['value'];
$dbValues['tax_id'] = $method->tax_id;
$payment_info='';
if (!empty($method->payment_info)) {
$lang = JFactory::getLanguage ();
if ($lang->hasKey ($method->payment_info)) {
$payment_info = vmText::_ ($method->payment_info);
} else {
$payment_info = $method->payment_info;
}
}
if (!class_exists ('VirtueMartModelCurrency')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'currency.php');
}
$currency = CurrencyDisplay::getInstance ('', $order['details']['BT']->virtuemart_vendor_id);
if(!array_key_exists("fizetesValasz", $_REQUEST)){
$transaction_id = $this->getTransactionID();
$_REQUEST['tranzakcioAzonosito'] = $transaction_id;
$price = $cart->cartPrices['billTotal'];
$_REQUEST['osszeg'] = round($price);
$_REQUEST['devizanem'] = 'HUF';
$_REQUEST['backURL'] = "http://" . $_SERVER['SERVER_NAME'] . '/component/virtuemart/cart/confirm.html?Itemid=' . $_REQUEST['Itemid'];
$_REQUEST['nyelvkod'] = 'hu';
$dbValues['transaction_id'] = $transaction_id;
//this is where I redirect to the bank interface
process();
}
else{
//this is where I get the data about transaction
$transaction_datas = processDirectedToBackUrl(false);
$status_code = $transaction_datas->getStatuszKod();
$dbValues['otp_response'] = $status_code;
$this->storePSPluginInternalData ($dbValues);
$modelOrder = VmModel::getModel ('orders');
switch ($status_code) {
case 'FELDOLGOZVA':
if($transaction_datas->isSuccessful()){
$message = 'Sikeres Tranzakció!';
$new_status = $this->getNewStatus($method);
$order['customer_notified'] = 1;
$order['comments'] = '';
$modelOrder->updateStatusForOneOrder ($order['details']['BT']->virtuemart_order_id, $order, TRUE);
$message = getMessageText(($transaction_datas->getPosValaszkod()));
$cart->emptyCart();
$html = $this->renderByLayout('post_payment_success', array(
'message' =>$message,
'order_number' =>$order['details']['BT']->order_number,
'order_pass' =>$order['details']['BT']->order_pass,
'payment_name' => $dbValues['payment_name'],
'displayTotalInPaymentCurrency' => round($totalInPaymentCurrency['display'])
));
vRequest::setVar ('html', $html);
return TRUE;
}
else{
$new_status = $method->status_cancelled;
$modelOrder->updateStatusForOneOrder($order['details']['BT']->virtuemart_order_id, $order, TRUE);
$message = 'Sajnos a bank visszautasította a tranzakciót.';
$html = $this->renderByLayout('post_payment_failure', array(
'message' => $message
));
vRequest::setVar('html', $html);
return FALSE;
}
break;
case 'VEVOOLDAL_VISSZAVONT':
return FALSE;
break;
case 'VEVOOLDAL_TIMEOUT':
return FALSE;
break;
}
}
return FALSE;
}
Every help is appreciated. Thanks in advance!
So, the problem was the redirect url. There is an action called plgVmOnPaymentResponseReceived(). This is fired when a specific url is called. I only had to rewrite the $_REQUEST parameter for the redirection.

php : paypal recurring payments token is invalid

I used paypal php sdk with this :
https://github.com/paypal/merchant-sdk-php/blob/master/samples/RecurringPayments/CreateRecurringPaymentsProfile.php
Express checkout is works well, but use recurring payments have problem : token is invalid.
Line 152 in the sdk, it's said
A timestamped token, the value of which was returned in the response
to the first call to SetExpressCheckout. Call
CreateRecurringPaymentsProfile once for each billing
agreement included in SetExpressCheckout request and use the same
token for each call. Each CreateRecurringPaymentsProfile request
creates a single recurring payments profile.
But i don't understand how to "Call CreateRecurringPaymentsProfile once in SetExpressCheckout", there is my code:
public function createPayToken($returnUrl, $cancelUrl, $payModeData) {
$itemName = $payModeData['name'];
$order = $payModeData['fee'];
// $category = 'Digital';
$category = 'Physical';
$currencyCode = "USD";
$paymentDetails = new PaymentDetailsType();
$itemAmount = new BasicAmountType($currencyCode, $order);
$itemDetails = new PaymentDetailsItemType();
$itemDetails->Name = $itemName;
$itemDetails->Amount = $itemAmount;
$itemDetails->Quantity = 1;
$itemDetails->ItemCategory = $category;
$paymentDetails->OrderTotal = new BasicAmountType($currencyCode, $order);
$paymentDetails->PaymentAction = 'Sale';
$paymentDetails->PaymentDetailsItem[] = $itemDetails;
$setECReqDetails = new SetExpressCheckoutRequestDetailsType();
$setECReqDetails->PaymentDetails[] = $paymentDetails;
$setECReqDetails->ReqConfirmShipping = 0;
$setECReqDetails->NoShipping = 1;
$setECReqDetails->AddressOverride = 0;
$setECReqDetails->CancelURL = $cancelUrl;
$setECReqDetails->ReturnURL = $returnUrl;
$setECReqType = new SetExpressCheckoutRequestType();
$setECReqType->SetExpressCheckoutRequestDetails = $setECReqDetails;
$setECReq = new SetExpressCheckoutReq();
$setECReq->SetExpressCheckoutRequest = $setECReqType;
$paypalService = new PayPalAPIInterfaceServiceService();
try {
$setECResponse = $paypalService->SetExpressCheckout($setECReq);
exit;
} catch (Exception $ex) {
echo $ex;
exit;
}
if(isset($setECResponse)) {
if($setECResponse->Ack =='Success') {
$token = $setECResponse->Token;
return $token;
}
var_dump($setECResponse);
exit;
}
return false;
}
Thank you.
You just need to make sure you're including the billing agreement information in your SetExpressCheckout request. Take a look at this sample of set of API calls to complete a recurring payments profile using Express Checkout.
You'll notice the SEC request includes parameters for L_BILLINGTYPE0 AND L_BILLINGAGREEMENTDESCRIPTION0. You need to make sure you include those, otherwise the token that you get back won't be valid for CreateRecurringPaymentsProfile.

OpenERP 7 API invoice validation and payment

I am working with OpenERP 7's XML-RPC API and I am trying to validate an invoice and apply a payment but I can't figure out what model I should be using.
I have successfully created an invoice and added lines. There doesn't seem to be anything in account.invoice and account.payment.term and payment.order do not seem to work either.
Any help would be appreciated.
Hi i figured out how to validate payment to an invoice automatically via XML-RPC using php.
This how openERP invoice workflow works for the payment.
When you create an invoice, payment to this invoice is done by a voucher i.e. model account.voucher is used to apply a payment to an invoice. So when you create an invoice and validate it, the invoice changes status to open of which you can now access the "customer payments" menu and enter the customer name, the onchange_partner_id() function defined in account.voucher is executed to make a calculation of all the invoices the currently enter partner has open for payments.
Then when you enter the payment to make in "Paid Amount" field, onchange_payment() function is executed to allocate the amount paid to different open invoices of the selected partner.
And when you click validate on the payment form, automatically openerp pays the invoice and marks it as paid.
This therefore means you should atleast understand how openerp handles invoices and payments to that invoice by studying the python code in modules account and account_voucher To make the long story short, this is the code that i used.
First create an invoice for a particular partner and validate it. make sure that you partner has a valid phone number set in res.partner model. (Just create it using openerp forms)
************** php code **********
<?php
error_reporting(1);
/*
* TODO
* Improve on handling of server responses. Success and Failures
*/
date_default_timezone_set('Europe/Moscow');
include_once("openerp_models.php");
/////////////////////////////////////////////////////////////////////
//confirm that a username and password is set
if (isset($_SERVER['PHP_AUTH_USER']) && $_SERVER['PHP_AUTH_PW']) {
//password and username -- Basic Authentication
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
///important parameters
$phone_no = $_REQUEST['sender_phone']; //get the mobile number. Use this number to get the partner information.
$amount = $_REQUEST['amount']; // get amount from url
$amount_again = $_REQUEST['amount']; //this will be displayed to the paying client. $amount above is reduced to zero hence
//we create another amount variable to show the customer with success message.
$payment_ref = $_REQUEST['k2_transaction_id']; // get this from url
$firstname = $_REQUEST['first_name'];
$lastname = $_REQUEST['last_name'];
$middlename = $_REQUEST['middle_name'];
$service_name = $_REQUEST['service_name'];
$business_number = $_REQUEST['business_number'];
$transaction_reference = $_REQUEST['transaction_reference'];
$internal_transaction_id = $_REQUEST['internal_transaction_id'];
$transaction_timestamp = $_REQUEST['transaction_timestamp'];
$transaction_type = $_REQUEST['transaction_type'];
$account_number = $_REQUEST['account_number'];
$currency = $_REQUEST['currency'];
$signature = $_REQUEST['signature'];
//openerp instance, pass login,password,dbname and serverURL
$kengen_model = new OpenERPXmlrpc($username, $password, 'copia_training_db', 'http://127.0.0.1:8069/xmlrpc/');
/* TODO UNCOMMENT THIS CODE FOR ACTUAL TESTING WITH KOPOKOPO SERVER
* We will then authorize kopokopo to continue with record creation. But before that,
* we should make sure that the request is actually coming from kopokopo using the signature value sent.
* To learn more see https://app.kopokopo.com/push_api
*
//set up base string
$base_string = "account_number=".$account_number."&amount=".$amount."&business_number=".$business_number."&"
. "currency=".$currency."&first_name=".$firstname."&internal_transaction_id=".$internal_transaction_id."&"
. "last_name=".$lastname."&middle_name=".$middlename."&sender_phone=".$phone_no."&service_name=".$service_name."&transaction_reference=".$transaction_reference."&"
. "transaction_timestamp=".$transaction_timestamp.""
. "transaction_type=".$transaction_type." ";
//get the symmetric key from table keys.api. This key should be copied from Your KopoKopo Account
$get_key = $kengen_model->search('keys.api', 'provider_name', '=', 'KopoKopo') ;
$key_id = $get_key[0];
$key_value = '' ;
//we read
$read_keys = $kengen_model->read('keys.api', [$key_id]);
//loop
foreach ($read_keys as $keys => $values) {
$value = $values->scalarval();
// print_r($value);
// print '<br/>';
//$myarray [] = array($value['name']->scalarval());
$key_value = $value['key_value']->scalarval();
}
// print $key_value; exit;
//data to use
$hash_data = hash_hmac('sha256', $base_string, $key_value, true);
//generate our own signature to compare with
$signature_to_test = base64_encode($hash_data) ;
///test if the parameter $signature passed by KopoKopo is equal to $signature_to_test
// print $signature_to_test;
* TODO, DO the actual testing with Real KEY_VALUE and Request from kopokopo and only allow execution if
* $signature_to_test = $signature else return an access denied status
*/
/////////////////////////////////////////
/* We retrieve the payment journal for kopokopo. We will
* use the journal code to retrieve the journal id.
* The code for kopokopo should be KPKPJ
*/
$get_jrnl_code = $kengen_model->search('account.journal', 'code', '=', 'KPKPJ') ;
$journal_id = $get_jrnl_code[0]; //kopokopo journal
/*
* We retrieve the account_id to pay to. This code is code for KopoKopo Account
* should be static i.e. 2040 is the account unless otherwise specified.
*/
$get_acc_code = $kengen_model->search('account.account', 'code', '=', '2040') ;
$account_id = $get_acc_code[0]; //kopokopo account
//for this record to appear on list of customer payment
$type = 'receipt';
//
/* TODO
* after a successful login, we must authorize this user. We do this to make sure that
* the request if coming from kopokopo server.
*/
//now search for the partner using phone/mobile number parameter
$search_partner = $kengen_model->search('res.partner', 'phone', '=', $phone_no);
//check to make sure that the customer exists
//create an array
$ids = array();
//loop through the $search content and assign its contents to the $ids
for ($i = 0; $i <= count($search_partner); $i++) {
// print $search_partner[$i];
$ids [] = $search_partner[$i];
}
// if a user exist we continue processing
if (count($ids[0]) > 0) {
//perform a read, by picking the first item on the array
$read = $kengen_model->read('res.partner', [$ids[0]]);
// print_r($read);
$myarray = null;
$client_name = '';
//this foreach loop with only loop once. hence just retrieve the client name and amount saved
// in openerp
foreach ($read as $keys => $values) {
$value = $values->scalarval();
// print '<br/>';
//$myarray [] = array($value['name']->scalarval());
$client_name = $value['name']->scalarval();
}
/////////////////////////////////////////////////////
//get invoices, pass partner_id and invoice status which is open for unpaid invoices
//get invoices to retrieve the journal id
$get_invoices = $kengen_model->getPartnetInvoices('account.voucher', $ids[0], 'open');
$retrieved_pay_account_id = 0;
$pay_journal_id = 0;
$period_id = 0;
foreach ($get_invoices as $keys => $values) {
$value = $values->scalarval();
$retrieved_pay_account_id = $value[4]->scalarval();
$pay_journal_id = $value[5]->scalarval();
$period_id = $value[6]->scalarval();
$move_id = $value[7]->scalarval();
}
// print $retrieved_account_id;
/////////////////////////////////////////////////////
//fields to create
$account_voucher_fields = array(
'partner_id' => $ids[0],
'amount' => $amount,
'reference' => $payment_ref,
'journal_id' => $journal_id,
'account_id' => $account_id,
// 'move_id' => $move_id ,
// 'journal_id'=> $retrieved_journal_id,
'type' => $type);
//voucher payment
$create_kopokopo_payment = $kengen_model->createRecord($account_voucher_fields, 'account.voucher');
//we get the total amount of invoice available for this customer.
$total_invoices_amount = $kengen_model->getPartnetInvoices('account.voucher', $ids[0], 'open');
$invoice_totals = 0;
foreach ($total_invoices_amount as $keys => $values) {
$value = $values->scalarval();
$invoice_totals += $value[3]->scalarval();
///
}
// print 'invoice totals is '.$invoice_totals ;
//voucher line payment
//we will retrieve all invoices available for this partner
//get invoices, pass partner_id and invoice status which is open for unpaid invoices
$invoices = $kengen_model->getPartnetInvoices('account.voucher', $ids[0], 'open');
//loop through available invoices. Remember that a customer can have more than one open invoice
$total_credit = 0;
foreach ($invoices as $keys => $values) {
$value = $values->scalarval();
$number = $value[1]->scalarval();
$invoice_amount_to_pay = $value[3]->scalarval();
/*
* To undestand how this code works look at account.voucher model in openerp
* function recompute_voucher_lines(). This openerp function calculates voucher lines given
* a particular payment.
*/
$min_amount = min($invoice_amount_to_pay, $amount);
//
/* print 'x';
print 'on existing invoices in ELSE IF >>>' . ($min_amount);
print '<br/>';
print 'amount_unreconciled is >>>' . ($invoice_amount_to_pay);
print '<br/>';
print 'total_credit is >>>' . $amount;
print '<br/>'; */
///
//reduce amount paid
$amount -= $min_amount;
//convert amount into int
$amount_to_allocate = intval($min_amount);
// print $amount_total ;
///get invoice move line ids
$new_number = str_replace('/', '', $number); //convert the invoice line
$move_ids = $kengen_model->search('account.move.line', 'ref', '=', $new_number);
/////
$account_voucher_line_fields = array(
'partner_id' => $ids[0],
'voucher_id' => $create_kopokopo_payment, //last id inserted in account.voucher
'account_id' => $retrieved_pay_account_id,
'move_line_id' => $move_ids[0],
'amount' => $amount_to_allocate,
'type' => 'cr',
'name' => $number,);
//////
$create_kopokopo_line_payment = $kengen_model->createRecord($account_voucher_line_fields,
'account.voucher.line');
}
/*
* we validate the payment. We access method button_proforma_voucher declared in model account.voucher
* This methods validates an invoice payment and does reconcilation process for us if the user has paid
* fully else the method reconciles invoice partially.
*/
$validate_voucher_payment = $kengen_model->call_function_func('account.voucher',
'button_proforma_voucher', array($create_kopokopo_payment));
//customer found. Return a json response for KopoKopo
$message = "Thank you " . $client_name . " for your payment of Ksh " . $amount_again . ". We value your business";
// see doc # https://app.kopokopo.com/push_api
$success_response = array("status" => "01", "description" => "Accepted",
"subscriber_message" => $message);
echo json_encode($success_response);
return json_encode($success_response);
}
// else we return a json_response with error message
else {
//customer not found. Return a json response for KopoKopo
// see doc # https://app.kopokopo.com/push_api
$error_response = array("status" => "02", "description" => "Account not found");
echo json_encode($error_response);
return json_encode($error_response);
}
} else {
header('WWW-Authenticate: Basic realm="Copia ERP"');
header('HTTP/1.0 401 Unauthorized');
print 'Access Denied';
exit();
}
?>
Hope this will help you.

PayPal IPN with CodeIgniter

I am trying to implement a membership subscription service on a website built in CodeIgniter. I wish to use PayPal to manage payments, and am having a very hard time implementing this.
What I am trying to achieve is:
User fills in a membership form with
personal details
User selects a
subscription option (1 of 8 choices - each different price) and submits form
User is sent to PayPal to pay
User is returned to site upon successful payment and personal details are stored in database which creates user account (membership).
There is also the addition of form validation, I use the form_validation helper in CodeIgniter, but this needs to be done before PayPal payment can commence.
I have attempted to implement the PayPal_Lib from Ran Aroussi, but I feel it has not enough clear documentation or guidance on it. Any implemented examples or advice would be much appreciated.
Lucas
I found Ran's library a little hard to use too so I've written a replacement - which also has the benefit of performing more checks on the transaction, and logging the IPN call and the order details in your database. Here's the library on GitHub, I hope you find it useful:
https://github.com/orderly/codeigniter-paypal-ipn
Below is the unmodified code that i used with Ran's library.
Hope it helps.
<?php
/**
* PayPal_Lib Controller Class (Paypal IPN Class)
*
* Paypal controller that provides functionality to the creation for PayPal forms,
* submissions, success and cancel requests, as well as IPN responses.
*
* The class requires the use of the PayPal_Lib library and config files.
*
* #package CodeIgniter
* #subpackage Libraries
* #category Commerce
* #author Ran Aroussi <ran#aroussi.com>
* #copyright Copyright (c) 2006, http://aroussi.com/ci/
*
*/
class Paypal extends Controller
{
function Paypal()
{
parent::Controller();
$this->load->library('Paypal_Lib');
}
function index()
{
$this->form();
}
function form()
{
$this->paypal_lib->add_field('business', 'herrka_1245670546_biz#pandorascode.com');
$this->paypal_lib->add_field('return', site_url('paypal/success') );
$this->paypal_lib->add_field('cancel_return', site_url('paypal/cancel') );
$this->paypal_lib->add_field('notify_url', site_url('paypal/ipn') ); // <-- IPN url
$this->paypal_lib->add_field('custom', '470874552'); // <-- Verify return
$this->paypal_lib->add_field('item_name', 'Paypal Test Transaction');
$this->paypal_lib->add_field('item_number', '5');
$this->paypal_lib->add_field('amount', '9.95');
// if you want an image button use this:
$this->paypal_lib->image('button_03.gif');
// otherwise, don't write anything or (if you want to
// change the default button text), write this:
// $this->paypal_lib->button('Click to Pay!');
$data['paypal_form'] = $this->paypal_lib->paypal_form();
$this->load->view('paypal/form', $data);
}
function cancel()
{
$this->load->view('paypal/cancel');
}
function success()
{
//$data['pp_info'] = $this->input->post();
$data['pp_info'] = $_POST; //FIX?
$this->load->view('paypal/success', $data);
}
function ipn()
{
$ipn_valid = $this->paypal_lib->validate_ipn();
if ( $ipn_valid == TRUE )
{
/**
Log IPN
TODO: bunu daha guzel gozukecek sekilde yapayim ilerde.
**/
date_default_timezone_set('Europe/Istanbul');
$this->load->helper('date');
$raw = '';
foreach ($this->paypal_lib->ipn_data as $key=>$value)
{
$raw .= "\n$key: $value";
}
$this->load->model('model_paypal');
$data_ipn['user_id'] = $this->paypal_lib->ipn_data['custom']; /* get USER_ID from custom field. */
$data_ipn['txn_id'] = $this->paypal_lib->ipn_data['txn_id'];
$data_ipn['payment_status'] = $this->paypal_lib->ipn_data['payment_status'];
$data_ipn['mc_gross'] = $this->paypal_lib->ipn_data['mc_gross'];
$data_ipn['mc_fee'] = $this->paypal_lib->ipn_data['mc_fee'];
$data_ipn['mc_currency'] = $this->paypal_lib->ipn_data['mc_currency'];
$data_ipn['item_number'] = $this->paypal_lib->ipn_data['item_number'];
$data_ipn['datetime'] = mdate( "%Y-%m-%d %H:%i:%s" );
$data_ipn['status'] = IPN_ENTRY_AWAITING;
$data_ipn['raw'] = $raw;
$this->model_paypal->ipn_entry_add ( $data_ipn );
$ipn_payment_status = $this->paypal_lib->ipn_data['payment_status'];
if ( strtolower($ipn_payment_status) == 'pending' )
{
log_message('debug', 'payment status TAMAM');
$this->load->model('model_user_premium');
$ipn_item_number = $this->paypal_lib->ipn_data['item_number'];
$item_info = $this->model_user_premium->Premium_item_info ( $ipn_item_number );
$ipn_mc_gross = $this->paypal_lib->ipn_data['mc_gross'];
log_message('debug', 'Item fee: '. $item_info['item_fee'] );
if ( $item_info['item_fee'] == $ipn_mc_gross )
{
log_message('debug', 'fee ile gross TAMAM');
$data_account['user_id'] = $data_ipn['user_id'];
$data_account['type'] = $item_info['item_type'];
$data_account['date_expire'] = date("Y-m-d", mktime(0, 0, 0, date("m") + $item_info['date_extender'], date("d"), date("y") ) );
log_message('debug', 'UserID: '. $data_account['user_id'] );
log_message('debug', 'Type:'. $data_account['type'] );
log_message('debug', 'Expire:'. $data_account['date_expire'] );
$this->model_user_premium->Premium_membership_change( $data_ipn['user_id'], $data_account );
}
else
{
//TODO: report eksik transaction.
}
}
}
elseif ( $ipn_valid == FALSE )
{
$this->load->library('email');
$this->email->to( 'demo#demo.com' );
$this->email->subject('IPN - FAILED');
$this->email->from( 'notify#bulusturx.com', 'PAYPAL' );
$this->email->message('or 4 life');
$this->email->send();
}
}
function ipn_list()
{
//TODO: admin check
$this->load->helper('form');
$this->load->model('model_theme');
switch ( $_SERVER['REQUEST_METHOD'] )
{
case 'GET':
/* Theme System with Reference Variable ( first param ) */
$this->model_theme->Theme_returnThemeInfo( $data, 'paypal' );
$this->load->view( $data['theme_folder_vault'] . 'master-ipn_list', $data );
break;
case 'POST':
$this->load->model('model_paypal');
$user_id = $this->input->post('user_id');
$txn_id = $this->input->post('txn_id');
$list_ipn = $this->model_paypal->ipn_entry_list ( $user_id, $txn_id );
echo '<pre>';
print_r( $list_ipn );
echo '</pre>';
break;
default:
break;
}
}
function ipn_test()
{
$this->load->model('model_user_premium');
$data_account['user_id'] = 123;
$data_account['type'] = 4;
$data_account['date_expire'] = date("Y-m-d", mktime(0, 0, 0, date("m") + 12, date("d"), date("y") ) );
echo '<pre>';
print_r( $data_account );
echo '</pre>';
$this->model_user_premium->Premium_membership_change( 123, $data_account );
}
}
?>
Here's a paypal library from Jamie Rumbelow that I've been using with minor tweaks:
http://bitbucket.org/jamierumbelow/codeigniter-paypal/src

Categories