How to Create a Recurring Payments Profile with Express Checkout - codeigniter

I'm currently integrating the paypal recurring payment process in my website. i used this code
function process()
{
include_once("config.php");
include_once("paypal.class.php");
if($_POST) //Post Data received from product list page.
{
//Mainly we need 4 variables from an item, Item Name, Item Price, Item Number and Item Quantity.
$ItemName = $_POST["itemname"]; //Item Name
$ItemPrice = $_POST["itemprice"]; //Item Price
$ItemNumber = $_POST["itemnumber"]; //Item Number
$ItemQty = $_POST["itemQty"]; // Item Quantity
$ItemTotalPrice = ($ItemPrice*$ItemQty); //(Item Price x Quantity = Total) Get total amount of product;
//Data to be sent to paypal
$padata = '&CURRENCYCODE='.urlencode($PayPalCurrencyCode).
'&PAYMENTACTION=Sale'.
'&ALLOWNOTE=1'.
'&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($PayPalCurrencyCode).
'&PAYMENTREQUEST_0_AMT='.urlencode($ItemTotalPrice).
'&PAYMENTREQUEST_0_ITEMAMT='.urlencode($ItemTotalPrice).
'&L_PAYMENTREQUEST_0_QTY0='. urlencode($ItemQty).
'&L_PAYMENTREQUEST_0_AMT0='.urlencode($ItemPrice).
'&L_PAYMENTREQUEST_0_NAME0='.urlencode($ItemName).
'&L_PAYMENTREQUEST_0_NUMBER0='.urlencode($ItemNumber).
'&AMT='.urlencode($ItemTotalPrice).
'&L_BILLINGTYPE0='.urlencode('RecurringPayments').
'&L_BILLINGAGREEMENTDESCRIPTION0='.urlencode('message plan').
'&RETURNURL='.urlencode($PayPalReturnURL ).
'&CANCELURL='.urlencode($PayPalCancelURL);
//We need to execute the "SetExpressCheckOut" method to obtain paypal token
$paypal= new MyPayPal();
$httpParsedResponseAr = $paypal->PPHttpPost('SetExpressCheckout', $padata, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);
//Respond according to message we receive from Paypal
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
// If successful set some session variable we need later when user is redirected back to page from paypal.
$_SESSION['itemprice'] = $ItemPrice;
$_SESSION['totalamount'] = $ItemTotalPrice;
$_SESSION['itemName'] = $ItemName;
$_SESSION['itemNo'] = $ItemNumber;
$_SESSION['itemQTY'] = $ItemQty;
if($PayPalMode=='sandbox')
{
$paypalmode = '.sandbox';
}
else
{
$paypalmode = '';
}
//Redirect user to PayPal store with Token received.
$paypalurl ='https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';
header('Location: '.$paypalurl);
}else{
//Show error message
echo '<div style="color:red"><b>Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
echo '<pre>';
print_r($httpParsedResponseAr);
echo '</pre>';
}
}
//Paypal redirects back to this page using ReturnURL, We should receive TOKEN and Payer ID
if(isset($_GET["token"]) && isset($_GET["PayerID"]))
{
//we will be using these two variables to execute the "DoExpressCheckoutPayment"
//Note: we haven't received any payment yet.
$token = $_GET["token"];
$playerid = $_GET["PayerID"];
//get session variables
$ItemPrice = $_SESSION['itemprice'];
$ItemTotalPrice = $_SESSION['totalamount'];
$ItemName = $_SESSION['itemName'];
$ItemNumber = $_SESSION['itemNo'];
$ItemQTY =$_SESSION['itemQTY'];
$padata = '&TOKEN='.urlencode($token).
'&PAYERID='.urlencode($playerid).
'&PAYMENTACTION='.urlencode("SALE").
'&AMT='.urlencode($ItemTotalPrice).
'&CURRENCYCODE='.urlencode($PayPalCurrencyCode).
'&NOTIFYURL='.urlencode('http://mywebiste.com/listner');
//We need to execute the "DoExpressCheckoutPayment" at this point to Receive payment from user.
$paypal= new MyPayPal();
$httpParsedResponseAr = $paypal->PPHttpPost('DoExpressCheckoutPayment', $padata, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);
//Check if everything went ok..
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
echo '<h2>Success</h2>';
echo 'Your Transaction ID :'.urldecode($httpParsedResponseAr["TRANSACTIONID"]);
/*
//Sometimes Payment are kept pending even when transaction is complete.
//May be because of Currency change, or user choose to review each payment etc.
//hence we need to notify user about it and ask him manually approve the transiction
*/
if('Completed' == $httpParsedResponseAr["PAYMENTSTATUS"])
{
echo '<div style="color:green">Payment Received! Your product will be sent to you very soon!</div>';
}
elseif('Pending' == $httpParsedResponseAr["PAYMENTSTATUS"])
{
echo '<div style="color:red">Transaction Complete, but payment is still pending! You need to manually authorize this payment in your <a target="_new" href="http://www.paypal.com">Paypal Account</a></div>';
}
echo '<br /><b>Stuff to store in database :</b><br /><pre>';
$transactionID = urlencode($httpParsedResponseAr["TRANSACTIONID"]);
$nvpStr = "&TRANSACTIONID=".$transactionID;
$paypal= new MyPayPal();
$httpParsedResponseAr = $paypal->PPHttpPost('GetTransactionDetails', $nvpStr, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
$nvpstr="&TOKEN=".$_GET['token'];
$nvpstr.="&BILLINGPERIOD=Month";
$nvpstr.="&BILLINGFREQUENCY=1";
$nvpstr.="&AMT=1";
$nvpstr.="&CURRENCYCODE=USD";
$nvpstr.="&COUNTRYCODE=US";
$nvpstr.="&PAYERID=".$httpParsedResponseAr['PAYERID'];
$nvpstr.="&PROFILESTARTDATE=".date('Y-m-d');
$recurr = $paypal->PPHttpPost('CreateRecurringPaymentsProfile',$nvpStr,$PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode);
echo '<pre>';
print_r($httpParsedResponseAr);
echo '</pre>';
print_r($recurr);
} else {
echo '<div style="color:red"><b>GetTransactionDetails failed:</b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
echo '<pre>';
print_r($httpParsedResponseAr);
echo '</pre>';
}
}else{
echo '<div style="color:red"><b>Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
echo '<pre>';
print_r($httpParsedResponseAr);
echo '</pre>';
}
}
}
i am getting token and payer id etc . its all working fine. but when i try to create recurring profile iam getting this response
Array
(
[TIMESTAMP] => 2013%2d03%2d18T05%3a32%3a06Z
[CORRELATIONID] => 912b6004f40bb
[ACK] => Failure
[VERSION] => 76%2e0
[BUILD] => 5294323
[L_ERRORCODE0] => 11585
[L_ERRORCODE1] => 11518
[L_ERRORCODE2] => 11516
[L_ERRORCODE3] => 11519
[L_ERRORCODE4] => 11549
[L_SHORTMESSAGE0] => Missing%20Token%20or%20payment%20source
[L_SHORTMESSAGE1] => Invalid%20billing%20period%2e
[L_SHORTMESSAGE2] => Invalid%20billing%20frequency
[L_SHORTMESSAGE3] => Invalid%20amount
[L_SHORTMESSAGE4] => Start%20Date%20is%20required
[L_LONGMESSAGE0] => Missing%20Token%20or%20buyer%20credit%20card
[L_LONGMESSAGE1] => Billing%20period%20must%20be%20one%20of%20Day%2c%20Week%2c%20SemiMonth%2c%20or%20Year
[L_LONGMESSAGE2] => Billing%20frequency%20must%20be%20%3e%200%20and%20be%20less%20than%20or%20equal%20to%20one%20year
[L_LONGMESSAGE3] => Bill%20amount%20must%20be%20greater%20than%200
[L_LONGMESSAGE4] => Subscription%20start%20date%20is%20required
[L_SEVERITYCODE0] => Error
[L_SEVERITYCODE1] => Error
[L_SEVERITYCODE2] => Error
[L_SEVERITYCODE3] => Error
[L_SEVERITYCODE4] => Error
)
i dont know where i did wrong in this.
thank you.

