Paypal adaptive payment not showing shipping cost - paypal

Is there a way to show shipping cost once user is redirected to paypal?
I tried with setPaymentOption but no help.
Here is my code-
This function is generating the payKey
function process_payment($JobId,$company_email,$file_id,$printer_id,$cost){
require('/includes/assets/paypal_config/config.php');
require('admin/config/rs_server.php');
// $secondryReceiverQuery = "UPDATE 3d_job_info set pay_key = '".$PayPalResult['PayKey']."' WHERE job_id ='$JobId'";
// $jobInsertQrrRes = mysqli_query($DB_CONN,$jobInsertQrr);
// $cost =$cost+10;
$primary_amt = ((12/100)*$cost) ;
$secondary_amt = $cost - $primary_amt;
// Create PayPal object.
$PayPalConfig = array(
'Sandbox' => $sandbox,
'DeveloperAccountEmail' => $developer_account_email,
'ApplicationID' => $application_id,
'DeviceID' => $device_id,
'IPAddress' => $_SERVER['REMOTE_ADDR'],
'APIUsername' => $api_username,
'APIPassword' => $api_password,
'APISignature' => $api_signature,
'APISubject' => $api_subject,
'PrintHeaders' => $print_headers,
'LogResults' => $log_results,
'LogPath' => $log_path,
);
$PayPal = new Adaptive($PayPalConfig);
// Prepare request arrays
$PayRequestFields = array(
'ActionType' => 'PAY_PRIMARY', // Required. Whether the request pays the receiver or whether the request is set up to create a payment request, but not fulfill the payment until the ExecutePayment is called. Values are: PAY, CREATE, PAY_PRIMARY
'CancelURL' => $domain."index.php?t=cancel_payment&jobid=$JobId",// Required. The URL to which the sender's browser is redirected if the sender cancels the approval for the payment after logging in to paypal.com. 1024 char max.
'CurrencyCode' => 'USD', // Required. 3 character currency code.
'FeesPayer' => 'PRIMARYRECEIVER',// The payer of the fees.lol Values are: SENDER, PRIMARYRECEIVER, EACHRECEIVER, SECONDARYONLY
'IPNNotificationURL' => '', // The URL to which you want all IPN messages for this payment to be sent. 1024 char max.
'Memo' => 'This transection is from localhost', // A note associated with the payment (text, not HTML). 1000 char max
'Pin' => '', // The sener's personal id number, which was specified when the sender signed up for the preapproval
'PreapprovalKey' => '',// The key associated with a preapproval for this payment. The preapproval is required if this is a preapproved payment.
'ReturnURL' => $domain."index.php?t=payment_success&jobid=$JobId", // Required. The URL to which the sener"s browser is redirected after approvaing a payment on paypal.com. 1024 char max.
'ReverseAllParallelPaymentsOnError' => '',// Whether to reverse paralel payments if an error occurs with a payment. Values are: TRUE, FALSE
'SenderEmail' => '',// Sender's email address. 127 char max.
'TrackingID' => '',// Unique ID that you specify to track the payment. 127 char max.
);
$ClientDetailsFields = array(
'CustomerID' => '45', // Your ID for the sender 127 char max.
'CustomerType' => 'type', // Your ID of the type of customer. 127 char max.
'GeoLocation' => '',// Sender's geographic location
'Model' => 'zxc', // A sub-identification of the application. 127 char max.
'PartnerName' => 'zxc' // Your organization's name or ID
);
$FundingTypes = array('ECHECK', 'BALANCE', 'CREDITCARD');// Funding constrainigs require advanced permissions levels.
$Receivers = array();
$Receiver = array(
'Amount' =>$cost,// Required. Amount to be paid to the receiver.
'Email' => 'payment#creiterate.com', // Receiver's email address. 127 char max.
'InvoiceID' => '', // The invoice number for the payment. 127 char max.
'PaymentType' => 'GOODS', // Transaction type. Values are: GOODS, SERVICE, PERSONAL, CASHADVANCE, DIGITALGOODS
'PaymentSubType' => '', // The transaction subtype for the payment.
'AccountID' => '',
'Phone' => array('CountryCode' => '', 'PhoneNumber' => '', 'Extension' => ''), // Receiver's phone number. Numbers only.
'Primary' => 'true' // Whether this receiver is the primary receiver. Values are boolean: TRUE, FALSE
);
array_push($Receivers,$Receiver);
$Receiver = array(
'Amount' => $secondary_amt,// Required. Amount to be paid to the receiver.
'Email' => $company_email, // Receiver's email address. 127 char max.
'InvoiceID' => '',// The invoice number for the payment. 127 char max.
'PaymentType' => '',// Transaction type. Values are: GOODS, SERVICE, PERSONAL, CASHADVANCE, DIGITALGOODS
'PaymentSubType' => '',// The transaction subtype for the payment.
'AccountID' => '',
'Phone' => array('CountryCode' => '', 'PhoneNumber' => '', 'Extension' => ''), // Receiver's phone number. Numbers only.
'Primary' => 'false'// Whether this receiver is the primary receiver. Values are boolean: TRUE, FALSE
);
array_push($Receivers,$Receiver);
$SenderIdentifierFields = array(
'UseCredentials' => TRUE// If TRUE, use credentials to identify the sender. Default is false.
);
$AccountIdentifierFields = array(
'Email' => $_SESSION['loggin_info']['email_address'],// Sender's email address. 127 char max.
'Phone' => array('CountryCode' => '', 'PhoneNumber' => '', 'Extension' => '')// Sender's phone number. Numbers only.
);
$PayPalRequestData = array(
'PayRequestFields' => $PayRequestFields,
'ClientDetailsFields' => $ClientDetailsFields,
// 'CreateInvoiceFields' => $CreateInvoiceFields,
//'FundingTypes' => $FundingTypes,
'Receivers' => $Receivers,
'SenderIdentifierFields' => $SenderIdentifierFields,
'AccountIdentifierFields' => $AccountIdentifierFields
);
// Pass data into class for processing with PayPal and load the response array into $PayPalResult
$PayPalResult = $PayPal->Pay($PayPalRequestData);
//Before redirecting setting the pay option here
setPaymentOption($PayPalResult['PayKey'],$PayPal,$cost);
header("Location: ". $PayPalResult['RedirectURL']);
}
This is my set payment option function.
function setPaymentOption($PayKey,$PayPal,$cost){
require('/../assets/paypal_config/config.php');
require('/admin/config/rs_server.php');
// Create PayPal object.
$PayPalConfig = array(
'Sandbox' => $sandbox,
'DeveloperAccountEmail' => $developer_account_email,
'ApplicationID' => $application_id,
'DeviceID' => $device_id,
'IPAddress' => $_SERVER['REMOTE_ADDR'],
'APIUsername' => $api_username,
'APIPassword' => $api_password,
'APISignature' => $api_signature,
'APISubject' => $api_subject,
'PrintHeaders' => $print_headers,
'LogResults' => $log_results,
'LogPath' => $log_path,
);
// $PayPal = new Adaptive($PayPalConfig);
// Prepare request arrays
$SPOFields = array(
'PayKey' => $PayKey, // Required. The pay key that identifies the payment for which you want to set payment options.
'ShippingAddressID' => '' // Sender's shipping address ID.
);
$DisplayOptions = array(
'EmailHeaderImageURL' => '', // The URL of the image that displays in the header of customer emails. 1,024 char max. Image dimensions: 43 x 240
'EmailMarketingImageURL' => 'http://www.angelleye.com/images/email_marketing_image.jpg', // The URL of the image that displays in the customer emails. 1,024 char max. Image dimensions: 80 x 530
'HeaderImageURL' => 'http://www.angelleye.com/header_image.jpg', // The URL of the image that displays in the header of a payment page. 1,024 char max. Image dimensions: 750 x 90
'BusinessName' => 'Test business' // The business name to display. 128 char max.
);
$InstitutionCustomer = array(
'CountryCode' => 'US', // Required. 2 char code of the home country of the end user.
'DisplayName' => 'Tester Testerson', // Required. The full name of the consumer as known by the institution. 200 char max.
'InstitutionCustomerEmail' => 'payment#creiterate.com ', // The email address of the consumer. 127 char max.
'FirstName' => 'Tester', // Required. The first name of the consumer. 64 char max.
'LastName' => 'Testerson', // Required. The last name of the consumer. 64 char max.
'InstitutionCustomerID' => '12345', // Required. The unique ID assigned to the consumer by the institution. 64 char max.
'InstitutionID' => '6V8R7B4KPS22E' // Required. The unique ID assigned to the institution. 64 char max.
);
$SenderOptions = array(
'RequireShippingAddressSelection' => '' // Boolean. If true, require the sender to select a shipping address during the embedded payment flow. Default is false.
);
// Begin loop to populate receiver options.
$ReceiverOptions = array();
$ReceiverOption = array(
'Description' => 'Test Hello', // A description you want to associate with the payment. 1000 char max.
'CustomID' => '' // An external reference number you want to associate with the payment. 1000 char max.
);
$cost =$cost-10;
$InvoiceData = array(
'TotalTax' => '', // Total tax associated with the payment.
'TotalShipping' => '10' // Total shipping associated with the payment.
);
$InvoiceItems = array();
$InvoiceItem = array(
'Name' => 'Widget ABC', // Name of item.
'Identifier' => '', // External reference to item or item ID.
'Price' => $cost, // Total of line item.
'ItemPrice' => $cost, // Price of an individual item.
'ItemCount' => '1' // Item QTY
);
array_push($InvoiceItems,$InvoiceItem);
$PayPalRequestData = array(
'SPOFields' => $SPOFields,
'DisplayOptions' => $DisplayOptions,
'InstitutionCustomer' => $InstitutionCustomer,
'SenderOptions' => $SenderOptions,
'ReceiverOptions' => $ReceiverOptions
);
// Pass data into class for processing with PayPal and load the response array into $PayPalResult
$PayPalResult = $PayPal->SetPaymentOptions($PayPalRequestData);
}

