I am currently testing an online store using a custom cart within paypal sandbox.
I am able to go trough all transcation steps properly
setExpressCheckout-> pay -> DoExpressCheckout.
During the DoExpressCheckout step I think it would be the good time to update my database with the order. For that I use the GetExpressCheckoutDetails function to retrieve the content of the transaction.
Sadly this function return everything paypal has to offer but miss the content of my cart. All i can get is the detail of one item. If the transaction involve multiple items i would only get the details of the first one.
Here is my code (mostly taken from paypal samples) :
$token =urlencode( $_REQUEST['token']);
$payerId=urlencode( $_REQUEST['PayerID']);
$getExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType($token);
$getExpressCheckoutReq = new GetExpressCheckoutDetailsReq();
$getExpressCheckoutReq->GetExpressCheckoutDetailsRequest = $getExpressCheckoutDetailsRequest;
$paypalService = new PayPalAPIInterfaceServiceService();
$getECResponse = $paypalService->GetExpressCheckoutDetails($getExpressCheckoutReq);
$details = $getECResponse->GetExpressCheckoutDetailsResponseDetails;
// $details->PaymentDetails->PaymentDetailsItem this array should hold all items details
// sadly it always have 1 element instead of the full content of my cart :(
$orderTotal = $details->PaymentDetails->OrderTotal;
$PaymentDetails= new PaymentDetailsType();
$PaymentDetails->OrderTotal = $orderTotal;
//
Some stuff with payment details
//
$DoECRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType();
$DoECRequest = new DoExpressCheckoutPaymentRequestType();
$DoECRequest->DoExpressCheckoutPaymentRequestDetails = $DoECRequestDetails;
$DoECReq = new DoExpressCheckoutPaymentReq();
$DoECReq->DoExpressCheckoutPaymentRequest = $DoECRequest;
$DoECResponse = $paypalService->DoExpressCheckoutPayment($DoECReq);
Do i miss a step or call a bad function. Because i tried to print_r every variable i came across and the full content of my cart was nowhere to be found. I find this strange since the 'orderTotal' of the transaction match with my original cart. I could store my original order during the SetExpressCheckout step but since paypal already have those values i find it redundant.
As a last resort I did found the content of my cart using $paypalService->getLastRequest() but seriously this is the raw XML returned by paypal and the api should be parsing it properly :(.
Thanks for reading
I had this exact same issue - while the XML returned by PayPal is fine, their PHP SDK doesn't parse it properly, so you can only ever see the last item in GetExpressCheckout.
I've posted a fix for this problem in an issue on PayPal's GitHub, please check it out:
https://github.com/paypal/SDKs/issues/37
Related
I am using Paypal IPN
I have written a script that works fine with the Web Accept transaction type when used with the simulator. I get the variables back and process them etc However when I switch the transaction type to express checkout it stops working. Can anyone help me figure out why?
My code is in PHP
The question is sort of old, but in case others land on this page with the same problem... If you're using the IPN Listener code from the official PayPal Developer site, you probably still have some code in there that's expecting specific form POST items, and that's the problem. Those items do not exist in the IPN Simulator's Express Checkout messages. Here's the problematic code:
// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
The Express Checkout form post will not have item_name nor item_number, but it will have item_name1 and item_number1. So, a good solution would be to take out all those lines of code, in that section, that specify form field names, and instead iterate through all the form fields. In the loop, you can test for existence of expected items, if needed. Or, if you just want to do something with the full set of form items, you could do that, like this:
foreach($_POST as $key => $value) {
$strOutput .= $key . " = " . $value . "|";
}
FYI... The problematic code was found here:
https://developer.paypal.com/docs/classic/ipn/ht_ipn/
...and here:
https://gist.github.com/xcommerce-gists/3440401#file-completelistener-php
I am using a paypal ipn script i found here
http://coderzone.org/library/PHP-PayPal-Instant-Payment-Notification-IPN_1099.htm
I am aware that I can send information to paypal and get a response. It states I can get the information back using $_POST . My query is how do I specify the UK currency?
Also wanted to clarify a minor point. Am I correct that this is how i can confirm it was a success.
if ($_POST['payment_status'] == 'completed')
// Received Payment!
// $_POST['custom'] is order id and has been paid for.
}
This might be a little late for you sorry, but just in case - I currently use "currencyCode" = > "AUD" and it is working in the sandbox.
There's a full list of the currency codes available at PayPal
For yours, I'm guessing it would be:
$p->add_field('currencyCode', 'GBP');
As for your question about the IPN itself, it looks like you're on the right track. It will depend on the data you're getting back and whether you're interested in the individual transactions (if using adaptive payments) or if you're reversing them all on error etc. The easiest way to determine what you'll need to do is to simply display or log all the post data so you can see how it's constructed.
You'll also need to set it up so that the script is accessible by PayPal. You'll then pass the full URL of this script to the "notify_url" parameter and send it off to PayPal. Once the payment has completed PayPal will send a bunch of information to your script so that you can process it.
Unfortunately I'm not from a PHP background so I can't give you the exact code you'll need. Also note that there are a lot of security issues that you'll want to look into before going to a production environment. Not sure if you already intend to do this with that validateIPN function, but you need to ensure that you can tell whether it comes from PayPal and not a malicious user. One way would be to pass a value using the custom attribute and have PayPal pass this back to you, however you'd be much better off using the API certificates etc.
If you haven't already, it may be worth checking out a few of the sample applications PayPal has done up, there seem to be quite a few PHP ones.
Let me know if you need anything else,
Use this, it works for me
$p->add_field('currency_code', 'GBP');
You need to use PayPal Adaptive Payments, IPN wouldn't help.
PayPal Adaptive Payments
Using PayPal PHP library then it could look like this:
// Create an instance, you'll make all the necessary requests through this
// object, if you digged through the code, you'll notice an AdaptivePaymentsProxy class
// wich has in it all of the classes corresponding to every object mentioned on the
// documentation of the API
$ap = new AdaptivePayments();
// Our request envelope
$requestEnvelope = new RequestEnvelope();
$requestEnvelope->detailLevel = 0;
$requestEnvelope->errorLanguage = 'en_GB';
// Our base amount, in other words the currency we want to convert to
// other currency type. It's very straighforward, just have a public
// prop. to hold de amount and the current code.
$baseAmountList = new CurrencyList();
$baseAmountList->currency = array( 'amount' => $this->amount, 'code' => 'GBP' );
// Our target currency type. Given that I'm from Mexico I would like to
// see it in mexican pesos. Again, just need to provide the code of the
// currency. On the docs you'll have access to the complete list of codes
$convertToCurrencyListUSD = new CurrencyCodeList();
$convertToCurrencyListUSD->currencyCode = 'USD';
// Now create a instance of the ConvertCurrencyRequest object, which is
// the one necessary to handle this request.
// This object takes as parameters the ones we previously created, which
// are our base currency, our target currency, and the req. envelop
$ccReq = new ConvertCurrencyRequest();
$ccReq->baseAmountList = $baseAmountList;
$ccReq->convertToCurrencyList = $convertToCurrencyListUSD;
$ccReq->requestEnvelope = $requestEnvelope;
// And finally we call the ConvertCurrency method on our AdaptivePayment object,
// and assign whatever result we get to our variable
$resultUSD = $ap->ConvertCurrency($ccReq);
$convertToCurrencyListUSD->currencyCode = 'EUR';
$resultEUR = $ap->ConvertCurrency($ccReq);
// Given that our result should be a ConvertCurrencyResponse object, we can
// look into its properties for further display/processing purposes
$resultingCurrencyListUSD = $resultUSD->estimatedAmountTable->currencyConversionList;
$resultingCurrencyListEUR = $resultEUR->estimatedAmountTable->currencyConversionList;
I have a Redirect to take the buyer to the Paypal cart. The URL it forwards them to is (formatted for readability):
https://www.paypal.com/cgi-bin/webscr?cmd=_xclick
&business=email#domain.com
&pal=BGUR9WCWZAL7G
&button_subtype=services
&no_note=1
&no_shipping=1
&rm=1
&return=http://127.0.0.1/store/thank-you
&cancel_return=http://127.0.0.1/store/payment-cancelled
&shipping=0.00
&custom=LoggedInUser|45
¤cy_code=EUR
&item_name_1=Store 9 Item
&amount_1=12.00
&item_name_2=Something else
&amount_2=24.00
I can't use Post data for design reasons.
If I have it as a single item by passing &amount=1&item_name=5 Store Items it works fine, but I need to break it down into individual items if possible.
Is this do-able? I see this question:
Paying for multiple items (at once) via paypal
But it's for posting, not a url
You may want to try the cart upload method. See this page for more information.
It will basically turn out something like this:
https://www.paypal.com/cgi-bin/webscr?cmd=_cart
&business=email#domain.com
&pal=BGUR9WCWZAL7G
&button_subtype=services
&upload=1
&no_note=1
&rm=1
&return=http://127.0.0.1/store/thank-you
&cancel_return=http://127.0.0.1/store/payment-cancelled
¤cy_code=EUR
&item_name_1=Store 9 Item
&amount_1=12.00
&quantity_1=1
&shipping_1=0.00
&item_name_2=Something else
&amount_2=24.00
&quantity_2=1
&shipping_2=0.00
See above is a picture of new order acknowledgement email of Magento.
On the website we're developing we use Fontis Australia extension (http://www.magentocommerce.com/magento-connect/fontis-australia.html) to implement BPay payment method. The extension works ok, except that on the order acknowledgement email, the Email ref always show 000000.
I try to look at it and see that the ref number generated need the order ID as input to generate the correct ref number.
The extension use this code to get the last order number on payment info block:
$order_id = Mage::getSingleton('checkout/session')->getLastRealOrderId();
I try to use and print the result from other controller, it shows the correct order number. But seems that for the payment info block on email, the order number info can't be retrieved. Actually the same block also called out on the checkout success page, and it shows correctly.
Can somebody suggest other way to get the last order id on payment info block on Magento Email?
In info template you can use $order = $this->getInfo()->getOrder(); to get Mage_Sales_Model_Order object. Then you can get current order id by $order->getData('increment_id').
But with this code, you get error in checkout process, because $this->getInfo() returns other model.
So dirty solution, that works for me without errors, is:
$info = $this->getInfo();
if ($info instanceof Mage_Sales_Model_Order_Payment) {
$order = $info->getOrder();
echo $order->getData('increment_id'));
}
I need to determine when a user's paypal subscription is set to end/renew. I know that the easiest way to do this would be to extrapolate it from the time when the initial subscr_signup gets sent through, based on the subscription interval value, but because I'm working with some 3rd party software, it's not possible (or at least, not ideal).
It seems to me that I ought to be able to send a query to paypal to get this info based on txn_id, but I can't find any documentation that implies that this is the case.
if you send a request with:
TRXTYPE = R -this is to tell it recurring profiles
ACTION = I - this is to tell it to make an inquiry
ORIGPROFILEID = XXX - this is the profile you want to look up
PAYMENTHISTORY = N - this will tell it not to return payment history
from there the array will return something like this:
RESULT[1]=0
RPREF[12]=XXXXX
PROFILEID[12]=XXX
STATUS[6]=ACTIVE
PROFILENAME[1]=0
START[8]=10182006
TERM[1]=0
NEXTPAYMENT[8]=10182009
PAYPERIOD[4]=QTER
TENDER[1]=C
AMT[5]=0.00
ACCT[16]=XXXXXXXXXXXXXXXX
EXPDATE[4]=0101
AGGREGATEAMT[6]=0.00
AGGREGATEOPTIONALAMT[5]=0.00
MAXFAILPAYMENTS[1]=0
NUMFAILPAYMENTS[1]=1
RETRYNUMDAYS[1]=4
NAME[11]=BLAHBLAH
ZIP[5]=12345
What you are looking for is the START, but pretty much all the items in the array are self explanitory.