Your request is missing a bunch of parameters which are required to create a recurring payment profile. Please refer to https://www.x.com/developers/paypal/documentation-tools/express-checkout/integration-guide/ECRecurringPayments.

I think the procedure is wrong: the second call should be a GetExpressCheckoutDetails to retrive the PAYERID in order to be able to do a CreateRecurringPaymentsProfile.
Just follow this tutorial step by step:
https://www.x.com/developers/paypal/documentation-tools/express-checkout/how-to/ht_ec-recurringPaymentProfile-curl-etc

Related

Code Issue when clicks "Return to Merchant" Button of Paypal

I am using Codeigniter to integrate the PayPal payment gateway on my website.
//This is my buy method
public function buy($id){
$course = $this->course_model->fetch_course_details_for_buy($id);
$returnURL = base_url().'paypal/success'; //payment success url
$cancelURL = base_url().'paypal/cancel'; //payment cancel url
$notifyURL = base_url().'paypal/ipn'; //ipn url
$userID = $this->session->userdata('student_id'); //current user id
$_SESSION['course_id'] = $course->course_id;
$logo = base_url().'assets/images/test-logo.png';
$this->paypal_lib->add_field('return', $returnURL);
$this->paypal_lib->add_field('cancel_return', $cancelURL);
$this->paypal_lib->add_field('notify_url', $notifyURL);
$this->paypal_lib->add_field('item_name', $course->title);
$this->paypal_lib->add_field('custom', $userID);
$this->paypal_lib->add_field('item_number', $course->course_id);
$this->paypal_lib->add_field('amount', $course->amount);
$this->paypal_lib->image($logo);
$this->paypal_lib->paypal_auto_form();
}
This is my PayPal's class method of success
function success(){
//get the transaction data
$paypalInfo = $this->input->get();
$data['item_number'] = $paypalInfo['item_number'];
$data['txn_id'] = $paypalInfo["tx"];
$data['payment_amt'] = $paypalInfo["amt"];
$data['currency_code'] = $paypalInfo["cc"];
$data['status'] = $paypalInfo["st"];
//pass the transaction data to view
$this->load->view('paypal/success', $data);
}
This is my IPN method
function ipn(){
//paypal return transaction details array
$paypalInfo = $this->input->post();
$data['user_id'] = $paypalInfo['custom'];
$data['product_id'] = $paypalInfo["item_number"];
$data['txn_id'] = $paypalInfo["txn_id"];
$data['payment_gross'] = $paypalInfo["mc_gross"];
$data['currency_code'] = $paypalInfo["mc_currency"];
$data['payer_email'] = $paypalInfo["payer_email"];
$data['payment_status'] = $paypalInfo["payment_status"];
$paypalURL = $this->paypal_lib->paypal_url;
$result = $this->paypal_lib->curlPost($paypalURL,$paypalInfo);
//check whether the payment is verified
if(preg_match("/VERIFIED/i",$result)){
//insert the transaction data into the database
$this->product->insertTransaction($data);
}
}
My payment is successful done from the sandbox account. But When I click the return to merchant button after payment it's throwing error of undefined indexes as mention in the success method. I apply first a time payment gateway and don't know what is missing in my code. Any help is appreciable.
You should log what $paypalInfo contains.
If you have enabled PDT, information may be coming as a POST rather than a GET.
In any case, make your code be able to check for and handle the missing data/indices or put it in a try/catch equivalent; it should not error.