Related

PayPal express checkout instant update callback not being called [Sandbox]

I'm having troubles with the PayPal callback feature, i can't for the life of me get it to work at all. I have double checked the callback URL path, it's correct. When the user logs into paypal, it always just returns the default shipping rate. I'm just really not sure what i am missing here, if anyone can help out. Also, i have the callback timeout set to 6, though it seems it only takes about 3 - 4 seconds for it to fail and return the default shipping rate.
I've followed the documentation here https://developer.paypal.com/docs/classic/express-checkout/integration-guide/ECInstantUpdateAPI/ and applied it to my website. I've also made sure i am logged into sandbox too.
SetExpressCheckout params:
// SetExpressCheckout
$params = array (
'METHOD' => 'SetExpressCheckout',
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
'VERSION' => $version, // 124.0
'USER' => $paypal_user,
'PWD' => $paypal_password,
'SIGNATURE' => $signature,
'L_SHIPPINGOPTIONNAME0' => 'Flat',
'L_SHIPPINGOPTIONLABEL0' => 'N/A',
'L_SHIPPINGOPTIONAMOUNT0' => '6.99',
'L_SHIPPINGOPTIONISDEFAULT0' => 'true',
'PAYMENTREQUEST_0_INSURANCEOPTIONSOFFERED' => 'false',
'PAYMENTREQUEST_0_SHIPPINGAMT' => $shipping_default, // 6.99
'PAYMENTREQUEST_0_ITEMAMT' => $cart_total,
'PAYMENTREQUEST_0_AMT' => $cart_total + $shipping_default,
'MAXAMT' => $cart_total + 30, // 30 is the total possible shipping amount
'PAYMENTREQUEST_0_CURRENCYCODE' => $paypal_currency, // AUD
'RETURNURL' => $paypal_return,
'CANCELURL' => $paypal_cancel,
'CALLBACK' => 'HTTP://localhost/moes/php/paypal_callback_php.php',
'CALLBACKTIMEOUT' => 6,
'CALLBACKVERSION' => '61.0',
'ALLOWNOTE' => 1,
'PAYMENTREQUEST_0_INVNUM' => '123' /*$invoice_number*/,
'PAYMENTREQUEST_0_TAXAMT' => $tax, // 0.00
);
// List each product and add to exress check-out array
foreach ($paypal_products as $k => $product){
$params["L_PAYMENTREQUEST_0_NAME$k"] = $product['name'];
$params["L_PAYMENTREQUEST_0_AMT$k"] = number_format($product['price'],2);
$params["L_PAYMENTREQUEST_0_QTY$k"] = $product['qty'];
$params["L_PAYMENTREQUEST_0_NUMBER$k"] = $product['code'];
$params["L_PAYMENTREQUEST_0_DESC$k"] = '1';
/* Optional shipping options to calculate shipping costs on callback
Option weight (L_PAYMENTREQUEST_n_ITEMWEIGHTVALUEm, L_PAYMENTREQUEST_n_ITEMWEITHTUNITm)
Option height (L_PAYMENTREQUEST_n_ITEMHEIGHTVALUEm, L_PAYMENTREQUEST_n_ITEMHEIGHTUNITm)
Option length (L_PAYMENTREQUEST_n_ITEMLENGTHVALUEm, L_PAYMENTREQUEST_n_ITEMLENGTHUNITm)
Option width (L_PAYMENTREQUEST_n_ITEMWIDTHVALUEm, L_PAYMENTREQUEST_n_ITEMWIDTHUNITm)*/
}
Callback script:
<?php
// Populate variables into local variables
$method = $_POST['METHOD'];
$version = $_POST['CALLBACKVERSION'];
$token = $_POST['TOKEN'];
$currencycode = $_POST['CURRENCYCODE'];
$localecode = $_POST['LOCALECODE'];
$street = $_POST['SHIPTOSTREET'];
$street2 = $_POST['SHIPTOSTREET2'];
$city = $_POST['SHIPTOCITY'];
$state = $_POST['SHIPTOSTATE'];
$country = $_POST['SHIPTOCOUNTRY'];
$zip = $_POST['SHIPTOZIP'];
// Setting shipping rate based on country [Test only]
if ($country == "US"){
echo "METHOD=CallbackResponse&OFFERINSURANCEOPTION=false&L_SHIPPINGOPTIONNAME0=FLat&L_SHIPPINGOPTIONLABEL0=N/A&L_SHIPPINGOPTIONAMOUNT0=10.00&L_TAXAMT0=1.00&L_INSURANCEAMOUNT0=9.00&L_SHIPPINGOPTIONISDEFAULT0=true";
} else {
echo "METHOD=CallbackResponse&OFFERINSURANCEOPTION=false&L_SHIPPINGOPTIONNAME0=FLat&L_SHIPPINGOPTIONLABEL0=N/A&L_SHIPPINGOPTIONAMOUNT0=30.00&L_TAXAMT0=1.00&L_INSURANCEAMOUNT0=9.00&L_SHIPPINGOPTIONISDEFAULT0=true";
}
?>
I'm guessing i missing something fundamental here, or i'm going about it completely the wrong way.
The solution to my problem was :
localhost/moes/php/paypal_callback_php.php
Obviously PayPal can't send a HTTP request to 'localhost'. My WAMP server is not configured to be accessible over the internet.