Import Profile Product Review import/export

I'm using Magento extension https://www.magentocommerce.com/magento-connect/product-review-import-export.html for importing prodcuts review.
I've exported review from one Magento site and I'm trying to import on another website.
While importing products it's show message "Processed 0% 0/1 records" and keep it showing, No process in importing products.
Importing Preview
I've changed my table prefix in "app/code/local/MK/Reviewexport/Model/Convert/Adapter/Reviewimport.php" but still nothing happening.
Waited too long but it keep showing me "Processed 0% 0/1 records" I've too many reviews and so it was not working I've removed all reviews from CSV and kept only one review.
This extension is created by : https://magento.stackexchange.com/users/599/mufaddal
Anyways I've resolved the issue by making custom script for importing reviews which is exported by that mentioned extension.
Here is a code
<?php
ini_set('memory_limit', '128M');
error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once 'app/Mage.php';
Mage::app();
$fileLocation = "var/import/import_review.csv";
$fp = fopen($fileLocation, 'r');
$count = 1;
while($data = fgetcsv($fp)){
if($count > 1){
//intiate requirement varibles
$_createdAt = $data[0];
$_sku = $data[1];
$_catalog = Mage::getModel('catalog/product');
$_productId = $_catalog->getIdBySku($_sku);
$_statusId = $data[2];
$_title = $data[3];
$_detail = $data[4];
$_customerId = NULL;
$_nickname = $data[5];
//load magento review model and assign values
$review = Mage::getModel('review/review');
$review->setCreatedAt($_createdAt); //created date and time
$review->setEntityPkValue($_productId);//product id
$review->setStatusId($_statusId); // status id
$review->setTitle($_title); // review title
$review->setDetail($_detail); // review detail
$review->setEntityId(1); // leave it 1
$review->setStoreId(Mage::app()->getStore()->getId()); // store id
$review->setCustomerId($_customerId); //null is for administrator
$review->setNickname($_nickname); //customer nickname
$review->setReviewId($review->getId());//set current review id
$review->setStores(array(Mage::app()->getStore()->getId()));//store id's
$review->save();
$review->aggregate();
//set review ratings
if($data[7]){
$arr_data = explode("#",$data[7]);
if(!empty($arr_data)) {
foreach($arr_data as $each_data) {
$arr_rating = explode(":",$each_data);
if($arr_rating[1] != 0) {
Mage::getModel('rating/rating')
->setRatingId($arr_rating[0])
->setReviewId($review->getId())
->setCustomerId($_customerId)
->addOptionVote($arr_rating[1], $_productId);
}
}
}
$review->aggregate();
}
}
// if($count == 5){
// die("total $count reviews are imported!");
// }
$count++;
}
echo "total $count reviews are imported!";
?>

Adding step to Magento onepage checkout process

I am try to create an additional step in the Magento onepage checkout process.
I am following the tutorial located at http://www.excellencemagentoblog.com/magento-onestep-checkout-add-step but specifically adding a step at the end before the review.
My folder / file structure is as follows. (Ignore widget.xml)
I have uploaded the code in it's current state to this gist:
https://gist.github.com/Relequestual/5263498
I have the theme set to 'new'.
I am var_dumping the $this->getSteps() which shows that the 'testcheck' returns null.
In config.xml, if I change under gobal, blocks, checkout, rewrite, onepage to the same class with '_TestCheck' on the end, the checkout doesn't display at all, but 'Test Check' appears in the progress section on the right. When I revert this change, it then shows as not being null in the var dump like so...
But, I still don't see the step actually added to the page.
I've not done any magento before, so feel a bit in over my head. I expect there is some problem with the xml configuration files, but I've been working on this for 2 days now, and am somewhat lost as to what else I can try.
I know this question may sound similar to others, which it is, however I can't find a question where the OP has the same symptoms as what I am seeing.
By default magento gives some checkout steps. But Sometime you need to add extra information from the customer for future reference. A common requested customization is to add the Custom Form in default checkout process.
This is not good practice to touch core files. You can do this via overriding Modules.
In this example Comapnyname is Ipragmatech and Module name is Checkoutstep.
Step1: Add Custom step in the checkout process
Open the Ipragmatech > Checkoutstep > Block > Onepage> Checkoutstep.php file and write the following code
class Ipragmatech_Checkoutstep_Block_Onepage_Checkoutstep extends Mage_Checkout_Block_Onepage_Abstract
{
protected function _construct()
{
$this->getCheckout()->setStepData('checkoutstep', array(
'label' => Mage::helper('checkout')->__('Invitation to participation'),
'is_show' => true
));
parent::_construct();
}
}
Step2: Add steps which and where you want in the checkout process
Open the Ipragmatech > Checkoutstep > Block > Onepage> Checkoutstep.php file and write the following code
class Ipragmatech_Checkoutstep_Block_Onepage extends Mage_Checkout_Block_Onepage
{
public function getSteps()
{
$steps = array();
if (!$this->isCustomerLoggedIn()) {
$steps['login'] = $this->getCheckout()->getStepData('login');
}
$stepCodes = array('billing', 'shipping', 'shipping_method', 'payment', 'checkoutstep', 'review');
foreach ($stepCodes as $step) {
$steps[$step] = $this->getCheckout()->getStepData($step);
}
return $steps;
}
}
Step3: Grab the submitted value of custom form and set the values of Custom form
Open the ipragmatech > Checkoutstep > controllers > OnepageController.php and write the following fucntion
public function saveCheckoutstepAction()
{
$this->_expireAjax();
if ($this->getRequest()->isPost()) {
//Grab the submited value
$_entrant_name = $this->getRequest()->getPost('entrant_name',"");
$_entrant_phone = $this->getRequest()->getPost('entrant_phone',"");
$_entrant_email = $this->getRequest()->getPost('entrant_email',"");
$_permanent_address = $this->getRequest() ->getPost('permanent_address',"");
$_address = $this->getRequest()->getPost('local_address',"");
Mage::getSingleton('core/session') ->setIpragmatechCheckoutstep(serialize(array(
'entrant_name' =>$_entrant_name,
'entrant_phone' =>$_entrant_phone,
'entrant_email' =>$_entrant_email,
'permanent_address' =>$_permanent_address,
'address' =>$_address
)));
$result = array();
$redirectUrl = $this->getOnePage()->getQuote()->getPayment() ->getCheckoutRedirectUrl();
if (!$redirectUrl) {
$this->loadLayout('checkout_onepage_review');
$result['goto_section'] = 'review';
$result['update_section'] = array(
'name' => 'review',
'html' => $this->_getReviewHtml()
);
}
if ($redirectUrl) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Zend_Json::encode($result));
}
}
Step4: Save Custom Form information
When checkout_onepage_controller_success_action
event hook is called. Open the Ipragmatech > Checkoutstep > Model >Observer.php and write the following
class Ipragmatech_Checkoutstep_Model_Observer {
const ORDER_ATTRIBUTE_FHC_ID = 'checkoutstep';
public function hookToOrderSaveEvent() {
if (Mage::helper('checkoutstep')->isEnabled()) {
$order = new Mage_Sales_Model_Order ();
$incrementId = Mage::getSingleton ( 'checkout/session' )->getLastRealOrderId ();
$order->loadByIncrementId ( $incrementId );
// Fetch the data
$_checkoutstep_data = null;
$_checkoutstep_data = Mage::getSingleton ( 'core/session' )->getIpragmatechCheckoutstep ();
$model = Mage::getModel ( 'checkoutstep/customerdata' )->setData ( unserialize ( $_checkoutstep_data ) );
$model->setData ( "order_id",$order["entity_id"] );
try {
$insertId = $model->save ()->getId ();
Mage::log ( "Data successfully inserted. Insert ID: " . $insertId, null, 'mylog.log');
} catch ( Exception $e ) {
Mage::log ( "EXCEPTION " . $e->getMessage (), null, 'mylog.log' );
}
}
}
}
Magento – Add Custom Form in Checkout Extension is a complete solution to add extra step in Checkout process for your ecommerce website. It allow admin to export data from custom table in CSV format.
Visit the link to get this free extension http://www.magentocommerce.com/magento-connect/custom-form-in-checkout.html