PayPal Receipt not showing Description information using SetExpressCheckout

I am using PayPal's API to process a payment using SetExpressCheckout method.
$requestParams = array(
'RETURNURL' => 'SUCCESS_PAGE_URL',
'CANCELURL' => 'CANCE_PAGE_URL'
);
$orderParams = array(
'PAYMENTREQUEST_0_AMT' => $price,
'PAYMENTREQUEST_0_SHIPPINGAMT' => '0',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
'PAYMENTREQUEST_0_ITEMAMT' => $price
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => $item_name,
'L_PAYMENTREQUEST_0_DESC0' => $item_description,
'L_PAYMENTREQUEST_0_AMT0' => $price,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);
It all works great, but even though the description is showing in the PayPal's checkout page, the email receipt that I get is missing the description information.
Does anyone know what how I can get the description to show on the receipt?
Figured it out. When the SetExpressCheckout is done and returns "Success" it gets redirected to PayPal, after which it goes back to your specified RETURNURL. On this RETURNURL page, for DoExpressCheckoutPayment, you need to specify the order details, this is what shows up in the invoice. Here is the code:
// Complete the checkout transaction
$requestParams = array(
'TOKEN' => $_GET['token'],
'PAYMENTACTION' => 'Sale',
'PAYERID' => $_GET['PayerID'],
'PAYMENTREQUEST_0_AMT' => '1', // Same amount as in the original request
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD' // Same currency as the original request
);
$item = array(
'L_PAYMENTREQUEST_0_NAME0' => $name,
'L_PAYMENTREQUEST_0_DESC0' => $desc, // <-- this is the description
'L_PAYMENTREQUEST_0_AMT0' => $price,
'L_PAYMENTREQUEST_0_QTY0' => '1'
);
$response = $paypal -> request('DoExpressCheckoutPayment',$requestParams + $item);