Magento : Display html element based on product attribute set?

I wish to display a static block on the product page if the product belongs to a certain Attribute Set
For example if I was a fashion store, and I have an attribute set of "Footwear" I only want the static block to show on product pages when the attribute set matches "Footwear"
I have found a little bit of code that outputs the ID of the Attribute set but I want to turn it into an else if statement.
<?php
$entityTypeId = Mage::getModel('eav/entity')
->setType('catalog_product')
->getTypeId();
$attributeSetName = 'Footwear';
$attributeSetId = Mage::getModel('eav/entity_attribute_set')
->getCollection()
->setEntityTypeFilter($entityTypeId)
->addFieldToFilter('attribute_set_name', $attributeSetName)
->getFirstItem()
->getAttributeSetId();
echo $attributeSetId;
?>
Anyone have any ideas?
G
Add this method to the Product View Block
(not to core file app/code/core/Mage/Catalog/Block/Product/View.php of course):
public function checkAttributeSet($product = null, $attributeSetName = null)
{
if(is_null($product) || is_null($attributeSetName))
return false;
$attributeSetModel = Mage::getModel("eav/entity_attribute_set");
$attributeSetModel->load($product->getAttributeSetId());
if($attributeSetModel->getAttributeSetName() == $attributeSetName) {
return true;
} else {
return false;
}
}
Then in app/design/frontend/package/theme/template/catalog/product/view.phtml:
if($this->checkAttributeSet($_product, 'Monitors')):
echo $this->getLayout()->createBlock('cms/block')->setBlockId('monitor')->toHtml();
elseif($this->checkAttributeSet($_product, 'Footwear')):
echo $this->getLayout()->createBlock('cms/block')->setBlockId('footwear')->toHtml();
endif;
FOR THE ADMINS WHO DELETE USEFUL INFORMATION FOR POINTS ON STACKOVERFLOW >>>> 3rd time replying to this post with updated material ya know just incase someone stumbles on this thread.
This is the updated magento 2.3 way of completing this task.
Add code to
module-catalog/view/frontend/templates/product/view
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$attributeSet = $objectManager->create('Magento\Eav\Api\AttributeSetRepositoryInterface');
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($_product->getId());
$attributeSetRepository = $attributeSet->get($product->getAttributeSetId());
$attribute_set_name = $attributeSetRepository->getAttributeSetName();
//$attribute_set_name_arr[] = $attribute_set_name;
//echo '<pre>'; print_r($attribute_set_name);
if( !empty($attribute_set_name) && $attribute_set_name == 'Rc' ) {
// echo $this->getLayout()
->createBlock('Magento\Cms\Block\Block')
->setBlockId('rcitems')
->toHtml();
}
?>
setBlockId = The Identifier of the block in admin.
Rc = is the attribute set
no need to add to default.xml

Sandbox Paypal Money Deduction Issues

My code:
function paiement_echec()
{
echo "payment cancelled by the user";
}
function paiement_succes()
{
// Obtain the token from PayPal.
if(!array_key_exists('token', $_REQUEST))
exit('Token is not received.');
// Set request-specific fields.
$token = urlencode(htmlspecialchars($_REQUEST['token']));
// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = $this->PPHttpPost('GetExpressCheckoutDetails', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
//print_r($httpParsedResponseAr);
$payerID = urlencode($httpParsedResponseAr["PAYERID"]);
//$token = urlencode("token");
$paymentType = urlencode('Sale'); // or 'Sale' or 'Order'
$paymentAmount = urlencode("4.39");
$currencyID = urlencode("USD"); // or other currency code ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token&PAYERID=$payerID&PAYMENTACTION=$paymentType&AMT=$paymentAmount&CURRENCYCODE=$currencyID";
$httpParsedResponseAr = $this->PPHttpPost('DoExpressCheckoutPayment', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
$this->load->model('payment_model');
$this->payment_model->paypal_payment();
$msg = "<label>Thank you !! your payment is successfully done</label>
<a href='".base_url()."envoie_de_photos/envoyer_vos_photos"."'>Go To Photo Uploading</a>";
echo $msg;
}
else
{
exit('GetExpressCheckoutDetails failed: ' . print_r($httpParsedResponseAr, true));
//echo "Payment failed for unknown reason";
}
}
else
{
//exit('GetExpressCheckoutDetails failed: ' . print_r($httpParsedResponseAr, true));
echo "Payment failed for unknown reason";
}
}
function pay_by_paypal()
{
$environment = 'sandbox';
$_SESSION['item_name']=$this->input->post('item_name');
$_SESSION['amount']=$this->input->post('amount');
$_SESSION['currency_code']=$this->input->post('currency_code');
$_SESSION['no_of_photo']=$this->input->post('no_of_photo');
$qty=urlencode("1");
$product_name=urldecode($_SESSION['item_name']);
$price=urlencode($_SESSION['amount']);
//$currencyID = urlencode($_SESSION['currency_code']);
$currencyID = urlencode("USD");
// or other currency code ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
$paymentType = urlencode('Order');
$nvpStr="";
$returnURL = (base_url()."paiement/paiement_succes");
$cancelURL = (base_url()."paiement/paiement_echec");
$i=0;
$total_amount=0;
$str = "&METHOD=SetExpressCheckout
&RETURNURL=$returnURL
&CANCELURL=$cancelURL
&L_PAYMENTREQUEST_0_NAME0=$product_name
&L_PAYMENTREQUEST_0_NUMBER0=$qty
&L_PAYMENTREQUEST_0_AMT0=$price
&L_PAYMENTREQUEST_0_DESC0=$product_name
&PAYMENTREQUEST_0_AMT=$price
&PAYMENTREQUEST_0_PAYMENTACTION=$paymentType
&PAYMENTREQUEST_0_CURRENCYCODE=$currencyID";
$nvpStr=$nvpStr.$str;
$httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
// Redirect to paypal.com.
$token = urldecode($httpParsedResponseAr["TOKEN"]);
$payPalURL = "https://www.$environment.paypal.com/webscr&cmd=_express-checkout&token=$token";
if("sandbox" === $environment)
{
$payPalURL = "https://www.$environment.paypal.com/webscr&cmd=_express-checkout&token=$token";
}
header("Location: $payPalURL");
exit;
}
else
{
exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
}
}
/** SetExpressCheckout NVP example; last modified 08MAY23.
*
* Initiate an Express Checkout transaction.
*/
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
private function PPHttpPost($methodName_, $nvpStr_) {
//global $environment;
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode('saswat_1360720799_biz_api1.gmail.com');
$API_Password = urlencode('1360720821');
$API_Signature = urlencode('ApDCeFez-N1Gd1-O3ubTGdpyiow4AlNlRemm8XJFcbsA.WbSMtlMSqHf');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment) {
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('65.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
I have three accounts in the Paypal sandbox: two business and one personal. All of my Paypal accounts have USD as default currency.
In the above code I was using EUR as a currency.
When I am carrying out transaction, if I am paying from my personal (buyer) account in EUR, then my buyer account is getting money deducted (equivalent amount of USD is getting subtracted from my buyer account). This is totally fine, there is no issue with that.
The problem is that no amount is getting added to my business or (seller) account.
I found a post on Stack Overflow that reads:
if the currencycode of the transaction and the seller account doesnt
match, then money doesnt get aded to sellers account
I changed the euro to USD, (since my sandbox seller test account is in USD) and found out that, after converting it into USD, then my money is getting added to my seller account.
Is this a problem with the sandbox only, or does it apply to live paypal as well?
I have a site where buyers can pay in GBP, EUR, MYN, SGD, AUD.
If the transaction needs to be carried out in particular currency, that is the currency set as per the seller account, then there's no need to use different currencies.
Since the currencyCode which is passed in SetExpressCheckOut should match with the DoExpressCheckout, and as I have faced problem, currencyCode needs to be same as that of sandbox seller account, so even if buyers are selecting GBP, I have to send it to SetExpressCheckout as the currencyCode of the seller account.
You should add the currencies you would like to receive payments in through the control panel of your business account in question.
Go to Profile -> My Settings -> Financial Information tab and Currency Balances. From there select a currency and add it to the list. Your received payments are then kept in the respective currency balance they were made until you convert them to whatever you want.
By default, transactions that take place in a currency you don't hold are held until you decide what to do with them. If you log into the seller account in question, you should see the transaction listed under your history. You should be able to accept it or deny it from there.
There are two ways around this:
Add Euros as a currency balance to your seller's account, as Alderis noted.
Have all transactions that take place in a currency you don't hold automatically accepted and converted to USD. To do this, log into the seller's account, click on Profile, then click on Payment Receiving Preferences (in the Selling preferences column), then set Block payments sent to me in a currency I do not hold to No, accept them and convert them to U.S. Dollars, then click Save.

Resources