How do you get the shipping address back from an Adaptive Payment API call?

How are you supposed to get the shipping info back from a Parallel Payment, using PayPal's Adaptive API system? Normally it would just get passed back as payer_country, etc - when the IPN script is requested. However, this doesn't seem to be the case.
Here are the params being passed in when the IPN script is called:
transaction[0].amount
transaction[0].id
verify_sign
transaction[1].receiver
reverse_all_parallel_payments_on_error
transaction[1].pending_reason
transaction[0].pending_reason
transaction[1].id_for_sender_txn
transaction[0].invoiceId
payment_request_date
test_ipn
cancel_url
charset
return_url
transaction[0].status_for_sender_txn
ipn_notification_url
transaction[1].is_primary_receiver
transaction[1].status
transaction_type
transaction[1].amount
transaction[0].status
log_default_shipping_address_in_transaction
transaction[0].receiver
status
transaction[0].id_for_sender_txn
action_type
fees_payer
pay_key
transaction[1].status_for_sender_txn
transaction[0].paymentType
transaction[1].invoiceId
transaction[1].id
sender_email
notify_version
transaction[1].paymentType
transaction[0].is_primary_receiver
If I then do a PaymentDetails API call, I get back stuff like:
$VAR1 = {
'currencyCode' => 'USD',
'responseEnvelope' => {
'correlationId' => '9944330ab9a8c',
'timestamp' => '2014-04-07T06:08:16.094-07:00',
'ack' => 'Success',
'build' => '10273932'
},
'status' => 'COMPLETED',
'senderEmail' => 'andy.aaaa#ultranerds.co.uk',
'cancelUrl' => 'http://somesite.net/paypal/cancel.html',
'paymentInfoList' => {
'paymentInfo' => [
{
'pendingRefund' => 'false',
'receiver' => {
'accountId' => 'NY3AD33DD739C',
'email' => 'andy-xxx#ultranerds.com',
'amount' => '65.00',
'invoiceId' => '1022',
'primary' => 'false',
'paymentType' => 'GOODS'
},
'transactionId' => '8E1114341X895213Y',
'senderTransactionStatus' => 'COMPLETED',
'senderTransactionId' => '5EV71352C33256006',
'transactionStatus' => 'COMPLETED',
'refundedAmount' => '0.00'
},
{
'pendingRefund' => 'false',
'receiver' => {
'accountId' => 'YYP5C69YWCMKE',
'email' => 'andy.yyy#gmail.com',
'amount' => '15.00',
'invoiceId' => '1023',
'primary' => 'false',
'paymentType' => 'GOODS'
},
'transactionId' => '68H86656UP574062X',
'senderTransactionStatus' => 'COMPLETED',
'senderTransactionId' => '2XW88939LK1112523',
'transactionStatus' => 'COMPLETED',
'refundedAmount' => '0.00'
}
]
},
'feesPayer' => 'EACHRECEIVER',
'actionType' => 'CREATE',
'ipnNotificationUrl' => 'http://somesite.net/paypal/test_ipn.cgi',
'sender' => {
'useCredentials' => 'false',
'accountId' => 'B74RBM5F6SLZG',
'email' => 'andy.aaa#ultranerds.co.uk'
},
'returnUrl' => 'http://somesite.net/paypal/success.html',
'payKey' => 'AP-4EK17906VB6613533',
'reverseAllParallelPaymentsOnError' => 'false'
};
As you can see, there is no reference to the delivery address at all. How are you supposed to get that info back?
UPDATE: Mmm ok, so it looks like GetShippingAddresses is what I need - but for some reason its coming back with nothing in when I call it:
{"requestEnvelope":{"errorLanguage":"en_US","detailLevel":"ReturnAll"},"key":"AP-1B1377463N9785350"} /GetShippingAddresses_API_Operation/
...simply returns:
{
'responseEnvelope' => {
'correlationId' => '3a4443aed09c9',
'timestamp' => '2014-04-07T06:40:35.460-07:00',
'ack' => 'Success',
'build' => '10273932'
}
}
I'm a bit baffled as to why its doing that. Any suggestions?
I found a quote here:
http://go.developer.ebay.com/devzone/articles/using-paypals-adaptive-payments-and-google-app-engine-build-online-market-python-part-3
Unfortunately, although this follows the process recommended by
PayPal's documentation, it doesn't work. There's currently a bug in
PayPal's Adaptive Payments implementation. For a traditional payment,
the shipping address is not collected; for embedded payments, the
GetShippingAddresses call does not return the shipping address.
PayPal has acknowledged the bug and indicated that it expects to have
this fixed in April 2011. If you need shipping addresses right now,
the recommendation is to collect them on your site rather than relying
on the PayPal API.
That was from 2011... but is this still the case??
Sorry to bump - but has anyone got any suggestions?
Ok, well I got my answer - but unfortunately its not what I was hoping for:
Yes, unfortunately this feature is only available for embedded payment
flow.
https://developer.paypal.com/webapps/developer/docs/classic/adaptive-payments/ht_ap-embeddedPayment-curl-etc/
If you're using embedded payment flow, then you can retrieve the
address on their PayPal account by passing in
senderOptions.requireShippingAddressSelection = true during
SetPaymentOption API call. You can then retrieve it via
GetShippingAddresses API call.
So it looks like really what I need to do, is ask the user to provide their shipping information BEFORE sending them to paypal, then storing it. Not ideal - but I guess you just have to work with what you got!

send data to email view cakephp

I want to send email with cakephp.
But I want send in the email with lot of data like
'Envoie' => array(
(int) 0 => array(
'id' => '59',
'compte_id' => '1',
'annonce_id' => '19',
'site_id' => '8',
'valider' => '0',
'lien' => null,
'created' => '2013-09-19 15:56:28'
),
in my code i have this
$Email = new CakeEmail();
$Email->template('default', 'a');
$envoie = $this->Envoie->find('all',array('conditions' => array(
'Envoie.annonce_id' =>$annonce['Annonce']['id'])));
$Email->viewVars(array("envoie"=>$envoie));
$Email->emailFormat('html');
$Email->to('email#hotmail.com');//$annonce['User']['username']
$Email->from('no-repley#domaine.com');
$Email->subject('subject');
$Email->send();
How i can send my table to my view ?
You have $envoie array in your view ie app/View/Emails/html/default.ctp.
For example, you can get value of id using $envoie['id'] and so on...
In your email template
app/View/Emails/html/default.ctp
You already have access to $envoie, just extract the variable's values to your needs.

Setting shipping info in OmniPay

I'm trying to set a shipping info (name,address, email, etc) using OmniPay for PayPal Express.
I've tried adding shipping info in options array in purchase($options) object:
$options = array(
// required fields (username, pass, etc)
// .....
'shippingAddress1' => 'Elm Street'
'shippingCity' => 'Elm',
'shippingPostcode' => '1000'
// etc.
);
I also tried passing this info to CreditCard object:
$card = new Omnipay\Common\CreditCard($card_options);
without any success. The code:
$gateway = GatewayFactory::create('PayPal_Express');
$gateway->setUsername(USERNAME);
$gateway->setPassword(PASS);
$gateway->setSignature(SIGNATURE);
$gateway->setTestMode(true);
$card_options = array(
'shippingAddress1' => 'Elm Street',
'shippingCity' => 'Elm',
'shippingPostcode' => '10000',
'shippingState' => '',
'shippingCountry' => 'NEverland',
'shippingPhone' => '123465789',
'company' => '',
'email' => 'shipping#test.com'
);
$card = new Omnipay\Common\CreditCard($card_options);
$response = $gateway->purchase(
array(
'cancelUrl'=>'http://localhost/laravel_paypal/',
'returnUrl'=>'http://localhost/laravel_paypal/public/paypalexpress_confirm',
'amount' => '0.99',
'currency' => 'USD',
'card' => $card
)
)->send();
How to add shipping info to PayPal Express using OmniPay?
BTW, I'm using Laravel with PayPal Sandbox.
This problem has recently been fixed (https://github.com/adrianmacneil/omnipay/pull/140) so it should now be possible to set shipping info properly.